Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 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/arping.c

    r821 r1765  
    99 */
    1010
    11 #include <sys/ioctl.h>
    12 #include <signal.h>
    13 
    14 #include <errno.h>
    15 #include <stdlib.h>
    16 #include <string.h>
    17 #include <unistd.h>
    18 
    1911#include <arpa/inet.h>
    2012#include <net/if.h>
     
    2214#include <netpacket/packet.h>
    2315
    24 #include "busybox.h"
     16#include "libbb.h"
     17
     18/* We don't expect to see 1000+ seconds delay, unsigned is enough */
     19#define MONOTONIC_US() ((unsigned)monotonic_us())
    2520
    2621static struct in_addr src;
     
    2823static struct sockaddr_ll me;
    2924static struct sockaddr_ll he;
    30 static struct timeval last;
    31 
    32 enum cfg_e {
    33     dad = 1,
    34     unsolicited = 2,
    35     advert = 4,
    36     quiet = 8,
    37     quit_on_reply = 16,
    38     broadcast_only = 32,
    39     unicasting = 64
     25static unsigned last;
     26
     27enum {
     28    DAD = 1,
     29    UNSOLICITED = 2,
     30    ADVERT = 4,
     31    QUIET = 8,
     32    QUIT_ON_REPLY = 16,
     33    BCAST_ONLY = 32,
     34    UNICASTING = 64
    4035};
    41 static int cfg;
    42 
    43 static int s;
    44 static int count = -1;
    45 static int timeout;
    46 static int sent;
    47 static int brd_sent;
    48 static int received;
    49 static int brd_recv;
    50 static int req_recv;
    51 
    52 
    53 #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \
    54                ((tv1).tv_usec-(tv2).tv_usec)/1000 )
    55 #if 0
    56 static void set_signal(int signo, void (*handler) (void))
    57 {
    58     struct sigaction sa;
    59 
    60     memset(&sa, 0, sizeof(sa));
    61     sa.sa_handler = (void (*)(int)) handler;
    62     sa.sa_flags = SA_RESTART;
    63     sigaction(signo, &sa, NULL);
    64 }
    65 #endif
    66 
    67 static int send_pack(int sock, struct in_addr *src_addr,
    68                      struct in_addr *dst_addr, struct sockaddr_ll *ME,
    69                      struct sockaddr_ll *HE)
     36
     37static int sock;
     38static unsigned count = UINT_MAX;
     39static unsigned timeout_us;
     40static unsigned sent;
     41static unsigned brd_sent;
     42static unsigned received;
     43static unsigned brd_recv;
     44static unsigned req_recv;
     45
     46static int send_pack(struct in_addr *src_addr,
     47            struct in_addr *dst_addr, struct sockaddr_ll *ME,
     48            struct sockaddr_ll *HE)
    7049{
    7150    int err;
    72     struct timeval now;
    73     RESERVE_CONFIG_UBUFFER(buf, 256);
     51    unsigned now;
     52    unsigned char buf[256];
    7453    struct arphdr *ah = (struct arphdr *) buf;
    7554    unsigned char *p = (unsigned char *) (ah + 1);
     
    8059    ah->ar_hln = ME->sll_halen;
    8160    ah->ar_pln = 4;
    82     ah->ar_op = cfg&advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST);
     61    ah->ar_op = option_mask32 & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST);
    8362
    8463    memcpy(p, &ME->sll_addr, ah->ar_hln);
     
    8867    p += 4;
    8968
    90     if (cfg&advert)
     69    if (option_mask32 & ADVERT)
    9170        memcpy(p, &ME->sll_addr, ah->ar_hln);
    9271    else
     
    9776    p += 4;
    9877
    99     gettimeofday(&now, NULL);
     78    now = MONOTONIC_US();
    10079    err = sendto(sock, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE));
    10180    if (err == p - buf) {
    10281        last = now;
    10382        sent++;
    104         if (!(cfg&unicasting))
     83        if (!(option_mask32 & UNICASTING))
    10584            brd_sent++;
    10685    }
    107     RELEASE_CONFIG_BUFFER(buf);
    10886    return err;
    10987}
    11088
     89static void finish(void) ATTRIBUTE_NORETURN;
    11190static void finish(void)
    11291{
    113     if (!(cfg&quiet)) {
    114         printf("Sent %d probes (%d broadcast(s))\n"
    115             "Received %d repl%s",
     92    if (!(option_mask32 & QUIET)) {
     93        printf("Sent %u probe(s) (%u broadcast(s))\n"
     94            "Received %u repl%s"
     95            " (%u request(s), %u broadcast(s))\n",
    11696            sent, brd_sent,
    117             received, (received > 1) ? "ies" : "y");
    118         if (brd_recv || req_recv) {
    119             printf(" (");
    120             if (req_recv)
    121                 printf("%d request(s)", req_recv);
    122             if (brd_recv)
    123                 printf("%s%d broadcast(s)", req_recv ? ", " : "", brd_recv);
    124             putchar(')');
    125         }
    126         putchar('\n');
    127         fflush(stdout);
    128     }
    129     if (cfg&dad)
     97            received, (received == 1) ? "ies" : "y",
     98            req_recv, brd_recv);
     99    }
     100    if (option_mask32 & DAD)
    130101        exit(!!received);
    131     if (cfg&unsolicited)
     102    if (option_mask32 & UNSOLICITED)
    132103        exit(0);
    133104    exit(!received);
     
    136107static void catcher(void)
    137108{
    138     struct timeval tv;
    139     static struct timeval start;
    140 
    141     gettimeofday(&tv, NULL);
    142 
    143     if (start.tv_sec == 0)
    144         start = tv;
    145 
    146     if (count-- == 0
    147         || (timeout && MS_TDIFF(tv, start) > timeout * 1000 + 500))
     109    static unsigned start;
     110
     111    unsigned now;
     112
     113    now = MONOTONIC_US();
     114    if (start == 0)
     115        start = now;
     116
     117    if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000)))
    148118        finish();
    149119
    150     if (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500) {
    151         send_pack(s, &src, &dst, &me, &he);
    152         if (count == 0 && cfg&unsolicited)
     120    count--;
     121
     122    if (last == 0 || (now - last) > 500000) {
     123        send_pack(&src, &dst, &me, &he);
     124        if (count == 0 && (option_mask32 & UNSOLICITED))
    153125            finish();
    154126    }
     
    163135
    164136    /* Filter out wild packets */
    165     if (FROM->sll_pkttype != PACKET_HOST &&
    166         FROM->sll_pkttype != PACKET_BROADCAST &&
    167         FROM->sll_pkttype != PACKET_MULTICAST)
     137    if (FROM->sll_pkttype != PACKET_HOST
     138     && FROM->sll_pkttype != PACKET_BROADCAST
     139     && FROM->sll_pkttype != PACKET_MULTICAST)
    168140        return 0;
    169141
     
    173145
    174146    /* ARPHRD check and this darned FDDI hack here :-( */
    175     if (ah->ar_hrd != htons(FROM->sll_hatype) &&
    176         (FROM->sll_hatype != ARPHRD_FDDI
    177          || ah->ar_hrd != htons(ARPHRD_ETHER)))
     147    if (ah->ar_hrd != htons(FROM->sll_hatype)
     148     && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER)))
    178149        return 0;
    179150
     
    189160    memcpy(&src_ip, p + ah->ar_hln, 4);
    190161    memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4);
    191     if (!(cfg&dad)) {
     162    if (!(option_mask32 & DAD)) {
    192163        if (src_ip.s_addr != dst.s_addr)
    193164            return 0;
     
    217188            return 0;
    218189    }
    219     if (!(cfg&quiet)) {
     190    if (!(option_mask32 & QUIET)) {
    220191        int s_printed = 0;
    221         struct timeval tv;
    222 
    223         gettimeofday(&tv, NULL);
    224 
    225         printf("%s %s from %s [%s]",
    226             FROM->sll_pkttype == PACKET_HOST ? "Unicast" : "Broadcast",
    227             ah->ar_op == htons(ARPOP_REPLY) ? "reply" : "request",
     192
     193        printf("%scast re%s from %s [%s]",
     194            FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad",
     195            ah->ar_op == htons(ARPOP_REPLY) ? "ply" : "quest",
    228196            inet_ntoa(src_ip),
    229197            ether_ntoa((struct ether_addr *) p));
     
    236204                printf("for ");
    237205            printf("[%s]",
    238                    ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4));
    239         }
    240 
    241         if (last.tv_sec) {
    242             long usecs = (tv.tv_sec - last.tv_sec) * 1000000 +
    243                 tv.tv_usec - last.tv_usec;
    244             long msecs = (usecs + 500) / 1000;
    245 
    246             usecs -= msecs * 1000 - 500;
    247             printf(" %ld.%03ldms\n", msecs, usecs);
     206                ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4));
     207        }
     208
     209        if (last) {
     210            printf(" %u.%03ums\n", last / 1000, last % 1000);
    248211        } else {
    249212            printf(" UNSOLICITED?\n");
     
    256219    if (ah->ar_op == htons(ARPOP_REQUEST))
    257220        req_recv++;
    258     if (cfg&quit_on_reply)
     221    if (option_mask32 & QUIT_ON_REPLY)
    259222        finish();
    260     if (!(cfg&broadcast_only)) {
     223    if (!(option_mask32 & BCAST_ONLY)) {
    261224        memcpy(he.sll_addr, p, me.sll_halen);
    262         cfg |= unicasting;
     225        option_mask32 |= UNICASTING;
    263226    }
    264227    return 1;
    265228}
    266229
     230int arping_main(int argc, char **argv);
    267231int arping_main(int argc, char **argv)
    268232{
    269     char *device = "eth0";
     233    const char *device = "eth0";
    270234    int ifindex;
    271235    char *source = NULL;
    272236    char *target;
    273 
    274     s = socket(PF_PACKET, SOCK_DGRAM, 0);
    275     ifindex = errno;
     237    unsigned char *packet;
     238
     239    sock = xsocket(PF_PACKET, SOCK_DGRAM, 0);
    276240
    277241    // Drop suid root privileges
     
    279243
    280244    {
    281         unsigned long opt;
    282         char *_count, *_timeout, *_device;
     245        unsigned opt;
     246        char *str_count, *str_timeout;
    283247
    284248        /* Dad also sets quit_on_reply.
    285249         * Advert also sets unsolicited.
    286250         */
    287         bb_opt_complementally = "Df:AU";
    288         opt = bb_getopt_ulflags(argc, argv, "DUAqfbc:w:i:s:",
    289                         &_count, &_timeout, &_device);
    290         cfg |= opt & 63; /* set respective flags */
    291         if (opt & 64) /* count */
    292             count = atoi(_count);
    293         if (opt & 128) /* timeout */
    294             timeout = atoi(_timeout);
    295         if (opt & 256) { /* interface */
    296             if (strlen(_device) > IF_NAMESIZE) {
    297                 bb_error_msg_and_die("Interface name `%s' must be less than %d",
    298                                 _device, IF_NAMESIZE);
    299             }
    300             device = _device;
    301         }
    302         if (opt & 512) /* source */
    303             source = optarg;
    304     }
    305     argc -= optind;
    306     argv += optind;
    307 
    308     if (argc != 1)
    309         bb_show_usage();
    310 
    311     target = *argv;
    312 
    313 
    314     if (s < 0) {
    315         bb_default_error_retval = ifindex;
    316         bb_perror_msg_and_die("socket");
    317     }
    318     bb_default_error_retval = 2;
     251        opt_complementary = "=1:Df:AU";
     252        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);
     256        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        }
     263        //if (opt & 0x200) /* -s: source */
     264        option_mask32 &= 0x3f; /* set respective flags */
     265    }
     266
     267    target = argv[optind];
     268
     269    xfunc_error_retval = 2;
    319270
    320271    {
     
    323274        memset(&ifr, 0, sizeof(ifr));
    324275        strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
    325         if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
    326             bb_error_msg_and_die("Interface %s not found", device);
    327         }
     276        ioctl_or_perror_and_die(sock, SIOCGIFINDEX, &ifr, "interface %s not found", device);
    328277        ifindex = ifr.ifr_ifindex;
    329278
    330         if (ioctl(s, SIOCGIFFLAGS, (char *) &ifr)) {
    331             bb_error_msg_and_die("SIOCGIFFLAGS");
    332         }
     279        xioctl(sock, SIOCGIFFLAGS, (char *) &ifr);
     280
    333281        if (!(ifr.ifr_flags & IFF_UP)) {
    334             bb_error_msg_and_die("Interface %s is down", device);
     282            bb_error_msg_and_die("interface %s is down", device);
    335283        }
    336284        if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
    337             bb_error_msg("Interface %s is not ARPable", device);
    338             exit(cfg&dad ? 0 : 2);
     285            bb_error_msg("interface %s is not ARPable", device);
     286            return (option_mask32 & DAD ? 0 : 2);
    339287        }
    340288    }
    341289
    342290    if (!inet_aton(target, &dst)) {
    343         struct hostent *hp;
    344 
    345         hp = gethostbyname2(target, AF_INET);
    346         if (!hp) {
    347             bb_error_msg_and_die("invalid or unknown target %s", target);
    348         }
    349         memcpy(&dst, hp->h_addr, 4);
     291        len_and_sockaddr *lsa;
     292        lsa = xhost_and_af2sockaddr(target, 0, AF_INET);
     293        memcpy(&dst, &lsa->sin.sin_addr.s_addr, 4);
     294        if (ENABLE_FEATURE_CLEAN_UP)
     295            free(lsa);
    350296    }
    351297
     
    354300    }
    355301
    356     if (!(cfg&dad) && cfg&unsolicited && src.s_addr == 0)
     302    if (!(option_mask32 & DAD) && (option_mask32 & UNSOLICITED) && src.s_addr == 0)
    357303        src = dst;
    358304
    359     if (!(cfg&dad) || src.s_addr) {
     305    if (!(option_mask32 & DAD) || src.s_addr) {
    360306        struct sockaddr_in saddr;
    361         int probe_fd = socket(AF_INET, SOCK_DGRAM, 0); /* maybe use bb_xsocket? */
    362 
    363         if (probe_fd < 0) {
    364             bb_error_msg_and_die("socket");
    365         }
     307        int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     308
    366309        if (device) {
    367             if (setsockopt
    368                 (probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device,
    369                  strlen(device) + 1) == -1)
    370                 bb_error_msg("WARNING: interface %s is ignored", 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);
    371312        }
    372313        memset(&saddr, 0, sizeof(saddr));
     
    374315        if (src.s_addr) {
    375316            saddr.sin_addr = src;
    376             if (bind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) {
    377                 bb_error_msg_and_die("bind");
    378             }
    379         } else if (!(cfg&dad)) {
    380             int on = 1;
     317            xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
     318        } else if (!(option_mask32 & DAD)) {
    381319            socklen_t alen = sizeof(saddr);
    382320
     
    384322            saddr.sin_addr = dst;
    385323
    386             if (setsockopt
    387                 (probe_fd, SOL_SOCKET, SO_DONTROUTE, (char *) &on,
    388                  sizeof(on)) == -1)
    389                 bb_perror_msg("WARNING: setsockopt(SO_DONTROUTE)");
    390             if (connect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr))
    391                 == -1) {
    392                 bb_error_msg_and_die("connect");
    393             }
    394             if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) ==
    395                 -1) {
     324            if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1)
     325                bb_perror_msg("warning: setsockopt(SO_DONTROUTE)");
     326            xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
     327            if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) {
    396328                bb_error_msg_and_die("getsockname");
    397329            }
     
    399331        }
    400332        close(probe_fd);
    401     };
     333    }
    402334
    403335    me.sll_family = AF_PACKET;
    404336    me.sll_ifindex = ifindex;
    405337    me.sll_protocol = htons(ETH_P_ARP);
    406     if (bind(s, (struct sockaddr *) &me, sizeof(me)) == -1) {
    407         bb_error_msg_and_die("bind");
    408     }
     338    xbind(sock, (struct sockaddr *) &me, sizeof(me));
    409339
    410340    {
    411341        socklen_t alen = sizeof(me);
    412342
    413         if (getsockname(s, (struct sockaddr *) &me, &alen) == -1) {
     343        if (getsockname(sock, (struct sockaddr *) &me, &alen) == -1) {
    414344            bb_error_msg_and_die("getsockname");
    415345        }
    416346    }
    417347    if (me.sll_halen == 0) {
    418         bb_error_msg("Interface \"%s\" is not ARPable (no ll address)", device);
    419         exit(cfg&dad ? 0 : 2);
     348        bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device);
     349        return (option_mask32 & DAD ? 0 : 2);
    420350    }
    421351    he = me;
    422352    memset(he.sll_addr, -1, he.sll_halen);
    423353
    424     if (!(cfg&quiet)) {
     354    if (!(option_mask32 & QUIET)) {
    425355        printf("ARPING to %s from %s via %s\n",
    426356            inet_ntoa(dst), inet_ntoa(src),
     
    428358    }
    429359
    430     if (!src.s_addr && !(cfg&dad)) {
     360    if (!src.s_addr && !(option_mask32 & DAD)) {
    431361        bb_error_msg_and_die("no src address in the non-DAD mode");
    432362    }
     
    447377    catcher();
    448378
     379    packet = xmalloc(4096);
    449380    while (1) {
    450381        sigset_t sset, osset;
    451         RESERVE_CONFIG_UBUFFER(packet, 4096);
    452382        struct sockaddr_ll from;
    453383        socklen_t alen = sizeof(from);
    454384        int cc;
    455385
    456         if ((cc = recvfrom(s, packet, 4096, 0,
    457                            (struct sockaddr *) &from, &alen)) < 0) {
    458             perror("recvfrom");
     386        cc = recvfrom(sock, packet, 4096, 0, (struct sockaddr *) &from, &alen);
     387        if (cc < 0) {
     388            bb_perror_msg("recvfrom");
    459389            continue;
    460390        }
     
    465395        recv_pack(packet, cc, &from);
    466396        sigprocmask(SIG_SETMASK, &osset, NULL);
    467         RELEASE_CONFIG_BUFFER(packet);
    468     }
    469 }
     397    }
     398}
Note: See TracChangeset for help on using the changeset viewer.