Rev 4717 | Rev 4731 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4717 | Rev 4720 | ||
|---|---|---|---|
| Line 40... | Line 40... | ||
| 40 | #include <time.h> |
40 | #include <time.h> |
| 41 | #include <ipc/services.h> |
41 | #include <ipc/services.h> |
| 42 | 42 | ||
| 43 | #include "../../include/icmp_api.h" |
43 | #include "../../include/icmp_api.h" |
| 44 | #include "../../include/in.h" |
44 | #include "../../include/in.h" |
| - | 45 | #include "../../include/in6.h" |
|
| 45 | #include "../../include/inet.h" |
46 | #include "../../include/inet.h" |
| 46 | #include "../../include/ip_codes.h" |
47 | #include "../../include/ip_codes.h" |
| 47 | #include "../../include/socket_codes.h" |
48 | #include "../../include/socket_errno.h" |
| 48 | 49 | ||
| 49 | #include "../../err.h" |
50 | #include "../../err.h" |
| 50 | 51 | ||
| 51 | #include "../parse.h" |
52 | #include "../parse.h" |
| - | 53 | #include "../print_error.h" |
|
| 52 | 54 | ||
| 53 | /** Echo module name. |
55 | /** Echo module name. |
| 54 | */ |
56 | */ |
| 55 | #define NAME "Ping" |
57 | #define NAME "Ping" |
| 56 | 58 | ||
| Line 67... | Line 69... | ||
| 67 | void print_help( void ); |
69 | void print_help( void ); |
| 68 | 70 | ||
| 69 | /** Translates the character string to the address family number. |
71 | /** Translates the character string to the address family number. |
| 70 | * @param name The address family name. Input parameter. |
72 | * @param name The address family name. Input parameter. |
| 71 | * @returns The corresponding address family number. |
73 | * @returns The corresponding address family number. |
| - | 74 | * @returns EAFNOSUPPORTED if the address family is not supported. |
|
| 72 | */ |
75 | */ |
| 73 | int parse_address_family( const char * name ); |
76 | int parse_address_family( const char * name ); |
| 74 | 77 | ||
| 75 | void print_help( void ){ |
78 | void print_help( void ){ |
| 76 | printf( |
79 | printf( |
| 77 | "Network Ping aplication\n" \ |
80 | "Network Ping aplication\n" \ |
| 78 | "Usage: ping [options] numeric_address\n" \ |
81 | "Usage: ping [options] numeric_address\n" \ |
| Line 83... | Line 86... | ||
| 83 | "\n" \ |
86 | "\n" \ |
| 84 | "--dont_fragment\n" \ |
87 | "--dont_fragment\n" \ |
| 85 | "\tDisable packet fragmentation.\n" |
88 | "\tDisable packet fragmentation.\n" |
| 86 | "\n" \ |
89 | "\n" \ |
| 87 | "-f address_family | --family=address_family\n" \ |
90 | "-f address_family | --family=address_family\n" \ |
| 88 | "\tThe given address family. Only the AF_INET is supported.\n" |
91 | "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n" |
| 89 | "\n" \ |
92 | "\n" \ |
| 90 | "-h | --help\n" \ |
93 | "-h | --help\n" \ |
| 91 | "\tShow this application help.\n" |
94 | "\tShow this application help.\n" |
| 92 | "\n" \ |
95 | "\n" \ |
| 93 | "-s packet_size | --size=packet_size\n" \ |
96 | "-s packet_size | --size=packet_size\n" \ |
| Line 108... | Line 111... | ||
| 108 | } |
111 | } |
| 109 | 112 | ||
| 110 | int parse_address_family( const char * name ){ |
113 | int parse_address_family( const char * name ){ |
| 111 | if( str_lcmp( name, "AF_INET", 7 ) == 0 ){ |
114 | if( str_lcmp( name, "AF_INET", 7 ) == 0 ){ |
| 112 | return AF_INET; |
115 | return AF_INET; |
| - | 116 | }else if( str_lcmp( name, "AF_INET6", 8 ) == 0 ){ |
|
| - | 117 | return AF_INET6; |
|
| 113 | } |
118 | } |
| 114 | return ENOENT; |
119 | return EAFNOSUPPORT; |
| 115 | } |
120 | } |
| 116 | 121 | ||
| 117 | int main( int argc, char * argv[] ){ |
122 | int main( int argc, char * argv[] ){ |
| 118 | ERROR_DECLARE; |
123 | ERROR_DECLARE; |
| 119 | 124 | ||
| Line 122... | Line 127... | ||
| 122 | int dont_fragment = 0; |
127 | int dont_fragment = 0; |
| 123 | ip_ttl_t ttl = 0; |
128 | ip_ttl_t ttl = 0; |
| 124 | ip_tos_t tos = 0; |
129 | ip_tos_t tos = 0; |
| 125 | int count = 3; |
130 | int count = 3; |
| 126 | suseconds_t timeout = 3000; |
131 | suseconds_t timeout = 3000; |
| 127 | struct sockaddr_in address = { .sin_family = AF_INET, .sin_port = 7 }; |
132 | int family = AF_INET; |
| 128 | 133 | ||
| - | 134 | socklen_t max_length = sizeof( struct sockaddr_in6 ); |
|
| - | 135 | uint8_t address_data[ max_length ]; |
|
| - | 136 | struct sockaddr * address = ( struct sockaddr * ) address_data; |
|
| - | 137 | struct sockaddr_in * address_in = ( struct sockaddr_in * ) address; |
|
| - | 138 | struct sockaddr_in6 * address_in6 = ( struct sockaddr_in6 * ) address; |
|
| - | 139 | socklen_t addrlen; |
|
| - | 140 | char address_string[ INET6_ADDRSTRLEN ]; |
|
| - | 141 | uint8_t * address_start; |
|
| 129 | int icmp_phone; |
142 | int icmp_phone; |
| 130 | struct timeval time_before; |
143 | struct timeval time_before; |
| 131 | struct timeval time_after; |
144 | struct timeval time_after; |
| 132 | int result; |
145 | int result; |
| 133 | int value; |
146 | int value; |
| Line 139... | Line 152... | ||
| 139 | for( index = 1; index < argc - 1; ++ index ){ |
152 | for( index = 1; index < argc - 1; ++ index ){ |
| 140 | if( argv[ index ][ 0 ] == '-' ){ |
153 | if( argv[ index ][ 0 ] == '-' ){ |
| 141 | switch( argv[ index ][ 1 ] ){ |
154 | switch( argv[ index ][ 1 ] ){ |
| 142 | case 'c': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "count", 0 )); |
155 | case 'c': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "count", 0 )); |
| 143 | break; |
156 | break; |
| 144 | case 'f': ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "address family", 0, parse_address_family )); |
157 | case 'f': ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "address family", 0, parse_address_family )); |
| 145 | address.sin_family = ( uint16_t ) value; |
- | |
| 146 | break; |
158 | break; |
| 147 | case 'h': print_help(); |
159 | case 'h': print_help(); |
| 148 | return EOK; |
160 | return EOK; |
| 149 | break; |
161 | break; |
| 150 | case 's': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 0 )); |
162 | case 's': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 0 )); |
| Line 158... | Line 170... | ||
| 158 | case '-': if( str_lcmp( argv[ index ] + 2, "count=", 6 ) == 0 ){ |
170 | case '-': if( str_lcmp( argv[ index ] + 2, "count=", 6 ) == 0 ){ |
| 159 | ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "received count", 8 )) |
171 | ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "received count", 8 )) |
| 160 | }else if( str_lcmp( argv[ index ] + 2, "dont_fragment", 13 ) == 0 ){ |
172 | }else if( str_lcmp( argv[ index ] + 2, "dont_fragment", 13 ) == 0 ){ |
| 161 | dont_fragment = 1; |
173 | dont_fragment = 1; |
| 162 | }else if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){ |
174 | }else if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){ |
| 163 | ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "address family", 9, parse_address_family )); |
175 | ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "address family", 9, parse_address_family )); |
| 164 | address.sin_family = ( uint16_t ) value; |
- | |
| 165 | }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){ |
176 | }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){ |
| 166 | print_help(); |
177 | print_help(); |
| 167 | return EOK; |
178 | return EOK; |
| 168 | }else if( str_lcmp( argv[ index ] + 2, "size=", 5 ) == 0 ){ |
179 | }else if( str_lcmp( argv[ index ] + 2, "size=", 5 ) == 0 ){ |
| 169 | ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 7 )); |
180 | ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 7 )); |
| Line 195... | Line 206... | ||
| 195 | print_help(); |
206 | print_help(); |
| 196 | return EINVAL; |
207 | return EINVAL; |
| 197 | } |
208 | } |
| 198 | } |
209 | } |
| 199 | 210 | ||
| - | 211 | bzero( address_data, max_length ); |
|
| - | 212 | switch( family ){ |
|
| - | 213 | case AF_INET: |
|
| - | 214 | address_in->sin_family = AF_INET; |
|
| - | 215 | address_start = ( uint8_t * ) & address_in->sin_addr.s_addr; |
|
| - | 216 | addrlen = sizeof( struct sockaddr_in ); |
|
| - | 217 | break; |
|
| - | 218 | case AF_INET6: |
|
| - | 219 | address_in6->sin6_family = AF_INET6; |
|
| - | 220 | address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr; |
|
| - | 221 | addrlen = sizeof( struct sockaddr_in6 ); |
|
| - | 222 | break; |
|
| - | 223 | default: |
|
| - | 224 | fprintf( stderr, "Protocol family is not supported\n" ); |
|
| - | 225 | return EAFNOSUPPORT; |
|
| - | 226 | } |
|
| - | 227 | ||
| 200 | if( ERROR_OCCURRED( inet_pton( address.sin_family, argv[ argc - 1 ], ( uint8_t * ) & address.sin_addr ))){ |
228 | if( ERROR_OCCURRED( inet_pton( family, argv[ argc - 1 ], address_start ))){ |
| 201 | fprintf( stderr, "Address parse error %d\n", ERROR_CODE ); |
229 | fprintf( stderr, "Address parse error %d\n", ERROR_CODE ); |
| 202 | return ERROR_CODE; |
230 | return ERROR_CODE; |
| 203 | } |
231 | } |
| 204 | 232 | ||
| 205 | icmp_phone = icmp_connect_module( SERVICE_ICMP ); |
233 | icmp_phone = icmp_connect_module( SERVICE_ICMP ); |
| 206 | if( icmp_phone < 0 ){ |
234 | if( icmp_phone < 0 ){ |
| 207 | fprintf( stderr, "ICMP connect error %d\n", icmp_phone ); |
235 | fprintf( stderr, "ICMP connect error %d\n", icmp_phone ); |
| 208 | } |
236 | } |
| 209 | 237 | ||
| 210 | printf( "PING %d bytes of data\n", size ); |
238 | printf( "PING %d bytes of data\n", size ); |
| - | 239 | if( ERROR_OCCURRED( inet_ntop( address->sa_family, address_start, address_string, sizeof( address_string )))){ |
|
| - | 240 | fprintf( stderr, "Address error %d\n", ERROR_CODE ); |
|
| - | 241 | }else{ |
|
| - | 242 | printf( "Address %s:\n", address_string ); |
|
| - | 243 | } |
|
| 211 | 244 | ||
| 212 | while( count > 0 ){ |
245 | while( count > 0 ){ |
| 213 | if( ERROR_OCCURRED( gettimeofday( & time_before, NULL ))){ |
246 | if( ERROR_OCCURRED( gettimeofday( & time_before, NULL ))){ |
| 214 | fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); |
247 | fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); |
| 215 | return ERROR_CODE; |
248 | return ERROR_CODE; |
| 216 | } |
249 | } |
| 217 | result = icmp_echo_msg( icmp_phone, size, timeout, ttl, tos, dont_fragment, ( struct sockaddr * ) & address, sizeof( address )); |
250 | result = icmp_echo_msg( icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen ); |
| 218 | if( ERROR_OCCURRED( gettimeofday( & time_after, NULL ))){ |
251 | if( ERROR_OCCURRED( gettimeofday( & time_after, NULL ))){ |
| 219 | fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); |
252 | fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); |
| 220 | return ERROR_CODE; |
253 | return ERROR_CODE; |
| 221 | } |
254 | } |
| 222 | switch( result ){ |
255 | switch( result ){ |
| 223 | case ICMP_ECHO: |
256 | case ICMP_ECHO: |
| 224 | printf( "Ping round trip time %d microseconds\n", tv_sub( & time_after, & time_before )); |
257 | printf( "Ping round trip time %d microseconds\n", tv_sub( & time_after, & time_before )); |
| 225 | break; |
258 | break; |
| 226 | case ELIMIT: |
259 | case ETIMEOUT: |
| 227 | printf( "Timeouted.\n" ); |
260 | printf( "Timeouted.\n" ); |
| 228 | break; |
261 | break; |
| 229 | default: |
262 | default: |
| 230 | printf( "Error %d.\n", result ); |
263 | print_error( stdout, result, NULL, "\n" ); |
| 231 | } |
264 | } |
| 232 | -- count; |
265 | -- count; |
| 233 | } |
266 | } |
| 234 | 267 | ||
| 235 | if( verbose ) printf( "Exiting\n" ); |
268 | if( verbose ) printf( "Exiting\n" ); |