Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/networking/udhcp/arpping.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/networking/udhcp/arpping.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * arpping.c4 *5 3 * Mostly stolen from: dhcpcd - DHCP client daemon 6 4 * by Yoichi Hariguchi <yoichi@fore.com> 5 * 6 * Licensed under GPLv2, see file LICENSE in this source tree. 7 7 */ 8 9 8 #include <netinet/if_ether.h> 10 9 #include <net/if_arp.h> … … 12 11 #include "common.h" 13 12 #include "dhcpd.h" 14 15 13 16 14 struct arpMsg { … … 31 29 uint8_t tInaddr[4]; /* 26 target's IP address */ 32 30 uint8_t pad[18]; /* 2a pad for min. ethernet payload (60 bytes) */ 33 } ATTRIBUTE_PACKED;31 } PACKED; 34 32 33 enum { 34 ARP_MSG_SIZE = 0x2a 35 }; 35 36 36 37 /* 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) 38 int 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) 39 43 { 40 int timeout = 2; 41 int s; /* socket */ 44 int timeout_ms; 45 struct pollfd pfd[1]; 46 #define s (pfd[0].fd) /* socket */ 42 47 int rv = 1; /* "no reply received" yet */ 43 48 struct sockaddr addr; /* for interface name */ 44 49 struct arpMsg arp; 45 fd_set fdset;46 struct timeval tm;47 unsigned prevTime;48 50 49 51 s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); … … 54 56 55 57 if (setsockopt_broadcast(s) == -1) { 56 bb_perror_msg("can not setsocketopt on raw socket");58 bb_perror_msg("can't enable bcast on raw socket"); 57 59 goto ret; 58 60 } … … 70 72 memcpy(arp.sHaddr, from_mac, 6); /* source hardware address */ 71 73 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 */ 74 76 75 77 memset(&addr, 0, sizeof(addr)); 76 78 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. 78 82 goto ret; 83 } 79 84 80 85 /* wait for arp reply, and check it */ 86 timeout_ms = 2000; 81 87 do { 88 typedef uint32_t aliased_uint32_t FIX_ALIASING; 82 89 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) 92 99 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 99 110 ) { 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"); 101 118 break; 102 119 } 103 120 } 104 timeout -= monotonic_sec() - prevTime;105 } while (timeout > 0);121 timeout_ms -= (unsigned)monotonic_ms() - prevTime; 122 } while (timeout_ms > 0); 106 123 107 124 ret: 108 125 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"); 110 127 return rv; 111 128 }
Note:
See TracChangeset
for help on using the changeset viewer.