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/udhcp/arpping.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * arpping.c
    4  *
    53 * Mostly stolen from: dhcpcd - DHCP client daemon
    64 * by Yoichi Hariguchi <yoichi@fore.com>
     5 *
     6 * Licensed under GPLv2, see file LICENSE in this source tree.
    77 */
    8 
    98#include <netinet/if_ether.h>
    109#include <net/if_arp.h>
     
    1211#include "common.h"
    1312#include "dhcpd.h"
    14 
    1513
    1614struct arpMsg {
     
    3129    uint8_t  tInaddr[4];    /* 26 target's IP address */
    3230    uint8_t  pad[18];       /* 2a pad for min. ethernet payload (60 bytes) */
    33 } ATTRIBUTE_PACKED;
     31} PACKED;
    3432
     33enum {
     34    ARP_MSG_SIZE = 0x2a
     35};
    3536
    3637/* Returns 1 if no reply received */
    37 
    38 int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *interface)
     38int FAST_FUNC arpping(uint32_t test_nip,
     39        const uint8_t *safe_mac,
     40        uint32_t from_ip,
     41        uint8_t *from_mac,
     42        const char *interface)
    3943{
    40     int timeout = 2;
    41     int s;                  /* socket */
     44    int timeout_ms;
     45    struct pollfd pfd[1];
     46#define s (pfd[0].fd)           /* socket */
    4247    int rv = 1;             /* "no reply received" yet */
    4348    struct sockaddr addr;   /* for interface name */
    4449    struct arpMsg arp;
    45     fd_set fdset;
    46     struct timeval tm;
    47     unsigned prevTime;
    4850
    4951    s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
     
    5456
    5557    if (setsockopt_broadcast(s) == -1) {
    56         bb_perror_msg("cannot setsocketopt on raw socket");
     58        bb_perror_msg("can't enable bcast on raw socket");
    5759        goto ret;
    5860    }
     
    7072    memcpy(arp.sHaddr, from_mac, 6);                /* source hardware address */
    7173    memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */
    72     /* tHaddr */                                    /* target hardware address */
    73     memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */
     74    /* tHaddr is zero-filled */                     /* target hardware address */
     75    memcpy(arp.tInaddr, &test_nip, sizeof(test_nip));/* target IP address */
    7476
    7577    memset(&addr, 0, sizeof(addr));
    7678    safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
    77     if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0)
     79    if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) {
     80        // TODO: error message? caller didn't expect us to fail,
     81        // just returning 1 "no reply received" misleads it.
    7882        goto ret;
     83    }
    7984
    8085    /* wait for arp reply, and check it */
     86    timeout_ms = 2000;
    8187    do {
     88        typedef uint32_t aliased_uint32_t FIX_ALIASING;
    8289        int r;
    83         prevTime = monotonic_sec();
    84         FD_ZERO(&fdset);
    85         FD_SET(s, &fdset);
    86         tm.tv_sec = timeout;
    87         tm.tv_usec = 0;
    88         r = select(s + 1, &fdset, NULL, NULL, &tm);
    89         if (r < 0) {
    90             bb_perror_msg("error on ARPING request");
    91             if (errno != EINTR)
     90        unsigned prevTime = monotonic_ms();
     91
     92        pfd[0].events = POLLIN;
     93        r = safe_poll(pfd, 1, timeout_ms);
     94        if (r < 0)
     95            break;
     96        if (r) {
     97            r = safe_read(s, &arp, sizeof(arp));
     98            if (r < 0)
    9299                break;
    93         } else if (r) {
    94             if (recv(s, &arp, sizeof(arp), 0) < 0)
    95                 break;
    96             if (arp.operation == htons(ARPOP_REPLY)
    97              && memcmp(arp.tHaddr, from_mac, 6) == 0
    98              && *((uint32_t *) arp.sInaddr) == test_ip
     100
     101            //log3("sHaddr %02x:%02x:%02x:%02x:%02x:%02x",
     102            //  arp.sHaddr[0], arp.sHaddr[1], arp.sHaddr[2],
     103            //  arp.sHaddr[3], arp.sHaddr[4], arp.sHaddr[5]);
     104
     105            if (r >= ARP_MSG_SIZE
     106             && arp.operation == htons(ARPOP_REPLY)
     107             /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */
     108             /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */
     109             && *(aliased_uint32_t*)arp.sInaddr == test_nip
    99110            ) {
    100                 rv = 0;
     111                /* if ARP source MAC matches safe_mac
     112                 * (which is client's MAC), then it's not a conflict
     113                 * (client simply already has this IP and replies to ARPs!)
     114                 */
     115                if (!safe_mac || memcmp(safe_mac, arp.sHaddr, 6) != 0)
     116                    rv = 0;
     117                //else log2("sHaddr == safe_mac");
    101118                break;
    102119            }
    103120        }
    104         timeout -= monotonic_sec() - prevTime;
    105     } while (timeout > 0);
     121        timeout_ms -= (unsigned)monotonic_ms() - prevTime;
     122    } while (timeout_ms > 0);
    106123
    107124 ret:
    108125    close(s);
    109     DEBUG("%srp reply received for this address", rv ? "No a" : "A");
     126    log1("%srp reply received for this address", rv ? "No a" : "A");
    110127    return rv;
    111128}
Note: See TracChangeset for help on using the changeset viewer.