2
* dhcpcd - DHCP client daemon -
3
* Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
4
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
6
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
8
* This is free software; you can redistribute it and/or modify it
9
* under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful, but
14
* WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
* See the GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
#include <sys/types.h>
24
#include <sys/socket.h>
25
#include <sys/ioctl.h>
27
#include <netinet/in.h>
28
#include <net/route.h>
30
#include <arpa/nameser.h>
41
#include "pathnames.h"
44
extern int dhcpSocket;
45
extern int prev_ip_addr;
47
extern int SetDHCPDefaultRoutes;
50
extern int SetDomainName;
51
extern int SetHostName;
52
extern int ReplResolvConf;
53
extern int ReplNISConf;
54
extern int ReplNTPConf;
55
extern int IfName_len,IfNameExt_len;
56
extern char *IfName,*IfNameExt,*Cfilename,*ConfigDir;
57
extern char **ProgramEnviron;
58
extern unsigned char ClientHwAddr[ETH_ALEN],*ClientID;
59
extern struct in_addr default_router;
60
extern dhcpInterface DhcpIface;
61
extern dhcpOptions DhcpOptions;
62
extern const dhcpMessage *DhcpMsgRecv;
66
char hostinfo_file[128];
70
int have_info=0; /* set once we have written the hostinfo file */
72
/* Note: Legths initialised to negative to allow us to distinguish between "empty" and "not set" */
73
char InitialHostName[HOSTNAME_MAX_LEN];
74
int InitialHostName_len=-1;
75
char InitialDomainName[HOSTNAME_MAX_LEN];
76
int InitialDomainName_len=-1;
78
/*****************************************************************************/
79
char *cleanmetas(cstr) /* this is to clean single quotes out of DHCP strings */
80
char *cstr; /* replace single quotes with space */
82
register char *c=cstr;
84
if ( *c == 39 ) *c = ' ';
89
/*****************************************************************************/
90
void execute_on_change(prm)
102
char *argc[5],exec_on_change[128];
104
snprintf(exec_on_change,sizeof(exec_on_change),Cfilename);
106
snprintf(exec_on_change,sizeof(exec_on_change),EXEC_ON_CHANGE,ConfigDir);
107
argc[0]=exec_on_change;
108
argc[1]=hostinfo_file;
115
if ( execve(exec_on_change,argc,ProgramEnviron) && errno != ENOENT )
116
syslog(LOG_ERR,"error executing \"%s %s %s\": %m\n",
117
exec_on_change,hostinfo_file,prm);
121
/*****************************************************************************/
122
unsigned long getgenmask(ip_in) /* this is to guess genmask */
123
unsigned long ip_in; /* from network address */
125
unsigned long t,p=ntohl(ip_in);
143
/*****************************************************************************/
144
int setDefaultRoute(route_addr)
147
struct rtentry rtent;
148
struct sockaddr_in *p;
150
memset(&rtent,0,sizeof(struct rtentry));
151
p = (struct sockaddr_in *)&rtent.rt_dst;
152
p->sin_family = AF_INET;
153
p->sin_addr.s_addr = 0;
154
p = (struct sockaddr_in *)&rtent.rt_gateway;
155
p->sin_family = AF_INET;
156
memcpy(&p->sin_addr.s_addr,route_addr,4);
157
p = (struct sockaddr_in *)&rtent.rt_genmask;
158
p->sin_family = AF_INET;
159
p->sin_addr.s_addr = 0;
160
#ifdef OLD_LINUX_VERSION
161
rtent.rt_dev = IfName;
163
rtent.rt_dev = IfNameExt;
166
rtent.rt_window = Window;
167
rtent.rt_flags = RTF_UP|RTF_GATEWAY|(Window ? RTF_WINDOW : 0);
168
if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) == -1 )
170
if ( errno == ENETUNREACH ) /* possibly gateway is over the bridge */
171
{ /* try adding a route to gateway first */
172
memset(&rtent,0,sizeof(struct rtentry));
173
p = (struct sockaddr_in *)&rtent.rt_dst;
174
p->sin_family = AF_INET;
175
memcpy(&p->sin_addr.s_addr,route_addr,4);
176
p = (struct sockaddr_in *)&rtent.rt_gateway;
177
p->sin_family = AF_INET;
178
p->sin_addr.s_addr = 0;
179
p = (struct sockaddr_in *)&rtent.rt_genmask;
180
p->sin_family = AF_INET;
181
p->sin_addr.s_addr = 0xffffffff;
182
#ifdef OLD_LINUX_VERSION
183
rtent.rt_dev = IfName;
185
rtent.rt_dev = IfNameExt;
188
rtent.rt_flags = RTF_UP|RTF_HOST;
189
if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) == 0 )
191
memset(&rtent,0,sizeof(struct rtentry));
192
p = (struct sockaddr_in *)&rtent.rt_dst;
193
p->sin_family = AF_INET;
194
p->sin_addr.s_addr = 0;
195
p = (struct sockaddr_in *)&rtent.rt_gateway;
196
p->sin_family = AF_INET;
197
memcpy(&p->sin_addr.s_addr,route_addr,4);
198
p = (struct sockaddr_in *)&rtent.rt_genmask;
199
p->sin_family = AF_INET;
200
p->sin_addr.s_addr = 0;
201
#ifdef OLD_LINUX_VERSION
202
rtent.rt_dev = IfName;
204
rtent.rt_dev = IfNameExt;
207
rtent.rt_window = Window;
208
rtent.rt_flags = RTF_UP|RTF_GATEWAY|(Window ? RTF_WINDOW : 0);
209
if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) == -1 )
211
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
218
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
224
/*****************************************************************************/
229
char hostinfo_file_old[128];
231
struct rtentry rtent;
232
#ifdef OLD_LINUX_VERSION
233
struct sockaddr_pkt sap;
235
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
236
struct hostent *hp=NULL;
240
if ( TestCase ) goto tsc;
241
memset(&ifr,0,sizeof(struct ifreq));
242
#ifdef OLD_LINUX_VERSION
243
memcpy(ifr.ifr_name,IfName,IfName_len);
245
memcpy(ifr.ifr_name,IfNameExt,IfNameExt_len);
247
p->sin_family = AF_INET;
248
p->sin_addr.s_addr = DhcpIface.ciaddr;
249
if ( ioctl(dhcpSocket,SIOCSIFADDR,&ifr) == -1 ) /* setting IP address */
251
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFADDR: %m\n");
254
memcpy(&p->sin_addr.s_addr,DhcpOptions.val[subnetMask],4);
255
if ( ioctl(dhcpSocket,SIOCSIFNETMASK,&ifr) == -1 ) /* setting netmask */
257
p->sin_addr.s_addr = 0xffffffff; /* try 255.255.255.255 */
258
if ( ioctl(dhcpSocket,SIOCSIFNETMASK,&ifr) == -1 )
260
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFNETMASK: %m\n");
264
memcpy(&p->sin_addr.s_addr,DhcpOptions.val[broadcastAddr],4);
265
if ( ioctl(dhcpSocket,SIOCSIFBRDADDR,&ifr) == -1 ) /* setting broadcast address */
266
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFBRDADDR: %m\n");
268
/* setting local route - not needed on later kernels */
269
#ifdef OLD_LINUX_VERSION
270
memset(&rtent,0,sizeof(struct rtentry));
271
p = (struct sockaddr_in *)&rtent.rt_dst;
272
p->sin_family = AF_INET;
273
memcpy(&p->sin_addr.s_addr,DhcpOptions.val[subnetMask],4);
274
p->sin_addr.s_addr &= DhcpIface.ciaddr;
275
p = (struct sockaddr_in *)&rtent.rt_gateway;
276
p->sin_family = AF_INET;
277
p->sin_addr.s_addr = 0;
278
p = (struct sockaddr_in *)&rtent.rt_genmask;
279
p->sin_family = AF_INET;
280
memcpy(&p->sin_addr.s_addr,DhcpOptions.val[subnetMask],4);
281
rtent.rt_dev = IfName;
283
rtent.rt_flags = RTF_UP;
284
if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) )
285
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
288
for (i=0;i<DhcpOptions.len[staticRoute];i+=8)
289
{ /* setting static routes */
290
struct sockaddr_in *dstp;
291
struct sockaddr_in *gwp;
292
struct sockaddr_in *mskp;
293
memset(&rtent,0,sizeof(struct rtentry));
294
dstp = (struct sockaddr_in *)&rtent.rt_dst;
295
dstp->sin_family = AF_INET;
296
memcpy(&dstp->sin_addr.s_addr,((char *)DhcpOptions.val[staticRoute])+i,4);
297
gwp = (struct sockaddr_in *)&rtent.rt_gateway;
298
gwp->sin_family = AF_INET;
299
memcpy(&gwp->sin_addr.s_addr,((char *)DhcpOptions.val[staticRoute])+i+4,4);
300
mskp = (struct sockaddr_in *)&rtent.rt_genmask;
301
mskp->sin_family = AF_INET;
302
mskp->sin_addr.s_addr = getgenmask(dstp->sin_addr.s_addr);
303
rtent.rt_flags = RTF_UP|RTF_GATEWAY;
304
if ( mskp->sin_addr.s_addr == 0xffffffff ) rtent.rt_flags |= RTF_HOST;
306
#ifdef OLD_LINUX_VERSION
307
rtent.rt_dev = IfName;
309
rtent.rt_dev = IfNameExt;
312
if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) )
313
syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
316
if ( SetDHCPDefaultRoutes )
318
if ( DhcpOptions.len[routersOnSubnet] > 3 )
319
for (i=0;i<DhcpOptions.len[routersOnSubnet];i+=4)
320
setDefaultRoute(DhcpOptions.val[routersOnSubnet]);
323
if ( default_router.s_addr > 0 ) setDefaultRoute((char *)&(default_router.s_addr));
325
/* rebind dhcpSocket after changing ip address to avoid problems with 2.0 kernels */
326
#ifdef OLD_LINUX_VERSION
327
memset(&sap,0,sizeof(sap));
328
sap.spkt_family = AF_INET;
329
sap.spkt_protocol = htons(ETH_P_ALL);
330
memcpy(sap.spkt_device,IfName,IfName_len);
331
if ( bind(dhcpSocket,(void*)&sap,sizeof(struct sockaddr)) == -1 )
332
syslog(LOG_ERR,"dhcpConfig: bind: %m\n");
337
fprintf(stdout,"dhcpcd: your IP address = %u.%u.%u.%u\n",
338
((unsigned char *)&DhcpIface.ciaddr)[0],
339
((unsigned char *)&DhcpIface.ciaddr)[1],
340
((unsigned char *)&DhcpIface.ciaddr)[2],
341
((unsigned char *)&DhcpIface.ciaddr)[3]);
342
if ( ReplResolvConf )
344
resolv_renamed=1+rename(RESOLV_CONF,""RESOLV_CONF".sv");
345
f=fopen(RESOLV_CONF,"w");
350
if ( DhcpOptions.len[nisDomainName] )
351
fprintf(f,"domain %s\n",(char *)DhcpOptions.val[nisDomainName]);
353
if ( DhcpOptions.len[domainName] )
354
fprintf(f,"domain %s\n",(char *)DhcpOptions.val[domainName]);
356
for (i=0;i<DhcpOptions.len[dns];i+=4)
357
fprintf(f,"nameserver %u.%u.%u.%u\n",
358
((unsigned char *)DhcpOptions.val[dns])[i],
359
((unsigned char *)DhcpOptions.val[dns])[i+1],
360
((unsigned char *)DhcpOptions.val[dns])[i+2],
361
((unsigned char *)DhcpOptions.val[dns])[i+3]);
363
if ( DhcpOptions.len[nisDomainName] + DhcpOptions.len[domainName] )
366
if ( DhcpOptions.len[nisDomainName] )
367
fprintf(f," %s",(char *)DhcpOptions.val[nisDomainName]);
368
if ( DhcpOptions.len[domainName] )
369
fprintf(f," %s",(char *)DhcpOptions.val[domainName]);
373
if ( DhcpOptions.len[dnsSearchPath] )
374
fprintf(f,"search %s\n", (char *)DhcpOptions.val[dnsSearchPath]);
375
else if ( DhcpOptions.len[domainName] )
376
fprintf(f,"search %s\n",(char *)DhcpOptions.val[domainName]);
381
syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
383
/* moved the next section of code from before to after we've created
384
* resolv.conf. See below for explanation. <poeml@suse.de>
385
* res_init() is normally called from within the first function of the
386
* resolver which is called. Here, we want resolv.conf to be
387
* reread. Otherwise, we won't be able to find out about our hostname,
388
* because the resolver won't notice the change in resolv.conf */
393
yp_renamed=1+rename(NIS_CONF,""NIS_CONF".sv");
394
f=fopen(NIS_CONF,"w");
399
if ( DhcpOptions.len[nisDomainName] )
400
domain=(char *)DhcpOptions.val[nisDomainName];
402
domain=(char *)DhcpOptions.val[domainName];
403
for (i=0;i<DhcpOptions.len[nisServers];i+=4)
404
fprintf(f,"domain %s server %u.%u.%u.%u\n",(domain?domain:"localdomain"),
405
((unsigned char *)DhcpOptions.val[nisServers])[i],
406
((unsigned char *)DhcpOptions.val[nisServers])[i+1],
407
((unsigned char *)DhcpOptions.val[nisServers])[i+2],
408
((unsigned char *)DhcpOptions.val[nisServers])[i+3]);
409
if ( !DhcpOptions.len[nisServers] )
410
fprintf(f,"domain %s broadcast\n", (domain?domain:"localdomain"));
414
syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
418
ntp_renamed=1+rename(NTP_CONF,""NTP_CONF".sv");
419
f=fopen(NTP_CONF,"w");
423
memcpy(&mask,DhcpOptions.val[subnetMask],4);
424
net = DhcpIface.ciaddr & mask;
426
/* Note: Revise drift/log file names and stratum for local clock */
427
fprintf(f,"restrict default noquery notrust nomodify\n");
428
fprintf(f,"restrict 127.0.0.1\n");
429
fprintf(f,"restrict %u.%u.%u.%u mask %u.%u.%u.%u\n",
430
((unsigned char *)&net)[0],
431
((unsigned char *)&net)[1],
432
((unsigned char *)&net)[2],
433
((unsigned char *)&net)[3],
434
((unsigned char *)&mask)[0],
435
((unsigned char *)&mask)[1],
436
((unsigned char *)&mask)[2],
437
((unsigned char *)&mask)[3]);
438
if ( DhcpOptions.len[ntpServers]>=4 )
441
char addr[4*3+3*1+1];
442
for (i=0;i<DhcpOptions.len[ntpServers];i+=4)
444
snprintf(addr,sizeof(addr),"%u.%u.%u.%u",
445
((unsigned char *)DhcpOptions.val[ntpServers])[i],
446
((unsigned char *)DhcpOptions.val[ntpServers])[i+1],
447
((unsigned char *)DhcpOptions.val[ntpServers])[i+2],
448
((unsigned char *)DhcpOptions.val[ntpServers])[i+3]);
449
fprintf(f,"restrict %s\nserver %s\n",addr,addr);
453
{ /* No servers found, use local clock */
454
fprintf(f, "fudge 127.127.1.0 stratum 3\n");
455
fprintf(f, "server 127.127.1.0\n");
457
fprintf(f, "driftfile /etc/ntp.drift\n");
458
fprintf(f, "logfile /var/log/ntp.log\n");
462
syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
466
if ( ! DhcpOptions.len[hostName] )
468
hp=gethostbyaddr((char *)&DhcpIface.ciaddr,
469
sizeof(DhcpIface.ciaddr),AF_INET);
473
while ( *dname > 32 )
480
dname_len=dname-hp->h_name;
481
DhcpOptions.val[hostName]=(char *)malloc(dname_len+1);
482
DhcpOptions.len[hostName]=dname_len;
483
memcpy((char *)DhcpOptions.val[hostName],
484
hp->h_name,dname_len);
485
((char *)DhcpOptions.val[hostName])[dname_len]=0;
489
if ( InitialHostName_len<0 && gethostname(InitialHostName,sizeof(InitialHostName))==0 )
491
InitialHostName_len=strlen(InitialHostName);
493
fprintf(stdout,"dhcpcd: orig hostname = %s\n",InitialHostName);
495
if ( DhcpOptions.len[hostName] )
497
sethostname(DhcpOptions.val[hostName],DhcpOptions.len[hostName]);
499
fprintf(stdout,"dhcpcd: your hostname = %s\n",
500
(char *)DhcpOptions.val[hostName]);
505
if ( InitialDomainName_len<0 && getdomainname(InitialDomainName,sizeof(InitialDomainName))==0 )
507
InitialDomainName_len=strlen(InitialDomainName);
509
fprintf(stdout,"dhcpcd: orig domainname = %s\n",InitialDomainName);
512
if ( DhcpOptions.len[nisDomainName] )
514
setdomainname(DhcpOptions.val[nisDomainName],
515
DhcpOptions.len[nisDomainName]);
517
fprintf(stdout,"dhcpcd: your domainname = %s\n",
518
(char *)DhcpOptions.val[nisDomainName]);
523
if ( ! DhcpOptions.len[domainName] )
526
hp=gethostbyaddr((char *)&DhcpIface.ciaddr,
527
sizeof(DhcpIface.ciaddr),AF_INET);
531
while ( *dname > 32 )
539
dname_len=strlen(dname);
542
DhcpOptions.val[domainName]=(char *)malloc(dname_len+1);
543
DhcpOptions.len[domainName]=dname_len;
544
memcpy((char *)DhcpOptions.val[domainName],
546
((char *)DhcpOptions.val[domainName])[dname_len]=0;
551
if ( DhcpOptions.len[domainName] )
553
setdomainname(DhcpOptions.val[domainName],
554
DhcpOptions.len[domainName]);
556
fprintf(stdout,"dhcpcd: your domainname = %s\n",
557
(char *)DhcpOptions.val[domainName]);
564
memset(DhcpIface.version,0,sizeof(DhcpIface.version));
565
strncpy(DhcpIface.version,VERSION,sizeof(DhcpIface.version));
566
snprintf(hostinfo_file_old,sizeof(hostinfo_file_old),DHCP_CACHE_FILE,ConfigDir,IfNameExt);
567
i=open(hostinfo_file_old,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR+S_IWUSR);
569
write(i,(char *)&DhcpIface,sizeof(dhcpInterface)) == -1 ||
571
syslog(LOG_ERR,"dhcpConfig: open/write/close: %m\n");
572
snprintf(hostinfo_file,sizeof(hostinfo_file),DHCP_HOSTINFO,ConfigDir,IfNameExt);
573
snprintf(hostinfo_file_old,sizeof(hostinfo_file_old),""DHCP_HOSTINFO".old",ConfigDir,IfNameExt);
574
rename(hostinfo_file,hostinfo_file_old);
575
f=fopen(hostinfo_file,"w");
579
memcpy(&b,DhcpOptions.val[subnetMask],4);
580
c = DhcpIface.ciaddr & b;
582
IPADDR=%u.%u.%u.%u\n\
583
NETMASK=%u.%u.%u.%u\n\
584
NETWORK=%u.%u.%u.%u\n\
585
BROADCAST=%u.%u.%u.%u\n",
586
((unsigned char *)&DhcpIface.ciaddr)[0],
587
((unsigned char *)&DhcpIface.ciaddr)[1],
588
((unsigned char *)&DhcpIface.ciaddr)[2],
589
((unsigned char *)&DhcpIface.ciaddr)[3],
590
((unsigned char *)DhcpOptions.val[subnetMask])[0],
591
((unsigned char *)DhcpOptions.val[subnetMask])[1],
592
((unsigned char *)DhcpOptions.val[subnetMask])[2],
593
((unsigned char *)DhcpOptions.val[subnetMask])[3],
594
((unsigned char *)&c)[0],
595
((unsigned char *)&c)[1],
596
((unsigned char *)&c)[2],
597
((unsigned char *)&c)[3],
598
((unsigned char *)DhcpOptions.val[broadcastAddr])[0],
599
((unsigned char *)DhcpOptions.val[broadcastAddr])[1],
600
((unsigned char *)DhcpOptions.val[broadcastAddr])[2],
601
((unsigned char *)DhcpOptions.val[broadcastAddr])[3]);
602
if ( DhcpOptions.len[routersOnSubnet] > 3 )
605
GATEWAY=%u.%u.%u.%u",
606
((unsigned char *)DhcpOptions.val[routersOnSubnet])[0],
607
((unsigned char *)DhcpOptions.val[routersOnSubnet])[1],
608
((unsigned char *)DhcpOptions.val[routersOnSubnet])[2],
609
((unsigned char *)DhcpOptions.val[routersOnSubnet])[3]);
610
for (i=4;i<DhcpOptions.len[routersOnSubnet];i+=4)
611
fprintf(f,",%u.%u.%u.%u",
612
((unsigned char *)DhcpOptions.val[routersOnSubnet])[i],
613
((unsigned char *)DhcpOptions.val[routersOnSubnet])[1+i],
614
((unsigned char *)DhcpOptions.val[routersOnSubnet])[2+i],
615
((unsigned char *)DhcpOptions.val[routersOnSubnet])[3+i]);
617
if ( DhcpOptions.len[staticRoute] )
619
fprintf(f,"\nROUTE=%u.%u.%u.%u,%u.%u.%u.%u",
620
((unsigned char *)DhcpOptions.val[staticRoute])[0],
621
((unsigned char *)DhcpOptions.val[staticRoute])[1],
622
((unsigned char *)DhcpOptions.val[staticRoute])[2],
623
((unsigned char *)DhcpOptions.val[staticRoute])[3],
624
((unsigned char *)DhcpOptions.val[staticRoute])[4],
625
((unsigned char *)DhcpOptions.val[staticRoute])[5],
626
((unsigned char *)DhcpOptions.val[staticRoute])[6],
627
((unsigned char *)DhcpOptions.val[staticRoute])[7]);
628
for (i=8;i<DhcpOptions.len[staticRoute];i+=8)
629
fprintf(f,",%u.%u.%u.%u,%u.%u.%u.%u",
630
((unsigned char *)DhcpOptions.val[staticRoute])[i],
631
((unsigned char *)DhcpOptions.val[staticRoute])[1+i],
632
((unsigned char *)DhcpOptions.val[staticRoute])[2+i],
633
((unsigned char *)DhcpOptions.val[staticRoute])[3+i],
634
((unsigned char *)DhcpOptions.val[staticRoute])[4+i],
635
((unsigned char *)DhcpOptions.val[staticRoute])[5+i],
636
((unsigned char *)DhcpOptions.val[staticRoute])[6+i],
637
((unsigned char *)DhcpOptions.val[staticRoute])[7+i]);
639
if ( DhcpOptions.len[hostName] )
640
fprintf(f,"\nHOSTNAME=\'%s\'",cleanmetas((char *)DhcpOptions.val[hostName]));
641
if ( DhcpOptions.len[domainName] )
642
fprintf(f,"\nDOMAIN=\'%s\'",cleanmetas((char *)DhcpOptions.val[domainName]));
643
if ( DhcpOptions.len[nisDomainName] )
644
fprintf(f,"\nNISDOMAIN=\'%s\'",cleanmetas((char *)DhcpOptions.val[nisDomainName]));
645
if ( DhcpOptions.len[rootPath] )
646
fprintf(f,"\nROOTPATH=\'%s\'",cleanmetas((char *)DhcpOptions.val[rootPath]));
649
((unsigned char *)DhcpOptions.val[dns])[0],
650
((unsigned char *)DhcpOptions.val[dns])[1],
651
((unsigned char *)DhcpOptions.val[dns])[2],
652
((unsigned char *)DhcpOptions.val[dns])[3]);
653
for (i=4;i<DhcpOptions.len[dns];i+=4)
654
fprintf(f,",%u.%u.%u.%u",
655
((unsigned char *)DhcpOptions.val[dns])[i],
656
((unsigned char *)DhcpOptions.val[dns])[1+i],
657
((unsigned char *)DhcpOptions.val[dns])[2+i],
658
((unsigned char *)DhcpOptions.val[dns])[3+i]);
659
if ( DhcpOptions.len[dnsSearchPath] )
660
fprintf(f, "\nDNSSEARCH=\'%s\'", cleanmetas((char *)DhcpOptions.val[dnsSearchPath]));
661
if ( DhcpOptions.len[ntpServers]>=4 )
663
fprintf(f,"\nNTPSERVERS=%u.%u.%u.%u",
664
((unsigned char *)DhcpOptions.val[ntpServers])[0],
665
((unsigned char *)DhcpOptions.val[ntpServers])[1],
666
((unsigned char *)DhcpOptions.val[ntpServers])[2],
667
((unsigned char *)DhcpOptions.val[ntpServers])[3]);
668
for (i=4;i<DhcpOptions.len[ntpServers];i+=4)
669
fprintf(f,",%u.%u.%u.%u",
670
((unsigned char *)DhcpOptions.val[ntpServers])[i],
671
((unsigned char *)DhcpOptions.val[ntpServers])[1+i],
672
((unsigned char *)DhcpOptions.val[ntpServers])[2+i],
673
((unsigned char *)DhcpOptions.val[ntpServers])[3+i]);
675
if ( DhcpOptions.len[nisServers]>=4 )
677
fprintf(f,"\nNISSERVERS=%u.%u.%u.%u",
678
((unsigned char *)DhcpOptions.val[nisServers])[0],
679
((unsigned char *)DhcpOptions.val[nisServers])[1],
680
((unsigned char *)DhcpOptions.val[nisServers])[2],
681
((unsigned char *)DhcpOptions.val[nisServers])[3]);
682
for (i=4;i<DhcpOptions.len[nisServers];i+=4)
683
fprintf(f,",%u.%u.%u.%u",
684
((unsigned char *)DhcpOptions.val[nisServers])[i],
685
((unsigned char *)DhcpOptions.val[nisServers])[1+i],
686
((unsigned char *)DhcpOptions.val[nisServers])[2+i],
687
((unsigned char *)DhcpOptions.val[nisServers])[3+i]);
690
DHCPSID=%u.%u.%u.%u\n\
691
DHCPGIADDR=%u.%u.%u.%u\n\
692
DHCPSIADDR=%u.%u.%u.%u\n\
693
DHCPCHADDR=%02X:%02X:%02X:%02X:%02X:%02X\n\
694
DHCPSHADDR=%02X:%02X:%02X:%02X:%02X:%02X\n\
701
((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],
702
((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],
703
((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],
704
((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3],
705
((unsigned char *)&DhcpMsgRecv->giaddr)[0],
706
((unsigned char *)&DhcpMsgRecv->giaddr)[1],
707
((unsigned char *)&DhcpMsgRecv->giaddr)[2],
708
((unsigned char *)&DhcpMsgRecv->giaddr)[3],
709
((unsigned char *)&DhcpMsgRecv->siaddr)[0],
710
((unsigned char *)&DhcpMsgRecv->siaddr)[1],
711
((unsigned char *)&DhcpMsgRecv->siaddr)[2],
712
((unsigned char *)&DhcpMsgRecv->siaddr)[3],
725
cleanmetas(DhcpMsgRecv->sname),
726
ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime]),
727
ntohl(*(unsigned int *)DhcpOptions.val[dhcpT1value]),
728
ntohl(*(unsigned int *)DhcpOptions.val[dhcpT2value]),
732
fprintf(f,"CLIENTID=\'%s\'\n",ClientID);
734
fprintf(f,"CLIENTID=%02X:%02X:%02X:%02X:%02X:%02X\n",
735
DhcpIface.client_id[3],DhcpIface.client_id[4],DhcpIface.client_id[5],
736
DhcpIface.client_id[6],DhcpIface.client_id[7],DhcpIface.client_id[8]);
741
syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
749
if ( execve(Cfilename,argc,ProgramEnviron) )
750
syslog(LOG_ERR,"error executing \"%s\": %m\n",
755
if ( DhcpIface.ciaddr == prev_ip_addr )
756
execute_on_change("up");
757
else /* IP address has changed */
759
execute_on_change("new");
760
prev_ip_addr=DhcpIface.ciaddr;
762
if ( *(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime] == 0xffffffff )
764
syslog(LOG_INFO,"infinite IP address lease time. Exiting\n");
769
/*****************************************************************************/