Changes in uspace/srv/net/app/ping/ping.c [3be62bc:4be390b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/app/ping/ping.c
r3be62bc r4be390b 39 39 #include <task.h> 40 40 #include <time.h> 41 #include <ipc/ipc.h>42 41 #include <ipc/services.h> 43 42 … … 64 63 * @returns EOK on success. 65 64 */ 66 int main(int argc, char * argv[]);65 int main( int argc, char * argv[] ); 67 66 68 67 /** Prints the application help. 69 68 */ 70 void ping_print_help(void); 71 72 int main(int argc, char * argv[]){ 73 ERROR_DECLARE; 74 75 size_t size = 38; 76 int verbose = 0; 77 int dont_fragment = 0; 78 ip_ttl_t ttl = 0; 79 ip_tos_t tos = 0; 80 int count = 3; 81 suseconds_t timeout = 3000; 82 int family = AF_INET; 83 84 socklen_t max_length = sizeof(struct sockaddr_in6); 85 uint8_t address_data[max_length]; 86 struct sockaddr * address = (struct sockaddr *) address_data; 87 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 88 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 89 socklen_t addrlen; 90 char address_string[INET6_ADDRSTRLEN]; 91 uint8_t * address_start; 92 int icmp_phone; 93 struct timeval time_before; 94 struct timeval time_after; 95 int result; 96 int value; 97 int index; 98 99 // print the program label 100 printf("Task %d - ", task_get_id()); 101 printf("%s\n", NAME); 102 103 // parse the command line arguments 104 // stop before the last argument if it does not start with the minus sign ('-') 105 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 106 // options should start with the minus sign ('-') 107 if(argv[index][0] == '-'){ 108 switch(argv[index][1]){ 109 // short options with only one letter 110 case 'c': 111 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "count", 0)); 112 break; 113 case 'f': 114 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 0, parse_address_family)); 115 break; 116 case 'h': 117 ping_print_help(); 118 return EOK; 119 break; 120 case 's': 121 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0)); 122 size = (value >= 0) ? (size_t) value : 0; 123 break; 124 case 't': 125 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "timeout", 0)); 126 timeout = (value >= 0) ? (suseconds_t) value : 0; 127 break; 128 case 'v': 129 verbose = 1; 130 break; 131 // long options with the double minus sign ('-') 132 case '-': 133 if(str_lcmp(argv[index] + 2, "count=", 6) == 0){ 134 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "received count", 8)); 135 }else if(str_lcmp(argv[index] + 2, "dont_fragment", 13) == 0){ 136 dont_fragment = 1; 137 }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 138 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 9, parse_address_family)); 139 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 140 ping_print_help(); 141 return EOK; 142 }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){ 143 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 7)); 144 size = (value >= 0) ? (size_t) value : 0; 145 }else if(str_lcmp(argv[index] + 2, "timeout=", 8) == 0){ 146 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "timeout", 7)); 147 timeout = (value >= 0) ? (suseconds_t) value : 0; 148 }else if(str_lcmp(argv[index] + 2, "tos=", 4) == 0){ 149 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "type of service", 7)); 150 tos = (value >= 0) ? (ip_tos_t) value : 0; 151 }else if(str_lcmp(argv[index] + 2, "ttl=", 4) == 0){ 152 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "time to live", 7)); 153 ttl = (value >= 0) ? (ip_ttl_t) value : 0; 154 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ 155 verbose = 1; 156 }else{ 157 print_unrecognized(index, argv[index] + 2); 158 ping_print_help(); 159 return EINVAL; 160 } 161 break; 162 default: 163 print_unrecognized(index, argv[index] + 1); 164 ping_print_help(); 165 return EINVAL; 166 } 167 }else{ 168 print_unrecognized(index, argv[index]); 169 ping_print_help(); 170 return EINVAL; 171 } 172 } 173 174 // if not before the last argument containing the address 175 if(index >= argc){ 176 printf("Command line error: missing address\n"); 177 ping_print_help(); 178 return EINVAL; 179 } 180 181 // prepare the address buffer 182 bzero(address_data, max_length); 183 switch(family){ 184 case AF_INET: 185 address_in->sin_family = AF_INET; 186 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 187 addrlen = sizeof(struct sockaddr_in); 188 break; 189 case AF_INET6: 190 address_in6->sin6_family = AF_INET6; 191 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 192 addrlen = sizeof(struct sockaddr_in6); 193 break; 194 default: 195 fprintf(stderr, "Address family is not supported\n"); 196 return EAFNOSUPPORT; 197 } 198 199 // parse the last argument which should contain the address 200 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 201 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); 202 return ERROR_CODE; 203 } 204 205 // connect to the ICMP module 206 icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT); 207 if(icmp_phone < 0){ 208 fprintf(stderr, "ICMP connect error %d\n", icmp_phone); 209 return icmp_phone; 210 } 211 212 // print the ping header 213 printf("PING %d bytes of data\n", size); 214 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ 215 fprintf(stderr, "Address error %d\n", ERROR_CODE); 216 }else{ 217 printf("Address %s:\n", address_string); 218 } 219 220 // do count times 221 while(count > 0){ 222 223 // get the starting time 224 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 225 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 226 // release the ICMP phone 227 ipc_hangup(icmp_phone); 228 return ERROR_CODE; 229 } 230 231 // request the ping 232 result = icmp_echo_msg(icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen); 233 234 // get the ending time 235 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 236 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 237 // release the ICMP phone 238 ipc_hangup(icmp_phone); 239 return ERROR_CODE; 240 } 241 242 // print the result 243 switch(result){ 244 case ICMP_ECHO: 245 printf("Ping round trip time %d miliseconds\n", tv_sub(&time_after, &time_before) / 1000); 246 break; 247 case ETIMEOUT: 248 printf("Timed out.\n"); 249 break; 250 default: 251 print_error(stdout, result, NULL, "\n"); 252 } 253 -- count; 254 } 255 256 if(verbose){ 257 printf("Exiting\n"); 258 } 259 260 // release the ICMP phone 261 ipc_hangup(icmp_phone); 262 263 return EOK; 264 } 265 266 void ping_print_help(void){ 69 void print_help( void ); 70 71 /** Translates the character string to the address family number. 72 * @param[in] name The address family name. 73 * @returns The corresponding address family number. 74 * @returns EAFNOSUPPORTED if the address family is not supported. 75 */ 76 int parse_address_family( const char * name ); 77 78 void print_help( void ){ 267 79 printf( 268 80 "Network Ping aplication\n" \ … … 299 111 } 300 112 113 int parse_address_family( const char * name ){ 114 if( str_lcmp( name, "AF_INET", 7 ) == 0 ){ 115 return AF_INET; 116 }else if( str_lcmp( name, "AF_INET6", 8 ) == 0 ){ 117 return AF_INET6; 118 } 119 return EAFNOSUPPORT; 120 } 121 122 int main( int argc, char * argv[] ){ 123 ERROR_DECLARE; 124 125 size_t size = 38; 126 int verbose = 0; 127 int dont_fragment = 0; 128 ip_ttl_t ttl = 0; 129 ip_tos_t tos = 0; 130 int count = 3; 131 suseconds_t timeout = 3000; 132 int family = AF_INET; 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; 142 int icmp_phone; 143 struct timeval time_before; 144 struct timeval time_after; 145 int result; 146 int value; 147 int index; 148 149 printf( "Task %d - ", task_get_id()); 150 printf( "%s\n", NAME ); 151 152 if( argc <= 1 ){ 153 print_help(); 154 return EINVAL; 155 } 156 157 for( index = 1; ( index < argc - 1 ) || (( index == argc ) && ( argv[ index ][ 0 ] == '-' )); ++ index ){ 158 if( argv[ index ][ 0 ] == '-' ){ 159 switch( argv[ index ][ 1 ] ){ 160 case 'c': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "count", 0 )); 161 break; 162 case 'f': ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "address family", 0, parse_address_family )); 163 break; 164 case 'h': print_help(); 165 return EOK; 166 break; 167 case 's': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 0 )); 168 size = (value >= 0 ) ? ( size_t ) value : 0; 169 break; 170 case 't': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "timeout", 0 )); 171 timeout = (value >= 0 ) ? ( suseconds_t ) value : 0; 172 break; 173 case 'v': verbose = 1; 174 break; 175 case '-': if( str_lcmp( argv[ index ] + 2, "count=", 6 ) == 0 ){ 176 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "received count", 8 )); 177 }else if( str_lcmp( argv[ index ] + 2, "dont_fragment", 13 ) == 0 ){ 178 dont_fragment = 1; 179 }else if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){ 180 ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "address family", 9, parse_address_family )); 181 }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){ 182 print_help(); 183 return EOK; 184 }else if( str_lcmp( argv[ index ] + 2, "size=", 5 ) == 0 ){ 185 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 7 )); 186 size = (value >= 0 ) ? ( size_t ) value : 0; 187 }else if( str_lcmp( argv[ index ] + 2, "timeout=", 8 ) == 0 ){ 188 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "timeout", 7 )); 189 timeout = (value >= 0 ) ? ( suseconds_t ) value : 0; 190 }else if( str_lcmp( argv[ index ] + 2, "tos=", 4 ) == 0 ){ 191 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "type of service", 7 )); 192 tos = (value >= 0 ) ? ( ip_tos_t ) value : 0; 193 }else if( str_lcmp( argv[ index ] + 2, "ttl=", 4 ) == 0 ){ 194 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "time to live", 7 )); 195 ttl = (value >= 0 ) ? ( ip_ttl_t ) value : 0; 196 }else if( str_lcmp( argv[ index ] + 2, "verbose", 8 ) == 0 ){ 197 verbose = 1; 198 }else{ 199 print_unrecognized( index, argv[ index ] + 2 ); 200 print_help(); 201 return EINVAL; 202 } 203 break; 204 default: 205 print_unrecognized( index, argv[ index ] + 1 ); 206 print_help(); 207 return EINVAL; 208 } 209 }else{ 210 print_unrecognized( index, argv[ index ] ); 211 print_help(); 212 return EINVAL; 213 } 214 } 215 216 bzero( address_data, max_length ); 217 switch( family ){ 218 case AF_INET: 219 address_in->sin_family = AF_INET; 220 address_start = ( uint8_t * ) & address_in->sin_addr.s_addr; 221 addrlen = sizeof( struct sockaddr_in ); 222 break; 223 case AF_INET6: 224 address_in6->sin6_family = AF_INET6; 225 address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr; 226 addrlen = sizeof( struct sockaddr_in6 ); 227 break; 228 default: 229 fprintf( stderr, "Address family is not supported\n" ); 230 return EAFNOSUPPORT; 231 } 232 233 if( ERROR_OCCURRED( inet_pton( family, argv[ argc - 1 ], address_start ))){ 234 fprintf( stderr, "Address parse error %d\n", ERROR_CODE ); 235 return ERROR_CODE; 236 } 237 238 icmp_phone = icmp_connect_module( SERVICE_ICMP, ICMP_CONNECT_TIMEOUT ); 239 if( icmp_phone < 0 ){ 240 fprintf( stderr, "ICMP connect error %d\n", icmp_phone ); 241 return icmp_phone; 242 } 243 244 printf( "PING %d bytes of data\n", size ); 245 if( ERROR_OCCURRED( inet_ntop( address->sa_family, address_start, address_string, sizeof( address_string )))){ 246 fprintf( stderr, "Address error %d\n", ERROR_CODE ); 247 }else{ 248 printf( "Address %s:\n", address_string ); 249 } 250 251 while( count > 0 ){ 252 if( ERROR_OCCURRED( gettimeofday( & time_before, NULL ))){ 253 fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); 254 return ERROR_CODE; 255 } 256 result = icmp_echo_msg( icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen ); 257 if( ERROR_OCCURRED( gettimeofday( & time_after, NULL ))){ 258 fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); 259 return ERROR_CODE; 260 } 261 switch( result ){ 262 case ICMP_ECHO: 263 printf( "Ping round trip time %d miliseconds\n", tv_sub( & time_after, & time_before ) / 1000 ); 264 break; 265 case ETIMEOUT: 266 printf( "Timed out.\n" ); 267 break; 268 default: 269 print_error( stdout, result, NULL, "\n" ); 270 } 271 -- count; 272 } 273 274 if( verbose ) printf( "Exiting\n" ); 275 276 return EOK; 277 } 278 301 279 /** @} 302 280 */
Note:
See TracChangeset
for help on using the changeset viewer.