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; |