int send_ping( int s, HOST_ENTRY *h )
{
- char *buffer;
- FPING_ICMPHDR *icp;
int n;
int myseq;
int ret = 1;
- buffer = ( char* )malloc( ( size_t )ping_pkt_size );
- if( !buffer )
- crash_and_burn( "can't malloc ping packet" );
-
- memset( buffer, 0, ping_pkt_size * sizeof( char ) );
- icp = ( FPING_ICMPHDR* )buffer;
-
gettimeofday( &h->last_send_time, &tz );
myseq = seqmap_add(h->i, h->num_sent, &h->last_send_time);
-#ifndef IPV6
- icp->icmp_type = ICMP_ECHO;
- icp->icmp_code = 0;
- icp->icmp_cksum = 0;
- icp->icmp_seq = htons(myseq);
- icp->icmp_id = htons(ident);
-
- icp->icmp_cksum = in_cksum( ( unsigned short* )icp, ping_pkt_size );
-#else
- icp->icmp6_type = ICMP6_ECHO_REQUEST;
- icp->icmp6_code = 0;
- icp->icmp6_seq = htons(myseq);
- icp->icmp6_id = htons(ident);
-
- icp->icmp6_cksum = 0; // The IPv6 stack calculates the checksum for us...
-#endif
#if defined(DEBUG) || defined(_DEBUG)
if( trace_flag )
printf( "sending [%d] to %s\n", h->num_sent, h->host );
#endif /* DEBUG || _DEBUG */
- n = sendto( s, buffer, ping_pkt_size, 0, (struct sockaddr *) &h->saddr, h->saddr_len);
+ n = socket_sendto_ping(s, (struct sockaddr *) &h->saddr, h->saddr_len, ping_pkt_size, myseq, ident);
if(
(n < 0 || n != ping_pkt_size)
h->waiting++;
num_pingsent++;
last_send_time = h->last_send_time;
- free( buffer );
return(ret);
}
/* fping.c */
void crash_and_burn( char *message );
void errno_crash_and_burn( char *message );
+int in_cksum( unsigned short *p, int n );
/* socket.c */
-int open_ping_socket();
+int open_ping_socket();
void socket_set_src_addr(int s, FPING_INADDR src_addr);
+int socket_sendto_ping(int s, struct sockaddr *saddr, socklen_t saddr_len, size_t ping_pkg_size, uint16_t icmp_seq, uint16_t icmp_id);
#endif
int open_ping_socket_ipv6();
void socket_set_src_addr_ipv4(int s, FPING_INADDR src_addr);
void socket_set_src_addr_ipv6(int s, FPING_INADDR src_addr);
+int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, size_t ping_pkg_size, uint16_t icmp_seq_nr, uint16_t icmp_id_nr);
+int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, size_t ping_pkg_size, uint16_t icmp_seq_nr, uint16_t icmp_id_nr);
int open_ping_socket()
{
socket_set_src_addr_ipv6(s, src_addr);
#endif
}
+
+int socket_sendto_ping(int s, struct sockaddr *saddr, socklen_t saddr_len, size_t ping_pkt_size, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
+{
+#ifndef IPV6
+ return socket_sendto_ping_ipv4(s, saddr, saddr_len, ping_pkt_size, icmp_seq_nr, icmp_id_nr);
+#else
+ return socket_sendto_ping_ipv6(s, saddr, saddr_len, ping_pkt_size, icmp_seq_nr, icmp_id_nr);
+#endif
+}
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
-int open_ping_socket_ipv4()
+char *ping_buffer = 0;
+size_t ping_pkt_size;
+
+int open_ping_socket_ipv4(size_t ping_data_size)
{
struct protoent *proto;
int s;
}
}
+ /* allocate ping buffer */
+ ping_pkt_size = ping_data_size + ICMP_MINLEN;
+ ping_buffer = (char *) calloc(1, ping_pkt_size);
+ if(!ping_buffer)
+ crash_and_burn( "can't malloc ping packet" );
+
return s;
}
if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
errno_crash_and_burn( "cannot bind source address" );
}
+
+int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, size_t ping_pkt_size, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
+{
+ struct icmp *icp;
+ int n;
+
+ icp = (struct icmp *) ping_buffer;
+
+ icp->icmp_type = ICMP_ECHO;
+ icp->icmp_code = 0;
+ icp->icmp_cksum = 0;
+ icp->icmp_seq = htons(icmp_seq_nr);
+ icp->icmp_id = htons(icmp_id_nr);
+ icp->icmp_cksum = in_cksum((unsigned short*) icp, ping_pkt_size );
+
+ n = sendto(s, icp, ping_pkt_size, 0, saddr, saddr_len);
+
+ return n;
+}
#include <netdb.h>
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
-#include <netinet/icmp6.h>
+#include <netinet/icmp6.h>
-int open_ping_socket_ipv6()
+char *ping_buffer = 0;
+size_t ping_pkt_size;
+
+int open_ping_socket_ipv6(size_t ping_data_size)
{
struct protoent *proto;
int opton = 1;
}
}
+ /* allocate ping buffer */
+ ping_pkt_size = ping_data_size + sizeof(struct icmp6_hdr);
+ ping_buffer = (char *) calloc(1, ping_pkt_size);
+ if(!ping_buffer)
+ crash_and_burn( "can't malloc ping packet" );
+
return s;
}
if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
errno_crash_and_burn( "cannot bind source address" );
}
+
+int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
+{
+ struct icmp6_hdr *icp;
+ int n;
+
+ // FIXME: randomization
+ icp = (struct icmp6_hdr *) ping_buffer;
+ if(!icp) {
+ crash_and_burn("can't malloc ping packet");
+ }
+
+ icp->icmp6_type = ICMP6_ECHO_REQUEST;
+ icp->icmp6_code = 0;
+ icp->icmp6_seq = htons(icmp_seq_nr);
+ icp->icmp6_id = htons(icmp_id_nr);
+ icp->icmp6_cksum = 0; // The IPv6 stack calculates the checksum for us...
+
+ n = sendto(s, icp, ping_pkt_size, 0, saddr, saddr_len);
+
+ return n;
+}