|
|
@ -334,7 +334,6 @@ void print_netdata( void );
|
|
|
|
void print_global_stats( void );
|
|
|
|
void print_global_stats( void );
|
|
|
|
void main_loop();
|
|
|
|
void main_loop();
|
|
|
|
void finish();
|
|
|
|
void finish();
|
|
|
|
int handle_random_icmp( FPING_ICMPHDR *p, struct sockaddr *addr, socklen_t addr_len);
|
|
|
|
|
|
|
|
char *sprint_tm( int t );
|
|
|
|
char *sprint_tm( int t );
|
|
|
|
void ev_enqueue(HOST_ENTRY *h);
|
|
|
|
void ev_enqueue(HOST_ENTRY *h);
|
|
|
|
HOST_ENTRY *ev_dequeue();
|
|
|
|
HOST_ENTRY *ev_dequeue();
|
|
|
@ -1661,13 +1660,229 @@ int receive_packet(int socket,
|
|
|
|
return recv_len;
|
|
|
|
return recv_len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef IPV6
|
|
|
|
|
|
|
|
int decode_icmp_ipv4(
|
|
|
|
|
|
|
|
struct sockaddr *response_addr,
|
|
|
|
|
|
|
|
size_t response_addr_len,
|
|
|
|
|
|
|
|
char *reply_buf,
|
|
|
|
|
|
|
|
size_t reply_buf_len,
|
|
|
|
|
|
|
|
unsigned short *id,
|
|
|
|
|
|
|
|
unsigned short *seq
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ip *ip = (struct ip *) reply_buf;
|
|
|
|
|
|
|
|
struct icmp *icp;
|
|
|
|
|
|
|
|
int hlen = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#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;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
hlen = ip->ip_hl << 2;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( reply_buf_len < hlen + ICMP_MINLEN ) {
|
|
|
|
|
|
|
|
/* too short */
|
|
|
|
|
|
|
|
if( verbose_flag )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char buf[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
getnameinfo((struct sockaddr *)&response_addr, sizeof(response_addr), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
|
|
|
|
printf( "received packet too short for ICMP (%d bytes from %s)\n", (int) reply_buf_len, buf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
icp = (struct icmp *)(reply_buf + hlen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( icp->icmp_type != ICMP_ECHOREPLY )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Handle other ICMP packets */
|
|
|
|
|
|
|
|
struct icmp *sent_icmp;
|
|
|
|
|
|
|
|
SEQMAP_VALUE *seqmap_value;
|
|
|
|
|
|
|
|
char addr_ascii[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
HOST_ENTRY *h;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reply icmp packet (hlen + ICMP_MINLEN) followed by "sent packet" (ip + icmp headers) */
|
|
|
|
|
|
|
|
if(reply_buf_len < hlen + ICMP_MINLEN + sizeof(struct ip) + ICMP_MINLEN) {
|
|
|
|
|
|
|
|
/* discard ICMP message if we can't tell that it was caused by us (i.e. if the "sent packet" is not included). */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sent_icmp = (struct icmp *) (reply_buf + hlen + ICMP_MINLEN + sizeof(struct ip));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(sent_icmp->icmp_type != ICMP_ECHO || ntohs(sent_icmp->icmp_id) != ident) {
|
|
|
|
|
|
|
|
/* not caused by us */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), ¤t_time);
|
|
|
|
|
|
|
|
if(seqmap_value == NULL) {
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getnameinfo(response_addr, response_addr_len, addr_ascii, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(icp->icmp_type) {
|
|
|
|
|
|
|
|
case ICMP_UNREACH:
|
|
|
|
|
|
|
|
h = table[seqmap_value->host_nr];
|
|
|
|
|
|
|
|
if( icp->icmp_code > ICMP_UNREACH_MAXTYPE ) {
|
|
|
|
|
|
|
|
print_warning("ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
print_warning("%s from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icmp_unreach_str[icp->icmp_code], addr_ascii, h->host);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( inet_addr( h->host ) == INADDR_NONE )
|
|
|
|
|
|
|
|
print_warning(" (%s)", addr_ascii);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print_warning("\n" );
|
|
|
|
|
|
|
|
num_othericmprcvd++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case ICMP_SOURCEQUENCH:
|
|
|
|
|
|
|
|
case ICMP_REDIRECT:
|
|
|
|
|
|
|
|
case ICMP_TIMXCEED:
|
|
|
|
|
|
|
|
case ICMP_PARAMPROB:
|
|
|
|
|
|
|
|
h = table[seqmap_value->host_nr];
|
|
|
|
|
|
|
|
if(icp->icmp_type <= ICMP_TYPE_STR_MAX) {
|
|
|
|
|
|
|
|
print_warning("%s from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icmp_type_str[icp->icmp_type], addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
print_warning("ICMP %d from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icp->icmp_type, addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if( inet_addr( h->host ) == INADDR_NONE )
|
|
|
|
|
|
|
|
print_warning(" (%s)", addr_ascii );
|
|
|
|
|
|
|
|
print_warning( "\n" );
|
|
|
|
|
|
|
|
num_othericmprcvd++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*id = ntohs(icp->icmp_id);
|
|
|
|
|
|
|
|
*seq = ntohs(icp->icmp_seq);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 1; // success
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
// IPV6
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int decode_icmp_ipv6(
|
|
|
|
|
|
|
|
struct sockaddr *response_addr,
|
|
|
|
|
|
|
|
size_t response_addr_len,
|
|
|
|
|
|
|
|
char *reply_buf,
|
|
|
|
|
|
|
|
size_t reply_buf_len,
|
|
|
|
|
|
|
|
unsigned short *id,
|
|
|
|
|
|
|
|
unsigned short *seq
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct icmp6_hdr *icp;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( reply_buf_len < sizeof(FPING_ICMPHDR) )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if( verbose_flag )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char buf[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
getnameinfo((struct sockaddr *)&response_addr, sizeof(response_addr), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
|
|
|
|
printf( "received packet too short for ICMP (%d bytes from %s)\n", (int) reply_buf_len, buf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0; /* too short */
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
icp = (struct icmp6_hdr *) reply_buf;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( icp->icmp6_type != ICMP6_ECHO_REPLY )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Handle other ICMP packets */
|
|
|
|
|
|
|
|
struct icmp6_hdr *sent_icmp;
|
|
|
|
|
|
|
|
SEQMAP_VALUE *seqmap_value;
|
|
|
|
|
|
|
|
char addr_ascii[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
HOST_ENTRY *h;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reply icmp packet (ICMP_MINLEN) followed by "sent packet" (ip + icmp headers) */
|
|
|
|
|
|
|
|
if(reply_buf_len < ICMP_MINLEN + sizeof(struct ip) + ICMP_MINLEN) {
|
|
|
|
|
|
|
|
/* discard ICMP message if we can't tell that it was caused by us (i.e. if the "sent packet" is not included). */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sent_icmp = (struct icmp6_hdr *) (reply_buf + sizeof(struct icmp6_hdr) + sizeof(struct ip));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(sent_icmp->icmp6_type != ICMP_ECHO || ntohs(sent_icmp->icmp6_id) != ident) {
|
|
|
|
|
|
|
|
/* not caused by us */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp6_seq), ¤t_time);
|
|
|
|
|
|
|
|
if(seqmap_value == NULL) {
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getnameinfo(response_addr, response_addr_len, addr_ascii, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(icp->icmp6_type) {
|
|
|
|
|
|
|
|
case ICMP_UNREACH:
|
|
|
|
|
|
|
|
h = table[seqmap_value->host_nr];
|
|
|
|
|
|
|
|
if( icp->icmp6_code > ICMP_UNREACH_MAXTYPE ) {
|
|
|
|
|
|
|
|
print_warning("ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
print_warning("%s from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icmp_unreach_str[icp->icmp6_code], addr_ascii, h->host);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( inet_addr( h->host ) == INADDR_NONE )
|
|
|
|
|
|
|
|
print_warning(" (%s)", addr_ascii);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print_warning("\n" );
|
|
|
|
|
|
|
|
num_othericmprcvd++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case ICMP_SOURCEQUENCH:
|
|
|
|
|
|
|
|
case ICMP_REDIRECT:
|
|
|
|
|
|
|
|
case ICMP_TIMXCEED:
|
|
|
|
|
|
|
|
case ICMP_PARAMPROB:
|
|
|
|
|
|
|
|
h = table[seqmap_value->host_nr];
|
|
|
|
|
|
|
|
if(icp->icmp6_type <= ICMP_TYPE_STR_MAX) {
|
|
|
|
|
|
|
|
print_warning("%s from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icmp_type_str[icp->icmp6_type], addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
print_warning("ICMP %d from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icp->icmp6_type, addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if( inet_addr( h->host ) == INADDR_NONE )
|
|
|
|
|
|
|
|
print_warning(" (%s)", addr_ascii );
|
|
|
|
|
|
|
|
print_warning( "\n" );
|
|
|
|
|
|
|
|
num_othericmprcvd++;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*id = ntohs(icp->icmp6_id);
|
|
|
|
|
|
|
|
*seq = ntohs(icp->icmp6_seq);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int wait_for_reply(long wait_time)
|
|
|
|
int wait_for_reply(long wait_time)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
int result;
|
|
|
|
static char buffer[4096];
|
|
|
|
static char buffer[4096];
|
|
|
|
struct sockaddr_storage response_addr;
|
|
|
|
struct sockaddr_storage response_addr;
|
|
|
|
int hlen = 0;
|
|
|
|
|
|
|
|
FPING_ICMPHDR *icp;
|
|
|
|
|
|
|
|
int n, avg;
|
|
|
|
int n, avg;
|
|
|
|
HOST_ENTRY *h;
|
|
|
|
HOST_ENTRY *h;
|
|
|
|
long this_reply;
|
|
|
|
long this_reply;
|
|
|
@ -1675,9 +1890,8 @@ int wait_for_reply(long wait_time)
|
|
|
|
struct timeval *sent_time;
|
|
|
|
struct timeval *sent_time;
|
|
|
|
struct timeval recv_time;
|
|
|
|
struct timeval recv_time;
|
|
|
|
SEQMAP_VALUE *seqmap_value;
|
|
|
|
SEQMAP_VALUE *seqmap_value;
|
|
|
|
#ifndef IPV6
|
|
|
|
unsigned short id;
|
|
|
|
struct ip *ip;
|
|
|
|
unsigned short seq;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for the socket to become ready
|
|
|
|
// Wait for the socket to become ready
|
|
|
|
if(wait_time) {
|
|
|
|
if(wait_time) {
|
|
|
@ -1708,73 +1922,30 @@ int wait_for_reply(long wait_time)
|
|
|
|
if(result <= 0) {
|
|
|
|
if(result <= 0) {
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Process ICMP packet and retrieve id/seq
|
|
|
|
|
|
|
|
// unsigned short icmp_id;
|
|
|
|
|
|
|
|
// unsigned short icmp_seq
|
|
|
|
|
|
|
|
//#ifndef IPV6
|
|
|
|
|
|
|
|
// if(!process_icmp_ipv4(response_addr, sizeof(response_addr), buffer, sizeof(buffer),
|
|
|
|
|
|
|
|
// &icmp_id, &icmp_seq))
|
|
|
|
|
|
|
|
//#else
|
|
|
|
|
|
|
|
// if(!process_icmp_ipv6(response_addr, sizeof(response_addr), buffer, sizeof(buffer)
|
|
|
|
|
|
|
|
// &icmp_id, &icmp_seq))
|
|
|
|
|
|
|
|
//#endif
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// return(1);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef IPV6
|
|
|
|
|
|
|
|
ip = ( struct ip* )buffer;
|
|
|
|
|
|
|
|
#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;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
hlen = ip->ip_hl << 2;
|
|
|
|
|
|
|
|
#endif /* defined(__alpha__) && __STDC__ */
|
|
|
|
|
|
|
|
if( result < hlen + ICMP_MINLEN )
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
if( result < sizeof(FPING_ICMPHDR) )
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if( verbose_flag )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char buf[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
getnameinfo((struct sockaddr *)&response_addr, sizeof(response_addr), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
|
|
|
|
printf( "received packet too short for ICMP (%d bytes from %s)\n", result, buf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return( 1 ); /* too short */
|
|
|
|
|
|
|
|
}/* IF */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gettimeofday( ¤t_time, &tz );
|
|
|
|
gettimeofday( ¤t_time, &tz );
|
|
|
|
|
|
|
|
|
|
|
|
icp = ( FPING_ICMPHDR* )( buffer + hlen );
|
|
|
|
// Process ICMP packet and retrieve id/seq
|
|
|
|
#ifndef IPV6
|
|
|
|
#ifndef IPV6
|
|
|
|
if( icp->icmp_type != ICMP_ECHOREPLY )
|
|
|
|
if(!decode_icmp_ipv4(
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
if( icp->icmp6_type != ICMP6_ECHO_REPLY )
|
|
|
|
if(!decode_icmp_ipv6(
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
(struct sockaddr *) &response_addr,
|
|
|
|
/* handle some problem */
|
|
|
|
sizeof(response_addr),
|
|
|
|
if( handle_random_icmp( icp, (struct sockaddr *)&response_addr, sizeof(response_addr) ) )
|
|
|
|
buffer,
|
|
|
|
num_othericmprcvd++;
|
|
|
|
sizeof(buffer),
|
|
|
|
return 1;
|
|
|
|
&id,
|
|
|
|
}/* IF */
|
|
|
|
&seq)
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
return(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef IPV6
|
|
|
|
if( id != ident ) {
|
|
|
|
if( ntohs(icp->icmp_id) != ident )
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
if( ntohs(icp->icmp6_id) != ident )
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 1; /* packet received, but not the one we are looking for! */
|
|
|
|
return 1; /* packet received, but not the one we are looking for! */
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef IPV6
|
|
|
|
seqmap_value = seqmap_fetch(seq, ¤t_time);
|
|
|
|
seqmap_value = seqmap_fetch(ntohs(icp->icmp_seq), ¤t_time);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
seqmap_value = seqmap_fetch(ntohs(icp->icmp6_seq), ¤t_time);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if(seqmap_value == NULL) {
|
|
|
|
if(seqmap_value == NULL) {
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1924,118 +2095,6 @@ int wait_for_reply(long wait_time)
|
|
|
|
|
|
|
|
|
|
|
|
} /* wait_for_reply() */
|
|
|
|
} /* wait_for_reply() */
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Function: handle_random_icmp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int handle_random_icmp(FPING_ICMPHDR *p, struct sockaddr *addr, socklen_t addr_len)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
FPING_ICMPHDR *sent_icmp;
|
|
|
|
|
|
|
|
unsigned char *c;
|
|
|
|
|
|
|
|
HOST_ENTRY *h;
|
|
|
|
|
|
|
|
SEQMAP_VALUE *seqmap_value;
|
|
|
|
|
|
|
|
char addr_ascii[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
unsigned short icmp_type;
|
|
|
|
|
|
|
|
unsigned short icmp_code;
|
|
|
|
|
|
|
|
unsigned short sent_icmp_type;
|
|
|
|
|
|
|
|
unsigned short sent_icmp_seq;
|
|
|
|
|
|
|
|
unsigned short sent_icmp_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getnameinfo((struct sockaddr *) addr, addr_len, addr_ascii, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c = ( unsigned char* )p;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
|
|
|
|
|
|
|
|
#ifndef IPV6
|
|
|
|
|
|
|
|
icmp_type = p->icmp_type;
|
|
|
|
|
|
|
|
icmp_code = p->icmp_code;
|
|
|
|
|
|
|
|
sent_icmp_type = sent_icmp->icmp_type;
|
|
|
|
|
|
|
|
sent_icmp_seq = sent_icmp->icmp_seq;
|
|
|
|
|
|
|
|
sent_icmp_id = sent_icmp->icmp_id;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
icmp_type = p->icmp6_type;
|
|
|
|
|
|
|
|
icmp_code = p->icmp6_code;
|
|
|
|
|
|
|
|
sent_icmp_type = sent_icmp->icmp6_type;
|
|
|
|
|
|
|
|
sent_icmp_seq = sent_icmp->icmp6_seq;
|
|
|
|
|
|
|
|
sent_icmp_id = sent_icmp->icmp6_id;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch(icmp_type)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case ICMP_UNREACH:
|
|
|
|
|
|
|
|
seqmap_value = seqmap_fetch(ntohs(sent_icmp_seq), ¤t_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( ( sent_icmp_type == ICMP_ECHO ) &&
|
|
|
|
|
|
|
|
( ntohs(sent_icmp_id) == ident ) &&
|
|
|
|
|
|
|
|
( seqmap_value != NULL ) )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* this is a response to a ping we sent */
|
|
|
|
|
|
|
|
h = table[ntohs(sent_icmp_seq) % num_hosts];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( icmp_code > ICMP_UNREACH_MAXTYPE ) {
|
|
|
|
|
|
|
|
print_warning("ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
print_warning("%s from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icmp_unreach_str[icmp_code], addr_ascii, h->host);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( inet_addr( h->host ) == INADDR_NONE )
|
|
|
|
|
|
|
|
print_warning(" (%s)", addr_ascii);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print_warning("\n" );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case ICMP_SOURCEQUENCH:
|
|
|
|
|
|
|
|
case ICMP_REDIRECT:
|
|
|
|
|
|
|
|
case ICMP_TIMXCEED:
|
|
|
|
|
|
|
|
case ICMP_PARAMPROB:
|
|
|
|
|
|
|
|
seqmap_value = seqmap_fetch(ntohs(sent_icmp_seq), ¤t_time);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( ( sent_icmp_type == ICMP_ECHO ) &&
|
|
|
|
|
|
|
|
( ntohs(sent_icmp_id) == ident ) &&
|
|
|
|
|
|
|
|
( seqmap_value != NULL ) )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* this is a response to a ping we sent */
|
|
|
|
|
|
|
|
h = table[ntohs(sent_icmp_seq) % num_hosts];
|
|
|
|
|
|
|
|
if(icmp_type <= ICMP_TYPE_STR_MAX) {
|
|
|
|
|
|
|
|
print_warning("%s from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icmp_type_str[icmp_type], addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
print_warning("ICMP %d from %s for ICMP Echo sent to %s",
|
|
|
|
|
|
|
|
icmp_type, addr_ascii, h->host );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( inet_addr( h->host ) == INADDR_NONE )
|
|
|
|
|
|
|
|
print_warning(" (%s)", addr_ascii );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print_warning( "\n" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}/* IF */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* no way to tell whether any of these are sent due to our ping */
|
|
|
|
|
|
|
|
/* or not (shouldn't be, of course), so just discard */
|
|
|
|
|
|
|
|
case ICMP_TSTAMP:
|
|
|
|
|
|
|
|
case ICMP_TSTAMPREPLY:
|
|
|
|
|
|
|
|
case ICMP_IREQ:
|
|
|
|
|
|
|
|
case ICMP_IREQREPLY:
|
|
|
|
|
|
|
|
case ICMP_MASKREQ:
|
|
|
|
|
|
|
|
case ICMP_MASKREPLY:
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}/* SWITCH */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} /* handle_random_icmp() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************
|
|
|
|
/************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
Function: add_name
|
|
|
|
Function: add_name
|
|
|
|