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.c131
1 files changed, 74 insertions, 57 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index dcaceddb..6a4239a8 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -208,29 +208,25 @@ typedef enum enum_threshold_mode threshold_mode;
208/** prototypes **/ 208/** prototypes **/
209void print_help(void); 209void print_help(void);
210void print_usage(void); 210void print_usage(void);
211static u_int get_timevar(const char *); 211static u_int get_timevar(const char * /*str*/);
212static u_int get_timevaldiff(struct timeval *, struct timeval *); 212static u_int get_timevaldiff(struct timeval * /*early*/, struct timeval * /*later*/);
213static in_addr_t get_ip_address(const char *); 213static in_addr_t get_ip_address(const char * /*ifname*/);
214static int wait_for_reply(int, u_int); 214static int wait_for_reply(int /*sock*/, u_int /*t*/);
215static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval *); 215static int recvfrom_wto(int /*sock*/, void * /*buf*/, unsigned int /*len*/, struct sockaddr * /*saddr*/, u_int * /*timo*/,
216static int send_icmp_ping(int, struct rta_host *); 216 struct timeval * /*tv*/);
217static int send_icmp_ping(int /*sock*/, struct rta_host * /*host*/);
217static int get_threshold(char *str, threshold *th); 218static int get_threshold(char *str, threshold *th);
218static bool get_threshold2(char *str, size_t length, threshold *, threshold *, threshold_mode mode); 219static bool get_threshold2(char *str, size_t length, threshold * /*warn*/, threshold * /*crit*/, threshold_mode mode);
219static bool parse_threshold2_helper(char *s, size_t length, threshold *thr, threshold_mode mode); 220static bool parse_threshold2_helper(char *s, size_t length, threshold *thr, threshold_mode mode);
220static void run_checks(void); 221static void run_checks(void);
221static void set_source_ip(char *); 222static void set_source_ip(char * /*arg*/);
222static int add_target(char *); 223static int add_target(char * /*arg*/);
223static int add_target_ip(char *, struct sockaddr_storage *); 224static int add_target_ip(char * /*arg*/, struct sockaddr_storage * /*in*/);
224static int handle_random_icmp(unsigned char *, struct sockaddr_storage *); 225static int handle_random_icmp(unsigned char * /*packet*/, struct sockaddr_storage * /*addr*/);
225static void parse_address(struct sockaddr_storage *, char *, int); 226static void parse_address(struct sockaddr_storage * /*addr*/, char * /*address*/, int /*size*/);
226static unsigned short icmp_checksum(uint16_t *, size_t); 227static unsigned short icmp_checksum(uint16_t * /*p*/, size_t /*n*/);
227static void finish(int); 228static void finish(int /*sig*/);
228static void crash(const char *, ...); 229static void crash(const char * /*fmt*/, ...);
229
230/** external **/
231extern int optind;
232extern char *optarg;
233extern char **environ;
234 230
235/** global variables **/ 231/** global variables **/
236static struct rta_host **table, *cursor, *list; 232static struct rta_host **table, *cursor, *list;
@@ -386,7 +382,8 @@ static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icm
386} 382}
387 383
388static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr) { 384static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr) {
389 struct icmp p, sent_icmp; 385 struct icmp p;
386 struct icmp sent_icmp;
390 struct rta_host *host = NULL; 387 struct rta_host *host = NULL;
391 388
392 memcpy(&p, packet, sizeof(p)); 389 memcpy(&p, packet, sizeof(p));
@@ -469,7 +466,9 @@ int main(int argc, char **argv) {
469 int i; 466 int i;
470 char *ptr; 467 char *ptr;
471 long int arg; 468 long int arg;
472 int icmp_sockerrno, udp_sockerrno, tcp_sockerrno; 469 int icmp_sockerrno;
470 int udp_sockerrno;
471 int tcp_sockerrno;
473 int result; 472 int result;
474 struct rta_host *host; 473 struct rta_host *host;
475#ifdef HAVE_SIGACTION 474#ifdef HAVE_SIGACTION
@@ -880,8 +879,10 @@ int main(int argc, char **argv) {
880} 879}
881 880
882static void run_checks(void) { 881static void run_checks(void) {
883 u_int i, t; 882 u_int i;
884 u_int final_wait, time_passed; 883 u_int t;
884 u_int final_wait;
885 u_int time_passed;
885 886
886 /* this loop might actually violate the pkt_interval or target_interval 887 /* this loop might actually violate the pkt_interval or target_interval
887 * settings, but only if there aren't any packets on the wire which 888 * settings, but only if there aren't any packets on the wire which
@@ -940,15 +941,19 @@ static void run_checks(void) {
940 * icmp echo reply : the rest 941 * icmp echo reply : the rest
941 */ 942 */
942static int wait_for_reply(int sock, u_int t) { 943static int wait_for_reply(int sock, u_int t) {
943 int n, hlen; 944 int n;
945 int hlen;
944 static unsigned char buf[65536]; 946 static unsigned char buf[65536];
945 struct sockaddr_storage resp_addr; 947 struct sockaddr_storage resp_addr;
946 union ip_hdr *ip; 948 union ip_hdr *ip;
947 union icmp_packet packet; 949 union icmp_packet packet;
948 struct rta_host *host; 950 struct rta_host *host;
949 struct icmp_ping_data data; 951 struct icmp_ping_data data;
950 struct timeval wait_start, now; 952 struct timeval wait_start;
951 u_int tdiff, i, per_pkt_wait; 953 struct timeval now;
954 u_int tdiff;
955 u_int i;
956 u_int per_pkt_wait;
952 double jitter_tmp; 957 double jitter_tmp;
953 958
954 if (!(packet.buf = malloc(icmp_pkt_size))) { 959 if (!(packet.buf = malloc(icmp_pkt_size))) {
@@ -1045,14 +1050,14 @@ static int wait_for_reply(int sock, u_int t) {
1045 if (address_family == PF_INET) { 1050 if (address_family == PF_INET) {
1046 memcpy(&data, packet.icp->icmp_data, sizeof(data)); 1051 memcpy(&data, packet.icp->icmp_data, sizeof(data));
1047 if (debug > 2) { 1052 if (debug > 2) {
1048 printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp->icmp_id), 1053 printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", sizeof(data), ntohs(packet.icp->icmp_id),
1049 ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum); 1054 ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum);
1050 } 1055 }
1051 host = table[ntohs(packet.icp->icmp_seq) / packets]; 1056 host = table[ntohs(packet.icp->icmp_seq) / packets];
1052 } else { 1057 } else {
1053 memcpy(&data, &packet.icp6->icmp6_dataun.icmp6_un_data8[4], sizeof(data)); 1058 memcpy(&data, &packet.icp6->icmp6_dataun.icmp6_un_data8[4], sizeof(data));
1054 if (debug > 2) { 1059 if (debug > 2) {
1055 printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp6->icmp6_id), 1060 printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", sizeof(data), ntohs(packet.icp6->icmp6_id),
1056 ntohs(packet.icp6->icmp6_seq), packet.icp6->icmp6_cksum); 1061 ntohs(packet.icp6->icmp6_seq), packet.icp6->icmp6_cksum);
1057 } 1062 }
1058 host = table[ntohs(packet.icp6->icmp6_seq) / packets]; 1063 host = table[ntohs(packet.icp6->icmp6_seq) / packets];
@@ -1182,8 +1187,8 @@ static int send_icmp_ping(int sock, struct rta_host *host) {
1182 icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size); 1187 icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size);
1183 1188
1184 if (debug > 2) { 1189 if (debug > 2) {
1185 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", (unsigned long)sizeof(data), 1190 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", sizeof(data), ntohs(icp->icmp_id),
1186 ntohs(icp->icmp_id), ntohs(icp->icmp_seq), icp->icmp_cksum, host->name); 1191 ntohs(icp->icmp_seq), icp->icmp_cksum, host->name);
1187 } 1192 }
1188 } else { 1193 } else {
1189 struct icmp6_hdr *icp6 = (struct icmp6_hdr *)buf; 1194 struct icmp6_hdr *icp6 = (struct icmp6_hdr *)buf;
@@ -1199,8 +1204,8 @@ static int send_icmp_ping(int sock, struct rta_host *host) {
1199 // let checksum be calculated automatically 1204 // let checksum be calculated automatically
1200 1205
1201 if (debug > 2) { 1206 if (debug > 2) {
1202 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", (unsigned long)sizeof(data), 1207 printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", sizeof(data), ntohs(icp6->icmp6_id),
1203 ntohs(icp6->icmp6_id), ntohs(icp6->icmp6_seq), icp6->icmp6_cksum, host->name); 1208 ntohs(icp6->icmp6_seq), icp6->icmp6_cksum, host->name);
1204 } 1209 }
1205 } 1210 }
1206 1211
@@ -1228,7 +1233,7 @@ static int send_icmp_ping(int sock, struct rta_host *host) {
1228 if (len < 0 || (unsigned int)len != icmp_pkt_size) { 1233 if (len < 0 || (unsigned int)len != icmp_pkt_size) {
1229 if (debug) { 1234 if (debug) {
1230 char address[INET6_ADDRSTRLEN]; 1235 char address[INET6_ADDRSTRLEN];
1231 parse_address((struct sockaddr_storage *)&host->saddr_in, address, sizeof(address)); 1236 parse_address((&host->saddr_in), address, sizeof(address));
1232 printf("Failed to send ping to %s: %s\n", address, strerror(errno)); 1237 printf("Failed to send ping to %s: %s\n", address, strerror(errno));
1233 } 1238 }
1234 errno = 0; 1239 errno = 0;
@@ -1243,9 +1248,13 @@ static int send_icmp_ping(int sock, struct rta_host *host) {
1243 1248
1244static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, u_int *timo, struct timeval *tv) { 1249static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, u_int *timo, struct timeval *tv) {
1245 u_int slen; 1250 u_int slen;
1246 int n, ret; 1251 int n;
1247 struct timeval to, then, now; 1252 int ret;
1248 fd_set rd, wr; 1253 struct timeval to;
1254 struct timeval then;
1255 struct timeval now;
1256 fd_set rd;
1257 fd_set wr;
1249#ifdef HAVE_MSGHDR_MSG_CONTROL 1258#ifdef HAVE_MSGHDR_MSG_CONTROL
1250 char ans_data[4096]; 1259 char ans_data[4096];
1251#endif // HAVE_MSGHDR_MSG_CONTROL 1260#endif // HAVE_MSGHDR_MSG_CONTROL
@@ -1701,8 +1710,10 @@ static u_int get_timevaldiff(struct timeval *early, struct timeval *later) {
1701 1710
1702static int add_target_ip(char *arg, struct sockaddr_storage *in) { 1711static int add_target_ip(char *arg, struct sockaddr_storage *in) {
1703 struct rta_host *host; 1712 struct rta_host *host;
1704 struct sockaddr_in *sin, *host_sin; 1713 struct sockaddr_in *sin;
1705 struct sockaddr_in6 *sin6, *host_sin6; 1714 struct sockaddr_in *host_sin;
1715 struct sockaddr_in6 *sin6;
1716 struct sockaddr_in6 *host_sin6;
1706 1717
1707 if (address_family == AF_INET) { 1718 if (address_family == AF_INET) {
1708 sin = (struct sockaddr_in *)in; 1719 sin = (struct sockaddr_in *)in;
@@ -1786,9 +1797,12 @@ static int add_target_ip(char *arg, struct sockaddr_storage *in) {
1786 1797
1787/* wrapper for add_target_ip */ 1798/* wrapper for add_target_ip */
1788static int add_target(char *arg) { 1799static int add_target(char *arg) {
1789 int error, result = -1; 1800 int error;
1801 int result = -1;
1790 struct sockaddr_storage ip; 1802 struct sockaddr_storage ip;
1791 struct addrinfo hints, *res, *p; 1803 struct addrinfo hints;
1804 struct addrinfo *res;
1805 struct addrinfo *p;
1792 struct sockaddr_in *sin; 1806 struct sockaddr_in *sin;
1793 struct sockaddr_in6 *sin6; 1807 struct sockaddr_in6 *sin6;
1794 1808
@@ -1826,22 +1840,21 @@ static int add_target(char *arg) {
1826 if (result == 1) { 1840 if (result == 1) {
1827 /* don't add all ip's if we were given a specific one */ 1841 /* don't add all ip's if we were given a specific one */
1828 return add_target_ip(arg, &ip); 1842 return add_target_ip(arg, &ip);
1843 }
1844 errno = 0;
1845 memset(&hints, 0, sizeof(hints));
1846 if (address_family == -1) {
1847 hints.ai_family = AF_UNSPEC;
1829 } else { 1848 } else {
1849 hints.ai_family = address_family == AF_INET ? PF_INET : PF_INET6;
1850 }
1851 hints.ai_socktype = SOCK_RAW;
1852 if ((error = getaddrinfo(arg, NULL, &hints, &res)) != 0) {
1830 errno = 0; 1853 errno = 0;
1831 memset(&hints, 0, sizeof(hints)); 1854 crash("Failed to resolve %s: %s", arg, gai_strerror(error));
1832 if (address_family == -1) { 1855 return -1;
1833 hints.ai_family = AF_UNSPEC;
1834 } else {
1835 hints.ai_family = address_family == AF_INET ? PF_INET : PF_INET6;
1836 }
1837 hints.ai_socktype = SOCK_RAW;
1838 if ((error = getaddrinfo(arg, NULL, &hints, &res)) != 0) {
1839 errno = 0;
1840 crash("Failed to resolve %s: %s", arg, gai_strerror(error));
1841 return -1;
1842 }
1843 address_family = res->ai_family;
1844 } 1856 }
1857 address_family = res->ai_family;
1845 1858
1846 /* possibly add all the IP's as targets */ 1859 /* possibly add all the IP's as targets */
1847 for (p = res; p != NULL; p = p->ai_next) { 1860 for (p = res; p != NULL; p = p->ai_next) {
@@ -1907,9 +1920,12 @@ static in_addr_t get_ip_address(const char *ifname) {
1907 * return value is in microseconds 1920 * return value is in microseconds
1908 */ 1921 */
1909static u_int get_timevar(const char *str) { 1922static u_int get_timevar(const char *str) {
1910 char p, u, *ptr; 1923 char p;
1924 char u;
1925 char *ptr;
1911 size_t len; 1926 size_t len;
1912 u_int i, d; /* integer and decimal, respectively */ 1927 u_int i;
1928 u_int d; /* integer and decimal, respectively */
1913 u_int factor = 1000; /* default to milliseconds */ 1929 u_int factor = 1000; /* default to milliseconds */
1914 1930
1915 if (!str) { 1931 if (!str) {
@@ -1970,7 +1986,8 @@ static u_int get_timevar(const char *str) {
1970 1986
1971/* not too good at checking errors, but it'll do (main() should barfe on -1) */ 1987/* not too good at checking errors, but it'll do (main() should barfe on -1) */
1972static int get_threshold(char *str, threshold *th) { 1988static int get_threshold(char *str, threshold *th) {
1973 char *p = NULL, i = 0; 1989 char *p = NULL;
1990 char i = 0;
1974 1991
1975 if (!str || !strlen(str) || !th) { 1992 if (!str || !strlen(str) || !th) {
1976 return -1; 1993 return -1;