42,13 → 42,15 |
|
#include "../../include/icmp_api.h" |
#include "../../include/in.h" |
#include "../../include/in6.h" |
#include "../../include/inet.h" |
#include "../../include/ip_codes.h" |
#include "../../include/socket_codes.h" |
#include "../../include/socket_errno.h" |
|
#include "../../err.h" |
|
#include "../parse.h" |
#include "../print_error.h" |
|
/** Echo module name. |
*/ |
69,6 → 71,7 |
/** Translates the character string to the address family number. |
* @param name The address family name. Input parameter. |
* @returns The corresponding address family number. |
* @returns EAFNOSUPPORTED if the address family is not supported. |
*/ |
int parse_address_family( const char * name ); |
|
85,7 → 88,7 |
"\tDisable packet fragmentation.\n" |
"\n" \ |
"-f address_family | --family=address_family\n" \ |
"\tThe given address family. Only the AF_INET is supported.\n" |
"\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n" |
"\n" \ |
"-h | --help\n" \ |
"\tShow this application help.\n" |
110,8 → 113,10 |
int parse_address_family( const char * name ){ |
if( str_lcmp( name, "AF_INET", 7 ) == 0 ){ |
return AF_INET; |
}else if( str_lcmp( name, "AF_INET6", 8 ) == 0 ){ |
return AF_INET6; |
} |
return ENOENT; |
return EAFNOSUPPORT; |
} |
|
int main( int argc, char * argv[] ){ |
124,8 → 129,16 |
ip_tos_t tos = 0; |
int count = 3; |
suseconds_t timeout = 3000; |
struct sockaddr_in address = { .sin_family = AF_INET, .sin_port = 7 }; |
int family = AF_INET; |
|
socklen_t max_length = sizeof( struct sockaddr_in6 ); |
uint8_t address_data[ max_length ]; |
struct sockaddr * address = ( struct sockaddr * ) address_data; |
struct sockaddr_in * address_in = ( struct sockaddr_in * ) address; |
struct sockaddr_in6 * address_in6 = ( struct sockaddr_in6 * ) address; |
socklen_t addrlen; |
char address_string[ INET6_ADDRSTRLEN ]; |
uint8_t * address_start; |
int icmp_phone; |
struct timeval time_before; |
struct timeval time_after; |
141,8 → 154,7 |
switch( argv[ index ][ 1 ] ){ |
case 'c': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "count", 0 )); |
break; |
case 'f': ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "address family", 0, parse_address_family )); |
address.sin_family = ( uint16_t ) value; |
case 'f': ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "address family", 0, parse_address_family )); |
break; |
case 'h': print_help(); |
return EOK; |
160,8 → 172,7 |
}else if( str_lcmp( argv[ index ] + 2, "dont_fragment", 13 ) == 0 ){ |
dont_fragment = 1; |
}else if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){ |
ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "address family", 9, parse_address_family )); |
address.sin_family = ( uint16_t ) value; |
ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "address family", 9, parse_address_family )); |
}else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){ |
print_help(); |
return EOK; |
197,7 → 208,24 |
} |
} |
|
if( ERROR_OCCURRED( inet_pton( address.sin_family, argv[ argc - 1 ], ( uint8_t * ) & address.sin_addr ))){ |
bzero( address_data, max_length ); |
switch( family ){ |
case AF_INET: |
address_in->sin_family = AF_INET; |
address_start = ( uint8_t * ) & address_in->sin_addr.s_addr; |
addrlen = sizeof( struct sockaddr_in ); |
break; |
case AF_INET6: |
address_in6->sin6_family = AF_INET6; |
address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr; |
addrlen = sizeof( struct sockaddr_in6 ); |
break; |
default: |
fprintf( stderr, "Protocol family is not supported\n" ); |
return EAFNOSUPPORT; |
} |
|
if( ERROR_OCCURRED( inet_pton( family, argv[ argc - 1 ], address_start ))){ |
fprintf( stderr, "Address parse error %d\n", ERROR_CODE ); |
return ERROR_CODE; |
} |
208,6 → 236,11 |
} |
|
printf( "PING %d bytes of data\n", size ); |
if( ERROR_OCCURRED( inet_ntop( address->sa_family, address_start, address_string, sizeof( address_string )))){ |
fprintf( stderr, "Address error %d\n", ERROR_CODE ); |
}else{ |
printf( "Address %s:\n", address_string ); |
} |
|
while( count > 0 ){ |
if( ERROR_OCCURRED( gettimeofday( & time_before, NULL ))){ |
214,7 → 247,7 |
fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); |
return ERROR_CODE; |
} |
result = icmp_echo_msg( icmp_phone, size, timeout, ttl, tos, dont_fragment, ( struct sockaddr * ) & address, sizeof( address )); |
result = icmp_echo_msg( icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen ); |
if( ERROR_OCCURRED( gettimeofday( & time_after, NULL ))){ |
fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); |
return ERROR_CODE; |
223,11 → 256,11 |
case ICMP_ECHO: |
printf( "Ping round trip time %d microseconds\n", tv_sub( & time_after, & time_before )); |
break; |
case ELIMIT: |
case ETIMEOUT: |
printf( "Timeouted.\n" ); |
break; |
default: |
printf( "Error %d.\n", result ); |
print_error( stdout, result, NULL, "\n" ); |
} |
-- count; |
} |