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/zcip.c

    r902 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * RFC3927 ZeroConf IPv4 Link-Local addressing
     
    2324// - link status monitoring (restart on link-up; stop on link-down)
    2425
    25 #include "busybox.h"
    26 #include <errno.h>
    27 #include <string.h>
    2826#include <syslog.h>
    2927#include <poll.h>
    30 #include <time.h>
    31 
    3228#include <sys/wait.h>
    33 
    3429#include <netinet/ether.h>
    3530#include <net/ethernet.h>
    3631#include <net/if.h>
    3732#include <net/if_arp.h>
    38 
    3933#include <linux/if_packet.h>
    4034#include <linux/sockios.h>
    4135
     36#include "libbb.h"
     37
     38/* We don't need more than 32 bits of the counter */
     39#define MONOTONIC_US() ((unsigned)monotonic_us())
    4240
    4341struct arp_packet {
     
    7270};
    7371
    74 /* Implicitly zero-initialized */
    75 static const struct in_addr null_ip;
    76 static const struct ether_addr null_addr;
    77 static int verbose;
    78 
    79 #define DBG(fmt,args...) \
     72#define VDBG(fmt,args...) \
    8073    do { } while (0)
    81 #define VDBG    DBG
    8274
    8375/**
     
    8779static void pick(struct in_addr *ip)
    8880{
    89     unsigned    tmp;
    90 
    91     /* use cheaper math than lrand48() mod N */
     81    unsigned tmp;
     82
    9283    do {
    93         tmp = (lrand48() >> 16) & IN_CLASSB_HOST;
     84        tmp = rand() & IN_CLASSB_HOST;
    9485    } while (tmp > (IN_CLASSB_HOST - 0x0200));
    9586    ip->s_addr = htonl((LINKLOCAL_ADDR + 0x0100) + tmp);
     
    9990 * Broadcast an ARP packet.
    10091 */
    101 static int arp(int fd, struct sockaddr *saddr, int op,
     92static void arp(int fd, struct sockaddr *saddr, int op,
    10293    const struct ether_addr *source_addr, struct in_addr source_ip,
    10394    const struct ether_addr *target_addr, struct in_addr target_ip)
     
    118109    p.arp.arp_op = htons(op);
    119110    memcpy(&p.arp.arp_sha, source_addr, ETH_ALEN);
    120     memcpy(&p.arp.arp_spa, &source_ip, sizeof (p.arp.arp_spa));
     111    memcpy(&p.arp.arp_spa, &source_ip, sizeof(p.arp.arp_spa));
    121112    memcpy(&p.arp.arp_tha, target_addr, ETH_ALEN);
    122     memcpy(&p.arp.arp_tpa, &target_ip, sizeof (p.arp.arp_tpa));
     113    memcpy(&p.arp.arp_tpa, &target_ip, sizeof(p.arp.arp_tpa));
    123114
    124115    // send it
    125     if (sendto(fd, &p, sizeof (p), 0, saddr, sizeof (*saddr)) < 0) {
    126         perror("sendto");
     116    xsendto(fd, &p, sizeof(p), saddr, sizeof(*saddr));
     117
     118    // Currently all callers ignore errors, that's why returns are
     119    // commented out...
     120    //return 0;
     121}
     122
     123/**
     124 * Run a script. argv[2] is already NULL.
     125 */
     126static int run(char *argv[3], const char *intf, struct in_addr *ip)
     127{
     128    int status;
     129
     130    VDBG("%s run %s %s\n", intf, argv[0], argv[1]);
     131
     132    if (ip) {
     133        char *addr = inet_ntoa(*ip);
     134        setenv("ip", addr, 1);
     135        bb_info_msg("%s %s %s", argv[1], intf, addr);
     136    }
     137
     138    status = wait4pid(spawn(argv));
     139    if (status < 0) {
     140        bb_perror_msg("%s %s", argv[1], intf);
    127141        return -errno;
    128142    }
    129     return 0;
     143    if (status != 0)
     144        bb_error_msg("script %s %s failed, exitcode=%d", argv[0], argv[1], status);
     145    return status;
    130146}
    131147
    132148/**
    133  * Run a script.
    134  */
    135 static int run(char *script, char *arg, char *intf, struct in_addr *ip)
     149 * Return milliseconds of random delay, up to "secs" seconds.
     150 */
     151static unsigned ALWAYS_INLINE ms_rdelay(unsigned secs)
    136152{
    137     int pid, status;
    138     char *why;
    139 
    140     if (script != NULL) {
    141         VDBG("%s run %s %s\n", intf, script, arg);
    142         if (ip != NULL) {
    143             char *addr = inet_ntoa(*ip);
    144             setenv("ip", addr, 1);
    145             syslog(LOG_INFO, "%s %s %s", arg, intf, addr);
    146         }
    147 
    148         pid = vfork();
    149         if (pid < 0) {          // error
    150             why = "vfork";
    151             goto bad;
    152         } else if (pid == 0) {      // child
    153             execl(script, script, arg, NULL);
    154             perror("execl");
    155             _exit(EXIT_FAILURE);
    156         }
    157 
    158         if (waitpid(pid, &status, 0) <= 0) {
    159             why = "waitpid";
    160             goto bad;
    161         }
    162         if (WEXITSTATUS(status) != 0) {
    163             bb_error_msg("script %s failed, exit=%d\n",
    164                     script, WEXITSTATUS(status));
    165             return -errno;
     153    return rand() % (secs * 1000);
     154}
     155
     156/**
     157 * main program
     158 */
     159int zcip_main(int argc, char **argv);
     160int zcip_main(int argc, char **argv)
     161{
     162    int state = PROBE;
     163    struct ether_addr eth_addr;
     164    const char *why;
     165    int fd;
     166    char *r_opt;
     167    unsigned opts;
     168
     169    /* Ugly trick, but I want these zeroed in one go */
     170    struct {
     171        const struct in_addr null_ip;
     172        const struct ether_addr null_addr;
     173        struct sockaddr saddr;
     174        struct in_addr ip;
     175        struct ifreq ifr;
     176        char *intf;
     177        char *script_av[3];
     178        int timeout_ms; /* must be signed */
     179        unsigned conflicts;
     180        unsigned nprobes;
     181        unsigned nclaims;
     182        int ready;
     183        int verbose;
     184    } L;
     185#define null_ip    (L.null_ip   )
     186#define null_addr  (L.null_addr )
     187#define saddr      (L.saddr     )
     188#define ip         (L.ip        )
     189#define ifr        (L.ifr       )
     190#define intf       (L.intf      )
     191#define script_av  (L.script_av )
     192#define timeout_ms (L.timeout_ms)
     193#define conflicts  (L.conflicts )
     194#define nprobes    (L.nprobes   )
     195#define nclaims    (L.nclaims   )
     196#define ready      (L.ready     )
     197#define verbose    (L.verbose   )
     198
     199    memset(&L, 0, sizeof(L));
     200
     201#define FOREGROUND (opts & 1)
     202#define QUIT       (opts & 2)
     203    // parse commandline: prog [options] ifname script
     204    // exactly 2 args; -v accumulates and implies -f
     205    opt_complementary = "=2:vv:vf";
     206    opts = getopt32(argv, "fqr:v", &r_opt, &verbose);
     207    if (!FOREGROUND) {
     208        /* Do it early, before all bb_xx_msg calls */
     209        openlog(applet_name, 0, LOG_DAEMON);
     210        logmode |= LOGMODE_SYSLOG;
     211    }
     212    if (opts & 4) { // -r n.n.n.n
     213        if (inet_aton(r_opt, &ip) == 0
     214         || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR
     215        ) {
     216            bb_error_msg_and_die("invalid link address");
    166217        }
    167218    }
    168     return 0;
    169 bad:
    170     status = -errno;
    171     syslog(LOG_ERR, "%s %s, %s error: %s",
    172         arg, intf, why, strerror(errno));
    173     return status;
    174 }
    175 
    176 
    177 /**
    178  * Return milliseconds of random delay, up to "secs" seconds.
    179  */
    180 static inline unsigned ms_rdelay(unsigned secs)
    181 {
    182     return lrand48() % (secs * 1000);
    183 }
    184 
    185 /**
    186  * main program
    187  */
    188 
    189 int zcip_main(int argc, char *argv[])
    190 {
    191     char *intf = NULL;
    192     char *script = NULL;
    193     int quit = 0;
    194     int foreground = 0;
    195 
    196     char *why;
    197     struct sockaddr saddr;
    198     struct ether_addr addr;
    199     struct in_addr ip = { 0 };
    200     int fd;
    201     int ready = 0;
    202     suseconds_t timeout = 0;    // milliseconds
    203     unsigned conflicts = 0;
    204     unsigned nprobes = 0;
    205     unsigned nclaims = 0;
    206     int t;
    207     int state = PROBE;
    208 
    209     // parse commandline: prog [options] ifname script
    210     while ((t = getopt(argc, argv, "fqr:v")) != EOF) {
    211         switch (t) {
    212         case 'f':
    213             foreground = 1;
    214             continue;
    215         case 'q':
    216             quit = 1;
    217             continue;
    218         case 'r':
    219             if (inet_aton(optarg, &ip) == 0
    220                     || (ntohl(ip.s_addr) & IN_CLASSB_NET)
    221                         != LINKLOCAL_ADDR) {
    222                 bb_error_msg_and_die("invalid link address");
    223             }
    224             continue;
    225         case 'v':
    226             verbose++;
    227             foreground = 1;
    228             continue;
    229         default:
    230             bb_error_msg_and_die("bad option");
    231         }
    232     }
    233     if (optind < argc - 1) {
    234         intf = argv[optind++];
    235         setenv("interface", intf, 1);
    236         script = argv[optind++];
    237     }
    238     if (optind != argc || !intf)
    239         bb_show_usage();
    240     openlog(bb_applet_name, 0, LOG_DAEMON);
     219    // On NOMMU reexec early (or else we will rerun things twice)
     220#if !BB_MMU
     221    if (!FOREGROUND)
     222        bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
     223#endif
     224    argc -= optind;
     225    argv += optind;
     226
     227    intf = argv[0];
     228    script_av[0] = argv[1];
     229    setenv("interface", intf, 1);
    241230
    242231    // initialize the interface (modprobe, ifup, etc)
    243     if (run(script, "init", intf, NULL) < 0)
     232    script_av[1] = (char*)"init";
     233    if (run(script_av, intf, NULL))
    244234        return EXIT_FAILURE;
    245235
    246236    // initialize saddr
    247     memset(&saddr, 0, sizeof (saddr));
    248     safe_strncpy(saddr.sa_data, intf, sizeof (saddr.sa_data));
     237    //memset(&saddr, 0, sizeof(saddr));
     238    safe_strncpy(saddr.sa_data, intf, sizeof(saddr.sa_data));
    249239
    250240    // open an ARP socket
    251     if ((fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) < 0) {
    252         why = "open";
    253 fail:
    254         foreground = 1;
    255         goto bad;
    256     }
     241    fd = xsocket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
    257242    // bind to the interface's ARP socket
    258     if (bind(fd, &saddr, sizeof (saddr)) < 0) {
    259         why = "bind";
    260         goto fail;
    261     } else {
    262         struct ifreq ifr;
    263         unsigned short seed[3];
    264 
    265         // get the interface's ethernet address
    266         memset(&ifr, 0, sizeof (ifr));
    267         strncpy(ifr.ifr_name, intf, sizeof (ifr.ifr_name));
    268         if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
    269             why = "get ethernet address";
    270             goto fail;
    271         }
    272         memcpy(&addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
    273 
    274         // start with some stable ip address, either a function of
    275         // the hardware address or else the last address we used.
    276         // NOTE: the sequence of addresses we try changes only
    277         // depending on when we detect conflicts.
    278         memcpy(seed, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
    279         seed48(seed);
    280         if (ip.s_addr == 0)
    281             pick(&ip);
    282     }
     243    xbind(fd, &saddr, sizeof(saddr));
     244
     245    // get the interface's ethernet address
     246    //memset(&ifr, 0, sizeof(ifr));
     247    strncpy(ifr.ifr_name, intf, sizeof(ifr.ifr_name));
     248    xioctl(fd, SIOCGIFHWADDR, &ifr);
     249    memcpy(&eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
     250
     251    // start with some stable ip address, either a function of
     252    // the hardware address or else the last address we used.
     253    // NOTE: the sequence of addresses we try changes only
     254    // depending on when we detect conflicts.
     255    srand(*(unsigned*)&ifr.ifr_hwaddr.sa_data);
     256    if (ip.s_addr == 0)
     257        pick(&ip);
    283258
    284259    // FIXME cases to handle:
     
    287262
    288263    // daemonize now; don't delay system startup
    289     if (!foreground) {
    290         if (daemon(0, verbose) < 0) {
    291             why = "daemon";
    292             goto bad;
    293         }
    294         syslog(LOG_INFO, "start, interface %s", intf);
     264    if (!FOREGROUND) {
     265#if BB_MMU
     266        bb_daemonize(DAEMON_CHDIR_ROOT);
     267#endif
     268        bb_info_msg("start, interface %s", intf);
    295269    }
    296270
     
    305279    while (1) {
    306280        struct pollfd fds[1];
    307         struct timeval tv1;
     281        unsigned deadline_us;
    308282        struct arp_packet p;
     283
     284        int source_ip_conflict = 0;
     285        int target_ip_conflict = 0;
    309286
    310287        fds[0].fd = fd;
     
    312289        fds[0].revents = 0;
    313290
    314         int source_ip_conflict = 0;
    315         int target_ip_conflict = 0;
    316 
    317291        // poll, being ready to adjust current timeout
    318         if (!timeout) {
    319             timeout = ms_rdelay(PROBE_WAIT);
     292        if (!timeout_ms) {
     293            timeout_ms = ms_rdelay(PROBE_WAIT);
    320294            // FIXME setsockopt(fd, SO_ATTACH_FILTER, ...) to
    321295            // make the kernel filter out all packets except
    322296            // ones we'd care about.
    323297        }
    324         // set tv1 to the point in time when we timeout
    325         gettimeofday(&tv1, NULL);
    326         tv1.tv_usec += (timeout % 1000) * 1000;
    327         while (tv1.tv_usec > 1000000) {
    328             tv1.tv_usec -= 1000000;
    329             tv1.tv_sec++;
    330         }
    331         tv1.tv_sec += timeout / 1000;
    332    
    333         VDBG("...wait %ld %s nprobes=%d, nclaims=%d\n",
    334                 timeout, intf, nprobes, nclaims);
    335         switch (poll(fds, 1, timeout)) {
     298        // set deadline_us to the point in time when we timeout
     299        deadline_us = MONOTONIC_US() + timeout_ms * 1000;
     300
     301        VDBG("...wait %d %s nprobes=%u, nclaims=%u\n",
     302                timeout_ms, intf, nprobes, nclaims);
     303        switch (poll(fds, 1, timeout_ms)) {
    336304
    337305        // timeout
     
    340308            switch (state) {
    341309            case PROBE:
    342                 // timeouts in the PROBE state means no conflicting ARP packets
     310                // timeouts in the PROBE state mean no conflicting ARP packets
    343311                // have been received, so we can progress through the states
    344312                if (nprobes < PROBE_NUM) {
    345313                    nprobes++;
    346                     VDBG("probe/%d %s@%s\n",
     314                    VDBG("probe/%u %s@%s\n",
    347315                            nprobes, intf, inet_ntoa(ip));
    348                     (void)arp(fd, &saddr, ARPOP_REQUEST,
    349                             &addr, null_ip,
     316                    arp(fd, &saddr, ARPOP_REQUEST,
     317                            &eth_addr, null_ip,
    350318                            &null_addr, ip);
    351                     timeout = PROBE_MIN * 1000;
    352                     timeout += ms_rdelay(PROBE_MAX
    353                             - PROBE_MIN);
     319                    timeout_ms = PROBE_MIN * 1000;
     320                    timeout_ms += ms_rdelay(PROBE_MAX - PROBE_MIN);
    354321                }
    355322                else {
     
    357324                    state = ANNOUNCE;
    358325                    nclaims = 0;
    359                     VDBG("announce/%d %s@%s\n",
     326                    VDBG("announce/%u %s@%s\n",
    360327                            nclaims, intf, inet_ntoa(ip));
    361                     (void)arp(fd, &saddr, ARPOP_REQUEST,
    362                             &addr, ip,
    363                             &addr, ip);
    364                     timeout = ANNOUNCE_INTERVAL * 1000;
     328                    arp(fd, &saddr, ARPOP_REQUEST,
     329                            &eth_addr, ip,
     330                            &eth_addr, ip);
     331                    timeout_ms = ANNOUNCE_INTERVAL * 1000;
    365332                }
    366333                break;
    367334            case RATE_LIMIT_PROBE:
    368                 // timeouts in the RATE_LIMIT_PROBE state means no conflicting ARP packets
     335                // timeouts in the RATE_LIMIT_PROBE state mean no conflicting ARP packets
    369336                // have been received, so we can move immediately to the announce state
    370337                state = ANNOUNCE;
    371338                nclaims = 0;
    372                 VDBG("announce/%d %s@%s\n",
     339                VDBG("announce/%u %s@%s\n",
    373340                        nclaims, intf, inet_ntoa(ip));
    374                 (void)arp(fd, &saddr, ARPOP_REQUEST,
    375                         &addr, ip,
    376                         &addr, ip);
    377                 timeout = ANNOUNCE_INTERVAL * 1000;
     341                arp(fd, &saddr, ARPOP_REQUEST,
     342                        &eth_addr, ip,
     343                        &eth_addr, ip);
     344                timeout_ms = ANNOUNCE_INTERVAL * 1000;
    378345                break;
    379346            case ANNOUNCE:
    380                 // timeouts in the ANNOUNCE state means no conflicting ARP packets
     347                // timeouts in the ANNOUNCE state mean no conflicting ARP packets
    381348                // have been received, so we can progress through the states
    382349                if (nclaims < ANNOUNCE_NUM) {
    383350                    nclaims++;
    384                     VDBG("announce/%d %s@%s\n",
     351                    VDBG("announce/%u %s@%s\n",
    385352                            nclaims, intf, inet_ntoa(ip));
    386                     (void)arp(fd, &saddr, ARPOP_REQUEST,
    387                             &addr, ip,
    388                             &addr, ip);
    389                     timeout = ANNOUNCE_INTERVAL * 1000;
     353                    arp(fd, &saddr, ARPOP_REQUEST,
     354                            &eth_addr, ip,
     355                            &eth_addr, ip);
     356                    timeout_ms = ANNOUNCE_INTERVAL * 1000;
    390357                }
    391358                else {
     
    394361                    // link is ok to use earlier
    395362                    // FIXME update filters
    396                     run(script, "config", intf, &ip);
     363                    script_av[1] = (char*)"config";
     364                    run(script_av, intf, &ip);
    397365                    ready = 1;
    398366                    conflicts = 0;
    399                     timeout = -1; // Never timeout in the monitor state.
    400 
    401                     // NOTE:  all other exit paths
     367                    timeout_ms = -1; // Never timeout in the monitor state.
     368
     369                    // NOTE: all other exit paths
    402370                    // should deconfig ...
    403                     if (quit)
     371                    if (QUIT)
    404372                        return EXIT_SUCCESS;
    405373                }
     
    408376                // We won!  No ARP replies, so just go back to monitor.
    409377                state = MONITOR;
    410                 timeout = -1;
     378                timeout_ms = -1;
    411379                conflicts = 0;
    412380                break;
     
    415383                state = PROBE;
    416384                pick(&ip);
    417                 timeout = 0;
     385                timeout_ms = 0;
    418386                nprobes = 0;
    419387                nclaims = 0;
     
    425393            // We need to adjust the timeout in case we didn't receive
    426394            // a conflicting packet.
    427             if (timeout > 0) {
    428                 struct timeval tv2;
    429 
    430                 gettimeofday(&tv2, NULL);
    431                 if (timercmp(&tv1, &tv2, <)) {
     395            if (timeout_ms > 0) {
     396                unsigned diff = deadline_us - MONOTONIC_US();
     397                if ((int)(diff) < 0) {
    432398                    // Current time is greater than the expected timeout time.
    433399                    // Should never happen.
    434400                    VDBG("missed an expected timeout\n");
    435                     timeout = 0;
     401                    timeout_ms = 0;
    436402                } else {
    437403                    VDBG("adjusting timeout\n");
    438                     timersub(&tv1, &tv2, &tv1);
    439                     timeout = 1000 * tv1.tv_sec
    440                             + tv1.tv_usec / 1000;
     404                    timeout_ms = diff / 1000;
     405                    if (!timeout_ms) timeout_ms = 1;
    441406                }
    442407            }
     
    446411                    // FIXME: links routinely go down;
    447412                    // this shouldn't necessarily exit.
    448                     bb_error_msg("%s: poll error\n", intf);
     413                    bb_error_msg("%s: poll error", intf);
    449414                    if (ready) {
    450                         run(script, "deconfig",
    451                                 intf, &ip);
     415                        script_av[1] = (char*)"deconfig";
     416                        run(script_av, intf, &ip);
    452417                    }
    453418                    return EXIT_FAILURE;
     
    457422
    458423            // read ARP packet
    459             if (recv(fd, &p, sizeof (p), 0) < 0) {
     424            if (recv(fd, &p, sizeof(p), 0) < 0) {
    460425                why = "recv";
    461426                goto bad;
     
    486451
    487452            if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0 &&
    488                 memcmp(&addr, &p.arp.arp_sha, ETH_ALEN) != 0) {
     453                memcmp(&eth_addr, &p.arp.arp_sha, ETH_ALEN) != 0) {
    489454                source_ip_conflict = 1;
    490455            }
    491456            if (memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0 &&
    492457                p.arp.arp_op == htons(ARPOP_REQUEST) &&
    493                 memcmp(&addr, &p.arp.arp_tha, ETH_ALEN) != 0) {
     458                memcmp(&eth_addr, &p.arp.arp_tha, ETH_ALEN) != 0) {
    494459                target_ip_conflict = 1;
    495460            }
    496461
    497             VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", 
     462            VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n",
    498463                state, source_ip_conflict, target_ip_conflict);
    499464            switch (state) {
     
    506471                    if (conflicts >= MAX_CONFLICTS) {
    507472                        VDBG("%s ratelimit\n", intf);
    508                         timeout = RATE_LIMIT_INTERVAL * 1000;
     473                        timeout_ms = RATE_LIMIT_INTERVAL * 1000;
    509474                        state = RATE_LIMIT_PROBE;
    510475                    }
     
    512477                    // restart the whole protocol
    513478                    pick(&ip);
    514                     timeout = 0;
     479                    timeout_ms = 0;
    515480                    nprobes = 0;
    516481                    nclaims = 0;
     
    522487                    VDBG("monitor conflict -- defending\n");
    523488                    state = DEFEND;
    524                     timeout = DEFEND_INTERVAL * 1000;
    525                     (void)arp(fd, &saddr,
     489                    timeout_ms = DEFEND_INTERVAL * 1000;
     490                    arp(fd, &saddr,
    526491                            ARPOP_REQUEST,
    527                             &addr, ip,
    528                             &addr, ip);
     492                            &eth_addr, ip,
     493                            &eth_addr, ip);
    529494                }
    530495                break;
     
    535500                    VDBG("defend conflict -- starting over\n");
    536501                    ready = 0;
    537                     run(script, "deconfig", intf, &ip);
     502                    script_av[1] = (char*)"deconfig";
     503                    run(script_av, intf, &ip);
    538504
    539505                    // restart the whole protocol
    540506                    pick(&ip);
    541                     timeout = 0;
     507                    timeout_ms = 0;
    542508                    nprobes = 0;
    543509                    nclaims = 0;
     
    549515                state = PROBE;
    550516                pick(&ip);
    551                 timeout = 0;
     517                timeout_ms = 0;
    552518                nprobes = 0;
    553519                nclaims = 0;
     
    561527        } // switch poll
    562528    }
    563 bad:
    564     if (foreground)
    565         perror(why);
    566     else
    567         syslog(LOG_ERR, "%s %s, %s error: %s",
    568             bb_applet_name, intf, why, strerror(errno));
     529 bad:
     530    bb_perror_msg("%s, %s", intf, why);
    569531    return EXIT_FAILURE;
    570532}
Note: See TracChangeset for help on using the changeset viewer.