~ubuntu-branches/ubuntu/trusty/dhcpcd/trusty-security

« back to all changes in this revision

Viewing changes to dhcpconfig.c

  • Committer: Bazaar Package Importer
  • Author(s): Simon Kelley
  • Date: 2005-09-30 02:21:51 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050930022151-vq3xlcazj0bdpyf4
Tags: 1:2.0.0-2
Clear out /etc/dhcpc/resolv.conf and /var/lib/dhcpc/* 
during purge. (closes: #330515)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
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>
5
 
 *
6
 
 * dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
7
 
 *
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.
12
 
 *
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.
17
 
 *
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.
21
 
 */
22
 
 
23
 
#include <sys/types.h>
24
 
#include <sys/socket.h>
25
 
#include <sys/ioctl.h>
26
 
#include <sys/stat.h>
27
 
#include <netinet/in.h>
28
 
#include <net/route.h>
29
 
#include <net/if.h>
30
 
#include <arpa/nameser.h>
31
 
#include <fcntl.h>
32
 
#include <stdio.h>
33
 
#include <string.h>
34
 
#include <syslog.h>
35
 
#include <errno.h>
36
 
#include <stdlib.h>
37
 
#include <unistd.h>
38
 
#include <resolv.h>
39
 
#include <netdb.h>
40
 
#include "kversion.h"
41
 
#include "pathnames.h"
42
 
#include "client.h"
43
 
 
44
 
extern  int                     dhcpSocket;
45
 
extern  int                     prev_ip_addr;
46
 
extern  int                     Window;
47
 
extern  int                     SetDHCPDefaultRoutes;
48
 
extern  int                     TestCase;
49
 
extern  int                     DebugFlag;
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;
63
 
 
64
 
int     arpInform();
65
 
 
66
 
char    hostinfo_file[128];
67
 
int     resolv_renamed=0; 
68
 
int     yp_renamed=0;
69
 
int     ntp_renamed=0;  
70
 
int     have_info=0; /* set once we have written the hostinfo file */
71
 
 
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;
77
 
 
78
 
/*****************************************************************************/
79
 
char *cleanmetas(cstr) /* this is to clean single quotes out of DHCP strings */
80
 
char *cstr;             /* replace single quotes with space */
81
 
{
82
 
  register char *c=cstr;
83
 
  do
84
 
    if ( *c == 39 ) *c = ' ';
85
 
  while ( *c++ );
86
 
  return cstr;
87
 
}
88
 
 
89
 
/*****************************************************************************/
90
 
void execute_on_change(prm)
91
 
char *prm;
92
 
{
93
 
  if (!have_info)
94
 
    return;
95
 
  
96
 
#ifdef EMBED
97
 
  if ( vfork() == 0 )
98
 
#else
99
 
  if ( fork() == 0 )
100
 
#endif
101
 
    {
102
 
      char *argc[5],exec_on_change[128];
103
 
      if ( Cfilename )
104
 
        snprintf(exec_on_change,sizeof(exec_on_change),Cfilename);
105
 
      else
106
 
        snprintf(exec_on_change,sizeof(exec_on_change),EXEC_ON_CHANGE,ConfigDir);
107
 
      argc[0]=exec_on_change;
108
 
      argc[1]=hostinfo_file;
109
 
      argc[2]=prm;
110
 
      if ( DebugFlag )
111
 
        argc[3]="-d";
112
 
      else
113
 
        argc[3]=NULL;
114
 
      argc[4]=NULL;
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);
118
 
      exit(0);
119
 
    }
120
 
}
121
 
/*****************************************************************************/
122
 
unsigned long getgenmask(ip_in)         /* this is to guess genmask     */
123
 
unsigned long ip_in;                    /* from network address         */
124
 
{
125
 
  unsigned long t,p=ntohl(ip_in);
126
 
  if ( IN_CLASSA(p) )
127
 
    t= ~IN_CLASSA_NET;
128
 
  else
129
 
    {
130
 
      if ( IN_CLASSB(p) )
131
 
        t= ~IN_CLASSB_NET;
132
 
      else
133
 
        {
134
 
          if ( IN_CLASSC(p) )
135
 
            t= ~IN_CLASSC_NET;
136
 
          else
137
 
            t=0;
138
 
        }
139
 
    }
140
 
  while ( t&p ) t>>=1;
141
 
  return htonl(~t);
142
 
}
143
 
/*****************************************************************************/
144
 
int setDefaultRoute(route_addr)
145
 
char *route_addr;
146
 
