Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/arping.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * arping.c - Ping hosts by ARP requests/replies
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 *
    5  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    6  *
    7  * Author:  Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
     5 * Author: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
    86 * Busybox port: Nick Fedchik <nick@fedchik.org.ua>
    97 */
     
    1816/* We don't expect to see 1000+ seconds delay, unsigned is enough */
    1917#define MONOTONIC_US() ((unsigned)monotonic_us())
    20 
    21 static struct in_addr src;
    22 static struct in_addr dst;
    23 static struct sockaddr_ll me;
    24 static struct sockaddr_ll he;
    25 static unsigned last;
    2618
    2719enum {
     
    3527};
    3628
    37 static int sock;
    38 static unsigned count = UINT_MAX;
    39 static unsigned timeout_us;
    40 static unsigned sent;
    41 static unsigned brd_sent;
    42 static unsigned received;
    43 static unsigned brd_recv;
    44 static unsigned req_recv;
     29struct globals {
     30    struct in_addr src;
     31    struct in_addr dst;
     32    struct sockaddr_ll me;
     33    struct sockaddr_ll he;
     34    int sock_fd;
     35
     36    int count; // = -1;
     37    unsigned last;
     38    unsigned timeout_us;
     39    unsigned start;
     40
     41    unsigned sent;
     42    unsigned brd_sent;
     43    unsigned received;
     44    unsigned brd_recv;
     45    unsigned req_recv;
     46} FIX_ALIASING;
     47#define G (*(struct globals*)&bb_common_bufsiz1)
     48#define src        (G.src       )
     49#define dst        (G.dst       )
     50#define me         (G.me        )
     51#define he         (G.he        )
     52#define sock_fd    (G.sock_fd   )
     53#define count      (G.count     )
     54#define last       (G.last      )
     55#define timeout_us (G.timeout_us)
     56#define start      (G.start     )
     57#define sent       (G.sent      )
     58#define brd_sent   (G.brd_sent  )
     59#define received   (G.received  )
     60#define brd_recv   (G.brd_recv  )
     61#define req_recv   (G.req_recv  )
     62#define INIT_G() do { \
     63    count = -1; \
     64} while (0)
     65
     66// If GNUisms are not available...
     67//static void *mempcpy(void *_dst, const void *_src, int n)
     68//{
     69//  memcpy(_dst, _src, n);
     70//  return (char*)_dst + n;
     71//}
    4572
    4673static int send_pack(struct in_addr *src_addr,
     
    4976{
    5077    int err;
    51     unsigned now;
    5278    unsigned char buf[256];
    5379    struct arphdr *ah = (struct arphdr *) buf;
    5480    unsigned char *p = (unsigned char *) (ah + 1);
    5581
    56     ah->ar_hrd = htons(ME->sll_hatype);
    5782    ah->ar_hrd = htons(ARPHRD_ETHER);
    5883    ah->ar_pro = htons(ETH_P_IP);
     
    6186    ah->ar_op = option_mask32 & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST);
    6287
    63     memcpy(p, &ME->sll_addr, ah->ar_hln);
    64     p += ME->sll_halen;
    65 
    66     memcpy(p, src_addr, 4);
    67     p += 4;
     88    p = mempcpy(p, &ME->sll_addr, ah->ar_hln);
     89    p = mempcpy(p, src_addr, 4);
    6890
    6991    if (option_mask32 & ADVERT)
    70         memcpy(p, &ME->sll_addr, ah->ar_hln);
     92        p = mempcpy(p, &ME->sll_addr, ah->ar_hln);
    7193    else
    72         memcpy(p, &HE->sll_addr, ah->ar_hln);
    73     p += ah->ar_hln;
    74 
    75     memcpy(p, dst_addr, 4);
    76     p += 4;
    77 
    78     now = MONOTONIC_US();
    79     err = sendto(sock, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE));
     94        p = mempcpy(p, &HE->sll_addr, ah->ar_hln);
     95
     96    p = mempcpy(p, dst_addr, 4);
     97
     98    err = sendto(sock_fd, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE));
    8099    if (err == p - buf) {
    81         last = now;
     100        last = MONOTONIC_US();
    82101        sent++;
    83102        if (!(option_mask32 & UNICASTING))
     
    87106}
    88107
    89 static void finish(void) ATTRIBUTE_NORETURN;
     108static void finish(void) NORETURN;
    90109static void finish(void)
    91110{
     
    101120        exit(!!received);
    102121    if (option_mask32 & UNSOLICITED)
    103         exit(0);
     122        exit(EXIT_SUCCESS);
    104123    exit(!received);
    105124}
     
    107126static void catcher(void)
    108127{
    109     static unsigned start;
    110 
    111128    unsigned now;
    112129
     
    115132        start = now;
    116133
    117     if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000)))
     134    if (count == 0 || (timeout_us && (now - start) > timeout_us))
    118135        finish();
    119136
    120     count--;
     137    /* count < 0 means "infinite count" */
     138    if (count > 0)
     139        count--;
    121140
    122141    if (last == 0 || (now - last) > 500000) {
     
    128147}
    129148
    130 static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
     149static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
    131150{
    132151    struct arphdr *ah = (struct arphdr *) buf;
    133152    unsigned char *p = (unsigned char *) (ah + 1);
    134153    struct in_addr src_ip, dst_ip;
     154    /* moves below assume in_addr is 4 bytes big, ensure that */
     155    struct BUG_in_addr_must_be_4 {
     156        char BUG_in_addr_must_be_4[
     157            sizeof(struct in_addr) == 4 ? 1 : -1
     158        ];
     159        char BUG_s_addr_must_be_4[
     160            sizeof(src_ip.s_addr) == 4 ? 1 : -1
     161        ];
     162    };
    135163
    136164    /* Filter out wild packets */
     
    138166     && FROM->sll_pkttype != PACKET_BROADCAST
    139167     && FROM->sll_pkttype != PACKET_MULTICAST)
    140         return 0;
    141 
    142     /* Only these types are recognised */
     168        return false;
     169
     170    /* Only these types are recognized */
    143171    if (ah->ar_op != htons(ARPOP_REQUEST) && ah->ar_op != htons(ARPOP_REPLY))
    144         return 0;
     172        return false;
    145173
    146174    /* ARPHRD check and this darned FDDI hack here :-( */
    147175    if (ah->ar_hrd != htons(FROM->sll_hatype)
    148176     && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER)))
    149         return 0;
     177        return false;
    150178
    151179    /* Protocol must be IP. */
    152     if (ah->ar_pro != htons(ETH_P_IP))
    153         return 0;
    154     if (ah->ar_pln != 4)
    155         return 0;
    156     if (ah->ar_hln != me.sll_halen)
    157         return 0;
    158     if (len < sizeof(*ah) + 2 * (4 + ah->ar_hln))
    159         return 0;
    160     memcpy(&src_ip, p + ah->ar_hln, 4);
    161     memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4);
     180    if (ah->ar_pro != htons(ETH_P_IP)
     181     || (ah->ar_pln != 4)
     182     || (ah->ar_hln != me.sll_halen)
     183     || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln))))
     184        return false;
     185
     186    move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln);
     187    move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln);
     188
     189    if (dst.s_addr != src_ip.s_addr)
     190        return false;
    162191    if (!(option_mask32 & DAD)) {
    163         if (src_ip.s_addr != dst.s_addr)
    164             return 0;
    165         if (src.s_addr != dst_ip.s_addr)
    166             return 0;
    167         if (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln))
    168             return 0;
     192        if ((src.s_addr != dst_ip.s_addr)
     193            || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln)))
     194            return false;
    169195    } else {
    170196        /* DAD packet was:
     
    181207           dst_ip/dst_hw do not matter.
    182208         */
    183         if (src_ip.s_addr != dst.s_addr)
    184             return 0;
    185         if (memcmp(p, &me.sll_addr, me.sll_halen) == 0)
    186             return 0;
    187         if (src.s_addr && src.s_addr != dst_ip.s_addr)
    188             return 0;
     209        if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0)
     210         || (src.s_addr && src.s_addr != dst_ip.s_addr))
     211            return false;
    189212    }
    190213    if (!(option_mask32 & QUIET)) {
     
    208231
    209232        if (last) {
    210             printf(" %u.%03ums\n", last / 1000, last % 1000);
     233            unsigned diff = MONOTONIC_US() - last;
     234            printf(" %u.%03ums\n", diff / 1000, diff % 1000);
    211235        } else {
    212236            printf(" UNSOLICITED?\n");
    213237        }
    214         fflush(stdout);
     238        fflush_all();
    215239    }
    216240    received++;
     
    225249        option_mask32 |= UNICASTING;
    226250    }
    227     return 1;
     251    return true;
    228252}
    229253
    230 int arping_main(int argc, char **argv);
    231 int arping_main(int argc, char **argv)
     254int arping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     255int arping_main(int argc UNUSED_PARAM, char **argv)
    232256{
    233257    const char *device = "eth0";
    234     int ifindex;
    235258    char *source = NULL;
    236259    char *target;
    237260    unsigned char *packet;
    238 
    239     sock = xsocket(PF_PACKET, SOCK_DGRAM, 0);
     261    char *err_str;
     262
     263    INIT_G();
     264
     265    sock_fd = xsocket(AF_PACKET, SOCK_DGRAM, 0);
    240266
    241267    // Drop suid root privileges
    242     xsetuid(getuid());
    243 
     268    // Need to remove SUID_NEVER from applets.h for this to work
     269    //xsetuid(getuid());
     270
     271    err_str = xasprintf("interface %s %%s", device);
    244272    {
    245273        unsigned opt;
    246         char *str_count, *str_timeout;
     274        char *str_timeout;
    247275
    248276        /* Dad also sets quit_on_reply.
    249277         * Advert also sets unsolicited.
    250278         */
    251         opt_complementary = "=1:Df:AU";
     279        opt_complementary = "=1:Df:AU:c+";
    252280        opt = getopt32(argv, "DUAqfbc:w:I:s:",
    253                 &str_count, &str_timeout, &device, &source);
    254         if (opt & 0x40) /* -c: count */
    255             count = xatou(str_count);
     281                &count, &str_timeout, &device, &source);
    256282        if (opt & 0x80) /* -w: timeout */
    257             timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000;
    258         //if (opt & 0x100) /* -I: interface */
    259         if (strlen(device) >= IF_NAMESIZE) {
    260             bb_error_msg_and_die("interface name '%s' is too long",
    261                             device);
    262         }
     283            timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000;
    263284        //if (opt & 0x200) /* -s: source */
    264285        option_mask32 &= 0x3f; /* set respective flags */
     
    273294
    274295        memset(&ifr, 0, sizeof(ifr));
    275         strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
    276         ioctl_or_perror_and_die(sock, SIOCGIFINDEX, &ifr, "interface %s not found", device);
    277         ifindex = ifr.ifr_ifindex;
    278 
    279         xioctl(sock, SIOCGIFFLAGS, (char *) &ifr);
     296        strncpy_IFNAMSIZ(ifr.ifr_name, device);
     297        /* We use ifr.ifr_name in error msg so that problem
     298         * with truncated name will be visible */
     299        ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &ifr, err_str, "not found");
     300        me.sll_ifindex = ifr.ifr_ifindex;
     301
     302        xioctl(sock_fd, SIOCGIFFLAGS, (char *) &ifr);
    280303
    281304        if (!(ifr.ifr_flags & IFF_UP)) {
    282             bb_error_msg_and_die("interface %s is down", device);
     305            bb_error_msg_and_die(err_str, "is down");
    283306        }
    284307        if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
    285             bb_error_msg("interface %s is not ARPable", device);
     308            bb_error_msg(err_str, "is not ARPable");
    286309            return (option_mask32 & DAD ? 0 : 2);
    287310        }
    288311    }
    289312
    290     if (!inet_aton(target, &dst)) {
     313    /* if (!inet_aton(target, &dst)) - not needed */ {
    291314        len_and_sockaddr *lsa;
    292315        lsa = xhost_and_af2sockaddr(target, 0, AF_INET);
    293         memcpy(&dst, &lsa->sin.sin_addr.s_addr, 4);
     316        dst = lsa->u.sin.sin_addr;
    294317        if (ENABLE_FEATURE_CLEAN_UP)
    295318            free(lsa);
     
    300323    }
    301324
    302     if (!(option_mask32 & DAD) && (option_mask32 & UNSOLICITED) && src.s_addr == 0)
     325    if ((option_mask32 & (DAD|UNSOLICITED)) == UNSOLICITED && src.s_addr == 0)
    303326        src = dst;
    304327
     
    307330        int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0);
    308331
    309         if (device) {
    310             if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1)
    311                 bb_error_msg("warning: interface %s is ignored", device);
    312         }
     332        setsockopt_bindtodevice(probe_fd, device);
    313333        memset(&saddr, 0, sizeof(saddr));
    314334        saddr.sin_family = AF_INET;
    315335        if (src.s_addr) {
     336            /* Check that this is indeed our IP */
    316337            saddr.sin_addr = src;
    317338            xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
    318         } else if (!(option_mask32 & DAD)) {
     339        } else { /* !(option_mask32 & DAD) case */
     340            /* Find IP address on this iface */
    319341            socklen_t alen = sizeof(saddr);
    320342
     
    323345
    324346            if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1)
    325                 bb_perror_msg("warning: setsockopt(SO_DONTROUTE)");
     347                bb_perror_msg("setsockopt(SO_DONTROUTE)");
    326348            xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
    327             if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) {
    328                 bb_error_msg_and_die("getsockname");
    329             }
     349            getsockname(probe_fd, (struct sockaddr *) &saddr, &alen);
     350            //never happens:
     351            //if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1)
     352            //  bb_perror_msg_and_die("getsockname");
     353            if (saddr.sin_family != AF_INET)
     354                bb_error_msg_and_die("no IP address configured");
    330355            src = saddr.sin_addr;
    331356        }
     
    334359
    335360    me.sll_family = AF_PACKET;
    336     me.sll_ifindex = ifindex;
     361    //me.sll_ifindex = ifindex; - done before
    337362    me.sll_protocol = htons(ETH_P_ARP);
    338     xbind(sock, (struct sockaddr *) &me, sizeof(me));
     363    xbind(sock_fd, (struct sockaddr *) &me, sizeof(me));
    339364
    340365    {
    341366        socklen_t alen = sizeof(me);
    342 
    343         if (getsockname(sock, (struct sockaddr *) &me, &alen) == -1) {
    344             bb_error_msg_and_die("getsockname");
    345         }
     367        getsockname(sock_fd, (struct sockaddr *) &me, &alen);
     368        //never happens:
     369        //if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1)
     370        //  bb_perror_msg_and_die("getsockname");
    346371    }
    347372    if (me.sll_halen == 0) {
    348         bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device);
     373        bb_error_msg(err_str, "is not ARPable (no ll address)");
    349374        return (option_mask32 & DAD ? 0 : 2);
    350375    }
     
    353378
    354379    if (!(option_mask32 & QUIET)) {
    355         printf("ARPING to %s from %s via %s\n",
    356             inet_ntoa(dst), inet_ntoa(src),
    357             device ? device : "unknown");
    358     }
    359 
    360     if (!src.s_addr && !(option_mask32 & DAD)) {
    361         bb_error_msg_and_die("no src address in the non-DAD mode");
    362     }
    363 
    364     {
    365         struct sigaction sa;
    366 
    367         memset(&sa, 0, sizeof(sa));
    368         sa.sa_flags = SA_RESTART;
    369 
    370         sa.sa_handler = (void (*)(int)) finish;
    371         sigaction(SIGINT, &sa, NULL);
    372 
    373         sa.sa_handler = (void (*)(int)) catcher;
    374         sigaction(SIGALRM, &sa, NULL);
    375     }
     380        /* inet_ntoa uses static storage, can't use in same printf */
     381        printf("ARPING to %s", inet_ntoa(dst));
     382        printf(" from %s via %s\n", inet_ntoa(src), device);
     383    }
     384
     385    signal_SA_RESTART_empty_mask(SIGINT,  (void (*)(int))finish);
     386    signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher);
    376387
    377388    catcher();
     
    384395        int cc;
    385396
    386         cc = recvfrom(sock, packet, 4096, 0, (struct sockaddr *) &from, &alen);
     397        cc = recvfrom(sock_fd, packet, 4096, 0, (struct sockaddr *) &from, &alen);
    387398        if (cc < 0) {
    388399            bb_perror_msg("recvfrom");
Note: See TracChangeset for help on using the changeset viewer.