Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (17 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

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

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/* dhcpc.c
    23 *
     
    89 */
    910
    10 #include <sys/file.h>
    11 #include <unistd.h>
    1211#include <getopt.h>
    13 #include <stdlib.h>
    14 #include <sys/socket.h>
    15 #include <netinet/in.h>
    16 #include <arpa/inet.h>
    17 #include <signal.h>
    18 #include <time.h>
    19 #include <string.h>
    20 #include <sys/ioctl.h>
    21 #include <net/if.h>
    22 #include <errno.h>
    23 
     12#include <syslog.h>
     13
     14/* Override ENABLE_FEATURE_PIDFILE - ifupdown needs our pidfile to always exist */
     15#define WANT_PIDFILE 1
    2416#include "common.h"
    2517#include "dhcpd.h"
    2618#include "dhcpc.h"
    2719#include "options.h"
    28 #include "clientpacket.h"
    29 #include "clientsocket.h"
    30 #include "socket.h"
    31 #include "signalpipe.h"
    32 
    33 static int state;
    34 static unsigned long requested_ip; /* = 0 */
    35 static unsigned long server_addr;
    36 static unsigned long timeout;
     20
     21
     22/* Something is definitely wrong here. IPv4 addresses
     23 * in variables of type long?? BTW, we use inet_ntoa()
     24 * in the code. Manpage says that struct in_addr has a member of type long (!)
     25 * which holds IPv4 address, and the struct is passed by value (!!)
     26 */
     27static unsigned timeout;
     28static uint32_t requested_ip; /* = 0 */
     29static uint32_t server_addr;
    3730static int packet_num; /* = 0 */
    38 static int fd = -1;
     31static int sockfd = -1;
    3932
    4033#define LISTEN_NONE 0
    4134#define LISTEN_KERNEL 1
    4235#define LISTEN_RAW 2
    43 static int listen_mode;
    44 
    45 struct client_config_t client_config = {
    46     /* Default options. */
    47     .abort_if_no_lease = 0,
    48     .foreground = 0,
    49     .quit_after_lease = 0,
    50     .background_if_no_lease = 0,
    51     .interface = "eth0",
    52     .pidfile = NULL,
    53     .script = DEFAULT_SCRIPT,
    54     .clientid = NULL,
    55     .vendorclass = NULL,
    56     .hostname = NULL,
    57     .fqdn = NULL,
    58     .ifindex = 0,
    59     .retries = 3,
    60     .timeout = 3,
    61     .arp = "\0\0\0\0\0\0",      /* appease gcc-3.0 */
    62 };
     36static smallint listen_mode;
     37
     38static smallint state;
     39
     40struct client_config_t client_config;
     41
    6342
    6443/* just a little helper */
    6544static void change_mode(int new_mode)
    6645{
    67     DEBUG(LOG_INFO, "entering %s listen mode",
     46    DEBUG("entering %s listen mode",
    6847        new_mode ? (new_mode == 1 ? "kernel" : "raw") : "none");
    69     if (fd >= 0) close(fd);
    70     fd = -1;
     48    if (sockfd >= 0) {
     49        close(sockfd);
     50        sockfd = -1;
     51    }
    7152    listen_mode = new_mode;
    7253}
     
    7657static void perform_renew(void)
    7758{
    78     LOG(LOG_INFO, "Performing a DHCP renew");
     59    bb_info_msg("Performing a DHCP renew");
    7960    switch (state) {
    8061    case BOUND:
     
    10687static void perform_release(void)
    10788{
    108     char buffer[16];
     89    char buffer[sizeof("255.255.255.255")];
    10990    struct in_addr temp_addr;
    11091
     
    11293    if (state == BOUND || state == RENEWING || state == REBINDING) {
    11394        temp_addr.s_addr = server_addr;
    114         sprintf(buffer, "%s", inet_ntoa(temp_addr));
     95        strcpy(buffer, inet_ntoa(temp_addr));
    11596        temp_addr.s_addr = requested_ip;
    116         LOG(LOG_INFO, "Unicasting a release of %s to %s",
     97        bb_info_msg("Unicasting a release of %s to %s",
    11798                inet_ntoa(temp_addr), buffer);
    11899        send_release(server_addr, requested_ip); /* unicast */
    119100        udhcp_run_script(NULL, "deconfig");
    120101    }
    121     LOG(LOG_INFO, "Entering released state");
     102    bb_info_msg("Entering released state");
    122103
    123104    change_mode(LISTEN_NONE);
    124105    state = RELEASED;
    125     timeout = 0x7fffffff;
     106    timeout = INT_MAX;
    126107}
    127108
     
    129110static void client_background(void)
    130111{
    131     udhcp_background(client_config.pidfile);
    132     client_config.foreground = 1; /* Do not fork again. */
     112#if !BB_MMU
     113    bb_error_msg("cannot background in uclinux (yet)");
     114/* ... mainly because udhcpc calls client_background()
     115 * in _the _middle _of _udhcpc _run_, not at the start!
     116 * If that will be properly disabled for NOMMU, client_background()
     117 * will work on NOMMU too */
     118#else
     119    bb_daemonize(0);
     120    logmode &= ~LOGMODE_STDIO;
     121    /* rewrite pidfile, as our pid is different now */
     122    write_pidfile(client_config.pidfile);
     123#endif
     124    /* Do not fork again. */
     125    client_config.foreground = 1;
    133126    client_config.background_if_no_lease = 0;
    134127}
    135128
    136129
    137 int udhcpc_main(int argc, char *argv[])
     130static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
     131{
     132    uint8_t *storage;
     133    int len = strlen(str);
     134    if (len > 255) len = 255;
     135    storage = xzalloc(len + extra + OPT_DATA);
     136    storage[OPT_CODE] = code;
     137    storage[OPT_LEN] = len + extra;
     138    memcpy(storage + extra + OPT_DATA, str, len);
     139    return storage;
     140}
     141
     142
     143int udhcpc_main(int argc, char **argv);
     144int udhcpc_main(int argc, char **argv)
    138145{
    139146    uint8_t *temp, *message;
    140     unsigned long t1 = 0, t2 = 0, xid = 0;
    141     unsigned long start = 0, lease;
     147    char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_t;
     148    uint32_t xid = 0;
     149    uint32_t lease = 0; /* can be given as 32-bit quantity */
     150    unsigned t1 = 0, t2 = 0; /* what a wonderful names */
     151    unsigned start = 0;
     152    unsigned now;
     153    unsigned opt;
     154    int max_fd;
     155    int retval;
     156    int len;
     157    struct timeval tv;
     158    struct in_addr temp_addr;
     159    struct dhcpMessage packet;
    142160    fd_set rfds;
    143     int retval;
    144     struct timeval tv;
    145     int c, len;
    146     struct dhcpMessage packet;
    147     struct in_addr temp_addr;
    148     long now;
    149     int max_fd;
    150     int sig;
    151     int no_clientid = 0;
    152 
    153     static const struct option arg_options[] = {
    154         {"clientid",    required_argument,  0, 'c'},
    155         {"clientid-none", no_argument,      0, 'C'},
    156         {"vendorclass", required_argument,  0, 'V'},
    157         {"foreground",  no_argument,        0, 'f'},
    158         {"background",  no_argument,        0, 'b'},
    159         {"hostname",    required_argument,  0, 'H'},
    160         {"hostname",    required_argument,  0, 'h'},
    161         {"fqdn",    required_argument,  0, 'F'},
    162         {"interface",   required_argument,  0, 'i'},
    163         {"now",     no_argument,        0, 'n'},
    164         {"pidfile", required_argument,  0, 'p'},
    165         {"quit",    no_argument,        0, 'q'},
    166         {"request", required_argument,  0, 'r'},
    167         {"script",  required_argument,  0, 's'},
    168         {"timeout", required_argument,  0, 'T'},
    169         {"version", no_argument,        0, 'v'},
    170         {"retries", required_argument,  0, 't'},
    171         {0, 0, 0, 0}
     161
     162    enum {
     163        OPT_c = 1 << 0,
     164        OPT_C = 1 << 1,
     165        OPT_V = 1 << 2,
     166        OPT_f = 1 << 3,
     167        OPT_b = 1 << 4,
     168        OPT_H = 1 << 5,
     169        OPT_h = 1 << 6,
     170        OPT_F = 1 << 7,
     171        OPT_i = 1 << 8,
     172        OPT_n = 1 << 9,
     173        OPT_p = 1 << 10,
     174        OPT_q = 1 << 11,
     175        OPT_R = 1 << 12,
     176        OPT_r = 1 << 13,
     177        OPT_s = 1 << 14,
     178        OPT_T = 1 << 15,
     179        OPT_t = 1 << 16,
     180        OPT_v = 1 << 17,
     181        OPT_S = 1 << 18,
    172182    };
    173 
    174     /* get options */
    175     while (1) {
    176         int option_index = 0;
    177         c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:T:t:v", arg_options, &option_index);
    178         if (c == -1) break;
    179 
    180         switch (c) {
    181         case 'c':
    182             if (no_clientid) bb_show_usage();
    183             len = strlen(optarg) > 255 ? 255 : strlen(optarg);
    184             free(client_config.clientid);
    185             client_config.clientid = xmalloc(len + 2);
    186             client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
    187             client_config.clientid[OPT_LEN] = len;
    188             client_config.clientid[OPT_DATA] = '\0';
    189             strncpy((char*)client_config.clientid + OPT_DATA, optarg, len);
    190             break;
    191         case 'C':
    192             if (client_config.clientid) bb_show_usage();
    193             no_clientid = 1;
    194             break;
    195         case 'V':
    196             len = strlen(optarg) > 255 ? 255 : strlen(optarg);
    197             free(client_config.vendorclass);
    198             client_config.vendorclass = xmalloc(len + 2);
    199             client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
    200             client_config.vendorclass[OPT_LEN] = len;
    201             strncpy((char*)client_config.vendorclass + OPT_DATA, optarg, len);
    202             break;
    203         case 'f':
    204             client_config.foreground = 1;
    205             break;
    206         case 'b':
    207             client_config.background_if_no_lease = 1;
    208             break;
    209         case 'h':
    210         case 'H':
    211             len = strlen(optarg) > 255 ? 255 : strlen(optarg);
    212             free(client_config.hostname);
    213             client_config.hostname = xmalloc(len + 2);
    214             client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
    215             client_config.hostname[OPT_LEN] = len;
    216             strncpy((char*)client_config.hostname + 2, optarg, len);
    217             break;
    218         case 'F':
    219             len = strlen(optarg) > 255 ? 255 : strlen(optarg);
    220             free(client_config.fqdn);
    221             client_config.fqdn = xmalloc(len + 5);
    222             client_config.fqdn[OPT_CODE] = DHCP_FQDN;
    223             client_config.fqdn[OPT_LEN] = len + 3;
    224             /* Flags: 0000NEOS
    225             S: 1 => Client requests Server to update A RR in DNS as well as PTR
    226             O: 1 => Server indicates to client that DNS has been updated regardless
    227             E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com"
    228             N: 1 => Client requests Server to not update DNS
    229             */
    230             client_config.fqdn[OPT_LEN + 1] = 0x1;
    231             client_config.fqdn[OPT_LEN + 2] = 0;
    232             client_config.fqdn[OPT_LEN + 3] = 0;
    233             strncpy((char*)client_config.fqdn + 5, optarg, len);
    234             break;
    235         case 'i':
    236             client_config.interface =  optarg;
    237             break;
    238         case 'n':
    239             client_config.abort_if_no_lease = 1;
    240             break;
    241         case 'p':
    242             client_config.pidfile = optarg;
    243             break;
    244         case 'q':
    245             client_config.quit_after_lease = 1;
    246             break;
    247         case 'r':
    248             requested_ip = inet_addr(optarg);
    249             break;
    250         case 's':
    251             client_config.script = optarg;
    252             break;
    253         case 'T':
    254             client_config.timeout = atoi(optarg);
    255             break;
    256         case 't':
    257             client_config.retries = atoi(optarg);
    258             break;
    259         case 'v':
    260             printf("version %s\n\n", BB_VER);
    261             return 0;
    262             break;
    263         default:
    264             bb_show_usage();
    265         }
    266     }
    267 
    268     /* Start the log, sanitize fd's, and write a pid file */
    269     udhcp_start_log_and_pid("udhcpc", client_config.pidfile);
     183#if ENABLE_GETOPT_LONG
     184    static const char udhcpc_longopts[] ALIGN1 =
     185        "clientid\0"      Required_argument "c"
     186        "clientid-none\0" No_argument       "C"
     187        "vendorclass\0"   Required_argument "V"
     188        "foreground\0"    No_argument       "f"
     189        "background\0"    No_argument       "b"
     190        "hostname\0"      Required_argument "H"
     191        "hostname\0"      Required_argument "h"
     192        "fqdn\0"          Required_argument "F"
     193        "interface\0"     Required_argument "i"
     194        "now\0"           No_argument       "n"
     195        "pidfile\0"       Required_argument "p"
     196        "quit\0"          No_argument       "q"
     197        "release\0"       No_argument       "R"
     198        "request\0"       Required_argument "r"
     199        "script\0"        Required_argument "s"
     200        "timeout\0"       Required_argument "T"
     201        "version\0"       No_argument       "v"
     202        "retries\0"       Required_argument "t"
     203        "syslog\0"        No_argument       "S"
     204        ;
     205#endif
     206    /* Default options. */
     207    client_config.interface = "eth0";
     208    client_config.script = DEFAULT_SCRIPT;
     209    client_config.retries = 3;
     210    client_config.timeout = 3;
     211
     212    /* Parse command line */
     213    opt_complementary = "c--C:C--c" // mutually exclusive
     214                        ":hH:Hh"; // -h and -H are the same
     215#if ENABLE_GETOPT_LONG
     216    applet_long_options = udhcpc_longopts;
     217#endif
     218    opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vS",
     219        &str_c, &str_V, &str_h, &str_h, &str_F,
     220        &client_config.interface, &client_config.pidfile, &str_r,
     221        &client_config.script, &str_T, &str_t
     222        );
     223
     224    if (opt & OPT_c)
     225        client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0);
     226    //if (opt & OPT_C)
     227    if (opt & OPT_V)
     228        client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
     229    if (opt & OPT_f)
     230        client_config.foreground = 1;
     231    if (opt & OPT_b)
     232        client_config.background_if_no_lease = 1;
     233    if (opt & OPT_h)
     234        client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
     235    if (opt & OPT_F) {
     236        client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
     237        /* Flags: 0000NEOS
     238        S: 1 => Client requests Server to update A RR in DNS as well as PTR
     239        O: 1 => Server indicates to client that DNS has been updated regardless
     240        E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com"
     241        N: 1 => Client requests Server to not update DNS
     242        */
     243        client_config.fqdn[OPT_DATA + 0] = 0x1;
     244        /* client_config.fqdn[OPT_DATA + 1] = 0; - redundant */
     245        /* client_config.fqdn[OPT_DATA + 2] = 0; - redundant */
     246    }
     247    // if (opt & OPT_i) client_config.interface = ...
     248    if (opt & OPT_n)
     249        client_config.abort_if_no_lease = 1;
     250    // if (opt & OPT_p) client_config.pidfile = ...
     251    if (opt & OPT_q)
     252        client_config.quit_after_lease = 1;
     253    if (opt & OPT_R)
     254        client_config.release_on_quit = 1;
     255    if (opt & OPT_r)
     256        requested_ip = inet_addr(str_r);
     257    // if (opt & OPT_s) client_config.script = ...
     258    if (opt & OPT_T)
     259        client_config.timeout = xatoi_u(str_T);
     260    if (opt & OPT_t)
     261        client_config.retries = xatoi_u(str_t);
     262    if (opt & OPT_v) {
     263        printf("version %s\n", BB_VER);
     264        return 0;
     265    }
     266
     267    if (opt & OPT_S) {
     268        openlog(applet_name, LOG_PID, LOG_LOCAL0);
     269        logmode |= LOGMODE_SYSLOG;
     270    }
    270271
    271272    if (read_interface(client_config.interface, &client_config.ifindex,
    272                NULL, client_config.arp) < 0)
     273               NULL, client_config.arp))
    273274        return 1;
    274275
     276    /* Make sure fd 0,1,2 are open */
     277    bb_sanitize_stdio();
     278    /* Equivalent of doing a fflush after every \n */
     279    setlinebuf(stdout);
     280
     281    /* Create pidfile */
     282    write_pidfile(client_config.pidfile);
     283    /* if (!..) bb_perror_msg("cannot create pidfile %s", pidfile); */
     284
     285    /* Goes to stdout and possibly syslog */
     286    bb_info_msg("%s (v%s) started", applet_name, BB_VER);
     287
    275288    /* if not set, and not suppressed, setup the default client ID */
    276     if (!client_config.clientid && !no_clientid) {
    277         client_config.clientid = xmalloc(6 + 3);
    278         client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
    279         client_config.clientid[OPT_LEN] = 7;
     289    if (!client_config.clientid && !(opt & OPT_C)) {
     290        client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
    280291        client_config.clientid[OPT_DATA] = 1;
    281         memcpy(client_config.clientid + 3, client_config.arp, 6);
    282     }
    283 
    284     if (!client_config.vendorclass) {
    285         client_config.vendorclass = xmalloc(sizeof("udhcp "BB_VER) + 2);
    286         client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
    287         client_config.vendorclass[OPT_LEN] = sizeof("udhcp "BB_VER) - 1;
    288         client_config.vendorclass[OPT_DATA] = 1;
    289         memcpy(&client_config.vendorclass[OPT_DATA],
    290             "udhcp "BB_VER, sizeof("udhcp "BB_VER) - 1);
    291     }
    292 
     292        memcpy(client_config.clientid + OPT_DATA+1, client_config.arp, 6);
     293    }
     294
     295    if (!client_config.vendorclass)
     296        client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, "udhcp "BB_VER, 0);
    293297
    294298    /* setup the signal pipe */
     
    298302    udhcp_run_script(NULL, "deconfig");
    299303    change_mode(LISTEN_RAW);
     304    tv.tv_sec = 0;
     305    goto jump_in;
    300306
    301307    for (;;) {
    302 
    303         tv.tv_sec = timeout - uptime();
     308        tv.tv_sec = timeout - monotonic_sec();
     309 jump_in:
    304310        tv.tv_usec = 0;
    305311
    306         if (listen_mode != LISTEN_NONE && fd < 0) {
     312        if (listen_mode != LISTEN_NONE && sockfd < 0) {
    307313            if (listen_mode == LISTEN_KERNEL)
    308                 fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface);
     314                sockfd = listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface);
    309315            else
    310                 fd = raw_socket(client_config.ifindex);
    311             if (fd < 0) {
    312                 LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m");
    313                 return 0;
    314             }
     316                sockfd = raw_socket(client_config.ifindex);
    315317        }
    316         max_fd = udhcp_sp_fd_set(&rfds, fd);
    317 
     318        max_fd = udhcp_sp_fd_set(&rfds, sockfd);
     319
     320        retval = 0; /* If we already timed out, fall through, else... */
    318321        if (tv.tv_sec > 0) {
    319             DEBUG(LOG_INFO, "Waiting on select...");
     322            DEBUG("Waiting on select...");
    320323            retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
    321         } else retval = 0; /* If we already timed out, fall through */
    322 
    323         now = uptime();
    324         if (retval == 0) {
     324        }
     325
     326        now = monotonic_sec();
     327        if (retval < 0) {
     328            /* EINTR? signal was caught, don't panic */
     329            if (errno != EINTR) {
     330                /* Else: an error occured, panic! */
     331                bb_perror_msg_and_die("select");
     332            }
     333        } else if (retval == 0) {
    325334            /* timeout dropped to zero */
    326335            switch (state) {
     
    338347                    udhcp_run_script(NULL, "leasefail");
    339348                    if (client_config.background_if_no_lease) {
    340                         LOG(LOG_INFO, "No lease, forking to background.");
     349                        bb_info_msg("No lease, forking to background");
    341350                        client_background();
    342351                    } else if (client_config.abort_if_no_lease) {
    343                         LOG(LOG_INFO, "No lease, failing.");
    344                         return 1;
     352                        bb_info_msg("No lease, failing");
     353                        retval = 1;
     354                        goto ret;
    345355                    }
    346356                    /* wait to try again */
     
    361371                } else {
    362372                    /* timed out, go back to init state */
    363                     if (state == RENEW_REQUESTED) udhcp_run_script(NULL, "deconfig");
     373                    if (state == RENEW_REQUESTED)
     374                        udhcp_run_script(NULL, "deconfig");
    364375                    state = INIT_SELECTING;
    365376                    timeout = now;
     
    372383                state = RENEWING;
    373384                change_mode(LISTEN_KERNEL);
    374                 DEBUG(LOG_INFO, "Entering renew state");
     385                DEBUG("Entering renew state");
    375386                /* fall right through */
    376387            case RENEWING:
     
    380391                    state = REBINDING;
    381392                    timeout = now + (t2 - t1);
    382                     DEBUG(LOG_INFO, "Entering rebinding state");
     393                    DEBUG("Entering rebinding state");
    383394                } else {
    384395                    /* send a request packet */
    385396                    send_renew(xid, server_addr, requested_ip); /* unicast */
    386 
    387397                    t1 = (t2 - t1) / 2 + t1;
    388                     timeout = t1 + start;
     398                    timeout = start + t1;
    389399                }
    390400                break;
     
    394404                    /* timed out, enter init state */
    395405                    state = INIT_SELECTING;
    396                     LOG(LOG_INFO, "Lease lost, entering init state");
     406                    bb_info_msg("Lease lost, entering init state");
    397407                    udhcp_run_script(NULL, "deconfig");
    398408                    timeout = now;
     
    402412                    /* send a request packet */
    403413                    send_renew(xid, 0, requested_ip); /* broadcast */
    404 
    405414                    t2 = (lease - t2) / 2 + t2;
    406                     timeout = t2 + start;
     415                    timeout = start + t2;
    407416                }
    408417                break;
    409418            case RELEASED:
    410419                /* yah, I know, *you* say it would never happen */
    411                 timeout = 0x7fffffff;
    412                 break;
    413             }
    414         } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) {
     420                timeout = INT_MAX;
     421                break;
     422            }
     423        } else if (listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
    415424            /* a packet is ready, read it */
    416425
    417426            if (listen_mode == LISTEN_KERNEL)
    418                 len = udhcp_get_packet(&packet, fd);
    419             else len = get_raw_packet(&packet, fd);
     427                len = udhcp_get_packet(&packet, sockfd);
     428            else len = get_raw_packet(&packet, sockfd);
    420429
    421430            if (len == -1 && errno != EINTR) {
    422                 DEBUG(LOG_INFO, "error on read, %m, reopening socket");
     431                DEBUG("error on read, %s, reopening socket", strerror(errno));
    423432                change_mode(listen_mode); /* just close and reopen */
    424433            }
     
    426435
    427436            if (packet.xid != xid) {
    428                 DEBUG(LOG_INFO, "Ignoring XID %lx (our xid is %lx)",
    429                     (unsigned long) packet.xid, xid);
     437                DEBUG("Ignoring XID %x (our xid is %x)",
     438                    (unsigned)packet.xid, (unsigned)xid);
    430439                continue;
    431440            }
     
    433442            /* Ignore packets that aren't for us */
    434443            if (memcmp(packet.chaddr, client_config.arp, 6)) {
    435                 DEBUG(LOG_INFO, "packet does not have our chaddr -- ignoring");
     444                DEBUG("Packet does not have our chaddr - ignoring");
    436445                continue;
    437446            }
    438447
    439             if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
    440                 DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
     448            message = get_option(&packet, DHCP_MESSAGE_TYPE);
     449            if (message == NULL) {
     450                bb_error_msg("cannot get option from packet - ignoring");
    441451                continue;
    442452            }
     
    446456                /* Must be a DHCPOFFER to one of our xid's */
    447457                if (*message == DHCPOFFER) {
    448                     if ((temp = get_option(&packet, DHCP_SERVER_ID))) {
     458                    temp = get_option(&packet, DHCP_SERVER_ID);
     459                    if (temp) {
     460                        /* can be misaligned, thus memcpy */
    449461                        memcpy(&server_addr, temp, 4);
    450462                        xid = packet.xid;
     
    456468                        packet_num = 0;
    457469                    } else {
    458                         DEBUG(LOG_ERR, "No server ID in message");
     470                        bb_error_msg("no server ID in message");
    459471                    }
    460472                }
     
    465477            case REBINDING:
    466478                if (*message == DHCPACK) {
    467                     if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) {
    468                         LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease");
     479                    temp = get_option(&packet, DHCP_LEASE_TIME);
     480                    if (!temp) {
     481                        bb_error_msg("no lease time with ACK, using 1 hour lease");
    469482                        lease = 60 * 60;
    470483                    } else {
     484                        /* can be misaligned, thus memcpy */
    471485                        memcpy(&lease, temp, 4);
    472486                        lease = ntohl(lease);
     
    477491
    478492                    /* little fixed point for n * .875 */
    479                     t2 = (lease * 0x7) >> 3;
     493                    t2 = (lease * 7) >> 3;
    480494                    temp_addr.s_addr = packet.yiaddr;
    481                     LOG(LOG_INFO, "Lease of %s obtained, lease time %ld",
    482                         inet_ntoa(temp_addr), lease);
     495                    bb_info_msg("Lease of %s obtained, lease time %u",
     496                        inet_ntoa(temp_addr), (unsigned)lease);
    483497                    start = now;
    484                     timeout = t1 + start;
     498                    timeout = start + t1;
    485499                    requested_ip = packet.yiaddr;
    486500                    udhcp_run_script(&packet,
     
    489503                    state = BOUND;
    490504                    change_mode(LISTEN_NONE);
    491                     if (client_config.quit_after_lease)
    492                         return 0;
     505                    if (client_config.quit_after_lease) {
     506                        if (client_config.release_on_quit)
     507                            perform_release();
     508                        goto ret0;
     509                    }
    493510                    if (!client_config.foreground)
    494511                        client_background();
     
    496513                } else if (*message == DHCPNAK) {
    497514                    /* return to init state */
    498                     LOG(LOG_INFO, "Received DHCP NAK");
     515                    bb_info_msg("Received DHCP NAK");
    499516                    udhcp_run_script(&packet, "nak");
    500517                    if (state != REQUESTING)
     
    510527            /* case BOUND, RELEASED: - ignore all packets */
    511528            }
    512         } else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) {
    513             switch (sig) {
     529        } else {
     530            int signo = udhcp_sp_read(&rfds);
     531            switch (signo) {
    514532            case SIGUSR1:
    515533                perform_renew();
     
    519537                break;
    520538            case SIGTERM:
    521                 LOG(LOG_INFO, "Received SIGTERM");
    522                 return 0;
    523             }
    524         } else if (retval == -1 && errno == EINTR) {
    525             /* a signal was caught */
    526         } else {
    527             /* An error occured */
    528             DEBUG(LOG_ERR, "Error on select");
     539                bb_info_msg("Received SIGTERM");
     540                if (client_config.release_on_quit)
     541                    perform_release();
     542                goto ret0;
     543            }
    529544        }
    530 
    531     }
    532     return 0;
     545    } /* for (;;) */
     546 ret0:
     547    retval = 0;
     548 ret:
     549    /*if (client_config.pidfile) - remove_pidfile has it's own check */
     550        remove_pidfile(client_config.pidfile);
     551    return retval;
    533552}
Note: See TracChangeset for help on using the changeset viewer.