File fping-4.0-fix_ipv6-disabled.patch of Package fping
From bb0eeaaeba6db5a2fe6b63ae6dac11fd4650e056 Mon Sep 17 00:00:00 2001
From: David Schweikert <david@schweikert.ch>
Date: Wed, 21 Feb 2018 17:28:09 +0100
Subject: [PATCH] Fix running on servers with disabled IPv6, fixes #118
---
CHANGELOG.md | 1 +
ci/test-11-nopriv.pl | 2 +-
src/fping.c | 28 ++++++++++++++++------------
src/socket4.c | 2 +-
src/socket6.c | 2 +-
5 files changed, 20 insertions(+), 15 deletions(-)
Index: fping-4.0/src/fping.c
===================================================================
--- fping-4.0.orig/src/fping.c
+++ fping-4.0/src/fping.c
@@ -231,11 +231,11 @@ HOST_ENTRY* ev_last;
char* prog;
int ident; /* our pid */
-int socket4 = 0;
+int socket4 = -1;
#ifndef IPV6
int hints_ai_family = AF_INET;
#else
-int socket6 = 0;
+int socket6 = -1;
int hints_ai_family = AF_UNSPEC;
#endif
@@ -435,14 +435,14 @@ int main(int argc, char** argv)
break;
case 'M':
#ifdef IP_MTU_DISCOVER
- if (socket4) {
+ if (socket4 >= 0) {
int val = IP_PMTUDISC_DO;
if (setsockopt(socket4, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) {
perror("setsockopt IP_MTU_DISCOVER");
}
}
#ifdef IPV6
- if (socket6) {
+ if (socket6 >= 0) {
int val = IPV6_PMTUDISC_DO;
if (setsockopt(socket6, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, sizeof(val))) {
perror("setsockopt IPV6_MTU_DISCOVER");
@@ -624,13 +624,13 @@ int main(int argc, char** argv)
case 'I':
#ifdef SO_BINDTODEVICE
- if (socket4) {
+ if (socket4 >= 0) {
if (setsockopt(socket4, SOL_SOCKET, SO_BINDTODEVICE, optparse_state.optarg, strlen(optparse_state.optarg))) {
perror("binding to specific interface (SO_BINTODEVICE)");
}
}
#ifdef IPV6
- if (socket6) {
+ if (socket6 >= 0) {
if (setsockopt(socket6, SOL_SOCKET, SO_BINDTODEVICE, optparse_state.optarg, strlen(optparse_state.optarg))) {
perror("binding to specific interface (SO_BINTODEVICE), IPV6");
}
@@ -649,13 +649,13 @@ int main(int argc, char** argv)
case 'O':
if (sscanf(optparse_state.optarg, "%i", &tos)) {
- if (socket4) {
+ if (socket4 >= 0) {
if (setsockopt(socket4, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) {
perror("setting type of service octet IP_TOS");
}
}
#if defined(IPV6) && defined(IPV6_TCLASS)
- if (socket6) {
+ if (socket6 >= 0) {
if (setsockopt(socket6, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos))) {
perror("setting type of service octet IPV6_TCLASS");
}
@@ -681,6 +681,10 @@ int main(int argc, char** argv)
/* validate various option settings */
+ if (socket4 < 0 && socket6 < 0) {
+ crash_and_burn("can't create socket (must run as root?)");
+ }
+
if (ttl > 255) {
fprintf(stderr, "%s: ttl %u out of range\n", prog, ttl);
exit(1);
@@ -827,13 +831,13 @@ int main(int argc, char** argv)
/* set the TTL, if the -H option was set (otherwise ttl will be = 0) */
if (ttl > 0) {
- if (socket4) {
+ if (socket4 >= 0) {
if (setsockopt(socket4, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) {
perror("setting time to live");
}
}
#ifdef IPV6
- if (socket6) {
+ if (socket6 >= 0) {
if (setsockopt(socket6, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl))) {
perror("setting time to live");
}
@@ -844,13 +848,13 @@ int main(int argc, char** argv)
#if HAVE_SO_TIMESTAMP
{
int opt = 1;
- if (socket4) {
+ if (socket4 >= 0) {
if (setsockopt(socket4, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt))) {
perror("setting SO_TIMESTAMP option");
}
}
#ifdef IPV6
- if (socket6) {
+ if (socket6 >= 0) {
if (setsockopt(socket6, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt))) {
perror("setting SO_TIMESTAMP option (IPv6)");
}
@@ -928,11 +932,11 @@ int main(int argc, char** argv)
exit(num_noaddress ? 2 : 1);
}
- if (src_addr_set) {
+ if (src_addr_set && socket4 >= 0) {
socket_set_src_addr_ipv4(socket4, &src_addr);
}
#ifdef IPV6
- if (src_addr6_set) {
+ if (src_addr6_set && socket6 >= 0) {
socket_set_src_addr_ipv6(socket6, &src_addr6);
}
#endif
@@ -1626,11 +1630,11 @@ int send_ping(HOST_ENTRY* h)
printf("sending [%d] to %s\n", h->num_sent, h->host);
#endif /* DEBUG || _DEBUG */
- if (h->saddr.ss_family == AF_INET) {
+ if (h->saddr.ss_family == AF_INET && socket4 >= 0) {
n = socket_sendto_ping_ipv4(socket4, (struct sockaddr*)&h->saddr, h->saddr_len, myseq, ident);
}
#ifdef IPV6
- else if (h->saddr.ss_family == AF_INET6) {
+ else if (h->saddr.ss_family == AF_INET6 && socket6 >= 0) {
n = socket_sendto_ping_ipv6(socket6, (struct sockaddr*)&h->saddr, h->saddr_len, myseq, ident);
}
#endif
@@ -1689,9 +1693,9 @@ int socket_can_read(struct timeval* time
select_again:
FD_ZERO(&readset);
FD_ZERO(&writeset);
- FD_SET(socket4, &readset);
+ if(socket4 >= 0) FD_SET(socket4, &readset);
#ifdef IPV6
- FD_SET(socket6, &readset);
+ if(socket6 >= 0) FD_SET(socket6, &readset);
#endif
nfound = select(socketmax + 1, &readset, &writeset, NULL, timeout);
@@ -1706,11 +1710,11 @@ select_again:
}
if (nfound > 0) {
- if (FD_ISSET(socket4, &readset)) {
+ if (socket4 >= 0 && FD_ISSET(socket4, &readset)) {
return socket4;
}
#ifdef IPV6
- if (FD_ISSET(socket6, &readset)) {
+ if (socket6 >= 0 && FD_ISSET(socket6, &readset)) {
return socket6;
}
#endif
Index: fping-4.0/src/socket4.c
===================================================================
--- fping-4.0.orig/src/socket4.c
+++ fping-4.0/src/socket4.c
@@ -62,7 +62,7 @@ int open_ping_socket_ipv4()
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */
s = socket(AF_INET, SOCK_DGRAM, proto->p_proto);
if (s < 0) {
- errno_crash_and_burn("can't create socket (must run as root?)");
+ return -1;
}
}
Index: fping-4.0/src/socket6.c
===================================================================
--- fping-4.0.orig/src/socket6.c
+++ fping-4.0/src/socket6.c
@@ -61,7 +61,7 @@ int open_ping_socket_ipv6()
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */
s = socket(AF_INET6, SOCK_DGRAM, proto->p_proto);
if (s < 0) {
- errno_crash_and_burn("can't create raw socket (must run as root?)");
+ return -1;
}
}