Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/networking/udhcp/arpping.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 4  Line 4 
4   *   *
5   * Mostly stolen from: dhcpcd - DHCP client daemon   * Mostly stolen from: dhcpcd - DHCP client daemon
6   * by Yoichi Hariguchi <yoichi@fore.com>   * by Yoichi Hariguchi <yoichi@fore.com>
7     *
8     * Licensed under GPLv2, see file LICENSE in this tarball for details.
9   */   */
   
10  #include <netinet/if_ether.h>  #include <netinet/if_ether.h>
11  #include <net/if_arp.h>  #include <net/if_arp.h>
12    
13  #include "common.h"  #include "common.h"
14  #include "dhcpd.h"  #include "dhcpd.h"
15    
   
16  struct arpMsg {  struct arpMsg {
17   /* Ethernet header */   /* Ethernet header */
18   uint8_t  h_dest[6];     /* 00 destination ether addr */   uint8_t  h_dest[6];     /* 00 destination ether addr */
# Line 36  enum { Line 36  enum {
36   ARP_MSG_SIZE = 0x2a   ARP_MSG_SIZE = 0x2a
37  };  };
38    
   
39  /* Returns 1 if no reply received */  /* Returns 1 if no reply received */
40    int FAST_FUNC arpping(uint32_t test_nip,
41  int FAST_FUNC arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *interface)   const uint8_t *safe_mac,
42     uint32_t from_ip,
43     uint8_t *from_mac,
44     const char *interface)
45  {  {
46   int timeout_ms;   int timeout_ms;
47   struct pollfd pfd[1];   struct pollfd pfd[1];
# Line 55  int FAST_FUNC arpping(uint32_t test_ip, Line 57  int FAST_FUNC arpping(uint32_t test_ip,
57   }   }
58    
59   if (setsockopt_broadcast(s) == -1) {   if (setsockopt_broadcast(s) == -1) {
60   bb_perror_msg("cannot enable bcast on raw socket");   bb_perror_msg("can't enable bcast on raw socket");
61   goto ret;   goto ret;
62   }   }
63    
# Line 71  int FAST_FUNC arpping(uint32_t test_ip, Line 73  int FAST_FUNC arpping(uint32_t test_ip,
73   arp.operation = htons(ARPOP_REQUEST);           /* ARP op code */   arp.operation = htons(ARPOP_REQUEST);           /* ARP op code */
74   memcpy(arp.sHaddr, from_mac, 6);                /* source hardware address */   memcpy(arp.sHaddr, from_mac, 6);                /* source hardware address */
75   memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */   memcpy(arp.sInaddr, &from_ip, sizeof(from_ip)); /* source IP address */
76   /* tHaddr is zero-fiiled */                     /* target hardware address */   /* tHaddr is zero-filled */                     /* target hardware address */
77   memcpy(arp.tInaddr, &test_ip, sizeof(test_ip)); /* target IP address */   memcpy(arp.tInaddr, &test_nip, sizeof(test_nip));/* target IP address */
78    
79   memset(&addr, 0, sizeof(addr));   memset(&addr, 0, sizeof(addr));
80   safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));   safe_strncpy(addr.sa_data, interface, sizeof(addr.sa_data));
# Line 86  int FAST_FUNC arpping(uint32_t test_ip, Line 88  int FAST_FUNC arpping(uint32_t test_ip,
88   timeout_ms = 2000;   timeout_ms = 2000;
89   do {   do {
90   int r;   int r;
91   unsigned prevTime = monotonic_us();   unsigned prevTime = monotonic_ms();
92    
93   pfd[0].events = POLLIN;   pfd[0].events = POLLIN;
94   r = safe_poll(pfd, 1, timeout_ms);   r = safe_poll(pfd, 1, timeout_ms);
95   if (r < 0)   if (r < 0)
96   break;   break;
97   if (r) {   if (r) {
98   r = read(s, &arp, sizeof(arp));   r = safe_read(s, &arp, sizeof(arp));
99   if (r < 0)   if (r < 0)
100   break;   break;
101    
102     //log3("sHaddr %02x:%02x:%02x:%02x:%02x:%02x",
103     // arp.sHaddr[0], arp.sHaddr[1], arp.sHaddr[2],
104     // arp.sHaddr[3], arp.sHaddr[4], arp.sHaddr[5]);
105    
106   if (r >= ARP_MSG_SIZE   if (r >= ARP_MSG_SIZE
107   && arp.operation == htons(ARPOP_REPLY)   && arp.operation == htons(ARPOP_REPLY)
108   /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */   /* don't check it: Linux doesn't return proper tHaddr (fixed in 2.6.24?) */
109   /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */   /* && memcmp(arp.tHaddr, from_mac, 6) == 0 */
110   && *((uint32_t *) arp.sInaddr) == test_ip   && *((uint32_t *) arp.sInaddr) == test_nip
111   ) {   ) {
112   rv = 0;   /* if ARP source MAC matches safe_mac
113     * (which is client's MAC), then it's not a conflict
114     * (client simply already has this IP and replies to ARPs!)
115     */
116     if (!safe_mac || memcmp(safe_mac, arp.sHaddr, 6) != 0)
117     rv = 0;
118     //else log2("sHaddr == safe_mac");
119   break;   break;
120   }   }
121   }   }
122   timeout_ms -= ((unsigned)monotonic_us() - prevTime) / 1000;   timeout_ms -= (unsigned)monotonic_ms() - prevTime;
123   } while (timeout_ms > 0);   } while (timeout_ms > 0);
124    
125   ret:   ret:
126   close(s);   close(s);
127   DEBUG("%srp reply received for this address", rv ? "No a" : "A");   log1("%srp reply received for this address", rv ? "No a" : "A");
128   return rv;   return rv;
129  }  }

Legend:
Removed from v.983  
changed lines
  Added in v.984