busybox/networking/udhcp/dhcpc.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * udhcp client
   4 * Russ Dill <Russ.Dill@asu.edu> July 2001
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20//applet:IF_UDHCPC(APPLET(udhcpc, BB_DIR_SBIN, BB_SUID_DROP))
  21
  22//kbuild:lib-$(CONFIG_UDHCPC) += common.o packet.o signalpipe.o socket.o
  23//kbuild:lib-$(CONFIG_UDHCPC) += dhcpc.o
  24//kbuild:lib-$(CONFIG_FEATURE_UDHCPC_ARPING) += arpping.o
  25//kbuild:lib-$(CONFIG_FEATURE_UDHCP_RFC3397) += domain_codec.o
  26
  27#include <syslog.h>
  28/* Override ENABLE_FEATURE_PIDFILE - ifupdown needs our pidfile to always exist */
  29#define WANT_PIDFILE 1
  30#include "common.h"
  31#include "dhcpd.h"
  32#include "dhcpc.h"
  33
  34#include <netinet/if_ether.h>
  35#include <linux/filter.h>
  36#include <linux/if_packet.h>
  37
  38#ifndef PACKET_AUXDATA
  39# define PACKET_AUXDATA 8
  40struct tpacket_auxdata {
  41        uint32_t tp_status;
  42        uint32_t tp_len;
  43        uint32_t tp_snaplen;
  44        uint16_t tp_mac;
  45        uint16_t tp_net;
  46        uint16_t tp_vlan_tci;
  47        uint16_t tp_padding;
  48};
  49#endif
  50
  51
  52/* "struct client_data_t client_data" is in bb_common_bufsiz1 */
  53
  54
  55#if ENABLE_LONG_OPTS
  56static const char udhcpc_longopts[] ALIGN1 =
  57        "clientid-none\0"  No_argument       "C"
  58        "vendorclass\0"    Required_argument "V"
  59        "hostname\0"       Required_argument "H"
  60        "fqdn\0"           Required_argument "F"
  61        "interface\0"      Required_argument "i"
  62        "now\0"            No_argument       "n"
  63        "pidfile\0"        Required_argument "p"
  64        "quit\0"           No_argument       "q"
  65        "release\0"        No_argument       "R"
  66        "request\0"        Required_argument "r"
  67        "script\0"         Required_argument "s"
  68        "timeout\0"        Required_argument "T"
  69        "retries\0"        Required_argument "t"
  70        "tryagain\0"       Required_argument "A"
  71        "syslog\0"         No_argument       "S"
  72        "request-option\0" Required_argument "O"
  73        "no-default-options\0" No_argument   "o"
  74        "foreground\0"     No_argument       "f"
  75        USE_FOR_MMU(
  76        "background\0"     No_argument       "b"
  77        )
  78        "broadcast\0"      No_argument       "B"
  79        IF_FEATURE_UDHCPC_ARPING("arping\0"     Optional_argument "a")
  80        IF_FEATURE_UDHCP_PORT("client-port\0"   Required_argument "P")
  81        ;
  82#endif
  83/* Must match getopt32 option string order */
  84enum {
  85        OPT_C = 1 << 0,
  86        OPT_V = 1 << 1,
  87        OPT_H = 1 << 2,
  88        OPT_h = 1 << 3,
  89        OPT_F = 1 << 4,
  90        OPT_i = 1 << 5,
  91        OPT_n = 1 << 6,
  92        OPT_p = 1 << 7,
  93        OPT_q = 1 << 8,
  94        OPT_R = 1 << 9,
  95        OPT_r = 1 << 10,
  96        OPT_s = 1 << 11,
  97        OPT_T = 1 << 12,
  98        OPT_t = 1 << 13,
  99        OPT_S = 1 << 14,
 100        OPT_A = 1 << 15,
 101        OPT_O = 1 << 16,
 102        OPT_o = 1 << 17,
 103        OPT_x = 1 << 18,
 104        OPT_f = 1 << 19,
 105        OPT_B = 1 << 20,
 106/* The rest has variable bit positions, need to be clever */
 107        OPTBIT_B = 20,
 108        USE_FOR_MMU(             OPTBIT_b,)
 109        IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
 110        IF_FEATURE_UDHCP_PORT(   OPTBIT_P,)
 111        USE_FOR_MMU(             OPT_b = 1 << OPTBIT_b,)
 112        IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)
 113        IF_FEATURE_UDHCP_PORT(   OPT_P = 1 << OPTBIT_P,)
 114};
 115
 116
 117/*** Script execution code ***/
 118
 119/* get a rough idea of how long an option will be (rounding up...) */
 120static const uint8_t len_of_option_as_string[] ALIGN1 = {
 121        [OPTION_IP              ] = sizeof("255.255.255.255 "),
 122        [OPTION_IP_PAIR         ] = sizeof("255.255.255.255 ") * 2,
 123        [OPTION_STATIC_ROUTES   ] = sizeof("255.255.255.255/32 255.255.255.255 "),
 124        [OPTION_6RD             ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
 125        [OPTION_STRING          ] = 1,
 126        [OPTION_STRING_HOST     ] = 1,
 127#if ENABLE_FEATURE_UDHCP_RFC3397
 128        [OPTION_DNS_STRING      ] = 1, /* unused */
 129        /* Hmmm, this severely overestimates size if SIP_SERVERS option
 130         * is in domain name form: N-byte option in binary form
 131         * mallocs ~16*N bytes. But it is freed almost at once.
 132         */
 133        [OPTION_SIP_SERVERS     ] = sizeof("255.255.255.255 "),
 134#endif
 135//      [OPTION_BOOLEAN         ] = sizeof("yes "),
 136        [OPTION_U8              ] = sizeof("255 "),
 137        [OPTION_U16             ] = sizeof("65535 "),
 138//      [OPTION_S16             ] = sizeof("-32768 "),
 139        [OPTION_U32             ] = sizeof("4294967295 "),
 140        [OPTION_S32             ] = sizeof("-2147483684 "),
 141};
 142
 143/* note: ip is a pointer to an IP in network order, possibly misaliged */
 144static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
 145{
 146        return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
 147}
 148
 149/* really simple implementation, just count the bits */
 150static int mton(uint32_t mask)
 151{
 152        int i = 0;
 153        mask = ntohl(mask); /* 111110000-like bit pattern */
 154        while (mask) {
 155                i++;
 156                mask <<= 1;
 157        }
 158        return i;
 159}
 160
 161#if ENABLE_FEATURE_UDHCPC_SANITIZEOPT
 162/* Check if a given label represents a valid DNS label
 163 * Return pointer to the first character after the label
 164 * (NUL or dot) upon success, NULL otherwise.
 165 * See RFC1035, 2.3.1
 166 */
 167/* We don't need to be particularly anal. For example, allowing _, hyphen
 168 * at the end, or leading and trailing dots would be ok, since it
 169 * can't be used for attacks. (Leading hyphen can be, if someone uses
 170 * cmd "$hostname"
 171 * in the script: then hostname may be treated as an option)
 172 */
 173static const char *valid_domain_label(const char *label)
 174{
 175        unsigned char ch;
 176        //unsigned pos = 0;
 177
 178        if (label[0] == '-')
 179                return NULL;
 180        for (;;) {
 181                ch = *label;
 182                if ((ch|0x20) < 'a' || (ch|0x20) > 'z') {
 183                        if (ch < '0' || ch > '9') {
 184                                if (ch == '\0' || ch == '.')
 185                                        return label;
 186                                /* DNS allows only '-', but we are more permissive */
 187                                if (ch != '-' && ch != '_')
 188                                        return NULL;
 189                        }
 190                }
 191                label++;
 192                //pos++;
 193                //Do we want this?
 194                //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */
 195                //      return NULL;
 196        }
 197}
 198
 199/* Check if a given name represents a valid DNS name */
 200/* See RFC1035, 2.3.1 */
 201static int good_hostname(const char *name)
 202{
 203        //const char *start = name;
 204
 205        for (;;) {
 206                name = valid_domain_label(name);
 207                if (!name)
 208                        return 0;
 209                if (!name[0])
 210                        return 1;
 211                        //Do we want this?
 212                        //return ((name - start) < 1025); /* NS_MAXDNAME */
 213                name++;
 214                if (*name == '\0')
 215                        return 1; // We allow trailing dot too
 216        }
 217}
 218#else
 219# define good_hostname(name) 1
 220#endif
 221
 222/* Create "opt_name=opt_value" string */
 223static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name)
 224{
 225        unsigned upper_length;
 226        int len, type, optlen;
 227        char *dest, *ret;
 228
 229        /* option points to OPT_DATA, need to go back to get OPT_LEN */
 230        len = option[-OPT_DATA + OPT_LEN];
 231
 232        type = optflag->flags & OPTION_TYPE_MASK;
 233        optlen = dhcp_option_lengths[type];
 234        upper_length = len_of_option_as_string[type]
 235                * ((unsigned)(len + optlen) / (unsigned)optlen);
 236
 237        dest = ret = xmalloc(upper_length + strlen(opt_name) + 2);
 238        dest += sprintf(ret, "%s=", opt_name);
 239
 240        while (len >= optlen) {
 241                switch (type) {
 242                case OPTION_IP:
 243                case OPTION_IP_PAIR:
 244                        dest += sprint_nip(dest, "", option);
 245                        if (type == OPTION_IP)
 246                                break;
 247                        dest += sprint_nip(dest, "/", option + 4);
 248                        break;
 249//              case OPTION_BOOLEAN:
 250//                      dest += sprintf(dest, *option ? "yes" : "no");
 251//                      break;
 252                case OPTION_U8:
 253                        dest += sprintf(dest, "%u", *option);
 254                        break;
 255//              case OPTION_S16:
 256                case OPTION_U16: {
 257                        uint16_t val_u16;
 258                        move_from_unaligned16(val_u16, option);
 259                        dest += sprintf(dest, "%u", ntohs(val_u16));
 260                        break;
 261                }
 262                case OPTION_S32:
 263                case OPTION_U32: {
 264                        uint32_t val_u32;
 265                        move_from_unaligned32(val_u32, option);
 266                        dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32));
 267                        break;
 268                }
 269                /* Note: options which use 'return' instead of 'break'
 270                 * (for example, OPTION_STRING) skip the code which handles
 271                 * the case of list of options.
 272                 */
 273                case OPTION_STRING:
 274                case OPTION_STRING_HOST:
 275                        memcpy(dest, option, len);
 276                        dest[len] = '\0';
 277//TODO: it appears option 15 DHCP_DOMAIN_NAME is often abused
 278//by DHCP admins to contain a space-separated list of domains,
 279//not one domain name (presumably, to work as list of search domains,
 280//instead of using proper option 119 DHCP_DOMAIN_SEARCH).
 281//Currently, good_hostname() balks on strings containing spaces.
 282//Do we need to allow it? Only for DHCP_DOMAIN_NAME option?
 283                        if (type == OPTION_STRING_HOST && !good_hostname(dest))
 284                                safe_strncpy(dest, "bad", len);
 285                        return ret;
 286                case OPTION_STATIC_ROUTES: {
 287                        /* Option binary format:
 288                         * mask [one byte, 0..32]
 289                         * ip [big endian, 0..4 bytes depending on mask]
 290                         * router [big endian, 4 bytes]
 291                         * may be repeated
 292                         *
 293                         * We convert it to a string "IP/MASK ROUTER IP2/MASK2 ROUTER2"
 294                         */
 295                        const char *pfx = "";
 296
 297                        while (len >= 1 + 4) { /* mask + 0-byte ip + router */
 298                                uint32_t nip;
 299                                uint8_t *p;
 300                                unsigned mask;
 301                                int bytes;
 302
 303                                mask = *option++;
 304                                if (mask > 32)
 305                                        break;
 306                                len--;
 307
 308                                nip = 0;
 309                                p = (void*) &nip;
 310                                bytes = (mask + 7) / 8; /* 0 -> 0, 1..8 -> 1, 9..16 -> 2 etc */
 311                                while (--bytes >= 0) {
 312                                        *p++ = *option++;
 313                                        len--;
 314                                }
 315                                if (len < 4)
 316                                        break;
 317
 318                                /* print ip/mask */
 319                                dest += sprint_nip(dest, pfx, (void*) &nip);
 320                                pfx = " ";
 321                                dest += sprintf(dest, "/%u ", mask);
 322                                /* print router */
 323                                dest += sprint_nip(dest, "", option);
 324                                option += 4;
 325                                len -= 4;
 326                        }
 327
 328                        return ret;
 329                }
 330                case OPTION_6RD:
 331                        /* Option binary format (see RFC 5969):
 332                         *  0                   1                   2                   3
 333                         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 334                         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 335                         * |  OPTION_6RD   | option-length |  IPv4MaskLen  |  6rdPrefixLen |
 336                         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 337                         * |                           6rdPrefix                           |
 338                         * ...                        (16 octets)                        ...
 339                         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 340                         * ...                   6rdBRIPv4Address(es)                    ...
 341                         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 342                         * We convert it to a string
 343                         * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..."
 344                         *
 345                         * Sanity check: ensure that our length is at least 22 bytes, that
 346                         * IPv4MaskLen <= 32,
 347                         * 6rdPrefixLen <= 128,
 348                         * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128
 349                         * (2nd condition need no check - it follows from 1st and 3rd).
 350                         * Else, return envvar with empty value ("optname=")
 351                         */
 352                        if (len >= (1 + 1 + 16 + 4)
 353                         && option[0] <= 32
 354                         && (option[1] + 32 - option[0]) <= 128
 355                        ) {
 356                                /* IPv4MaskLen */
 357                                dest += sprintf(dest, "%u ", *option++);
 358                                /* 6rdPrefixLen */
 359                                dest += sprintf(dest, "%u ", *option++);
 360                                /* 6rdPrefix */
 361                                dest += sprint_nip6(dest, /* "", */ option);
 362                                option += 16;
 363                                len -= 1 + 1 + 16 + 4;
 364                                /* "+ 4" above corresponds to the length of IPv4 addr
 365                                 * we consume in the loop below */
 366                                while (1) {
 367                                        /* 6rdBRIPv4Address(es) */
 368                                        dest += sprint_nip(dest, " ", option);
 369                                        option += 4;
 370                                        len -= 4; /* do we have yet another 4+ bytes? */
 371                                        if (len < 0)
 372                                                break; /* no */
 373                                }
 374                        }
 375
 376                        return ret;
 377#if ENABLE_FEATURE_UDHCP_RFC3397
 378                case OPTION_DNS_STRING:
 379                        /* unpack option into dest; use ret for prefix (i.e., "optname=") */
 380                        dest = dname_dec(option, len, ret);
 381                        if (dest) {
 382                                free(ret);
 383                                return dest;
 384                        }
 385                        /* error. return "optname=" string */
 386                        return ret;
 387                case OPTION_SIP_SERVERS:
 388                        /* Option binary format:
 389                         * type: byte
 390                         * type=0: domain names, dns-compressed
 391                         * type=1: IP addrs
 392                         */
 393                        option++;
 394                        len--;
 395                        if (option[-1] == 0) {
 396                                dest = dname_dec(option, len, ret);
 397                                if (dest) {
 398                                        free(ret);
 399                                        return dest;
 400                                }
 401                        } else
 402                        if (option[-1] == 1) {
 403                                const char *pfx = "";
 404                                while (1) {
 405                                        len -= 4;
 406                                        if (len < 0)
 407                                                break;
 408                                        dest += sprint_nip(dest, pfx, option);
 409                                        pfx = " ";
 410                                        option += 4;
 411                                }
 412                        }
 413                        return ret;
 414#endif
 415                } /* switch */
 416
 417                /* If we are here, try to format any remaining data
 418                 * in the option as another, similarly-formatted option
 419                 */
 420                option += optlen;
 421                len -= optlen;
 422// TODO: it can be a list only if (optflag->flags & OPTION_LIST).
 423// Should we bail out/warn if we see multi-ip option which is
 424// not allowed to be such (for example, DHCP_BROADCAST)? -
 425                if (len < optlen /* || !(optflag->flags & OPTION_LIST) */)
 426                        break;
 427                *dest++ = ' ';
 428                *dest = '\0';
 429        } /* while */
 430
 431        return ret;
 432}
 433
 434/* put all the parameters into the environment */
 435static char **fill_envp(struct dhcp_packet *packet)
 436{
 437        int envc;
 438        int i;
 439        char **envp, **curr;
 440        const char *opt_name;
 441        uint8_t *temp;
 442        uint8_t overload = 0;
 443
 444#define BITMAP unsigned
 445#define BBITS (sizeof(BITMAP) * 8)
 446#define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1)))
 447#define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS])
 448        BITMAP found_opts[256 / BBITS];
 449
 450        memset(found_opts, 0, sizeof(found_opts));
 451
 452        /* We need 6 elements for:
 453         * "interface=IFACE"
 454         * "ip=N.N.N.N" from packet->yiaddr
 455         * "siaddr=IP" from packet->siaddr_nip (unless 0)
 456         * "boot_file=FILE" from packet->file (unless overloaded)
 457         * "sname=SERVER_HOSTNAME" from packet->sname (unless overloaded)
 458         * terminating NULL
 459         */
 460        envc = 6;
 461        /* +1 element for each option, +2 for subnet option: */
 462        if (packet) {
 463                /* note: do not search for "pad" (0) and "end" (255) options */
 464//TODO: change logic to scan packet _once_
 465                for (i = 1; i < 255; i++) {
 466                        temp = udhcp_get_option(packet, i);
 467                        if (temp) {
 468                                if (i == DHCP_OPTION_OVERLOAD)
 469                                        overload |= *temp;
 470                                else if (i == DHCP_SUBNET)
 471                                        envc++; /* for $mask */
 472                                envc++;
 473                                /*if (i != DHCP_MESSAGE_TYPE)*/
 474                                FOUND_OPTS(i) |= BMASK(i);
 475                        }
 476                }
 477        }
 478        curr = envp = xzalloc(sizeof(envp[0]) * envc);
 479
 480        *curr = xasprintf("interface=%s", client_data.interface);
 481        putenv(*curr++);
 482
 483        if (!packet)
 484                return envp;
 485
 486        /* Export BOOTP fields. Fields we don't (yet?) export:
 487         * uint8_t op;      // always BOOTREPLY
 488         * uint8_t htype;   // hardware address type. 1 = 10mb ethernet
 489         * uint8_t hlen;    // hardware address length
 490         * uint8_t hops;    // used by relay agents only
 491         * uint32_t xid;
 492         * uint16_t secs;   // elapsed since client began acquisition/renewal
 493         * uint16_t flags;  // only one flag so far: bcast. Never set by server
 494         * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different
 495         *                  // if during renew server wants to give us different IP?)
 496         * uint32_t gateway_nip; // relay agent IP address
 497         * uint8_t chaddr[16]; // link-layer client hardware address (MAC)
 498         * TODO: export gateway_nip as $giaddr?
 499         */
 500        /* Most important one: yiaddr as $ip */
 501        *curr = xmalloc(sizeof("ip=255.255.255.255"));
 502        sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr);
 503        putenv(*curr++);
 504        if (packet->siaddr_nip) {
 505                /* IP address of next server to use in bootstrap */
 506                *curr = xmalloc(sizeof("siaddr=255.255.255.255"));
 507                sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip);
 508                putenv(*curr++);
 509        }
 510        if (!(overload & FILE_FIELD) && packet->file[0]) {
 511                /* watch out for invalid packets */
 512                *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file);
 513                putenv(*curr++);
 514        }
 515        if (!(overload & SNAME_FIELD) && packet->sname[0]) {
 516                /* watch out for invalid packets */
 517                *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname);
 518                putenv(*curr++);
 519        }
 520
 521        /* Export known DHCP options */
 522        opt_name = dhcp_option_strings;
 523        i = 0;
 524        while (*opt_name) {
 525                uint8_t code = dhcp_optflags[i].code;
 526                BITMAP *found_ptr = &FOUND_OPTS(code);
 527                BITMAP found_mask = BMASK(code);
 528                if (!(*found_ptr & found_mask))
 529                        goto next;
 530                *found_ptr &= ~found_mask; /* leave only unknown options */
 531                temp = udhcp_get_option(packet, code);
 532                *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name);
 533                putenv(*curr++);
 534                if (code == DHCP_SUBNET && temp[-OPT_DATA + OPT_LEN] == 4) {
 535                        /* Subnet option: make things like "$ip/$mask" possible */
 536                        uint32_t subnet;
 537                        move_from_unaligned32(subnet, temp);
 538                        *curr = xasprintf("mask=%u", mton(subnet));
 539                        putenv(*curr++);
 540                }
 541 next:
 542                opt_name += strlen(opt_name) + 1;
 543                i++;
 544        }
 545        /* Export unknown options */
 546        for (i = 0; i < 256;) {
 547                BITMAP bitmap = FOUND_OPTS(i);
 548                if (!bitmap) {
 549                        i += BBITS;
 550                        continue;
 551                }
 552                if (bitmap & BMASK(i)) {
 553                        unsigned len, ofs;
 554
 555                        temp = udhcp_get_option(packet, i);
 556                        /* udhcp_get_option returns ptr to data portion,
 557                         * need to go back to get len
 558                         */
 559                        len = temp[-OPT_DATA + OPT_LEN];
 560                        *curr = xmalloc(sizeof("optNNN=") + 1 + len*2);
 561                        ofs = sprintf(*curr, "opt%u=", i);
 562                        *bin2hex(*curr + ofs, (void*) temp, len) = '\0';
 563                        putenv(*curr++);
 564                }
 565                i++;
 566        }
 567
 568        return envp;
 569}
 570
 571/* Call a script with a par file and env vars */
 572static void udhcp_run_script(struct dhcp_packet *packet, const char *name)
 573{
 574        char **envp, **curr;
 575        char *argv[3];
 576
 577        envp = fill_envp(packet);
 578
 579        /* call script */
 580        log1("executing %s %s", client_data.script, name);
 581        argv[0] = (char*) client_data.script;
 582        argv[1] = (char*) name;
 583        argv[2] = NULL;
 584        spawn_and_wait(argv);
 585
 586        for (curr = envp; *curr; curr++) {
 587                log2(" %s", *curr);
 588                bb_unsetenv_and_free(*curr);
 589        }
 590        free(envp);
 591}
 592
 593
 594/*** Sending/receiving packets ***/
 595
 596static ALWAYS_INLINE uint32_t random_xid(void)
 597{
 598        return rand();
 599}
 600
 601/* Initialize the packet with the proper defaults */
 602static void init_packet(struct dhcp_packet *packet, char type)
 603{
 604        uint16_t secs;
 605
 606        /* Fill in: op, htype, hlen, cookie fields; message type option: */
 607        udhcp_init_header(packet, type);
 608
 609        packet->xid = random_xid();
 610
 611        client_data.last_secs = monotonic_sec();
 612        if (client_data.first_secs == 0)
 613                client_data.first_secs = client_data.last_secs;
 614        secs = client_data.last_secs - client_data.first_secs;
 615        packet->secs = htons(secs);
 616
 617        memcpy(packet->chaddr, client_data.client_mac, 6);
 618        if (client_data.clientid)
 619                udhcp_add_binary_option(packet, client_data.clientid);
 620}
 621
 622static void add_client_options(struct dhcp_packet *packet)
 623{
 624        int i, end, len;
 625
 626        udhcp_add_simple_option(packet, DHCP_MAX_SIZE, htons(IP_UDP_DHCP_SIZE));
 627
 628        /* Add a "param req" option with the list of options we'd like to have
 629         * from stubborn DHCP servers. Pull the data from the struct in common.c.
 630         * No bounds checking because it goes towards the head of the packet. */
 631        end = udhcp_end_option(packet->options);
 632        len = 0;
 633        for (i = 1; i < DHCP_END; i++) {
 634                if (client_data.opt_mask[i >> 3] & (1 << (i & 7))) {
 635                        packet->options[end + OPT_DATA + len] = i;
 636                        len++;
 637                }
 638        }
 639        if (len) {
 640                packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
 641                packet->options[end + OPT_LEN] = len;
 642                packet->options[end + OPT_DATA + len] = DHCP_END;
 643        }
 644
 645        if (client_data.vendorclass)
 646                udhcp_add_binary_option(packet, client_data.vendorclass);
 647        if (client_data.hostname)
 648                udhcp_add_binary_option(packet, client_data.hostname);
 649        if (client_data.fqdn)
 650                udhcp_add_binary_option(packet, client_data.fqdn);
 651
 652        /* Request broadcast replies if we have no IP addr */
 653        if ((option_mask32 & OPT_B) && packet->ciaddr == 0)
 654                packet->flags |= htons(BROADCAST_FLAG);
 655
 656        /* Add -x options if any */
 657        {
 658                struct option_set *curr = client_data.options;
 659                while (curr) {
 660                        udhcp_add_binary_option(packet, curr->data);
 661                        curr = curr->next;
 662                }
 663//              if (client_data.sname)
 664//                      strncpy((char*)packet->sname, client_data.sname, sizeof(packet->sname) - 1);
 665//              if (client_data.boot_file)
 666//                      strncpy((char*)packet->file, client_data.boot_file, sizeof(packet->file) - 1);
 667        }
 668
 669        // This will be needed if we remove -V VENDOR_STR in favor of
 670        // -x vendor:VENDOR_STR
 671        //if (!udhcp_find_option(packet.options, DHCP_VENDOR))
 672        //      /* not set, set the default vendor ID */
 673        //      ...add (DHCP_VENDOR, "udhcp "BB_VER) opt...
 674}
 675
 676/* RFC 2131
 677 * 4.4.4 Use of broadcast and unicast
 678 *
 679 * The DHCP client broadcasts DHCPDISCOVER, DHCPREQUEST and DHCPINFORM
 680 * messages, unless the client knows the address of a DHCP server.
 681 * The client unicasts DHCPRELEASE messages to the server. Because
 682 * the client is declining the use of the IP address supplied by the server,
 683 * the client broadcasts DHCPDECLINE messages.
 684 *
 685 * When the DHCP client knows the address of a DHCP server, in either
 686 * INIT or REBOOTING state, the client may use that address
 687 * in the DHCPDISCOVER or DHCPREQUEST rather than the IP broadcast address.
 688 * The client may also use unicast to send DHCPINFORM messages
 689 * to a known DHCP server. If the client receives no response to DHCP
 690 * messages sent to the IP address of a known DHCP server, the DHCP
 691 * client reverts to using the IP broadcast address.
 692 */
 693
 694static int raw_bcast_from_client_data_ifindex(struct dhcp_packet *packet, uint32_t src_nip)
 695{
 696        return udhcp_send_raw_packet(packet,
 697                /*src*/ src_nip, CLIENT_PORT,
 698                /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
 699                client_data.ifindex);
 700}
 701
 702static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
 703{
 704        if (server)
 705                return udhcp_send_kernel_packet(packet,
 706                        ciaddr, CLIENT_PORT,
 707                        server, SERVER_PORT);
 708        return raw_bcast_from_client_data_ifindex(packet, ciaddr);
 709}
 710
 711/* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
 712/* NOINLINE: limit stack usage in caller */
 713static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
 714{
 715        struct dhcp_packet packet;
 716
 717        /* Fill in: op, htype, hlen, cookie, chaddr fields,
 718         * random xid field (we override it below),
 719         * client-id option (unless -C), message type option:
 720         */
 721        init_packet(&packet, DHCPDISCOVER);
 722
 723        packet.xid = xid;
 724        if (requested)
 725                udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
 726
 727        /* Add options: maxsize,
 728         * optionally: hostname, fqdn, vendorclass,
 729         * "param req" option according to -O, options specified with -x
 730         */
 731        add_client_options(&packet);
 732
 733        bb_info_msg("sending %s", "discover");
 734        return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
 735}
 736
 737/* Broadcast a DHCP request message */
 738/* RFC 2131 3.1 paragraph 3:
 739 * "The client _broadcasts_ a DHCPREQUEST message..."
 740 */
 741/* NOINLINE: limit stack usage in caller */
 742static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requested)
 743{
 744        struct dhcp_packet packet;
 745        struct in_addr temp_addr;
 746
 747/*
 748 * RFC 2131 4.3.2 DHCPREQUEST message
 749 * ...
 750 * If the DHCPREQUEST message contains a 'server identifier'
 751 * option, the message is in response to a DHCPOFFER message.
 752 * Otherwise, the message is a request to verify or extend an
 753 * existing lease. If the client uses a 'client identifier'
 754 * in a DHCPREQUEST message, it MUST use that same 'client identifier'
 755 * in all subsequent messages. If the client included a list
 756 * of requested parameters in a DHCPDISCOVER message, it MUST
 757 * include that list in all subsequent messages.
 758 */
 759        /* Fill in: op, htype, hlen, cookie, chaddr fields,
 760         * random xid field (we override it below),
 761         * client-id option (unless -C), message type option:
 762         */
 763        init_packet(&packet, DHCPREQUEST);
 764
 765        packet.xid = xid;
 766        udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
 767
 768        udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
 769
 770        /* Add options: maxsize,
 771         * optionally: hostname, fqdn, vendorclass,
 772         * "param req" option according to -O, and options specified with -x
 773         */
 774        add_client_options(&packet);
 775
 776        temp_addr.s_addr = requested;
 777        bb_info_msg("sending select for %s", inet_ntoa(temp_addr));
 778        return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
 779}
 780
 781/* Unicast or broadcast a DHCP renew message */
 782/* NOINLINE: limit stack usage in caller */
 783static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
 784{
 785        struct dhcp_packet packet;
 786        struct in_addr temp_addr;
 787
 788/*
 789 * RFC 2131 4.3.2 DHCPREQUEST message
 790 * ...
 791 * DHCPREQUEST generated during RENEWING state:
 792 *
 793 * 'server identifier' MUST NOT be filled in, 'requested IP address'
 794 * option MUST NOT be filled in, 'ciaddr' MUST be filled in with
 795 * client's IP address. In this situation, the client is completely
 796 * configured, and is trying to extend its lease. This message will
 797 * be unicast, so no relay agents will be involved in its
 798 * transmission.  Because 'giaddr' is therefore not filled in, the
 799 * DHCP server will trust the value in 'ciaddr', and use it when
 800 * replying to the client.
 801 */
 802        /* Fill in: op, htype, hlen, cookie, chaddr fields,
 803         * random xid field (we override it below),
 804         * client-id option (unless -C), message type option:
 805         */
 806        init_packet(&packet, DHCPREQUEST);
 807
 808        packet.xid = xid;
 809        packet.ciaddr = ciaddr;
 810
 811        /* Add options: maxsize,
 812         * optionally: hostname, fqdn, vendorclass,
 813         * "param req" option according to -O, and options specified with -x
 814         */
 815        add_client_options(&packet);
 816
 817        temp_addr.s_addr = server;
 818        bb_info_msg("sending renew to %s", inet_ntoa(temp_addr));
 819        return bcast_or_ucast(&packet, ciaddr, server);
 820}
 821
 822#if ENABLE_FEATURE_UDHCPC_ARPING
 823/* Broadcast a DHCP decline message */
 824/* NOINLINE: limit stack usage in caller */
 825static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t requested)
 826{
 827        struct dhcp_packet packet;
 828
 829        /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields,
 830         * client-id option (unless -C), message type option:
 831         */
 832        init_packet(&packet, DHCPDECLINE);
 833
 834#if 0
 835        /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client,
 836         * but in case the server is buggy and wants DHCPDECLINE's xid
 837         * to match the xid which started entire handshake,
 838         * we use the same xid we used in initial DHCPDISCOVER:
 839         */
 840        packet.xid = xid;
 841#endif
 842        /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */
 843        udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
 844
 845        udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
 846
 847        bb_info_msg("sending %s", "decline");
 848        return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY);
 849}
 850#endif
 851
 852/* Unicast a DHCP release message */
 853static
 854ALWAYS_INLINE /* one caller, help compiler to use this fact */
 855int send_release(uint32_t server, uint32_t ciaddr)
 856{
 857        struct dhcp_packet packet;
 858
 859        /* Fill in: op, htype, hlen, cookie, chaddr, random xid fields,
 860         * client-id option (unless -C), message type option:
 861         */
 862        init_packet(&packet, DHCPRELEASE);
 863
 864        /* DHCPRELEASE uses ciaddr, not "requested ip", to store IP being released */
 865        packet.ciaddr = ciaddr;
 866
 867        udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
 868
 869        bb_info_msg("sending %s", "release");
 870        /* Note: normally we unicast here since "server" is not zero.
 871         * However, there _are_ people who run "address-less" DHCP servers,
 872         * and reportedly ISC dhcp client and Windows allow that.
 873         */
 874        return bcast_or_ucast(&packet, ciaddr, server);
 875}
 876
 877/* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */
 878/* NOINLINE: limit stack usage in caller */
 879static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
 880{
 881        int bytes;
 882        struct ip_udp_dhcp_packet packet;
 883        uint16_t check;
 884        unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
 885        struct iovec iov;
 886        struct msghdr msg;
 887        struct cmsghdr *cmsg;
 888
 889        /* used to use just safe_read(fd, &packet, sizeof(packet))
 890         * but we need to check for TP_STATUS_CSUMNOTREADY :(
 891         */
 892        iov.iov_base = &packet;
 893        iov.iov_len = sizeof(packet);
 894        memset(&msg, 0, sizeof(msg));
 895        msg.msg_iov = &iov;
 896        msg.msg_iovlen = 1;
 897        msg.msg_control = cmsgbuf;
 898        msg.msg_controllen = sizeof(cmsgbuf);
 899        for (;;) {
 900                bytes = recvmsg(fd, &msg, 0);
 901                if (bytes < 0) {
 902                        if (errno == EINTR)
 903                                continue;
 904                        log1("packet read error, ignoring");
 905                        /* NB: possible down interface, etc. Caller should pause. */
 906                        return bytes; /* returns -1 */
 907                }
 908                break;
 909        }
 910
 911        if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) {
 912                log1("packet is too short, ignoring");
 913                return -2;
 914        }
 915
 916        if (bytes < ntohs(packet.ip.tot_len)) {
 917                /* packet is bigger than sizeof(packet), we did partial read */
 918                log1("oversized packet, ignoring");
 919                return -2;
 920        }
 921
 922        /* ignore any extra garbage bytes */
 923        bytes = ntohs(packet.ip.tot_len);
 924
 925        /* make sure its the right packet for us, and that it passes sanity checks */
 926        if (packet.ip.protocol != IPPROTO_UDP
 927         || packet.ip.version != IPVERSION
 928         || packet.ip.ihl != (sizeof(packet.ip) >> 2)
 929         || packet.udp.dest != htons(CLIENT_PORT)
 930        /* || bytes > (int) sizeof(packet) - can't happen */
 931         || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip))
 932        ) {
 933                log1("unrelated/bogus packet, ignoring");
 934                return -2;
 935        }
 936
 937        /* verify IP checksum */
 938        check = packet.ip.check;
 939        packet.ip.check = 0;
 940        if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) {
 941                log1("bad IP header checksum, ignoring");
 942                return -2;
 943        }
 944
 945        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
 946                if (cmsg->cmsg_level == SOL_PACKET
 947                 && cmsg->cmsg_type == PACKET_AUXDATA
 948                ) {
 949                        /* some VMs don't checksum UDP and TCP data
 950                         * they send to the same physical machine,
 951                         * here we detect this case:
 952                         */
 953                        struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);
 954                        if (aux->tp_status & TP_STATUS_CSUMNOTREADY)
 955                                goto skip_udp_sum_check;
 956                }
 957        }
 958
 959        /* verify UDP checksum. IP header has to be modified for this */
 960        memset(&packet.ip, 0, offsetof(struct iphdr, protocol));
 961        /* ip.xx fields which are not memset: protocol, check, saddr, daddr */
 962        packet.ip.tot_len = packet.udp.len; /* yes, this is needed */
 963        check = packet.udp.check;
 964        packet.udp.check = 0;
 965        if (check && check != inet_cksum((uint16_t *)&packet, bytes)) {
 966                log1("packet with bad UDP checksum received, ignoring");
 967                return -2;
 968        }
 969 skip_udp_sum_check:
 970
 971        if (packet.data.cookie != htonl(DHCP_MAGIC)) {
 972                bb_info_msg("packet with bad magic, ignoring");
 973                return -2;
 974        }
 975
 976        log1("received %s", "a packet");
 977        udhcp_dump_packet(&packet.data);
 978
 979        bytes -= sizeof(packet.ip) + sizeof(packet.udp);
 980        memcpy(dhcp_pkt, &packet.data, bytes);
 981        return bytes;
 982}
 983
 984
 985/*** Main ***/
 986
 987/* Values for client_data.listen_mode */
 988#define LISTEN_NONE   0
 989#define LISTEN_KERNEL 1
 990#define LISTEN_RAW    2
 991
 992/* Values for client_data.state */
 993/* initial state: (re)start DHCP negotiation */
 994#define INIT_SELECTING  0
 995/* discover was sent, DHCPOFFER reply received */
 996#define REQUESTING      1
 997/* select/renew was sent, DHCPACK reply received */
 998#define BOUND           2
 999/* half of lease passed, want to renew it by sending unicast renew requests */
