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

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * arpping.c
     
    67 */
    78
    8 #include <time.h>
    9 #include <sys/socket.h>
    109#include <netinet/if_ether.h>
    1110#include <net/if_arp.h>
    12 #include <netinet/in.h>
    13 #include <string.h>
    14 #include <unistd.h>
    15 #include <errno.h>
    1611
     12#include "common.h"
    1713#include "dhcpd.h"
    18 #include "arpping.h"
    19 #include "common.h"
    20 
    21 /* args:    yiaddr - what IP to ping
    22  *      ip - our ip
    23  *      mac - our arp address
    24  *      interface - interface to use
    25  * retn:    1 addr free
    26  *      0 addr used
    27  *      -1 error
    28  */
    29 
    30 /* FIXME: match response against chaddr */
    31 int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface)
    32 {
    33 
    34     int timeout = 2;
    35     int optval = 1;
    36     int s;          /* socket */
    37     int rv = 1;         /* return value */
    38     struct sockaddr addr;       /* for interface name */
    39     struct arpMsg   arp;
    40     fd_set      fdset;
    41     struct timeval  tm;
    42     time_t      prevTime;
    4314
    4415
    45     if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) {
    46 #ifdef IN_BUSYBOX
    47         LOG(LOG_ERR, bb_msg_can_not_create_raw_socket);
    48 #else
    49         LOG(LOG_ERR, "Could not open raw socket");
    50 #endif
     16struct arpMsg {
     17    /* Ethernet header */
     18    uint8_t  h_dest[6];     /* 00 destination ether addr */
     19    uint8_t  h_source[6];   /* 06 source ether addr */
     20    uint16_t h_proto;       /* 0c packet type ID field */
     21
     22    /* ARP packet */
     23    uint16_t htype;         /* 0e hardware type (must be ARPHRD_ETHER) */
     24    uint16_t ptype;         /* 10 protocol type (must be ETH_P_IP) */
     25    uint8_t  hlen;          /* 12 hardware address length (must be 6) */
     26    uint8_t  plen;          /* 13 protocol address length (must be 4) */
     27    uint16_t operation;     /* 14 ARP opcode */
     28    uint8_t  sHaddr[6];     /* 16 sender's hardware address */
     29    uint8_t  sInaddr[4];    /* 1c sender's IP address */
     30    uint8_t  tHaddr[6];     /* 20 target's hardware address */
     31    uint8_t  tInaddr[4];    /* 26 target's IP address */
     32    uint8_t  pad[18];       /* 2a pad for min. ethernet payload (60 bytes) */
     33} ATTRIBUTE_PACKED;
     34
     35
     36/* Returns 1 if no reply received */
     37
     38int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *interface)
     39{
     40    int timeout = 2;
     41    int s;                  /* socket */
     42    int rv = 1;             /* "no reply received" yet */
     43    struct sockaddr addr;   /* for interface name */
     44    struct arpMsg arp;
     45    fd_set fdset;
     46    struct timeval tm;
     47    unsigned prevTime;
     48
     49    s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
     50    if (s == -1) {
     51        bb_perror_msg(bb_msg_can_not_create_raw_socket);
    5152        return -1;
    5253    }
    5354
    54     if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) == -1) {
    55         LOG(LOG_ERR, "Could not setsocketopt on raw socket");
    56         close(s);
    57         return -1;
     55    if (setsockopt_broadcast(s) == -1) {
     56        bb_perror_msg("cannot setsocketopt on raw socket");
     57        goto ret;
    5858    }
    5959
    6060    /* send arp request */
    6161    memset(&arp, 0, sizeof(arp));
    62     memcpy(arp.h_dest, MAC_BCAST_ADDR, 6);      /* MAC DA */
    63     memcpy(arp.h_source, mac, 6);           /* MAC SA */
    64     arp.h_proto = htons(ETH_P_ARP);         /* protocol type (Ethernet) */
    65     arp.htype = htons(ARPHRD_ETHER);        /* hardware type */
    66     arp.ptype = htons(ETH_P_IP);            /* protocol type (ARP message) */
    67     arp.hlen = 6;                   /* hardware address length */
    68     arp.plen = 4;                   /* protocol address length */
    69     arp.operation = htons(ARPOP_REQUEST);       /* ARP op code */
    70     memcpy(arp.sInaddr, &ip, sizeof(ip));       /* source IP address */
    71     memcpy(arp.sHaddr, mac, 6);         /* source hardware address */
    72     memcpy(arp.tInaddr, &yiaddr, sizeof(yiaddr));   /* target IP address */
     62    memset(arp.h_dest, 0xff, 6);                    /* MAC DA */
     63    memcpy(arp.h_source, from_mac, 6);              /* MAC SA */
     64    arp.h_proto = htons(ETH_P_ARP);                 /* protocol type (Ethernet) */
     65    arp.htype = htons(ARPHRD_ETHER);                /* hardware type */
     66    arp.ptype = htons(ETH_P_IP);                    /* protocol type (ARP message) */
     67    arp.hlen = 6;                                   /* hardware address length */
     68    arp.plen = 4;                                   /* protocol address length */
     69    arp.operation = htons(ARPOP_REQUEST);           /* ARP op code */
     70    memcpy(arp.sHaddr, from_mac, 6);                /* source hardware address */
     71    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 */
    7374
    7475    memset(&addr, 0, sizeof(addr));
    75     strcpy(addr.sa_data, interface);
     76    safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
    7677    if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0)
    77         rv = 0;
     78        goto ret;
    7879
    79     /* wait arp reply, and check it */
    80     tm.tv_usec = 0;
    81     prevTime = uptime();
    82     while (timeout > 0) {
     80    /* wait for arp reply, and check it */
     81    do {
     82        int r;
     83        prevTime = monotonic_sec();
    8384        FD_ZERO(&fdset);
    8485        FD_SET(s, &fdset);
    8586        tm.tv_sec = timeout;
    86         if (select(s + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, &tm) < 0) {
    87             DEBUG(LOG_ERR, "Error on ARPING request: %m");
    88             if (errno != EINTR) rv = 0;
    89         } else if (FD_ISSET(s, &fdset)) {
    90             if (recv(s, &arp, sizeof(arp), 0) < 0 ) rv = 0;
    91             if (arp.operation == htons(ARPOP_REPLY) &&
    92                 memcmp(arp.tHaddr, mac, 6) == 0 &&
    93                 *((uint32_t *) arp.sInaddr) == yiaddr) {
    94                 DEBUG(LOG_INFO, "Valid arp reply receved for this address");
     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)
     92                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
     99            ) {
    95100                rv = 0;
    96101                break;
    97102            }
    98103        }
    99         timeout -= uptime() - prevTime;
    100         prevTime = uptime();
    101     }
     104        timeout -= monotonic_sec() - prevTime;
     105    } while (timeout > 0);
     106
     107 ret:
    102108    close(s);
    103     DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V");
     109    DEBUG("%srp reply received for this address", rv ? "No a" : "A");
    104110    return rv;
    105111}
Note: See TracChangeset for help on using the changeset viewer.