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

« back to all changes in this revision

Viewing changes to client.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/stat.h>
26
 
#include <sys/ioctl.h>
27
 
#include <sys/time.h>
28
 
#include <sys/utsname.h>
29
 
#include <net/if.h>
30
 
#include <net/if_arp.h>
31
 
#ifdef __GLIBC__
32
 
#include <net/if_packet.h>
33
 
#else
34
 
#include <linux/if_packet.h>
35
 
#endif
36
 
#include <net/route.h>
37
 
#include <fcntl.h>
38
 
#include <stdio.h>
39
 
#include <stdlib.h>
40
 
#include <string.h>
41
 
#include <unistd.h>
42
 
#include <syslog.h>
43
 
#include <errno.h>
44
 
#include <setjmp.h>
45
 
#include <time.h>
46
 
#include "client.h"
47
 
#include "buildmsg.h"
48
 
#include "udpipgen.h"
49
 
#include "pathnames.h"
50
 
#include "kversion.h"
51
 
 
52
 
extern  char            *ProgramName;
53
 
extern  char            *IfName,*IfNameExt;
54
 
extern  int             IfName_len,IfNameExt_len;
55
 
extern  char            *HostName;
56
 
extern  unsigned char   *ClassID;
57
 
extern  int             ClassID_len;
58
 
extern  unsigned char   *ClientID;
59
 
extern  int             ClientID_len;
60
 
extern  int             DebugFlag;
61
 
extern  int             BeRFC1541;
62
 
extern  unsigned        LeaseTime;
63
 
extern  int             SetDomainName;
64
 
extern  int             SetHostName;
65
 
extern  int             SendSecondDiscover;
66
 
extern  unsigned short  ip_id;
67
 
extern  void            *(*currState)();
68
 
extern  time_t          TimeOut;
69
 
extern  unsigned        nleaseTime;
70
 
extern  struct in_addr  inform_ipaddr;
71
 
extern  int             DoCheckSum;
72
 
extern  int             TestCase;
73
 
extern  int             resolv_renamed,yp_renamed,ntp_renamed;
74
 
extern  int             InitialHostName_len,InitialDomainName_len;
75
 
extern  char            *InitialHostName,*InitialDomainName;
76
 
 
77
 
#if 0
78
 
extern  unsigned char   ClientMACaddr[ETH_ALEN];
79
 
extern  int             ClientMACaddr_ind;
80
 
#endif
81
 
 
82
 
#ifdef ARPCHECK
83
 
int arpCheck();
84
 
#endif
85
 
int     arpRelease();
86
 
int     dhcpConfig();
87
 
int     readDhcpCache();
88
 
int     deleteDhcpCache();
89
 
void    execute_on_change(char *prm);
90
 
 
91
 
int                     dhcpSocket;
92
 
int                     udpFooSocket;
93
 
int                     prev_ip_addr;
94
 
time_t                  ReqSentTime;
95
 
dhcpOptions             DhcpOptions;
96
 
dhcpInterface           DhcpIface;
97
 
udpipMessage            UdpIpMsgSend,UdpIpMsgRecv;
98
 
jmp_buf                 env;
99
 
unsigned char           ClientHwAddr[ETH_ALEN];
100
 
 
101
 
const struct ip *ipSend=(struct ip *)((struct udpiphdr *)UdpIpMsgSend.udpipmsg)->ip;
102
 
const struct ip *ipRecv=(struct ip *)((struct udpiphdr *)UdpIpMsgRecv.udpipmsg)->ip;
103
 
const dhcpMessage *DhcpMsgSend = (dhcpMessage *)&UdpIpMsgSend.udpipmsg[sizeof(udpiphdr)];
104
 
      dhcpMessage *DhcpMsgRecv = (dhcpMessage *)&UdpIpMsgRecv.udpipmsg[sizeof(udpiphdr)];
105
 
 
106
 
static short int saved_if_flags = 0;
107
 
int     TokenRingIf     =       0;
108
 
/*****************************************************************************/
109
 
/* Decode an RFC3397 DNS search order option into a space
110
 
   seperated string. Returns length of string (including 
111
 
   terminating zero) or zero on error. out may be NULL
112
 
   to just determine output length. */
113
 
 
114
 
static unsigned int decodeSearch(u_char *p, int len, u_char *out)
115
 
{
116
 
  u_char *r, *q = p;
117
 
  unsigned int count = 0, l, hops;
118
 
 
119
 
  while (q - p < len)
120
 
    {
121
 
      r = NULL;
122
 
      hops = 0;
123
 
      while ((l = *q++))
124
 
        {
125
 
          unsigned int label_type = l & 0xc0;
126
 
          if (label_type == 0x80 || label_type == 0x40)
127
 
            return 0;
128
 
          else if (label_type == 0xc0) /* pointer */
129
 
            { 
130
 
              l = (l&0x3f) << 8;
131
 
              l |= *q++;
132
 
              
133
 
              /* save source of first jump. */
134
 
              if (!r)
135
 
                r = q;
136
 
 
137
 
              hops++;
138
 
              if (hops > 255)
139
 
                return 0;
140
 
              q = p + l;
141
 
              if (q - p >= len)
142
 
                return 0;
143
 
            }
144
 
          else 
145
 
            {
146
 
              /* straightforward name segment, add with '.' */
147
 
              count += l+1;
148
 
              if (out)
149
 
                {
150
 
                  memcpy(out, q, l);
151
 
                  out += l;
152
 
                  *out++ = '.';
153
 
                }
154
 
              q += l;
155
 
            }
156
 
        }
157
 
 
158
 
      /* change last dot to space */
159
 
      if (out)
160
 
        *(out-1) = ' ';
161
 
 
162
 
      if (r)
163
 
        q = r;
164
 
    }
165
 
 
166
 
  /* change last space to zero terminator */
167
 
  if (out)
168
 
    *(out-1) = 0;
169
 
 
170
 
  return count;  
171
 
}
172
 
 
173
 
int parseDhcpMsgRecv() /* this routine parses dhcp message received */
174
 
