Changes in uspace/srv/net/app/nettest1/nettest1.c [aadf01e:3be62bc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/app/nettest1/nettest1.c
raadf01e r3be62bc 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 nettest1_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 1 aplication - sockets\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 28 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(NETTEST1_TEXT) - 1){ 227 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1); 228 length += sizeof(NETTEST1_TEXT) - 1; 229 } 230 memcpy(data + length, NETTEST1_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 nettest1_refresh_data(char * data, size_t size); 388 80 389 81 int main(int argc, char * argv[]){ … … 392 84 size_t size = 27; 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; … … 414 106 struct timeval time_after; 415 107 108 // print the program label 416 109 printf("Task %d - ", task_get_id()); 417 110 printf("%s\n", NAME); 418 111 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){ 112 // parse the command line arguments 113 // stop before the last argument if it does not start with the minus sign ('-') 114 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 115 // options should start with the minus sign ('-') 425 116 if(argv[index][0] == '-'){ 426 117 switch(argv[index][1]){ 118 // short options with only one letter 427 119 case 'f': 428 120 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family)); 429 121 break; 430 122 case 'h': 431 print_help();123 nettest1_print_help(); 432 124 return EOK; 433 125 break; … … 453 145 verbose = 1; 454 146 break; 147 // long options with the double minus sign ('-') 455 148 case '-': 456 149 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 457 150 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family)); 458 151 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 459 print_help();152 nettest1_print_help(); 460 153 return EOK; 461 154 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ … … 473 166 }else{ 474 167 print_unrecognized(index, argv[index] + 2); 475 print_help();168 nettest1_print_help(); 476 169 return EINVAL; 477 170 } … … 479 172 default: 480 173 print_unrecognized(index, argv[index] + 1); 481 print_help();174 nettest1_print_help(); 482 175 return EINVAL; 483 176 } 484 177 }else{ 485 178 print_unrecognized(index, argv[index]); 486 print_help();179 nettest1_print_help(); 487 180 return EINVAL; 488 181 } 489 182 } 490 183 184 // if not before the last argument containing the address 185 if(index >= argc){ 186 printf("Command line error: missing address\n"); 187 nettest1_print_help(); 188 return EINVAL; 189 } 190 191 // prepare the address buffer 491 192 bzero(address_data, max_length); 492 193 switch(family){ … … 508 209 } 509 210 211 // parse the last argument which should contain the address 510 212 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 511 213 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); … … 513 215 } 514 216 217 // check the buffer size 515 218 if(size <= 0){ 516 219 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 517 220 size = 1024; 518 221 } 519 // size plus terminating null (\0) 222 223 // prepare the buffer 224 // size plus the terminating null (\0) 520 225 data = (char *) malloc(size + 1); 521 226 if(! data){ … … 523 228 return ENOMEM; 524 229 } 525 refresh_data(data, size); 526 230 nettest1_refresh_data(data, size); 231 232 // check the socket count 527 233 if(sockets <= 0){ 528 234 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 529 235 sockets = 2; 530 236 } 531 // count plus terminating null (\0) 237 238 // prepare the socket buffer 239 // count plus the terminating null (\0) 532 240 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 533 241 if(! socket_ids){ … … 673 381 } 674 382 383 void nettest1_print_help(void){ 384 printf( 385 "Network Networking test 1 aplication - sockets\n" \ 386 "Usage: echo [options] numeric_address\n" \ 387 "Where options are:\n" \ 388 "-f protocol_family | --family=protocol_family\n" \ 389 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n" 390 "\n" \ 391 "-h | --help\n" \ 392 "\tShow this application help.\n" 393 "\n" \ 394 "-m count | --messages=count\n" \ 395 "\tThe number of messages to send and receive per socket. The default is 10.\n" \ 396 "\n" \ 397 "-n sockets | --sockets=count\n" \ 398 "\tThe number of sockets to use. The default is 10.\n" \ 399 "\n" \ 400 "-p port_number | --port=port_number\n" \ 401 "\tThe port number the application should send messages to. The default is 7.\n" \ 402 "\n" \ 403 "-s packet_size | --size=packet_size\n" \ 404 "\tThe packet data size the application sends. The default is 28 bytes.\n" \ 405 "\n" \ 406 "-v | --verbose\n" \ 407 "\tShow all output messages.\n" 408 ); 409 } 410 411 void nettest1_refresh_data(char * data, size_t size){ 412 size_t length; 413 414 // fill the data 415 length = 0; 416 while(size > length + sizeof(NETTEST1_TEXT) - 1){ 417 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1); 418 length += sizeof(NETTEST1_TEXT) - 1; 419 } 420 memcpy(data + length, NETTEST1_TEXT, size - length); 421 data[size] = '\0'; 422 } 423 675 424 /** @} 676 425 */
Note:
See TracChangeset
for help on using the changeset viewer.