{
147
 
struct  rtentry         rtent;
148
 
struct  sockaddr_in     *p;
149
 
 
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;
162
 
#else
163
 
  rtent.rt_dev          =       IfNameExt;
164
 
#endif
165
 
rtent.rt_metric         =       1;
166
 
rtent.rt_window         =       Window;
167
 
rtent.rt_flags          =       RTF_UP|RTF_GATEWAY|(Window ? RTF_WINDOW : 0);
168
 
if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) == -1 )
169
 
  {
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;
184
 
#else
185
 
        rtent.rt_dev            =       IfNameExt;
186
 
#endif
187
 
        rtent.rt_metric     =     0;
188
 
        rtent.rt_flags      =     RTF_UP|RTF_HOST;
189
 
        if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) == 0 )
190
 
          {
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;
203
 
#else
204
 
            rtent.rt_dev        =       IfNameExt;
205
 
#endif
206
 
            rtent.rt_metric     =       1;
207
 
            rtent.rt_window     =       Window;
208
 
            rtent.rt_flags      =       RTF_UP|RTF_GATEWAY|(Window ? RTF_WINDOW : 0);
209
 
            if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) == -1 )
210
 
              {
211
 
                syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
212
 
                return -1;
213
 
              }
214
 
          }
215
 
      }
216
 
    else
217
 
      {
218
 
        syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
219
 
        return -1;
220
 
      }
221
 
  }
222
 
return 0;
223
 
}
224
 
/*****************************************************************************/
225
 
int dhcpConfig()
226
 
{
227
 
  int i;
228
 
  FILE *f;
229
 
  char hostinfo_file_old[128];
230
 
  struct ifreq          ifr;
231
 
  struct rtentry        rtent;
232
 
#ifdef OLD_LINUX_VERSION
233
 
  struct sockaddr_pkt   sap;
234
 
#endif
235
 
  struct sockaddr_in    *p = (struct sockaddr_in *)&(ifr.ifr_addr);
236
 
  struct hostent *hp=NULL;
237
 
  char *dname=NULL;
238
 
  int dname_len=0;
239
 
 
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);
244
 
#else
245
 
  memcpy(ifr.ifr_name,IfNameExt,IfNameExt_len);
246
 
#endif
247
 
  p->sin_family = AF_INET;
248
 
  p->sin_addr.s_addr = DhcpIface.ciaddr;
249
 
  if ( ioctl(dhcpSocket,SIOCSIFADDR,&ifr) == -1 )  /* setting IP address */
250
 
    {
251
 
      syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFADDR: %m\n");
252
 
      return -1;
253
 
    }
254
 
  memcpy(&p->sin_addr.s_addr,DhcpOptions.val[subnetMask],4);
255
 
  if ( ioctl(dhcpSocket,SIOCSIFNETMASK,&ifr) == -1 )  /* setting netmask */
256
 
    {
257
 
      p->sin_addr.s_addr = 0xffffffff; /* try 255.255.255.255 */
258
 
      if ( ioctl(dhcpSocket,SIOCSIFNETMASK,&ifr) == -1 )
259
 
        {
260
 
          syslog(LOG_ERR,"dhcpConfig: ioctl SIOCSIFNETMASK: %m\n");
261
 
          return -1;
262
 
        }
263
 
    }
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");
267
 
 
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;
282
 
  rtent.rt_metric       =       1;
283
 
  rtent.rt_flags        =       RTF_UP;
284
 
  if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) )
285
 
    syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
286
 
#endif
287
 
 
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;
305
 
 
306
 
#ifdef OLD_LINUX_VERSION
307
 
      rtent.rt_dev            =   IfName;
308
 
#else
309
 
      rtent.rt_dev            =   IfNameExt;
310
 
#endif
311
 
      rtent.rt_metric     =       1;
312
 
      if ( ioctl(dhcpSocket,SIOCADDRT,&rtent) )
313
 
        syslog(LOG_ERR,"dhcpConfig: ioctl SIOCADDRT: %m\n");
314
 
    }
315
 
 
316
 
  if ( SetDHCPDefaultRoutes )
317
 
    {
318
 
      if ( DhcpOptions.len[routersOnSubnet] > 3 )
319
 
        for (i=0;i<DhcpOptions.len[routersOnSubnet];i+=4)
320
 
          setDefaultRoute(DhcpOptions.val[routersOnSubnet]);
321
 
    }
322
 
  else
323
 
    if ( default_router.s_addr > 0 ) setDefaultRoute((char *)&(default_router.s_addr));
324
 
 
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");
333
 
#endif  
334
 
 
335
 
  arpInform();
336
 
  if ( DebugFlag )
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 )
343
 
    {
344
 
      resolv_renamed=1+rename(RESOLV_CONF,""RESOLV_CONF".sv");
345
 
      f=fopen(RESOLV_CONF,"w");
346
 
      if ( f )
347
 
        {
348
 
          int i;
349
 
#if 0
350
 
          if ( DhcpOptions.len[nisDomainName] )
351
 
            fprintf(f,"domain %s\n",(char *)DhcpOptions.val[nisDomainName]);
352
 
          else
353
 
            if ( DhcpOptions.len[domainName] )
354
 
              fprintf(f,"domain %s\n",(char *)DhcpOptions.val[domainName]);
355
 
#endif
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]);
362
 
