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" ); |