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