|
Lines 24-30
Link Here
|
| 24 |
#include <sys/select.h> |
24 |
#include <sys/select.h> |
| 25 |
#include <sys/socket.h> |
25 |
#include <sys/socket.h> |
| 26 |
#include <netinet/in_systm.h> |
26 |
#include <netinet/in_systm.h> |
| 27 |
#ifdef __linux |
27 |
#ifdef __linux__ |
| 28 |
#include <netinet/ether.h> |
28 |
#include <netinet/ether.h> |
| 29 |
#include <netpacket/packet.h> |
29 |
#include <netpacket/packet.h> |
| 30 |
#endif |
30 |
#endif |
|
Lines 76-81
Link Here
|
| 76 |
int arpsize = arphdr_len2 (iface->hwlen, sizeof (struct in_addr)); |
76 |
int arpsize = arphdr_len2 (iface->hwlen, sizeof (struct in_addr)); |
| 77 |
int retval; |
77 |
int retval; |
| 78 |
|
78 |
|
|
|
79 |
logger (LOG_DEBUG, "hwlen %d family %d arpsize %d", iface->hwlen, iface->family, arpsize); |
| 80 |
|
| 81 |
|
| 79 |
arp = xmalloc (arpsize); |
82 |
arp = xmalloc (arpsize); |
| 80 |
memset (arp, 0, arpsize); |
83 |
memset (arp, 0, arpsize); |
| 81 |
|
84 |
|
|
Lines 90-95
Link Here
|
| 90 |
memcpy (ar_tha (arp), taddr, arp->ar_hln); |
93 |
memcpy (ar_tha (arp), taddr, arp->ar_hln); |
| 91 |
memcpy (ar_tpa (arp), &tip, arp->ar_pln); |
94 |
memcpy (ar_tpa (arp), &tip, arp->ar_pln); |
| 92 |
|
95 |
|
|
|
96 |
logger (LOG_DEBUG, "arphdr_len %d", arphdr_len (arp)); |
| 97 |
|
| 93 |
retval = send_packet (iface, ETHERTYPE_ARP, |
98 |
retval = send_packet (iface, ETHERTYPE_ARP, |
| 94 |
(unsigned char *) arp, arphdr_len (arp)); |
99 |
(unsigned char *) arp, arphdr_len (arp)); |
| 95 |
free (arp); |
100 |
free (arp); |
|
Lines 105-110
Link Here
|
| 105 |
int nprobes = 0; |
110 |
int nprobes = 0; |
| 106 |
int nclaims = 0; |
111 |
int nclaims = 0; |
| 107 |
struct in_addr null_address; |
112 |
struct in_addr null_address; |
|
|
113 |
struct timeval stopat; |
| 114 |
struct timeval now; |
| 108 |
|
115 |
|
| 109 |
if (! iface->arpable) { |
116 |
if (! iface->arpable) { |
| 110 |
logger (LOG_DEBUG, "interface `%s' is not ARPable", iface->name); |
117 |
logger (LOG_DEBUG, "interface `%s' is not ARPable", iface->name); |
|
Lines 130-149
Link Here
|
| 130 |
int buflen = sizeof (char *) * iface->buffer_length; |
137 |
int buflen = sizeof (char *) * iface->buffer_length; |
| 131 |
fd_set rset; |
138 |
fd_set rset; |
| 132 |
int bytes; |
139 |
int bytes; |
| 133 |
int s; |
140 |
int s = 0; |
| 134 |
|
141 |
|
| 135 |
tv.tv_sec = 0; |
142 |
/* Only select if we have a timeout */ |
| 136 |
tv.tv_usec = timeout; |
143 |
if (timeout > 0) { |
|
|
144 |
tv.tv_sec = 0; |
| 145 |
tv.tv_usec = timeout; |
| 137 |
|
146 |
|
| 138 |
FD_ZERO (&rset); |
147 |
FD_ZERO (&rset); |
| 139 |
FD_SET (iface->fd, &rset); |
148 |
FD_SET (iface->fd, &rset); |
| 140 |
errno = 0; |
149 |
|
| 141 |
if ((s = select (FD_SETSIZE, &rset, NULL, NULL, &tv)) == -1) { |
150 |
errno = 0; |
| 142 |
if (errno != EINTR) |
151 |
if ((s = select (FD_SETSIZE, &rset, NULL, NULL, &tv)) == -1) { |
| 143 |
logger (LOG_ERR, "select: `%s'", strerror (errno)); |
152 |
if (errno != EINTR) |
| 144 |
break; |
153 |
logger (LOG_ERR, "select: `%s'", strerror (errno)); |
| 145 |
} else if (s == 0) { |
154 |
break; |
| 146 |
/* Timed out */ |
155 |
} |
|
|
156 |
} |
| 157 |
|
| 158 |
/* Timed out */ |
| 159 |
if (s == 0) { |
| 147 |
if (nprobes < NPROBES) { |
160 |
if (nprobes < NPROBES) { |
| 148 |
nprobes ++; |
161 |
nprobes ++; |
| 149 |
timeout = PROBE_INTERVAL; |
162 |
timeout = PROBE_INTERVAL; |
|
Lines 159-166
Link Here
|
| 159 |
retval = 0; |
172 |
retval = 0; |
| 160 |
break; |
173 |
break; |
| 161 |
} |
174 |
} |
|
|
175 |
|
| 176 |
/* Setup our stop time */ |
| 177 |
if (get_time (&stopat) != 0) |
| 178 |
break; |
| 179 |
stopat.tv_usec += timeout; |
| 180 |
|
| 181 |
continue; |
| 162 |
} |
182 |
} |
| 163 |
|
183 |
|
|
|
184 |
/* We maybe ARP flooded, so check our time */ |
| 185 |
if (get_time (&now) != 0) |
| 186 |
break; |
| 187 |
if (timercmp (&now, &stopat, >)) { |
| 188 |
timeout = 0; |
| 189 |
continue; |
| 190 |
} |
| 191 |
|
| 164 |
if (! FD_ISSET (iface->fd, &rset)) |
192 |
if (! FD_ISSET (iface->fd, &rset)) |
| 165 |
continue; |
193 |
continue; |
| 166 |
|
194 |
|