Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/networking/udhcp/dhcpc.c

    r3306 r3621  
    2626#include "dhcpc.h"
    2727
    28 #include <asm/types.h>
    29 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION)
    30 # include <netpacket/packet.h>
    31 # include <net/ethernet.h>
    32 #else
    33 # include <linux/if_packet.h>
    34 # include <linux/if_ether.h>
     28#include <netinet/if_ether.h>
     29#include <linux/filter.h>
     30#include <linux/if_packet.h>
     31
     32#ifndef PACKET_AUXDATA
     33# define PACKET_AUXDATA 8
     34struct tpacket_auxdata {
     35    uint32_t tp_status;
     36    uint32_t tp_len;
     37    uint32_t tp_snaplen;
     38    uint16_t tp_mac;
     39    uint16_t tp_net;
     40    uint16_t tp_vlan_tci;
     41    uint16_t tp_padding;
     42};
    3543#endif
    36 #include <linux/filter.h>
     44
    3745
    3846/* "struct client_config_t client_config" is in bb_common_bufsiz1 */
     
    6169    "background\0"     No_argument       "b"
    6270    "broadcast\0"      No_argument       "B"
    63     IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument      "a")
     71    IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a")
    6472    IF_FEATURE_UDHCP_PORT("client-port\0"   Required_argument "P")
    6573    ;
     
    102110
    103111/* get a rough idea of how long an option will be (rounding up...) */
    104 static const uint8_t len_of_option_as_string[] = {
     112static const uint8_t len_of_option_as_string[] ALIGN1 = {
    105113    [OPTION_IP              ] = sizeof("255.255.255.255 "),
    106114    [OPTION_IP_PAIR         ] = sizeof("255.255.255.255 ") * 2,
    107115    [OPTION_STATIC_ROUTES   ] = sizeof("255.255.255.255/32 255.255.255.255 "),
    108     [OPTION_6RD             ] = sizeof("32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
     116    [OPTION_6RD             ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
    109117    [OPTION_STRING          ] = 1,
    110118    [OPTION_STRING_HOST     ] = 1,
     
    143151}
    144152
     153#if ENABLE_FEATURE_UDHCPC_SANITIZEOPT
    145154/* Check if a given label represents a valid DNS label
    146155 * Return pointer to the first character after the label upon success,
     
    162171        ch = *label;
    163172        if ((ch|0x20) < 'a' || (ch|0x20) > 'z') {
    164             if (pos == 0) {
    165                 /* label must begin with letter */
    166                 return NULL;
    167             }
    168173            if (ch < '0' || ch > '9') {
    169174                if (ch == '\0' || ch == '.')
     
    197202            //return ((name - start) < 1025); /* NS_MAXDNAME */
    198203        name++;
    199     }
    200 }
     204        if (*name == '\0')
     205            return 1; // We allow trailing dot too
     206    }
     207}
     208#else
     209# define good_hostname(name) 1
     210#endif
    201211
    202212/* Create "opt_name=opt_value" string */
     
    213223    optlen = dhcp_option_lengths[type];
    214224    upper_length = len_of_option_as_string[type]
    215         * ((unsigned)(len + optlen - 1) / (unsigned)optlen);
     225        * ((unsigned)(len + optlen) / (unsigned)optlen);
    216226
    217227    dest = ret = xmalloc(upper_length + strlen(opt_name) + 2);
     
    552562
    553563    /* call script */
    554     log1("Executing %s %s", client_config.script, name);
     564    log1("executing %s %s", client_config.script, name);
    555565    argv[0] = (char*) client_config.script;
    556566    argv[1] = (char*) name;
     
    666676 */
    667677
    668 static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet)
     678static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip)
    669679{
    670680    return udhcp_send_raw_packet(packet,
    671         /*src*/ INADDR_ANY, CLIENT_PORT,
     681        /*src*/ src_nip, CLIENT_PORT,
    672682        /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
    673683        client_config.ifindex);
     684}
     685
     686static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
     687{
     688    if (server)
     689        return udhcp_send_kernel_packet(packet,
     690            ciaddr, CLIENT_PORT,
     691            server, SERVER_PORT);
     692    return raw_bcast_from_client_config_ifindex(packet, ciaddr);
    674693}
    675694
     
    696715    add_client_options(&packet);
    697716
    698     bb_info_msg("Sending discover...");
    699     return raw_bcast_from_client_config_ifindex(&packet);
     717    bb_error_msg("sending %s", "discover");
     718    return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
    700719}
    701720
     
    740759
    741760    addr.s_addr = requested;
    742     bb_info_msg("Sending select for %s...", inet_ntoa(addr));
    743     return raw_bcast_from_client_config_ifindex(&packet);
     761    bb_error_msg("sending select for %s", inet_ntoa(addr));
     762    return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
    744763}
    745764
     
    779798    add_client_options(&packet);
    780799
    781     bb_info_msg("Sending renew...");
    782     if (server)
    783         return udhcp_send_kernel_packet(&packet,
    784             ciaddr, CLIENT_PORT,
    785             server, SERVER_PORT);
    786     return raw_bcast_from_client_config_ifindex(&packet);
     800    bb_error_msg("sending %s", "renew");
     801    return bcast_or_ucast(&packet, ciaddr, server);
    787802}
    788803
     
    812827    udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
    813828
    814     bb_info_msg("Sending decline...");
    815     return raw_bcast_from_client_config_ifindex(&packet);
     829    bb_error_msg("sending %s", "decline");
     830    return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
    816831}
    817832#endif
     
    832847    udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
    833848
    834     bb_info_msg("Sending release...");
    835     return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT);
     849    bb_error_msg("sending %s", "release");
     850    /* Note: normally we unicast here since "server" is not zero.
     851     * However, there _are_ people who run "address-less" DHCP servers,
     852     * and reportedly ISC dhcp client and Windows allow that.
     853     */
     854    return bcast_or_ucast(&packet, ciaddr, server);
    836855}
    837856
     
    843862    struct ip_udp_dhcp_packet packet;
    844863    uint16_t check;
    845 #ifdef PACKET_AUXDATA
    846864    unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
    847     struct cmsghdr *cmsg;
    848 #endif
    849865    struct iovec iov;
    850866    struct msghdr msg;
    851 
    852 #ifdef PACKET_AUXDATA
     867    struct cmsghdr *cmsg;
     868
    853869    /* used to use just safe_read(fd, &packet, sizeof(packet))
    854870     * but we need to check for TP_STATUS_CSUMNOTREADY :(
     
    866882            if (errno == EINTR)
    867883                continue;
    868             log1("Packet read error, ignoring");
     884            log1("packet read error, ignoring");
    869885            /* NB: possible down interface, etc. Caller should pause. */
    870886            return bytes; /* returns -1 */
     
    872888        break;
    873889    }
    874 #else
    875     memset(&packet, 0, sizeof(packet));
    876     bytes = safe_read(fd, &packet, sizeof(packet));
    877     if (bytes < 0) {
    878         log1("Packet read error, ignoring");
    879         /* NB: possible down interface, etc. Caller should pause. */
    880         return bytes; /* returns -1 */
    881     }
    882 #endif
    883890
    884891    if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) {
    885         log1("Packet is too short, ignoring");
     892        log1("packet is too short, ignoring");
    886893        return -2;
    887894    }
     
    889896    if (bytes < ntohs(packet.ip.tot_len)) {
    890897        /* packet is bigger than sizeof(packet), we did partial read */
    891         log1("Oversized packet, ignoring");
     898        log1("oversized packet, ignoring");
    892899        return -2;
    893900    }
     
    904911     || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip))
    905912    ) {
    906         log1("Unrelated/bogus packet, ignoring");
     913        log1("unrelated/bogus packet, ignoring");
    907914        return -2;
    908915    }
     
    912919    packet.ip.check = 0;
    913920    if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) {
    914         log1("Bad IP header checksum, ignoring");
     921        log1("bad IP header checksum, ignoring");
    915922        return -2;
    916923    }
    917924
    918 #ifdef PACKET_AUXDATA
    919925    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
    920926        if (cmsg->cmsg_level == SOL_PACKET
     
    930936        }
    931937    }
    932 #endif
    933938
    934939    /* verify UDP checksum. IP header has to be modified for this */
     
    939944    packet.udp.check = 0;
    940945    if (check && check != inet_cksum((uint16_t *)&packet, bytes)) {
    941         log1("Packet with bad UDP checksum received, ignoring");
     946        log1("packet with bad UDP checksum received, ignoring");
    942947        return -2;
    943948    }
    944 #ifdef PACKET_AUXDATA
    945949 skip_udp_sum_check:
    946 #endif
    947950
    948951    if (packet.data.cookie != htonl(DHCP_MAGIC)) {
    949         bb_info_msg("Packet with bad magic, ignoring");
     952        bb_error_msg("packet with bad magic, ignoring");
    950953        return -2;
    951954    }
    952955
    953     log1("Received a packet");
     956    log1("received %s", "a packet");
    954957    udhcp_dump_packet(&packet.data);
    955958
     
    990993    struct sockaddr_ll sock;
    991994
    992     /*
    993      * Comment:
    994      *
    995      *  I've selected not to see LL header, so BPF doesn't see it, too.
    996      *  The filter may also pass non-IP and non-ARP packets, but we do
    997      *  a more complete check when receiving the message in userspace.
    998      *
    999      * and filter shamelessly stolen from:
    1000      *
    1001      *  http://www.flamewarmaster.de/software/dhcpclient/
    1002      *
    1003      * There are a few other interesting ideas on that page (look under
    1004      * "Motivation").  Use of netlink events is most interesting.  Think
    1005      * of various network servers listening for events and reconfiguring.
    1006      * That would obsolete sending HUP signals and/or make use of restarts.
    1007      *
    1008      * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>.
    1009      * License: GPL v2.
    1010      *
    1011      * TODO: make conditional?
     995    log1("opening raw socket on ifindex %d", ifindex); //log2?
     996
     997    fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
     998    /* ^^^^^
     999     * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them)
     1000     * ETH_P_IP: want to receive only packets with IPv4 eth type
    10121001     */
    1013     static const struct sock_filter filter_instr[] = {
    1014         /* load 9th byte (protocol) */
    1015         BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
    1016         /* jump to L1 if it is IPPROTO_UDP, else to L4 */
    1017         BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
    1018         /* L1: load halfword from offset 6 (flags and frag offset) */
    1019         BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
    1020         /* jump to L4 if any bits in frag offset field are set, else to L2 */
    1021         BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
    1022         /* L2: skip IP header (load index reg with header len) */
    1023         BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
    1024         /* load udp destination port from halfword[header_len + 2] */
    1025         BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
    1026         /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */
    1027         BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
    1028         /* L3: accept packet */
    1029         BPF_STMT(BPF_RET|BPF_K, 0xffffffff),
    1030         /* L4: discard packet */
    1031         BPF_STMT(BPF_RET|BPF_K, 0),
    1032     };
    1033     static const struct sock_fprog filter_prog = {
    1034         .len = sizeof(filter_instr) / sizeof(filter_instr[0]),
    1035         /* casting const away: */
    1036         .filter = (struct sock_filter *) filter_instr,
    1037     };
    1038 
    1039     log1("Opening raw socket on ifindex %d", ifindex); //log2?
    1040 
    1041     fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
    1042     log1("Got raw socket fd"); //log2?
     1002    log1("got raw socket fd"); //log2?
    10431003
    10441004    sock.sll_family = AF_PACKET;
     
    10471007    xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
    10481008
     1009#if 0 /* Several users reported breakage when BPF filter is used */
    10491010    if (CLIENT_PORT == 68) {
    10501011        /* Use only if standard port is in use */
     1012        /*
     1013         *  I've selected not to see LL header, so BPF doesn't see it, too.
     1014         *  The filter may also pass non-IP and non-ARP packets, but we do
     1015         *  a more complete check when receiving the message in userspace.
     1016         *
     1017         * and filter shamelessly stolen from:
     1018         *
     1019         *  http://www.flamewarmaster.de/software/dhcpclient/
     1020         *
     1021         * There are a few other interesting ideas on that page (look under
     1022         * "Motivation").  Use of netlink events is most interesting.  Think
     1023         * of various network servers listening for events and reconfiguring.
     1024         * That would obsolete sending HUP signals and/or make use of restarts.
     1025         *
     1026         * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>.
     1027         * License: GPL v2.
     1028         */
     1029        static const struct sock_filter filter_instr[] = {
     1030            /* load 9th byte (protocol) */
     1031            BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
     1032            /* jump to L1 if it is IPPROTO_UDP, else to L4 */
     1033            BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
     1034            /* L1: load halfword from offset 6 (flags and frag offset) */
     1035            BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
     1036            /* jump to L4 if any bits in frag offset field are set, else to L2 */
     1037            BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
     1038            /* L2: skip IP header (load index reg with header len) */
     1039            BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
     1040            /* load udp destination port from halfword[header_len + 2] */
     1041            BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
     1042            /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */
     1043            BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
     1044            /* L3: accept packet ("accept 0x7fffffff bytes") */
     1045            /* Accepting 0xffffffff works too but kernel 2.6.19 is buggy */
     1046            BPF_STMT(BPF_RET|BPF_K, 0x7fffffff),
     1047            /* L4: discard packet ("accept zero bytes") */
     1048            BPF_STMT(BPF_RET|BPF_K, 0),
     1049        };
     1050        static const struct sock_fprog filter_prog = {
     1051            .len = sizeof(filter_instr) / sizeof(filter_instr[0]),
     1052            /* casting const away: */
     1053            .filter = (struct sock_filter *) filter_instr,
     1054        };
    10511055        /* Ignoring error (kernel may lack support for this) */
    10521056        if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
    10531057                sizeof(filter_prog)) >= 0)
    1054             log1("Attached filter to raw socket fd"); // log?
    1055     }
    1056 
    1057 #ifdef PACKET_AUXDATA
    1058     if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA,
    1059             &const_int_1, sizeof(int)) < 0
    1060     ) {
     1058            log1("attached filter to raw socket fd"); // log?
     1059    }
     1060#endif
     1061
     1062    if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) {
    10611063        if (errno != ENOPROTOOPT)
    1062             log1("Can't set PACKET_AUXDATA on raw socket");
    1063     }
    1064 #else
    1065     sock.sll_family = AF_PACKET;
    1066     sock.sll_protocol = htons(ETH_P_IP);
    1067     sock.sll_ifindex = ifindex;
    1068     xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
    1069 #endif
    1070 
    1071     log1("Created raw socket");
     1064            log1("can't set PACKET_AUXDATA on raw socket");
     1065    }
     1066
     1067    log1("created raw socket");
    10721068
    10731069    return fd;
     
    10761072static void change_listen_mode(int new_mode)
    10771073{
    1078     log1("Entering listen mode: %s",
     1074    log1("entering listen mode: %s",
    10791075        new_mode != LISTEN_NONE
    10801076            ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw")
     
    10971093static void perform_renew(void)
    10981094{
    1099     bb_info_msg("Performing a DHCP renew");
     1095    bb_error_msg("performing DHCP renew");
    11001096    switch (state) {
    11011097    case BOUND:
     
    11271123        strcpy(buffer, inet_ntoa(temp_addr));
    11281124        temp_addr.s_addr = requested_ip;
    1129         bb_info_msg("Unicasting a release of %s to %s",
     1125        bb_error_msg("unicasting a release of %s to %s",
    11301126                inet_ntoa(temp_addr), buffer);
    11311127        send_release(server_addr, requested_ip); /* unicast */
    11321128        udhcp_run_script(NULL, "deconfig");
    11331129    }
    1134     bb_info_msg("Entering released state");
     1130    bb_error_msg("entering released state");
    11351131
    11361132    change_listen_mode(LISTEN_NONE);
     
    11651161//usage:#endif
    11661162//usage:#define udhcpc_trivial_usage
    1167 //usage:       "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n"
    1168 //usage:       "    [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]")
     1163//usage:       "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC/-n]\n"
     1164//usage:       "    [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n"
     1165//usage:       "    [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..."
    11691166//usage:#define udhcpc_full_usage "\n"
    11701167//usage:    IF_LONG_OPTS(
    11711168//usage:     "\n    -i,--interface IFACE    Interface to use (default eth0)"
     1169//usage:    IF_FEATURE_UDHCP_PORT(
     1170//usage:     "\n    -P,--client-port PORT   Use PORT (default 68)"
     1171//usage:    )
     1172//usage:     "\n    -s,--script PROG    Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
    11721173//usage:     "\n    -p,--pidfile FILE   Create pidfile"
    1173 //usage:     "\n    -s,--script PROG    Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
    11741174//usage:     "\n    -B,--broadcast      Request broadcast replies"
    1175 //usage:     "\n    -t,--retries N      Send up to N discover packets"
    1176 //usage:     "\n    -T,--timeout N      Pause between packets (default 3 seconds)"
    1177 //usage:     "\n    -A,--tryagain N     Wait N seconds after failure (default 20)"
     1175//usage:     "\n    -t,--retries N      Send up to N discover packets (default 3)"
     1176//usage:     "\n    -T,--timeout SEC    Pause between packets (default 3)"
     1177//usage:     "\n    -A,--tryagain SEC   Wait if lease is not obtained (default 20)"
     1178//usage:     "\n    -n,--now        Exit if lease is not obtained"
     1179//usage:     "\n    -q,--quit       Exit after obtaining lease"
     1180//usage:     "\n    -R,--release        Release IP on exit"
    11781181//usage:     "\n    -f,--foreground     Run in foreground"
    11791182//usage:    USE_FOR_MMU(
    11801183//usage:     "\n    -b,--background     Background if lease is not obtained"
    11811184//usage:    )
    1182 //usage:     "\n    -n,--now        Exit if lease is not obtained"
    1183 //usage:     "\n    -q,--quit       Exit after obtaining lease"
    1184 //usage:     "\n    -R,--release        Release IP on exit"
    11851185//usage:     "\n    -S,--syslog     Log to syslog too"
    1186 //usage:    IF_FEATURE_UDHCP_PORT(
    1187 //usage:     "\n    -P,--client-port N  Use port N (default 68)"
     1186//usage:    IF_FEATURE_UDHCPC_ARPING(
     1187//usage:     "\n    -a[MSEC],--arping[=MSEC] Validate offered address with ARP ping"
    11881188//usage:    )
    1189 //usage:    IF_FEATURE_UDHCPC_ARPING(
    1190 //usage:     "\n    -a,--arping     Use arping to validate offered address"
    1191 //usage:    )
     1189//usage:     "\n    -r,--request IP     Request this IP address"
     1190//usage:     "\n    -o,--no-default-options Don't request any options (unless -O is given)"
    11921191//usage:     "\n    -O,--request-option OPT Request option OPT from server (cumulative)"
    1193 //usage:     "\n    -o,--no-default-options Don't request any options (unless -O is given)"
    1194 //usage:     "\n    -r,--request IP     Request this IP address"
    11951192//usage:     "\n    -x OPT:VAL      Include option OPT in sent packets (cumulative)"
    11961193//usage:     "\n                Examples of string, numeric, and hex byte opts:"
     
    12071204//usage:    IF_NOT_LONG_OPTS(
    12081205//usage:     "\n    -i IFACE    Interface to use (default eth0)"
     1206//usage:    IF_FEATURE_UDHCP_PORT(
     1207//usage:     "\n    -P PORT     Use PORT (default 68)"
     1208//usage:    )
     1209//usage:     "\n    -s PROG     Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
    12091210//usage:     "\n    -p FILE     Create pidfile"
    1210 //usage:     "\n    -s PROG     Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
    12111211//usage:     "\n    -B      Request broadcast replies"
    1212 //usage:     "\n    -t N        Send up to N discover packets"
    1213 //usage:     "\n    -T N        Pause between packets (default 3 seconds)"
    1214 //usage:     "\n    -A N        Wait N seconds (default 20) after failure"
     1212//usage:     "\n    -t N        Send up to N discover packets (default 3)"
     1213//usage:     "\n    -T SEC      Pause between packets (default 3)"
     1214//usage:     "\n    -A SEC      Wait if lease is not obtained (default 20)"
     1215//usage:     "\n    -n      Exit if lease is not obtained"
     1216//usage:     "\n    -q      Exit after obtaining lease"
     1217//usage:     "\n    -R      Release IP on exit"
    12151218//usage:     "\n    -f      Run in foreground"
    12161219//usage:    USE_FOR_MMU(
    12171220//usage:     "\n    -b      Background if lease is not obtained"
    12181221//usage:    )
    1219 //usage:     "\n    -n      Exit if lease is not obtained"
    1220 //usage:     "\n    -q      Exit after obtaining lease"
    1221 //usage:     "\n    -R      Release IP on exit"
    12221222//usage:     "\n    -S      Log to syslog too"
    1223 //usage:    IF_FEATURE_UDHCP_PORT(
    1224 //usage:     "\n    -P N        Use port N (default 68)"
     1223//usage:    IF_FEATURE_UDHCPC_ARPING(
     1224//usage:     "\n    -a[MSEC]    Validate offered address with ARP ping"
    12251225//usage:    )
    1226 //usage:    IF_FEATURE_UDHCPC_ARPING(
    1227 //usage:     "\n    -a      Use arping to validate offered address"
    1228 //usage:    )
     1226//usage:     "\n    -r IP       Request this IP address"
     1227//usage:     "\n    -o      Don't request any options (unless -O is given)"
    12291228//usage:     "\n    -O OPT      Request option OPT from server (cumulative)"
    1230 //usage:     "\n    -o      Don't request any options (unless -O is given)"
    1231 //usage:     "\n    -r IP       Request this IP address"
    12321229//usage:     "\n    -x OPT:VAL  Include option OPT in sent packets (cumulative)"
    12331230//usage:     "\n            Examples of string, numeric, and hex byte opts:"
     
    12501247int udhcpc_main(int argc UNUSED_PARAM, char **argv)
    12511248{
    1252     uint8_t *temp, *message;
     1249    uint8_t *message;
    12531250    const char *str_V, *str_h, *str_F, *str_r;
     1251    IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";)
    12541252    IF_FEATURE_UDHCP_PORT(char *str_P;)
    12551253    void *clientid_mac_ptr;
     
    12661264    unsigned already_waited_sec;
    12671265    unsigned opt;
     1266    IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;)
    12681267    int max_fd;
    12691268    int retval;
    12701269    fd_set rfds;
     1270
     1271    setup_common_bufsiz();
    12711272
    12721273    /* Default options */
     
    12831284    opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB"
    12841285        USE_FOR_MMU("b")
    1285         IF_FEATURE_UDHCPC_ARPING("a")
     1286        IF_FEATURE_UDHCPC_ARPING("a::")
    12861287        IF_FEATURE_UDHCP_PORT("P:")
    12871288        "v"
     
    12921293        , &list_O
    12931294        , &list_x
     1295        IF_FEATURE_UDHCPC_ARPING(, &str_a)
    12941296        IF_FEATURE_UDHCP_PORT(, &str_P)
    12951297        IF_UDHCP_VERBOSE(, &dhcp_verbose)
     
    13231325    }
    13241326#endif
     1327    IF_FEATURE_UDHCPC_ARPING(arpping_ms = xatou(str_a);)
    13251328    while (list_O) {
    13261329        char *optstr = llist_pop(&list_O);
     
    13951398    write_pidfile(client_config.pidfile);
    13961399    /* Goes to stdout (unless NOMMU) and possibly syslog */
    1397     bb_info_msg("%s (v"BB_VER") started", applet_name);
     1400    bb_error_msg("started, v"BB_VER);
    13981401    /* Set up the signal pipe */
    13991402    udhcp_sp_setup();
     
    14341437        /* If we already timed out, fall through with retval = 0, else... */
    14351438        if ((int)tv.tv_sec > 0) {
    1436             log1("Waiting on select %u seconds", (int)tv.tv_sec);
     1439            log1("waiting on select %u seconds", (int)tv.tv_sec);
    14371440            timestamp_before_wait = (unsigned)monotonic_sec();
    14381441            retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
     
    14851488#if BB_MMU /* -b is not supported on NOMMU */
    14861489                if (opt & OPT_b) { /* background if no lease */
    1487                     bb_info_msg("No lease, forking to background");
     1490                    bb_error_msg("no lease, forking to background");
    14881491                    client_background();
    14891492                    /* do not background again! */
     
    14921495#endif
    14931496                if (opt & OPT_n) { /* abort if no lease */
    1494                     bb_info_msg("No lease, failing");
     1497                    bb_error_msg("no lease, failing");
    14951498                    retval = 1;
    14961499                    goto ret;
     
    15011504                continue;
    15021505            case REQUESTING:
    1503                 if (!discover_retries || packet_num < discover_retries) {
     1506                if (packet_num < 3) {
    15041507                    /* send broadcast select packet */
    15051508                    send_select(xid, server_addr, requested_ip);
     
    15201523                client_config.first_secs = 0; /* make secs field count from 0 */
    15211524                change_listen_mode(LISTEN_KERNEL);
    1522                 log1("Entering renew state");
     1525                log1("entering renew state");
    15231526                /* fall right through */
    15241527            case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
     
    15401543                }
    15411544                /* Timed out, enter rebinding state */
    1542                 log1("Entering rebinding state");
     1545                log1("entering rebinding state");
    15431546                state = REBINDING;
    15441547                /* fall right through */
     
    15551558                }
    15561559                /* Timed out, enter init state */
    1557                 bb_info_msg("Lease lost, entering init state");
     1560                bb_error_msg("lease lost, entering init state");
    15581561                udhcp_run_script(NULL, "deconfig");
    15591562                state = INIT_SELECTING;
     
    16031606            continue;
    16041607        case SIGTERM:
    1605             bb_info_msg("Received SIGTERM");
     1608            bb_error_msg("received %s", "SIGTERM");
    16061609            goto ret0;
    16071610        }
     
    16211624            if (len == -1) {
    16221625                /* Error is severe, reopen socket */
    1623                 bb_info_msg("Read error: %s, reopening socket", strerror(errno));
     1626                bb_error_msg("read error: %s, reopening socket", strerror(errno));
    16241627                sleep(discover_timeout); /* 3 seconds by default */
    16251628                change_listen_mode(listen_mode); /* just close and reopen */
     
    16581661            /* Must be a DHCPOFFER */
    16591662            if (*message == DHCPOFFER) {
     1663                uint8_t *temp;
     1664
    16601665/* What exactly is server's IP? There are several values.
    16611666 * Example DHCP offer captured with tchdump:
     
    16771682 * "Next server" and router are definitely wrong ones to use, though...
    16781683 */
     1684/* We used to ignore pcakets without DHCP_SERVER_ID.
     1685 * I've got user reports from people who run "address-less" servers.
     1686 * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all.
     1687 * They say ISC DHCP client supports this case.
     1688 */
     1689                server_addr = 0;
    16791690                temp = udhcp_get_option(&packet, DHCP_SERVER_ID);
    16801691                if (!temp) {
    1681                     bb_error_msg("no server ID, ignoring packet");
    1682                     continue;
    1683                     /* still selecting - this server looks bad */
     1692                    bb_error_msg("no server ID, using 0.0.0.0");
     1693                } else {
     1694                    /* it IS unaligned sometimes, don't "optimize" */
     1695                    move_from_unaligned32(server_addr, temp);
    16841696                }
    1685                 /* it IS unaligned sometimes, don't "optimize" */
    1686                 move_from_unaligned32(server_addr, temp);
    16871697                /*xid = packet.xid; - already is */
    16881698                requested_ip = packet.yiaddr;
     
    17001710        case REBINDING:
    17011711            if (*message == DHCPACK) {
     1712                unsigned start;
    17021713                uint32_t lease_seconds;
    17031714                struct in_addr temp_addr;
     1715                uint8_t *temp;
    17041716
    17051717                temp = udhcp_get_option(&packet, DHCP_LEASE_TIME);
     
    17321744                            (uint32_t) 0,
    17331745                            client_config.client_mac,
    1734                             client_config.interface)
     1746                            client_config.interface,
     1747                            arpping_ms)
    17351748                    ) {
    1736                         bb_info_msg("Offered address is in use "
     1749                        bb_error_msg("offered address is in use "
    17371750                            "(got ARP reply), declining");
    17381751                        send_decline(/*xid,*/ server_addr, packet.yiaddr);
     
    17521765#endif
    17531766                /* enter bound state */
    1754                 timeout = lease_seconds / 2;
    17551767                temp_addr.s_addr = packet.yiaddr;
    1756                 bb_info_msg("Lease of %s obtained, lease time %u",
     1768                bb_error_msg("lease of %s obtained, lease time %u",
    17571769                    inet_ntoa(temp_addr), (unsigned)lease_seconds);
    17581770                requested_ip = packet.yiaddr;
     1771
     1772                start = monotonic_sec();
    17591773                udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew");
     1774                already_waited_sec = (unsigned)monotonic_sec() - start;
     1775                timeout = lease_seconds / 2;
     1776                if ((unsigned)timeout < already_waited_sec) {
     1777                    /* Something went wrong. Back to discover state */
     1778                    timeout = already_waited_sec = 0;
     1779                }
    17601780
    17611781                state = BOUND;
     
    17751795                /* make future renew packets use different xid */
    17761796                /* xid = random_xid(); ...but why bother? */
    1777                 already_waited_sec = 0;
     1797
    17781798                continue; /* back to main loop */
    17791799            }
    17801800            if (*message == DHCPNAK) {
     1801                /* If network has more than one DHCP server,
     1802                 * "wrong" server can reply first, with a NAK.
     1803                 * Do not interpret it as a NAK from "our" server.
     1804                 */
     1805                if (server_addr != 0) {
     1806                    uint32_t svid;
     1807                    uint8_t *temp;
     1808
     1809                    temp = udhcp_get_option(&packet, DHCP_SERVER_ID);
     1810                    if (!temp) {
     1811 non_matching_svid:
     1812                        log1("%s with wrong server ID, ignoring packet",
     1813                            "Received DHCP NAK"
     1814                        );
     1815                        continue;
     1816                    }
     1817                    move_from_unaligned32(svid, temp);
     1818                    if (svid != server_addr)
     1819                        goto non_matching_svid;
     1820                }
    17811821                /* return to init state */
    1782                 bb_info_msg("Received DHCP NAK");
     1822                bb_error_msg("received %s", "DHCP NAK");
    17831823                udhcp_run_script(&packet, "nak");
    17841824                if (state != REQUESTING)
Note: See TracChangeset for help on using the changeset viewer.