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

    r1765 r2725  
    1212 * Mike Muuss.
    1313 *
    14  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     14 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1515 */
    1616/* from ping6.c:
     
    3131
    3232#if ENABLE_PING6
    33 #include <netinet/icmp6.h>
     33# include <netinet/icmp6.h>
    3434/* I see RENUMBERED constants in bits/in.h - !!?
    3535 * What a fuck is going on with libc? Is it a glibc joke? */
    36 #ifdef IPV6_2292HOPLIMIT
    37 #undef IPV6_HOPLIMIT
    38 #define IPV6_HOPLIMIT IPV6_2292HOPLIMIT
    39 #endif
     36# ifdef IPV6_2292HOPLIMIT
     37#  undef IPV6_HOPLIMIT
     38#  define IPV6_HOPLIMIT IPV6_2292HOPLIMIT
     39# endif
    4040#endif
    4141
     
    4444    MAXIPLEN = 60,
    4545    MAXICMPLEN = 76,
    46     MAXPACKET = 65468,
    4746    MAX_DUP_CHK = (8 * 128),
    4847    MAXWAIT = 10,
     
    5049};
    5150
    52 /* common routines */
     51/* Common routines */
    5352
    5453static int in_cksum(unsigned short *buf, int sz)
     
    7776#if !ENABLE_FEATURE_FANCY_PING
    7877
    79 /* simple version */
    80 
    81 static char *hostname;
    82 
    83 static void noresp(int ign ATTRIBUTE_UNUSED)
    84 {
    85     printf("No response from %s\n", hostname);
     78/* Simple version */
     79
     80struct globals {
     81    char *hostname;
     82    char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
     83} FIX_ALIASING;
     84#define G (*(struct globals*)&bb_common_bufsiz1)
     85#define INIT_G() do { } while (0)
     86
     87static void noresp(int ign UNUSED_PARAM)
     88{
     89    printf("No response from %s\n", G.hostname);
    8690    exit(EXIT_FAILURE);
    8791}
     
    8993static void ping4(len_and_sockaddr *lsa)
    9094{
    91     struct sockaddr_in pingaddr;
    9295    struct icmp *pkt;
    9396    int pingsock, c;
    94     char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
    9597
    9698    pingsock = create_icmp_socket();
    97     pingaddr = lsa->sin;
    98 
    99     pkt = (struct icmp *) packet;
    100     memset(pkt, 0, sizeof(packet));
     99
     100    pkt = (struct icmp *) G.packet;
     101    memset(pkt, 0, sizeof(G.packet));
    101102    pkt->icmp_type = ICMP_ECHO;
    102     pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet));
    103 
    104     c = xsendto(pingsock, packet, DEFDATALEN + ICMP_MINLEN,
    105                (struct sockaddr *) &pingaddr, sizeof(pingaddr));
     103    pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(G.packet));
     104
     105    xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len);
    106106
    107107    /* listen for replies */
     
    110110        socklen_t fromlen = sizeof(from);
    111111
    112         c = recvfrom(pingsock, packet, sizeof(packet), 0,
     112        c = recvfrom(pingsock, G.packet, sizeof(G.packet), 0,
    113113                (struct sockaddr *) &from, &fromlen);
    114114        if (c < 0) {
     
    118118        }
    119119        if (c >= 76) {          /* ip + icmp */
    120             struct iphdr *iphdr = (struct iphdr *) packet;
    121 
    122             pkt = (struct icmp *) (packet + (iphdr->ihl << 2)); /* skip ip hdr */
     120            struct iphdr *iphdr = (struct iphdr *) G.packet;
     121
     122            pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2));   /* skip ip hdr */
    123123            if (pkt->icmp_type == ICMP_ECHOREPLY)
    124124                break;
     
    132132static void ping6(len_and_sockaddr *lsa)
    133133{
    134     struct sockaddr_in6 pingaddr;
    135134    struct icmp6_hdr *pkt;
    136135    int pingsock, c;
    137136    int sockopt;
    138     char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
    139137
    140138    pingsock = create_icmp6_socket();
    141     pingaddr = lsa->sin6;
    142 
    143     pkt = (struct icmp6_hdr *) packet;
    144     memset(pkt, 0, sizeof(packet));
     139
     140    pkt = (struct icmp6_hdr *) G.packet;
     141    memset(pkt, 0, sizeof(G.packet));
    145142    pkt->icmp6_type = ICMP6_ECHO_REQUEST;
    146143
     
    148145    setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt));
    149146
    150     c = xsendto(pingsock, packet, DEFDATALEN + sizeof (struct icmp6_hdr),
    151                (struct sockaddr *) &pingaddr, sizeof(pingaddr));
     147    xsendto(pingsock, G.packet, DEFDATALEN + sizeof(struct icmp6_hdr), &lsa->u.sa, lsa->len);
    152148
    153149    /* listen for replies */
     
    156152        socklen_t fromlen = sizeof(from);
    157153
    158         c = recvfrom(pingsock, packet, sizeof(packet), 0,
     154        c = recvfrom(pingsock, G.packet, sizeof(G.packet), 0,
    159155                (struct sockaddr *) &from, &fromlen);
    160156        if (c < 0) {
     
    163159            continue;
    164160        }
    165         if (c >= 8) {           /* icmp6_hdr */
    166             pkt = (struct icmp6_hdr *) packet;
     161        if (c >= ICMP_MINLEN) {         /* icmp6_hdr */
     162            pkt = (struct icmp6_hdr *) G.packet;
    167163            if (pkt->icmp6_type == ICMP6_ECHO_REPLY)
    168164                break;
     
    174170#endif
    175171
    176 int ping_main(int argc, char **argv);
    177 int ping_main(int argc, char **argv)
     172#if !ENABLE_PING6
     173# define common_ping_main(af, argv) common_ping_main(argv)
     174#endif
     175static int common_ping_main(sa_family_t af, char **argv)
    178176{
    179177    len_and_sockaddr *lsa;
    180 #if ENABLE_PING6
    181     sa_family_t af = AF_UNSPEC;
    182 
     178
     179    INIT_G();
     180
     181#if ENABLE_PING6
    183182    while ((++argv)[0] && argv[0][0] == '-') {
    184183        if (argv[0][1] == '4') {
     
    196195#endif
    197196
    198     hostname = *argv;
    199     if (!hostname)
     197    G.hostname = *argv;
     198    if (!G.hostname)
    200199        bb_show_usage();
    201200
    202201#if ENABLE_PING6
    203     lsa = xhost_and_af2sockaddr(hostname, 0, af);
     202    lsa = xhost_and_af2sockaddr(G.hostname, 0, af);
    204203#else
    205     lsa = xhost_and_af2sockaddr(hostname, 0, AF_INET);
     204    lsa = xhost_and_af2sockaddr(G.hostname, 0, AF_INET);
    206205#endif
    207206    /* Set timer _after_ DNS resolution */
     
    210209
    211210#if ENABLE_PING6
    212     if (lsa->sa.sa_family == AF_INET6)
     211    if (lsa->u.sa.sa_family == AF_INET6)
    213212        ping6(lsa);
    214213    else
    215214#endif
    216215        ping4(lsa);
    217     printf("%s is alive!\n", hostname);
     216    printf("%s is alive!\n", G.hostname);
    218217    return EXIT_SUCCESS;
    219218}
     
    223222
    224223
    225 /* full(er) version */
    226 
    227 #define OPT_STRING ("qvc:s:I:4" USE_PING6("6"))
     224/* Full(er) version */
     225
     226#define OPT_STRING ("qvc:s:w:W:I:4" IF_PING6("6"))
    228227enum {
    229228    OPT_QUIET = 1 << 0,
     
    231230    OPT_c = 1 << 2,
    232231    OPT_s = 1 << 3,
    233     OPT_I = 1 << 4,
    234     OPT_IPV4 = 1 << 5,
    235     OPT_IPV6 = (1 << 6) * ENABLE_PING6,
     232    OPT_w = 1 << 4,
     233    OPT_W = 1 << 5,
     234    OPT_I = 1 << 6,
     235    OPT_IPV4 = 1 << 7,
     236    OPT_IPV6 = (1 << 8) * ENABLE_PING6,
    236237};
    237238
     
    239240struct globals {
    240241    int pingsock;
     242    int if_index;
     243    char *str_I;
    241244    len_and_sockaddr *source_lsa;
    242245    unsigned datalen;
    243     int if_index;
    244     unsigned long ntransmitted, nreceived, nrepeats, pingcount;
     246    unsigned pingcount; /* must be int-sized */
     247    unsigned long ntransmitted, nreceived, nrepeats;
    245248    uint16_t myid;
    246249    unsigned tmin, tmax; /* in us */
    247250    unsigned long long tsum; /* in us, sum of all times */
     251    unsigned deadline;
     252    unsigned timeout;
     253    unsigned total_secs;
     254    unsigned sizeof_rcv_packet;
     255    char *rcv_packet; /* [datalen + MAXIPLEN + MAXICMPLEN] */
     256    void *snd_packet; /* [datalen + ipv4/ipv6_const] */
    248257    const char *hostname;
    249258    const char *dotted;
     
    256265    } pingaddr;
    257266    char rcvd_tbl[MAX_DUP_CHK / 8];
    258 };
     267} FIX_ALIASING;
    259268#define G (*(struct globals*)&bb_common_bufsiz1)
    260269#define pingsock     (G.pingsock    )
     270#define if_index     (G.if_index    )
    261271#define source_lsa   (G.source_lsa  )
     272#define str_I        (G.str_I       )
    262273#define datalen      (G.datalen     )
    263 #define if_index     (G.if_index    )
    264274#define ntransmitted (G.ntransmitted)
    265275#define nreceived    (G.nreceived   )
     
    270280#define tmax         (G.tmax        )
    271281#define tsum         (G.tsum        )
     282#define deadline     (G.deadline    )
     283#define timeout      (G.timeout     )
     284#define total_secs   (G.total_secs  )
    272285#define hostname     (G.hostname    )
    273286#define dotted       (G.dotted      )
     
    276289void BUG_ping_globals_too_big(void);
    277290#define INIT_G() do { \
    278         if (sizeof(G) > COMMON_BUFSIZE) \
    279                 BUG_ping_globals_too_big(); \
     291    if (sizeof(G) > COMMON_BUFSIZE) \
     292        BUG_ping_globals_too_big(); \
    280293    pingsock = -1; \
     294    datalen = DEFDATALEN; \
     295    timeout = MAXWAIT; \
    281296    tmin = UINT_MAX; \
    282297} while (0)
    283298
    284299
    285 #define A(bit)      rcvd_tbl[(bit)>>3]  /* identify byte in array */
    286 #define B(bit)      (1 << ((bit) & 0x07))   /* identify bit in byte */
    287 #define SET(bit)    (A(bit) |= B(bit))
    288 #define CLR(bit)    (A(bit) &= (~B(bit)))
    289 #define TST(bit)    (A(bit) & B(bit))
     300#define A(bit)      rcvd_tbl[(bit)>>3]  /* identify byte in array */
     301#define B(bit)      (1 << ((bit) & 0x07))   /* identify bit in byte */
     302#define SET(bit)    (A(bit) |= B(bit))
     303#define CLR(bit)    (A(bit) &= (~B(bit)))
     304#define TST(bit)    (A(bit) & B(bit))
    290305
    291306/**************************************************************************/
    292307
    293 static void pingstats(int junk ATTRIBUTE_UNUSED)
     308static void print_stats_and_exit(int junk) NORETURN;
     309static void print_stats_and_exit(int junk UNUSED_PARAM)
    294310{
    295311    signal(SIGINT, SIG_IGN);
     
    310326            tmax / 1000, tmax % 1000);
    311327    }
    312     exit(nreceived == 0); /* (nreceived == 0) is true (1) -- 'failure' */
     328    /* if condition is true, exit with 1 -- 'failure' */
     329    exit(nreceived == 0 || (deadline && nreceived < pingcount));
    313330}
    314331
     
    326343        bb_error_msg_and_die(bb_msg_write_error);
    327344
    328     signal(SIGALRM, sp);
    329     if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */
     345    if (pingcount == 0 || deadline || ntransmitted < pingcount) {
     346        /* Didn't send all pings yet - schedule next in 1s */
     347        signal(SIGALRM, sp);
     348        if (deadline) {
     349            total_secs += PINGINTERVAL;
     350            if (total_secs >= deadline)
     351                signal(SIGALRM, print_stats_and_exit);
     352        }
    330353        alarm(PINGINTERVAL);
    331     } else { /* done, wait for the last ping to come back */
    332         /* todo, don't necessarily need to wait so long... */
    333         signal(SIGALRM, pingstats);
    334         alarm(MAXWAIT);
    335     }
    336 }
    337 
    338 static void sendping4(int junk ATTRIBUTE_UNUSED)
    339 {
    340     /* +4 reserves a place for timestamp, which may end up sitting
    341      * *after* packet. Saves one if() */
    342     struct icmp *pkt = alloca(datalen + ICMP_MINLEN + 4);
    343 
     354    } else { /* -c NN, and all NN are sent (and no deadline) */
     355        /* Wait for the last ping to come back.
     356         * -W timeout: wait for a response in seconds.
     357         * Affects only timeout in absense of any responses,
     358         * otherwise ping waits for two RTTs. */
     359        unsigned expire = timeout;
     360
     361        if (nreceived) {
     362            /* approx. 2*tmax, in seconds (2 RTT) */
     363            expire = tmax / (512*1024);
     364            if (expire == 0)
     365                expire = 1;
     366        }
     367        signal(SIGALRM, print_stats_and_exit);
     368        alarm(expire);
     369    }
     370}
     371
     372static void sendping4(int junk UNUSED_PARAM)
     373{
     374    struct icmp *pkt = G.snd_packet;
     375
     376    //memset(pkt, 0, datalen + ICMP_MINLEN + 4); - G.snd_packet was xzalloced
    344377    pkt->icmp_type = ICMP_ECHO;
    345     pkt->icmp_code = 0;
    346     pkt->icmp_cksum = 0;
     378    /*pkt->icmp_code = 0;*/
     379    pkt->icmp_cksum = 0; /* cksum is calculated with this field set to 0 */
    347380    pkt->icmp_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */
    348381    pkt->icmp_id = myid;
    349382
    350     /* We don't do hton, because we will read it back on the same machine */
     383    /* If datalen < 4, we store timestamp _past_ the packet,
     384     * but it's ok - we allocated 4 extra bytes in xzalloc() just in case.
     385     */
    351386    /*if (datalen >= 4)*/
     387        /* No hton: we'll read it back on the same machine */
    352388        *(uint32_t*)&pkt->icmp_dun = monotonic_us();
    353389
     
    357393}
    358394#if ENABLE_PING6
    359 static void sendping6(int junk ATTRIBUTE_UNUSED)
    360 {
    361     struct icmp6_hdr *pkt = alloca(datalen + sizeof(struct icmp6_hdr) + 4);
    362 
     395static void sendping6(int junk UNUSED_PARAM)
     396{
     397    struct icmp6_hdr *pkt = G.snd_packet;
     398
     399    //memset(pkt, 0, datalen + sizeof(struct icmp6_hdr) + 4);
    363400    pkt->icmp6_type = ICMP6_ECHO_REQUEST;
    364     pkt->icmp6_code = 0;
    365     pkt->icmp6_cksum = 0;
     401    /*pkt->icmp6_code = 0;*/
     402    /*pkt->icmp6_cksum = 0;*/
    366403    pkt->icmp6_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */
    367404    pkt->icmp6_id = myid;
     
    369406    /*if (datalen >= 4)*/
    370407        *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us();
     408
     409    //TODO? pkt->icmp_cksum = in_cksum(...);
    371410
    372411    sendping_tail(sendping6, pkt, datalen + sizeof(struct icmp6_hdr));
     
    458497        printf(" time=%u.%03u ms", triptime / 1000, triptime % 1000);
    459498    puts(dupmsg);
    460     fflush(stdout);
     499    fflush_all();
    461500}
    462501static void unpack4(char *buf, int sz, struct sockaddr_in *from)
     
    494533}
    495534#if ENABLE_PING6
    496 static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit)
     535static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/ int hoplimit)
    497536{
    498537    struct icmp6_hdr *icmppkt;
     
    527566static void ping4(len_and_sockaddr *lsa)
    528567{
    529     char packet[datalen + MAXIPLEN + MAXICMPLEN];
    530568    int sockopt;
    531569
    532570    pingsock = create_icmp_socket();
    533     pingaddr.sin = lsa->sin;
     571    pingaddr.sin = lsa->u.sin;
    534572    if (source_lsa) {
    535573        if (setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_IF,
    536                 &source_lsa->sa, source_lsa->len))
     574                &source_lsa->u.sa, source_lsa->len))
    537575            bb_error_msg_and_die("can't set multicast source interface");
    538         xbind(pingsock, &source_lsa->sa, source_lsa->len);
    539     }
     576        xbind(pingsock, &source_lsa->u.sa, source_lsa->len);
     577    }
     578    if (str_I)
     579        setsockopt_bindtodevice(pingsock, str_I);
    540580
    541581    /* enable broadcast pings */
    542582    setsockopt_broadcast(pingsock);
    543583
    544     /* set recv buf for broadcast pings */
    545     sockopt = 48 * 1024; /* explain why 48k? */
     584    /* set recv buf (needed if we can get lots of responses: flood ping,
     585     * broadcast ping etc) */
     586    sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */
    546587    setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));
    547588
    548     signal(SIGINT, pingstats);
     589    signal(SIGINT, print_stats_and_exit);
    549590
    550591    /* start the ping's going ... */
     
    557598        int c;
    558599
    559         c = recvfrom(pingsock, packet, sizeof(packet), 0,
     600        c = recvfrom(pingsock, G.rcv_packet, G.sizeof_rcv_packet, 0,
    560601                (struct sockaddr *) &from, &fromlen);
    561602        if (c < 0) {
     
    564605            continue;
    565606        }
    566         unpack4(packet, c, &from);
    567         if (pingcount > 0 && nreceived >= pingcount)
     607        unpack4(G.rcv_packet, c, &from);
     608        if (pingcount && nreceived >= pingcount)
    568609            break;
    569610    }
     
    573614static void ping6(len_and_sockaddr *lsa)
    574615{
    575     char packet[datalen + MAXIPLEN + MAXICMPLEN];
    576616    int sockopt;
    577617    struct msghdr msg;
     
    581621
    582622    pingsock = create_icmp6_socket();
    583     pingaddr.sin6 = lsa->sin6;
     623    pingaddr.sin6 = lsa->u.sin6;
    584624    /* untested whether "-I addr" really works for IPv6: */
    585625    if (source_lsa)
    586         xbind(pingsock, &source_lsa->sa, source_lsa->len);
     626        xbind(pingsock, &source_lsa->u.sa, source_lsa->len);
     627    if (str_I)
     628        setsockopt_bindtodevice(pingsock, str_I);
    587629
    588630#ifdef ICMP6_FILTER
     
    604646    setsockopt_broadcast(pingsock);
    605647
    606     /* set recv buf for broadcast pings */
    607     sockopt = 48 * 1024; /* explain why 48k? */
     648    /* set recv buf (needed if we can get lots of responses: flood ping,
     649     * broadcast ping etc) */
     650    sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */
    608651    setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));
    609652
     
    619662        pingaddr.sin6.sin6_scope_id = if_index;
    620663
    621     signal(SIGINT, pingstats);
     664    signal(SIGINT, print_stats_and_exit);
    622665
    623666    /* start the ping's going ... */
     
    630673    msg.msg_iovlen = 1;
    631674    msg.msg_control = control_buf;
    632     iov.iov_base = packet;
    633     iov.iov_len = sizeof(packet);
     675    iov.iov_base = G.rcv_packet;
     676    iov.iov_len = G.sizeof_rcv_packet;
    634677    while (1) {
    635678        int c;
     
    650693             /* && mp->cmsg_len >= CMSG_LEN(sizeof(int)) */
    651694            ) {
    652                 hoplimit = *(int*)CMSG_DATA(mp);
     695                /*hoplimit = *(int*)CMSG_DATA(mp); - unaligned access */
     696                move_from_unaligned_int(hoplimit, CMSG_DATA(mp));
    653697            }
    654698        }
    655         unpack6(packet, c, &from, hoplimit);
    656         if (pingcount > 0 && nreceived >= pingcount)
     699        unpack6(G.rcv_packet, c, /*&from,*/ hoplimit);
     700        if (pingcount && nreceived >= pingcount)
    657701            break;
    658702    }
     
    665709    if (source_lsa) {
    666710        printf(" from %s",
    667             xmalloc_sockaddr2dotted_noport(&source_lsa->sa));
     711            xmalloc_sockaddr2dotted_noport(&source_lsa->u.sa));
    668712    }
    669713    printf(": %d data bytes\n", datalen);
    670714
    671 #if ENABLE_PING6
    672     if (lsa->sa.sa_family == AF_INET6)
     715    G.sizeof_rcv_packet = datalen + MAXIPLEN + MAXICMPLEN;
     716    G.rcv_packet = xzalloc(G.sizeof_rcv_packet);
     717#if ENABLE_PING6
     718    if (lsa->u.sa.sa_family == AF_INET6) {
     719        /* +4 reserves a place for timestamp, which may end up sitting
     720         * _after_ packet. Saves one if() - see sendping4/6() */
     721        G.snd_packet = xzalloc(datalen + sizeof(struct icmp6_hdr) + 4);
    673722        ping6(lsa);
    674     else
    675 #endif
     723    } else
     724#endif
     725    {
     726        G.snd_packet = xzalloc(datalen + ICMP_MINLEN + 4);
    676727        ping4(lsa);
    677 }
    678 
    679 int ping_main(int argc, char **argv);
    680 int ping_main(int argc, char **argv)
     728    }
     729}
     730
     731static int common_ping_main(int opt, char **argv)
    681732{
    682733    len_and_sockaddr *lsa;
    683     char *opt_c, *opt_s, *opt_I;
    684     USE_PING6(sa_family_t af = AF_UNSPEC;)
     734    char *str_s;
    685735
    686736    INIT_G();
    687737
    688     datalen = DEFDATALEN; /* initialized here rather than in global scope to work around gcc bug */
    689 
    690     /* exactly one argument needed, -v and -q don't mix */
    691     opt_complementary = "=1:q--v:v--q";
    692     getopt32(argv, OPT_STRING, &opt_c, &opt_s, &opt_I);
    693     if (option_mask32 & OPT_c) pingcount = xatoul(opt_c); // -c
    694     if (option_mask32 & OPT_s) datalen = xatou16(opt_s); // -s
    695     if (option_mask32 & OPT_I) { // -I
    696         if_index = if_nametoindex(opt_I);
     738    /* exactly one argument needed; -v and -q don't mix; -c NUM, -w NUM, -W NUM */
     739    opt_complementary = "=1:q--v:v--q:c+:w+:W+";
     740    opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &deadline, &timeout, &str_I);
     741    if (opt & OPT_s)
     742        datalen = xatou16(str_s); // -s
     743    if (opt & OPT_I) { // -I
     744        if_index = if_nametoindex(str_I);
    697745        if (!if_index) {
    698746            /* TODO: I'm not sure it takes IPv6 unless in [XX:XX..] format */
    699             source_lsa = xdotted2sockaddr(opt_I, 0);
     747            source_lsa = xdotted2sockaddr(str_I, 0);
     748            str_I = NULL; /* don't try to bind to device later */
    700749        }
    701750    }
     
    703752    hostname = argv[optind];
    704753#if ENABLE_PING6
    705     if (option_mask32 & OPT_IPV4)
    706         af = AF_INET;
    707     if (option_mask32 & OPT_IPV6)
    708         af = AF_INET6;
    709     lsa = xhost_and_af2sockaddr(hostname, 0, af);
     754    {
     755        sa_family_t af = AF_UNSPEC;
     756        if (opt & OPT_IPV4)
     757            af = AF_INET;
     758        if (opt & OPT_IPV6)
     759            af = AF_INET6;
     760        lsa = xhost_and_af2sockaddr(hostname, 0, af);
     761    }
    710762#else
    711763    lsa = xhost_and_af2sockaddr(hostname, 0, AF_INET);
    712764#endif
    713765
    714     if (source_lsa && source_lsa->sa.sa_family != lsa->sa.sa_family)
     766    if (source_lsa && source_lsa->u.sa.sa_family != lsa->u.sa.sa_family)
    715767        /* leaking it here... */
    716768        source_lsa = NULL;
    717769
    718     dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa);
     770    dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
    719771    ping(lsa);
    720     pingstats(0);
    721     return EXIT_SUCCESS;
     772    print_stats_and_exit(EXIT_SUCCESS);
     773    /*return EXIT_SUCCESS;*/
    722774}
    723775#endif /* FEATURE_FANCY_PING */
    724776
    725777
    726 #if ENABLE_PING6
    727 int ping6_main(int argc, char **argv);
    728 int ping6_main(int argc, char **argv)
    729 {
    730     argv[0] = (char*)"-6";
    731     return ping_main(argc + 1, argv - 1);
     778int ping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     779int ping_main(int argc UNUSED_PARAM, char **argv)
     780{
     781#if !ENABLE_FEATURE_FANCY_PING
     782    return common_ping_main(AF_UNSPEC, argv);
     783#else
     784    return common_ping_main(0, argv);
     785#endif
     786}
     787
     788#if ENABLE_PING6
     789int ping6_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     790int ping6_main(int argc UNUSED_PARAM, char **argv)
     791{
     792# if !ENABLE_FEATURE_FANCY_PING
     793    return common_ping_main(AF_INET6, argv);
     794# else
     795    return common_ping_main(OPT_IPV6, argv);
     796# endif
    732797}
    733798#endif
Note: See TracChangeset for help on using the changeset viewer.