Changeset b40bfac in mainline for uspace/app/nettest2/nettest2.c
- Timestamp:
- 2010-11-08T07:13:25Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63a1e60
- Parents:
- d70a463 (diff), 3da12d74 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/nettest2/nettest2.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup nettest 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * Networking test 2 application - transfer. 35 */ 34 * Networking test 2 application - transfer. 35 */ 36 37 #include "nettest.h" 38 #include "print_error.h" 36 39 37 40 #include <malloc.h> … … 41 44 #include <time.h> 42 45 #include <arg_parse.h> 43 #include < err.h>46 #include <bool.h> 44 47 45 48 #include <net/in.h> … … 49 52 #include <net/socket_parse.h> 50 53 51 #include "nettest.h" 52 #include "print_error.h" 53 54 /** Echo module name. 55 */ 54 /** Echo module name. */ 56 55 #define NAME "Nettest2" 57 56 58 /** Packet data pattern. 59 */ 57 /** Packet data pattern. */ 60 58 #define NETTEST2_TEXT "Networking test 2 - transfer" 61 59 62 /** Module entry point. 63 * Starts testing. 64 * @param[in] argc The number of command line parameters. 65 * @param[in] argv The command line parameters. 66 * @returns EOK on success. 67 */ 68 int main(int argc, char * argv[]); 69 70 /** Prints the application help. 71 */ 72 void nettest2_print_help(void); 73 74 /** Refreshes the data. 75 * Fills the data block with the NETTEST1_TEXT pattern. 76 * @param[out] data The data block. 77 * @param[in] size The data block size in bytes. 78 */ 79 void nettest2_refresh_data(char * data, size_t size); 80 81 int main(int argc, char * argv[]){ 82 ERROR_DECLARE; 83 84 size_t size = 28; 85 int verbose = 0; 86 sock_type_t type = SOCK_DGRAM; 87 int sockets = 10; 88 int messages = 10; 89 int family = PF_INET; 90 uint16_t port = 7; 91 92 socklen_t max_length = sizeof(struct sockaddr_in6); 93 uint8_t address_data[max_length]; 94 struct sockaddr * address = (struct sockaddr *) address_data; 95 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 96 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 60 static size_t size; 61 static bool verbose; 62 static sock_type_t type; 63 static int sockets; 64 static int messages; 65 static int family; 66 static uint16_t port; 67 68 static void nettest2_print_help(void) 69 { 70 printf( 71 "Network Networking test 2 aplication - UDP transfer\n" 72 "Usage: echo [options] address\n" 73 "Where options are:\n" 74 "-f protocol_family | --family=protocol_family\n" 75 "\tThe listenning socket protocol family. Only the PF_INET and " 76 "PF_INET6 are supported.\n" 77 "\n" 78 "-h | --help\n" 79 "\tShow this application help.\n" 80 "\n" 81 "-m count | --messages=count\n" 82 "\tThe number of messages to send and receive per socket. The " 83 "default is 10.\n" 84 "\n" 85 "-n sockets | --sockets=count\n" 86 "\tThe number of sockets to use. The default is 10.\n" 87 "\n" 88 "-p port_number | --port=port_number\n" 89 "\tThe port number the application should send messages to. The " 90 "default is 7.\n" 91 "\n" 92 "-s packet_size | --size=packet_size\n" 93 "\tThe packet data size the application sends. The default is 29 " 94 "bytes.\n" 95 "\n" 96 "-v | --verbose\n" 97 "\tShow all output messages.\n"); 98 } 99 100 /** Fill buffer with the NETTEST2_TEXT pattern. 101 * 102 * @param buffer Data buffer. 103 * @param size Buffer size in bytes. 104 */ 105 static void nettest2_fill_buffer(char *buffer, size_t size) 106 { 107 size_t length; 108 109 length = 0; 110 while (size > length + sizeof(NETTEST2_TEXT) - 1) { 111 memcpy(buffer + length, NETTEST2_TEXT, 112 sizeof(NETTEST2_TEXT) - 1); 113 length += sizeof(NETTEST2_TEXT) - 1; 114 } 115 116 memcpy(buffer + length, NETTEST2_TEXT, size - length); 117 buffer[size] = '\0'; 118 } 119 120 /** Parse one command-line option. 121 * 122 * @param argc Number of all command-line arguments. 123 * @param argv All command-line arguments. 124 * @param index Current argument index (in, out). 125 */ 126 static int nettest2_parse_opt(int argc, char *argv[], int *index) 127 { 128 int value; 129 int rc; 130 131 switch (argv[*index][1]) { 132 /* 133 * Short options with only one letter 134 */ 135 case 'f': 136 rc = arg_parse_name_int(argc, argv, index, &family, 0, 137 socket_parse_protocol_family); 138 if (rc != EOK) 139 return rc; 140 break; 141 case 'h': 142 nettest2_print_help(); 143 return EOK; 144 break; 145 case 'm': 146 rc = arg_parse_int(argc, argv, index, &messages, 0); 147 if (rc != EOK) 148 return rc; 149 break; 150 case 'n': 151 rc = arg_parse_int(argc, argv, index, &sockets, 0); 152 if (rc != EOK) 153 return rc; 154 break; 155 case 'p': 156 rc = arg_parse_int(argc, argv, index, &value, 0); 157 if (rc != EOK) 158 return rc; 159 port = (uint16_t) value; 160 break; 161 case 's': 162 rc = arg_parse_int(argc, argv, index, &value, 0); 163 if (rc != EOK) 164 return rc; 165 size = (value >= 0) ? (size_t) value : 0; 166 break; 167 case 't': 168 rc = arg_parse_name_int(argc, argv, index, &value, 0, 169 socket_parse_socket_type); 170 if (rc != EOK) 171 return rc; 172 type = (sock_type_t) value; 173 break; 174 case 'v': 175 verbose = true; 176 break; 177 /* 178 * Long options with double dash ('-') 179 */ 180 case '-': 181 if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) { 182 rc = arg_parse_name_int(argc, argv, index, &family, 9, 183 socket_parse_protocol_family); 184 if (rc != EOK) 185 return rc; 186 } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) { 187 nettest2_print_help(); 188 return EOK; 189 } else if (str_lcmp(argv[*index] + 2, "messages=", 6) == 0) { 190 rc = arg_parse_int(argc, argv, index, &messages, 8); 191 if (rc != EOK) 192 return rc; 193 } else if (str_lcmp(argv[*index] + 2, "sockets=", 6) == 0) { 194 rc = arg_parse_int(argc, argv, index, &sockets, 8); 195 if (rc != EOK) 196 return rc; 197 } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) { 198 rc = arg_parse_int(argc, argv, index, &value, 7); 199 if (rc != EOK) 200 return rc; 201 port = (uint16_t) value; 202 } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) { 203 rc = arg_parse_name_int(argc, argv, index, &value, 7, 204 socket_parse_socket_type); 205 if (rc != EOK) 206 return rc; 207 type = (sock_type_t) value; 208 } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) { 209 verbose = 1; 210 } else { 211 nettest2_print_help(); 212 return EINVAL; 213 } 214 break; 215 default: 216 nettest2_print_help(); 217 return EINVAL; 218 } 219 220 return EOK; 221 } 222 223 int main(int argc, char *argv[]) 224 { 225 socklen_t max_length; 226 uint8_t address_data[sizeof(struct sockaddr_in6)]; 227 struct sockaddr *address; 228 struct sockaddr_in *address_in; 229 struct sockaddr_in6 *address_in6; 97 230 socklen_t addrlen; 98 // char address_string[INET6_ADDRSTRLEN]; 99 uint8_t * address_start; 100 101 int * socket_ids; 102 char * data; 103 int value; 231 uint8_t *address_start; 232 233 int *socket_ids; 234 char *data; 104 235 int index; 105 236 struct timeval time_before; 106 237 struct timeval time_after; 107 238 108 // parse the command line arguments 109 // stop before the last argument if it does not start with the minus sign ('-') 110 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 111 // options should start with the minus sign ('-') 112 if(argv[index][0] == '-'){ 113 switch(argv[index][1]){ 114 // short options with only one letter 115 case 'f': 116 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family)); 117 break; 118 case 'h': 119 nettest2_print_help(); 120 return EOK; 121 break; 122 case 'm': 123 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0)); 124 break; 125 case 'n': 126 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0)); 127 break; 128 case 'p': 129 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 130 port = (uint16_t) value; 131 break; 132 case 's': 133 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 134 size = (value >= 0) ? (size_t) value : 0; 135 break; 136 case 't': 137 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 138 type = (sock_type_t) value; 139 break; 140 case 'v': 141 verbose = 1; 142 break; 143 // long options with the double minus sign ('-') 144 case '-': 145 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 146 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family)); 147 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 148 nettest2_print_help(); 149 return EOK; 150 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ 151 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8)); 152 }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){ 153 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8)); 154 }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){ 155 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 156 port = (uint16_t) value; 157 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 158 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type)); 159 type = (sock_type_t) value; 160 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ 161 verbose = 1; 162 }else{ 163 nettest2_print_help(); 164 return EINVAL; 165 } 166 break; 167 default: 168 nettest2_print_help(); 169 return EINVAL; 170 } 171 }else{ 239 int rc; 240 241 size = 28; 242 verbose = false; 243 type = SOCK_DGRAM; 244 sockets = 10; 245 messages = 10; 246 family = PF_INET; 247 port = 7; 248 249 max_length = sizeof(address_data); 250 address = (struct sockaddr *) address_data; 251 address_in = (struct sockaddr_in *) address; 252 address_in6 = (struct sockaddr_in6 *) address; 253 254 /* 255 * Parse the command line arguments. 256 * 257 * Stop before the last argument if it does not start with dash ('-') 258 */ 259 for (index = 1; (index < argc - 1) || ((index == argc - 1) && 260 (argv[index][0] == '-')); ++index) { 261 262 /* Options should start with dash ('-') */ 263 if (argv[index][0] == '-') { 264 rc = nettest2_parse_opt(argc, argv, &index); 265 if (rc != EOK) 266 return rc; 267 } else { 172 268 nettest2_print_help(); 173 269 return EINVAL; … … 175 271 } 176 272 177 / / if not before the last argument containing the address178 if (index >= argc){273 /* If not before the last argument containing the address */ 274 if (index >= argc) { 179 275 printf("Command line error: missing address\n"); 180 276 nettest2_print_help(); … … 182 278 } 183 279 184 / / prepare the address buffer280 /* Prepare the address buffer */ 185 281 bzero(address_data, max_length); 186 switch(family){ 187 case PF_INET: 188 address_in->sin_family = AF_INET; 189 address_in->sin_port = htons(port); 190 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 191 addrlen = sizeof(struct sockaddr_in); 192 break; 193 case PF_INET6: 194 address_in6->sin6_family = AF_INET6; 195 address_in6->sin6_port = htons(port); 196 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 197 addrlen = sizeof(struct sockaddr_in6); 198 break; 199 default: 200 fprintf(stderr, "Address family is not supported\n"); 201 return EAFNOSUPPORT; 202 } 203 204 // parse the last argument which should contain the address 205 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 206 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); 207 return ERROR_CODE; 208 } 209 210 // check the buffer size 211 if(size <= 0){ 212 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 282 283 switch (family) { 284 case PF_INET: 285 address_in->sin_family = AF_INET; 286 address_in->sin_port = htons(port); 287 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 288 addrlen = sizeof(struct sockaddr_in); 289 break; 290 case PF_INET6: 291 address_in6->sin6_family = AF_INET6; 292 address_in6->sin6_port = htons(port); 293 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 294 addrlen = sizeof(struct sockaddr_in6); 295 break; 296 default: 297 fprintf(stderr, "Address family is not supported\n"); 298 return EAFNOSUPPORT; 299 } 300 301 /* Parse the last argument which should contain the address. */ 302 rc = inet_pton(family, argv[argc - 1], address_start); 303 if (rc != EOK) { 304 fprintf(stderr, "Address parse error %d\n", rc); 305 return rc; 306 } 307 308 /* Check data buffer size. */ 309 if (size <= 0) { 310 fprintf(stderr, "Data buffer size too small (%d). Using 1024 " 311 "bytes instead.\n", size); 213 312 size = 1024; 214 313 } 215 314 216 // prepare the buffer 217 // size plus terminating null (\0) 315 /* 316 * Prepare the buffer. Allocate size bytes plus one for terminating 317 * null character. 318 */ 218 319 data = (char *) malloc(size + 1); 219 if (! data){320 if (!data) { 220 321 fprintf(stderr, "Failed to allocate data buffer.\n"); 221 322 return ENOMEM; 222 323 } 223 nettest2_refresh_data(data, size); 224 225 // check the socket count 226 if(sockets <= 0){ 227 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 324 325 /* Fill buffer with a pattern. */ 326 nettest2_fill_buffer(data, size); 327 328 /* Check socket count. */ 329 if (sockets <= 0) { 330 fprintf(stderr, "Socket count too small (%d). Using " 331 "2 instead.\n", sockets); 228 332 sockets = 2; 229 333 } 230 334 231 // prepare the socket buffer 232 // count plus the terminating null (\0) 335 /* 336 * Prepare the socket buffer. 337 * Allocate count entries plus the terminating null (\0) 338 */ 233 339 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 234 if (! socket_ids){340 if (!socket_ids) { 235 341 fprintf(stderr, "Failed to allocate receive buffer.\n"); 236 342 return ENOMEM; … … 238 344 socket_ids[sockets] = NULL; 239 345 240 if (verbose){346 if (verbose) 241 347 printf("Starting tests\n"); 242 } 243 244 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 245 246 if(type == SOCK_STREAM){ 247 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 248 } 249 250 if(verbose){ 348 349 rc = sockets_create(verbose, socket_ids, sockets, family, type); 350 if (rc != EOK) 351 return rc; 352 353 if (type == SOCK_STREAM) { 354 rc = sockets_connect(verbose, socket_ids, sockets, 355 address, addrlen); 356 if (rc != EOK) 357 return rc; 358 } 359 360 if (verbose) 251 361 printf("\n"); 252 } 253 254 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 255 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 256 return ERROR_CODE; 257 } 258 259 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 260 261 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 262 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 263 return ERROR_CODE; 264 } 265 266 if(verbose){ 362 363 rc = gettimeofday(&time_before, NULL); 364 if (rc != EOK) { 365 fprintf(stderr, "Get time of day error %d\n", rc); 366 return rc; 367 } 368 369 rc = sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, 370 &addrlen, data, size, messages); 371 if (rc != EOK) 372 return rc; 373 374 rc = gettimeofday(&time_after, NULL); 375 if (rc != EOK) { 376 fprintf(stderr, "Get time of day error %d\n", rc); 377 return rc; 378 } 379 380 if (verbose) 267 381 printf("\tOK\n"); 268 } 269 270 printf("sendto + recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before)); 271 272 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 273 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 274 return ERROR_CODE; 275 } 276 277 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages)); 278 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 279 280 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 281 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 282 return ERROR_CODE; 283 } 284 285 if(verbose){ 382 383 printf("sendto + recvfrom tested in %d microseconds\n", 384 tv_sub(&time_after, &time_before)); 385 386 rc = gettimeofday(&time_before, NULL); 387 if (rc != EOK) { 388 fprintf(stderr, "Get time of day error %d\n", rc); 389 return rc; 390 } 391 392 rc = sockets_sendto(verbose, socket_ids, sockets, address, addrlen, 393 data, size, messages); 394 if (rc != EOK) 395 return rc; 396 397 rc = sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, 398 data, size, messages); 399 if (rc != EOK) 400 return rc; 401 402 rc = gettimeofday(&time_after, NULL); 403 if (rc != EOK) { 404 fprintf(stderr, "Get time of day error %d\n", rc); 405 return rc; 406 } 407 408 if (verbose) 286 409 printf("\tOK\n"); 287 } 288 289 printf("sendto, recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before)); 290 291 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 292 293 if(verbose){ 410 411 printf("sendto, recvfrom tested in %d microseconds\n", 412 tv_sub(&time_after, &time_before)); 413 414 rc = sockets_close(verbose, socket_ids, sockets); 415 if (rc != EOK) 416 return rc; 417 418 if (verbose) 294 419 printf("\nExiting\n"); 295 }296 420 297 421 return EOK; 298 422 } 299 423 300 void nettest2_print_help(void){301 printf(302 "Network Networking test 2 aplication - UDP transfer\n" \303 "Usage: echo [options] numeric_address\n" \304 "Where options are:\n" \305 "-f protocol_family | --family=protocol_family\n" \306 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"307 "\n" \308 "-h | --help\n" \309 "\tShow this application help.\n"310 "\n" \311 "-m count | --messages=count\n" \312 "\tThe number of messages to send and receive per socket. The default is 10.\n" \313 "\n" \314 "-n sockets | --sockets=count\n" \315 "\tThe number of sockets to use. The default is 10.\n" \316 "\n" \317 "-p port_number | --port=port_number\n" \318 "\tThe port number the application should send messages to. The default is 7.\n" \319 "\n" \320 "-s packet_size | --size=packet_size\n" \321 "\tThe packet data size the application sends. The default is 29 bytes.\n" \322 "\n" \323 "-v | --verbose\n" \324 "\tShow all output messages.\n"325 );326 }327 328 void nettest2_refresh_data(char * data, size_t size){329 size_t length;330 331 // fill the data332 length = 0;333 while(size > length + sizeof(NETTEST2_TEXT) - 1){334 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);335 length += sizeof(NETTEST2_TEXT) - 1;336 }337 memcpy(data + length, NETTEST2_TEXT, size - length);338 data[size] = '\0';339 }340 341 424 /** @} 342 425 */
Note:
See TracChangeset
for help on using the changeset viewer.