ip/ipconfig: implement rfc3397 dhcp dns search option (dnsdomain)

This commit is contained in:
cinap_lenrek 2018-09-25 15:02:29 +02:00
parent 2f076f946f
commit 12b3c82014
4 changed files with 110 additions and 68 deletions

View file

@ -17,6 +17,7 @@ enum
Tbyte, Tbyte,
Tulong, Tulong,
Tvec, Tvec,
Tnames,
}; };
typedef struct Option Option; typedef struct Option Option;
@ -107,10 +108,11 @@ static Option option[256] =
[ODclientid] { "clientid", Tvec }, [ODclientid] { "clientid", Tvec },
[ODtftpserver] { "tftp", Taddr }, [ODtftpserver] { "tftp", Taddr },
[ODbootfile] { "bootfile", Tstr }, [ODbootfile] { "bootfile", Tstr },
[ODdnsdomain] { "dnsdomain", Tnames },
}; };
static uchar defrequested[] = { static uchar defrequested[] = {
OBmask, OBrouter, OBdnserver, OBhostname, OBdomainname, OBntpserver, OBmask, OBrouter, OBdnserver, OBhostname, OBdomainname, ODdnsdomain, OBntpserver,
}; };
static uchar requested[256]; static uchar requested[256];
@ -139,6 +141,7 @@ static uchar* optget(uchar*, int, int*);
static ulong optgetulong(uchar*, int); static ulong optgetulong(uchar*, int);
static int optgetvec(uchar*, int, uchar*, int); static int optgetvec(uchar*, int, uchar*, int);
static char* optgetx(uchar*, uchar); static char* optgetx(uchar*, uchar);
static int optgetnames(uchar*, int, char*, int);
static void getoptions(uchar*); static void getoptions(uchar*);
static int parseoptions(uchar *p, int n); static int parseoptions(uchar *p, int n);
@ -513,10 +516,15 @@ dhcprecv(void)
DEBUG("ntp=%I ", conf.ntp + i*IPaddrlen); DEBUG("ntp=%I ", conf.ntp + i*IPaddrlen);
/* get names */ /* get names */
optgetstr(bp->optdata, OBhostname, if(optgetstr(bp->optdata, OBhostname,
conf.hostname, sizeof conf.hostname); conf.hostname, sizeof conf.hostname))
optgetstr(bp->optdata, OBdomainname, DEBUG("hostname=%s ", conf.hostname);
conf.domainname, sizeof conf.domainname); 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 */ /* get anything else we asked for */
getoptions(bp->optdata); getoptions(bp->optdata);
@ -679,9 +687,8 @@ optget(uchar *p, int op, int *np)
continue; continue;
} }
if(np != nil){ if(np != nil){
if(*np > len) { if(*np > len)
return 0; return 0;
}
*np = len; *np = len;
} }
return p; return p;
@ -799,6 +806,28 @@ optgetstr(uchar *p, int op, char *s, int n)
return len; 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 int
addoption(char *opt) addoption(char *opt)
{ {
@ -865,7 +894,6 @@ optgetx(uchar *p, uchar opt)
case Tvec: case Tvec:
n = optgetvec(p, opt, vec, sizeof vec); n = optgetvec(p, opt, vec, sizeof vec);
if(n > 0) if(n > 0)
/* what's %H? it's not installed */
s = smprint("%s=%.*H", o->name, n, vec); s = smprint("%s=%.*H", o->name, n, vec);
break; break;
} }

View file

@ -127,6 +127,8 @@ void catch(void*, char*);
int countaddrs(uchar *a, int len); int countaddrs(uchar *a, int len);
void addaddrs(uchar *to, int nto, uchar *from, int nfrom); void addaddrs(uchar *to, int nto, uchar *from, int nfrom);
void addnames(char *d, char *s, int len); void addnames(char *d, char *s, int len);
int pnames(uchar*, int, char*);
int gnames(char*, int, uchar*, int);
Ndb* opendatabase(void); Ndb* opendatabase(void);
void ndb2conf(Ndb *db, uchar *ip); void ndb2conf(Ndb *db, uchar *ip);
void putndb(void); void putndb(void);

View file

@ -544,66 +544,6 @@ genipmkask(uchar *mask, int len)
*mask = ~((1<<(8-len))-1); *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; typedef struct Route Route;
struct Route struct Route
{ {

View file

@ -61,6 +61,7 @@ static void
init(void) init(void)
{ {
srand(truerand()); srand(truerand());
fmtinstall('H', encodefmt);
fmtinstall('E', eipfmt); fmtinstall('E', eipfmt);
fmtinstall('I', eipfmt); fmtinstall('I', eipfmt);
fmtinstall('M', eipfmt); fmtinstall('M', eipfmt);
@ -895,6 +896,77 @@ next:
} }
} }
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* static Ndbtuple*
uniquent(Ndbtuple *t) uniquent(Ndbtuple *t)
{ {