{
175
 
#ifdef DEBUG
176
 
  int i,j;
177
 
#endif
178
 
  register u_char *p = DhcpMsgRecv->options+4;
179
 
  unsigned char *end = DhcpMsgRecv->options+sizeof(DhcpMsgRecv->options);
180
 
 
181
 
  /* Force T1 and T2 to 0: either new values will be in message, or they
182
 
     will need to be recalculated from lease time */
183
 
  if ( DhcpOptions.val[dhcpT1value] && DhcpOptions.len[dhcpT1value] > 0 )
184
 
    memset(DhcpOptions.val[dhcpT1value],0,DhcpOptions.len[dhcpT1value]);
185
 
  if ( DhcpOptions.val[dhcpT2value] && DhcpOptions.len[dhcpT2value] > 0 )
186
 
    memset(DhcpOptions.val[dhcpT2value],0,DhcpOptions.len[dhcpT2value]);
187
 
  while ( p < end )
188
 
    switch ( *p )
189
 
      {
190
 
        case endOption: goto swend;
191
 
        case padOption: p++; break;
192
 
        case dnsSearchPath:
193
 
          {
194
 
            unsigned int len;
195
 
            
196
 
            if (p + 2 + p[1] >= end)
197
 
              goto swend; /* corrupt packet */
198
 
 
199
 
            if (len = decodeSearch(p+2, p[1], NULL))
200
 
              {
201
 
                if ( DhcpOptions.val[*p] )
202
 
                  free(DhcpOptions.val[*p]);
203
 
                DhcpOptions.val[*p] = malloc(len);
204
 
                DhcpOptions.len[*p] = len;
205
 
                decodeSearch(p+2, p[1], DhcpOptions.val[*p]);
206
 
              }
207
 
            p += p[1]+2;
208
 
            break;
209
 
          }
210
 
 
211
 
        default:
212
 
          if ( p[1] )
213
 
            {
214
 
              if (p + 2 + p[1] >= end)
215
 
              goto swend; /* corrupt packet */
216
 
              
217
 
              if ( DhcpOptions.len[*p] == p[1] )
218
 
                memcpy(DhcpOptions.val[*p],p+2,p[1]);
219
 
              else
220
 
                {
221
 
                  DhcpOptions.len[*p] = p[1];
222
 
                  if ( DhcpOptions.val[*p] )
223
 
                    free(DhcpOptions.val[*p]);
224
 
                  else
225
 
                    DhcpOptions.num++;
226
 
                  DhcpOptions.val[*p] = malloc(p[1]+1);
227
 
                  memset(DhcpOptions.val[*p],0,p[1]+1);
228
 
                  memcpy(DhcpOptions.val[*p],p+2,p[1]);
229
 
                }
230
 
            }
231
 
          p+=p[1]+2;
232
 
      }
233
 
swend:
234
 
#ifdef DEBUG
235
 
  fprintf(stderr,"parseDhcpMsgRecv: %d options received:\n",DhcpOptions.num);
236
 
  for (i=1;i<255;i++)
237
 
    if ( DhcpOptions.val[i] )
238
 
      switch ( i )
239
 
        {
240
 
          case 1: /* subnet mask */
241
 
          case 3: /* routers on subnet */
242
 
          case 4: /* time servers */
243
 
          case 5: /* name servers */
244
 
          case 6: /* dns servers */
245
 
          case 28:/* broadcast addr */
246
 
          case 33:/* staticRoute */
247
 
          case 41:/* NIS servers */
248
 
          case 42:/* NTP servers */
249
 
          case 50:/* dhcpRequestdIPaddr */
250
 
          case 54:/* dhcpServerIdentifier */
251
 
            for (j=0;j<DhcpOptions.len[i];j+=4)
252
 
              fprintf(stderr,"i=%-2d  len=%-2d  option = %u.%u.%u.%u\n",
253
 
                i,DhcpOptions.len[i],
254
 
                ((unsigned char *)DhcpOptions.val[i])[0+j],
255
 
                ((unsigned char *)DhcpOptions.val[i])[1+j],
256
 
                ((unsigned char *)DhcpOptions.val[i])[2+j],
257
 
                ((unsigned char *)DhcpOptions.val[i])[3+j]);
258
 
            break;
259
 
          case 2: /* time offset */
260
 
          case 51:/* dhcpAddrLeaseTime */
261
 
          case 57:/* dhcpMaxMsgSize */
262
 
          case 58:/* dhcpT1value */
263
 
          case 59:/* dhcpT2value */
264
 
            fprintf(stderr,"i=%-2d  len=%-2d  option = %d\n",
265
 
                i,DhcpOptions.len[i],
266
 
                    ntohl(*(int *)DhcpOptions.val[i]));
267
 
            break;
268
 
          case 23:/* defaultIPTTL */
269
 
          case 29:/* performMaskdiscovery */
270
 
          case 31:/* performRouterdiscovery */
271
 
          case 53:/* dhcpMessageType */
272
 
            fprintf(stderr,"i=%-2d  len=%-2d  option = %u\n",
273
 
                i,DhcpOptions.len[i],*(unsigned char *)DhcpOptions.val[i]);
274
 
            break;
275
 
          default:
276
 
            fprintf(stderr,"i=%-2d  len=%-2d  option = \"%s\"\n",
277
 
                i,DhcpOptions.len[i],(char *)DhcpOptions.val[i]);
278
 
        }
279
 
fprintf(stderr,"\
280
 
DhcpMsgRecv->yiaddr  = %u.%u.%u.%u\n\
281
 
DhcpMsgRecv->siaddr  = %u.%u.%u.%u\n\
282
 
DhcpMsgRecv->giaddr  = %u.%u.%u.%u\n\
283
 
DhcpMsgRecv->sname   = \"%s\"\n\
284
 
ServerHardwareAddr   = %02X.%02X.%02X.%02X.%02X.%02X\n",
285
 
((unsigned char *)&DhcpMsgRecv->yiaddr)[0],
286
 
((unsigned char *)&DhcpMsgRecv->yiaddr)[1],
287
 
((unsigned char *)&DhcpMsgRecv->yiaddr)[2],
288
 
((unsigned char *)&DhcpMsgRecv->yiaddr)[3],
289
 
((unsigned char *)&DhcpMsgRecv->siaddr)[0],
290
 
((unsigned char *)&DhcpMsgRecv->siaddr)[1],
291
 
((unsigned char *)&DhcpMsgRecv->siaddr)[2],
292
 
((unsigned char *)&DhcpMsgRecv->siaddr)[3],
293
 
((unsigned char *)&DhcpMsgRecv->giaddr)[0],
294
 
((unsigned char *)&DhcpMsgRecv->giaddr)[1],
295
 
((unsigned char *)&DhcpMsgRecv->giaddr)[2],
296
 
((unsigned char *)&DhcpMsgRecv->giaddr)[3],
297
 
DhcpMsgRecv->sname,
298
 
UdpIpMsgRecv.ethhdr.ether_shost[0],
299
 
UdpIpMsgRecv.ethhdr.ether_shost[1],
300
 
UdpIpMsgRecv.ethhdr.ether_shost[2],
301
 
UdpIpMsgRecv.ethhdr.ether_shost[3],
302
 
UdpIpMsgRecv.ethhdr.ether_shost[4],
303
 
UdpIpMsgRecv.ethhdr.ether_shost[5]);
304
 
#endif
305
 
  if ( ! DhcpMsgRecv->yiaddr ) DhcpMsgRecv->yiaddr=DhcpMsgSend->ciaddr;
306
 
  if ( ! DhcpOptions.val[dhcpServerIdentifier] ) /* did not get dhcpServerIdentifier */
307
 
    {   /* make it the same as IP address of the sender */
308
 
      DhcpOptions.val[dhcpServerIdentifier] = malloc(4);
309
 
      memcpy(DhcpOptions.val[dhcpServerIdentifier],&ipRecv->ip_src.s_addr,4);
310
 
      DhcpOptions.len[dhcpServerIdentifier] = 4;
311
 
      DhcpOptions.num++;
312
 
      if ( DebugFlag )
313
 
        syslog(LOG_DEBUG,
314
 
        "dhcpServerIdentifier option is missing in DHCP server response. Assuming %u.%u.%u.%u\n",
315
 
        ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],
316
 
        ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],
317
 
        ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],
318
 
        ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);
319
 
    }
320
 
  if ( ! DhcpOptions.val[dns] ) /* did not get DNS */
321
 
    {   /* make it the same as dhcpServerIdentifier */
322
 
      DhcpOptions.val[dns] = malloc(4);
323
 
      memcpy(DhcpOptions.val[dns],DhcpOptions.val[dhcpServerIdentifier],4);
324
 
      DhcpOptions.len[dns] = 4;
325
 
      DhcpOptions.num++;
326
 
      if ( DebugFlag )
327
 
        syslog(LOG_DEBUG,
328
 
        "dns option is missing in DHCP server response. Assuming %u.%u.%u.%u\n",
329
 
        ((unsigned char *)DhcpOptions.val[dns])[0],
330
 
        ((unsigned char *)DhcpOptions.val[dns])[1],
331
 
        ((unsigned char *)DhcpOptions.val[dns])[2],
332
 
        ((unsigned char *)DhcpOptions.val[dns])[3]);
333
 
    }
334
 
  if ( ! DhcpOptions.val[subnetMask] ) /* did not get subnetMask */
335
 
    {
336
 
      DhcpOptions.val[subnetMask] = malloc(4);
337
 
      ((unsigned char *)DhcpOptions.val[subnetMask])[0] = 255;
338
 
#if 0
339
 
      if ( ((unsigned char *)&DhcpMsgRecv->yiaddr)[0] < 128 )
340
 
#else
341
 
      if ( IN_CLASSA(ntohl(DhcpMsgRecv->yiaddr)) )
342
 
#endif
343
 
        {
344
 
          ((unsigned char *)DhcpOptions.val[subnetMask])[1] = 0; /* class A */
345
 
          ((unsigned char *)DhcpOptions.val[subnetMask])[2] = 0;
346
 
          ((unsigned char *)DhcpOptions.val[subnetMask])[3] = 0;
347
 
        }
348
 
      else
349
 
        {
350
 
          ((unsigned char *)DhcpOptions.val[subnetMask])[1] = 255;
351
 
#if 0
352
 
          if ( ((unsigned char *)&DhcpMsgRecv->yiaddr)[0] < 192 )
353
 
#else
354
 
          if ( IN_CLASSB(ntohl(DhcpMsgRecv->yiaddr)) )
355
 
#endif
356
 
            {
357
 
              ((unsigned char *)DhcpOptions.val[subnetMask])[2] = 0;/* class B */
358
 
              ((unsigned char *)DhcpOptions.val[subnetMask])[3] = 0;
359
 
            }
360
 
          else
361
 
            {
362
 
              ((unsigned char *)DhcpOptions.val[subnetMask])[2] = 255;
363
 
              if ( IN_CLASSC(ntohl(DhcpMsgRecv->yiaddr)) )
364
 
                ((unsigned char *)DhcpOptions.val[subnetMask])[3] = 0; /* class C */
365
 
              else
366
 
                ((unsigned char *)DhcpOptions.val[subnetMask])[3] = 255;
367
 
            }
368
 
        }
369
 
      DhcpOptions.len[subnetMask] = 4;
370
 
      DhcpOptions.num++;
371
 
      if ( DebugFlag )
372
 
        syslog(LOG_DEBUG,
373
 
        "subnetMask option is missing in DHCP server response. Assuming %u.%u.%u.%u\n",
374
 
        ((unsigned char *)DhcpOptions.val[subnetMask])[0],
375
 
        ((unsigned char *)DhcpOptions.val[subnetMask])[1],
376
 
        ((unsigned char *)DhcpOptions.val[subnetMask])[2],
377
 
        ((unsigned char *)DhcpOptions.val[subnetMask])[3]);
378
 
    }
379
 
  if ( ! DhcpOptions.val[broadcastAddr] ) /* did not get broadcastAddr */
