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.c152
1 files changed, 85 insertions, 67 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 31eb4c6..1d47e9f 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -1,39 +1,39 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_icmp plugin 3* Monitoring check_icmp plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2005-2008 Monitoring Plugins Development Team 6* Copyright (c) 2005-2008 Monitoring Plugins Development Team
7* Original Author : Andreas Ericsson <ae@op5.se> 7* Original Author : Andreas Ericsson <ae@op5.se>
8* 8*
9* Description: 9* Description:
10* 10*
11* This file contains the check_icmp plugin 11* This file contains the check_icmp plugin
12* 12*
13* Relevant RFC's: 792 (ICMP), 791 (IP) 13* Relevant RFC's: 792 (ICMP), 791 (IP)
14* 14*
15* This program was modeled somewhat after the check_icmp program, 15* This program was modeled somewhat after the check_icmp program,
16* which was in turn a hack of fping (www.fping.org) but has been 16* which was in turn a hack of fping (www.fping.org) but has been
17* completely rewritten since to generate higher precision rta values, 17* completely rewritten since to generate higher precision rta values,
18* and support several different modes as well as setting ttl to control. 18* and support several different modes as well as setting ttl to control.
19* redundant routes. The only remainders of fping is currently a few 19* redundant routes. The only remainders of fping is currently a few
20* function names. 20* function names.
21* 21*
22* 22*
23* This program is free software: you can redistribute it and/or modify 23* This program is free software: you can redistribute it and/or modify
24* it under the terms of the GNU General Public License as published by 24* it under the terms of the GNU General Public License as published by
25* the Free Software Foundation, either version 3 of the License, or 25* the Free Software Foundation, either version 3 of the License, or
26* (at your option) any later version. 26* (at your option) any later version.
27* 27*
28* This program is distributed in the hope that it will be useful, 28* This program is distributed in the hope that it will be useful,
29* but WITHOUT ANY WARRANTY; without even the implied warranty of 29* but WITHOUT ANY WARRANTY; without even the implied warranty of
30* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31* GNU General Public License for more details. 31* GNU General Public License for more details.
32* 32*
33* You should have received a copy of the GNU General Public License 33* You should have received a copy of the GNU General Public License
34* along with this program. If not, see <http://www.gnu.org/licenses/>. 34* along with this program. If not, see <http://www.gnu.org/licenses/>.
35* 35*
36* 36*
37*****************************************************************************/ 37*****************************************************************************/
38 38
39/* progname may change */ 39/* progname may change */
@@ -50,19 +50,12 @@ const char *email = "devel@monitoring-plugins.org";
50#if HAVE_SYS_SOCKIO_H 50#if HAVE_SYS_SOCKIO_H
51#include <sys/sockio.h> 51#include <sys/sockio.h>
52#endif 52#endif
53#include <sys/ioctl.h> 53
54#include <sys/time.h> 54#include <sys/time.h>
55#include <sys/types.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <stdarg.h>
59#include <unistd.h>
60#include <stddef.h>
61#include <errno.h> 55#include <errno.h>
62#include <string.h> 56#include <signal.h>
63#include <ctype.h> 57#include <ctype.h>
64#include <netdb.h> 58#include <float.h>
65#include <sys/socket.h>
66#include <net/if.h> 59#include <net/if.h>
67#include <netinet/in_systm.h> 60#include <netinet/in_systm.h>
68#include <netinet/in.h> 61#include <netinet/in.h>
@@ -71,8 +64,6 @@ const char *email = "devel@monitoring-plugins.org";
71#include <netinet/ip_icmp.h> 64#include <netinet/ip_icmp.h>
72#include <netinet/icmp6.h> 65#include <netinet/icmp6.h>
73#include <arpa/inet.h> 66#include <arpa/inet.h>
74#include <signal.h>
75#include <float.h>
76 67
77 68
78/** sometimes undefined system macros (quite a few, actually) **/ 69/** sometimes undefined system macros (quite a few, actually) **/
@@ -105,10 +96,6 @@ const char *email = "devel@monitoring-plugins.org";
105# define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 96# define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
106#endif 97#endif
107 98
108#ifndef DBL_MAX
109# define DBL_MAX 9.9999999999e999
110#endif
111
112typedef unsigned short range_t; /* type for get_range() -- unimplemented */ 99typedef unsigned short range_t; /* type for get_range() -- unimplemented */
113 100
114typedef struct rta_host { 101typedef struct rta_host {
@@ -207,7 +194,7 @@ static int add_target(char *);
207static int add_target_ip(char *, struct sockaddr_storage *); 194static int add_target_ip(char *, struct sockaddr_storage *);
208static int handle_random_icmp(unsigned char *, struct sockaddr_storage *); 195static int handle_random_icmp(unsigned char *, struct sockaddr_storage *);
209static void parse_address(struct sockaddr_storage *, char *, int); 196static void parse_address(struct sockaddr_storage *, char *, int);
210static unsigned short icmp_checksum(unsigned short *, int); 197static unsigned short icmp_checksum(uint16_t *, size_t);
211static void finish(int); 198static void finish(int);
212static void crash(const char *, ...); 199static void crash(const char *, ...);
213 200
@@ -223,7 +210,7 @@ static int mode, protocols, sockets, debug = 0, timeout = 10;
223static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE; 210static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE;
224static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN; 211static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN;
225 212
226static unsigned int icmp_sent = 0, icmp_recv = 0, icmp_lost = 0; 213static unsigned int icmp_sent = 0, icmp_recv = 0, icmp_lost = 0, ttl = 0;
227#define icmp_pkts_en_route (icmp_sent - (icmp_recv + icmp_lost)) 214#define icmp_pkts_en_route (icmp_sent - (icmp_recv + icmp_lost))
228static unsigned short targets_down = 0, targets = 0, packets = 0; 215static unsigned short targets_down = 0, targets = 0, packets = 0;
229#define targets_alive (targets - targets_down) 216#define targets_alive (targets - targets_down)
@@ -233,7 +220,6 @@ static pid_t pid;
233static struct timezone tz; 220static struct timezone tz;
234static struct timeval prog_start; 221static struct timeval prog_start;
235static unsigned long long max_completion_time = 0; 222static unsigned long long max_completion_time = 0;
236static unsigned char ttl = 0; /* outgoing ttl */
237static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values */ 223static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values */
238static int min_hosts_alive = -1; 224static int min_hosts_alive = -1;
239float pkt_backoff_factor = 1.5; 225float pkt_backoff_factor = 1.5;
@@ -288,7 +274,7 @@ get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code)
288 break; 274 break;
289 275
290 case ICMP_TIMXCEED: 276 case ICMP_TIMXCEED:
291 /* really 'out of reach', or non-existant host behind a router serving 277 /* really 'out of reach', or non-existent host behind a router serving
292 * two different subnets */ 278 * two different subnets */
293 switch(icmp_code) { 279 switch(icmp_code) {
294 case ICMP_TIMXCEED_INTRANS: msg = "Time to live exceeded in transit"; break; 280 case ICMP_TIMXCEED_INTRANS: msg = "Time to live exceeded in transit"; break;
@@ -410,6 +396,7 @@ main(int argc, char **argv)
410#ifdef SO_TIMESTAMP 396#ifdef SO_TIMESTAMP
411 int on = 1; 397 int on = 1;
412#endif 398#endif
399 char *source_ip = NULL;
413 char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:64"; 400 char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:64";
414 401
415 setlocale (LC_ALL, ""); 402 setlocale (LC_ALL, "");
@@ -461,10 +448,17 @@ main(int argc, char **argv)
461 packets = 5; 448 packets = 5;
462 } 449 }
463 450
451 /* support "--help" and "--version" */
452 if(argc == 2) {
453 if(!strcmp(argv[1], "--help"))
454 strcpy(argv[1], "-h");
455 if(!strcmp(argv[1], "--version"))
456 strcpy(argv[1], "-V");
457 }
458
464 /* Parse protocol arguments first */ 459 /* Parse protocol arguments first */
465 for(i = 1; i < argc; i++) { 460 for(i = 1; i < argc; i++) {
466 while((arg = getopt(argc, argv, opts_str)) != EOF) { 461 while((arg = getopt(argc, argv, opts_str)) != EOF) {
467 unsigned short size;
468 switch(arg) { 462 switch(arg) {
469 case '4': 463 case '4':
470 if (address_family != -1) 464 if (address_family != -1)
@@ -487,10 +481,10 @@ main(int argc, char **argv)
487 /* Reset argument scanning */ 481 /* Reset argument scanning */
488 optind = 1; 482 optind = 1;
489 483
484 unsigned short size;
490 /* parse the arguments */ 485 /* parse the arguments */
491 for(i = 1; i < argc; i++) { 486 for(i = 1; i < argc; i++) {
492 while((arg = getopt(argc, argv, opts_str)) != EOF) { 487 while((arg = getopt(argc, argv, opts_str)) != EOF) {
493 unsigned short size;
494 switch(arg) { 488 switch(arg) {
495 case 'v': 489 case 'v':
496 debug++; 490 debug++;
@@ -502,7 +496,7 @@ main(int argc, char **argv)
502 icmp_data_size = size; 496 icmp_data_size = size;
503 icmp_pkt_size = size + ICMP_MINLEN; 497 icmp_pkt_size = size + ICMP_MINLEN;
504 } else 498 } else
505 usage_va("ICMP data length must be between: %d and %d", 499 usage_va("ICMP data length must be between: %lu and %lu",
506 sizeof(struct icmp) + sizeof(struct icmp_ping_data), 500 sizeof(struct icmp) + sizeof(struct icmp_ping_data),
507 MAX_PING_DATA - 1); 501 MAX_PING_DATA - 1);
508 break; 502 break;
@@ -530,7 +524,7 @@ main(int argc, char **argv)
530 add_target(optarg); 524 add_target(optarg);
531 break; 525 break;
532 case 'l': 526 case 'l':
533 ttl = (unsigned char)strtoul(optarg, NULL, 0); 527 ttl = (int)strtoul(optarg, NULL, 0);
534 break; 528 break;
535 case 'm': 529 case 'm':
536 min_hosts_alive = (int)strtoul(optarg, NULL, 0); 530 min_hosts_alive = (int)strtoul(optarg, NULL, 0);
@@ -542,7 +536,7 @@ main(int argc, char **argv)
542 } 536 }
543 break; 537 break;
544 case 's': /* specify source IP address */ 538 case 's': /* specify source IP address */
545 set_source_ip(optarg); 539 source_ip = optarg;
546 break; 540 break;
547 case 'V': /* version */ 541 case 'V': /* version */
548 print_revision (progname, NP_VERSION); 542 print_revision (progname, NP_VERSION);
@@ -566,14 +560,6 @@ main(int argc, char **argv)
566 /* Parse extra opts if any */ 560 /* Parse extra opts if any */
567 argv=np_extra_opts(&argc, argv, progname); 561 argv=np_extra_opts(&argc, argv, progname);
568 562
569 /* support "--help" and "--version" */
570 if(argc == 2) {
571 if(!strcmp(argv[1], "--help"))
572 strcpy(argv[1], "-h");
573 if(!strcmp(argv[1], "--version"))
574 strcpy(argv[1], "-V");
575 }
576
577 argv = &argv[optind]; 563 argv = &argv[optind];
578 while(*argv) { 564 while(*argv) {
579 add_target(*argv); 565 add_target(*argv);
@@ -597,6 +583,8 @@ main(int argc, char **argv)
597 sockets |= HAVE_ICMP; 583 sockets |= HAVE_ICMP;
598 else icmp_sockerrno = errno; 584 else icmp_sockerrno = errno;
599 585
586 if( source_ip )
587 set_source_ip(source_ip);
600 588
601#ifdef SO_TIMESTAMP 589#ifdef SO_TIMESTAMP
602 if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) 590 if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
@@ -717,7 +705,7 @@ main(int argc, char **argv)
717static void 705static void
718run_checks() 706run_checks()
719{ 707{
720 u_int i, t, result; 708 u_int i, t;
721 u_int final_wait, time_passed; 709 u_int final_wait, time_passed;
722 710
723 /* this loop might actually violate the pkt_interval or target_interval 711 /* this loop might actually violate the pkt_interval or target_interval
@@ -735,9 +723,9 @@ run_checks()
735 723
736 /* we're still in the game, so send next packet */ 724 /* we're still in the game, so send next packet */
737 (void)send_icmp_ping(icmp_sock, table[t]); 725 (void)send_icmp_ping(icmp_sock, table[t]);
738 result = wait_for_reply(icmp_sock, target_interval); 726 wait_for_reply(icmp_sock, target_interval);
739 } 727 }
740 result = wait_for_reply(icmp_sock, pkt_interval * targets); 728 wait_for_reply(icmp_sock, pkt_interval * targets);
741 } 729 }
742 730
743 if(icmp_pkts_en_route && targets_alive) { 731 if(icmp_pkts_en_route && targets_alive) {
@@ -757,7 +745,7 @@ run_checks()
757 * haven't yet */ 745 * haven't yet */
758 if(debug) printf("Waiting for %u micro-seconds (%0.3f msecs)\n", 746 if(debug) printf("Waiting for %u micro-seconds (%0.3f msecs)\n",
759 final_wait, (float)final_wait / 1000); 747 final_wait, (float)final_wait / 1000);
760 result = wait_for_reply(icmp_sock, final_wait); 748 wait_for_reply(icmp_sock, final_wait);
761 } 749 }
762} 750}
763 751
@@ -776,7 +764,7 @@ static int
776wait_for_reply(int sock, u_int t) 764wait_for_reply(int sock, u_int t)
777{ 765{
778 int n, hlen; 766 int n, hlen;
779 static unsigned char buf[4096]; 767 static unsigned char buf[65536];
780 struct sockaddr_storage resp_addr; 768 struct sockaddr_storage resp_addr;
781 union ip_hdr *ip; 769 union ip_hdr *ip;
782 union icmp_packet packet; 770 union icmp_packet packet;
@@ -913,15 +901,33 @@ wait_for_reply(int sock, u_int t)
913 if(debug) { 901 if(debug) {
914 char address[INET6_ADDRSTRLEN]; 902 char address[INET6_ADDRSTRLEN];
915 parse_address(&resp_addr, address, sizeof(address)); 903 parse_address(&resp_addr, address, sizeof(address));
916 printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n", 904
917 (float)tdiff / 1000, address, 905 switch(address_family) {
918 ttl, ip->ip.ip_ttl, (float)host->rtmax / 1000, (float)host->rtmin / 1000); 906 case AF_INET: {
907 printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n",
908 (float)tdiff / 1000,
909 address,
910 ttl,
911 ip->ip.ip_ttl,
912 (float)host->rtmax / 1000,
913 (float)host->rtmin / 1000);
914 break;
915 };
916 case AF_INET6: {
917 printf("%0.3f ms rtt from %s, outgoing ttl: %u, max: %0.3f, min: %0.3f\n",
918 (float)tdiff / 1000,
919 address,
920 ttl,
921 (float)host->rtmax / 1000,
922 (float)host->rtmin / 1000);
923 };
924 }
919 } 925 }
920 926
921 /* if we're in hostcheck mode, exit with limited printouts */ 927 /* if we're in hostcheck mode, exit with limited printouts */
922 if(mode == MODE_HOSTCHECK) { 928 if(mode == MODE_HOSTCHECK) {
923 printf("OK - %s responds to ICMP. Packet %u, rta %0.3fms|" 929 printf("OK - %s responds to ICMP. Packet %u, rta %0.3fms|"
924 "pkt=%u;;0;%u rta=%0.3f;%0.3f;%0.3f;;\n", 930 "pkt=%u;;;0;%u rta=%0.3f;%0.3f;%0.3f;;\n",
925 host->name, icmp_recv, (float)tdiff / 1000, 931 host->name, icmp_recv, (float)tdiff / 1000,
926 icmp_recv, packets, (float)tdiff / 1000, 932 icmp_recv, packets, (float)tdiff / 1000,
927 (float)warn.rta / 1000, (float)crit.rta / 1000); 933 (float)warn.rta / 1000, (float)crit.rta / 1000);
@@ -938,6 +944,7 @@ static int
938send_icmp_ping(int sock, struct rta_host *host) 944send_icmp_ping(int sock, struct rta_host *host)
939{ 945{
940 long int len; 946 long int len;
947 size_t addrlen;
941 struct icmp_ping_data data; 948 struct icmp_ping_data data;
942 struct msghdr hdr; 949 struct msghdr hdr;
943 struct iovec iov; 950 struct iovec iov;
@@ -969,6 +976,7 @@ send_icmp_ping(int sock, struct rta_host *host)
969 976
970 if (address_family == AF_INET) { 977 if (address_family == AF_INET) {
971 struct icmp *icp = (struct icmp*)buf; 978 struct icmp *icp = (struct icmp*)buf;
979 addrlen = sizeof(struct sockaddr_in);
972 980
973 memcpy(&icp->icmp_data, &data, sizeof(data)); 981 memcpy(&icp->icmp_data, &data, sizeof(data));
974 982
@@ -977,7 +985,7 @@ send_icmp_ping(int sock, struct rta_host *host)
977 icp->icmp_cksum = 0; 985 icp->icmp_cksum = 0;
978 icp->icmp_id = htons(pid); 986 icp->icmp_id = htons(pid);
979 icp->icmp_seq = htons(host->id++); 987 icp->icmp_seq = htons(host->id++);
980 icp->icmp_cksum = icmp_checksum((unsigned short*)buf, icmp_pkt_size); 988 icp->icmp_cksum = icmp_checksum((uint16_t*)buf, (size_t)icmp_pkt_size);
981 989
982 if (debug > 2) 990 if (debug > 2)
983 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", 991 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n",
@@ -985,7 +993,10 @@ send_icmp_ping(int sock, struct rta_host *host)
985 } 993 }
986 else { 994 else {
987 struct icmp6_hdr *icp6 = (struct icmp6_hdr*)buf; 995 struct icmp6_hdr *icp6 = (struct icmp6_hdr*)buf;
996 addrlen = sizeof(struct sockaddr_in6);
997
988 memcpy(&icp6->icmp6_dataun.icmp6_un_data8[4], &data, sizeof(data)); 998 memcpy(&icp6->icmp6_dataun.icmp6_un_data8[4], &data, sizeof(data));
999
989 icp6->icmp6_type = ICMP6_ECHO_REQUEST; 1000 icp6->icmp6_type = ICMP6_ECHO_REQUEST;
990 icp6->icmp6_code = 0; 1001 icp6->icmp6_code = 0;
991 icp6->icmp6_cksum = 0; 1002 icp6->icmp6_cksum = 0;
@@ -1006,7 +1017,7 @@ send_icmp_ping(int sock, struct rta_host *host)
1006 1017
1007 memset(&hdr, 0, sizeof(hdr)); 1018 memset(&hdr, 0, sizeof(hdr));
1008 hdr.msg_name = (struct sockaddr *)&host->saddr_in; 1019 hdr.msg_name = (struct sockaddr *)&host->saddr_in;
1009 hdr.msg_namelen = sizeof(struct sockaddr_storage); 1020 hdr.msg_namelen = addrlen;
1010 hdr.msg_iov = &iov; 1021 hdr.msg_iov = &iov;
1011 hdr.msg_iovlen = 1; 1022 hdr.msg_iovlen = 1;
1012 1023
@@ -1210,7 +1221,7 @@ finish(int sig)
1210 host->rta / 1000, (float)warn.rta / 1000, (float)crit.rta / 1000, 1221 host->rta / 1000, (float)warn.rta / 1000, (float)crit.rta / 1000,
1211 (targets > 1) ? host->name : "", host->pl, warn.pl, crit.pl, 1222 (targets > 1) ? host->name : "", host->pl, warn.pl, crit.pl,
1212 (targets > 1) ? host->name : "", (float)host->rtmax / 1000, 1223 (targets > 1) ? host->name : "", (float)host->rtmax / 1000,
1213 (targets > 1) ? host->name : "", (host->rtmin < DBL_MAX) ? (float)host->rtmin / 1000 : (float)0); 1224 (targets > 1) ? host->name : "", (host->rtmin < INFINITY) ? (float)host->rtmin / 1000 : (float)0);
1214 1225
1215 host = host->next; 1226 host = host->next;
1216 } 1227 }
@@ -1293,7 +1304,7 @@ add_target_ip(char *arg, struct sockaddr_storage *in)
1293 if(!host) { 1304 if(!host) {
1294 char straddr[INET6_ADDRSTRLEN]; 1305 char straddr[INET6_ADDRSTRLEN];
1295 parse_address((struct sockaddr_storage*)&in, straddr, sizeof(straddr)); 1306 parse_address((struct sockaddr_storage*)&in, straddr, sizeof(straddr));
1296 crash("add_target_ip(%s, %s): malloc(%d) failed", 1307 crash("add_target_ip(%s, %s): malloc(%lu) failed",
1297 arg, straddr, sizeof(struct rta_host)); 1308 arg, straddr, sizeof(struct rta_host));
1298 } 1309 }
1299 memset(host, 0, sizeof(struct rta_host)); 1310 memset(host, 0, sizeof(struct rta_host));
@@ -1313,7 +1324,7 @@ add_target_ip(char *arg, struct sockaddr_storage *in)
1313 memcpy(host_sin6->sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, sizeof host_sin6->sin6_addr.s6_addr); 1324 memcpy(host_sin6->sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, sizeof host_sin6->sin6_addr.s6_addr);
1314 } 1325 }
1315 1326
1316 host->rtmin = DBL_MAX; 1327 host->rtmin = INFINITY;
1317 1328
1318 if(!list) list = cursor = host; 1329 if(!list) list = cursor = host;
1319 else cursor->next = host; 1330 else cursor->next = host;
@@ -1328,7 +1339,7 @@ add_target_ip(char *arg, struct sockaddr_storage *in)
1328static int 1339static int
1329add_target(char *arg) 1340add_target(char *arg)
1330{ 1341{
1331 int error, result; 1342 int error, result = -1;
1332 struct sockaddr_storage ip; 1343 struct sockaddr_storage ip;
1333 struct addrinfo hints, *res, *p; 1344 struct addrinfo hints, *res, *p;
1334 struct sockaddr_in *sin; 1345 struct sockaddr_in *sin;
@@ -1419,20 +1430,26 @@ set_source_ip(char *arg)
1419static in_addr_t 1430static in_addr_t
1420get_ip_address(const char *ifname) 1431get_ip_address(const char *ifname)
1421{ 1432{
1433 // TODO: Rewrite this so the function return an error and we exit somewhere else
1434 struct sockaddr_in ip;
1435 ip.sin_addr.s_addr = 0; // Fake initialization to make compiler happy
1422#if defined(SIOCGIFADDR) 1436#if defined(SIOCGIFADDR)
1423 struct ifreq ifr; 1437 struct ifreq ifr;
1424 struct sockaddr_in ip;
1425 1438
1426 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); 1439 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
1440
1427 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; 1441 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
1442
1428 if(ioctl(icmp_sock, SIOCGIFADDR, &ifr) == -1) 1443 if(ioctl(icmp_sock, SIOCGIFADDR, &ifr) == -1)
1429 crash("Cannot determine IP address of interface %s", ifname); 1444 crash("Cannot determine IP address of interface %s", ifname);
1445
1430 memcpy(&ip, &ifr.ifr_addr, sizeof(ip)); 1446 memcpy(&ip, &ifr.ifr_addr, sizeof(ip));
1431 return ip.sin_addr.s_addr;
1432#else 1447#else
1448 (void) ifname;
1433 errno = 0; 1449 errno = 0;
1434 crash("Cannot get interface IP address on this platform."); 1450 crash("Cannot get interface IP address on this platform.");
1435#endif 1451#endif
1452 return ip.sin_addr.s_addr;
1436} 1453}
1437 1454
1438/* 1455/*
@@ -1514,18 +1531,19 @@ get_threshold(char *str, threshold *th)
1514} 1531}
1515 1532
1516unsigned short 1533unsigned short
1517icmp_checksum(unsigned short *p, int n) 1534icmp_checksum(uint16_t *p, size_t n)
1518{ 1535{
1519 unsigned short cksum; 1536 unsigned short cksum;
1520 long sum = 0; 1537 long sum = 0;
1521 1538
1522 while(n > 2) { 1539 /* sizeof(uint16_t) == 2 */
1523 sum += *p++; 1540 while(n >= 2) {
1524 n -= sizeof(unsigned short); 1541 sum += *(p++);
1542 n -= 2;
1525 } 1543 }
1526 1544
1527 /* mop up the occasional odd byte */ 1545 /* mop up the occasional odd byte */
1528 if(n == 1) sum += (unsigned char)*p; 1546 if(n == 1) sum += *((uint8_t *)p -1);
1529 1547
1530 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 1548 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1531 sum += (sum >> 16); /* add carry */ 1549 sum += (sum >> 16); /* add carry */