Changeset 60ab6c3 in mainline for uspace/srv/net/app/nettest2/nettest2.c
- Timestamp:
- 2010-03-10T05:46:54Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5782081
- Parents:
- 71b00dcc (diff), b48ebd19 (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/srv/net/app/nettest2/nettest2.c
r71b00dcc r60ab6c3 48 48 #include "../../err.h" 49 49 50 #include "../nettest.h" 50 51 #include "../parse.h" 51 52 #include "../print_error.h" … … 69 70 /** Prints the application help. 70 71 */ 71 void print_help(void); 72 73 /** Translates the character string to the protocol family number. 74 * @param[in] name The protocol family name. 75 * @returns The corresponding protocol family number. 76 * @returns EPFNOSUPPORTED if the protocol family is not supported. 77 */ 78 int parse_protocol_family(const char * name); 79 80 /** Translates the character string to the socket type number. 81 * @param[in] name The socket type name. 82 * @returns The corresponding socket type number. 83 * @returns ESOCKNOSUPPORTED if the socket type is not supported. 84 */ 85 int parse_socket_type(const char * name); 72 void nettest2_print_help(void); 86 73 87 74 /** Refreshes the data. … … 90 77 * @param[in] size The data block size in bytes. 91 78 */ 92 void refresh_data(char * data, size_t size); 93 94 /** Creates new sockets. 95 * @param[in] verbose A value indicating whether to print out verbose information. 96 * @param[out] socket_ids A field to store the socket identifiers. 97 * @param[in] sockets The number of sockets to create. Should be at most the size of the field. 98 * @param[in] family The socket address family. 99 * @param[in] type The socket type. 100 * @returns EOK on success. 101 * @returns Other error codes as defined for the socket() function. 102 */ 103 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type); 104 105 /** Closes sockets. 106 * @param[in] verbose A value indicating whether to print out verbose information. 107 * @param[in] socket_ids A field of stored socket identifiers. 108 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 109 * @returns EOK on success. 110 * @returns Other error codes as defined for the closesocket() function. 111 */ 112 int sockets_close(int verbose, int * socket_ids, int sockets); 113 114 /** Connects sockets. 115 * @param[in] verbose A value indicating whether to print out verbose information. 116 * @param[in] socket_ids A field of stored socket identifiers. 117 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 118 * @param[in] address The destination host address to connect to. 119 * @param[in] addrlen The length of the destination address in bytes. 120 * @returns EOK on success. 121 * @returns Other error codes as defined for the connect() function. 122 */ 123 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen); 124 125 /** Sends data via sockets. 126 * @param[in] verbose A value indicating whether to print out verbose information. 127 * @param[in] socket_ids A field of stored socket identifiers. 128 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 129 * @param[in] address The destination host address to send data to. 130 * @param[in] addrlen The length of the destination address in bytes. 131 * @param[in] data The data to be sent. 132 * @param[in] size The data size in bytes. 133 * @param[in] messages The number of datagrams per socket to be sent. 134 * @returns EOK on success. 135 * @returns Other error codes as defined for the sendto() function. 136 */ 137 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages); 138 139 /** Receives data via sockets. 140 * @param[in] verbose A value indicating whether to print out verbose information. 141 * @param[in] socket_ids A field of stored socket identifiers. 142 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 143 * @param[in] address The source host address of received datagrams. 144 * @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead. 145 * @param[out] data The received data. 146 * @param[in] size The maximum data size in bytes. 147 * @param[in] messages The number of datagrams per socket to be received. 148 * @returns EOK on success. 149 * @returns Other error codes as defined for the recvfrom() function. 150 */ 151 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 152 153 /** Sends and receives data via sockets. 154 * Each datagram is sent and a reply read consequently. 155 * The next datagram is sent after the reply is received. 156 * @param[in] verbose A value indicating whether to print out verbose information. 157 * @param[in] socket_ids A field of stored socket identifiers. 158 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 159 * @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead. 160 * @param[in] addrlen The length of the destination address in bytes. 161 * @param[in,out] data The data to be sent. The received data are set instead. 162 * @param[in] size The data size in bytes. 163 * @param[in] messages The number of datagrams per socket to be received. 164 * @returns EOK on success. 165 * @returns Other error codes as defined for the recvfrom() function. 166 */ 167 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 168 169 /** Prints a mark. 170 * If the index is a multiple of ten, a different mark is printed. 171 * @param[in] index The index of the mark to be printed. 172 */ 173 void print_mark(int index); 174 175 void print_help(void){ 176 printf( 177 "Network Networking test 2 aplication - UDP transfer\n" \ 178 "Usage: echo [options] numeric_address\n" \ 179 "Where options are:\n" \ 180 "-f protocol_family | --family=protocol_family\n" \ 181 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n" 182 "\n" \ 183 "-h | --help\n" \ 184 "\tShow this application help.\n" 185 "\n" \ 186 "-m count | --messages=count\n" \ 187 "\tThe number of messages to send and receive per socket. The default is 10.\n" \ 188 "\n" \ 189 "-n sockets | --sockets=count\n" \ 190 "\tThe number of sockets to use. The default is 10.\n" \ 191 "\n" \ 192 "-p port_number | --port=port_number\n" \ 193 "\tThe port number the application should send messages to. The default is 7.\n" \ 194 "\n" \ 195 "-s packet_size | --size=packet_size\n" \ 196 "\tThe packet data size the application sends. The default is 29 bytes.\n" \ 197 "\n" \ 198 "-v | --verbose\n" \ 199 "\tShow all output messages.\n" 200 ); 201 } 202 203 int parse_protocol_family(const char * name){ 204 if(str_lcmp(name, "PF_INET", 7) == 0){ 205 return PF_INET; 206 }else if(str_lcmp(name, "PF_INET6", 8) == 0){ 207 return PF_INET6; 208 } 209 return EPFNOSUPPORT; 210 } 211 212 int parse_socket_type(const char * name){ 213 if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){ 214 return SOCK_DGRAM; 215 }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){ 216 return SOCK_STREAM; 217 } 218 return ESOCKTNOSUPPORT; 219 } 220 221 void refresh_data(char * data, size_t size){ 222 size_t length; 223 224 // fill the data 225 length = 0; 226 while(size > length + sizeof(NETTEST2_TEXT) - 1){ 227 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1); 228 length += sizeof(NETTEST2_TEXT) - 1; 229 } 230 memcpy(data + length, NETTEST2_TEXT, size - length); 231 data[size] = '\0'; 232 } 233 234 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){ 235 int index; 236 237 if(verbose){ 238 printf("Create\t"); 239 } 240 fflush(stdout); 241 for(index = 0; index < sockets; ++ index){ 242 socket_ids[index] = socket(family, type, 0); 243 if(socket_ids[index] < 0){ 244 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 245 socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n"); 246 return socket_ids[index]; 247 } 248 if(verbose){ 249 print_mark(index); 250 } 251 } 252 return EOK; 253 } 254 255 int sockets_close(int verbose, int * socket_ids, int sockets){ 256 ERROR_DECLARE; 257 258 int index; 259 260 if(verbose){ 261 printf("\tClose\t"); 262 } 263 fflush(stdout); 264 for(index = 0; index < sockets; ++ index){ 265 if(ERROR_OCCURRED(closesocket(socket_ids[index]))){ 266 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 267 socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n"); 268 return ERROR_CODE; 269 } 270 if(verbose){ 271 print_mark(index); 272 } 273 } 274 return EOK; 275 } 276 277 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){ 278 ERROR_DECLARE; 279 280 int index; 281 282 if(verbose){ 283 printf("\tConnect\t"); 284 } 285 fflush(stdout); 286 for(index = 0; index < sockets; ++ index){ 287 if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){ 288 socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n"); 289 return ERROR_CODE; 290 } 291 if(verbose){ 292 print_mark(index); 293 } 294 } 295 return EOK; 296 } 297 298 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){ 299 ERROR_DECLARE; 300 301 int index; 302 int message; 303 304 if(verbose){ 305 printf("\tSendto\t"); 306 } 307 fflush(stdout); 308 for(index = 0; index < sockets; ++ index){ 309 for(message = 0; message < messages; ++ message){ 310 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){ 311 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 312 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 313 return ERROR_CODE; 314 } 315 } 316 if(verbose){ 317 print_mark(index); 318 } 319 } 320 return EOK; 321 } 322 323 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 324 int value; 325 int index; 326 int message; 327 328 if(verbose){ 329 printf("\tRecvfrom\t"); 330 } 331 fflush(stdout); 332 for(index = 0; index < sockets; ++ index){ 333 for(message = 0; message < messages; ++ message){ 334 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 335 if(value < 0){ 336 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 337 socket_print_error(stderr, value, "Socket receive: ", "\n"); 338 return value; 339 } 340 } 341 if(verbose){ 342 print_mark(index); 343 } 344 } 345 return EOK; 346 } 347 348 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 349 ERROR_DECLARE; 350 351 int value; 352 int index; 353 int message; 354 355 if(verbose){ 356 printf("\tSendto and recvfrom\t"); 357 } 358 fflush(stdout); 359 for(index = 0; index < sockets; ++ index){ 360 for(message = 0; message < messages; ++ message){ 361 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){ 362 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 363 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 364 return ERROR_CODE; 365 } 366 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 367 if(value < 0){ 368 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 369 socket_print_error(stderr, value, "Socket receive: ", "\n"); 370 return value; 371 } 372 } 373 if(verbose){ 374 print_mark(index); 375 } 376 } 377 return EOK; 378 } 379 380 void print_mark(int index){ 381 if((index + 1) % 10){ 382 printf("*"); 383 }else{ 384 printf("|"); 385 } 386 fflush(stdout); 387 } 79 void nettest2_refresh_data(char * data, size_t size); 388 80 389 81 int main(int argc, char * argv[]){ … … 392 84 size_t size = 28; 393 85 int verbose = 0; 394 sock_type_t type 86 sock_type_t type = SOCK_DGRAM; 395 87 int sockets = 10; 396 88 int messages = 10; 397 89 int family = PF_INET; 398 uint16_t port 399 400 socklen_t max_length = sizeof(struct sockaddr_in6);90 uint16_t port = 7; 91 92 socklen_t max_length = sizeof(struct sockaddr_in6); 401 93 uint8_t address_data[max_length]; 402 struct sockaddr * address = (struct sockaddr *) address_data;94 struct sockaddr * address = (struct sockaddr *) address_data; 403 95 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 404 96 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 405 97 socklen_t addrlen; 406 // char 98 // char address_string[INET6_ADDRSTRLEN]; 407 99 uint8_t * address_start; 408 100 409 101 int * socket_ids; 410 char * 102 char * data; 411 103 int value; 412 104 int index; … … 417 109 printf("%s\n", NAME); 418 110 419 if(argc <= 1){ 420 print_help(); 421 return EINVAL; 422 } 423 424 for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){ 111 // parse the command line arguments 112 // stop before the last argument if it does not start with the minus sign ('-') 113 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 114 // options should start with the minus sign ('-') 425 115 if(argv[index][0] == '-'){ 426 116 switch(argv[index][1]){ 117 // short options with only one letter 427 118 case 'f': 428 119 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family)); 429 120 break; 430 121 case 'h': 431 print_help();122 nettest2_print_help(); 432 123 return EOK; 433 124 break; … … 453 144 verbose = 1; 454 145 break; 146 // long options with the double minus sign ('-') 455 147 case '-': 456 148 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 457 149 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family)); 458 150 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 459 print_help();151 nettest2_print_help(); 460 152 return EOK; 461 153 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ … … 473 165 }else{ 474 166 print_unrecognized(index, argv[index] + 2); 475 print_help();167 nettest2_print_help(); 476 168 return EINVAL; 477 169 } … … 479 171 default: 480 172 print_unrecognized(index, argv[index] + 1); 481 print_help();173 nettest2_print_help(); 482 174 return EINVAL; 483 175 } 484 176 }else{ 485 177 print_unrecognized(index, argv[index]); 486 print_help();178 nettest2_print_help(); 487 179 return EINVAL; 488 180 } 489 181 } 490 182 183 // if not before the last argument containing the address 184 if(index >= argc){ 185 printf("Command line error: missing address\n"); 186 nettest2_print_help(); 187 return EINVAL; 188 } 189 190 // prepare the address buffer 491 191 bzero(address_data, max_length); 492 192 switch(family){ … … 508 208 } 509 209 210 // parse the last argument which should contain the address 510 211 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 511 212 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); … … 513 214 } 514 215 216 // check the buffer size 515 217 if(size <= 0){ 516 218 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 517 219 size = 1024; 518 220 } 221 222 // prepare the buffer 519 223 // size plus terminating null (\0) 520 224 data = (char *) malloc(size + 1); … … 523 227 return ENOMEM; 524 228 } 525 refresh_data(data, size); 526 229 nettest2_refresh_data(data, size); 230 231 // check the socket count 527 232 if(sockets <= 0){ 528 233 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 529 234 sockets = 2; 530 235 } 531 // count plus terminating null (\0) 236 237 // prepare the socket buffer 238 // count plus the terminating null (\0) 532 239 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 533 240 if(! socket_ids){ … … 597 304 } 598 305 306 void nettest2_print_help(void){ 307 printf( 308 "Network Networking test 2 aplication - UDP transfer\n" \ 309 "Usage: echo [options] numeric_address\n" \ 310 "Where options are:\n" \ 311 "-f protocol_family | --family=protocol_family\n" \ 312 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n" 313 "\n" \ 314 "-h | --help\n" \ 315 "\tShow this application help.\n" 316 "\n" \ 317 "-m count | --messages=count\n" \ 318 "\tThe number of messages to send and receive per socket. The default is 10.\n" \ 319 "\n" \ 320 "-n sockets | --sockets=count\n" \ 321 "\tThe number of sockets to use. The default is 10.\n" \ 322 "\n" \ 323 "-p port_number | --port=port_number\n" \ 324 "\tThe port number the application should send messages to. The default is 7.\n" \ 325 "\n" \ 326 "-s packet_size | --size=packet_size\n" \ 327 "\tThe packet data size the application sends. The default is 29 bytes.\n" \ 328 "\n" \ 329 "-v | --verbose\n" \ 330 "\tShow all output messages.\n" 331 ); 332 } 333 334 void nettest2_refresh_data(char * data, size_t size){ 335 size_t length; 336 337 // fill the data 338 length = 0; 339 while(size > length + sizeof(NETTEST2_TEXT) - 1){ 340 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1); 341 length += sizeof(NETTEST2_TEXT) - 1; 342 } 343 memcpy(data + length, NETTEST2_TEXT, size - length); 344 data[size] = '\0'; 345 } 346 599 347 /** @} 600 348 */
Note:
See TracChangeset
for help on using the changeset viewer.