char* prog;
int ident4 = 0; /* our icmp identity field */
int socket4 = -1;
+int using_sock_dgram4 = 0;
#ifndef IPV6
int hints_ai_family = AF_INET;
#else
usage(0);
}
- socket4 = open_ping_socket_ipv4();
+ socket4 = open_ping_socket_ipv4(&using_sock_dgram4);
#ifdef IPV6
socket6 = open_ping_socket_ipv6();
/* if called (sym-linked) via 'fping6', imply '-6'
unsigned short* id,
unsigned short* seq)
{
- struct ip* ip = (struct ip*)reply_buf;
struct icmp* icp;
int hlen = 0;
+ if (!using_sock_dgram4) {
+ struct ip* ip = (struct ip*)reply_buf;
+
#if defined(__alpha__) && __STDC__ && !defined(__GLIBC__)
- /* The alpha headers are decidedly broken.
- * Using an ANSI compiler, it provides ip_vhl instead of ip_hl and
- * ip_v. So, to get ip_hl, we mask off the bottom four bits.
- */
- hlen = (ip->ip_vhl & 0x0F) << 2;
+ /* The alpha headers are decidedly broken.
+ * Using an ANSI compiler, it provides ip_vhl instead of ip_hl and
+ * ip_v. So, to get ip_hl, we mask off the bottom four bits.
+ */
+ hlen = (ip->ip_vhl & 0x0F) << 2;
#else
- hlen = ip->ip_hl << 2;
+ hlen = ip->ip_hl << 2;
#endif
+ }
if (reply_buf_len < hlen + ICMP_MINLEN) {
/* too short */
if (id != ident4) {
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
else if (response_addr.ss_family == AF_INET6) {
extern int random_data_flag;
/* 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 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);
char* ping_buffer_ipv4 = 0;
size_t ping_pkt_size_ipv4;
-int open_ping_socket_ipv4()
+int open_ping_socket_ipv4(int *using_sock_dgram)
{
struct protoent* proto;
int s;
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);
if (s < 0) {
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 */