summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author依云 <lilydjwg@gmail.com>2016-07-29 14:21:59 +0800
committerlilydjwg <lilydjwg@gmail.com>2016-09-17 12:57:55 +0800
commitf455fee41c077d4b700a473b2f5b3487b8febc1d (patch)
tree1cd2fcdd113a83fd77aaf98b07200d07db4ad1f2
parent55828d1fef3fed7f07abcbf7be9282a9662e78c7 (diff)
downloadiputils-f455fee41c077d4b700a473b2f5b3487b8febc1d.tar.gz
ping: also bind the ICMP socket to the specific device
-rw-r--r--ping.c43
-rw-r--r--ping6_common.c6
2 files changed, 28 insertions, 21 deletions
diff --git a/ping.c b/ping.c
index 4455091..e6f6767 100644
--- a/ping.c
+++ b/ping.c
@@ -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);
}