380
 
    {
381
 
      int br = DhcpMsgRecv->yiaddr | ~*((int *)DhcpOptions.val[subnetMask]);
382
 
      DhcpOptions.val[broadcastAddr] = malloc(4);
383
 
      memcpy(DhcpOptions.val[broadcastAddr],&br,4);
384
 
      DhcpOptions.len[broadcastAddr] = 4;
385
 
      DhcpOptions.num++;
386
 
      if ( DebugFlag )
387
 
        syslog(LOG_DEBUG,
388
 
        "broadcastAddr option is missing in DHCP server response. Assuming %u.%u.%u.%u\n",
389
 
        ((unsigned char *)DhcpOptions.val[broadcastAddr])[0],
390
 
        ((unsigned char *)DhcpOptions.val[broadcastAddr])[1],
391
 
        ((unsigned char *)DhcpOptions.val[broadcastAddr])[2],
392
 
        ((unsigned char *)DhcpOptions.val[broadcastAddr])[3]);
393
 
    }
394
 
#if 0
395
 
  if ( ! DhcpOptions.val[routersOnSubnet] )
396
 
    {
397
 
      DhcpOptions.val[routersOnSubnet] = malloc(4);
398
 
      if ( DhcpMsgRecv->giaddr )
399
 
        memcpy(DhcpOptions.val[routersOnSubnet],&DhcpMsgRecv->giaddr,4);
400
 
      else
401
 
        memcpy(DhcpOptions.val[routersOnSubnet],DhcpOptions.val[dhcpServerIdentifier],4);
402
 
      DhcpOptions.len[routersOnSubnet] = 4;
403
 
      DhcpOptions.num++;
404
 
      if ( DebugFlag )
405
 
        syslog(LOG_DEBUG,
406
 
        "routersOnSubnet option is missing in DHCP server response. Assuming %u.%u.%u.%u\n",
407
 
        ((unsigned char *)DhcpOptions.val[routersOnSubnet])[0],
408
 
        ((unsigned char *)DhcpOptions.val[routersOnSubnet])[1],
409
 
        ((unsigned char *)DhcpOptions.val[routersOnSubnet])[2],
410
 
        ((unsigned char *)DhcpOptions.val[routersOnSubnet])[3]);
411
 
    }
412
 
#endif
413
 
  if ( DhcpOptions.val[dhcpIPaddrLeaseTime] && DhcpOptions.len[dhcpIPaddrLeaseTime] == 4 )
414
 
    {
415
 
      if ( *(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime] == 0 )
416
 
        {
417
 
          memcpy(DhcpOptions.val[dhcpIPaddrLeaseTime],&nleaseTime,4);
418
 
          if ( DebugFlag )
419
 
            syslog(LOG_DEBUG,"dhcpIPaddrLeaseTime=0 in DHCP server response. Assuming %u sec\n",LeaseTime);
420
 
        }
421
 
      else
422
 
        if ( DebugFlag )
423
 
          syslog(LOG_DEBUG,"dhcpIPaddrLeaseTime=%u in DHCP server response.\n",
424
 
          ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime]));
425
 
    }
426
 
  else /* did not get dhcpIPaddrLeaseTime */
427
 
    {
428
 
      DhcpOptions.val[dhcpIPaddrLeaseTime] = malloc(4);
429
 
      memcpy(DhcpOptions.val[dhcpIPaddrLeaseTime],&nleaseTime,4);
430
 
      DhcpOptions.len[dhcpIPaddrLeaseTime] = 4;
431
 
      DhcpOptions.num++;
432
 
      if ( DebugFlag )
433
 
        syslog(LOG_DEBUG,"dhcpIPaddrLeaseTime option is missing in DHCP server response. Assuming %u sec\n",LeaseTime);
434
 
    }
435
 
  if ( DhcpOptions.val[dhcpT1value] && DhcpOptions.len[dhcpT1value] == 4 )
436
 
    {
437
 
      if ( *(unsigned int *)DhcpOptions.val[dhcpT1value] == 0 )
438
 
        {
439
 
          unsigned t2 = 0.5*ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime]);
440
 
          int t1 = htonl(t2);
441
 
          memcpy(DhcpOptions.val[dhcpT1value],&t1,4);
442
 
          DhcpOptions.len[dhcpT1value] = 4;
443
 
          if ( DebugFlag )
444
 
            syslog(LOG_DEBUG,"dhcpT1value is missing in DHCP server response. Assuming %u sec\n",t2);
445
 
        }
446
 
    }
447
 
  else          /* did not get T1 */
448
 
    {
449
 
      unsigned t2 = 0.5*ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime]);
450
 
      int t1 = htonl(t2);
451
 
      DhcpOptions.val[dhcpT1value] = malloc(4);
452
 
      memcpy(DhcpOptions.val[dhcpT1value],&t1,4);
453
 
      DhcpOptions.len[dhcpT1value] = 4;
454
 
      DhcpOptions.num++;
455
 
      if ( DebugFlag )
456
 
        syslog(LOG_DEBUG,"dhcpT1value is missing in DHCP server response. Assuming %u sec\n",t2);
457
 
    }
458
 
  if ( DhcpOptions.val[dhcpT2value] && DhcpOptions.len[dhcpT2value] == 4 )
459
 
    {
460
 
      if ( *(unsigned int *)DhcpOptions.val[dhcpT2value] == 0 )
461
 
        {
462
 
          unsigned t2 = 0.875*ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime]);
463
 
          int t1 = htonl(t2);
464
 
          memcpy(DhcpOptions.val[dhcpT2value],&t1,4);
465
 
          DhcpOptions.len[dhcpT2value] = 4;
466
 
          if ( DebugFlag )
467
 
            syslog(LOG_DEBUG,"dhcpT2value is missing in DHCP server response. Assuming %u sec\n",t2);
468
 
        }
469
 
    }
470
 
  else          /* did not get T2 */
471
 
    {
472
 
      unsigned t2 = 0.875*ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime]);
473
 
      int t1 = htonl(t2);
474
 
      DhcpOptions.val[dhcpT2value] = malloc(4);
475
 
      memcpy(DhcpOptions.val[dhcpT2value],&t1,4);
476
 
      DhcpOptions.len[dhcpT2value] = 4;
477
 
      DhcpOptions.num++;
478
 
      if ( DebugFlag )
479
 
        syslog(LOG_DEBUG,"dhcpT2value is missing in DHCP server response. Assuming %u sec\n",t2);
480
 
    }
481
 
  if ( DhcpOptions.val[dhcpMessageType] )
482
 
    return *(unsigned char *)DhcpOptions.val[dhcpMessageType];
483
 
  return 0;
484
 
}
485
 
/*****************************************************************************/
486
 
void classIDsetup()
487
 
{
488
 
  struct utsname sname;
489
 
  if ( uname(&sname) ) syslog(LOG_ERR,"classIDsetup: uname: %m\n");
490
 
  DhcpIface.class_len=snprintf(DhcpIface.class_id,CLASS_ID_MAX_LEN,
491
 
  "%s %s %s",sname.sysname,sname.release,sname.machine);
492
 
}
493
 
/*****************************************************************************/
494
 
void clientIDsetup()
495
 
{
496
 
  unsigned char *c = DhcpIface.client_id;
497
 
  *c++ = dhcpClientIdentifier;
498
 
  if ( ClientID )
499
 
    {
500
 
      *c++ = ClientID_len + 1;  /* 1 for the field below */
501
 
      *c++ = 0;                 /* type: string */
502
 
      memcpy(c,ClientID,ClientID_len);
503
 
      DhcpIface.client_len = ClientID_len + 3;
504
 
      return;
505
 
    }
506
 
  *c++ = ETH_ALEN + 1;          /* length: 6 (MAC Addr) + 1 (# field) */
507
 
  *c++ = (TokenRingIf) ? ARPHRD_IEEE802_TR : ARPHRD_ETHER;      /* type: Ethernet address */
508
 
#if 0
509
 
  memcpy(c,DhcpIface.chaddr,ETH_ALEN);
510
 
#else
511
 
  memcpy(c,ClientHwAddr,ETH_ALEN);
512
 
#endif
513
 
  DhcpIface.client_len = ETH_ALEN + 3;
514
 
}
515
 
/*****************************************************************************/
516
 
void releaseDhcpOptions()
517
 
{
518
 
  register int i;
519
 
  for (i=1;i<256;i++)
520
 
    if ( DhcpOptions.val[i] ) free(DhcpOptions.val[i]);
521
 
  memset(&DhcpOptions,0,sizeof(dhcpOptions));
522
 
}
523
 
/*****************************************************************************/
524
 
#ifdef DEBUG
525
 
static void dumpframe(const char *title, struct packed_ether_header *frame)
526
 
{
527
 
  int i;
528
 
  unsigned char *dp;
529
 
 
530
 
  printf("%s:", title);
531
 
  dp = (unsigned char *)frame;
532
 
  for (i = 0; i < 32; i++)
533
 
    {
534
 
      if ((i % 16) == 0)
535
 
        printf("\n");
536
 
      printf("0x%02X ", *dp++);
537
 
    }
538
 
}
539
 
