Changeset 3be62bc in mainline
- Timestamp:
- 2010-03-09T22:23:18Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9f2ea28
- Parents:
- a8a13d0
- Location:
- uspace/srv/net/app
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/app/echo/echo.c
ra8a13d0 r3be62bc 55 55 #define NAME "Echo" 56 56 57 /** Prints the application help. 58 */ 59 void echo_print_help(void); 60 57 61 /** Module entry point. 58 62 * Reads command line parameters and starts listenning. … … 62 66 */ 63 67 int main(int argc, char * argv[]); 64 65 /** Prints the application help.66 */67 void echo_print_help(void);68 69 /** Translates the character string to the protocol family number.70 * @param[in] name The protocol family name.71 * @returns The corresponding protocol family number.72 * @returns EPFNOSUPPORTED if the protocol family is not supported.73 */74 int echo_parse_protocol_family(const char * name);75 76 /** Translates the character string to the socket type number.77 * @param[in] name The socket type name.78 * @returns The corresponding socket type number.79 * @returns ESOCKNOSUPPORTED if the socket type is not supported.80 */81 int echo_parse_socket_type(const char * name);82 68 83 69 void echo_print_help(void){ … … 115 101 } 116 102 117 int echo_parse_protocol_family(const char * name){118 if(str_lcmp(name, "PF_INET", 7) == 0){119 return PF_INET;120 }else if(str_lcmp(name, "PF_INET6", 8) == 0){121 return PF_INET6;122 }123 return EPFNOSUPPORT;124 }125 126 int echo_parse_socket_type(const char * name){127 if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){128 return SOCK_DGRAM;129 }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){130 return SOCK_STREAM;131 }132 return ESOCKTNOSUPPORT;133 }134 135 103 int main(int argc, char * argv[]){ 136 104 ERROR_DECLARE; … … 138 106 size_t size = 1024; 139 107 int verbose = 0; 140 char * reply 141 sock_type_t type 108 char * reply = NULL; 109 sock_type_t type = SOCK_DGRAM; 142 110 int count = -1; 143 111 int family = PF_INET; 144 uint16_t port 112 uint16_t port = 7; 145 113 int backlog = 3; 146 114 147 socklen_t max_length = sizeof(struct sockaddr_in6);115 socklen_t max_length = sizeof(struct sockaddr_in6); 148 116 uint8_t address_data[max_length]; 149 struct sockaddr * address = (struct sockaddr *) address_data;117 struct sockaddr * address = (struct sockaddr *) address_data; 150 118 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 151 119 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; … … 155 123 int socket_id; 156 124 int listening_id; 157 char * 125 char * data; 158 126 size_t length; 159 127 int index; … … 161 129 int value; 162 130 131 // print the program label 163 132 printf("Task %d - ", task_get_id()); 164 133 printf("%s\n", NAME); 165 134 135 // parse the command line arguments 166 136 for(index = 1; index < argc; ++ index){ 167 137 if(argv[index][0] == '-'){ … … 174 144 break; 175 145 case 'f': 176 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, echo_parse_protocol_family));146 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family)); 177 147 break; 178 148 case 'h': … … 192 162 break; 193 163 case 't': 194 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, echo_parse_socket_type));164 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type)); 195 165 type = (sock_type_t) value; 196 166 break; … … 198 168 verbose = 1; 199 169 break; 170 // long options with the double minus sign ('-') 200 171 case '-': 201 172 if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){ … … 204 175 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8)); 205 176 }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 206 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, echo_parse_protocol_family));177 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family)); 207 178 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 208 179 echo_print_help(); … … 217 188 size = (value >= 0) ? (size_t) value : 0; 218 189 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 219 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, echo_parse_socket_type));190 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type)); 220 191 type = (sock_type_t) value; 221 192 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ … … 239 210 } 240 211 212 // check the buffer size 241 213 if(size <= 0){ 242 214 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size); 243 215 size = 1024; 244 216 } 245 // size plus t erminating null (\0)217 // size plus the terminating null (\0) 246 218 data = (char *) malloc(size + 1); 247 219 if(! data){ … … 250 222 } 251 223 224 // set the reply size if set 252 225 reply_length = reply ? str_length(reply) : 0; 253 226 254 listening_id = socket(family, type, 0); 255 if(listening_id < 0){ 256 socket_print_error(stderr, listening_id, "Socket create: ", "\n"); 257 return listening_id; 258 } 259 227 // prepare the address buffer 260 228 bzero(address_data, max_length); 261 229 switch(family){ … … 275 243 } 276 244 245 // get a listening socket 277 246 listening_id = socket(family, type, 0); 278 247 if(listening_id < 0){ … … 281 250 } 282 251 252 // if the stream socket is used 283 253 if(type == SOCK_STREAM){ 254 // check the backlog 284 255 if(backlog <= 0){ 285 256 fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size); 286 257 backlog = 3; 287 258 } 259 // set the backlog 288 260 if(ERROR_OCCURRED(listen(listening_id, backlog))){ 289 261 socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n"); … … 292 264 } 293 265 266 // bind the listenning socket 294 267 if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){ 295 268 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n"); … … 303 276 socket_id = listening_id; 304 277 278 // do count times 279 // or indefinitely if set to a negative value 305 280 while(count){ 281 306 282 addrlen = max_length; 307 283 if(type == SOCK_STREAM){ 284 // acceept a socket if the stream socket is used 308 285 socket_id = accept(listening_id, address, &addrlen); 309 286 if(socket_id <= 0){ … … 315 292 } 316 293 } 294 295 // if the datagram socket is used or the stream socked was accepted 317 296 if(socket_id > 0){ 297 298 // receive an echo request 318 299 value = recvfrom(socket_id, data, size, 0, address, &addrlen); 319 300 if(value < 0){ … … 322 303 length = (size_t) value; 323 304 if(verbose){ 305 // print the header 306 307 // get the source port and prepare the address buffer 324 308 address_start = NULL; 325 309 switch(address->sa_family){ … … 335 319 fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family); 336 320 } 321 // parse the source address 337 322 if(address_start){ 338 323 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ … … 344 329 } 345 330 } 331 332 // answer the request either with the static reply or the original data 346 333 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){ 347 334 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 348 335 } 349 } 336 337 } 338 339 // close the accepted stream socket 350 340 if(type == SOCK_STREAM){ 351 341 if(ERROR_OCCURRED(closesocket(socket_id))){ … … 353 343 } 354 344 } 355 } 345 346 } 347 348 // decrease the count if positive 356 349 if(count > 0){ 357 350 -- count; … … 366 359 } 367 360 361 // close the listenning socket 368 362 if(ERROR_OCCURRED(closesocket(listening_id))){ 369 363 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n"); -
uspace/srv/net/app/nettest1/Makefile
ra8a13d0 r3be62bc 40 40 SOURCES = \ 41 41 $(NAME).c \ 42 $(NET_BASE)app/nettest.c \ 42 43 $(NET_BASE)app/parse.c \ 43 44 $(NET_BASE)app/print_error.c -
uspace/srv/net/app/nettest1/nettest1.c
ra8a13d0 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 */ -
uspace/srv/net/app/nettest2/Makefile
ra8a13d0 r3be62bc 40 40 SOURCES = \ 41 41 $(NAME).c \ 42 $(NET_BASE)app/nettest.c \ 42 43 $(NET_BASE)app/parse.c \ 43 44 $(NET_BASE)app/print_error.c -
uspace/srv/net/app/nettest2/nettest2.c
ra8a13d0 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 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 */ -
uspace/srv/net/app/parse.c
ra8a13d0 r3be62bc 38 38 #include <string.h> 39 39 40 #include "../include/socket.h" 41 40 42 #include "../err.h" 41 43 42 44 #include "parse.h" 45 46 int parse_address_family(const char * name){ 47 if(str_lcmp(name, "AF_INET", 7) == 0){ 48 return AF_INET; 49 }else if(str_lcmp(name, "AF_INET6", 8) == 0){ 50 return AF_INET6; 51 } 52 return EAFNOSUPPORT; 53 } 43 54 44 55 int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset){ … … 61 72 } 62 73 63 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){64 if(offset){65 *value = argv[*index] + offset;66 }else if((*index) + 1 < argc){67 ++ (*index);68 *value = argv[*index];69 }else{70 fprintf(stderr, "Command line error: missing %s\n", name);71 return EINVAL;72 }73 return EOK;74 }75 76 74 int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value)){ 77 75 ERROR_DECLARE; … … 88 86 } 89 87 88 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){ 89 if(offset){ 90 *value = argv[*index] + offset; 91 }else if((*index) + 1 < argc){ 92 ++ (*index); 93 *value = argv[*index]; 94 }else{ 95 fprintf(stderr, "Command line error: missing %s\n", name); 96 return EINVAL; 97 } 98 return EOK; 99 } 100 101 int parse_protocol_family(const char * name){ 102 if(str_lcmp(name, "PF_INET", 7) == 0){ 103 return PF_INET; 104 }else if(str_lcmp(name, "PF_INET6", 8) == 0){ 105 return PF_INET6; 106 } 107 return EPFNOSUPPORT; 108 } 109 110 int parse_socket_type(const char * name){ 111 if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){ 112 return SOCK_DGRAM; 113 }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){ 114 return SOCK_STREAM; 115 } 116 return ESOCKTNOSUPPORT; 117 } 118 90 119 void print_unrecognized(int index, const char * parameter){ 91 fprintf(stderr, "Command line error - unrecognized parameter(%d: %s)\n", index, parameter);120 fprintf(stderr, "Command line error: unrecognized argument (%d: %s)\n", index, parameter); 92 121 } 93 122 -
uspace/srv/net/app/parse.h
ra8a13d0 r3be62bc 38 38 #define __NET_APP_PARSE__ 39 39 40 /** Prints the parameter unrecognized message and the application help. 41 * @param[in] index The index of the parameter. 42 * @param[in] parameter The parameter name. 40 #include "../include/socket.h" 41 42 /** Translates the character string to the address family number. 43 * @param[in] name The address family name. 44 * @returns The corresponding address family number. 45 * @returns EAFNOSUPPORTED if the address family is not supported. 43 46 */ 44 void print_unrecognized(int index, const char * parameter);47 int parse_address_family(const char * name); 45 48 46 49 /** Parses the next parameter as an integral number. … … 58 61 */ 59 62 int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset); 60 61 /** Parses the next parameter as a character string.62 * The actual parameter is pointed by the index.63 * Uses the offseted actual parameter value if the offset is set or the next one if not.64 * Increments the actual index by the number of processed parameters.65 * @param[in] argc The total number of the parameters.66 * @param[in] argv The parameters.67 * @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.68 * @param[out] value The parsed parameter value.69 * @param[in] name The parameter name to be printed on errors.70 * @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.71 * @returns EOK on success.72 * @returns EINVAL if the parameter is missing.73 */74 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset);75 63 76 64 /** Parses the next named parameter as an integral number. … … 92 80 int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value)); 93 81 82 /** Parses the next parameter as a character string. 83 * The actual parameter is pointed by the index. 84 * Uses the offseted actual parameter value if the offset is set or the next one if not. 85 * Increments the actual index by the number of processed parameters. 86 * @param[in] argc The total number of the parameters. 87 * @param[in] argv The parameters. 88 * @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters. 89 * @param[out] value The parsed parameter value. 90 * @param[in] name The parameter name to be printed on errors. 91 * @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead. 92 * @returns EOK on success. 93 * @returns EINVAL if the parameter is missing. 94 */ 95 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset); 96 97 /** Translates the character string to the protocol family number. 98 * @param[in] name The protocol family name. 99 * @returns The corresponding protocol family number. 100 * @returns EPFNOSUPPORTED if the protocol family is not supported. 101 */ 102 int parse_protocol_family(const char * name); 103 104 /** Translates the character string to the socket type number. 105 * @param[in] name The socket type name. 106 * @returns The corresponding socket type number. 107 * @returns ESOCKNOSUPPORTED if the socket type is not supported. 108 */ 109 int parse_socket_type(const char * name); 110 111 /** Prints the parameter unrecognized message and the application help. 112 * @param[in] index The index of the parameter. 113 * @param[in] parameter The parameter name. 114 */ 115 void print_unrecognized(int index, const char * parameter); 116 94 117 #endif 95 118 -
uspace/srv/net/app/ping/ping.c
ra8a13d0 r3be62bc 39 39 #include <task.h> 40 40 #include <time.h> 41 #include <ipc/ipc.h> 41 42 #include <ipc/services.h> 42 43 … … 67 68 /** Prints the application help. 68 69 */ 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){ 79 printf( 80 "Network Ping aplication\n" \ 81 "Usage: ping [options] numeric_address\n" \ 82 "Where options are:\n" \ 83 "\n" \ 84 "-c request_count | --count=request_count\n" \ 85 "\tThe number of packets the application sends. The default is three (3).\n" \ 86 "\n" \ 87 "--dont_fragment\n" \ 88 "\tDisable packet fragmentation.\n" 89 "\n" \ 90 "-f address_family | --family=address_family\n" \ 91 "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n" 92 "\n" \ 93 "-h | --help\n" \ 94 "\tShow this application help.\n" 95 "\n" \ 96 "-s packet_size | --size=packet_size\n" \ 97 "\tThe packet data size the application sends. The default is 38 bytes.\n" \ 98 "\n" \ 99 "-t timeout | --timeout=timeout\n" \ 100 "\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \ 101 "\n" \ 102 "--tos=tos\n" \ 103 "\tThe type of service to be used.\n" \ 104 "\n" \ 105 "--ttl=ttl\n" \ 106 "\tThe time to live to be used.\n" \ 107 "\n" \ 108 "-v | --verbose\n" \ 109 "\tShow all output messages.\n" 110 ); 111 } 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 } 70 void ping_print_help(void); 121 71 122 72 int main(int argc, char * argv[]){ … … 126 76 int verbose = 0; 127 77 int dont_fragment = 0; 128 ip_ttl_t ttl 129 ip_tos_t tos 78 ip_ttl_t ttl = 0; 79 ip_tos_t tos = 0; 130 80 int count = 3; 131 suseconds_t timeout 81 suseconds_t timeout = 3000; 132 82 int family = AF_INET; 133 83 134 socklen_t max_length = sizeof(struct sockaddr_in6);84 socklen_t max_length = sizeof(struct sockaddr_in6); 135 85 uint8_t address_data[max_length]; 136 struct sockaddr * address = (struct sockaddr *) address_data;86 struct sockaddr * address = (struct sockaddr *) address_data; 137 87 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 138 88 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; … … 147 97 int index; 148 98 99 // print the program label 149 100 printf("Task %d - ", task_get_id()); 150 101 printf("%s\n", NAME); 151 102 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){ 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 ('-') 158 107 if(argv[index][0] == '-'){ 159 108 switch(argv[index][1]){ 109 // short options with only one letter 160 110 case 'c': 161 111 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "count", 0)); … … 165 115 break; 166 116 case 'h': 167 p rint_help();117 ping_print_help(); 168 118 return EOK; 169 119 break; … … 179 129 verbose = 1; 180 130 break; 131 // long options with the double minus sign ('-') 181 132 case '-': 182 133 if(str_lcmp(argv[index] + 2, "count=", 6) == 0){ … … 187 138 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 9, parse_address_family)); 188 139 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 189 p rint_help();140 ping_print_help(); 190 141 return EOK; 191 142 }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){ … … 205 156 }else{ 206 157 print_unrecognized(index, argv[index] + 2); 207 p rint_help();158 ping_print_help(); 208 159 return EINVAL; 209 160 } … … 211 162 default: 212 163 print_unrecognized(index, argv[index] + 1); 213 p rint_help();164 ping_print_help(); 214 165 return EINVAL; 215 166 } 216 167 }else{ 217 168 print_unrecognized(index, argv[index]); 218 p rint_help();169 ping_print_help(); 219 170 return EINVAL; 220 171 } 221 172 } 222 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 223 182 bzero(address_data, max_length); 224 183 switch(family){ … … 238 197 } 239 198 199 // parse the last argument which should contain the address 240 200 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 241 201 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); … … 243 203 } 244 204 205 // connect to the ICMP module 245 206 icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT); 246 207 if(icmp_phone < 0){ … … 249 210 } 250 211 212 // print the ping header 251 213 printf("PING %d bytes of data\n", size); 252 214 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ … … 256 218 } 257 219 220 // do count times 258 221 while(count > 0){ 222 223 // get the starting time 259 224 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 260 225 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 226 // release the ICMP phone 227 ipc_hangup(icmp_phone); 261 228 return ERROR_CODE; 262 229 } 230 231 // request the ping 263 232 result = icmp_echo_msg(icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen); 233 234 // get the ending time 264 235 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 265 236 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 237 // release the ICMP phone 238 ipc_hangup(icmp_phone); 266 239 return ERROR_CODE; 267 240 } 241 242 // print the result 268 243 switch(result){ 269 244 case ICMP_ECHO: … … 283 258 } 284 259 260 // release the ICMP phone 261 ipc_hangup(icmp_phone); 262 285 263 return EOK; 286 264 } 287 265 266 void ping_print_help(void){ 267 printf( 268 "Network Ping aplication\n" \ 269 "Usage: ping [options] numeric_address\n" \ 270 "Where options are:\n" \ 271 "\n" \ 272 "-c request_count | --count=request_count\n" \ 273 "\tThe number of packets the application sends. The default is three (3).\n" \ 274 "\n" \ 275 "--dont_fragment\n" \ 276 "\tDisable packet fragmentation.\n" 277 "\n" \ 278 "-f address_family | --family=address_family\n" \ 279 "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n" 280 "\n" \ 281 "-h | --help\n" \ 282 "\tShow this application help.\n" 283 "\n" \ 284 "-s packet_size | --size=packet_size\n" \ 285 "\tThe packet data size the application sends. The default is 38 bytes.\n" \ 286 "\n" \ 287 "-t timeout | --timeout=timeout\n" \ 288 "\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \ 289 "\n" \ 290 "--tos=tos\n" \ 291 "\tThe type of service to be used.\n" \ 292 "\n" \ 293 "--ttl=ttl\n" \ 294 "\tThe time to live to be used.\n" \ 295 "\n" \ 296 "-v | --verbose\n" \ 297 "\tShow all output messages.\n" 298 ); 299 } 300 288 301 /** @} 289 302 */ -
uspace/srv/net/app/print_error.c
ra8a13d0 r3be62bc 41 41 42 42 #include "print_error.h" 43 44 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){45 if(IS_ICMP_ERROR(error_code)){46 icmp_print_error(output, error_code, prefix, suffix);47 }else if(IS_SOCKET_ERROR(error_code)){48 socket_print_error(output, error_code, prefix, suffix);49 }50 }51 43 52 44 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ … … 101 93 } 102 94 95 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ 96 if(IS_ICMP_ERROR(error_code)){ 97 icmp_print_error(output, error_code, prefix, suffix); 98 }else if(IS_SOCKET_ERROR(error_code)){ 99 socket_print_error(output, error_code, prefix, suffix); 100 } 101 } 102 103 103 void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ 104 104 if(output){ -
uspace/srv/net/app/print_error.h
ra8a13d0 r3be62bc 50 50 #define IS_SOCKET_ERROR(error_code) ((error_code) < 0) 51 51 52 /** Prints the specific ICMP error description. 53 * @param[in] output The description output stream. May be NULL. 54 * @param[in] error_code The ICMP error code. 55 * @param[in] prefix The error description prefix. May be NULL. 56 * @param[in] suffix The error description suffix. May be NULL. 57 */ 58 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix); 59 52 60 /** Prints the error description. 53 61 * Supports ICMP and socket error codes. … … 58 66 */ 59 67 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix); 60 61 /** Prints the specific ICMP error description.62 * @param[in] output The description output stream. May be NULL.63 * @param[in] error_code The ICMP error code.64 * @param[in] prefix The error description prefix. May be NULL.65 * @param[in] suffix The error description suffix. May be NULL.66 */67 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);68 68 69 69 /** Prints the specific socket error description.
Note:
See TracChangeset
for help on using the changeset viewer.