1/* dhcpc.c 2 * 3 * udhcp DHCP client 4 * 5 * Russ Dill <Russ.Dill@asu.edu> July 2001 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22#include <stdio.h> 23#include <sys/time.h> 24#include <sys/types.h> 25#include <sys/file.h> 26#include <unistd.h> 27#include <getopt.h> 28#include <stdlib.h> 29#include <sys/socket.h> 30#include <netinet/in.h> 31#include <arpa/inet.h> 32#include <signal.h> 33#include <time.h> 34#include <string.h> 35#include <sys/ioctl.h> 36#include <net/if.h> 37#include <errno.h> 38#include <sys/sysinfo.h> 39 40#include "dhcpd.h" 41#include "dhcpc.h" 42#include "options.h" 43#include "clientpacket.h" 44#include "packet.h" 45#include "script.h" 46#include "socket.h" 47#include "debug.h" 48#include "pidfile.h" 49 50static int state; 51static unsigned long requested_ip; /* = 0 */ 52static unsigned long server_addr; 53static unsigned long timeout = 0;; 54static int packet_num; /* = 0 */ 55static int fd; 56static int signal_pipe[2]; 57 58#define LISTEN_NONE 0 59#define LISTEN_KERNEL 1 60#define LISTEN_RAW 2 61//static int listen_mode; 62static int listen_mode = LISTEN_NONE;/* Foxconn modified by Max Ding, 04/12/2008 @dhcp_issue_of_KO */ 63 64static int run_on_lan = 0; /* Foxconn added pling 02/24/2011 */ 65 66#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" 67 68struct client_config_t client_config = { 69 /* Default options. */ 70 abort_if_no_lease: 0, 71 foreground: 0, 72 quit_after_lease: 0, 73 background_if_no_lease: 0, 74 interface: "eth0", 75 pidfile: NULL, 76 script: DEFAULT_SCRIPT, 77 clientid: NULL, 78 hostname: NULL, 79 ifindex: 0, 80 arp: "\0\0\0\0\0\0", /* appease gcc-3.0 */ 81}; 82 83/* Foxconn add start, Max Ding, 04/12/2008 for @dhcp_issue_of_KO */ 84#define MAJOR_NUM 100 85#define AG_MAX_ARG_CNT 32 86#define DEVICE_FILE_NAME "acos_nat_cli" 87#define DEV_FILE_NAME_W_PATH "/dev/"DEVICE_FILE_NAME 88#define IOCTL_AG_FW_LISTEN_PORT_SET _IOR(MAJOR_NUM, 61, char *) 89#define DEV_LISTEN_PORT_DHCPC 5 /* DHCP listen port: 68 */ 90 91typedef struct agIoctlParamPackage 92{ 93 int paramCnt; 94 int paramLen[AG_MAX_ARG_CNT]; 95 void* param[AG_MAX_ARG_CNT]; 96 97} T_agIoctlParamPkg; 98 99static int agApi_setDeviceListenPort(int port_idx, int port_num, int enable) 100{ 101 int ret_val=0, file_desc; 102 T_agIoctlParamPkg paramPkg; 103 104 file_desc = open(DEV_FILE_NAME_W_PATH, O_RDWR); 105 if (file_desc < 0) 106 { 107 return 0; 108 } 109 110 memset(¶mPkg, 0, sizeof(paramPkg)); 111 paramPkg.paramCnt = 3; 112 paramPkg.param[0] = (void *)port_idx; 113 paramPkg.param[1] = (void *)port_num; 114 paramPkg.param[2] = (void *)enable; 115 116 ret_val = ioctl(file_desc, IOCTL_AG_FW_LISTEN_PORT_SET, ¶mPkg); 117 118 close(file_desc); 119 120 if (paramPkg.paramCnt <= -1) 121 return paramPkg.paramCnt; 122 123 return ret_val; 124} 125/* Foxconn add end, Max Ding, 04/12/2008 */ 126 127 128#ifndef BB_VER 129static void show_usage(void) 130{ 131 printf( 132"Usage: udhcpc [OPTIONS]\n\n" 133" -c, --clientid=CLIENTID Client identifier\n" 134" -H, --hostname=HOSTNAME Client hostname\n" 135" -h Alias for -H\n" 136" -f, --foreground Do not fork after getting lease\n" 137" -b, --background Fork to background if lease cannot be\n" 138" immediately negotiated.\n" 139" -i, --interface=INTERFACE Interface to use (default: eth0)\n" 140" -n, --now Exit with failure if lease cannot be\n" 141" immediately negotiated.\n" 142" -p, --pidfile=file Store process ID of daemon in file\n" 143" -q, --quit Quit after obtaining lease\n" 144" -r, --request=IP IP address to request (default: none)\n" 145" -s, --script=file Run file at dhcp events (default:\n" 146" " DEFAULT_SCRIPT ")\n" 147" -v, --version Display version\n" 148 ); 149 exit(0); 150} 151#endif 152 153 154/* just a little helper */ 155static void change_mode(int new_mode) 156{ 157 DEBUG(LOG_INFO, "entering %s listen mode", 158 new_mode ? (new_mode == 1 ? "kernel" : "raw") : "none"); 159 close(fd); 160 fd = -1; 161 /* Foxconn add start, Max Ding, 04/12/2008 for @dhcp_issue_of_KO */ 162 if (new_mode == LISTEN_NONE) 163 { 164 if (listen_mode != LISTEN_NONE) 165 agApi_setDeviceListenPort(DEV_LISTEN_PORT_DHCPC, 68, 0); 166 } 167 else 168 { 169 if (listen_mode == LISTEN_NONE) 170 agApi_setDeviceListenPort(DEV_LISTEN_PORT_DHCPC, 68, 1); 171 } 172 /* Foxconn add end, Max Ding, 04/12/2008 */ 173 listen_mode = new_mode; 174} 175 176 177/* perform a renew */ 178static void perform_renew(void) 179{ 180 LOG(LOG_INFO, "Performing a DHCP renew"); 181 switch (state) { 182 case BOUND: 183 change_mode(LISTEN_KERNEL); 184 case RENEWING: 185 case REBINDING: 186 state = RENEW_REQUESTED; 187 break; 188 case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ 189 run_script(NULL, "deconfig"); 190 case REQUESTING: 191 case RELEASED: 192 change_mode(LISTEN_RAW); 193 state = INIT_SELECTING; 194 break; 195 case INIT_SELECTING: 196 break; 197 } 198 199 /* start things over */ 200 packet_num = 0; 201 202 /* Kill any timeouts because the user wants this to hurry along */ 203 timeout = 0; 204} 205 206 207/* perform a release */ 208static void perform_release(void) 209{ 210 char buffer[16]; 211 struct in_addr temp_addr; 212 213 /* send release packet */ 214 if (state == BOUND || state == RENEWING || state == REBINDING) { 215 temp_addr.s_addr = server_addr; 216 sprintf(buffer, "%s", inet_ntoa(temp_addr)); 217 temp_addr.s_addr = requested_ip; 218 LOG(LOG_INFO, "Unicasting a release of %s to %s", 219 inet_ntoa(temp_addr), buffer); 220 send_release(server_addr, requested_ip); /* unicast */ 221 run_script(NULL, "deconfig"); 222 } 223 LOG(LOG_INFO, "Entering released state"); 224 225 change_mode(LISTEN_NONE); 226 state = RELEASED; 227 timeout = 0x7fffffff; 228} 229 230 231/* Exit and cleanup */ 232static void exit_client(int retval) 233{ 234 /* Foxconn added start pling 02/07/2012 */ 235 /* WNDR4000 #TD53: GRC test port 68 is not closed. 236 * Force disable NAT device list port for port 68, before we termiante */ 237 if (listen_mode != LISTEN_NONE) 238 change_mode(LISTEN_NONE); 239 /* Foxconn added end pling 02/07/2012 */ 240 241 pidfile_delete(client_config.pidfile); 242 CLOSE_LOG(); 243 exit(retval); 244} 245 246 247/* Signal handler */ 248static void signal_handler(int sig) 249{ 250 if (write(signal_pipe[1], &sig, sizeof(sig)) < 0) { 251 LOG(LOG_ERR, "Could not send signal: %s", 252 strerror(errno)); 253 } 254} 255 256 257static void background(void) 258{ 259 int pid_fd; 260 261 pid_fd = pidfile_acquire(client_config.pidfile); /* hold lock during fork. */ 262 while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */ 263 if (daemon(0, 0) == -1) { 264 perror("fork"); 265 exit_client(1); 266 } 267 client_config.foreground = 1; /* Do not fork again. */ 268 pidfile_write_release(pid_fd); 269} 270 271 272#ifdef COMBINED_BINARY 273int udhcpc_main(int argc, char *argv[]) 274#else 275int main(int argc, char *argv[]) 276#endif 277{ 278 unsigned char *temp, *message; 279 unsigned long t1 = 0, t2 = 0, xid = 0; 280 unsigned long start = 0, lease; 281 fd_set rfds; 282 int retval; 283 struct timeval tv; 284 int c, len; 285 /* Foxconn modify start, Max Ding, 06/11/2010 fix memory overwrite issue */ 286 /* struct dhcpMessage packet; */ 287 struct udp_dhcp_packet_rcv packet; 288 /* Foxconn modify end, Max Ding, 06/11/2010 */ 289 struct in_addr temp_addr; 290 int pid_fd; 291 time_t now; 292 int max_fd; 293 int sig; 294 unsigned long curr_time; 295 struct sysinfo info; 296 297 static struct option arg_options[] = { 298 {"clientid", required_argument, 0, 'c'}, 299 {"foreground", no_argument, 0, 'f'}, 300 {"background", no_argument, 0, 'b'}, 301 {"hostname", required_argument, 0, 'H'}, 302 {"hostname", required_argument, 0, 'h'}, 303 {"interface", required_argument, 0, 'i'}, 304 {"now", no_argument, 0, 'n'}, 305 {"pidfile", required_argument, 0, 'p'}, 306 {"quit", no_argument, 0, 'q'}, 307 {"request", required_argument, 0, 'r'}, 308 {"script", required_argument, 0, 's'}, 309 {"version", no_argument, 0, 'v'}, 310 {"help", no_argument, 0, '?'}, 311 {0, 0, 0, 0} 312 }; 313 314 /* get options */ 315 while (1) { 316 int option_index = 0; 317 /* Foxconn modified start pling 02/24/2011 */ 318 /* Add option '-l' to tell this runs on LAN (LAN auto ip) */ 319#if 0 320 c = getopt_long(argc, argv, "c:fbH:h:i:np:qr:s:v", arg_options, &option_index); 321#endif 322 c = getopt_long(argc, argv, "c:fbH:h:i:np:qr:s:vl", 323 arg_options, &option_index); 324 /* Foxconn modified end pling 02/24/2011 */ 325 if (c == -1) break; 326 327 switch (c) { 328 case 'c': 329 len = strlen(optarg) > 255 ? 255 : strlen(optarg); 330 if (client_config.clientid) free(client_config.clientid); 331 client_config.clientid = xmalloc(len + 2); 332 client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID; 333 client_config.clientid[OPT_LEN] = len; 334 client_config.clientid[OPT_DATA] = '\0'; 335 strncpy(client_config.clientid + OPT_DATA, optarg, len); 336 break; 337 case 'f': 338 client_config.foreground = 1; 339 break; 340 case 'b': 341 client_config.background_if_no_lease = 1; 342 break; 343 case 'h': 344 case 'H': 345 len = strlen(optarg) > 255 ? 255 : strlen(optarg); 346 if (client_config.hostname) free(client_config.hostname); 347 client_config.hostname = xmalloc(len + 2); 348 client_config.hostname[OPT_CODE] = DHCP_HOST_NAME; 349 client_config.hostname[OPT_LEN] = len; 350 strncpy(client_config.hostname + 2, optarg, len); 351 break; 352 case 'i': 353 client_config.interface = optarg; 354 break; 355 case 'n': 356 client_config.abort_if_no_lease = 1; 357 break; 358 case 'p': 359 client_config.pidfile = optarg; 360 break; 361 case 'q': 362 client_config.quit_after_lease = 1; 363 break; 364 case 'r': 365 requested_ip = inet_addr(optarg); 366 break; 367 case 's': 368 client_config.script = optarg; 369 break; 370 case 'v': 371 printf("udhcpcd, version %s\n\n", VERSION); 372 exit_client(0); 373 break; 374 /* Foxconn added start pling 02/24/2011 */ 375 /* LAN Auto IP changes */ 376 case 'l': 377 run_on_lan = 1; 378 LOG(LOG_INFO, "run on LAN!\n"); 379 break; 380 /* Foxconn added end pling 02/24/2011 */ 381 default: 382 show_usage(); 383 } 384 } 385 386 OPEN_LOG("udhcpc"); 387 LOG(LOG_INFO, "udhcp client (v%s) started", VERSION); 388 389 pid_fd = pidfile_acquire(client_config.pidfile); 390 pidfile_write_release(pid_fd); 391 392 if (read_interface(client_config.interface, &client_config.ifindex, 393 NULL, client_config.arp) < 0) 394 exit_client(1); 395 396 if (!client_config.clientid) { 397 client_config.clientid = xmalloc(6 + 3); 398 client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID; 399 client_config.clientid[OPT_LEN] = 7; 400 client_config.clientid[OPT_DATA] = 1; 401 memcpy(client_config.clientid + 3, client_config.arp, 6); 402 } 403 404 /* ensure that stdin/stdout/stderr are never returned by pipe() */ 405 if (fcntl(STDIN_FILENO, F_GETFL) == -1) 406 (void) open("/dev/null", O_RDONLY); 407 if (fcntl(STDOUT_FILENO, F_GETFL) == -1) 408 (void) open("/dev/null", O_WRONLY); 409 if (fcntl(STDERR_FILENO, F_GETFL) == -1) 410 (void) open("/dev/null", O_WRONLY); 411 412 /* setup signal handlers */ 413 pipe(signal_pipe); 414 signal(SIGUSR1, signal_handler); 415 signal(SIGUSR2, signal_handler); 416 signal(SIGTERM, signal_handler); 417 418 state = INIT_SELECTING; 419 run_script(NULL, "deconfig"); 420 change_mode(LISTEN_RAW); 421 422 for (;;) { 423 424 sysinfo(&info); 425 curr_time = (unsigned long)(info.uptime); 426 427 if (timeout > curr_time) 428 tv.tv_sec = timeout - curr_time; 429 else 430 tv.tv_sec = 0; 431 tv.tv_usec = 0; 432 FD_ZERO(&rfds); 433 434 if (listen_mode != LISTEN_NONE && fd < 0) { 435 if (listen_mode == LISTEN_KERNEL) 436 fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface); 437 else 438 fd = raw_socket(client_config.ifindex); 439 if (fd < 0) { 440 LOG(LOG_ERR, "FATAL: couldn't listen on socket, %s", strerror(errno)); 441 exit_client(0); 442 } 443 } 444 if (fd >= 0) FD_SET(fd, &rfds); 445 FD_SET(signal_pipe[0], &rfds); 446 447 if (tv.tv_sec > 0) { 448 DEBUG(LOG_INFO, "Waiting on select...\n"); 449 max_fd = signal_pipe[0] > fd ? signal_pipe[0] : fd; 450 retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); 451 } else retval = 0; /* If we already timed out, fall through */ 452 453 sysinfo(&info); 454 now = (unsigned long)(info.uptime); 455 if (retval == 0) { 456 /* timeout dropped to zero */ 457 switch (state) { 458 case INIT_SELECTING: 459 if (packet_num < 3) { 460 if (packet_num == 0) 461 xid = random_xid(); 462 463 /* send discover packet */ 464 send_discover(xid, requested_ip); /* broadcast */ 465 466 /* foxconn James modified start, 11/12/2008 @new_internet_detection */ 467#ifdef NEW_WANDETECT 468 timeout = now + ((packet_num == 2) ? 4 : 3); 469#else 470 timeout = now + ((packet_num == 2) ? 4 : 2); 471#endif 472 /* foxconn James modified end, 11/12/2008 @new_internet_detection */ 473 474 packet_num++; 475 } else { 476 if (client_config.background_if_no_lease) { 477 LOG(LOG_INFO, "No lease, forking to background."); 478 background(); 479 } else if (client_config.abort_if_no_lease) { 480 LOG(LOG_INFO, "No lease, failing."); 481 exit_client(1); 482 } 483 /* wait to try again */ 484 packet_num = 0; 485 timeout = now + 60; 486 487 /* Foxconn added start pling 02/24/2011 */ 488 /* No lease found yet, signal 'autoipd' 489 * to start Auto IP process */ 490 if (run_on_lan) { 491 system("killall -SIGUSR1 autoipd 2>/dev/null"); 492 /* Per Netgear Router Spec 2.0, need to resend 493 * DHCP Discover every 4 minutes. 494 */ 495 timeout = now + 240; 496 } 497 /* Foxconn added end pling 02/24/2011 */ 498 } 499 break; 500 case RENEW_REQUESTED: 501 case REQUESTING: 502 if (packet_num < 3) { 503 /* send request packet */ 504 if (state == RENEW_REQUESTED) 505 send_renew(xid, server_addr, requested_ip); /* unicast */ 506 else send_selecting(xid, server_addr, requested_ip); /* broadcast */ 507 508 timeout = now + ((packet_num == 2) ? 10 : 2); 509 packet_num++; 510 } else { 511 /* timed out, go back to init state */ 512 if (state == RENEW_REQUESTED) run_script(NULL, "deconfig"); 513 state = INIT_SELECTING; 514 timeout = now; 515 packet_num = 0; 516 change_mode(LISTEN_RAW); 517 } 518 break; 519 case BOUND: 520 /* Lease is starting to run out, time to enter renewing state */ 521 state = RENEWING; 522 change_mode(LISTEN_KERNEL); 523 DEBUG(LOG_INFO, "Entering renew state"); 524 /* fall right through */ 525 case RENEWING: 526 /* Either set a new T1, or enter REBINDING state */ 527 if ((t2 - t1) <= (lease / 14400 + 1)) { 528 /* timed out, enter rebinding state */ 529 state = REBINDING; 530 timeout = now + (t2 - t1); 531 DEBUG(LOG_INFO, "Entering rebinding state"); 532 } else { 533 /* send a request packet */ 534 send_renew(xid, server_addr, requested_ip); /* unicast */ 535 536 t1 = (t2 - t1) / 2 + t1; 537 timeout = t1 + start; 538 } 539 break; 540 case REBINDING: 541 /* Either set a new T2, or enter INIT state */ 542 if ((lease - t2) <= (lease / 14400 + 1)) { 543 /* timed out, enter init state */ 544 state = INIT_SELECTING; 545 LOG(LOG_INFO, "Lease lost, entering init state"); 546 run_script(NULL, "deconfig"); 547 timeout = now; 548 packet_num = 0; 549 change_mode(LISTEN_RAW); 550 } else { 551 /* send a request packet */ 552 send_renew(xid, 0, requested_ip); /* broadcast */ 553 554 t2 = (lease - t2) / 2 + t2; 555 timeout = t2 + start; 556 } 557 break; 558 case RELEASED: 559 /* yah, I know, *you* say it would never happen */ 560 timeout = 0x7fffffff; 561 break; 562 } 563 } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) { 564 /* a packet is ready, read it */ 565 566 /* Foxconn modify start, Max Ding, 06/11/2010 */ 567 if (listen_mode == LISTEN_KERNEL) 568 /* len = get_packet(&packet, fd); */ 569 len = get_packet(&packet.data, fd); 570 /* else len = get_raw_packet(&packet, fd); */ 571 else len = get_raw_packet(&packet.data, fd); 572 /* Foxconn modify start, Max Ding, 06/11/2010 */ 573 574 if (len == -1 && errno != EINTR) { 575 DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno)); 576 change_mode(listen_mode); /* just close and reopen */ 577 } 578 if (len < 0) continue; 579 580 /* Foxconn modify start, Max Ding, 06/11/2010 */ 581 /* if (packet.xid != xid) { */ 582 if (packet.data.xid != xid) { 583 DEBUG(LOG_INFO, "Ignoring XID %lx (our xid is %lx)", 584 /* (unsigned long) packet.xid, xid); */ 585 (unsigned long) packet.data.xid, xid); 586 continue; 587 } 588 589 /* if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { */ 590 if ((message = get_option(&packet.data, DHCP_MESSAGE_TYPE)) == NULL) { 591 DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring"); 592 continue; 593 } 594 /* Foxconn modify end, Max Ding, 06/11/2010 */ 595 596 switch (state) { 597 case INIT_SELECTING: 598 /* Must be a DHCPOFFER to one of our xid's */ 599 /* Foxconn modify start, Max Ding, 06/11/2010 */ 600 if (*message == DHCPOFFER) { 601 /* if ((temp = get_option(&packet, DHCP_SERVER_ID))) { */ 602 if ((temp = get_option(&packet.data, DHCP_SERVER_ID))) { 603 memcpy(&server_addr, temp, 4); 604 /* xid = packet.xid; 605 requested_ip = packet.yiaddr; */ 606 xid = packet.data.xid; 607 requested_ip = packet.data.yiaddr; 608 /* enter requesting state */ 609 state = REQUESTING; 610 timeout = now; 611 packet_num = 0; 612 } else { 613 DEBUG(LOG_ERR, "No server ID in message"); 614 } 615 } 616 /* Foxconn modify end, Max Ding, 06/11/2010 */ 617 break; 618 case RENEW_REQUESTED: 619 case REQUESTING: 620 case RENEWING: 621 case REBINDING: 622 if (*message == DHCPACK) { 623 /* Foxconn modify start, Max Ding, 06/11/2010 */ 624 /* if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) { */ 625 if (!(temp = get_option(&packet.data, DHCP_LEASE_TIME))) { 626 /* Foxconn modify end, Max Ding, 06/11/2010 */ 627 LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease"); 628 lease = 60 * 60; 629 } else { 630 memcpy(&lease, temp, 4); 631 lease = ntohl(lease); 632 } 633 634 /* wklin added start, 08/10/2007 */ 635 /* check before entering requesting state */ 636 /* Foxconn modify start, Max Ding, 06/11/2010 */ 637 /* Foxconn modified start pling 05/27/2010 */ 638 u_int32_t addr_to_arp; 639 if (state == REQUESTING) 640 addr_to_arp = 0; 641 else 642 addr_to_arp = requested_ip; 643 /* if (arpping(packet.yiaddr, 0, */ 644 if (arpping(packet.data.yiaddr, addr_to_arp, 645 /* Foxconn modified end pling 05/27/2010 */ 646 client_config.arp, client_config.interface)==0) { 647 /* send_decline(packet.xid, server_addr, packet.yiaddr); *//* broadcast */ 648 send_decline(packet.data.xid, server_addr, packet.data.yiaddr); /* broadcast */ 649 /* return to init state */ 650 state = INIT_SELECTING; 651 timeout = now; 652 requested_ip = 0; 653 packet_num = 0; 654 change_mode(LISTEN_RAW); 655 sleep(10); /* per the RFC, avoid excessive network traffic */ 656 break; 657 } 658 /* Foxconn modify end, Max Ding, 06/11/2010 */ 659 /* wklin added end, 08/10/2007 */ 660 /* enter bound state */ 661 t1 = lease / 2; 662 663 /* little fixed point for n * .875 */ 664 t2 = (lease * 0x7) >> 3; 665 /* Foxconn modify start, Max Ding, 06/11/2010 */ 666 /* temp_addr.s_addr = packet.yiaddr; */ 667 temp_addr.s_addr = packet.data.yiaddr; 668 LOG(LOG_INFO, "Lease of %s obtained, lease time %ld", 669 inet_ntoa(temp_addr), lease); 670 start = now; 671 timeout = t1 + start; 672 /* requested_ip = packet.yiaddr; */ 673 requested_ip = packet.data.yiaddr; 674 remove("/tmp/udhcpc.routes");/*foxconn added, water, 03/08/10, @option249*/ 675 /* run_script(&packet, */ 676 run_script(&packet.data, 677 ((state == RENEWING || state == REBINDING) ? "renew" : "bound")); 678 /* Foxconn modify end, Max Ding, 06/11/2010 */ 679 680 state = BOUND; 681 change_mode(LISTEN_NONE); 682 if (client_config.quit_after_lease) 683 exit_client(0); 684 if (!client_config.foreground) 685 background(); 686 687 } else if (*message == DHCPNAK) { 688 /* return to init state */ 689 LOG(LOG_INFO, "Received DHCP NAK"); 690 /* run_script(&packet, "nak"); */ 691 run_script(&packet.data, "nak");/* Foxconn modified by Max Ding, 06/11/2010 */ 692 if (state != REQUESTING) 693 run_script(NULL, "deconfig"); 694 state = INIT_SELECTING; 695 timeout = now; 696 requested_ip = 0; 697 packet_num = 0; 698 change_mode(LISTEN_RAW); 699 sleep(3); /* avoid excessive network traffic */ 700 } 701 break; 702 /* case BOUND, RELEASED: - ignore all packets */ 703 } 704 } else if (retval > 0 && FD_ISSET(signal_pipe[0], &rfds)) { 705 if (read(signal_pipe[0], &sig, sizeof(sig)) < 0) { 706 DEBUG(LOG_ERR, "Could not read signal: %s", 707 strerror(errno)); 708 continue; /* probably just EINTR */ 709 } 710 switch (sig) { 711 case SIGUSR1: 712 perform_renew(); 713 break; 714 case SIGUSR2: 715 perform_release(); 716 break; 717 case SIGTERM: 718 LOG(LOG_INFO, "Received SIGTERM"); 719 exit_client(0); 720 } 721 } else if (retval == -1 && errno == EINTR) { 722 /* a signal was caught */ 723 } else { 724 /* An error occured */ 725 DEBUG(LOG_ERR, "Error on select"); 726 } 727 728 } 729 return 0; 730} 731 732