#endif /* DEBUG */
540
 
/*****************************************************************************/
541
 
/***** convert ethernet and token-ring frames *****/
542
 
int eth2tr(struct packed_ether_header *frame, int datalen)
543
 
{
544
 
  struct trh_hdr *phdr;
545
 
  struct trllc *pllc;
546
 
  char trheader[sizeof(struct trh_hdr) - sizeof(phdr->rseg) + sizeof(struct trllc)];
547
 
  int len;
548
 
 
549
 
#ifdef DEBUG
550
 
  dumpframe("eth2tr: Incoming eth frame", frame);
551
 
#endif
552
 
  memset(trheader, 0, sizeof(trheader));
553
 
  phdr = (struct trh_hdr *)trheader;
554
 
  phdr->ac = AC;
555
 
  phdr->fc = LLC_FRAME;
556
 
  memcpy(phdr->daddr, frame->ether_dhost, TR_ALEN);
557
 
  memcpy(phdr->saddr, frame->ether_shost, TR_ALEN);
558
 
  if (phdr->daddr[0] & 0x80)
559
 
    { /* Destination is a broadcast */
560
 
      phdr->rcf = sizeof(phdr->rcf) | htons(TR_RCF_BROADCAST | 0x70); /* Unlimited frame length */
561
 
      pllc = (struct trllc *)&phdr->rseg[0];
562
 
      phdr->saddr[0] |= TR_RII; /* Set source-route indicator */
563
 
      len = sizeof(trheader);
564
 
    }
565
 
  else
566
 
    {
567
 
      pllc = (struct trllc *)&phdr->rcf;
568
 
      len = sizeof(trheader) - sizeof(phdr->rcf);
569
 
    }
570
 
  pllc->dsap = EXTENDED_SAP;
571
 
  pllc->ssap = EXTENDED_SAP;
572
 
  pllc->llc = UI_CMD;
573
 
  pllc->protid[0] = pllc->protid[1] = pllc->protid[2] = 0;
574
 
  pllc->ethertype = frame->ether_type;
575
 
  memmove((char *)(frame + 1) + (len - sizeof(struct packed_ether_header)),
576
 
          frame + 1, datalen); /* Make room for larger TR header */
577
 
  memcpy(frame, trheader, len); /* Install TR header */
578
 
#ifdef DEBUG
579
 
  dumpframe("eth2tr: Outgoing tr frame", frame);
580
 
#endif
581
 
  return len + datalen;
582
 
}
583
 
/*****************************************************************************/
584
 
int tr2eth(struct packed_ether_header *frame)
585
 
{
586
 
  struct trh_hdr hdr;
587
 
  struct trllc *pllc;
588
 
  int hlen = 0;
589
 
 
590
 
#ifdef DEBUG
591
 
  dumpframe("tr2eth: Incoming tr frame", frame);
592
 
#endif
593
 
  hdr = *((struct trh_hdr *)frame);
594
 
  if (hdr.saddr[0] & TR_RII)
595
 
    {
596
 
fake_rif :
597
 
      hlen = hdr.rcf & ntohs(TR_RCF_LEN_MASK);
598
 
#ifdef DEBUG
599
 
      printf("rcf = 0x%X SR len %d\n", hdr.rcf, hlen);
600
 
#endif
601
 
      if (hlen < sizeof(hdr.rcf) || (hlen & 1))
602
 
        return 1;
603
 
      hdr.saddr[0] &= ~TR_RII;
604
 
    }
605
 
  pllc = (struct trllc *)(((__u8 *)frame) + sizeof(struct trh_hdr) - TR_MAXRIFLEN + hlen);
606
 
  if (pllc->dsap != EXTENDED_SAP || pllc->llc != UI_CMD)
607
 
    {
608
 
      if (hlen == 0)
609
 
          goto fake_rif;        /* Bug in 2.2.3 kernel */
610
 
#ifdef DEBUG
611
 
      printf("corrupted TR-IP packet of ui=0x%x and dsap 0x%x discarded\n",
612
 
        pllc->llc,pllc->dsap);
613
 
#endif
614
 
      return 1;
615
 
    }
616
 
  memcpy(frame->ether_dhost, hdr.daddr, ETH_ALEN);
617
 
  memcpy(frame->ether_shost, hdr.saddr, ETH_ALEN);
618
 
  frame->ether_type = pllc->ethertype;
619
 
  memmove(frame + 1, pllc + 1, IPPACKET_SIZE); /* Move data portion: Overlapping buffer */
620
 
#ifdef DEBUG
621
 
  dumpframe("tr2eth: Outgoing eth frame", frame);
622
 
#endif
623
 
  return 0;
624
 
}
625
 
/*****************************************************************************/
626
 
/* Subtract the `struct timeval' values X and Y,
627
 
   storing the result in RESULT.
628
 
   Return 1 if the difference is negative, otherwise 0.  */
629
 
static int timeval_subtract(result,x,y)
630
 
struct timeval *result,*x,*y;
631
 
{
632
 
  /* Perform the carry for the later subtraction by updating Y. */
633
 
  if (x->tv_usec < y->tv_usec) {
634
 
    int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
635
 
    y->tv_usec -= 1000000 * nsec;
636
 
    y->tv_sec += nsec;
637
 
  }
638
 
  if (x->tv_usec - y->tv_usec > 1000000) {
639
 
    int nsec = (x->tv_usec - y->tv_usec) / 1000000;
640
 
    y->tv_usec += 1000000 * nsec;
641
 
    y->tv_sec -= nsec;
642
 
  }
643
 
 
644
 
  /* Compute the time remaining to wait.
645
 
     `tv_usec' is certainly positive. */
646
 
  result->tv_sec = x->tv_sec - y->tv_sec;
647
 
  result->tv_usec = x->tv_usec - y->tv_usec;
648
 
 
649
 
  /* Return 1 if result is negative. */
650
 
  return x->tv_sec < y->tv_sec;
651
 
}
652
 
/*****************************************************************************/
653
 
int dhcpSendAndRecv(xid,msg,buildUdpIpMsg)
654
 
unsigned xid,msg;
655
 
void (*buildUdpIpMsg)(unsigned);
656
 
