[
  [
    "udhcp-0.9.8.orig/dhcpc.c", 
    "udhcp-0.9.8/dhcpc.c", 
    [
      "Index: udhcp-0.9.8/dhcpc.c", 
      "===================================================================", 
      "--- udhcp-0.9.8.orig/dhcpc.c", 
      "+++ udhcp-0.9.8/dhcpc.c", 
      "@@ -1,3 +1,4 @@", 
      "+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */", 
      "/* dhcpc.c", 
      "*", 
      "* udhcp DHCP client", 
      "@@ -23,6 +24,7 @@", 
      "#include <sys/time.h>", 
      "#include <sys/types.h>", 
      "#include <sys/file.h>", 
      "+#include <sys/sysinfo.h>", 
      "#include <unistd.h>", 
      "#include <getopt.h>", 
      "#include <stdlib.h>", 
      "@@ -35,6 +37,8 @@", 
      "#include <sys/ioctl.h>", 
      "#include <net/if.h>", 
      "#include <errno.h>", 
      "+#include <netdb.h>", 
      "+#include <arpa/inet.h>", 
      "", 
      "#include \"dhcpd.h\"", 
      "#include \"dhcpc.h\"", 
      "@@ -45,9 +49,10 @@", 
      "#include \"socket.h\"", 
      "#include \"debug.h\"", 
      "#include \"pidfile.h\"", 
      "+#include \"arpping.h\"", 
      "", 
      "static int state;", 
      "-static unsigned long requested_ip; /* = 0 */", 
      "+static unsigned long requested_ip = 0;", 
      "static unsigned long server_addr;", 
      "static unsigned long timeout;", 
      "static int packet_num; /* = 0 */", 
      "@@ -59,11 +64,19 @@ static int signal_pipe[2];", 
      "#define LISTEN_RAW 2", 
      "static int listen_mode;", 
      "", 
      "-#define DEFAULT_SCRIPT\t\"/usr/share/udhcpc/default.script\"", 
      "+#define DEFAULT_SCRIPT\t\"/etc/udhcpc.script\"", 
      "+", 
      "+#define EXIT_CODE_FAILED_DISCOVER 100", 
      "+#define EXIT_CODE_FAILED_REQUEST 101", 
      "+#define EXIT_CODE_EXPIRED_LEASE 102", 
      "", 
      "struct client_config_t client_config = {", 
      "/* Default options. */", 
      "abort_if_no_lease: 0,", 
      "+        abort_if_failed_request: 0,", 
      "+        abort_if_expired_lease: 0,", 
      "+        no_deconfig_on_expire: 0,", 
      "+        process_zero_source_packet: 0,", 
      "foreground: 0,", 
      "quit_after_lease: 0,", 
      "background_if_no_lease: 0,", 
      "@@ -71,36 +84,63 @@ struct client_config_t client_config = {", 
      "pidfile: NULL,", 
      "script: DEFAULT_SCRIPT,", 
      "clientid: NULL,", 
      "+        userclientid: NULL,", 
      "hostname: NULL,", 
      "ifindex: 0,", 
      "+        start_init_reboot: 0,", 
      "+        start_renew: 0,", 
      "+        address_renewal_behaviour: 0,", 
      "+        leasetime: 0,", 
      "arp: \"\\0\\0\\0\\0\\0\\0\",\t\t/* appease gcc-3.0 */", 
      "};", 
      "", 
      "#ifndef BB_VER", 
      "static void show_usage(void)", 
      "{", 
      "-\tprintf(", 
      "+\tfprintf(stdout,", 
      "\"Usage: udhcpc [OPTIONS]\\n\\n\"", 
      "-\"  -c, --clientid=CLIENTID         Client identifier\\n\"", 
      "-\"  -H, --hostname=HOSTNAME         Client hostname\\n\"", 
      "-\"  -h                              Alias for -H\\n\"", 
      "-\"  -f, --foreground                Do not fork after getting lease\\n\"", 
      "-\"  -b, --background                Fork to background if lease cannot be\\n\"", 
      "-\"                                  immediately negotiated.\\n\"", 
      "-\"  -i, --interface=INTERFACE       Interface to use (default: eth0)\\n\"", 
      "-\"  -n, --now                       Exit with failure if lease cannot be\\n\"", 
      "-\"                                  immediately negotiated.\\n\"", 
      "-\"  -p, --pidfile=file              Store process ID of daemon in file\\n\"", 
      "-\"  -q, --quit                      Quit after obtaining lease\\n\"", 
      "-\"  -r, --request=IP                IP address to request (default: none)\\n\"", 
      "-\"  -s, --script=file               Run file at dhcp events (default:\\n\"", 
      "-\"                                  \" DEFAULT_SCRIPT \")\\n\"", 
      "-\"  -v, --version                   Display version\\n\"", 
      "-\t);", 
      "+\"  -c, --clientid=CLIENTID          Client identifier\\n\"", 
      "+\"  -u, --userclientid=USER_ID       User Class identifier\\n\"", 
      "+\"  -H, --hostname=HOSTNAME          Client hostname\\n\"", 
      "+\"  -h                               Alias for -H\\n\"", 
      "+\"  -f, --foreground                 Do not fork after getting lease\\n\"", 
      "+\"  -b, --background                 Fork to background if lease cannot be\\n\"", 
      "+\"                                   immediately negotiated.\\n\"", 
      "+\"  -i, --interface=INTERFACE        Interface to use (default: eth0)\\n\"", 
      "+\"  -n, --exit-on-failed-discover    Exit with failure code %d if lease cannot\\n\"", 
      "+\"                                   be immediately negotiated.\\n\"", 
      "+\"  -p, --pidfile=file               Store process ID of daemon in file\\n\"", 
      "+\"  -q, --quit                       Quit after obtaining lease\\n\"", 
      "+\"  -r, --request=IP                 IP address to request (default: none)\\n\"", 
      "+\"  -l, --leasetime=TIME             IP address to request (default: none)\\n\"", 
      "+\"  -s, --script=file                Run file at dhcp events (default:\\n\"", 
      "+\"                                   \" DEFAULT_SCRIPT \")\\n\"", 
      "+\"  -v, --version                    Display version\\n\"", 
      "+\"  -e                               Start in INIT-REBOOT state\\n\"", 
      "+\"  -w, --renew=DHCPSERVER           Start with renewing lease, instead of\\n\"", 
      "+\"                                   discover\\n\"", 
      "+\"                                   Requires IP address of DHCP server\\n\"", 
      "+\"      --exit-on-failed-request     Exit with failure code %d if request fails\\n\"", 
      "+\"      --exit-on-expired-lease      Exit with failure code %d if lease expires\\n\"", 
      "+\"      --no-deconfig-on-expire      Do not run deconfig script when lease\\n\"", 
      "+\"                                   expires\\n\"", 
      "+\"      --process-zero-source-packet Process ACKs with zero source IP-address.\\n\"", 
      "+\"                                   This is a compatibility option for certain\\n\"", 
      "+\"                                   DHCP relay agents, and is disabled by\\n\"", 
      "+\"                                   default because it makes DoS attacks\\n\"", 
      "+\"                                   easier.\\n\",", 
      "+                EXIT_CODE_FAILED_DISCOVER, EXIT_CODE_FAILED_REQUEST,", 
      "+                EXIT_CODE_EXPIRED_LEASE);", 
      "exit(0);", 
      "}", 
      "#endif", 
      "", 
      "+long uptime(void)", 
      "+{", 
      "+        struct sysinfo info;", 
      "+        sysinfo(&info);", 
      "+        return info.uptime;", 
      "+}", 
      "", 
      "/* just a little helper */", 
      "static void change_mode(int new_mode)", 
      "@@ -132,6 +172,7 @@ static void perform_renew(void)", 
      "state = INIT_SELECTING;", 
      "break;", 
      "case INIT_SELECTING:", 
      "+                break;", 
      "}", 
      "", 
      "/* start things over */", 
      "@@ -155,7 +196,10 @@ static void perform_release(void)", 
      "temp_addr.s_addr = requested_ip;", 
      "LOG(LOG_INFO, \"Unicasting a release of %s to %s\",", 
      "inet_ntoa(temp_addr), buffer);", 
      "-\t\tsend_release(server_addr, requested_ip); /* unicast */", 
      "+                if (send_release(server_addr, requested_ip) == -1) { /* unicast */", 
      "+                        LOG(LOG_WARNING, \"Unable to send DHCPRELEASE - %s\",", 
      "+                            strerror(errno));", 
      "+                }", 
      "run_script(NULL, \"deconfig\");", 
      "}", 
      "LOG(LOG_INFO, \"Entering released state\");", 
      "@@ -169,6 +213,7 @@ static void perform_release(void)", 
      "/* Exit and cleanup */", 
      "static void exit_client(int retval)", 
      "{", 
      "+        LOG(LOG_INFO, \"Exiting with code %d\", retval);", 
      "pidfile_delete(client_config.pidfile);", 
      "CLOSE_LOG();", 
      "exit(retval);", 
      "@@ -199,7 +244,6 @@ static void background(void)", 
      "pidfile_write_release(pid_fd);", 
      "}", 
      "", 
      "-", 
      "#ifdef COMBINED_BINARY", 
      "int udhcpc_main(int argc, char *argv[])", 
      "#else", 
      "@@ -208,7 +252,7 @@ int main(int argc, char *argv[])", 
      "{", 
      "unsigned char *temp, *message;", 
      "unsigned long t1 = 0, t2 = 0, xid = 0;", 
      "-\tunsigned long start = 0, lease;", 
      "+\tunsigned long start = 0, lease = 0;", 
      "fd_set rfds;", 
      "int retval;", 
      "struct timeval tv;", 
      "@@ -216,23 +260,33 @@ int main(int argc, char *argv[])", 
      "struct dhcpMessage packet;", 
      "struct in_addr temp_addr;", 
      "int pid_fd;", 
      "-\ttime_t now;", 
      "+\tlong now;", 
      "int max_fd;", 
      "int sig;", 
      "+       int numOfDiscoverMsg = 0;", 
      "+\tint arpret;", 
      "", 
      "static struct option arg_options[] = {", 
      "{\"clientid\",\trequired_argument,\t0, 'c'},", 
      "+\t\t{\"userclientid\", required_argument,\t0, 'u'},", 
      "{\"foreground\",\tno_argument,\t\t0, 'f'},", 
      "{\"background\",\tno_argument,\t\t0, 'b'},", 
      "{\"hostname\",\trequired_argument,\t0, 'H'},", 
      "{\"hostname\",    required_argument,      0, 'h'},", 
      "{\"interface\",\trequired_argument,\t0, 'i'},", 
      "-\t\t{\"now\", \tno_argument,\t\t0, 'n'},", 
      "+\t\t{\"exit-on-failed-discover\", no_argument,0, 'n'},", 
      "{\"pidfile\",\trequired_argument,\t0, 'p'},", 
      "{\"quit\",\tno_argument,\t\t0, 'q'},", 
      "{\"request\",\trequired_argument,\t0, 'r'},", 
      "+                {\"leasetime\",\trequired_argument,\t0, 'l'},", 
      "{\"script\",\trequired_argument,\t0, 's'},", 
      "{\"version\",\tno_argument,\t\t0, 'v'},", 
      "+                {\"init-reboot\",\tno_argument,\t\t0, 'e'},", 
      "+\t\t{\"renew\",\trequired_argument,\t0, 'w'},", 
      "+                {\"exit-on-failed-request\", no_argument, 0, 10},", 
      "+                {\"exit-on-expired-lease\", no_argument,  0, 11},", 
      "+                {\"no-deconfig-on-expire\", no_argument,  0, 12},", 
      "+                {\"process-zero-source-packet\", no_argument,  0, 13},", 
      "{\"help\",\tno_argument,\t\t0, '?'},", 
      "{0, 0, 0, 0}", 
      "};", 
      "@@ -240,19 +294,47 @@ int main(int argc, char *argv[])", 
      "/* get options */", 
      "while (1) {", 
      "int option_index = 0;", 
      "-\t\tc = getopt_long(argc, argv, \"c:fbH:h:i:np:qr:s:v\", arg_options, &option_index);", 
      "+                c = getopt_long(argc, argv, \"c:u:fbH:h:i:l:np:qr:s:vew:z\", arg_options, &option_index);", 
      "if (c == -1) break;", 
      "", 
      "switch (c) {", 
      "+                case 10:", 
      "+                        LOG(LOG_INFO, \"Will abort if request fails.\");", 
      "+                        client_config.abort_if_failed_request = 1;", 
      "+                        break;", 
      "+                case 11:", 
      "+                        LOG(LOG_INFO, \"Will abort if lease expires.\");", 
      "+                        client_config.abort_if_expired_lease = 1;", 
      "+                        break;", 
      "+                case 12:", 
      "+                        LOG(LOG_INFO, \"Will not run deconfig script when lease expires.\");", 
      "+                        client_config.no_deconfig_on_expire = 1;", 
      "+                        break;", 
      "+                case 13:", 
      "+                        LOG(LOG_INFO, \"WARNING: Will process zero source packets!\");", 
      "+                        client_config.process_zero_source_packet = 1;", 
      "+                        break;", 
      "case 'c':", 
      "len = strlen(optarg) > 255 ? 255 : strlen(optarg);", 
      "if (client_config.clientid) free(client_config.clientid);", 
      "client_config.clientid = xmalloc(len + 2);", 
      "+#ifdef KBOX", 
      "+\t\t\tclient_config.clientid[OPT_CODE] = DHCP_VENDOR;", 
      "+#else", 
      "client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;", 
      "+#endif", 
      "client_config.clientid[OPT_LEN] = len;", 
      "client_config.clientid[OPT_DATA] = '\\0';", 
      "strncpy(client_config.clientid + OPT_DATA, optarg, len);", 
      "break;", 
      "+\t\tcase 'u':", 
      "+\t\t\tlen = strlen(optarg) > 255 ? 255 : strlen(optarg);", 
      "+\t\t\tif (client_config.userclientid) free(client_config.userclientid);", 
      "+\t\t\tclient_config.userclientid = xmalloc(len + 2);", 
      "+\t\t\tclient_config.userclientid[OPT_CODE] = DHCP_USER_CLASS_ID;", 
      "+\t\t\tclient_config.userclientid[OPT_LEN] = len;", 
      "+\t\t\tstrncpy(client_config.userclientid + OPT_DATA, optarg, len);", 
      "+\t\t\tbreak;", 
      "case 'f':", 
      "client_config.foreground = 1;", 
      "break;", 
      "@@ -272,6 +354,7 @@ int main(int argc, char *argv[])", 
      "client_config.interface =  optarg;", 
      "break;", 
      "case 'n':", 
      "+                        LOG(LOG_INFO, \"Will abort if discover fails.\");", 
      "client_config.abort_if_no_lease = 1;", 
      "break;", 
      "case 'p':", 
      "@@ -283,6 +366,9 @@ int main(int argc, char *argv[])", 
      "case 'r':", 
      "requested_ip = inet_addr(optarg);", 
      "break;", 
      "+                case 'l':", 
      "+\t\t\tclient_config.leasetime = htonl(atoi(optarg));", 
      "+\t\t\tbreak;", 
      "case 's':", 
      "client_config.script = optarg;", 
      "break;", 
      "@@ -290,6 +376,27 @@ int main(int argc, char *argv[])", 
      "printf(\"udhcpcd, version %s\\n\\n\", VERSION);", 
      "exit_client(0);", 
      "break;", 
      "+                case 'e':", 
      "+                        client_config.start_init_reboot = 1;", 
      "+                        break;", 
      "+                case 'w':", 
      "+                        {", 
      "+                                server_addr = inet_addr(optarg);", 
      "+                                DEBUG(LOG_DEBUG, \"Server address: %s (%lx)\", optarg, server_addr);", 
      "+                                if (server_addr == INADDR_NONE) {", 
      "+                                        LOG(LOG_WARNING, \"Unable to parse DHCP server address.\");", 
      "+                                        server_addr = 0;", 
      "+                                }", 
      "+                                else if (server_addr == 0) {", 
      "+                                        client_config.start_renew = 1;", 
      "+                                        LOG(LOG_INFO, \"Server address zero. Going to renew state, but broadcast instead of unicast.\");", 
      "+                                }", 
      "+                                else {", 
      "+                                        client_config.start_renew = 1;", 
      "+                                        LOG(LOG_INFO, \"Using DHCP server %s\", optarg);", 
      "+                                }", 
      "+                        }", 
      "+                        break;", 
      "default:", 
      "show_usage();", 
      "}", 
      "@@ -301,8 +408,16 @@ int main(int argc, char *argv[])", 
      "pid_fd = pidfile_acquire(client_config.pidfile);", 
      "pidfile_write_release(pid_fd);", 
      "", 
      "+        unsigned long* addr = NULL;", 
      "+", 
      "+#ifdef KBOX", 
      "+        // Leaving this for now", 
      "+        if (requested_ip == 0) {", 
      "+          addr = &requested_ip;", 
      "+        }", 
      "+#endif  // KBOX", 
      "if (read_interface(client_config.interface, &client_config.ifindex,", 
      "-\t\t\t   NULL, client_config.arp) < 0)", 
      "+\t\t\t   &addr, client_config.arp) < 0)", 
      "exit_client(1);", 
      "", 
      "if (!client_config.clientid) {", 
      "@@ -317,15 +432,54 @@ int main(int argc, char *argv[])", 
      "socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);", 
      "signal(SIGUSR1, signal_handler);", 
      "signal(SIGUSR2, signal_handler);", 
      "+#ifdef KBOX", 
      "+\tsignal(SIGHUP, signal_handler);", 
      "+#endif", 
      "signal(SIGTERM, signal_handler);", 
      "", 
      "-\tstate = INIT_SELECTING;", 
      "-\trun_script(NULL, \"deconfig\");", 
      "-\tchange_mode(LISTEN_RAW);", 
      "+        if (client_config.start_init_reboot && client_config.start_renew) {", 
      "+                LOG(LOG_ERR, \"Can not use both -e and -w at the same time\");", 
      "+                exit_client(0);", 
      "+        }", 
      "+", 
      "+        if (client_config.start_init_reboot || client_config.start_renew) {", 
      "+                char hostname[128];", 
      "+                gethostname(hostname, sizeof(hostname));", 
      "+                struct hostent* he = gethostbyname(hostname);", 
      "+                struct in_addr* ia = (struct in_addr*)he->h_addr;", 
      "+                requested_ip = ia->s_addr;", 
      "+        }", 
      "+", 
      "+        if (client_config.start_renew) {", 
      "+                state = RENEWING;", 
      "+                xid = random_xid();", 
      "+                lease = 60;", 
      "+                start = uptime();", 
      "+                t1 = lease / 2;", 
      "+                t2 = (lease * 0x7) >> 3;", 
      "+                DEBUG(LOG_DEBUG, \"Setting state RENEWING. xid=%lx\", xid);", 
      "+                if (client_config.process_zero_source_packet) {", 
      "+                        change_mode(LISTEN_RAW);", 
      "+                } else {", 
      "+                        change_mode(LISTEN_KERNEL);", 
      "+                }", 
      "+                run_script(NULL, \"prerenew\");", 
      "+        }", 
      "+        else if (client_config.start_init_reboot) {", 
      "+                state = INIT_REBOOTING;", 
      "+                change_mode(LISTEN_RAW);", 
      "+                LOG(LOG_INFO, \"Setting state INIT_REBOOTING.\");", 
      "+        }", 
      "+        else {", 
      "+                state = INIT_SELECTING;", 
      "+                change_mode(LISTEN_RAW);", 
      "+        }", 
      "+", 
      "+        timeout = uptime() - 10;", 
      "", 
      "for (;;) {", 
      "", 
      "-\t\ttv.tv_sec = timeout - time(0);", 
      "+\t\ttv.tv_sec = timeout - uptime();", 
      "tv.tv_usec = 0;", 
      "FD_ZERO(&rfds);", 
      "", 
      "@@ -348,10 +502,33 @@ int main(int argc, char *argv[])", 
      "retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);", 
      "} else retval = 0; /* If we already timed out, fall through */", 
      "", 
      "-\t\tnow = time(0);", 
      "+\t\tnow = uptime();", 
      "if (retval == 0) {", 
      "/* timeout dropped to zero */", 
      "switch (state) {", 
      "+                        case INIT_REBOOTING:", 
      "+                                if (packet_num < 3) {", 
      "+                                        if (packet_num == 0)", 
      "+                                                xid = random_xid();", 
      "+", 
      "+                                        /* send request packet */", 
      "+                                        send_selecting(xid, 0, requested_ip); /* broadcast */", 
      "+                                        LOG(LOG_DEBUG, \"DHCP: Sent renew from INIT-REBOOT (%d/3)\", packet_num + 1);", 
      "+                                        timeout = now + ((packet_num == 2) ? 10 : 2);", 
      "+                                        packet_num++;", 
      "+                                } else {", 
      "+                                        /* timed out. exit or go to init state? */", 
      "+                                        if (client_config.abort_if_failed_request) {", 
      "+                                                LOG(LOG_INFO, \"No lease after %d request attempts, exiting.\", packet_num);", 
      "+                                                exit_client(EXIT_CODE_FAILED_REQUEST);", 
      "+                                        }", 
      "+                                        /* go back to init state */", 
      "+                                        state = INIT_SELECTING;", 
      "+                                        timeout = now;", 
      "+                                        packet_num = 0;", 
      "+                                        change_mode(LISTEN_RAW);", 
      "+                                }", 
      "+                                break;", 
      "case INIT_SELECTING:", 
      "if (packet_num < 3) {", 
      "if (packet_num == 0)", 
      "@@ -359,17 +536,25 @@ int main(int argc, char *argv[])", 
      "", 
      "/* send discover packet */", 
      "send_discover(xid, requested_ip); /* broadcast */", 
      "+                                        LOG(LOG_DEBUG, \"DHCP: Sent discover (%d/3)\", packet_num + 1);", 
      "", 
      "timeout = now + ((packet_num == 2) ? 4 : 2);", 
      "packet_num++;", 
      "+          if(numOfDiscoverMsg >= 0)", 
      "+            numOfDiscoverMsg++;", 
      "} else {", 
      "if (client_config.background_if_no_lease) {", 
      "-\t\t\t\t\t\tLOG(LOG_INFO, \"No lease, forking to background.\");", 
      "+\t\t\t\t\t\tLOG(LOG_INFO, \"No lease after %d discover attempts, forking to background.\", packet_num);", 
      "background();", 
      "} else if (client_config.abort_if_no_lease) {", 
      "-\t\t\t\t\t\tLOG(LOG_INFO, \"No lease, failing.\");", 
      "-\t\t\t\t\t\texit_client(1);", 
      "+                                                LOG(LOG_INFO, \"No lease after %d discover attempts, exiting.\", packet_num);", 
      "+\t\t\t\t\t\texit_client(EXIT_CODE_FAILED_DISCOVER);", 
      "}", 
      "+          if(numOfDiscoverMsg >= 3){", 
      "+            run_script(NULL, \"deconfig\");", 
      "+            numOfDiscoverMsg = -1;", 
      "+          }", 
      "+", 
      "/* wait to try again */", 
      "packet_num = 0;", 
      "timeout = now + 60;", 
      "@@ -378,15 +563,24 @@ int main(int argc, char *argv[])", 
      "case RENEW_REQUESTED:", 
      "case REQUESTING:", 
      "if (packet_num < 3) {", 
      "-\t\t\t\t\t/* send request packet */", 
      "-\t\t\t\t\tif (state == RENEW_REQUESTED)", 
      "+                                        /* send request packet */", 
      "+\t\t\t\t\tif (state == RENEW_REQUESTED) {", 
      "send_renew(xid, server_addr, requested_ip); /* unicast */", 
      "-\t\t\t\t\telse send_selecting(xid, server_addr, requested_ip); /* broadcast */", 
      "+                                                LOG(LOG_DEBUG, \"DHCP: Sent renew (%d/3)\", packet_num + 1);", 
      "+                                        } else {", 
      "+                                                send_selecting(xid, server_addr, requested_ip); /* broadcast */", 
      "+                                                LOG(LOG_DEBUG, \"DHCP: Sent request (%d/3)\", packet_num + 1);", 
      "+                                        }", 
      "", 
      "timeout = now + ((packet_num == 2) ? 10 : 2);", 
      "packet_num++;", 
      "} else {", 
      "-\t\t\t\t\t/* timed out, go back to init state */", 
      "+                                        /* timed out. exit or go to init state? */", 
      "+                                        if (client_config.abort_if_failed_request) {", 
      "+                                                LOG(LOG_INFO, \"No lease after %d request attempts, exiting.\", packet_num);", 
      "+                                                exit_client(EXIT_CODE_FAILED_REQUEST);", 
      "+                                        }", 
      "+\t\t\t\t\t/* go back to init state */", 
      "if (state == RENEW_REQUESTED) run_script(NULL, \"deconfig\");", 
      "state = INIT_SELECTING;", 
      "timeout = now;", 
      "@@ -397,37 +591,62 @@ int main(int argc, char *argv[])", 
      "case BOUND:", 
      "/* Lease is starting to run out, time to enter renewing state */", 
      "state = RENEWING;", 
      "-\t\t\t\tchange_mode(LISTEN_KERNEL);", 
      "+                                if (client_config.process_zero_source_packet) {", 
      "+                                        change_mode(LISTEN_RAW);", 
      "+                                } else {", 
      "+                                        change_mode(LISTEN_KERNEL);", 
      "+                                }", 
      "DEBUG(LOG_INFO, \"Entering renew state\");", 
      "/* fall right through */", 
      "case RENEWING:", 
      "-\t\t\t\t/* Either set a new T1, or enter REBINDING state */", 
      "-\t\t\t\tif ((t2 - t1) <= (lease / 14400 + 1)) {", 
      "-\t\t\t\t\t/* timed out, enter rebinding state */", 
      "-\t\t\t\t\tstate = REBINDING;", 
      "-\t\t\t\t\ttimeout = now + (t2 - t1);", 
      "-\t\t\t\t\tDEBUG(LOG_INFO, \"Entering rebinding state\");", 
      "-\t\t\t\t} else {", 
      "-\t\t\t\t\t/* send a request packet */", 
      "-\t\t\t\t\tsend_renew(xid, server_addr, requested_ip); /* unicast */", 
      "-", 
      "-\t\t\t\t\tt1 = (t2 - t1) / 2 + t1;", 
      "-\t\t\t\t\ttimeout = t1 + start;", 
      "+                                run_script(NULL, \"prerenew\");", 
      "+                                if (client_config.address_renewal_behaviour) {", 
      "+                                        LOG(LOG_DEBUG, \"Sending DHCPRELEASE now since MYRIO.address_renewal_behaviour = 1\");", 
      "+                                        perform_release();", 
      "+                                        run_script(NULL, \"deconfig\");", 
      "+\t\t\t\t\tstate = INIT_SELECTING;", 
      "+\t\t\t\t\ttimeout = now;", 
      "+\t\t\t\t\trequested_ip = 0;", 
      "+\t\t\t\t\tpacket_num = 0;", 
      "+\t\t\t\t\tchange_mode(LISTEN_RAW);", 
      "+\t\t\t\t\tsleep(3); /* avoid excessive network traffic */", 
      "+                                } else {", 
      "+                                        /* Either set a new T1, or enter REBINDING state */", 
      "+                                        if ((t2 - t1) <= (lease / 14400 + 1)) {", 
      "+                                                /* timed out, enter rebinding state */", 
      "+                                                state = REBINDING;", 
      "+                                                timeout = now + (t2 - t1);", 
      "+                                                DEBUG(LOG_INFO, \"Entering rebinding state\");", 
      "+                                        } else {", 
      "+                                                /* send a request packet */", 
      "+                                                send_renew(xid, server_addr, requested_ip); /* unicast */", 
      "+                                                LOG(LOG_DEBUG, \"DHCP: Sent unicast renew\");", 
      "+", 
      "+                                                t1 = (t2 - t1) / 2 + t1;", 
      "+                                                timeout = t1 + start;", 
      "+                                        }", 
      "}", 
      "break;", 
      "case REBINDING:", 
      "/* Either set a new T2, or enter INIT state */", 
      "if ((lease - t2) <= (lease / 14400 + 1)) {", 
      "-\t\t\t\t\t/* timed out, enter init state */", 
      "-\t\t\t\t\tstate = INIT_SELECTING;", 
      "-\t\t\t\t\tLOG(LOG_INFO, \"Lease lost, entering init state\");", 
      "-\t\t\t\t\trun_script(NULL, \"deconfig\");", 
      "-\t\t\t\t\ttimeout = now;", 
      "+                                        if (!client_config.no_deconfig_on_expire) {", 
      "+                                                run_script(NULL, \"deconfig\");", 
      "+                                        }", 
      "+                                        if (client_config.abort_if_expired_lease) {", 
      "+                                                LOG(LOG_INFO, \"Lease lost, exiting.\");", 
      "+                                                exit_client(EXIT_CODE_EXPIRED_LEASE);", 
      "+                                        }", 
      "+                                        /* timed out, enter init state */", 
      "+                                        state = INIT_SELECTING;", 
      "+                                        LOG(LOG_INFO, \"Lease lost, entering init state\");", 
      "+                                        timeout = now;", 
      "packet_num = 0;", 
      "change_mode(LISTEN_RAW);", 
      "} else {", 
      "/* send a request packet */", 
      "send_renew(xid, 0, requested_ip); /* broadcast */", 
      "+                                        LOG(LOG_DEBUG, \"DHCP: Sent broadcast renew\");", 
      "", 
      "t2 = (lease - t2) / 2 + t2;", 
      "timeout = t2 + start;", 
      "@@ -468,6 +687,8 @@ int main(int argc, char *argv[])", 
      "if (*message == DHCPOFFER) {", 
      "if ((temp = get_option(&packet, DHCP_SERVER_ID))) {", 
      "memcpy(&server_addr, temp, 4);", 
      "+                                                temp_addr.s_addr = server_addr;", 
      "+                                                DEBUG(LOG_INFO, \"Server ID %s retrieved from DHCPOFFER\", inet_ntoa(temp_addr));", 
      "xid = packet.xid;", 
      "requested_ip = packet.yiaddr;", 
      "", 
      "@@ -476,15 +697,45 @@ int main(int argc, char *argv[])", 
      "timeout = now;", 
      "packet_num = 0;", 
      "} else {", 
      "-\t\t\t\t\t\tDEBUG(LOG_ERR, \"No server ID in message\");", 
      "+\t\t\t\t\t\tDEBUG(LOG_ERR, \"No server ID in DHCPOFFER\");", 
      "+\t\t\t\t\t}", 
      "+\t\t\t\t\tunsigned char* option125= get_option(&packet, DHCP_VENDOR_SPECIFIC);", 
      "+\t\t\t\t\tif(option125){", 
      "+\t\t\t\t\t\tparse_gatewayidentity(option125);", 
      "}", 
      "}", 
      "break;", 
      "+                        case INIT_REBOOTING:", 
      "case RENEW_REQUESTED:", 
      "case REQUESTING:", 
      "case RENEWING:", 
      "case REBINDING:", 
      "if (*message == DHCPACK) {", 
      "+                                        unsigned char* option43 = get_option(&packet, DHCP_VENDOR_INFORMATION);", 
      "+                                        if (option43) {", 
      "+                                                int i = 0;", 
      "+                                                // This operation is safe since get_option returns (unsigned char*) p + 2.", 
      "+                                                int option43_len = *(option43-1);", 
      "+                                                if ((*(option43) >= '0') &&", 
      "+                                                    (*(option43) <= '9')) {", 
      "+                                                        // This is a IP-address. Classic style DHCP.", 
      "+                                                        option43_len = 0;", 
      "+                                                }", 
      "+                                                unsigned char *foo = xmalloc(option43_len + 1);", 
      "+                                                memset(foo, 0, option43_len);", 
      "+                                                strncpy(foo, option43, option43_len);", 
      "+                                                i = 0;", 
      "+                                                while (i < option43_len) {", 
      "+                                                        if (*(option43 + i) == 100) { /* As in hw/common.h. */", 
      "+                                                                client_config.address_renewal_behaviour = *(option43 + i + 2);", 
      "+                                                                LOG(LOG_INFO, \"address_renewal_behaviour = %d\",", 
      "+                                                                      client_config.address_renewal_behaviour);", 
      "+                                                                break;", 
      "+                                                        } else {", 
      "+                                                                i += *(option43 + 1 + i) + 2;", 
      "+                                                        }", 
      "+                                                }", 
      "+                                        }", 
      "if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) {", 
      "LOG(LOG_ERR, \"No lease time with ACK, using 1 hour lease\");", 
      "lease = 60 * 60;", 
      "@@ -492,9 +743,17 @@ int main(int argc, char *argv[])", 
      "memcpy(&lease, temp, 4);", 
      "lease = ntohl(lease);", 
      "}", 
      "+", 
      "+\t\t\t\t\tunsigned char* option125= get_option(&packet, DHCP_VENDOR_SPECIFIC);", 
      "+\t\t\t\t\tif(option125){", 
      "+\t\t\t\t\t\tparse_gatewayidentity(option125);", 
      "+\t\t\t\t\t}", 
      "", 
      "/* enter bound state */", 
      "t1 = lease / 2;", 
      "+                                        if (client_config.leasetime > 0) {", 
      "+                                                client_config.leasetime = htonl(lease);", 
      "+                                        }", 
      "", 
      "/* little fixed point for n * .875 */", 
      "t2 = (lease * 0x7) >> 3;", 
      "@@ -506,43 +765,74 @@ int main(int argc, char *argv[])", 
      "requested_ip = packet.yiaddr;", 
      "run_script(&packet,", 
      "((state == RENEWING || state == REBINDING) ? \"renew\" : \"bound\"));", 
      "+                                        run_script(NULL, \"postrenew\");", 
      "", 
      "state = BOUND;", 
      "-\t\t\t\t\tchange_mode(LISTEN_NONE);", 
      "+                                        change_mode(LISTEN_KERNEL);", 
      "if (client_config.quit_after_lease)", 
      "exit_client(0);", 
      "if (!client_config.foreground)", 
      "background();", 
      "", 
      "+\t\t\t\t\t// After the client receives a lease from the DHCP server, it will send an ARP for", 
      "+\t\t\t\t\t// the IP address it has been assigned. If any other client replies to that ARP,", 
      "+\t\t\t\t\t// the address is already in use. In this case,the client will issue a DHCP DECLINE to the DHCP server.", 
      "+\t\t\t\t\tarpret = arpping(requested_ip, requested_ip, client_config.arp, client_config.interface);", 
      "+\t\t\t\t\tLOG(LOG_INFO, \"arpping, req ip:%s, ret:%d\", inet_ntoa(temp_addr), arpret);//liuhf", 
      "+\t\t\t\t\tif(arpret == 0){", 
      "+\t\t\t\t\t\tsend_decline(packet.xid, server_addr, requested_ip);", 
      "+\t\t\t\t\t\tLOG(LOG_INFO, \"send_decline, xid:%ld\", packet.xid);//liuhf", 
      "+\t\t\t\t\t\trun_script(NULL, \"deconfig\");", 
      "+\t\t\t\t\t\tstate = INIT_SELECTING;", 
      "+\t\t\t\t\t\ttimeout = now;", 
      "+\t\t\t\t\t\trequested_ip = 0;", 
      "+\t\t\t\t\t\tpacket_num = 0;", 
      "+\t\t\t\t\t\tchange_mode(LISTEN_RAW);", 
      "+\t\t\t\t\t\tsleep(10); /* The client should wait a", 
      "+      minimum of ten seconds before restarting the configuration process", 
      "+      to avoid excessive network traffic in case of looping. see RFC 1531 */", 
      "+\t\t\t\t\t}", 
      "} else if (*message == DHCPNAK) {", 
      "/* return to init state */", 
      "LOG(LOG_INFO, \"Received DHCP NAK\");", 
      "run_script(&packet, \"nak\");", 
      "-\t\t\t\t\tif (state != REQUESTING)", 
      "-\t\t\t\t\t\trun_script(NULL, \"deconfig\");", 
      "+\t\t\t\t\trun_script(NULL, \"deconfig\");", 
      "state = INIT_SELECTING;", 
      "timeout = now;", 
      "requested_ip = 0;", 
      "packet_num = 0;", 
      "change_mode(LISTEN_RAW);", 
      "sleep(3); /* avoid excessive network traffic */", 
      "-\t\t\t\t}", 
      "+\t\t\t\t}", 
      "+                        case BOUND:", 
      "+                                if (*message == DHCPFORCERENEW) {", 
      "+                                        LOG(LOG_INFO, \"Received DHCP FORCERENEW\");", 
      "+                                        run_script(NULL, \"prerenew\");", 
      "+                                        perform_renew();", 
      "+                                }", 
      "break;", 
      "-\t\t\t/* case BOUND, RELEASED: - ignore all packets */", 
      "+\t\t\t/* case RELEASED: - ignore all packets */", 
      "}", 
      "} else if (retval > 0 && FD_ISSET(signal_pipe[0], &rfds)) {", 
      "-\t\t\tif (read(signal_pipe[0], &sig, sizeof(signal)) < 0) {", 
      "+\t\t\tif (read(signal_pipe[0], &sig, sizeof(sig)) < 0) {", 
      "DEBUG(LOG_ERR, \"Could not read signal: %s\",", 
      "strerror(errno));", 
      "continue; /* probably just EINTR */", 
      "}", 
      "switch (sig) {", 
      "case SIGUSR1:", 
      "+                                run_script(NULL, \"prerenew\");", 
      "perform_renew();", 
      "break;", 
      "case SIGUSR2:", 
      "perform_release();", 
      "break;", 
      "+#ifdef KBOX", 
      "+\t\t\tcase SIGHUP:", 
      "+\t\t\t\tLOG(LOG_INFO, \"Received SIGHUP\");", 
      "+\t\t\t\texit_client(0);", 
      "+\t\t\t\tbreak;", 
      "+#endif", 
      "case SIGTERM:", 
      "LOG(LOG_INFO, \"Received SIGTERM\");", 
      "exit_client(0);"
    ]
  ]
]