1000#define RENEWING        3
1001/* renew requests were not answered, lease is almost over, send broadcast renew */
1002#define REBINDING       4
1003/* manually requested renew (SIGUSR1) */
1004#define RENEW_REQUESTED 5
1005/* release, possibly manually requested (SIGUSR2) */
1006#define RELEASED        6
1007
1008static int udhcp_raw_socket(int ifindex)
1009{
1010        int fd;
1011        struct sockaddr_ll sock;
1012
1013        log2("opening raw socket on ifindex %d", ifindex);
1014
1015        fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
1016        /* ^^^^^
1017         * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them)
1018         * ETH_P_IP: want to receive only packets with IPv4 eth type
1019         */
1020        log3("got raw socket fd %d", fd);
1021
1022        memset(&sock, 0, sizeof(sock)); /* let's be deterministic */
1023        sock.sll_family = AF_PACKET;
1024        sock.sll_protocol = htons(ETH_P_IP);
1025        sock.sll_ifindex = ifindex;
1026        /*sock.sll_hatype = ARPHRD_???;*/
1027        /*sock.sll_pkttype = PACKET_???;*/
1028        /*sock.sll_halen = ???;*/
1029        /*sock.sll_addr[8] = ???;*/
1030        xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
1031
1032#if 0 /* Several users reported breakage when BPF filter is used */
1033        if (CLIENT_PORT == 68) {
1034                /* Use only if standard port is in use */
1035                /*
1036                 *      I've selected not to see LL header, so BPF doesn't see it, too.
1037                 *      The filter may also pass non-IP and non-ARP packets, but we do
1038                 *      a more complete check when receiving the message in userspace.
1039                 *
1040                 * and filter shamelessly stolen from:
1041                 *
1042                 *      http://www.flamewarmaster.de/software/dhcpclient/
1043                 *
1044                 * There are a few other interesting ideas on that page (look under
1045                 * "Motivation").  Use of netlink events is most interesting.  Think
1046                 * of various network servers listening for events and reconfiguring.
1047                 * That would obsolete sending HUP signals and/or make use of restarts.
1048                 *
1049                 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>.
1050                 * License: GPL v2.
1051                 */
1052                static const struct sock_filter filter_instr[] = {
1053                        /* load 9th byte (protocol) */
1054                        BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
1055                        /* jump to L1 if it is IPPROTO_UDP, else to L4 */
1056                        BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
1057                        /* L1: load halfword from offset 6 (flags and frag offset) */
1058                        BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
1059                        /* jump to L4 if any bits in frag offset field are set, else to L2 */
1060                        BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
1061                        /* L2: skip IP header (load index reg with header len) */
1062                        BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
1063                        /* load udp destination port from halfword[header_len + 2] */
1064                        BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
1065                        /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */
1066                        BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
1067                        /* L3: accept packet ("accept 0x7fffffff bytes") */
1068                        /* Accepting 0xffffffff works too but kernel 2.6.19 is buggy */
1069                        BPF_STMT(BPF_RET|BPF_K, 0x7fffffff),
1070                        /* L4: discard packet ("accept zero bytes") */
1071                        BPF_STMT(BPF_RET|BPF_K, 0),
1072                };
1073                static const struct sock_fprog filter_prog = {
1074                        .len = sizeof(filter_instr) / sizeof(filter_instr[0]),
1075                        /* casting const away: */
1076                        .filter = (struct sock_filter *) filter_instr,
1077                };
1078                /* Ignoring error (kernel may lack support for this) */
1079                if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
1080                                sizeof(filter_prog)) >= 0)
1081                        log1("attached filter to raw socket fd"); // log?
1082        }
1083#endif
1084
1085        if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) {
1086                if (errno != ENOPROTOOPT)
1087                        log1("can't set PACKET_AUXDATA on raw socket");
1088        }
1089
1090        log1("created raw socket");
1091
1092        return fd;
1093}
1094
1095static void change_listen_mode(int new_mode)
1096{
1097        log1("entering listen mode: %s",
1098                new_mode != LISTEN_NONE
1099                        ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw")
1100                        : "none"
1101        );
1102
1103        client_data.listen_mode = new_mode;
1104        if (client_data.sockfd >= 0) {
1105                close(client_data.sockfd);
1106                client_data.sockfd = -1;
1107        }
1108        if (new_mode == LISTEN_KERNEL)
1109                client_data.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_data.interface);
1110        else if (new_mode != LISTEN_NONE)
1111                client_data.sockfd = udhcp_raw_socket(client_data.ifindex);
1112        /* else LISTEN_NONE: client_data.sockfd stays closed */
1113}
1114
1115/* Called only on SIGUSR1 */
1116static void perform_renew(void)
1117{
1118        bb_info_msg("performing DHCP renew");
1119        switch (client_data.state) {
1120        case BOUND:
1121                change_listen_mode(LISTEN_KERNEL);
1122        case RENEWING:
1123        case REBINDING:
1124                client_data.state = RENEW_REQUESTED;
1125                break;
1126        case RENEW_REQUESTED: /* impatient are we? fine, square 1 */
1127                udhcp_run_script(NULL, "deconfig");
1128        case REQUESTING:
1129        case RELEASED:
1130                change_listen_mode(LISTEN_RAW);
1131                client_data.state = INIT_SELECTING;
1132                break;
1133        case INIT_SELECTING:
1134                break;
1135        }
1136}
1137
1138static void perform_release(uint32_t server_addr, uint32_t requested_ip)
1139{
1140        char buffer[sizeof("255.255.255.255")];
1141        struct in_addr temp_addr;
1142
1143        /* send release packet */
1144        if (client_data.state == BOUND
1145         || client_data.state == RENEWING
1146         || client_data.state == REBINDING
1147         || client_data.state == RENEW_REQUESTED
1148        ) {
1149                temp_addr.s_addr = server_addr;
1150                strcpy(buffer, inet_ntoa(temp_addr));
1151                temp_addr.s_addr = requested_ip;
1152                bb_info_msg("unicasting a release of %s to %s",
1153                                inet_ntoa(temp_addr), buffer);
1154                send_release(server_addr, requested_ip); /* unicast */
1155        }
1156        bb_info_msg("entering released state");
1157/*
1158 * We can be here on: SIGUSR2,
1159 * or on exit (SIGTERM) and -R "release on quit" is specified.
1160 * Users requested to be notified in all cases, even if not in one
1161 * of the states above.
1162 */
1163        udhcp_run_script(NULL, "deconfig");
1164
1165        change_listen_mode(LISTEN_NONE);
1166        client_data.state = RELEASED;
1167}
1168
1169static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
1170{
1171        uint8_t *storage;
1172        int len = strnlen(str, 255);
1173        storage = xzalloc(len + extra + OPT_DATA);
1174        storage[OPT_CODE] = code;
1175        storage[OPT_LEN] = len + extra;
1176        memcpy(storage + extra + OPT_DATA, str, len);
1177        return storage;
1178}
1179
1180#if BB_MMU
1181static void client_background(void)
1182{
1183        bb_daemonize(0);
1184        logmode &= ~LOGMODE_STDIO;
1185        /* rewrite pidfile, as our pid is different now */
1186        write_pidfile(client_data.pidfile);
1187}
1188#endif
1189
1190//usage:#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
1191//usage:# define IF_UDHCP_VERBOSE(...) __VA_ARGS__
1192//usage:#else
1193//usage:# define IF_UDHCP_VERBOSE(...)
1194//usage:#endif
1195//usage:#define udhcpc_trivial_usage
1196//usage:       "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC/-n]\n"
1197//usage:       "        [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n"
1198//usage:       "        [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..."
1199//usage:#define udhcpc_full_usage "\n"
1200//usage:     "\n        -i IFACE        Interface to use (default eth0)"
1201//usage:        IF_FEATURE_UDHCP_PORT(
1202//usage:     "\n        -P PORT         Use PORT (default 68)"
1203//usage:        )
1204//usage:     "\n        -s PROG         Run PROG at DHCP events (default "CONFIG_UDHCPC_DEFAULT_SCRIPT")"
1205//usage:     "\n        -p FILE         Create pidfile"
1206//usage:     "\n        -B              Request broadcast replies"
1207//usage:     "\n        -t N            Send up to N discover packets (default 3)"
1208//usage:     "\n        -T SEC          Pause between packets (default 3)"
1209//usage:     "\n        -A SEC          Wait if lease is not obtained (default 20)"
1210//usage:        USE_FOR_MMU(
1211//usage:     "\n        -b              Background if lease is not obtained"
1212//usage:        )
1213//usage:     "\n        -n              Exit if lease is not obtained"
1214//usage:     "\n        -q              Exit after obtaining lease"
1215//usage:     "\n        -R              Release IP on exit"
1216//usage:     "\n        -f              Run in foreground"
1217//usage:     "\n        -S              Log to syslog too"
1218//usage:        IF_FEATURE_UDHCPC_ARPING(
1219//usage:     "\n        -a[MSEC]        Validate offered address with ARP ping"
1220//usage:        )
1221//usage:     "\n        -r IP           Request this IP address"
1222//usage:     "\n        -o              Don't request any options (unless -O is given)"
1223//usage:     "\n        -O OPT          Request option OPT from server (cumulative)"
1224//usage:     "\n        -x OPT:VAL      Include option OPT in sent packets (cumulative)"
1225//usage:     "\n                        Examples of string, numeric, and hex byte opts:"
1226//usage:     "\n                        -x hostname:bbox - option 12"
1227//usage:     "\n                        -x lease:3600 - option 51 (lease time)"
1228//usage:     "\n                        -x 0x3d:0100BEEFC0FFEE - option 61 (client id)"
1229//usage:     "\n                        -x 14:'\"dumpfile\"' - option 14 (shell-quoted)"
1230//usage:     "\n        -F NAME         Ask server to update DNS mapping for NAME"
1231//usage:     "\n        -V VENDOR       Vendor identifier (default 'udhcp VERSION')"
1232//usage:     "\n        -C              Don't send MAC as client identifier"
1233//usage:        IF_UDHCP_VERBOSE(
1234//usage:     "\n        -v              Verbose"
1235//usage:        )
1236//usage:     "\nSignals:"
1237//usage:     "\n        USR1    Renew lease"
1238//usage:     "\n        USR2    Release lease"
1239
1240
1241int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1242int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1243{
1244        uint8_t *message;
1245        const char *str_V, *str_h, *str_F, *str_r;
1246        IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";)
1247        IF_FEATURE_UDHCP_PORT(char *str_P;)
1248        void *clientid_mac_ptr;
1249        llist_t *list_O = NULL;
1250        llist_t *list_x = NULL;
1251        int tryagain_timeout = 20;
1252        int discover_timeout = 3;
1253        int discover_retries = 3;
1254        uint32_t server_addr = server_addr; /* for compiler */
1255        uint32_t requested_ip = 0;
1256        uint32_t xid = xid; /* for compiler */
1257        int packet_num;
1258        int timeout; /* must be signed */
1259        unsigned already_waited_sec;
1260        unsigned opt;
1261        IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;)
1262        int retval;
1263
1264        setup_common_bufsiz();
1265
1266        /* Default options */
1267        IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
1268        IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
1269        client_data.interface = "eth0";
1270        client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
1271        client_data.sockfd = -1;
1272        str_V = "udhcp "BB_VER;
1273
1274        /* Make sure fd 0,1,2 are open */
1275        /* Set up the signal pipe on fds 3,4 - must be before openlog() */
1276        udhcp_sp_setup();
1277
1278        /* Parse command line */
1279        opt = getopt32long(argv, "^"
1280                /* O,x: list; -T,-t,-A take numeric param */
1281                "CV:H:h:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB"
1282                USE_FOR_MMU("b")
1283                IF_FEATURE_UDHCPC_ARPING("a::")
1284                IF_FEATURE_UDHCP_PORT("P:")
1285                "v"
1286                "\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */
1287                , udhcpc_longopts
1288                , &str_V, &str_h, &str_h, &str_F
1289                , &client_data.interface, &client_data.pidfile /* i,p */
1290                , &str_r /* r */
1291                , &client_data.script /* s */
1292                , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
1293                , &list_O
1294                , &list_x
1295                IF_FEATURE_UDHCPC_ARPING(, &str_a)
1296                IF_FEATURE_UDHCP_PORT(, &str_P)
1297                IF_UDHCP_VERBOSE(, &dhcp_verbose)
1298        );
1299        if (opt & (OPT_h|OPT_H)) {
1300                //msg added 2011-11
1301                bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME");
1302                client_data.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
1303        }
1304        if (opt & OPT_F) {
1305                /* FQDN option format: [0x51][len][flags][0][0]<fqdn> */
1306                client_data.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
1307                /* Flag bits: 0000NEOS
1308                 * S: 1 = Client requests server to update A RR in DNS as well as PTR
1309                 * O: 1 = Server indicates to client that DNS has been updated regardless
1310                 * E: 1 = Name is in DNS format, i.e. <4>host<6>domain<3>com<0>,
1311                 *    not "host.domain.com". Format 0 is obsolete.
1312                 * N: 1 = Client requests server to not update DNS (S must be 0 then)
1313                 * Two [0] bytes which follow are deprecated and must be 0.
1314                 */
1315                client_data.fqdn[OPT_DATA + 0] = 0x1;
1316                /*client_data.fqdn[OPT_DATA + 1] = 0; - xzalloc did it */
1317                /*client_data.fqdn[OPT_DATA + 2] = 0; */
1318        }
1319        if (opt & OPT_r)
1320                requested_ip = inet_addr(str_r);
1321#if ENABLE_FEATURE_UDHCP_PORT
1322        if (opt & OPT_P) {
1323                CLIENT_PORT = xatou16(str_P);
1324                SERVER_PORT = CLIENT_PORT - 1;
1325        }
1326#endif
1327        IF_FEATURE_UDHCPC_ARPING(arpping_ms = xatou(str_a);)
1328        while (list_O) {
1329                char *optstr = llist_pop(&list_O);
1330                unsigned n = bb_strtou(optstr, NULL, 0);
1331                if (errno || n > 254) {
1332                        n = udhcp_option_idx(optstr, dhcp_option_strings);
1333                        n = dhcp_optflags[n].code;
1334                }
1335                client_data.opt_mask[n >> 3] |= 1 << (n & 7);
1336        }
1337        if (!(opt & OPT_o)) {
1338                unsigned i, n;
1339                for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) {
1340                        if (dhcp_optflags[i].flags & OPTION_REQ) {
1341                                client_data.opt_mask[n >> 3] |= 1 << (n & 7);
1342                        }
1343                }
1344        }
1345        while (list_x) {
1346                char *optstr = xstrdup(llist_pop(&list_x));
1347                udhcp_str2optset(optstr, &client_data.options,
1348                                dhcp_optflags, dhcp_option_strings,
1349                                /*dhcpv6:*/ 0
1350                );
1351                free(optstr);
1352        }
1353
1354        if (udhcp_read_interface(client_data.interface,
1355                        &client_data.ifindex,
1356                        NULL,
1357                        client_data.client_mac)
1358        ) {
1359                return 1;
1360        }
1361
1362        clientid_mac_ptr = NULL;
1363        if (!(opt & OPT_C) && !udhcp_find_option(client_data.options, DHCP_CLIENT_ID)) {
1364                /* not suppressed and not set, set the default client ID */
1365                client_data.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
1366                client_data.clientid[OPT_DATA] = 1; /* type: ethernet */
1367                clientid_mac_ptr = client_data.clientid + OPT_DATA+1;
1368                memcpy(clientid_mac_ptr, client_data.client_mac, 6);
1369        }
1370        if (str_V[0] != '\0') {
1371                // can drop -V, str_V, client_data.vendorclass,
1372                // but need to add "vendor" to the list of recognized
1373                // string opts for this to work;
1374                // and need to tweak add_client_options() too...
1375                // ...so the question is, should we?
1376                //bb_error_msg("option -V VENDOR is deprecated, use -x vendor:VENDOR");
1377                client_data.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
1378        }
1379
1380#if !BB_MMU
1381        /* on NOMMU reexec (i.e., background) early */
1382        if (!(opt & OPT_f)) {
1383                bb_daemonize_or_rexec(0 /* flags */, argv);
1384                logmode = LOGMODE_NONE;
1385        }
1386#endif
1387        if (opt & OPT_S) {
1388                openlog(applet_name, LOG_PID, LOG_DAEMON);
1389                logmode |= LOGMODE_SYSLOG;
1390        }
1391
1392        /* Create pidfile */
1393        write_pidfile(client_data.pidfile);
1394        /* Goes to stdout (unless NOMMU) and possibly syslog */
1395        bb_info_msg("started, v"BB_VER);
1396        /* We want random_xid to be random... */
1397        srand(monotonic_us());
1398
1399        client_data.state = INIT_SELECTING;
1400        udhcp_run_script(NULL, "deconfig");
1401        change_listen_mode(LISTEN_RAW);
1402        packet_num = 0;
1403        timeout = 0;
1404        already_waited_sec = 0;
1405
1406        /* Main event loop. select() waits on signal pipe and possibly
1407         * on sockfd.
1408         * "continue" statements in code below jump to the top of the loop.
1409         */
1410        for (;;) {
1411                int tv;
1412                struct pollfd pfds[2];
1413                struct dhcp_packet packet;
1414                /* silence "uninitialized!" warning */
1415                unsigned timestamp_before_wait = timestamp_before_wait;
1416
1417                //bb_error_msg("sockfd:%d, listen_mode:%d", client_data.sockfd, client_data.listen_mode);
1418
1419                /* Was opening raw or udp socket here
1420                 * if (client_data.listen_mode != LISTEN_NONE && client_data.sockfd < 0),
1421                 * but on fast network renew responses return faster
1422                 * than we open sockets. Thus this code is moved
1423                 * to change_listen_mode(). Thus we open listen socket
1424                 * BEFORE we send renew request (see "case BOUND:"). */
1425
1426                udhcp_sp_fd_set(pfds, client_data.sockfd);
1427
1428                tv = timeout - already_waited_sec;
1429                retval = 0;
1430                /* If we already timed out, fall through with retval = 0, else... */
1431                if (tv > 0) {
1432                        log1("waiting %u seconds", tv);
1433                        timestamp_before_wait = (unsigned)monotonic_sec();
1434                        retval = poll(pfds, 2, tv < INT_MAX/1000 ? tv * 1000 : INT_MAX);
1435                        if (retval < 0) {
1436                                /* EINTR? A signal was caught, don't panic */
1437                                if (errno == EINTR) {
1438                                        already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
1439                                        continue;
1440                                }
1441                                /* Else: an error occurred, panic! */
1442                                bb_perror_msg_and_die("poll");
1443                        }
1444                }
1445
1446                /* If timeout dropped to zero, time to become active:
1447                 * resend discover/renew/whatever
1448                 */
1449                if (retval == 0) {
1450                        /* When running on a bridge, the ifindex may have changed
1451                         * (e.g. if member interfaces were added/removed
1452                         * or if the status of the bridge changed).
1453                         * Refresh ifindex and client_mac:
1454                         */
1455                        if (udhcp_read_interface(client_data.interface,
1456                                        &client_data.ifindex,
1457                                        NULL,
1458                                        client_data.client_mac)
1459                        ) {
1460                                goto ret0; /* iface is gone? */
1461                        }
1462                        if (clientid_mac_ptr)
1463                                memcpy(clientid_mac_ptr, client_data.client_mac, 6);
1464
1465                        /* We will restart the wait in any case */
1466                        already_waited_sec = 0;
1467
1468                        switch (client_data.state) {
1469                        case INIT_SELECTING:
1470                                if (!discover_retries || packet_num < discover_retries) {
1471                                        if (packet_num == 0)
1472                                                xid = random_xid();
1473                                        /* broadcast */
1474                                        send_discover(xid, requested_ip);
1475                                        timeout = discover_timeout;
1476                                        packet_num++;
1477                                        continue;
1478                                }
1479 leasefail:
1480                                udhcp_run_script(NULL, "leasefail");
1481#if BB_MMU /* -b is not supported on NOMMU */
1482                                if (opt & OPT_b) { /* background if no lease */
1483                                        bb_info_msg("no lease, forking to background");
1484                                        client_background();
1485                                        /* do not background again! */
1486                                        opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f);
1487                                        /* ^^^ also disables -n (-b takes priority over -n):
1488                                         * ifup's default udhcpc options are -R -n,
1489                                         * and users want to be able to add -b
1490                                         * (in a config file) to make it background
1491                                         * _and not exit_.
1492                                         */
1493                                } else
1494#endif
1495                                if (opt & OPT_n) { /* abort if no lease */
1496                                        bb_info_msg("no lease, failing");
1497                                        retval = 1;
1498                                        goto ret;
1499                                }
1500                                /* wait before trying again */
1501                                timeout = tryagain_timeout;
1502                                packet_num = 0;
1503                                continue;
1504                        case REQUESTING:
1505                                if (packet_num < 3) {
1506                                        /* send broadcast select packet */
1507                                        send_select(xid, server_addr, requested_ip);
1508                                        timeout = discover_timeout;
1509                                        packet_num++;
1510                                        continue;
1511                                }
1512                                /* Timed out, go back to init state.
1513                                 * "discover...select...discover..." loops
1514                                 * were seen in the wild. Treat them similarly
1515                                 * to "no response to discover" case */
1516                                change_listen_mode(LISTEN_RAW);
1517                                client_data.state = INIT_SELECTING;
1518                                goto leasefail;
1519                        case BOUND:
1520                                /* 1/2 lease passed, enter renewing state */
1521                                client_data.state = RENEWING;
1522                                client_data.first_secs = 0; /* make secs field count from 0 */
1523                                change_listen_mode(LISTEN_KERNEL);
1524                                log1("entering renew state");
1525                                /* fall right through */
1526                        case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
1527                        case_RENEW_REQUESTED:
1528                        case RENEWING:
1529                                if (timeout >= 60) {
1530                                        /* send an unicast renew request */
1531                        /* Sometimes observed to fail (EADDRNOTAVAIL) to bind
1532                         * a new UDP socket for sending inside send_renew.
1533                         * I hazard to guess existing listening socket
1534                         * is somehow conflicting with it, but why is it
1535                         * not deterministic then?! Strange.
1536                         * Anyway, it does recover by eventually failing through
1537                         * into INIT_SELECTING state.
1538                         */
1539                                        if (send_renew(xid, server_addr, requested_ip) >= 0) {
1540                                                timeout >>= 1;
1541//TODO: the timeout to receive an answer for our renew should not be selected
1542//with "timeout = lease_seconds / 2; ...; timeout = timeout / 2": it is often huge.
1543//Waiting e.g. 4*3600 seconds for a reply does not make sense
1544//(if reply isn't coming, we keep an open socket for hours),
1545//it should be something like 10 seconds.
1546//Also, it's probably best to try sending renew in kernel mode a few (3-5) times
1547//and fall back to raw mode if it does not work.
1548                                                continue;
1549                                        }
1550                                        /* else: error sending.
1551                                         * example: ENETUNREACH seen with server
1552                                         * which gave us bogus server ID 1.1.1.1
1553                                         * which wasn't reachable (and probably did not exist).
1554                                         */
1555                                }
1556                                /* Timed out or error, enter rebinding state */
1557                                log1("entering rebinding state");
1558                                client_data.state = REBINDING;
1559                                /* fall right through */
1560                        case REBINDING:
1561                                /* Switch to bcast receive */
1562                                change_listen_mode(LISTEN_RAW);
1563                                /* Lease is *really* about to run out,
1564                                 * try to find DHCP server using broadcast */
1565                                if (timeout > 0) {
1566                                        /* send a broadcast renew request */
1567                                        send_renew(xid, 0 /*INADDR_ANY*/, requested_ip);
1568                                        timeout >>= 1;
1569                                        continue;
1570                                }
1571                                /* Timed out, enter init state */
1572                                bb_info_msg("lease lost, entering init state");
1573                                udhcp_run_script(NULL, "deconfig");
1574                                client_data.state = INIT_SELECTING;
1575                                client_data.first_secs = 0; /* make secs field count from 0 */
1576                                /*timeout = 0; - already is */
1577                                packet_num = 0;
1578                                continue;
1579                        /* case RELEASED: */
1580                        }
1581                        /* yah, I know, *you* say it would never happen */
1582                        timeout = INT_MAX;
1583                        continue; /* back to main loop */
1584                } /* if poll timed out */
1585
1586                /* poll() didn't timeout, something happened */
1587
1588                /* Is it a signal? */
1589                switch (udhcp_sp_read()) {
1590                case SIGUSR1:
1591                        client_data.first_secs = 0; /* make secs field count from 0 */
1592                        already_waited_sec = 0;
1593                        perform_renew();
1594                        if (client_data.state == RENEW_REQUESTED) {
1595                                /* We might be either on the same network
1596                                 * (in which case renew might work),
1597                                 * or we might be on a completely different one
1598                                 * (in which case renew won't ever succeed).
1599                                 * For the second case, must make sure timeout
1600                                 * is not too big, or else we can send
1601                                 * futile renew requests for hours.
1602                                 */
1603                                if (timeout > 60)
1604                                        timeout = 60;
1605                                goto case_RENEW_REQUESTED;
1606                        }
1607                        /* Start things over */
1608                        packet_num = 0;
1609                        /* Kill any timeouts, user wants this to hurry along */
1610                        timeout = 0;
1611                        continue;
1612                case SIGUSR2:
1613                        perform_release(server_addr, requested_ip);
1614                        timeout = INT_MAX;
1615                        continue;
1616                case SIGTERM:
1617                        bb_info_msg("received %s", "SIGTERM");
1618                        goto ret0;
1619                }
1620
1621                /* Is it a packet? */
1622                if (!pfds[1].revents)
1623                        continue; /* no */
1624
1625                {
1626                        int len;
1627
1628                        /* A packet is ready, read it */
1629                        if (client_data.listen_mode == LISTEN_KERNEL)
1630                                len = udhcp_recv_kernel_packet(&packet, client_data.sockfd);
1631                        else
1632                                len = udhcp_recv_raw_packet(&packet, client_data.sockfd);
1633                        if (len == -1) {
1634                                /* Error is severe, reopen socket */
1635                                bb_error_msg("read error: "STRERROR_FMT", reopening socket" STRERROR_ERRNO);
1636                                sleep(discover_timeout); /* 3 seconds by default */
1637                                change_listen_mode(client_data.listen_mode); /* just close and reopen */
1638                        }
1639                        /* If this packet will turn out to be unrelated/bogus,
1640                         * we will go back and wait for next one.
1641                         * Be sure timeout is properly decreased. */
1642                        already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
1643                        if (len < 0)
1644                                continue;
1645                }
1646
1647                if (packet.xid != xid) {
1648                        log1("xid %x (our is %x), ignoring packet",
1649                                (unsigned)packet.xid, (unsigned)xid);
1650                        continue;
1651                }
1652
1653                /* Ignore packets that aren't for us */
1654                if (packet.hlen != 6
1655                 || memcmp(packet.chaddr, client_data.client_mac, 6) != 0
1656                ) {
1657//FIXME: need to also check that last 10 bytes are zero
1658                        log1("chaddr does not match, ignoring packet"); // log2?
1659                        continue;
1660                }
1661
1662                message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
1663                if (message == NULL) {
1664                        bb_info_msg("no message type option, ignoring packet");
1665                        continue;
1666                }
1667
1668                switch (client_data.state) {
1669                case INIT_SELECTING:
1670                        /* Must be a DHCPOFFER */
1671                        if (*message == DHCPOFFER) {
1672                                uint8_t *temp;
1673
1674/* What exactly is server's IP? There are several values.
1675 * Example DHCP offer captured with tchdump:
1676 *
1677 * 10.34.25.254:67 > 10.34.25.202:68 // IP header's src
1678 * BOOTP fields:
1679 * Your-IP 10.34.25.202
1680 * Server-IP 10.34.32.125   // "next server" IP
1681 * Gateway-IP 10.34.25.254  // relay's address (if DHCP relays are in use)
1682 * DHCP options:
1683 * DHCP-Message Option 53, length 1: Offer
1684 * Server-ID Option 54, length 4: 10.34.255.7       // "server ID"
1685 * Default-Gateway Option 3, length 4: 10.34.25.254 // router
1686 *
1687 * We think that real server IP (one to use in renew/release)
1688 * is one in Server-ID option. But I am not 100% sure.
1689 * IP header's src and Gateway-IP (same in this example)
1690 * might work too.
1691 * "Next server" and router are definitely wrong ones to use, though...
1692 */
1693/* We used to ignore packets without DHCP_SERVER_ID.
1694 * I've got user reports from people who run "address-less" servers.
1695 * They either supply DHCP_SERVER_ID of 0.0.0.0 or don't supply it at all.
1696 * They say ISC DHCP client supports this case.
1697 */
1698                                server_addr = 0;
1699                                temp = udhcp_get_option32(&packet, DHCP_SERVER_ID);
1700                                if (!temp) {
1701                                        bb_info_msg("no server ID, using 0.0.0.0");
1702                                } else {
1703                                        /* it IS unaligned sometimes, don't "optimize" */
1704                                        move_from_unaligned32(server_addr, temp);
1705                                }
1706                                /*xid = packet.xid; - already is */
1707                                requested_ip = packet.yiaddr;
1708
1709                                /* enter requesting state */
1710                                client_data.state = REQUESTING;
1711                                timeout = 0;
1712                                packet_num = 0;
1713                                already_waited_sec = 0;
1714                        }
1715                        continue;
1716                case REQUESTING:
1717                case RENEWING:
1718                case RENEW_REQUESTED:
1719                case REBINDING:
1720                        if (*message == DHCPACK) {
1721                                unsigned start;
1722                                uint32_t lease_seconds;
1723                                struct in_addr temp_addr;
1724                                uint8_t *temp;
1725
1726                                temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME);
1727                                if (!temp) {
1728                                        bb_info_msg("no lease time with ACK, using 1 hour lease");
1729                                        lease_seconds = 60 * 60;
1730                                } else {
1731                                        /* it IS unaligned sometimes, don't "optimize" */
1732                                        move_from_unaligned32(lease_seconds, temp);
1733                                        lease_seconds = ntohl(lease_seconds);
1734                                        /* paranoia: must not be too small and not prone to overflows */
1735                                        /* timeout > 60 - ensures at least one unicast renew attempt */
1736                                        if (lease_seconds < 2 * 61)
1737                                                lease_seconds = 2 * 61;
1738                                        //if (lease_seconds > 0x7fffffff)
1739                                        //      lease_seconds = 0x7fffffff;
1740                                        //^^^not necessary since "timeout = lease_seconds / 2"
1741                                        //does not overflow even for 0xffffffff.
1742                                }
1743#if ENABLE_FEATURE_UDHCPC_ARPING
1744                                if (opt & OPT_a) {
1745/* RFC 2131 3.1 paragraph 5:
1746 * "The client receives the DHCPACK message with configuration
1747 * parameters. The client SHOULD perform a final check on the
1748 * parameters (e.g., ARP for allocated network address), and notes
1749 * the duration of the lease specified in the DHCPACK message. At this
1750 * point, the client is configured. If the client detects that the
1751 * address is already in use (e.g., through the use of ARP),
1752 * the client MUST send a DHCPDECLINE message to the server and restarts
1753 * the configuration process..." */
1754                                        if (!arpping(packet.yiaddr,
1755                                                        NULL,
1756                                                        (uint32_t) 0,
1757                                                        client_data.client_mac,
1758                                                        client_data.interface,
1759                                                        arpping_ms)
1760                                        ) {
1761                                                bb_info_msg("offered address is in use "
1762                                                        "(got ARP reply), declining");
1763                                                send_decline(/*xid,*/ server_addr, packet.yiaddr);
1764
1765                                                if (client_data.state != REQUESTING)
1766                                                        udhcp_run_script(NULL, "deconfig");
1767                                                change_listen_mode(LISTEN_RAW);
1768                                                client_data.state = INIT_SELECTING;
1769                                                client_data.first_secs = 0; /* make secs field count from 0 */
1770                                                requested_ip = 0;
1771                                                timeout = tryagain_timeout;
1772                                                packet_num = 0;
1773                                                already_waited_sec = 0;
1774                                                continue; /* back to main loop */
1775                                        }
1776                                }
1777#endif
1778                                /* enter bound state */
1779                                temp_addr.s_addr = packet.yiaddr;
1780                                bb_info_msg("lease of %s obtained, lease time %u",
1781                                        inet_ntoa(temp_addr), (unsigned)lease_seconds);
1782                                requested_ip = packet.yiaddr;
1783
1784                                start = monotonic_sec();
1785                                udhcp_run_script(&packet, client_data.state == REQUESTING ? "bound" : "renew");
1786                                already_waited_sec = (unsigned)monotonic_sec() - start;
1787                                timeout = lease_seconds / 2;
1788                                if ((unsigned)timeout < already_waited_sec) {
1789                                        /* Something went wrong. Back to discover state */
1790                                        timeout = already_waited_sec = 0;
1791                                }
1792
1793                                client_data.state = BOUND;
1794                                change_listen_mode(LISTEN_NONE);
1795                                if (opt & OPT_q) { /* quit after lease */
1796                                        goto ret0;
1797                                }
1798                                /* future renew failures should not exit (JM) */
1799                                opt &= ~OPT_n;
1800#if BB_MMU /* NOMMU case backgrounded earlier */
1801                                if (!(opt & OPT_f)) {
1802                                        client_background();
1803                                        /* do not background again! */
1804                                        opt = ((opt & ~OPT_b) | OPT_f);
1805                                }
1806#endif
1807                                /* make future renew packets use different xid */
1808                                /* xid = random_xid(); ...but why bother? */
1809
1810                                continue; /* back to main loop */
1811                        }
1812                        if (*message == DHCPNAK) {
1813                                /* If network has more than one DHCP server,
1814                                 * "wrong" server can reply first, with a NAK.
1815                                 * Do not interpret it as a NAK from "our" server.
1816                                 */
1817                                if (server_addr != 0) {
1818                                        uint32_t svid;
1819                                        uint8_t *temp;
1820
1821                                        temp = udhcp_get_option32(&packet, DHCP_SERVER_ID);
1822                                        if (!temp) {
1823 non_matching_svid:
1824                                                log1("received DHCP NAK with wrong"
1825                                                        " server ID, ignoring packet");
1826                                                continue;
1827                                        }
1828                                        move_from_unaligned32(svid, temp);
1829                                        if (svid != server_addr)
1830                                                goto non_matching_svid;
1831                                }
1832                                /* return to init state */
1833                                bb_info_msg("received %s", "DHCP NAK");
1834                                udhcp_run_script(&packet, "nak");
1835                                if (client_data.state != REQUESTING)
1836                                        udhcp_run_script(NULL, "deconfig");
1837                                change_listen_mode(LISTEN_RAW);
1838                                sleep(3); /* avoid excessive network traffic */
1839                                client_data.state = INIT_SELECTING;
1840                                client_data.first_secs = 0; /* make secs field count from 0 */
1841                                requested_ip = 0;
1842                                timeout = 0;
1843                                packet_num = 0;
1844                                already_waited_sec = 0;
1845                        }
1846                        continue;
1847                /* case BOUND: - ignore all packets */
1848                /* case RELEASED: - ignore all packets */
1849                }
1850                /* back to main loop */
1851        } /* for (;;) - main loop ends */
1852
1853 ret0:
1854        if (opt & OPT_R) /* release on quit */
1855                perform_release(server_addr, requested_ip);
1856        retval = 0;
1857 ret:
1858        /*if (client_data.pidfile) - remove_pidfile has its own check */
1859                remove_pidfile(client_data.pidfile);
1860        return retval;
1861}
1862