ref: c966ea5e449c2e59b01b7b0499b1bffba633d7dd
parent: ae81d166452f0649ca498794a85f3776f56beb1c
	author: cinap_lenrek <cinap_lenrek@felloff.net>
	date: Tue Sep 25 11:02:29 EDT 2018
	
ip/ipconfig: implement rfc3397 dhcp dns search option (dnsdomain)
--- a/sys/src/cmd/ip/ipconfig/dhcp.c
+++ b/sys/src/cmd/ip/ipconfig/dhcp.c
@@ -17,6 +17,7 @@
Tbyte,
Tulong,
Tvec,
+ Tnames,
};
typedef struct Option Option;
@@ -107,10 +108,11 @@
 [ODclientid]		{ "clientid",		Tvec }, [ODtftpserver]		{ "tftp",		Taddr }, [ODbootfile]		{ "bootfile",		Tstr },+[ODdnsdomain]		{ "dnsdomain",		Tnames },};
 static uchar defrequested[] = {- OBmask, OBrouter, OBdnserver, OBhostname, OBdomainname, OBntpserver,
+ OBmask, OBrouter, OBdnserver, OBhostname, OBdomainname, ODdnsdomain, OBntpserver,
};
static uchar requested[256];
@@ -139,6 +141,7 @@
static ulong optgetulong(uchar*, int);
static int optgetvec(uchar*, int, uchar*, int);
static char* optgetx(uchar*, uchar);
+static int optgetnames(uchar*, int, char*, int);
static void getoptions(uchar*);
static int parseoptions(uchar *p, int n);
@@ -513,10 +516,15 @@
 			DEBUG("ntp=%I ", conf.ntp + i*IPaddrlen);/* get names */
