Skip to content

Commit

Permalink
only use getsockname() for identity with SOCK_DGRAM sockets
Browse files Browse the repository at this point in the history
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
  • Loading branch information
tycho committed Jun 10, 2020
1 parent 25e30da commit d2dda2d
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 32 deletions.
19 changes: 14 additions & 5 deletions src/fping.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,14 @@ HOST_ENTRY* ev_last;
char* prog;
int ident4 = 0; /* our icmp identity field */
int socket4 = -1;
int socktype4 = -1;
int using_sock_dgram4 = 0;
#ifndef IPV6
int hints_ai_family = AF_INET;
#else
int ident6 = 0;
int socket6 = -1;
int socktype6 = -1;
int hints_ai_family = AF_UNSPEC;
#endif

Expand Down Expand Up @@ -371,9 +373,16 @@ int main(int argc, char** argv)
usage(0);
}

socket4 = open_ping_socket_ipv4(&using_sock_dgram4);
socket4 = open_ping_socket_ipv4(&socktype4);
#ifdef __linux__
/* We only treat SOCK_DGRAM differently on Linux, where the IPv4 header
* structure is missing in the message.
*/
using_sock_dgram4 = (socktype4 == SOCK_DGRAM);
#endif

#ifdef IPV6
socket6 = open_ping_socket_ipv6();
socket6 = open_ping_socket_ipv6(&socktype6);
/* if called (sym-linked) via 'fping6', imply '-6'
* for backward compatibility */
if (strstr(prog, "fping6")) {
Expand All @@ -393,7 +402,7 @@ int main(int argc, char** argv)
}

optparse_init(&optparse_state, argv);
ident4 = ident6 = getpid() & 0xFFFF;
ident4 = ident6 = htons(getpid() & 0xFFFF);
verbose_flag = 1;
backoff_flag = 1;
opterr = 1;
Expand Down Expand Up @@ -984,11 +993,11 @@ int main(int argc, char** argv)
}

if (socket4 >= 0) {
socket_set_src_addr_ipv4(socket4, &src_addr, &ident4);
socket_set_src_addr_ipv4(socket4, &src_addr, (socktype4 == SOCK_DGRAM) ? &ident4 : NULL);
}
#ifdef IPV6
if (socket6 >= 0) {
socket_set_src_addr_ipv6(socket6, &src_addr6, &ident6);
socket_set_src_addr_ipv6(socket6, &src_addr6, (socktype6 == SOCK_DGRAM) ? &ident6 : NULL);
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/fping.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ int in_cksum( unsigned short *p, int n );
extern int random_data_flag;

/* socket.c */
int open_ping_socket_ipv4(int *using_sock_dgram);
int open_ping_socket_ipv4(int *socktype);
void init_ping_buffer_ipv4(size_t ping_data_size);
void socket_set_src_addr_ipv4(int s, struct in_addr *src_addr, int *ident);
int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq, uint16_t icmp_id);
#ifdef IPV6
int open_ping_socket_ipv6();
int open_ping_socket_ipv6(int *socktype);
void init_ping_buffer_ipv6(size_t ping_data_size);
void socket_set_src_addr_ipv6(int s, struct in6_addr *src_addr, int *ident);
int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq, uint16_t icmp_id);
Expand Down
29 changes: 12 additions & 17 deletions src/socket4.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
char* ping_buffer_ipv4 = 0;
size_t ping_pkt_size_ipv4;

int open_ping_socket_ipv4(int *using_sock_dgram)
int open_ping_socket_ipv4(int *socktype)
{
struct protoent* proto;
int s;
Expand All @@ -56,23 +56,16 @@ int open_ping_socket_ipv4(int *using_sock_dgram)
if ((proto = getprotobyname("icmp")) == NULL)
crash_and_burn("icmp: unknown protocol");

*using_sock_dgram = 0;

/* create raw socket for ICMP calls (ping) */
s = socket(AF_INET, SOCK_RAW, proto->p_proto);
*socktype = SOCK_RAW;
s = socket(AF_INET, *socktype, proto->p_proto);
if (s < 0) {
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */
s = socket(AF_INET, SOCK_DGRAM, proto->p_proto);
*socktype = SOCK_DGRAM;
s = socket(AF_INET, *socktype, proto->p_proto);
if (s < 0) {
return -1;
}

#ifdef __linux__
/* We only treat SOCK_DGRAM differently on Linux, where the IPv4 header
* structure is missing in the message.
*/
*using_sock_dgram = 1;
#endif
}

/* Make sure that we use non-blocking IO */
Expand Down Expand Up @@ -109,12 +102,14 @@ void socket_set_src_addr_ipv4(int s, struct in_addr* src_addr, int *ident)
if (bind(s, (struct sockaddr*)&sa, len) < 0)
errno_crash_and_burn("cannot bind source address");

memset(&sa, 0, len);
if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
errno_crash_and_burn("can't get ICMP socket identity");
if (ident) {
memset(&sa, 0, len);
if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
errno_crash_and_burn("can't get ICMP socket identity");

if (sa.sin_port)
*ident = sa.sin_port;
if (sa.sin_port)
*ident = sa.sin_port;
}
}

unsigned short calcsum(unsigned short* buffer, int length)
Expand Down
20 changes: 12 additions & 8 deletions src/socket6.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
char* ping_buffer_ipv6 = 0;
size_t ping_pkt_size_ipv6;

int open_ping_socket_ipv6()
int open_ping_socket_ipv6(int *socktype)
{
struct protoent* proto;
int s;
Expand All @@ -56,10 +56,12 @@ int open_ping_socket_ipv6()
crash_and_burn("icmp: unknown protocol");

/* create raw socket for ICMP calls (ping) */
s = socket(AF_INET6, SOCK_RAW, proto->p_proto);
*socktype = SOCK_RAW;
s = socket(AF_INET6, *socktype, proto->p_proto);
if (s < 0) {
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */
s = socket(AF_INET6, SOCK_DGRAM, proto->p_proto);
*socktype = SOCK_DGRAM;
s = socket(AF_INET6, *socktype, proto->p_proto);
if (s < 0) {
return -1;
}
Expand Down Expand Up @@ -99,12 +101,14 @@ void socket_set_src_addr_ipv6(int s, struct in6_addr* src_addr, int *ident)
if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0)
errno_crash_and_burn("cannot bind source address");

memset(&sa, 0, len);
if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
errno_crash_and_burn("can't get ICMP socket identity");
if (ident) {
memset(&sa, 0, len);
if (getsockname(s, (struct sockaddr *)&sa, &len) < 0)
errno_crash_and_burn("can't get ICMP socket identity");

if (sa.sin6_port)
*ident = sa.sin6_port;
if (sa.sin6_port)
*ident = sa.sin6_port;
}
}

int socket_sendto_ping_ipv6(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
Expand Down

0 comments on commit d2dda2d

Please sign in to comment.