Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/networking/udhcp


Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (8 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:
4 added
6 deleted
16 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/networking/udhcp/Config.src

    r3232 r3621  
    8585      and restart the discover process.
    8686
     87config FEATURE_UDHCPC_SANITIZEOPT
     88    bool "Do not pass malformed host and domain names"
     89    default y
     90    depends on UDHCPC
     91    help
     92      If selected, udhcpc will check some options (such as option 12 -
     93      hostname) and if they don't look like valid hostnames
     94      (for example, if they start with dash or contain spaces),
     95      they will be replaced with string "bad" when exporting
     96      to the environment.
     97
    8798config FEATURE_UDHCP_PORT
    8899    bool "Enable '-P port' option for udhcpd and udhcpc"
  • branches/3.3/mindi-busybox/networking/udhcp/arpping.c

    r3232 r3621  
    4040        uint32_t from_ip,
    4141        uint8_t *from_mac,
    42         const char *interface)
     42        const char *interface,
     43        unsigned timeo)
    4344{
    4445    int timeout_ms;
     
    4849    struct sockaddr addr;   /* for interface name */
    4950    struct arpMsg arp;
     51
     52    if (!timeo)
     53        return 1;
    5054
    5155    s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
     
    8488
    8589    /* wait for arp reply, and check it */
    86     timeout_ms = 2000;
     90    timeout_ms = (int)timeo;
    8791    do {
    8892        typedef uint32_t aliased_uint32_t FIX_ALIASING;
     
    125129         * (people did see overflows here when system time jumps):
    126130         */
    127     } while ((unsigned)timeout_ms <= 2000);
     131    } while ((unsigned)timeout_ms <= timeo);
    128132
    129133 ret:
    130134    close(s);
    131     log1("%srp reply received for this address", rv ? "No a" : "A");
     135    log1("%srp reply received for this address", rv ? "no a" : "A");
    132136    return rv;
    133137}
  • branches/3.3/mindi-busybox/networking/udhcp/common.c

    r3232 r3621  
    6363    { OPTION_U8                               , 0x85 }, /* DHCP_VLAN_PRIORITY */
    6464#endif
     65    { OPTION_STRING                           , 0xd1 }, /* DHCP_PXE_CONF_FILE */
     66    { OPTION_STRING                           , 0xd2 }, /* DHCP_PXE_PATH_PREFIX */
    6567    { OPTION_6RD                              , 0xd4 }, /* DHCP_6RD           */
    6668    { OPTION_STATIC_ROUTES | OPTION_LIST      , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */
     
    129131    "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY  */
    130132#endif
     133    "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE  */
     134    "pxepathprefix" "\0" /* DHCP_PXE_PATH_PREFIX  */
    131135    "ip6rd" "\0"       /* DHCP_6RD            */
    132136    "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */
     
    139143 * xmalloc_optname_optval: to estimate string length
    140144 * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type])
    141  * is the number of elements, multiply in by one element's string width
     145 * is the number of elements, multiply it by one element's string width
    142146 * (len_of_option_as_string[opt_type]) and you know how wide string you need.
    143147 */
     
    159163    /* Just like OPTION_STRING, we use minimum length here */
    160164    [OPTION_STATIC_ROUTES] = 5,
    161     [OPTION_6RD] =    22,  /* ignored by udhcp_str2optset */
     165    [OPTION_6RD] =    12,  /* ignored by udhcp_str2optset */
     166    /* The above value was chosen as follows:
     167     * len_of_option_as_string[] for this option is >60: it's a string of the form
     168     * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ".
     169     * Each additional ipv4 address takes 4 bytes in binary option and appends
     170     * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 4
     171     * but this severely overestimates string length: instead of 16 bytes,
     172     * it adds >60 for every 4 bytes in binary option.
     173     * We cheat and declare here that option is in units of 12 bytes.
     174     * This adds more than 60 bytes for every three ipv4 addresses - more than enough.
     175     * (Even 16 instead of 12 should work, but let's be paranoid).
     176     */
    162177};
    163178
     
    169184        char buf[256 * 2 + 2];
    170185        *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0';
    171         bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf);
     186        bb_error_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf);
    172187    }
    173188}
     
    243258
    244259        if (optionptr[OPT_CODE] == code) {
    245             log_option("Option found", optionptr);
     260            log_option("option found", optionptr);
    246261            return optionptr + OPT_DATA;
    247262        }
     
    255270
    256271    /* log3 because udhcpc uses it a lot - very noisy */
    257     log3("Option 0x%02x not found", code);
     272    log3("option 0x%02x not found", code);
    258273    return NULL;
    259274}
     
    289304        return;
    290305    }
    291     log_option("Adding option", addopt);
     306    log_option("adding option", addopt);
    292307    memcpy(optionptr + end, addopt, len);
    293308    optionptr[end + len] = DHCP_END;
     
    372387        int length)
    373388{
    374     struct option_set *existing, *new, **curr;
    375     char *allocated = NULL;
     389    struct option_set *existing;
     390    char *allocated;
     391
     392    allocated = allocate_tempopt_if_needed(optflag, buffer, &length);
     393#if ENABLE_FEATURE_UDHCP_RFC3397
     394    if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) {
     395        /* reuse buffer and length for RFC1035-formatted string */
     396        allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length);
     397    }
     398#endif
    376399
    377400    existing = udhcp_find_option(*opt_list, optflag->code);
    378401    if (!existing) {
    379         log2("Attaching option %02x to list", optflag->code);
    380         allocated = allocate_tempopt_if_needed(optflag, buffer, &length);
    381 #if ENABLE_FEATURE_UDHCP_RFC3397
    382         if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) {
    383             /* reuse buffer and length for RFC1035-formatted string */
    384             allocated = buffer = (char *)dname_enc(NULL, 0, buffer, &length);
    385         }
    386 #endif
     402        struct option_set *new, **curr;
     403
    387404        /* make a new option */
     405        log2("attaching option %02x to list", optflag->code);
    388406        new = xmalloc(sizeof(*new));
    389407        new->data = xmalloc(length + OPT_DATA);
     
    405423
    406424        /* add it to an existing option */
    407         log2("Attaching option %02x to existing member of list", optflag->code);
    408         allocated = allocate_tempopt_if_needed(optflag, buffer, &length);
     425        log2("attaching option %02x to existing member of list", optflag->code);
    409426        old_len = existing->data[OPT_LEN];
    410 #if ENABLE_FEATURE_UDHCP_RFC3397
    411         if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_DNS_STRING) {
    412             /* reuse buffer and length for RFC1035-formatted string */
    413             allocated = buffer = (char *)dname_enc(existing->data + OPT_DATA, old_len, buffer, &length);
    414         }
    415 #endif
    416427        if (old_len + length < 255) {
    417428            /* actually 255 is ok too, but adding a space can overlow it */
     
    425436                old_len++;
    426437            }
    427             memcpy(existing->data + OPT_DATA + old_len, buffer, length);
     438            memcpy(existing->data + OPT_DATA + old_len, (allocated ? allocated : buffer), length);
    428439            existing->data[OPT_LEN] = old_len + length;
    429440        } /* else, ignore the data, we could put this in a second option in the future */
  • branches/3.3/mindi-busybox/networking/udhcp/common.h

    r3232 r3621  
    1010
    1111#include "libbb.h"
     12#include "common_bufsiz.h"
    1213#include <netinet/udp.h>
    1314#include <netinet/ip.h>
     
    150151//#define DHCP_SIP_SERVERS      0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */
    151152//#define DHCP_STATIC_ROUTES    0x79 /* RFC 3442. (mask,ip,router) tuples */
    152 #define DHCP_VLAN_ID            0x84 /* 802.1P VLAN ID */
    153 #define DHCP_VLAN_PRIORITY      0x85 /* 802.1Q VLAN priority */
     153//#define DHCP_VLAN_ID          0x84 /* 802.1P VLAN ID */
     154//#define DHCP_VLAN_PRIORITY    0x85 /* 802.1Q VLAN priority */
     155//#define DHCP_PXE_CONF_FILE    0xd1 /* RFC 5071 Configuration File */
     156//#define DHCP_PXE_PATH_PREFIX  0xd2 /* RFC 5071 Configuration File */
    154157//#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */
    155158//#define DHCP_WPAD             0xfc /* MSIE's Web Proxy Autodiscovery Protocol */
     
    255258# define IF_UDHCP_VERBOSE(...) __VA_ARGS__
    256259extern unsigned dhcp_verbose;
    257 # define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0)
     260# define log1(...) do { if (dhcp_verbose >= 1) bb_error_msg(__VA_ARGS__); } while (0)
    258261# if CONFIG_UDHCP_DEBUG >= 2
    259262void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
    260 #  define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0)
     263#  define log2(...) do { if (dhcp_verbose >= 2) bb_error_msg(__VA_ARGS__); } while (0)
    261264# else
    262265#  define udhcp_dump_packet(...) ((void)0)
     
    264267# endif
    265268# if CONFIG_UDHCP_DEBUG >= 3
    266 #  define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0)
     269#  define log3(...) do { if (dhcp_verbose >= 3) bb_error_msg(__VA_ARGS__); } while (0)
    267270# else
    268271#  define log3(...) ((void)0)
     
    310313        uint32_t from_ip,
    311314        uint8_t *from_mac,
    312         const char *interface) FAST_FUNC;
     315        const char *interface,
     316        unsigned timeo) FAST_FUNC;
    313317
    314318/* note: ip is a pointer to an IPv6 in network order, possibly misaliged */
  • 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)
  • branches/3.3/mindi-busybox/networking/udhcp/dhcpc.h

    r3232 r3621  
    3030
    3131#if ENABLE_FEATURE_UDHCP_PORT
    32 #define CLIENT_PORT (client_config.port)
     32#define CLIENT_PORT  (client_config.port)
     33#define CLIENT_PORT6 (client_config.port)
    3334#else
    34 #define CLIENT_PORT 68
     35#define CLIENT_PORT  68
     36#define CLIENT_PORT6 546
    3537#endif
    3638
  • branches/3.3/mindi-busybox/networking/udhcp/dhcpd.c

    r3232 r3621  
    2323
    2424//usage:#define udhcpd_trivial_usage
    25 //usage:       "[-fS]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]"
     25//usage:       "[-fS] [-I ADDR]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [CONFFILE]"
    2626//usage:#define udhcpd_full_usage "\n\n"
    2727//usage:       "DHCP server\n"
    2828//usage:     "\n    -f  Run in foreground"
    2929//usage:     "\n    -S  Log to syslog too"
     30//usage:     "\n    -I ADDR Local address"
     31//usage:     "\n    -a MSEC Timeout for ARP ping (default 2000)"
    3032//usage:    IF_FEATURE_UDHCP_PORT(
    3133//usage:     "\n    -P N    Use port N (default 67)"
     
    6062     || dhcp_pkt->ciaddr == 0
    6163    ) {
    62         log1("Broadcasting packet to client");
     64        log1("broadcasting packet to client");
    6365        ciaddr = INADDR_BROADCAST;
    6466        chaddr = MAC_BCAST_ADDR;
    6567    } else {
    66         log1("Unicasting packet to client ciaddr");
     68        log1("unicasting packet to client ciaddr");
    6769        ciaddr = dhcp_pkt->ciaddr;
    6870        chaddr = dhcp_pkt->chaddr;
     
    7880static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt)
    7981{
    80     log1("Forwarding packet to relay");
     82    log1("forwarding packet to relay");
    8183
    8284    udhcp_send_kernel_packet(dhcp_pkt,
     
    148150        uint32_t static_lease_nip,
    149151        struct dyn_lease *lease,
    150         uint8_t *requested_ip_opt)
     152        uint8_t *requested_ip_opt,
     153        unsigned arpping_ms)
    151154{
    152155    struct dhcp_packet packet;
     
    187190        else {
    188191            /* Otherwise, find a free IP */
    189             packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr);
     192            packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr, arpping_ms);
    190193        }
    191194
     
    212215
    213216    addr.s_addr = packet.yiaddr;
    214     bb_info_msg("Sending OFFER of %s", inet_ntoa(addr));
     217    bb_error_msg("sending OFFER of %s", inet_ntoa(addr));
    215218    /* send_packet emits error message itself if it detects failure */
    216219    send_packet(&packet, /*force_bcast:*/ 0);
     
    224227    init_packet(&packet, oldpacket, DHCPNAK);
    225228
    226     log1("Sending NAK");
     229    log1("sending %s", "NAK");
    227230    send_packet(&packet, /*force_bcast:*/ 1);
    228231}
     
    245248
    246249    addr.s_addr = yiaddr;
    247     bb_info_msg("Sending ACK to %s", inet_ntoa(addr));
     250    bb_error_msg("sending ACK to %s", inet_ntoa(addr));
    248251    send_packet(&packet, /*force_bcast:*/ 0);
    249252
     
    303306    unsigned opt;
    304307    struct option_set *option;
     308    char *str_I = str_I;
     309    const char *str_a = "2000";
     310    unsigned arpping_ms;
    305311    IF_FEATURE_UDHCP_PORT(char *str_P;)
    306312
    307 #if ENABLE_FEATURE_UDHCP_PORT
    308     SERVER_PORT = 67;
    309     CLIENT_PORT = 68;
    310 #endif
     313    setup_common_bufsiz();
     314
     315    IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
     316    IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
    311317
    312318#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
    313319    opt_complementary = "vv";
    314320#endif
    315     opt = getopt32(argv, "fSv"
    316         IF_FEATURE_UDHCP_PORT("P:", &str_P)
     321    opt = getopt32(argv, "fSI:va:"
     322        IF_FEATURE_UDHCP_PORT("P:")
     323        , &str_I
     324        , &str_a
     325        IF_FEATURE_UDHCP_PORT(, &str_P)
    317326        IF_UDHCP_VERBOSE(, &dhcp_verbose)
    318327        );
     
    327336        logmode |= LOGMODE_SYSLOG;
    328337    }
     338    if (opt & 4) { /* -I */
     339        len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET);
     340        server_config.server_nip = lsa->u.sin.sin_addr.s_addr;
     341        free(lsa);
     342    }
    329343#if ENABLE_FEATURE_UDHCP_PORT
    330     if (opt & 8) { /* -P */
     344    if (opt & 32) { /* -P */
    331345        SERVER_PORT = xatou16(str_P);
    332346        CLIENT_PORT = SERVER_PORT + 1;
    333347    }
    334348#endif
     349    arpping_ms = xatou(str_a);
     350
    335351    /* Would rather not do read_config before daemonization -
    336352     * otherwise NOMMU machines will parse config twice */
     
    346362    /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */
    347363
    348     bb_info_msg("%s (v"BB_VER") started", applet_name);
     364    bb_error_msg("started, v"BB_VER);
    349365
    350366    option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME);
     
    368384    if (udhcp_read_interface(server_config.interface,
    369385            &server_config.ifindex,
    370             &server_config.server_nip,
     386            (server_config.server_nip == 0 ? &server_config.server_nip : NULL),
    371387            server_config.server_mac)
    372388    ) {
     
    398414        max_sock = udhcp_sp_fd_set(&rfds, server_socket);
    399415        if (server_config.auto_time) {
    400             tv.tv_sec = timeout_end - monotonic_sec();
     416            /* cast to signed is essential if tv_sec is wider than int */
     417            tv.tv_sec = (int)(timeout_end - monotonic_sec());
    401418            tv.tv_usec = 0;
    402419        }
     
    411428        }
    412429        if (retval < 0 && errno != EINTR) {
    413             log1("Error on select");
     430            log1("error on select");
    414431            continue;
    415432        }
     
    417434        switch (udhcp_sp_read(&rfds)) {
    418435        case SIGUSR1:
    419             bb_info_msg("Received SIGUSR1");
     436            bb_error_msg("received %s", "SIGUSR1");
    420437            write_leases();
    421438            /* why not just reset the timeout, eh */
    422439            goto continue_with_autotime;
    423440        case SIGTERM:
    424             bb_info_msg("Received SIGTERM");
     441            bb_error_msg("received %s", "SIGTERM");
    425442            write_leases();
    426443            goto ret0;
     
    435452            /* bytes can also be -2 ("bad packet data") */
    436453            if (bytes == -1 && errno != EINTR) {
    437                 log1("Read error: %s, reopening socket", strerror(errno));
     454                log1("read error: %s, reopening socket", strerror(errno));
    438455                close(server_socket);
    439456                server_socket = -1;
     
    470487        static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr);
    471488        if (static_lease_nip) {
    472             bb_info_msg("Found static lease: %x", static_lease_nip);
     489            bb_error_msg("found static lease: %x", static_lease_nip);
    473490            memcpy(&fake_lease.lease_mac, &packet.chaddr, 6);
    474491            fake_lease.lease_nip = static_lease_nip;
     
    488505
    489506        case DHCPDISCOVER:
    490             log1("Received DISCOVER");
    491 
    492             send_offer(&packet, static_lease_nip, lease, requested_ip_opt);
     507            log1("received %s", "DISCOVER");
     508
     509            send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms);
    493510            break;
    494511
    495512        case DHCPREQUEST:
    496             log1("Received REQUEST");
     513            log1("received %s", "REQUEST");
    497514/* RFC 2131:
    498515
     
    619636             * ciaddr must be 0 (we do not check this)
    620637             */
    621             log1("Received DECLINE");
     638            log1("received %s", "DECLINE");
    622639            if (server_id_opt
    623640             && requested_ip_opt
     
    639656             * ciaddr must be filled in
    640657             */
    641             log1("Received RELEASE");
     658            log1("received %s", "RELEASE");
    642659            if (server_id_opt
    643660             && lease  /* chaddr matches this lease */
     
    649666
    650667        case DHCPINFORM:
    651             log1("Received INFORM");
     668            log1("received %s", "INFORM");
    652669            send_inform(&packet);
    653670            break;
  • branches/3.3/mindi-busybox/networking/udhcp/dhcpd.h

    r2725 r3621  
    5858} FIX_ALIASING;
    5959
    60 #define server_config (*(struct server_config_t*)&bb_common_bufsiz1)
     60#define server_config (*(struct server_config_t*)bb_common_bufsiz1)
    6161/* client_config sits in 2nd half of bb_common_bufsiz1 */
    6262
    6363#if ENABLE_FEATURE_UDHCP_PORT
    64 #define SERVER_PORT (server_config.port)
     64#define SERVER_PORT  (server_config.port)
     65#define SERVER_PORT6 (server_config.port)
    6566#else
    66 #define SERVER_PORT 67
     67#define SERVER_PORT  67
     68#define SERVER_PORT6 547
    6769#endif
    6870
     
    99101struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC;
    100102struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC;
    101 uint32_t find_free_or_expired_nip(const uint8_t *safe_mac) FAST_FUNC;
     103uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) FAST_FUNC;
    102104
    103105
  • branches/3.3/mindi-busybox/networking/udhcp/dhcprelay.c

    r3232 r3621  
    3434} FIX_ALIASING;
    3535
    36 #define dhcprelay_xid_list (*(struct xid_item*)&bb_common_bufsiz1)
     36#define dhcprelay_xid_list (*(struct xid_item*)bb_common_bufsiz1)
     37#define INIT_G() do { setup_common_bufsiz(); } while (0)
    3738
    3839static struct xid_item *xid_add(uint32_t xid, struct sockaddr_in *ip, int client)
     
    257258    int num_sockets, max_socket;
    258259    uint32_t our_nip;
     260
     261    INIT_G();
    259262
    260263    server_addr.sin_family = AF_INET;
  • branches/3.3/mindi-busybox/networking/udhcp/domain_codec.c

    r2725 r3621  
    88 */
    99#ifdef DNS_COMPR_TESTING
     10# define _GNU_SOURCE
    1011# define FAST_FUNC /* nothing */
    1112# define xmalloc malloc
     
    4344    while (1) {
    4445        /* note: "return NULL" below are leak-safe since
    45          * dst isn't yet allocated */
     46         * dst isn't allocated yet */
    4647        const uint8_t *c;
    4748        unsigned crtpos, retpos, depth, len;
     
    6465                    return NULL;
    6566                if (dst)
    66                     memcpy(dst + len, c + 1, *c);
     67                    /* \3com ---> "com." */
     68                    ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.';
    6769                len += *c + 1;
    6870                crtpos += *c + 1;
    69                 if (dst)
    70                     dst[len - 1] = '.';
    7171            } else {
    7272                /* NUL: end of current domain name */
     
    7979                    retpos = depth = 0;
    8080                }
    81                 if (dst)
     81                if (dst && len != 0)
     82                    /* \4host\3com\0\4host and we are at \0:
     83                     * \3com was converted to "com.", change dot to space.
     84                     */
    8285                    dst[len - 1] = ' ';
    8386            }
     
    9699            /* allocate dst buffer and copy pre */
    97100            unsigned plen = strlen(pre);
    98             ret = dst = xmalloc(plen + len);
    99             memcpy(dst, pre, plen);
    100             dst += plen;
     101            ret = xmalloc(plen + len);
     102            dst = stpcpy(ret, pre);
    101103        } else {
    102104            dst[len - 1] = '\0';
     
    229231    uint8_t *encoded;
    230232
     233        uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 };
     234        printf("NUL:'%s'\n",   dname_dec(str, 6, ""));
     235
    231236#define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre))
    232237    printf("'%s'\n",       DNAME_DEC("\4host\3com\0", "test1:"));
  • branches/3.3/mindi-busybox/networking/udhcp/dumpleases.c

    r3232 r3621  
    55
    66//usage:#define dumpleases_trivial_usage
    7 //usage:       "[-r|-a] [-f LEASEFILE]"
     7//usage:       "[-r|-a] [-d] [-f LEASEFILE]"
    88//usage:#define dumpleases_full_usage "\n\n"
    99//usage:       "Display DHCP leases granted by udhcpd\n"
     
    1212//usage:     "\n    -r,--remaining  Show remaining time"
    1313//usage:     "\n    -a,--absolute   Show expiration time"
     14//usage:     "\n    -d,--decimal    Show time in seconds"
    1415//usage:    )
    1516//usage:    IF_NOT_LONG_OPTS(
     
    1718//usage:     "\n    -r  Show remaining time"
    1819//usage:     "\n    -a  Show expiration time"
     20//usage:     "\n    -d  Show time in seconds"
    1921//usage:    )
    2022
     
    2931    int i;
    3032    unsigned opt;
    31     int64_t written_at, curr, expires_abs;
     33    int64_t written_at, curr;
    3234    const char *file = LEASES_FILE;
    3335    struct dyn_lease lease;
    34     struct in_addr addr;
    3536
    3637    enum {
     
    3839        OPT_r = 0x2, // -r
    3940        OPT_f = 0x4, // -f
     41        OPT_d = 0x8, // -d
    4042    };
    4143#if ENABLE_LONG_OPTS
     
    4446        "remaining\0" No_argument       "r"
    4547        "file\0"      Required_argument "f"
     48        "decimal\0"   No_argument       "d"
    4649        ;
    4750
     
    5154
    5255    opt_complementary = "=0:a--r:r--a";
    53     opt = getopt32(argv, "arf:", &file);
     56    opt = getopt32(argv, "arf:d", &file);
    5457
    5558    fd = xopen(file, O_RDONLY);
    5659
    57     printf("Mac Address       IP Address      Host Name           Expires %s\n", (opt & OPT_a) ? "at" : "in");
     60    /*     "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */
    5861    /*     "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */
    59     /*     "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */
     62    printf("Mac %-14s"       "IP %-13s"      "Host %-15s"        "Expires %s\n",
     63        "Address", "Address", "Name",
     64        (opt & OPT_a) ? "at" : "in"
     65    );
    6066
    6167    xread(fd, &written_at, sizeof(written_at));
     
    6672
    6773    while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) {
     74        struct in_addr addr;
     75        int64_t expires_abs;
     76
    6877        const char *fmt = ":%02x" + 1;
    6978        for (i = 0; i < 6; i++) {
     
    8897            continue;
    8998        }
     99        if (opt & OPT_d) {
     100            /* -d: decimal time */
     101            if (!(opt & OPT_a))
     102                expires_abs -= curr;
     103            printf("%llu\n", (unsigned long long) expires_abs);
     104            continue;
     105        }
    90106        if (!(opt & OPT_a)) { /* no -a */
    91107            unsigned d, h, m;
  • branches/3.3/mindi-busybox/networking/udhcp/files.c

    r3232 r3621  
    5858    const char *keyword;
    5959    int (*handler)(const char *line, void *var) FAST_FUNC;
    60     void *var;
     60    unsigned ofs;
    6161    const char *def;
    6262};
    6363
     64#define OFS(field) offsetof(struct server_config_t, field)
     65
    6466static const struct config_keyword keywords[] = {
    6567    /* keyword        handler           variable address               default */
    66     {"start"        , udhcp_str2nip   , &server_config.start_ip     , "192.168.0.20"},
    67     {"end"          , udhcp_str2nip   , &server_config.end_ip       , "192.168.0.254"},
    68     {"interface"    , read_str        , &server_config.interface    , "eth0"},
     68    {"start"        , udhcp_str2nip   , OFS(start_ip     ), "192.168.0.20"},
     69    {"end"          , udhcp_str2nip   , OFS(end_ip       ), "192.168.0.254"},
     70    {"interface"    , read_str        , OFS(interface    ), "eth0"},
    6971    /* Avoid "max_leases value not sane" warning by setting default
    7072     * to default_end_ip - default_start_ip + 1: */
    71     {"max_leases"   , read_u32        , &server_config.max_leases   , "235"},
    72     {"auto_time"    , read_u32        , &server_config.auto_time    , "7200"},
    73     {"decline_time" , read_u32        , &server_config.decline_time , "3600"},
    74     {"conflict_time", read_u32        , &server_config.conflict_time, "3600"},
    75     {"offer_time"   , read_u32        , &server_config.offer_time   , "60"},
    76     {"min_lease"    , read_u32        , &server_config.min_lease_sec, "60"},
    77     {"lease_file"   , read_str        , &server_config.lease_file   , LEASES_FILE},
    78     {"pidfile"      , read_str        , &server_config.pidfile      , "/var/run/udhcpd.pid"},
    79     {"siaddr"       , udhcp_str2nip   , &server_config.siaddr_nip   , "0.0.0.0"},
     73    {"max_leases"   , read_u32        , OFS(max_leases   ), "235"},
     74    {"auto_time"    , read_u32        , OFS(auto_time    ), "7200"},
     75    {"decline_time" , read_u32        , OFS(decline_time ), "3600"},
     76    {"conflict_time", read_u32        , OFS(conflict_time), "3600"},
     77    {"offer_time"   , read_u32        , OFS(offer_time   ), "60"},
     78    {"min_lease"    , read_u32        , OFS(min_lease_sec), "60"},
     79    {"lease_file"   , read_str        , OFS(lease_file   ), LEASES_FILE},
     80    {"pidfile"      , read_str        , OFS(pidfile      ), "/var/run/udhcpd.pid"},
     81    {"siaddr"       , udhcp_str2nip   , OFS(siaddr_nip   ), "0.0.0.0"},
    8082    /* keywords with no defaults must be last! */
    81     {"option"       , udhcp_str2optset, &server_config.options      , ""},
    82     {"opt"          , udhcp_str2optset, &server_config.options      , ""},
    83     {"notify_file"  , read_str        , &server_config.notify_file  , NULL},
    84     {"sname"        , read_str        , &server_config.sname        , NULL},
    85     {"boot_file"    , read_str        , &server_config.boot_file    , NULL},
    86     {"static_lease" , read_staticlease, &server_config.static_leases, ""},
     83    {"option"       , udhcp_str2optset, OFS(options      ), ""},
     84    {"opt"          , udhcp_str2optset, OFS(options      ), ""},
     85    {"notify_file"  , read_str        , OFS(notify_file  ), NULL},
     86    {"sname"        , read_str        , OFS(sname        ), NULL},
     87    {"boot_file"    , read_str        , OFS(boot_file    ), NULL},
     88    {"static_lease" , read_staticlease, OFS(static_leases), ""},
    8789};
    8890enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 };
     
    9698
    9799    for (i = 0; i < KWS_WITH_DEFAULTS; i++)
    98         keywords[i].handler(keywords[i].def, keywords[i].var);
     100        keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs);
    99101
    100102    parser = config_open(file);
     
    102104        for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) {
    103105            if (strcasecmp(token[0], k->keyword) == 0) {
    104                 if (!k->handler(token[1], k->var)) {
     106                if (!k->handler(token[1], (char*)&server_config + k->ofs)) {
    105107                    bb_error_msg("can't parse line %u in %s",
    106108                            parser->lineno, file);
    107109                    /* reset back to the default value */
    108                     k->handler(k->def, k->var);
     110                    k->handler(k->def, (char*)&server_config + k->ofs);
    109111                }
    110112                break;
     
    190192
    191193    while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) {
    192 //FIXME: what if it matches some static lease?
    193194        uint32_t y = ntohl(lease.lease_nip);
    194195        if (y >= server_config.start_ip && y <= server_config.end_ip) {
    195196            signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed;
     197            uint32_t static_nip;
     198
    196199            if (expires <= 0)
     200                /* We keep expired leases: add_lease() will add
     201                 * a lease with 0 seconds remaining.
     202                 * Fewer IP address changes this way for mass reboot scenario.
     203                 */
     204                expires = 0;
     205
     206            /* Check if there is a different static lease for this IP or MAC */
     207            static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac);
     208            if (static_nip) {
     209                /* NB: we do not add lease even if static_nip == lease.lease_nip.
     210                 */
    197211                continue;
     212            }
     213            if (is_nip_reserved(server_config.static_leases, lease.lease_nip))
     214                continue;
     215
    198216            /* NB: add_lease takes "relative time", IOW,
    199217             * lease duration, not lease deadline. */
     
    211229        }
    212230    }
    213     log1("Read %d leases", i);
     231    log1("read %d leases", i);
    214232 ret:
    215233    close(fd);
  • branches/3.3/mindi-busybox/networking/udhcp/leases.c

    r3232 r3621  
    1818     * and therefore can't ever match */
    1919    for (i = 0; i < server_config.max_leases; i++) {
    20         if (g_leases[i].expires < oldest_time) {
     20        if (g_leases[i].expires == 0 /* empty entry */
     21         || g_leases[i].expires < oldest_time
     22        ) {
    2123            oldest_time = g_leases[i].expires;
    2224            oldest_lease = &g_leases[i];
     
    6668                hostname_len = sizeof(oldest->hostname);
    6769            p = safe_strncpy(oldest->hostname, hostname, hostname_len);
    68             /* sanitization (s/non-ASCII/^/g) */
     70            /*
     71             * Sanitization (s/bad_char/./g).
     72             * The intent is not to allow only "DNS-valid" hostnames,
     73             * but merely make dumpleases output safe for shells to use.
     74             * We accept "0-9A-Za-z._-", all other chars turn to dots.
     75             */
    6976            while (*p) {
    70                 if (*p < ' ' || *p > 126)
    71                     *p = '^';
     77                if (!isalnum(*p) && *p != '-' && *p != '_')
     78                    *p = '.';
    7279                p++;
    7380            }
     
    113120
    114121/* Check if the IP is taken; if it is, add it to the lease table */
    115 static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
     122static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms)
    116123{
    117124    struct in_addr temp;
     
    121128            server_config.server_nip,
    122129            server_config.server_mac,
    123             server_config.interface);
     130            server_config.interface,
     131            arpping_ms);
    124132    if (r)
    125133        return r;
    126134
    127135    temp.s_addr = nip;
    128     bb_info_msg("%s belongs to someone, reserving it for %u seconds",
     136    bb_error_msg("%s belongs to someone, reserving it for %u seconds",
    129137        inet_ntoa(temp), (unsigned)server_config.conflict_time);
    130138    add_lease(NULL, nip, server_config.conflict_time, NULL, 0);
     
    133141
    134142/* Find a new usable (we think) address */
    135 uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
     143uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms)
    136144{
    137145    uint32_t addr;
     
    178186        if (!lease) {
    179187//TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping!
    180             if (nobody_responds_to_arp(nip, safe_mac))
     188            if (nobody_responds_to_arp(nip, safe_mac, arpping_ms))
    181189                return nip;
    182190        } else {
     
    195203    if (oldest_lease
    196204     && is_expired_lease(oldest_lease)
    197      && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac)
     205     && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms)
    198206    ) {
    199207        return oldest_lease->lease_nip;
  • branches/3.3/mindi-busybox/networking/udhcp/packet.c

    r3232 r3621  
    3939        return;
    4040
    41     bb_info_msg(
    42         //" op %x"
     41    bb_error_msg(
     42        //"op %x"
    4343        //" htype %x"
    4444        " hlen %x"
     
    7474    );
    7575    *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0';
    76     bb_info_msg(" chaddr %s", buf);
     76    bb_error_msg("chaddr %s", buf);
    7777}
    7878#endif
     
    8686    bytes = safe_read(fd, packet, sizeof(*packet));
    8787    if (bytes < 0) {
    88         log1("Packet read error, ignoring");
     88        log1("packet read error, ignoring");
    8989        return bytes; /* returns -1 */
    9090    }
     
    9393     || packet->cookie != htonl(DHCP_MAGIC)
    9494    ) {
    95         bb_info_msg("Packet with bad magic, ignoring");
     95        bb_error_msg("packet with bad magic, ignoring");
    9696        return -2;
    9797    }
    98     log1("Received a packet");
     98    log1("received %s", "a packet");
    9999    udhcp_dump_packet(packet);
    100100
     
    144144     * In order to work with those buggy servers,
    145145     * we truncate packets after end option byte.
     146     *
     147     * However, RFC 1542 says "The IP Total Length and UDP Length
     148     * must be large enough to contain the minimal BOOTP header of 300 octets".
     149     * Thus, we retain enough padding to not go below 300 BOOTP bytes.
     150     * Some devices have filters which drop DHCP packets shorter than that.
    146151     */
    147152    padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options);
     153    if (padding > DHCP_SIZE - 300)
     154        padding = DHCP_SIZE - 300;
    148155
    149156    packet.ip.protocol = IPPROTO_UDP;
     
    216223    udhcp_dump_packet(dhcp_pkt);
    217224    padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options);
     225    if (padding > DHCP_SIZE - 300)
     226        padding = DHCP_SIZE - 300;
    218227    result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding);
    219228    msg = "write";
  • branches/3.3/mindi-busybox/networking/udhcp/socket.c

    r3232 r3621  
    5757            return -1;
    5858        }
    59         log1("Adapter index %d", ifr->ifr_ifindex);
     59        log1("adapter index %d", ifr->ifr_ifindex);
    6060        *ifindex = ifr->ifr_ifindex;
    6161    }
     
    8383    char *colon;
    8484
    85     log1("Opening listen socket on *:%d %s", port, inf);
     85    log1("opening listen socket on *:%d %s", port, inf);
    8686    fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    8787
  • branches/3.3/mindi-busybox/networking/udhcp/static_leases.c

    r2725 r3621  
    6767    cur = *st_lease_pp;
    6868    while (cur) {
    69         bb_info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x",
     69        bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x",
    7070            cur->mac[0], cur->mac[1], cur->mac[2],
    7171            cur->mac[3], cur->mac[4], cur->mac[5],
Note: See TracChangeset for help on using the changeset viewer.