linux: account for missing IP header block when using SOCK_DGRAM

Linux doesn't include an IP header in the payload when using an
unprivileged SOCK_DGRAM socket.

Signed-off-by: Steven Noonan <steven@uplinklabs.net>
pull/173/head
Steven Noonan 5 years ago
parent 1486bf209b
commit 6bc29919d3
No known key found for this signature in database
GPG Key ID: 408EEB508ED0CD4D

@ -232,6 +232,7 @@ HOST_ENTRY* ev_last;
char* prog; char* prog;
int ident4 = 0; /* our icmp identity field */ int ident4 = 0; /* our icmp identity field */
int socket4 = -1; int socket4 = -1;
int using_sock_dgram4 = 0;
#ifndef IPV6 #ifndef IPV6
int hints_ai_family = AF_INET; int hints_ai_family = AF_INET;
#else #else
@ -359,7 +360,7 @@ int main(int argc, char** argv)
usage(0); usage(0);
} }
socket4 = open_ping_socket_ipv4(); socket4 = open_ping_socket_ipv4(&using_sock_dgram4);
#ifdef IPV6 #ifdef IPV6
socket6 = open_ping_socket_ipv6(); socket6 = open_ping_socket_ipv6();
/* if called (sym-linked) via 'fping6', imply '-6' /* if called (sym-linked) via 'fping6', imply '-6'
@ -1836,10 +1837,12 @@ int decode_icmp_ipv4(
unsigned short* id, unsigned short* id,
unsigned short* seq) unsigned short* seq)
{ {
struct ip* ip = (struct ip*)reply_buf;
struct icmp* icp; struct icmp* icp;
int hlen = 0; int hlen = 0;
if (!using_sock_dgram4) {
struct ip* ip = (struct ip*)reply_buf;
#if defined(__alpha__) && __STDC__ && !defined(__GLIBC__) #if defined(__alpha__) && __STDC__ && !defined(__GLIBC__)
/* The alpha headers are decidedly broken. /* The alpha headers are decidedly broken.
* Using an ANSI compiler, it provides ip_vhl instead of ip_hl and * Using an ANSI compiler, it provides ip_vhl instead of ip_hl and
@ -1849,6 +1852,7 @@ int decode_icmp_ipv4(
#else #else
hlen = ip->ip_hl << 2; hlen = ip->ip_hl << 2;
#endif #endif
}
if (reply_buf_len < hlen + ICMP_MINLEN) { if (reply_buf_len < hlen + ICMP_MINLEN) {
/* too short */ /* too short */
@ -2091,6 +2095,10 @@ int wait_for_reply(long wait_time)
if (id != ident4) { if (id != ident4) {
return 1; /* packet received, but not the one we are looking for! */ return 1; /* packet received, but not the one we are looking for! */
} }
if (using_sock_dgram4) {
/* IP header is not included in read SOCK_DGRAM ICMP responses */
result += sizeof(struct ip);
}
} }
#ifdef IPV6 #ifdef IPV6
else if (response_addr.ss_family == AF_INET6) { else if (response_addr.ss_family == AF_INET6) {

@ -14,7 +14,7 @@ int in_cksum( unsigned short *p, int n );
extern int random_data_flag; extern int random_data_flag;
/* socket.c */ /* socket.c */
int open_ping_socket_ipv4(); int open_ping_socket_ipv4(int *using_sock_dgram);
void init_ping_buffer_ipv4(size_t ping_data_size); 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); 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); int socket_sendto_ping_ipv4(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; char* ping_buffer_ipv4 = 0;
size_t ping_pkt_size_ipv4; size_t ping_pkt_size_ipv4;
int open_ping_socket_ipv4() int open_ping_socket_ipv4(int *using_sock_dgram)
{ {
struct protoent* proto; struct protoent* proto;
int s; int s;
@ -56,6 +56,8 @@ int open_ping_socket_ipv4()
if ((proto = getprotobyname("icmp")) == NULL) if ((proto = getprotobyname("icmp")) == NULL)
crash_and_burn("icmp: unknown protocol"); crash_and_burn("icmp: unknown protocol");
*using_sock_dgram = 0;
/* create raw socket for ICMP calls (ping) */ /* create raw socket for ICMP calls (ping) */
s = socket(AF_INET, SOCK_RAW, proto->p_proto); s = socket(AF_INET, SOCK_RAW, proto->p_proto);
if (s < 0) { if (s < 0) {
@ -64,6 +66,13 @@ int open_ping_socket_ipv4()
if (s < 0) { if (s < 0) {
return -1; 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 */ /* Make sure that we use non-blocking IO */

Loading…
Cancel
Save