diff options
Diffstat (limited to 'plugins-root/check_icmp.c')
-rw-r--r-- | plugins-root/check_icmp.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index 7636bc7..80fbf61 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
@@ -54,6 +54,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
54 | #include "netutils.h" | 54 | #include "netutils.h" |
55 | #include "utils.h" | 55 | #include "utils.h" |
56 | 56 | ||
57 | #include <sys/ioctl.h> | ||
57 | #include <sys/time.h> | 58 | #include <sys/time.h> |
58 | #include <sys/types.h> | 59 | #include <sys/types.h> |
59 | #include <stdio.h> | 60 | #include <stdio.h> |
@@ -66,6 +67,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
66 | #include <ctype.h> | 67 | #include <ctype.h> |
67 | #include <netdb.h> | 68 | #include <netdb.h> |
68 | #include <sys/socket.h> | 69 | #include <sys/socket.h> |
70 | #include <net/if.h> | ||
69 | #include <netinet/in_systm.h> | 71 | #include <netinet/in_systm.h> |
70 | #include <netinet/in.h> | 72 | #include <netinet/in.h> |
71 | #include <netinet/ip.h> | 73 | #include <netinet/ip.h> |
@@ -178,11 +180,13 @@ void print_help (void); | |||
178 | void print_usage (void); | 180 | void print_usage (void); |
179 | static u_int get_timevar(const char *); | 181 | static u_int get_timevar(const char *); |
180 | static u_int get_timevaldiff(struct timeval *, struct timeval *); | 182 | static u_int get_timevaldiff(struct timeval *, struct timeval *); |
183 | static in_addr_t get_ip_address(const char *); | ||
181 | static int wait_for_reply(int, u_int); | 184 | static int wait_for_reply(int, u_int); |
182 | static int recvfrom_wto(int, char *, unsigned int, struct sockaddr *, u_int *); | 185 | static int recvfrom_wto(int, char *, unsigned int, struct sockaddr *, u_int *); |
183 | static int send_icmp_ping(int, struct rta_host *); | 186 | static int send_icmp_ping(int, struct rta_host *); |
184 | static int get_threshold(char *str, threshold *th); | 187 | static int get_threshold(char *str, threshold *th); |
185 | static void run_checks(void); | 188 | static void run_checks(void); |
189 | static void set_source_ip(char *); | ||
186 | static int add_target(char *); | 190 | static int add_target(char *); |
187 | static int add_target_ip(char *, struct in_addr *); | 191 | static int add_target_ip(char *, struct in_addr *); |
188 | static int handle_random_icmp(struct icmp *, struct sockaddr_in *); | 192 | static int handle_random_icmp(struct icmp *, struct sockaddr_in *); |
@@ -446,7 +450,7 @@ main(int argc, char **argv) | |||
446 | 450 | ||
447 | /* parse the arguments */ | 451 | /* parse the arguments */ |
448 | for(i = 1; i < argc; i++) { | 452 | for(i = 1; i < argc; i++) { |
449 | while((arg = getopt(argc, argv, "vhVw:c:n:p:t:H:i:b:I:l:m:")) != EOF) { | 453 | while((arg = getopt(argc, argv, "vhVw:c:n:p:t:H:s:i:b:I:l:m:")) != EOF) { |
450 | switch(arg) { | 454 | switch(arg) { |
451 | case 'v': | 455 | case 'v': |
452 | debug++; | 456 | debug++; |
@@ -489,6 +493,9 @@ main(int argc, char **argv) | |||
489 | crit_down = (unsigned char)strtoul(ptr + 1, NULL, 0); | 493 | crit_down = (unsigned char)strtoul(ptr + 1, NULL, 0); |
490 | } | 494 | } |
491 | break; | 495 | break; |
496 | case 's': /* specify source IP address */ | ||
497 | set_source_ip(optarg); | ||
498 | break; | ||
492 | case 'V': /* version */ | 499 | case 'V': /* version */ |
493 | /*print_revision (progname, revision);*/ /* FIXME: Why? */ | 500 | /*print_revision (progname, revision);*/ /* FIXME: Why? */ |
494 | exit (STATE_OK); | 501 | exit (STATE_OK); |
@@ -1109,6 +1116,38 @@ add_target(char *arg) | |||
1109 | 1116 | ||
1110 | return 0; | 1117 | return 0; |
1111 | } | 1118 | } |
1119 | |||
1120 | static void | ||
1121 | set_source_ip(char *arg) | ||
1122 | { | ||
1123 | struct sockaddr_in src; | ||
1124 | |||
1125 | memset(&src, 0, sizeof(src)); | ||
1126 | src.sin_family = AF_INET; | ||
1127 | if((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) | ||
1128 | src.sin_addr.s_addr = get_ip_address(arg); | ||
1129 | if(bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) | ||
1130 | crash("Cannot bind to IP address %s", arg); | ||
1131 | } | ||
1132 | |||
1133 | /* TODO: Move this to netutils.c and also change check_dhcp to use that. */ | ||
1134 | static in_addr_t | ||
1135 | get_ip_address(const char *ifname) | ||
1136 | { | ||
1137 | #if defined(SIOCGIFADDR) | ||
1138 | struct ifreq ifr; | ||
1139 | |||
1140 | strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); | ||
1141 | ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; | ||
1142 | if(ioctl(icmp_sock, SIOCGIFADDR, &ifr) == -1) | ||
1143 | crash("Cannot determine IP address of interface %s", ifname); | ||
1144 | return ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; | ||
1145 | #else | ||
1146 | errno = 0; | ||
1147 | crash("Cannot get interface IP address on this platform."); | ||
1148 | #endif | ||
1149 | } | ||
1150 | |||
1112 | /* | 1151 | /* |
1113 | * u = micro | 1152 | * u = micro |
1114 | * m = milli | 1153 | * m = milli |
@@ -1231,6 +1270,8 @@ print_help(void) | |||
1231 | printf (" %s\n", "-c"); | 1270 | printf (" %s\n", "-c"); |
1232 | printf (" %s", _("critical threshold (currently ")); | 1271 | printf (" %s", _("critical threshold (currently ")); |
1233 | printf ("%0.3fms,%u%%)\n", (float)crit.rta, crit.pl); | 1272 | printf ("%0.3fms,%u%%)\n", (float)crit.rta, crit.pl); |
1273 | printf (" %s\n", "-s"); | ||
1274 | printf (" %s\n", _("specify a source IP address or device name")); | ||
1234 | printf (" %s\n", "-n"); | 1275 | printf (" %s\n", "-n"); |
1235 | printf (" %s", _("number of packets to send (currently ")); | 1276 | printf (" %s", _("number of packets to send (currently ")); |
1236 | printf ("%u)\n",packets); | 1277 | printf ("%u)\n",packets); |