only use getsockname() for identity with SOCK_DGRAM sockets

Signed-off-by: Steven Noonan <steven@uplinklabs.net>
pull/193/head
Steven Noonan 5 years ago committed by David Schweikert
parent 8152668607
commit 6600b04152

@ -260,11 +260,13 @@ char* prog;
int ident4 = 0; /* our icmp identity field */
int ident6 = 0;
int socket4 = -1;
int socktype4 = -1;
int using_sock_dgram4 = 0;
#ifndef IPV6
int hints_ai_family = AF_INET;
#else
int socket6 = -1;
int socktype6 = -1;
int hints_ai_family = AF_UNSPEC;
#endif
@ -406,9 +408,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")) {
@ -428,7 +437,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;
@ -1023,11 +1032,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

@ -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);

@ -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;
@ -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 */
@ -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)

@ -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;
@ -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;
}
@ -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)

Loading…
Cancel
Save