|
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 69-76
Link Here
|
| 69 |
|
69 |
|
| 70 |
#ifdef ENABLE_ARP |
70 |
#ifdef ENABLE_ARP |
| 71 |
|
71 |
|
| 72 |
static int send_arp (interface_t *iface, int op, struct in_addr sip, |
72 |
static int send_arp (const interface_t *iface, int op, struct in_addr sip, |
| 73 |
unsigned char *taddr, struct in_addr tip) |
73 |
const unsigned char *taddr, struct in_addr tip) |
| 74 |
{ |
74 |
{ |
| 75 |
struct arphdr *arp; |
75 |
struct arphdr *arp; |
| 76 |
int arpsize = arphdr_len2 (iface->hwlen, sizeof (struct in_addr)); |
76 |
int arpsize = arphdr_len2 (iface->hwlen, sizeof (struct in_addr)); |
|
Lines 84-90
Link Here
|
| 84 |
arp->ar_hln = iface->hwlen; |
84 |
arp->ar_hln = iface->hwlen; |
| 85 |
arp->ar_pln = sizeof (struct in_addr); |
85 |
arp->ar_pln = sizeof (struct in_addr); |
| 86 |
arp->ar_op = htons (op); |
86 |
arp->ar_op = htons (op); |
| 87 |
memcpy (ar_sha (arp), &iface->hwaddr, arp->ar_hln); |
87 |
memcpy (ar_sha (arp), iface->hwaddr, arp->ar_hln); |
| 88 |
memcpy (ar_spa (arp), &sip, arp->ar_pln); |
88 |
memcpy (ar_spa (arp), &sip, arp->ar_pln); |
| 89 |
if (taddr) |
89 |
if (taddr) |
| 90 |
memcpy (ar_tha (arp), taddr, arp->ar_hln); |
90 |
memcpy (ar_tha (arp), taddr, arp->ar_hln); |
|
Lines 105-110
Link Here
|
| 105 |
int nprobes = 0; |
105 |
int nprobes = 0; |
| 106 |
int nclaims = 0; |
106 |
int nclaims = 0; |
| 107 |
struct in_addr null_address; |
107 |
struct in_addr null_address; |
|
|
108 |
struct timeval stopat; |
| 109 |
struct timeval now; |
| 108 |
|
110 |
|
| 109 |
if (! iface->arpable) { |
111 |
if (! iface->arpable) { |
| 110 |
logger (LOG_DEBUG, "interface `%s' is not ARPable", iface->name); |
112 |
logger (LOG_DEBUG, "interface `%s' is not ARPable", iface->name); |
|
Lines 117-123
Link Here
|
| 117 |
if (! open_socket (iface, true)) |
119 |
if (! open_socket (iface, true)) |
| 118 |
return (0); |
120 |
return (0); |
| 119 |
|
121 |
|
| 120 |
memset (&null_address, 0, sizeof (null_address)); |
122 |
memset (&null_address, 0, sizeof (struct in_addr)); |
| 121 |
|
123 |
|
| 122 |
buffer = xmalloc (sizeof (char *) * iface->buffer_length); |
124 |
buffer = xmalloc (sizeof (char *) * iface->buffer_length); |
| 123 |
|
125 |
|
|
Lines 130-149
Link Here
|
| 130 |
int buflen = sizeof (char *) * iface->buffer_length; |
132 |
int buflen = sizeof (char *) * iface->buffer_length; |
| 131 |
fd_set rset; |
133 |
fd_set rset; |
| 132 |
int bytes; |
134 |
int bytes; |
| 133 |
int s; |
135 |
int s = 0; |
| 134 |
|
136 |
|
| 135 |
tv.tv_sec = 0; |
137 |
/* Only select if we have a timeout */ |
| 136 |
tv.tv_usec = timeout; |
138 |
if (timeout > 0) { |
|
|
139 |
tv.tv_sec = 0; |
| 140 |
tv.tv_usec = timeout; |
| 137 |
|
141 |
|
| 138 |
FD_ZERO (&rset); |
142 |
FD_ZERO (&rset); |
| 139 |
FD_SET (iface->fd, &rset); |
143 |
FD_SET (iface->fd, &rset); |
| 140 |
errno = 0; |
144 |
|
| 141 |
if ((s = select (FD_SETSIZE, &rset, NULL, NULL, &tv)) == -1) { |
145 |
errno = 0; |
| 142 |
if (errno != EINTR) |
146 |
if ((s = select (FD_SETSIZE, &rset, NULL, NULL, &tv)) == -1) { |
| 143 |
logger (LOG_ERR, "select: `%s'", strerror (errno)); |
147 |
if (errno != EINTR) |
| 144 |
break; |
148 |
logger (LOG_ERR, "select: `%s'", strerror (errno)); |
| 145 |
} else if (s == 0) { |
149 |
break; |
| 146 |
/* Timed out */ |
150 |
} |
|
|
151 |
} |
| 152 |
|
| 153 |
/* Timed out */ |
| 154 |
if (s == 0) { |
| 147 |
if (nprobes < NPROBES) { |
155 |
if (nprobes < NPROBES) { |
| 148 |
nprobes ++; |
156 |
nprobes ++; |
| 149 |
timeout = PROBE_INTERVAL; |
157 |
timeout = PROBE_INTERVAL; |
|
Lines 159-166
Link Here
|
| 159 |
retval = 0; |
167 |
retval = 0; |
| 160 |
break; |
168 |
break; |
| 161 |
} |
169 |
} |
|
|
170 |
|
| 171 |
/* Setup our stop time */ |
| 172 |
if (get_time (&stopat) != 0) |
| 173 |
break; |
| 174 |
stopat.tv_usec += timeout; |
| 175 |
|
| 176 |
continue; |
| 162 |
} |
177 |
} |
| 163 |
|
178 |
|
|
|
179 |
/* We maybe ARP flooded, so check our time */ |
| 180 |
if (get_time (&now) != 0) |
| 181 |
break; |
| 182 |
if (timercmp (&now, &stopat, >)) { |
| 183 |
timeout = 0; |
| 184 |
continue; |
| 185 |
} |
| 186 |
|
| 164 |
if (! FD_ISSET (iface->fd, &rset)) |
187 |
if (! FD_ISSET (iface->fd, &rset)) |
| 165 |
continue; |
188 |
continue; |
| 166 |
|
189 |
|
|
Lines 196-202
Link Here
|
| 196 |
|
219 |
|
| 197 |
rp.c = (unsigned char *) ar_spa (reply); |
220 |
rp.c = (unsigned char *) ar_spa (reply); |
| 198 |
rh.c = (unsigned char *) ar_sha (reply); |
221 |
rh.c = (unsigned char *) ar_sha (reply); |
| 199 |
|
222 |
|
| 200 |
/* Ensure the ARP reply is for the address we asked for */ |
223 |
/* Ensure the ARP reply is for the address we asked for */ |
| 201 |
if (rp.a->s_addr != address.s_addr) |
224 |
if (rp.a->s_addr != address.s_addr) |
| 202 |
continue; |
225 |
continue; |