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.
31
#include <netinet/in.h>
32
#include <arpa/inet.h>
35
#include "pathnames.h"
40
struct in_addr inform_ipaddr,default_router;
41
char *ProgramName = NULL;
42
char **ProgramEnviron= NULL;
43
char *IfName = DEFAULT_IFNAME;
44
char *IfNameExt = DEFAULT_IFNAME;
45
int IfName_len = DEFAULT_IFNAME_LEN;
46
int IfNameExt_len = DEFAULT_IFNAME_LEN;
47
char *HostName = NULL;
49
char *Cfilename = NULL;
50
unsigned char *ClassID = NULL;
52
unsigned char *ClientID = NULL;
54
void *(*currState)() = &dhcpReboot;
57
unsigned LeaseTime = DEFAULT_LEASETIME;
58
int ReplResolvConf = 1;
61
int SetDomainName = 0;
63
int BroadcastResp = 0;
64
time_t TimeOut = DEFAULT_TIMEOUT;
66
unsigned short dhcpMsgSize = 0;
67
unsigned nleaseTime = 0;
70
int SendSecondDiscover = 0;
72
char *ConfigDir = CONFIG_DIR;
73
int SetDHCPDefaultRoutes= 1;
76
unsigned char ClientMACaddr[ETH_ALEN];
77
int ClientMACaddr_ind = 0;
79
/*****************************************************************************/
83
DHCP Client Daemon v."VERSION"\n\
84
Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>\n\
85
Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>\n\
86
Location: http://www.phystech.com/download/\n");
88
/*****************************************************************************/
89
void checkIfAlreadyRunning()
93
snprintf(pidfile,sizeof(pidfile),PID_FILE_PATH,ConfigDir,IfNameExt);
94
o=open(pidfile,O_RDONLY);
95
if ( o == -1 ) return;
98
**** %s: already running\n\
99
**** %s: if not then delete %s file\n",ProgramName,ProgramName,pidfile);
102
/*****************************************************************************/
103
int main(argn,argc,argv)
105
char *argc[],*argv[];
115
* Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
116
* This way we can close 0, 1, 2 after forking the daemon without clobbering
117
* a fd that we are using (such as our sockets). This is necessary if
118
* this program is run from init scripts where 0, 1, and/or 2 may be closed.
120
j=open("/dev/null",O_RDWR);
121
while ( j < 2 && j >= 0 ) j = dup(j);
122
if ( j > 2 ) close(j);
126
fprintf(stderr,"**** %s: not a superuser\n",argc[0]);
131
if ( argc[i][0]=='-' )
132
prgs: switch ( argc[i][s] )
183
if ( argc[i][s+1] ) goto usage;
186
if ( Cfilename == NULL || Cfilename[0] == '-' ) goto usage;
190
if ( argc[i][s+1] ) goto usage;
193
if ( ConfigDir == NULL || ConfigDir[0] != '/' ) goto usage;
198
if ( argc[i][s+1] ) goto usage;
200
if ( argc[i] == NULL ) goto usage;
201
if ( isxdigit(argc[i][0]) && isxdigit(argc[i][1]) && argc[i][2] == ':' )
202
ClientMACaddr[0] = 16*(argc[i][0]>64?(toupper(argc[i][0])-55):(argc[i][0]-48)) +
203
(argc[i][1]>64?(toupper(argc[i][1])-55):(argc[i][1]-48));
206
if ( isxdigit(argc[i][3]) && isxdigit(argc[i][4]) && argc[i][5] == ':' )
207
ClientMACaddr[1] = 16*(argc[i][3]>64?(toupper(argc[i][3])-55):(argc[i][3]-48)) +
208
(argc[i][4]>64?(toupper(argc[i][4])-55):(argc[i][4]-48));
211
if ( isxdigit(argc[i][6]) && isxdigit(argc[i][7]) && argc[i][8] == ':' )
212
ClientMACaddr[2] = 16*(argc[i][6]>64?(toupper(argc[i][6])-55):(argc[i][6]-48)) +
213
(argc[i][7]>64?(toupper(argc[i][7])-55):(argc[i][7]-48));
216
if ( isxdigit(argc[i][9]) && isxdigit(argc[i][10]) && argc[i][11] == ':' )
217
ClientMACaddr[3] = 16*(argc[i][9]>64?(toupper(argc[i][9])-55):(argc[i][9]-48)) +
218
(argc[i][10]>64?(toupper(argc[i][10])-55):(argc[i][10]-48));
221
if ( isxdigit(argc[i][12]) && isxdigit(argc[i][13]) && argc[i][14] == ':' )
222
ClientMACaddr[4] = 16*(argc[i][12]>64?(toupper(argc[i][12])-55):(argc[i][12]-48)) +
223
(argc[i][13]>64?(toupper(argc[i][13])-55):(argc[i][13]-48));
226
if ( isxdigit(argc[i][15]) && isxdigit(argc[i][16]) )
227
ClientMACaddr[5] = 16*(argc[i][15]>64?(toupper(argc[i][15])-55):(argc[i][15]-48)) +
228
(argc[i][16]>64?(toupper(argc[i][16])-55):(argc[i][16]-48));
237
if ( argc[i][s+1] ) goto usage;
240
if ( ClassID == NULL || ClassID[0] == '-' ) goto usage;
242
if ( (ClassID_len=strlen(ClassID)) < CLASS_ID_MAX_LEN+1 ) break;
243
fprintf(stderr,"**** %s: too long ClassID string: strlen=%d\n",
244
argc[0],ClassID_len);
247
if ( argc[i][s+1] ) goto usage;
250
if ( ClientID == NULL || ClientID[0] == '-' ) goto usage;
252
if ( (ClientID_len=strlen(ClientID)) < CLIENT_ID_MAX_LEN+1 ) break;
253
fprintf(stderr,"**** %s: too long ClientID string: strlen=%d\n",
254
argc[0],ClientID_len);
257
if ( argc[i][s+1] ) goto usage;
260
if ( HostName == NULL || HostName[0] == '-' ) goto usage;
262
if ( (HostName_len=strlen(HostName)+1) < HOSTNAME_MAX_LEN ) break;
263
fprintf(stderr,"**** %s: too long HostName string: strlen=%d\n",
264
argc[0],HostName_len);
267
if ( argc[i][s+1] ) goto usage;
270
TimeOut=atol(argc[i++]);
274
if ( TimeOut >= 0 ) break;
277
if ( argc[i][s+1] ) goto usage;
280
Window=atol(argc[i++]);
284
if ( Window >= 0 ) break;
287
if ( argc[i][s+1] ) goto usage;
289
if ( argc[i] && inet_aton(argc[i],&inform_ipaddr) )
292
memset(&inform_ipaddr,0,sizeof(inform_ipaddr));
293
currState = &dhcpInform;
297
if ( argc[i][s+1] ) goto usage;
298
SetDHCPDefaultRoutes=0;
300
if ( argc[i] && inet_aton(argc[i],&default_router) )
303
memset(&default_router,0,sizeof(default_router));
320
SendSecondDiscover=1;
323
if ( argc[i][s+1] ) goto usage;
326
LeaseTime=atol(argc[i++]);
330
if ( LeaseTime > 0 ) break;
332
usage: print_version();
334
"Usage: dhcpcd [-dknprBCDHNRSTY] [-l leasetime] [-h hostname] [-t timeout]\n\
335
[-i vendorClassID] [-I ClientID] [-c filename] [-s [ipaddr]]\n\
336
[-w windowsize] [-L ConfigDir] [-G [gateway]] [interface]\n");
343
if ( (IfNameExt_len=strlen(argc[1])) > IFNAMSIZ ) goto usage;
346
IfName_len=IfNameExt_len;
348
while ( IfNameExt[s] )
349
if ( IfNameExt[s] == ':' )
351
IfName=(char *)malloc(s+1);
352
memcpy(IfName,IfNameExt,s);
363
if ( killFlag ) killPid(killFlag);
364
if ( ! TestCase ) checkIfAlreadyRunning();
365
if ( versionFlag ) print_version();
366
openlog(PROGRAM_NAME,LOG_PID|(DebugFlag?LOG_CONS:0),LOG_LOCAL0);
368
if ( mkdir(ConfigDir,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) && errno != EEXIST )
370
syslog(LOG_ERR,"mkdir(\"%s\",0): %m\n",ConfigDir);
373
magic_cookie = htonl(MAGIC_COOKIE);
374
dhcpMsgSize = htons(sizeof(dhcpMessage)+sizeof(udpiphdr));
375
nleaseTime = htonl(LeaseTime);
379
if ( (currState=(void *(*)())currState()) == NULL ) exit(1);
380
while ( currState != &dhcpBound );
382
if ( TestCase ) exit(0);
386
writePidFile(getpid());
396
exit(0); /* got into bound state. */
399
if ( (i=open("/dev/null",O_RDWR,0)) >= 0 )
401
(void)dup2(i,STDIN_FILENO);
402
(void)dup2(i,STDOUT_FILENO);
403
(void)dup2(i,STDERR_FILENO);
404
if ( i > 2 ) (void)close(i);
408
do currState=(void *(*)())currState(); while ( currState );