{
657
 
  struct sockaddr addr;
658
 
  struct timeval begin, current, diff;
659
 
  int i,len,o,timeout=0;
660
 
  char foobuf[512];
661
 
  const struct udphdr *udpRecv;
662
 
  int j=DHCP_INITIAL_RTO/2;
663
 
 
664
 
  do
665
 
    {
666
 
      do
667
 
        {
668
 
          j+=j;
669
 
          if (j > DHCP_MAX_RTO) j = DHCP_MAX_RTO;
670
 
          memset(&addr,0,sizeof(struct sockaddr));
671
 
          memcpy(addr.sa_data,IfName,IfName_len);
672
 
          buildUdpIpMsg(xid);
673
 
          if ( TokenRingIf )      /* Here we convert a Eth frame into an TR frame */
674
 
            len = eth2tr(&UdpIpMsgSend.ethhdr,sizeof(udpiphdr)+sizeof(dhcpMessage));
675
 
          else
676
 
            len = sizeof(struct packed_ether_header)+sizeof(udpiphdr)+sizeof(dhcpMessage);
677
 
          if ( sendto(dhcpSocket,&UdpIpMsgSend,len,0,
678
 
                &addr,sizeof(struct sockaddr)) == -1 )
679
 
            {
680
 
              syslog(LOG_ERR,"sendto: %m\n");
681
 
              return -1;
682
 
            }
683
 
          gettimeofday(&begin, NULL);
684
 
          i=random();
685
 
        }
686
 
      while ( peekfd(dhcpSocket,j+i%200000) );
687
 
      do
688
 
        {
689
 
          struct ip ipRecv_local;
690
 
          char *tmp_ip;
691
 
          memset(&UdpIpMsgRecv,0,sizeof(udpipMessage));
692
 
          o=sizeof(struct sockaddr);
693
 
          len=recvfrom(dhcpSocket,&UdpIpMsgRecv,sizeof(udpipMessage),0,
694
 
                     (struct sockaddr *)&addr,&o);
695
 
          if ( len == -1 )
696
 
            {
697
 
              syslog(LOG_ERR,"recvfrom: %m\n");
698
 
              return -1;
699
 
            }
700
 
          if ( TokenRingIf )
701
 
            {    /* Here we convert a TR frame into an Eth frame */
702
 
              if ( tr2eth(&UdpIpMsgRecv.ethhdr) ) continue;
703
 
            }
704
 
          gettimeofday(&current, NULL);
705
 
          timeval_subtract(&diff, &current, &begin);
706
 
          timeout = j - diff.tv_sec*1000000 - diff.tv_usec + random()%200000;
707
 
          if ( UdpIpMsgRecv.ethhdr.ether_type != htons(ETHERTYPE_IP) )
708
 
            continue;
709
 
          tmp_ip = UdpIpMsgRecv.udpipmsg;
710
 
          for (i=0;i<sizeof(struct ip)-2;i+=2)
711
 
            if ( ( UdpIpMsgRecv.udpipmsg[i] == 0x45 ) &&
712
 
                 ( UdpIpMsgRecv.udpipmsg[i+1] == 0x00 ) )
713
 
              {
714
 
                tmp_ip=&(UdpIpMsgRecv.udpipmsg[i]);
715
 
                break;
716
 
              }
717
 
          /* Use local copy because ipRecv is not aligned.  */
718
 
          memcpy(&ipRecv_local,((struct udpiphdr *)tmp_ip)->ip,sizeof(struct ip));
719
 
          udpRecv=(struct udphdr *)((char*)(((struct udpiphdr*)tmp_ip)->ip)+sizeof(struct ip));
720
 
          if ( ipRecv_local.ip_p != IPPROTO_UDP ) continue;
721
 
          if ( TokenRingIf )
722
 
            {
723
 
              if ( udpRecv->uh_dport != htons(DHCP_CLIENT_PORT) ) continue;
724
 
            }
725
 
          len-=sizeof(struct packed_ether_header);
726
 
          i=(int )ntohs(ipRecv_local.ip_len);
727
 
          if ( len < i )
728
 
            {
729
 
              if ( DebugFlag ) syslog(LOG_DEBUG,
730
 
                "corrupted IP packet of size=%d and ip_len=%d discarded\n",
731
 
                len,i);
732
 
              continue;
733
 
            }
734
 
          len=i-(ipRecv_local.ip_hl<<2);
735
 
          i=(int )ntohs(udpRecv->uh_ulen);
736
 
          if ( len < i )
737
 
            {
738
 
              if ( DebugFlag ) syslog(LOG_DEBUG,
739
 
                "corrupted UDP msg of size=%d and uh_ulen=%d discarded\n",
740
 
                len,i);
741
 
              continue;
742
 
            }
743
 
          if ( DoCheckSum )
744
 
            {
745
 
              len=udpipchk((udpiphdr *)tmp_ip);
746
 
              if ( len )
747
 
                {
748
 
                  if ( DebugFlag )
749
 
                    switch ( len )
750
 
                      {
751
 
                        case -1: syslog(LOG_DEBUG,
752
 
                          "corrupted IP packet with ip_len=%d discarded\n",
753
 
                          (int )ntohs(ipRecv_local.ip_len));
754
 
                          break;
755
 
                        case -2: syslog(LOG_DEBUG,
756
 
                          "corrupted UDP msg with uh_ulen=%d discarded\n",
757
 
                          (int )ntohs(udpRecv->uh_ulen));
758
 
                        break;
759
 
                      }
760
 
                  continue;
761
 
                }
762
 
            }
763
 
          DhcpMsgRecv=(dhcpMessage *)&tmp_ip[(ipRecv_local.ip_hl<<2)+sizeof(struct udphdr)];
764
 
          if ( DhcpMsgRecv->xid != xid ) continue;
765
 
          if (  DhcpMsgRecv->htype != ARPHRD_ETHER &&
766
 
                DhcpMsgRecv->htype != (char)ARPHRD_IEEE802_TR )
767
 
            {
768
 
                if ( DebugFlag )
769
 
                  syslog(LOG_DEBUG,"wrong msg htype 0x%X discarded\n",DhcpMsgRecv->htype);
770
 
                continue;
771
 
            }
772
 
          if ( DhcpMsgRecv->op != DHCP_BOOTREPLY ) continue;
773
 
          while ( udpFooSocket > 0 &&
774
 
                recvfrom(udpFooSocket,(void *)foobuf,sizeof(foobuf),0,NULL,NULL) != -1 );
775
 
          if ( parseDhcpMsgRecv() == msg ) return 0;
776
 
          if ( DhcpOptions.val[dhcpMessageType] )
777
 
          if ( *(unsigned char *)DhcpOptions.val[dhcpMessageType] == DHCP_NAK )
778
 
            {
779
 
              if ( DhcpOptions.val[dhcpMsg] )
780
 
                syslog(LOG_ERR,
781
 
                "DHCP_NAK server response received: %s\n",
782
 
                (char *)DhcpOptions.val[dhcpMsg]);
783
 
              else
784
 
                syslog(LOG_ERR,
785
 
                "DHCP_NAK server response received\n");
786
 
              return 1;
787
 
            }
788
 
        }
789
 
      while ( timeout > 0 && peekfd(dhcpSocket, timeout) == 0 );
790
 
    }
791
 
  while ( 1 );
792
 
  return 1;
793
 
}
794
 
/*****************************************************************************/
795
 
void *dhcpStart()
796
 
{
797
 
  int o = 1;
798
 
  unsigned i=0;
799
 
  struct ifreq  ifr;
800
 
  struct sockaddr_pkt sap;
801
 
  struct sockaddr_in clientAddr;
802
 
  memset(&ifr,0,sizeof(struct ifreq));
803
 
  memcpy(ifr.ifr_name,IfName,IfName_len);
804
 
#ifdef OLD_LINUX_VERSION
805
 
  dhcpSocket = socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL));
806
 
#else
807
 
  dhcpSocket = socket(AF_PACKET,SOCK_PACKET,htons(ETH_P_ALL));
808
 
#endif
809
 
  if ( dhcpSocket == -1 )
810
 
    {
811
 
      syslog(LOG_ERR,"dhcpStart: socket: %m\n");
812
 
      exit(1);
813
 
    }
814
 
 
815
 
  if ( ioctl(dhcpSocket,SIOCGIFHWADDR,&ifr) )
816
 
    {
817
 
      syslog(LOG_ERR,"dhcpStart: ioctl SIOCGIFHWADDR: %m\n");
818
 
      exit(1);
819
 
    }
820
 
  if ( ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE802_TR )
821
 
    {
822
 
      syslog(LOG_ERR,"dhcpStart: interface %s is not Ethernet or 802.2 Token Ring\n",ifr.ifr_name);
823
 
      exit(1);
824
 
    }
825
 
  if ( ifr.ifr_hwaddr.sa_family == ARPHRD_IEEE802_TR )
826
 
    {
827
 
      TokenRingIf = 1;
828
 
      if ( DebugFlag )
829
 
        syslog(LOG_DEBUG,"found NIC of link layer type %d\n",ifr.ifr_hwaddr.sa_family);
830
 
    }
831
 
  if ( setsockopt(dhcpSocket,SOL_SOCKET,SO_BROADCAST,&o,sizeof(o)) == -1 )
832
 
    {
833
 
      syslog(LOG_ERR,"dhcpStart: setsockopt: %m\n");
834
 
      exit(1);
835
 
    }
836
 
  if ( ioctl(dhcpSocket,SIOCGIFFLAGS,&ifr) )  
837
 
    {  
838
 
      syslog(LOG_ERR,"dhcpStart: ioctl SIOCGIFFLAGS: %m\n");  
839
 
      exit(1);  
840
 
    }  
841
 
  saved_if_flags = ifr.ifr_flags;  
842
 
  ifr.ifr_flags = saved_if_flags | IFF_UP | IFF_BROADCAST | IFF_NOTRAILERS | IFF_RUNNING;
843
 
  if ( ioctl(dhcpSocket,SIOCSIFFLAGS,&ifr) )
844
 
    {
845
 
      syslog(LOG_ERR,"dhcpStart: ioctl SIOCSIFFLAGS: %m\n");
846
 
      exit(1);
847
 
    }
848
 
  memset(&sap,0,sizeof(sap));
849
 
 
850
 
  do
851
 
    {
852
 
      i++;
853
 
      if ( i>1 )
854
 
        syslog(LOG_WARNING,"dhcpStart: retrying MAC address request "
855
 
        "(returned %02x:%02x:%02x:%02x:%02x:%02x)",
856
 
        ClientHwAddr[0],ClientHwAddr[1],ClientHwAddr[2],
857
 
        ClientHwAddr[3],ClientHwAddr[4],ClientHwAddr[5]);
858
 
      if ( ioctl(dhcpSocket,SIOCGIFHWADDR,&ifr) )
859
 
        {
860
 
          syslog(LOG_ERR,"dhcpStart: ioctl SIOCGIFHWADDR: %m\n");
861
 
          exit(1);
862
 
        }
863
 
      if ( ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE802_TR )
864
 
        {
865
 
          syslog(LOG_ERR,"dhcpStart: interface %s is not Ethernet or 802.2 Token Ring\n",ifr.ifr_name);
866
 
          exit(1);
867
 
        }
868
 
      if ( setsockopt(dhcpSocket,SOL_SOCKET,SO_BROADCAST,&o,sizeof(o)) == -1 )
869
 
        {
870
 
          syslog(LOG_ERR,"dhcpStart: setsockopt: %m\n");
871
 
          exit(1);
872
 
        }
873
 
      ifr.ifr_flags = saved_if_flags | IFF_UP | IFF_BROADCAST | IFF_NOTRAILERS | IFF_RUNNING;
874
 
      if ( ioctl(dhcpSocket,SIOCSIFFLAGS,&ifr) )
875
 
        {
876
 
          syslog(LOG_ERR,"dhcpStart: ioctl SIOCSIFFLAGS: %m\n");
877
 
          exit(1);
878
 
        }
879
 
      memset(&sap,0,sizeof(sap));
880
 
      sap.spkt_protocol = htons(ETH_P_ALL);
881
 
      memcpy(sap.spkt_device,IfName,IfName_len);
882
 
#ifdef OLD_LINUX_VERSION
883
 
      sap.spkt_family = AF_INET;
884
 
#else
885
 
      sap.spkt_family = AF_PACKET;
886
 
#endif
887
 
      if ( bind(dhcpSocket,(void*)&sap,sizeof(struct sockaddr)) == -1 )
888
 
        syslog(LOG_ERR,"dhcpStart: bind: %m\n");
889
 
 
890
 
      memcpy(ClientHwAddr,ifr.ifr_hwaddr.sa_data,ETH_ALEN);
891
 
      if ( DebugFlag )
892
 
        fprintf(stdout,"dhcpcd: MAC address = %02x:%02x:%02x:%02x:%02x:%02x\n",
893
 
        ClientHwAddr[0], ClientHwAddr[1], ClientHwAddr[2],
894
 
        ClientHwAddr[3], ClientHwAddr[4], ClientHwAddr[5]);
895
 
    }
