summaryrefslogtreecommitdiffstats
path: root/plugins-root/check_icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-root/check_icmp.c')
-rw-r--r--plugins-root/check_icmp.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index c0b29f25..a5e898a1 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -192,7 +192,7 @@ static void run_checks(void);
192static void set_source_ip(char *); 192static void set_source_ip(char *);
193static int add_target(char *); 193static int add_target(char *);
194static int add_target_ip(char *, struct in_addr *); 194static int add_target_ip(char *, struct in_addr *);
195static int handle_random_icmp(struct icmp *, struct sockaddr_in *); 195static int handle_random_icmp(char *, struct sockaddr_in *);
196static unsigned short icmp_checksum(unsigned short *, int); 196static unsigned short icmp_checksum(unsigned short *, int);
197static void finish(int); 197static void finish(int);
198static void crash(const char *, ...); 198static void crash(const char *, ...);
@@ -299,19 +299,18 @@ get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code)
299} 299}
300 300
301static int 301static int
302handle_random_icmp(struct icmp *p, struct sockaddr_in *addr) 302handle_random_icmp(char *packet, struct sockaddr_in *addr)
303{ 303{
304 struct icmp sent_icmp; 304 struct icmp p, sent_icmp;
305 struct rta_host *host = NULL; 305 struct rta_host *host = NULL;
306 unsigned char *ptr;
307 306
308 if(p->icmp_type == ICMP_ECHO && p->icmp_id == pid) { 307 memcpy(&p, packet, sizeof(p));
308 if(p.icmp_type == ICMP_ECHO && p.icmp_id == pid) {
309 /* echo request from us to us (pinging localhost) */ 309 /* echo request from us to us (pinging localhost) */
310 return 0; 310 return 0;
311 } 311 }
312 312
313 ptr = (unsigned char *)p; 313 if(debug) printf("handle_random_icmp(%p, %p)\n", (void *)&p, (void *)addr);
314 if(debug) printf("handle_random_icmp(%p, %p)\n", (void *)p, (void *)addr);
315 314
316 /* only handle a few types, since others can't possibly be replies to 315 /* only handle a few types, since others can't possibly be replies to
317 * us in a sane network (if it is anyway, it will be counted as lost 316 * us in a sane network (if it is anyway, it will be counted as lost
@@ -323,15 +322,15 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
323 * TIMXCEED actually sends a proper icmp response we will have passed 322 * TIMXCEED actually sends a proper icmp response we will have passed
324 * too many hops to have a hope of reaching it later, in which case it 323 * too many hops to have a hope of reaching it later, in which case it
325 * indicates overconfidence in the network, poor routing or both. */ 324 * indicates overconfidence in the network, poor routing or both. */
326 if(p->icmp_type != ICMP_UNREACH && p->icmp_type != ICMP_TIMXCEED && 325 if(p.icmp_type != ICMP_UNREACH && p.icmp_type != ICMP_TIMXCEED &&
327 p->icmp_type != ICMP_SOURCEQUENCH && p->icmp_type != ICMP_PARAMPROB) 326 p.icmp_type != ICMP_SOURCEQUENCH && p.icmp_type != ICMP_PARAMPROB)
328 { 327 {
329 return 0; 328 return 0;
330 } 329 }
331 330
332 /* might be for us. At least it holds the original package (according 331 /* might be for us. At least it holds the original package (according
333 * to RFC 792). If it isn't, just ignore it */ 332 * to RFC 792). If it isn't, just ignore it */
334 memcpy(&sent_icmp, ptr + 28, sizeof(sent_icmp)); 333 memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp));
335 if(sent_icmp.icmp_type != ICMP_ECHO || sent_icmp.icmp_id != pid || 334 if(sent_icmp.icmp_type != ICMP_ECHO || sent_icmp.icmp_id != pid ||
336 sent_icmp.icmp_seq >= targets) 335 sent_icmp.icmp_seq >= targets)
337 { 336 {
@@ -343,7 +342,7 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
343 host = table[sent_icmp.icmp_seq]; 342 host = table[sent_icmp.icmp_seq];
344 if(debug) { 343 if(debug) {
345 printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n", 344 printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n",
346 get_icmp_error_msg(p->icmp_type, p->icmp_code), 345 get_icmp_error_msg(p.icmp_type, p.icmp_code),
347 inet_ntoa(addr->sin_addr), host->name); 346 inet_ntoa(addr->sin_addr), host->name);
348 } 347 }
349 348
@@ -354,7 +353,7 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
354 353
355 /* source quench means we're sending too fast, so increase the 354 /* source quench means we're sending too fast, so increase the
356 * interval and mark this packet lost */ 355 * interval and mark this packet lost */
357 if(p->icmp_type == ICMP_SOURCEQUENCH) { 356 if(p.icmp_type == ICMP_SOURCEQUENCH) {
358 pkt_interval *= pkt_backoff_factor; 357 pkt_interval *= pkt_backoff_factor;
359 target_interval *= target_backoff_factor; 358 target_interval *= target_backoff_factor;
360 } 359 }
@@ -362,8 +361,8 @@ handle_random_icmp(struct icmp *p, struct sockaddr_in *addr)
362 targets_down++; 361 targets_down++;
363 host->flags |= FLAG_LOST_CAUSE; 362 host->flags |= FLAG_LOST_CAUSE;
364 } 363 }
365 host->icmp_type = p->icmp_type; 364 host->icmp_type = p.icmp_type;
366 host->icmp_code = p->icmp_code; 365 host->icmp_code = p.icmp_code;
367 host->error_addr.s_addr = addr->sin_addr.s_addr; 366 host->error_addr.s_addr = addr->sin_addr.s_addr;
368 367
369 return 0; 368 return 0;
@@ -758,13 +757,13 @@ wait_for_reply(int sock, u_int t)
758 memcpy(&icp, buf + hlen, sizeof(icp)); 757 memcpy(&icp, buf + hlen, sizeof(icp));
759 758
760 if(icp.icmp_id != pid) { 759 if(icp.icmp_id != pid) {
761 handle_random_icmp(&icp, &resp_addr); 760 handle_random_icmp(buf + hlen, &resp_addr);
762 continue; 761 continue;
763 } 762 }
764 763
765 if(icp.icmp_type != ICMP_ECHOREPLY || icp.icmp_seq >= targets) { 764 if(icp.icmp_type != ICMP_ECHOREPLY || icp.icmp_seq >= targets) {
766 if(debug > 2) printf("not a proper ICMP_ECHOREPLY\n"); 765 if(debug > 2) printf("not a proper ICMP_ECHOREPLY\n");
767 handle_random_icmp(&icp, &resp_addr); 766 handle_random_icmp(buf + hlen, &resp_addr);
768 continue; 767 continue;
769 } 768 }
770 769