211 |
return 0; |
return 0; |
212 |
} |
} |
213 |
|
|
214 |
|
static int |
215 |
|
my_echo_reply (PING *p, icmphdr_t *icmp) |
216 |
|
{ |
217 |
|
struct ip *orig_ip = &icmp->icmp_ip; |
218 |
|
icmphdr_t *orig_icmp = (icmphdr_t *)(orig_ip + 1); |
219 |
|
|
220 |
|
return orig_ip->ip_dst.s_addr == p->ping_dest.sin_addr.s_addr |
221 |
|
&& orig_ip->ip_p == IPPROTO_ICMP |
222 |
|
&& orig_icmp->icmp_type == ICMP_ECHO |
223 |
|
&& orig_icmp->icmp_id == p->ping_ident; |
224 |
|
} |
225 |
|
|
226 |
int |
int |
227 |
ping_recv (PING *p) |
ping_recv (PING *p) |
228 |
{ |
{ |
233 |
int dupflag; |
int dupflag; |
234 |
|
|
235 |
if ((n = recvfrom (p->ping_fd, |
if ((n = recvfrom (p->ping_fd, |
236 |
(char *)p->ping_buffer, _PING_BUFLEN (p), 0, |
(char *)p->ping_buffer, _PING_BUFLEN (p), 0, |
237 |
(struct sockaddr *)&p->ping_from, &fromlen)) < 0) |
(struct sockaddr *)&p->ping_from, &fromlen)) < 0) |
238 |
return -1; |
return -1; |
239 |
|
|
240 |
if ((rc = icmp_generic_decode (p->ping_buffer, n, &ip, &icmp)) < 0) |
if ((rc = icmp_generic_decode (p->ping_buffer, n, &ip, &icmp)) < 0) |
241 |
{ |
{ |
242 |
/*FIXME: conditional*/ |
/*FIXME: conditional*/ |
243 |
fprintf (stderr,"packet too short (%d bytes) from %s\n", n, |
fprintf (stderr,"packet too short (%d bytes) from %s\n", n, |
|
inet_ntoa (p->ping_from.sin_addr)); |
|
|
return -1; |
|
|
} |
|
|
|
|
|
if (icmp->icmp_id != p->ping_ident) |
|
|
return -1; |
|
|
if (rc) |
|
|
{ |
|
|
fprintf (stderr, "checksum mismatch from %s\n", |
|
244 |
inet_ntoa (p->ping_from.sin_addr)); |
inet_ntoa (p->ping_from.sin_addr)); |
245 |
|
return -1; |
246 |
} |
} |
247 |
|
|
248 |
switch (icmp->icmp_type) |
switch (icmp->icmp_type) |
249 |
{ |
{ |
250 |
case ICMP_ECHOREPLY: |
case ICMP_ECHOREPLY: |
251 |
case ICMP_TIMESTAMPREPLY: |
case ICMP_TIMESTAMPREPLY: |
252 |
case ICMP_ADDRESSREPLY: |
case ICMP_ADDRESSREPLY: |
253 |
/* case ICMP_ROUTERADV:*/ |
/* case ICMP_ROUTERADV:*/ |
254 |
|
|
255 |
|
if (icmp->icmp_id != p->ping_ident) |
256 |
|
return -1; |
257 |
|
|
258 |
|
if (rc) |
259 |
|
fprintf (stderr, "checksum mismatch from %s\n", |
260 |
|
inet_ntoa (p->ping_from.sin_addr)); |
261 |
|
|
262 |
p->ping_num_recv++; |
p->ping_num_recv++; |
263 |
if (_PING_TST (p, icmp->icmp_seq % p->ping_cktab_size)) |
if (_PING_TST (p, icmp->icmp_seq % p->ping_cktab_size)) |
264 |
{ |
{ |
286 |
return -1; |
return -1; |
287 |
|
|
288 |
default: |
default: |
289 |
|
if (!my_echo_reply(p, icmp)) |
290 |
|
return -1; |
291 |
|
|
292 |
if (p->ping_event) |
if (p->ping_event) |
293 |
(*p->ping_event)(PEV_NOECHO, |
(*p->ping_event)(PEV_NOECHO, |
294 |
p->ping_closure, |
p->ping_closure, |