#if 0
363
 
          if ( DhcpOptions.len[nisDomainName] + DhcpOptions.len[domainName] )
364
 
            {
365
 
              fprintf(f,"search");
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]);
370
 
              fprintf(f,"\n");
371
 
            }
372
 
#else
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]);
377
 
#endif
378
 
          fclose(f);
379
 
        }
380
 
      else
381
 
        syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
382
 
 
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 */
389
 
      (void)res_init();
390
 
    }
391
 
  if ( ReplNISConf )
392
 
    {
393
 
      yp_renamed=1+rename(NIS_CONF,""NIS_CONF".sv");
394
 
      f=fopen(NIS_CONF,"w");
395
 
      if ( f )
396
 
        {
397
 
          int i;
398
 
          char *domain=NULL;
399
 
          if ( DhcpOptions.len[nisDomainName] )
400
 
            domain=(char *)DhcpOptions.val[nisDomainName];
401
 
          else
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"));
411
 
          fclose(f);
412
 
        }
413
 
      else
414
 
        syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
415
 
    }
416
 
  if ( ReplNTPConf )
417
 
    {
418
 
      ntp_renamed=1+rename(NTP_CONF,""NTP_CONF".sv");
419
 
      f=fopen(NTP_CONF,"w");
420
 
      if ( f )
421
 
        {
422
 
          int net, mask;
423
 
          memcpy(&mask,DhcpOptions.val[subnetMask],4);
424
 
          net = DhcpIface.ciaddr & mask;
425
 
 
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 )
439
 
            {
440
 
              int i;
441
 
              char addr[4*3+3*1+1];
442
 
              for (i=0;i<DhcpOptions.len[ntpServers];i+=4)
443
 
                {
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);
450
 
                }
451
 
            }
452
 
          else
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");
456
 
            }
457
 
          fprintf(f, "driftfile /etc/ntp.drift\n");
458
 
          fprintf(f, "logfile /var/log/ntp.log\n");
459
 
          fclose(f);
460
 
        }
461
 
       else
462
 
        syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
463
 
     }
464
 
  if ( SetHostName )
465
 
    {
466
 
      if ( ! DhcpOptions.len[hostName] )
467
 
        {
468
 
          hp=gethostbyaddr((char *)&DhcpIface.ciaddr,
469
 
          sizeof(DhcpIface.ciaddr),AF_INET);
470
 
          if ( hp )
471
 
            {
472
 
              dname=hp->h_name;
473
 
              while ( *dname > 32 )
474
 
#if 0
475
 
                if ( *dname == '.' )
476
 
                  break;
477
 
                else
478
 
#endif
479
 
                  dname++;
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;
486
 
              DhcpOptions.num++;
487
 
            }
488
 
        }
489
 
      if ( InitialHostName_len<0 && gethostname(InitialHostName,sizeof(InitialHostName))==0 )
490
 
        {
491
 
          InitialHostName_len=strlen(InitialHostName);
492
 
          if ( DebugFlag )
493
 
            fprintf(stdout,"dhcpcd: orig hostname = %s\n",InitialHostName);
494
 
        }
495
 
      if ( DhcpOptions.len[hostName] )
496
 
        {
497
 
          sethostname(DhcpOptions.val[hostName],DhcpOptions.len[hostName]);
498
 
          if ( DebugFlag )
499
 
            fprintf(stdout,"dhcpcd: your hostname = %s\n",
500
 
            (char *)DhcpOptions.val[hostName]);
501
 
        }
502
 
    }
503
 
  if ( SetDomainName )
