Просмотр исходного кода

Change set_source_ip to use inet_pton and explicitly bind to IPv6 addresses.
Should resolve #666

Sebastian Wolf 3 лет назад
Родитель
Сommit
89513b6f56
2 измененных файлов с 20 добавлено и 4 удалено
  1. 1 0
      NEWS
  2. 19 4
      plugins-root/check_icmp.c

+ 1 - 0
NEWS

@@ -4,6 +4,7 @@ This file documents the major additions and syntax changes between releases.
 	FIXES
 	check_ntp_time: Ensure -W/-C (stratum warning/critical thresholds) are available as short options (#661)
 	check_icmp: Fix "Invalid Argument" errors on FreeBSD 13.1 (#659)
+	check_icmp: Fix address binding in ipv6 (#666)
 
 2.4.0 2021-11-18
 	ENHANCEMENTS

+ 19 - 4
plugins-root/check_icmp.c

@@ -1847,12 +1847,27 @@ static int add_target(char *arg) {
 }
 
 static void set_source_ip(char *arg) {
-  struct sockaddr_in src;
+  struct sockaddr_storage src;
+  int result;
+  void *address_offset;
 
   memset(&src, 0, sizeof(src));
-  src.sin_family = address_family;
-  if ((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) {
-    src.sin_addr.s_addr = get_ip_address(arg);
+  src.ss_family = address_family;
+
+  if (address_family == AF_INET) {
+    struct sockaddr_in *src_ipv4 = (struct sockaddr_in *) &src;
+    address_offset = (void *) &src_ipv4->sin_addr.s_addr;
+  }
+  else if (address_family == AF_INET6) {
+    struct sockaddr_in6 *src_ipv6 = (struct sockaddr_in6 *) &src;
+    /* Note: s6_addr is already an array, unlike s_addr */
+    address_offset = (void *) src_ipv6->sin6_addr.s6_addr;
+  }
+
+  result = inet_pton(address_family, arg, address_offset);
+  if (result != 1) {
+    struct sockaddr_in *src_ipv4 = (struct sockaddr_in *) &src;
+    src_ipv4->sin_addr.s_addr = get_ip_address(arg);
   }
   if (bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) {
     crash("Cannot bind to IP address %s", arg);