896
 
  while ( !ClientHwAddr[0] &&
897
 
          !ClientHwAddr[1] &&
898
 
          !ClientHwAddr[2] &&
899
 
          !ClientHwAddr[3] &&
900
 
          !ClientHwAddr[4] &&
901
 
          !ClientHwAddr[5] &&
902
 
           i<HWADDR_TRIES );
903
 
 
904
 
  i=time(NULL)+ClientHwAddr[5]+4*ClientHwAddr[4]+8*ClientHwAddr[3]+
905
 
  16*ClientHwAddr[2]+32*ClientHwAddr[1]+64*ClientHwAddr[0];
906
 
  srandom(i);
907
 
  ip_id=i&0xffff;
908
 
 
909
 
  udpFooSocket = socket(AF_INET,SOCK_DGRAM,0);
910
 
  if ( udpFooSocket == -1 )
911
 
    {
912
 
      syslog(LOG_ERR,"dhcpStart: socket: %m\n");
913
 
      exit(1);
914
 
    }
915
 
  if ( setsockopt(udpFooSocket,SOL_SOCKET,SO_BROADCAST,&o,sizeof(o)) )
916
 
    syslog(LOG_ERR,"dhcpStart: setsockopt: %m\n");
917
 
  memset(&clientAddr.sin_addr,0,sizeof(&clientAddr.sin_addr));
918
 
  clientAddr.sin_family = AF_INET;
919
 
  clientAddr.sin_port = htons(DHCP_CLIENT_PORT);
920
 
  if ( bind(udpFooSocket,(struct sockaddr *)&clientAddr,sizeof(clientAddr)) )
921
 
    {
922
 
      if ( errno != EADDRINUSE )
923
 
        syslog(LOG_ERR,"dhcpStart: bind: %m\n");
924
 
      close(udpFooSocket);
925
 
      udpFooSocket = -1;
926
 
    }
927
 
  else
928
 
    if ( fcntl(udpFooSocket,F_SETFL,O_NONBLOCK) == -1 )
929
 
      {
930
 
        syslog(LOG_ERR,"dhcpStart: fcntl: %m\n");
931
 
        exit(1);
932
 
      }
933
 
 
934
 
  return &dhcpInit;
935
 
}
936
 
/*****************************************************************************/
937
 
void classclientsetup()
938
 
{
939
 
  if ( ClassID )
940
 
    {
941
 
      memcpy(DhcpIface.class_id,ClassID,ClassID_len);
942
 
      DhcpIface.class_len=ClassID_len;
943
 
    }
944
 
  else
945
 
    classIDsetup();
946
 
  clientIDsetup();
947
 
}
948
 
/*****************************************************************************/
949
 
void *dhcpReboot()
950
 
{
951
 
  if ( sigsetjmp(env,0xffff) )
952
 
    {
953
 
      if ( DebugFlag )
954
 
        syslog(LOG_DEBUG,"timed out waiting for DHCP_ACK response\n");
955
 
      if (TimeOut != 0)
956
 
        alarm(TimeOut);
957
 
      return &dhcpInit;
958
 
    }
959
 
  dhcpStart();
960
 
  memset(&DhcpOptions,0,sizeof(DhcpOptions));
961
 
  memset(&DhcpIface,0,sizeof(dhcpInterface));
962
 
  if ( readDhcpCache() )
963
 
    {
964
 
      struct ifreq      ifr;
965
 
      struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
966
 
      memset(&DhcpIface,0,sizeof(dhcpInterface));
967
 
      memset(&ifr,0,sizeof(struct ifreq));
968
 
#ifdef OLD_LINUX_VERSION
969
 
      memcpy(ifr.ifr_name,IfName,IfName_len);
970
 
#else
971
 
      memcpy(ifr.ifr_name,IfNameExt,IfNameExt_len);
972
 
#endif
973
 
      p->sin_family = AF_INET;
974
 
      if ( ioctl(dhcpSocket,SIOCGIFADDR,&ifr) == 0 )
975
 
        DhcpIface.ciaddr=p->sin_addr.s_addr;
976
 
#if 0
977
 
      if ( ClientMACaddr_ind )
978
 
        memcpy(DhcpIface.chaddr,ClientMACaddr,ETH_ALEN);
979
 
      else
980
 
        memcpy(DhcpIface.chaddr,ClientHwAddr,ETH_ALEN);
981
 
#endif
982
 
      classclientsetup();
983
 
      return &dhcpInit;
984
 
    }
985
 
  classclientsetup();
986
 
#if 0
987
 
  if ( ClientMACaddr_ind )
988
 
    memcpy(DhcpIface.chaddr,ClientMACaddr,ETH_ALEN);
989
 
  else
990
 
    memcpy(DhcpIface.chaddr,ClientHwAddr,ETH_ALEN);
991
 
#endif
992
 
  return dhcpRequest(random(),&buildDhcpReboot);
993
 
}
994
 
/*****************************************************************************/
995
 
void *dhcpInit()
996
 
{
997
 
  releaseDhcpOptions();
998
 
 
999
 
#ifdef DEBUG
1000
 
fprintf(stderr,"ClassID  = \"%s\"\n\
1001
 
ClientID = \"%u.%u.%u.%02X.%02X.%02X.%02X.%02X.%02X\"\n",
1002
 
DhcpIface.class_id,
1003
 
DhcpIface.client_id[0],DhcpIface.client_id[1],DhcpIface.client_id[2],
1004
 
DhcpIface.client_id[3],DhcpIface.client_id[4],DhcpIface.client_id[5],
1005
 
DhcpIface.client_id[6],DhcpIface.client_id[7],DhcpIface.client_id[8]);
1006
 
#endif
1007
 
 
1008
 
  if ( DebugFlag ) syslog(LOG_DEBUG,"broadcasting DHCP_DISCOVER\n");
1009
 
  if ( dhcpSendAndRecv(random(),DHCP_OFFER,&buildDhcpDiscover) )
1010
 
    {
1011
 
      dhcpStop();
1012
 
      return 0;
1013
 
    }
1014
 
  if ( SendSecondDiscover )
1015
 
    {
1016
 
      if ( DebugFlag ) syslog(LOG_DEBUG,"broadcasting second DHCP_DISCOVER\n");
1017
 
      dhcpSendAndRecv(DhcpMsgRecv->xid,DHCP_OFFER,&buildDhcpDiscover);
1018
 
    }
1019
 
  prev_ip_addr = DhcpIface.ciaddr;
1020
 
  DhcpIface.ciaddr = DhcpMsgRecv->yiaddr;
1021
 
  memcpy(&DhcpIface.siaddr,DhcpOptions.val[dhcpServerIdentifier],4);
1022
 
  memcpy(DhcpIface.shaddr,UdpIpMsgRecv.ethhdr.ether_shost,ETH_ALEN);
1023
 
  DhcpIface.xid = DhcpMsgRecv->xid;
1024
 
/* DHCP_OFFER received */
1025
 
  if ( DebugFlag )
1026
 
    syslog(LOG_DEBUG,"DHCP_OFFER received from %s (%u.%u.%u.%u)\n",
1027
 
    DhcpMsgRecv->sname,
1028
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],
1029
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],
1030
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],
1031
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);
1032
 
 
1033
 
  return dhcpRequest(DhcpIface.xid,&buildDhcpRequest);
1034
 
}
1035
 
/*****************************************************************************/
1036
 
void *dhcpRequest(xid,buildDhcpMsg)
1037
 
unsigned xid;
1038
 
void (*buildDhcpMsg)(unsigned);
1039
 