- optgetstr(bp->optdata, OBhostname,
- conf.hostname, sizeof conf.hostname);
- optgetstr(bp->optdata, OBdomainname,
- conf.domainname, sizeof conf.domainname);
+ if(optgetstr(bp->optdata, OBhostname,
+ conf.hostname, sizeof conf.hostname))
+			DEBUG("hostname=%s ", conf.hostname);+ if(optgetstr(bp->optdata, OBdomainname,
+ conf.domainname, sizeof conf.domainname))
+			DEBUG("domainname=%s ", conf.domainname);+ if(optgetnames(bp->optdata, ODdnsdomain,
+ conf.dnsdomain, sizeof conf.dnsdomain))
+			DEBUG("dnsdomain=%s ", conf.dnsdomain);/* get anything else we asked for */
getoptions(bp->optdata);
@@ -679,9 +687,8 @@
continue;
}
 		if(np != nil){-			if(*np > len) {+ if(*np > len)
return 0;
- }
*np = len;
}
return p;
@@ -799,6 +806,28 @@
return len;
}
+static int
+optgetnames(uchar *p, int op, char *s, int n)
+{+ uchar buf[256];
+ int nbuf, len;
+
+	for(nbuf=0;;p+=len,nbuf+=len){+ len = 1;
+ p = optget(p, op, &len);
+ if(p == nil)
+ break;
+ if(nbuf+len > sizeof(buf))
+ return 0;
+ memmove(buf+nbuf, p, len);
+ }
+	if((len = gnames(s, n, buf, nbuf)) < 0){+ memset(s, 0, n);
+ return 0;
+ }
+ return len;
+}
+
int
addoption(char *opt)
 {@@ -865,7 +894,6 @@
case Tvec:
n = optgetvec(p, opt, vec, sizeof vec);
if(n > 0)
- /* what's %H? it's not installed */
 			s = smprint("%s=%.*H", o->name, n, vec);break;
}
--- a/sys/src/cmd/ip/ipconfig/ipconfig.h
+++ b/sys/src/cmd/ip/ipconfig/ipconfig.h
@@ -127,6 +127,8 @@
int countaddrs(uchar *a, int len);
void addaddrs(uchar *to, int nto, uchar *from, int nfrom);
void addnames(char *d, char *s, int len);
+int pnames(uchar*, int, char*);
+int gnames(char*, int, uchar*, int);
Ndb* opendatabase(void);
void ndb2conf(Ndb *db, uchar *ip);
void putndb(void);
--- a/sys/src/cmd/ip/ipconfig/ipv6.c
+++ b/sys/src/cmd/ip/ipconfig/ipv6.c
@@ -544,66 +544,6 @@
*mask = ~((1<<(8-len))-1);
}
-static int
-pnames(uchar *d, int nd, char *s)
-{- uchar *de = d + nd;
- int l;
-
- if(nd < 1)
- return -1;
-	for(; *s != 0; s++){- for(l = 0; *s != 0 && *s != '.' && *s != ' '; l++)
- s++;
-
- d += l+1;
- if(d >= de || l > 077)
- return -1;
-
- d[-l-1] = l;
- memmove(d-l, s-l, l);
-
- if(*s != '.')
- *d++ = 0;
- }
- return d - (de - nd);
-}
-
-static int
-gnames(char *d, int nd, uchar *s, int ns)
-{- uchar *se = s + ns;
- char *de = d + nd;
- int l;
-
- if(nd < 1 || ns < 1)
- return -1;
- l = *s++ & 077;
-	while(l > 0){- if(d + l >= de || s + l >= se)
- return -1;
-
- memmove(d, s, l);
- d += l;
- s += l;
-
- l = *s++ & 077;
- if(l > 0)
- *d++ = '.';
-		else {- if(s >= se)
- break;
-
- l = *s++ & 077;
- if(l == 0)
- break;
- *d++ = ' ';
- }
- }
- *d = 0;
- return d - (de - nd);
-}
-
typedef struct Route Route;
struct Route
 {--- a/sys/src/cmd/ip/ipconfig/main.c
+++ b/sys/src/cmd/ip/ipconfig/main.c
@@ -61,6 +61,7 @@
init(void)
 {srand(truerand());
+	fmtinstall('H', encodefmt); 	fmtinstall('E', eipfmt); 	fmtinstall('I', eipfmt); 	fmtinstall('M', eipfmt);@@ -893,6 +894,77 @@
if(*s == 0)
break;
}
+}
+
+int
+pnames(uchar *d, int nd, char *s)
+{+ uchar *de = d + nd;
+ int l;
+
+ if(nd < 1)
+ return -1;
+	for(; *s != 0; s++){+ for(l = 0; *s != 0 && *s != '.' && *s != ' '; l++)
+ s++;
+
+ d += l+1;
+ if(d >= de || l > 077)
+ return -1;
+
+ d[-l-1] = l;
+ memmove(d-l, s-l, l);
+
+ if(*s != '.')
+ *d++ = 0;
+ }
+ return d - (de - nd);
+}
+
+int
+gnames(char *d, int nd, uchar *s, int ns)
+{+ char *de = d + nd;
+ uchar *se = s + ns;
+ uchar *c = nil;
+ int l, p = 0;
+
+ if(ns < 1 || nd < 1)
+ return -1;
+	while(s < se){+ l = *s++;
+		if((l & 0300) == 0300){+ if(++p > 100 || s >= se)
+ break;
+ l = (l & 077)<<8 | *s++;
+ if(c == nil)
+ c = s;
+ s = (se - ns) + l;
+ continue;
+ }
+ l &= 077;
+		if(l == 0){+ if(d <= de - nd)
+ break;
+ d[-1] = ' ';
+			if(c != nil){+ s = c;
+ c = nil;
+ p = 0;
+ }
+ continue;
+ }
+ if(s+l >= se || d+l >= de)
+ break;
+ memmove(d, s, l);
+ s += l;
+ d += l;
+ *d++ = '.';
+ }
+ if(p != 0 || s != se || d <= de - nd || d[-1] != ' ')
+ return -1;
+ *(--d) = 0;
+ return d - (de - nd);
}
static Ndbtuple*
--
⑨