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,
Tulong,
Tvec,
Tnames,
};
typedef struct Option Option;
@ -107,10 +108,11 @@ static Option option[256] =
[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 uchar* optget(uchar*, int, int*);
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 @@ dhcprecv(void)
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 @@ optget(uchar *p, int op, int *np)
continue;
}
if(np != nil){
if(*np > len) {
if(*np > len)
return 0;
}
*np = len;
}
return p;
@ -799,6 +806,28 @@ optgetstr(uchar *p, int op, char *s, int n)
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 @@ optgetx(uchar *p, uchar opt)
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;
}

View file

@ -127,6 +127,8 @@ void catch(void*, char*);
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);

View file

@ -544,66 +544,6 @@ genipmkask(uchar *mask, int len)
*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
{

View file

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