diff options
author | 依云 <lilydjwg@gmail.com> | 2016-07-29 14:21:59 +0800 |
---|---|---|
committer | lilydjwg <lilydjwg@gmail.com> | 2016-09-17 12:57:55 +0800 |
commit | f455fee41c077d4b700a473b2f5b3487b8febc1d (patch) | |
tree | 1cd2fcdd113a83fd77aaf98b07200d07db4ad1f2 | |
parent | 55828d1fef3fed7f07abcbf7be9282a9662e78c7 (diff) | |
download | iputils-f455fee41c077d4b700a473b2f5b3487b8febc1d.tar.gz |
ping: also bind the ICMP socket to the specific device
-rw-r--r-- | ping.c | 43 | ||||
-rw-r--r-- | ping6_common.c | 6 |
2 files changed, 28 insertions, 21 deletions
@@ -563,31 +563,36 @@ int ping4_run(int argc, char **argv, struct addrinfo *ai, socket_st *sock) } if (device) { struct ifreq ifr; - int rc; + int i; + int fds[2] = {probe_fd, sock->fd}; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, device, IFNAMSIZ-1); - enable_capability_raw(); - rc = setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1); - disable_capability_raw(); - - if (rc == -1) { - if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) { - struct ip_mreqn imr; - if (ioctl(probe_fd, SIOCGIFINDEX, &ifr) < 0) { - fprintf(stderr, "ping: unknown iface %s\n", device); - exit(2); - } - memset(&imr, 0, sizeof(imr)); - imr.imr_ifindex = ifr.ifr_ifindex; - if (setsockopt(probe_fd, SOL_IP, IP_MULTICAST_IF, &imr, sizeof(imr)) == -1) { - perror("ping: IP_MULTICAST_IF"); + for (i = 0; i < 2; i++) { + int fd = fds[i]; + int rc; + enable_capability_raw(); + rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1); + disable_capability_raw(); + + if (rc == -1) { + if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) { + struct ip_mreqn imr; + if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { + fprintf(stderr, "ping: unknown iface %s\n", device); + exit(2); + } + memset(&imr, 0, sizeof(imr)); + imr.imr_ifindex = ifr.ifr_ifindex; + if (setsockopt(fd, SOL_IP, IP_MULTICAST_IF, &imr, sizeof(imr)) == -1) { + perror("ping: IP_MULTICAST_IF"); + exit(2); + } + } else { + perror("ping: SO_BINDTODEVICE"); exit(2); } - } else { - perror("ping: SO_BINDTODEVICE"); - exit(2); } } } diff --git a/ping6_common.c b/ping6_common.c index fa01292..a81f1df 100644 --- a/ping6_common.c +++ b/ping6_common.c @@ -797,9 +797,11 @@ int ping6_run(int argc, char **argv, struct addrinfo *ai, struct socket_st *sock enable_capability_raw(); if ( #ifdef IPV6_RECVPKTINFO - setsockopt(probe_fd, IPPROTO_IPV6, IPV6_PKTINFO, &ipi, sizeof ipi) == -1 && + setsockopt(probe_fd, IPPROTO_IPV6, IPV6_PKTINFO, &ipi, sizeof ipi) == -1 && + setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO, &ipi, sizeof ipi) == -1 && #endif - setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1) == -1) { + setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1) == -1 && + setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1) == -1) { perror("setsockopt(SO_BINDTODEVICE)"); exit(2); } |