504
 
    {
505
 
      if ( InitialDomainName_len<0 && getdomainname(InitialDomainName,sizeof(InitialDomainName))==0 )
506
 
        {
507
 
          InitialDomainName_len=strlen(InitialDomainName);
508
 
          if ( DebugFlag )
509
 
            fprintf(stdout,"dhcpcd: orig domainname = %s\n",InitialDomainName);
510
 
        }
511
 
#if 0
512
 
      if ( DhcpOptions.len[nisDomainName] )
513
 
        {
514
 
          setdomainname(DhcpOptions.val[nisDomainName],
515
 
                      DhcpOptions.len[nisDomainName]);
516
 
          if ( DebugFlag )
517
 
            fprintf(stdout,"dhcpcd: your domainname = %s\n",
518
 
                (char *)DhcpOptions.val[nisDomainName]);
519
 
        }
520
 
      else
521
 
        {
522
 
#endif
523
 
          if ( ! DhcpOptions.len[domainName] )
524
 
            {
525
 
              if ( ! hp )
526
 
                hp=gethostbyaddr((char *)&DhcpIface.ciaddr,
527
 
                sizeof(DhcpIface.ciaddr),AF_INET);
528
 
              if ( hp )
529
 
                {
530
 
                  dname=hp->h_name;
531
 
                  while ( *dname > 32 )
532
 
                    if ( *dname == '.' )
533
 
                      {
534
 
                        dname++;
535
 
                        break;
536
 
                      }
537
 
                    else
538
 
                      dname++;
539
 
                  dname_len=strlen(dname);
540
 
                  if ( dname_len )
541
 
                    {
542
 
                      DhcpOptions.val[domainName]=(char *)malloc(dname_len+1);
543
 
                      DhcpOptions.len[domainName]=dname_len;
544
 
                      memcpy((char *)DhcpOptions.val[domainName],
545
 
                      dname,dname_len);
546
 
                      ((char *)DhcpOptions.val[domainName])[dname_len]=0;
547
 
                      DhcpOptions.num++;
548
 
                    }
549
 
                }
550
 
            }
551
 
          if ( DhcpOptions.len[domainName] )
552
 
            {
553
 
              setdomainname(DhcpOptions.val[domainName],
554
 
                DhcpOptions.len[domainName]);
555
 
              if ( DebugFlag )
556
 
                fprintf(stdout,"dhcpcd: your domainname = %s\n",
557
 
                (char *)DhcpOptions.val[domainName]);
558
 
            }
559
 
#if 0
560
 
        }
561
 
#endif
562
 
    }
563
 
tsc:
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);
568
 
  if ( i == -1 ||
569
 
      write(i,(char *)&DhcpIface,sizeof(dhcpInterface)) == -1 ||
570
 
      close(i) == -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");
576
 
  if ( f )
577
 
    {
578
 
      int b,c;
579
 
      memcpy(&b,DhcpOptions.val[subnetMask],4);
580
 
      c = DhcpIface.ciaddr & b;
581
 
      fprintf(f,"\
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 )
603
 
        {
604
 
          fprintf(f,"\
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]);
616
 
        }
617
 
if ( DhcpOptions.len[staticRoute] )
618
 
  {
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]);
638
 
  }
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]));
647
 
fprintf(f,"\n\
648
 
DNS=%u.%u.%u.%u",
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 )
662
 
  {
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]);
674
 
  }
675
 
if ( DhcpOptions.len[nisServers]>=4 )
676
 
  {
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]);
688
 
  }
689
 
fprintf(f,"\n\
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\
695
 
DHCPSNAME=\'%s\'\n\
696
 
LEASETIME=%u\n\
697
 
RENEWALTIME=%u\n\
698
 
REBINDTIME=%u\n\
699
 
INTERFACE=\'%s\'\n\
700
 
CLASSID=\'%s\'\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],
713
 
ClientHwAddr[0],
714
 
ClientHwAddr[1],
715
 
ClientHwAddr[2],
716
 
ClientHwAddr[3],
717
 
ClientHwAddr[4],
718
 
ClientHwAddr[5],
719
 
DhcpIface.shaddr[0],
720
 
DhcpIface.shaddr[1],
721
 
DhcpIface.shaddr[2],
722
 
DhcpIface.shaddr[3],
723
 
DhcpIface.shaddr[4],
724
 
DhcpIface.shaddr[5],
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]),
729
 
IfNameExt,
730
 
DhcpIface.class_id);
731
 
      if ( ClientID )
732
 
        fprintf(f,"CLIENTID=\'%s\'\n",ClientID);
733
 
      else
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]);
737
 
      fclose(f);
738
 
      have_info = 1;
739
 
    }
740
 
  else
741
 
    syslog(LOG_ERR,"dhcpConfig: fopen: %m\n");
742
 
#if 0
743
 
  if ( Cfilename )
744
 
    if ( fork() == 0 )
745
 
      {
746
 
        char *argc[2];
747
 
        argc[0]=Cfilename;
748
 
        argc[1]=NULL;
749
 
        if ( execve(Cfilename,argc,ProgramEnviron) )
750
 
          syslog(LOG_ERR,"error executing \"%s\": %m\n",
751
 
          Cfilename);
752
 
        exit(0);
753
 
      }
754
 
#endif
755
 
  if ( DhcpIface.ciaddr == prev_ip_addr )
756
 
    execute_on_change("up");
757
 
  else                                  /* IP address has changed */
758
 
    {
759
 
      execute_on_change("new");
760
 
      prev_ip_addr=DhcpIface.ciaddr;
761
 
    }
762
 
  if ( *(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime] == 0xffffffff )
763
 
    {
764
 
      syslog(LOG_INFO,"infinite IP address lease time. Exiting\n");
765
 
      exit(0);
766
 
    }
767
 
  return 0;
768
 
}
769
 
/*****************************************************************************/