{
1040
 
/* send the message and read and parse replies into DhcpOptions */
1041
 
  if ( DebugFlag )
1042
 
    syslog(LOG_DEBUG,"broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",
1043
 
           ((unsigned char *)&DhcpIface.ciaddr)[0],
1044
 
           ((unsigned char *)&DhcpIface.ciaddr)[1],
1045
 
           ((unsigned char *)&DhcpIface.ciaddr)[2],
1046
 
           ((unsigned char *)&DhcpIface.ciaddr)[3]);
1047
 
  if ( dhcpSendAndRecv(xid,DHCP_ACK,buildDhcpMsg) ) return &dhcpInit;
1048
 
  ReqSentTime=time(NULL);
1049
 
  if ( DebugFlag ) syslog(LOG_DEBUG,
1050
 
    "DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,
1051
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],
1052
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],
1053
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],
1054
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);
1055
 
#ifdef ARPCHECK
1056
 
/* check if the offered IP address already in use */
1057
 
  if ( arpCheck() )
1058
 
    {
1059
 
      if ( DebugFlag ) syslog(LOG_DEBUG,
1060
 
        "requested %u.%u.%u.%u address is in use\n",
1061
 
        ((unsigned char *)&DhcpIface.ciaddr)[0],
1062
 
        ((unsigned char *)&DhcpIface.ciaddr)[1],
1063
 
        ((unsigned char *)&DhcpIface.ciaddr)[2],
1064
 
        ((unsigned char *)&DhcpIface.ciaddr)[3]);
1065
 
      dhcpDecline();
1066
 
      DhcpIface.ciaddr = 0;
1067
 
      return &dhcpInit;
1068
 
    }
1069
 
  if ( DebugFlag ) syslog(LOG_DEBUG,
1070
 
    "verified %u.%u.%u.%u address is not in use\n",
1071
 
    ((unsigned char *)&DhcpIface.ciaddr)[0],
1072
 
    ((unsigned char *)&DhcpIface.ciaddr)[1],
1073
 
    ((unsigned char *)&DhcpIface.ciaddr)[2],
1074
 
    ((unsigned char *)&DhcpIface.ciaddr)[3]);
1075
 
#endif
1076
 
  if ( dhcpConfig() )
1077
 
    {
1078
 
      dhcpStop();
1079
 
      return 0;
1080
 
    }
1081
 
 
1082
 
  /* Successfull ACK: Use the fields obtained for future requests */
1083
 
  memcpy(&DhcpIface.siaddr,DhcpOptions.val[dhcpServerIdentifier],4);
1084
 
  memcpy(DhcpIface.shaddr,UdpIpMsgRecv.ethhdr.ether_shost,ETH_ALEN);
1085
 
 
1086
 
  return &dhcpBound;
1087
 
}
1088
 
/*****************************************************************************/
1089
 
void *dhcpBound()
1090
 
{
1091
 
  int i;
1092
 
  if ( sigsetjmp(env,0xffff) ) return &dhcpRenew;
1093
 
  i=ReqSentTime+ntohl(*(unsigned int *)DhcpOptions.val[dhcpT1value])-time(NULL);
1094
 
  if ( i > 0 )
1095
 
    alarm(i);
1096
 
  else
1097
 
    return &dhcpRenew;
1098
 
 
1099
 
  sleep(ntohl(*(u_int *)DhcpOptions.val[dhcpT1value]));
1100
 
  return &dhcpRenew;
1101
 
}
1102
 
/*****************************************************************************/
1103
 
void *dhcpRenew()
1104
 
{
1105
 
  int i;
1106
 
  if ( sigsetjmp(env,0xffff) ) return &dhcpRebind;
1107
 
  i = ReqSentTime+ntohl(*(unsigned int *)DhcpOptions.val[dhcpT2value])-time(NULL);
1108
 
  if ( i > 0 )
1109
 
    alarm(i);
1110
 
  else
1111
 
    return &dhcpRebind;
1112
 
 
1113
 
  if ( DebugFlag )
1114
 
    syslog(LOG_DEBUG,"sending DHCP_REQUEST for %u.%u.%u.%u to %u.%u.%u.%u\n",
1115
 
           ((unsigned char *)&DhcpIface.ciaddr)[0],
1116
 
           ((unsigned char *)&DhcpIface.ciaddr)[1],
1117
 
           ((unsigned char *)&DhcpIface.ciaddr)[2],
1118
 
           ((unsigned char *)&DhcpIface.ciaddr)[3],
1119
 
           ((unsigned char *)&DhcpIface.siaddr)[0],
1120
 
           ((unsigned char *)&DhcpIface.siaddr)[1],
1121
 
           ((unsigned char *)&DhcpIface.siaddr)[2],
1122
 
           ((unsigned char *)&DhcpIface.siaddr)[3]);
1123
 
  if ( dhcpSendAndRecv(random(),DHCP_ACK,&buildDhcpRenew) ) return &dhcpRebind;
1124
 
  ReqSentTime=time(NULL);
1125
 
  if ( DebugFlag ) syslog(LOG_DEBUG,
1126
 
    "DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,
1127
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],
1128
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],
1129
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],
1130
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);
1131
 
  return &dhcpBound;
1132
 
}
1133
 
/*****************************************************************************/
1134
 
void *dhcpRebind()
1135
 
{
1136
 
  int i;
1137
 
  if ( sigsetjmp(env,0xffff) ) return &dhcpStop;
1138
 
  i = ReqSentTime+ntohl(*(unsigned int *)DhcpOptions.val[dhcpIPaddrLeaseTime])-time(NULL);
1139
 
  if ( i > 0 )
1140
 
    alarm(i);
1141
 
  else
1142
 
    return &dhcpStop;
1143
 
 
1144
 
  if ( DebugFlag )
1145
 
    syslog(LOG_DEBUG,"broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",
1146
 
           ((unsigned char *)&DhcpIface.ciaddr)[0],
1147
 
           ((unsigned char *)&DhcpIface.ciaddr)[1],
1148
 
           ((unsigned char *)&DhcpIface.ciaddr)[2],
1149
 
           ((unsigned char *)&DhcpIface.ciaddr)[3]);
1150
 
  if ( dhcpSendAndRecv(random(),DHCP_ACK,&buildDhcpRebind) ) return &dhcpStop;
1151
 
  ReqSentTime=time(NULL);
1152
 
  if ( DebugFlag ) syslog(LOG_DEBUG,
1153
 
    "DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,
1154
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],
1155
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],
1156
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],
1157
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);
1158
 
 
1159
 
  /* Successfull ACK: Use the fields obtained for future requests */
1160
 
  memcpy(&DhcpIface.siaddr,DhcpOptions.val[dhcpServerIdentifier],4);
1161
 
  memcpy(DhcpIface.shaddr,UdpIpMsgRecv.ethhdr.ether_shost,ETH_ALEN);
1162
 
 
1163
 
  return &dhcpBound;
1164
 
}
1165
 
/*****************************************************************************/
1166
 
void *dhcpRelease()
1167
 
{
1168
 
  struct sockaddr addr;
1169
 
  deleteDhcpCache();
1170
 
  if ( DhcpIface.ciaddr == 0 ) return &dhcpInit;
1171
 
 
1172
 
  buildDhcpRelease(random());
1173
 
 
1174
 
  memset(&addr,0,sizeof(struct sockaddr));
1175
 
  memcpy(addr.sa_data,IfName,IfName_len);
1176
 
  if ( DebugFlag )
1177
 
    syslog(LOG_DEBUG,"sending DHCP_RELEASE for %u.%u.%u.%u to %u.%u.%u.%u\n",
1178
 
           ((unsigned char *)&DhcpIface.ciaddr)[0],
1179
 
           ((unsigned char *)&DhcpIface.ciaddr)[1],
1180
 
           ((unsigned char *)&DhcpIface.ciaddr)[2],
1181
 
           ((unsigned char *)&DhcpIface.ciaddr)[3],
1182
 
           ((unsigned char *)&DhcpIface.siaddr)[0],
1183
 
           ((unsigned char *)&DhcpIface.siaddr)[1],
1184
 
           ((unsigned char *)&DhcpIface.siaddr)[2],
1185
 
           ((unsigned char *)&DhcpIface.siaddr)[3]);
1186
 
  if ( sendto(dhcpSocket,&UdpIpMsgSend,sizeof(struct packed_ether_header)+
1187
 
              sizeof(udpiphdr)+sizeof(dhcpMessage),0,
1188
 
              &addr,sizeof(struct sockaddr)) == -1 )
1189
 
    syslog(LOG_ERR,"dhcpRelease: sendto: %m\n");
1190
 
  arpRelease(); /* clear ARP cache entries for client IP addr */
1191
 
  if ( SetHostName )
1192
 
    {
1193
 
      sethostname(InitialHostName,InitialHostName_len);
1194
 
      if ( DebugFlag )
1195
 
        fprintf(stdout,"dhcpcd: your hostname = %s\n",InitialHostName);
1196
 
    }
1197
 
  if ( SetDomainName )
1198
 
    {
1199
 
      setdomainname(InitialDomainName,InitialDomainName_len);
1200
 
      if ( DebugFlag )
1201
 
        fprintf(stdout,"dhcpcd: your domainname = %s\n",InitialDomainName);
1202
 
    }
1203
 
  DhcpIface.ciaddr=0;
1204
 
  return &dhcpInit;
1205
 
}
1206
 
