--- dhcpcd-1.3.22pl4.orig/client.c +++ dhcpcd-1.3.22pl4/client.c @@ -106,6 +106,70 @@ static short int saved_if_flags = 0; int TokenRingIf = 0; /*****************************************************************************/ +/* Decode an RFC3397 DNS search order option into a space + seperated string. Returns length of string (including + terminating zero) or zero on error. out may be NULL + to just determine output length. */ + +static unsigned int decodeSearch(u_char *p, int len, u_char *out) +{ + u_char *r, *q = p; + unsigned int count = 0, l, hops; + + while (q - p < len) + { + r = NULL; + hops = 0; + while ((l = *q++)) + { + unsigned int label_type = l & 0xc0; + if (label_type == 0x80 || label_type == 0x40) + return 0; + else if (label_type == 0xc0) /* pointer */ + { + l = (l&0x3f) << 8; + l |= *q++; + + /* save source of first jump. */ + if (!r) + r = q; + + hops++; + if (hops > 255) + return 0; + q = p + l; + if (q - p >= len) + return 0; + } + else + { + /* straightforward name segment, add with '.' */ + count += l+1; + if (out) + { + memcpy(out, q, l); + out += l; + *out++ = '.'; + } + q += l; + } + } + + /* change last dot to space */ + if (out) + *(out-1) = ' '; + + if (r) + q = r; + } + + /* change last space to zero terminator */ + if (out) + *(out-1) = 0; + + return count; +} + int parseDhcpMsgRecv() /* this routine parses dhcp message received */ { #ifdef DEBUG @@ -124,10 +188,29 @@ switch ( *p ) { case endOption: goto swend; - case padOption: p++; break; + case padOption: p++; break; + case dnsSearchPath: + { + if(p + 2 + p[1] >= end) + goto swend; + unsigned int len = decodeSearch(p+2, p[1], NULL); + if (len) + { + if ( DhcpOptions.val[*p] ) + free(DhcpOptions.val[*p]); + DhcpOptions.val[*p] = malloc(len); + DhcpOptions.len[*p] = len; + decodeSearch(p+2, p[1], DhcpOptions.val[*p]); + } + p += p[1]+2; + break; + } + default: if ( p[1] ) { + if(p + 2 + p[1] >= end) + goto swend; if ( DhcpOptions.len[*p] == p[1] ) memcpy(DhcpOptions.val[*p],p+2,p[1]); else @@ -866,7 +949,8 @@ { if ( DebugFlag ) syslog(LOG_DEBUG,"timed out waiting for DHCP_ACK response\n"); - alarm(TimeOut); + if (TimeOut != 0) + alarm(TimeOut); return &dhcpInit; } dhcpStart(); --- dhcpcd-1.3.22pl4.orig/client.h +++ dhcpcd-1.3.22pl4/client.h @@ -131,6 +131,7 @@ dhcpT2value = 59, dhcpClassIdentifier = 60, dhcpClientIdentifier = 61, + dnsSearchPath = 119, /* RFC 3397 */ endOption = 255 }; --- dhcpcd-1.3.22pl4.orig/buildmsg.c +++ dhcpcd-1.3.22pl4/buildmsg.c @@ -92,7 +92,7 @@ memcpy(p,&nleaseTime,4); p += 4; *p++ = dhcpParamRequest; - *p++ = 14; + *p++ = 15; *p++ = subnetMask; *p++ = routersOnSubnet; *p++ = dns; @@ -107,6 +107,7 @@ *p++ = nisDomainName; *p++ = nisServers; *p++ = ntpServers; + *p++ = dnsSearchPath; if ( HostName ) { *p++ = hostName; @@ -179,7 +180,7 @@ p += 4; } *p++ = dhcpParamRequest; - *p++ = 14; + *p++ = 15; *p++ = subnetMask; *p++ = routersOnSubnet; *p++ = dns; @@ -194,6 +195,7 @@ *p++ = nisDomainName; *p++ = nisServers; *p++ = ntpServers; + *p++ = dnsSearchPath; if ( HostName ) { *p++ = hostName; @@ -254,7 +256,7 @@ } #endif *p++ = dhcpParamRequest; - *p++ = 14; + *p++ = 15; *p++ = subnetMask; *p++ = routersOnSubnet; *p++ = dns; @@ -269,6 +271,7 @@ *p++ = nisDomainName; *p++ = nisServers; *p++ = ntpServers; + *p++ = dnsSearchPath; if ( HostName ) { *p++ = hostName; @@ -327,7 +330,7 @@ p += 4; } *p++ = dhcpParamRequest; - *p++ = 14; + *p++ = 15; *p++ = subnetMask; *p++ = routersOnSubnet; *p++ = dns; @@ -342,6 +345,7 @@ *p++ = nisDomainName; *p++ = nisServers; *p++ = ntpServers; + *p++ = dnsSearchPath; if ( HostName ) { *p++ = hostName; @@ -408,7 +412,7 @@ memcpy(p,&nleaseTime,4); p += 4; *p++ = dhcpParamRequest; - *p++ = 14; + *p++ = 15; *p++ = subnetMask; *p++ = routersOnSubnet; *p++ = dns; @@ -423,6 +427,7 @@ *p++ = nisDomainName; *p++ = nisServers; *p++ = ntpServers; + *p++ = dnsSearchPath; if ( HostName ) { *p++ = hostName; @@ -556,7 +561,7 @@ memcpy(p,&dhcpMsgSize,2); p += 2; *p++ = dhcpParamRequest; - *p++ = 14; + *p++ = 15; *p++ = subnetMask; *p++ = routersOnSubnet; *p++ = dns; @@ -571,6 +576,7 @@ *p++ = nisDomainName; *p++ = nisServers; *p++ = ntpServers; + *p++ = dnsSearchPath; if ( HostName ) { *p++ = hostName; --- dhcpcd-1.3.22pl4.orig/signals.c +++ dhcpcd-1.3.22pl4/signals.c @@ -35,6 +35,7 @@ extern char *IfNameExt; extern char *ConfigDir; extern int DebugFlag; +extern int Persistent; extern jmp_buf env; extern void *(*currState)(); /*****************************************************************************/ @@ -54,7 +55,6 @@ unlink(pidfile); ntrn: if ( sig == SIGALRM ) return; fprintf(stderr,"**** %s: not running\n",ProgramName); - exit(1); } exit(0); } @@ -122,7 +122,8 @@ } syslog(LOG_ERR,"terminating on signal %d\n",sig); } - dhcpStop(); + if (!Persistent || sig != SIGTERM) + dhcpStop(); deletePidFile(); exit(sig); } --- dhcpcd-1.3.22pl4.orig/dhcpconfig.c +++ dhcpcd-1.3.22pl4/dhcpconfig.c @@ -67,6 +67,7 @@ int resolv_renamed=0; int yp_renamed=0; int ntp_renamed=0; +int have_info=0; /* set once we have written the hostinfo file */ /* Note: Legths initialised to negative to allow us to distinguish between "empty" and "not set" */ char InitialHostName[HOSTNAME_MAX_LEN]; @@ -84,10 +85,14 @@ while ( *c++ ); return cstr; } + /*****************************************************************************/ void execute_on_change(prm) char *prm; { + if (!have_info) + return; + #ifdef EMBED if ( vfork() == 0 ) #else @@ -365,7 +370,9 @@ fprintf(f,"\n"); } #else - if ( DhcpOptions.len[domainName] ) + if ( DhcpOptions.len[dnsSearchPath] ) + fprintf(f,"search %s\n", (char *)DhcpOptions.val[dnsSearchPath]); + else if ( DhcpOptions.len[domainName] ) fprintf(f,"search %s\n",(char *)DhcpOptions.val[domainName]); #endif fclose(f); @@ -649,6 +656,8 @@ ((unsigned char *)DhcpOptions.val[dns])[1+i], ((unsigned char *)DhcpOptions.val[dns])[2+i], ((unsigned char *)DhcpOptions.val[dns])[3+i]); +if ( DhcpOptions.len[dnsSearchPath] ) + fprintf(f, "\nDNSSEARCH=\'%s\'", cleanmetas((char *)DhcpOptions.val[dnsSearchPath])); if ( DhcpOptions.len[ntpServers]>=4 ) { fprintf(f,"\nNTPSERVERS=%u.%u.%u.%u", @@ -726,6 +735,7 @@ DhcpIface.client_id[3],DhcpIface.client_id[4],DhcpIface.client_id[5], DhcpIface.client_id[6],DhcpIface.client_id[7],DhcpIface.client_id[8]); fclose(f); + have_info = 1; } else syslog(LOG_ERR,"dhcpConfig: fopen: %m\n"); --- dhcpcd-1.3.22pl4.orig/dhcpcd.c +++ dhcpcd-1.3.22pl4/dhcpcd.c @@ -70,6 +70,7 @@ int Window = 0; char *ConfigDir = CONFIG_DIR; int SetDHCPDefaultRoutes= 1; +int Persistent = 0; #if 0 unsigned char ClientMACaddr[ETH_ALEN]; int ClientMACaddr_ind = 0; @@ -133,6 +134,10 @@ i++; s=1; break; + case 'p': + s++; + Persistent = 1; + goto prgs; case 'k': s++; killFlag=SIGHUP; @@ -265,7 +270,7 @@ else goto usage; s=1; - if ( TimeOut > 0 ) break; + if ( TimeOut >= 0 ) break; goto usage; case 'w': if ( argc[i][s+1] ) goto usage; @@ -325,7 +330,7 @@ default: usage: print_version(); fprintf(stderr, -"Usage: dhcpcd [-dknrBCDHNRSTY] [-l leasetime] [-h hostname] [-t timeout]\n\ +"Usage: dhcpcd [-dknprBCDHNRSTY] [-l leasetime] [-h hostname] [-t timeout]\n\ [-i vendorClassID] [-I ClientID] [-c filename] [-s [ipaddr]]\n\ [-w windowsize] [-L ConfigDir] [-G [gateway]] [interface]\n"); exit(1); @@ -367,7 +372,8 @@ magic_cookie = htonl(MAGIC_COOKIE); dhcpMsgSize = htons(sizeof(dhcpMessage)); nleaseTime = htonl(LeaseTime); - alarm(TimeOut); + if (TimeOut != 0) + alarm(TimeOut); do if ( (currState=(void *(*)())currState()) == NULL ) exit(1); while ( currState != &dhcpBound );