diff options
author | Holger Weiss <hweiss@users.sourceforge.net> | 2008-01-08 01:51:14 +0000 |
---|---|---|
committer | Holger Weiss <hweiss@users.sourceforge.net> | 2008-01-08 01:51:14 +0000 |
commit | 6a00f7ecdd12dca8126b6674bf7f9ab7f36d591e (patch) | |
tree | 61d75da8fc47a0f18d77e5609fad2cc437bfee36 /plugins-root/check_icmp.c | |
parent | 5da79db21aa37e2663662f96ff328ce127db25e0 (diff) | |
download | monitoring-plugins-6a00f7ecdd12dca8126b6674bf7f9ab7f36d591e.tar.gz |
Fix the handling of ICMP packets which are not echo replies (such as
destination unreachable messages) or which are not directed at us.
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1896 f882894a-f735-0410-b71e-b25c423dba1c
Diffstat (limited to 'plugins-root/check_icmp.c')
-rw-r--r-- | plugins-root/check_icmp.c | 31 |
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); | |||
192 | static void set_source_ip(char *); | 192 | static void set_source_ip(char *); |
193 | static int add_target(char *); | 193 | static int add_target(char *); |
194 | static int add_target_ip(char *, struct in_addr *); | 194 | static int add_target_ip(char *, struct in_addr *); |
195 | static int handle_random_icmp(struct icmp *, struct sockaddr_in *); | 195 | static int handle_random_icmp(char *, struct sockaddr_in *); |
196 | static unsigned short icmp_checksum(unsigned short *, int); | 196 | static unsigned short icmp_checksum(unsigned short *, int); |
197 | static void finish(int); | 197 | static void finish(int); |
198 | static void crash(const char *, ...); | 198 | static void crash(const char *, ...); |
@@ -299,19 +299,18 @@ get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | static int | 301 | static int |
302 | handle_random_icmp(struct icmp *p, struct sockaddr_in *addr) | 302 | handle_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 | ||