/*****************************************************************************/
1207
 
void *dhcpStop()
1208
 
{
1209
 
  struct ifreq ifr;
1210
 
  struct sockaddr_in    *p = (struct sockaddr_in *)&(ifr.ifr_addr);
1211
 
 
1212
 
  releaseDhcpOptions();
1213
 
  if ( TestCase ) goto tsc;
1214
 
  memset(&ifr,0,sizeof(struct ifreq));
1215
 
#ifdef OLD_LINUX_VERSION
1216
 
  memcpy(ifr.ifr_name,IfName,IfName_len);
1217
 
#else
1218
 
  memcpy(ifr.ifr_name,IfNameExt,IfNameExt_len);
1219
 
#endif
1220
 
  p->sin_family = AF_INET;
1221
 
  p->sin_addr.s_addr = 0;
1222
 
#ifndef OLD_LINUX_VERSION
1223
 
  if ( ioctl(dhcpSocket,SIOCSIFADDR,&ifr) == -1 )
1224
 
    syslog(LOG_ERR,"dhcpStop: ioctl SIOCSIFADDR: %m\n");
1225
 
#endif
1226
 
  ifr.ifr_flags = saved_if_flags & ~IFF_UP;
1227
 
  if ( (IfName_len==IfNameExt_len) && ioctl(dhcpSocket,SIOCSIFFLAGS,&ifr) )
1228
 
    syslog(LOG_ERR,"dhcpStop: ioctl SIOCSIFFLAGS: %m\n");
1229
 
tsc:
1230
 
  close(dhcpSocket);
1231
 
  if ( resolv_renamed )
1232
 
    rename(""RESOLV_CONF".sv",RESOLV_CONF);
1233
 
  if ( yp_renamed )
1234
 
    rename(""NIS_CONF".sv",NIS_CONF);
1235
 
  if ( ntp_renamed )
1236
 
    rename(""NTP_CONF".sv",NTP_CONF);
1237
 
  execute_on_change("down");
1238
 
  return &dhcpStart;
1239
 
}
1240
 
/*****************************************************************************/
1241
 
#ifdef ARPCHECK
1242
 
void *dhcpDecline()
1243
 
{
1244
 
  struct sockaddr addr;
1245
 
  memset(&UdpIpMsgSend,0,sizeof(udpipMessage));
1246
 
  memcpy(UdpIpMsgSend.ethhdr.ether_dhost,MAC_BCAST_ADDR,ETH_ALEN);
1247
 
  memcpy(UdpIpMsgSend.ethhdr.ether_shost,ClientHwAddr,ETH_ALEN);
1248
 
  UdpIpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_IP);
1249
 
  buildDhcpDecline(random());
1250
 
  udpipgen((udpiphdr *)&UdpIpMsgSend.udpipmsg,0,INADDR_BROADCAST,
1251
 
  htons(DHCP_CLIENT_PORT),htons(DHCP_SERVER_PORT),sizeof(dhcpMessage));
1252
 
  memset(&addr,0,sizeof(struct sockaddr));
1253
 
  memcpy(addr.sa_data,IfName,IfName_len);
1254
 
  if ( DebugFlag ) syslog(LOG_DEBUG,"broadcasting DHCP_DECLINE\n");
1255
 
  if ( sendto(dhcpSocket,&UdpIpMsgSend,sizeof(struct packed_ether_header)+
1256
 
              sizeof(udpiphdr)+sizeof(dhcpMessage),0,
1257
 
              &addr,sizeof(struct sockaddr)) == -1 )
1258
 
    syslog(LOG_ERR,"dhcpDecline: sendto: %m\n");
1259
 
  return &dhcpInit;
1260
 
}
1261
 
#endif
1262
 
/*****************************************************************************/
1263
 
void *dhcpInform()
1264
 
{
1265
 
  dhcpStart();
1266
 
  memset(&DhcpOptions,0,sizeof(DhcpOptions));
1267
 
  memset(&DhcpIface,0,sizeof(dhcpInterface));
1268
 
  if ( ! inform_ipaddr.s_addr )
1269
 
    {
1270
 
      struct ifreq ifr;
1271
 
      struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
1272
 
      memset(&ifr,0,sizeof(struct ifreq));
1273
 
#ifdef OLD_LINUX_VERSION
1274
 
      memcpy(ifr.ifr_name,IfName,IfName_len);
1275
 
#else
1276
 
      memcpy(ifr.ifr_name,IfNameExt,IfNameExt_len);
1277
 
#endif
1278
 
      p->sin_family = AF_INET;
1279
 
      if ( ioctl(dhcpSocket,SIOCGIFADDR,&ifr) == 0 )
1280
 
        inform_ipaddr.s_addr=p->sin_addr.s_addr;
1281
 
      if ( ! inform_ipaddr.s_addr )
1282
 
        {
1283
 
          if ( readDhcpCache() )
1284
 
            {
1285
 
              syslog(LOG_ERR,"dhcpInform: no IP address given\n");
1286
 
              return NULL;
1287
 
            }
1288
 
          else
1289
 
            inform_ipaddr.s_addr=DhcpIface.ciaddr;
1290
 
        }
1291
 
    }
1292
 
#if 0
1293
 
  if ( ! DhcpIface.ciaddr )
1294
 
    {
1295
 
      if ( ClientMACaddr_ind )
1296
 
        memcpy(DhcpIface.chaddr,ClientMACaddr,ETH_ALEN);
1297
 
      else
1298
 
        memcpy(DhcpIface.chaddr,ClientHwAddr,ETH_ALEN);
1299
 
    }
1300
 
#endif
1301
 
  DhcpIface.ciaddr=inform_ipaddr.s_addr;
1302
 
  if ( ! DhcpIface.class_len )
1303
 
    { 
1304
 
      if ( ClassID )
1305
 
        {
1306
 
          memcpy(DhcpIface.class_id,ClassID,ClassID_len);
1307
 
          DhcpIface.class_len=ClassID_len;
1308
 
        }
1309
 
      else
1310
 
        classIDsetup();
1311
 
    }
1312
 
  if ( ! DhcpIface.client_len ) clientIDsetup();
1313
 
  if ( sigsetjmp(env,0xffff) )
1314
 
    {
1315
 
      if ( DebugFlag )
1316
 
        syslog(LOG_DEBUG,"timed out waiting for DHCP_ACK response\n");
1317
 
      return 0;
1318
 
    }
1319
 
  if ( DebugFlag )
1320
 
    syslog(LOG_DEBUG,"broadcasting DHCP_INFORM for %u.%u.%u.%u\n",
1321
 
           ((unsigned char *)&DhcpIface.ciaddr)[0],
1322
 
           ((unsigned char *)&DhcpIface.ciaddr)[1],
1323
 
           ((unsigned char *)&DhcpIface.ciaddr)[2],
1324
 
           ((unsigned char *)&DhcpIface.ciaddr)[3]);
1325
 
  if ( dhcpSendAndRecv(random(),DHCP_ACK,buildDhcpInform) ) return 0;
1326
 
  if ( DebugFlag ) syslog(LOG_DEBUG,
1327
 
    "DHCP_ACK received from %s (%u.%u.%u.%u)\n",DhcpMsgRecv->sname,
1328
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[0],
1329
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[1],
1330
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[2],
1331
 
    ((unsigned char *)DhcpOptions.val[dhcpServerIdentifier])[3]);
1332
 
#ifdef ARPCHECK
1333
 
/* check if the offered IP address already in use */
1334
 
  if ( arpCheck() )
1335
 
    {
1336
 
      if ( DebugFlag ) syslog(LOG_DEBUG,
1337
 
        "requested %u.%u.%u.%u address is in use\n",
1338
 
        ((unsigned char *)&DhcpIface.ciaddr)[0],
1339
 
        ((unsigned char *)&DhcpIface.ciaddr)[1],
1340
 
        ((unsigned char *)&DhcpIface.ciaddr)[2],
1341
 
        ((unsigned char *)&DhcpIface.ciaddr)[3]);
1342
 
      dhcpDecline();
1343
 
      return 0;
1344
 
    }
1345
 
  if ( DebugFlag ) syslog(LOG_DEBUG,
1346
 
    "verified %u.%u.%u.%u address is not in use\n",
1347
 
    ((unsigned char *)&DhcpIface.ciaddr)[0],
1348
 
    ((unsigned char *)&DhcpIface.ciaddr)[1],
1349
 
    ((unsigned char *)&DhcpIface.ciaddr)[2],
1350
 
    ((unsigned char *)&DhcpIface.ciaddr)[3]);
1351
 
#endif
1352
 
  if ( dhcpConfig() ) return 0;
1353
 
  exit(0);
1354
 
}