Changeset b40bfac in mainline for uspace/app/netecho/netecho.c
- Timestamp:
- 2010-11-08T07:13:25Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63a1e60
- Parents:
- d70a463 (diff), 3da12d74 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/netecho/netecho.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup netecho 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * Network echo application. 35 * Answers received packets. 36 36 */ 37 37 … … 41 41 #include <task.h> 42 42 #include <arg_parse.h> 43 #include <err.h>44 43 45 44 #include <net/in.h> … … 51 50 #include "print_error.h" 52 51 53 /** Network echo module name. 54 */ 52 /** Network echo module name. */ 55 53 #define NAME "Network Echo" 56 54 57 /** Prints the application help. 58 */ 59 void echo_print_help(void); 60 61 /** Module entry point. 62 * Reads command line parameters and starts listenning. 63 * @param[in] argc The number of command line parameters. 64 * @param[in] argv The command line parameters. 65 * @returns EOK on success. 66 */ 67 int main(int argc, char * argv[]); 68 69 void echo_print_help(void){ 55 static void echo_print_help(void) 56 { 70 57 printf( 71 58 "Network Echo aplication\n" \ … … 101 88 } 102 89 103 int main(int argc, char * argv[]){ 104 ERROR_DECLARE; 105 106 size_t size = 1024; 107 int verbose = 0; 108 char * reply = NULL; 109 sock_type_t type = SOCK_DGRAM; 110 int count = -1; 111 int family = PF_INET; 112 uint16_t port = 7; 113 int backlog = 3; 114 115 socklen_t max_length = sizeof(struct sockaddr_in6); 90 int main(int argc, char *argv[]) 91 { 92 size_t size = 1024; 93 int verbose = 0; 94 char *reply = NULL; 95 sock_type_t type = SOCK_DGRAM; 96 int count = -1; 97 int family = PF_INET; 98 uint16_t port = 7; 99 int backlog = 3; 100 101 socklen_t max_length = sizeof(struct sockaddr_in6); 116 102 uint8_t address_data[max_length]; 117 struct sockaddr * address= (struct sockaddr *) address_data;118 struct sockaddr_in * address_in= (struct sockaddr_in *) address;119 struct sockaddr_in6 * address_in6= (struct sockaddr_in6 *) address;103 struct sockaddr *address = (struct sockaddr *) address_data; 104 struct sockaddr_in *address_in = (struct sockaddr_in *) address; 105 struct sockaddr_in6 *address_in6 = (struct sockaddr_in6 *) address; 120 106 socklen_t addrlen; 121 107 char address_string[INET6_ADDRSTRLEN]; 122 uint8_t * 108 uint8_t *address_start; 123 109 int socket_id; 124 110 int listening_id; 125 char * 111 char *data; 126 112 size_t length; 127 113 int index; 128 114 size_t reply_length; 129 115 int value; 116 int rc; 130 117 131 118 // parse the command line arguments 132 for(index = 1; index < argc; ++ index){ 133 if(argv[index][0] == '-'){ 134 switch(argv[index][1]){ 135 case 'b': 136 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0)); 137 break; 138 case 'c': 139 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0)); 140 break; 141 case 'f': 142 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family)); 143 break; 144 case 'h': 119 for (index = 1; index < argc; ++ index) { 120 if (argv[index][0] == '-') { 121 switch (argv[index][1]) { 122 case 'b': 123 rc = arg_parse_int(argc, argv, &index, &backlog, 0); 124 if (rc != EOK) 125 return rc; 126 break; 127 case 'c': 128 rc = arg_parse_int(argc, argv, &index, &count, 0); 129 if (rc != EOK) 130 return rc; 131 break; 132 case 'f': 133 rc = arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family); 134 if (rc != EOK) 135 return rc; 136 break; 137 case 'h': 138 echo_print_help(); 139 return EOK; 140 break; 141 case 'p': 142 rc = arg_parse_int(argc, argv, &index, &value, 0); 143 if (rc != EOK) 144 return rc; 145 port = (uint16_t) value; 146 break; 147 case 'r': 148 rc = arg_parse_string(argc, argv, &index, &reply, 0); 149 if (rc != EOK) 150 return rc; 151 break; 152 case 's': 153 rc = arg_parse_int(argc, argv, &index, &value, 0); 154 if (rc != EOK) 155 return rc; 156 size = (value >= 0) ? (size_t) value : 0; 157 break; 158 case 't': 159 rc = arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type); 160 if (rc != EOK) 161 return rc; 162 type = (sock_type_t) value; 163 break; 164 case 'v': 165 verbose = 1; 166 break; 167 // long options with the double minus sign ('-') 168 case '-': 169 if (str_lcmp(argv[index] + 2, "backlog=", 6) == 0) { 170 rc = arg_parse_int(argc, argv, &index, &backlog, 8); 171 if (rc != EOK) 172 return rc; 173 } else if (str_lcmp(argv[index] + 2, "count=", 6) == 0) { 174 rc = arg_parse_int(argc, argv, &index, &count, 8); 175 } else if (str_lcmp(argv[index] + 2, "family=", 7) == 0) { 176 rc = arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family); 177 if (rc != EOK) 178 return rc; 179 } else if (str_lcmp(argv[index] + 2, "help", 5) == 0) { 145 180 echo_print_help(); 146 181 return EOK; 147 break; 148 case 'p': 149 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 182 } else if (str_lcmp(argv[index] + 2, "port=", 5) == 0) { 183 rc = arg_parse_int(argc, argv, &index, &value, 7); 184 if (rc != EOK) 185 return rc; 150 186 port = (uint16_t) value; 151 break; 152 case 'r': 153 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0)); 154 break; 155 case 's': 156 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 187 } else if (str_lcmp(argv[index] + 2, "reply=", 6) == 0) { 188 rc = arg_parse_string(argc, argv, &index, &reply, 8); 189 if (rc != EOK) 190 return rc; 191 } else if (str_lcmp(argv[index] + 2, "size=", 5) == 0) { 192 rc = arg_parse_int(argc, argv, &index, &value, 7); 193 if (rc != EOK) 194 return rc; 157 195 size = (value >= 0) ? (size_t) value : 0; 158 break; 159 case 't': 160 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 196 } else if (str_lcmp(argv[index] + 2, "type=", 5) == 0) { 197 rc = arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type); 198 if (rc != EOK) 199 return rc; 161 200 type = (sock_type_t) value; 162 break; 163 case 'v': 201 } else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) { 164 202 verbose = 1; 165 break; 166 // long options with the double minus sign ('-') 167 case '-': 168 if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){ 169 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8)); 170 }else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){ 171 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8)); 172 }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 173 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family)); 174 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 175 echo_print_help(); 176 return EOK; 177 }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){ 178 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 179 port = (uint16_t) value; 180 }else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){ 181 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8)); 182 }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){ 183 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 184 size = (value >= 0) ? (size_t) value : 0; 185 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 186 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type)); 187 type = (sock_type_t) value; 188 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ 189 verbose = 1; 190 }else{ 191 echo_print_help(); 192 return EINVAL; 193 } 194 break; 195 default: 203 } else { 196 204 echo_print_help(); 197 205 return EINVAL; 206 } 207 break; 208 default: 209 echo_print_help(); 210 return EINVAL; 198 211 } 199 } else{212 } else { 200 213 echo_print_help(); 201 214 return EINVAL; … … 204 217 205 218 // check the buffer size 206 if (size <= 0){219 if (size <= 0) { 207 220 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size); 208 221 size = 1024; … … 210 223 // size plus the terminating null (\0) 211 224 data = (char *) malloc(size + 1); 212 if (! data){225 if (!data) { 213 226 fprintf(stderr, "Failed to allocate receive buffer.\n"); 214 227 return ENOMEM; … … 220 233 // prepare the address buffer 221 234 bzero(address_data, max_length); 222 switch (family){223 224 225 226 227 228 229 230 231 232 233 234 235 235 switch (family) { 236 case PF_INET: 237 address_in->sin_family = AF_INET; 238 address_in->sin_port = htons(port); 239 addrlen = sizeof(struct sockaddr_in); 240 break; 241 case PF_INET6: 242 address_in6->sin6_family = AF_INET6; 243 address_in6->sin6_port = htons(port); 244 addrlen = sizeof(struct sockaddr_in6); 245 break; 246 default: 247 fprintf(stderr, "Protocol family is not supported\n"); 248 return EAFNOSUPPORT; 236 249 } 237 250 238 251 // get a listening socket 239 252 listening_id = socket(family, type, 0); 240 if (listening_id < 0){253 if (listening_id < 0) { 241 254 socket_print_error(stderr, listening_id, "Socket create: ", "\n"); 242 255 return listening_id; … … 244 257 245 258 // if the stream socket is used 246 if (type == SOCK_STREAM){259 if (type == SOCK_STREAM) { 247 260 // check the backlog 248 if (backlog <= 0){261 if (backlog <= 0) { 249 262 fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size); 250 263 backlog = 3; 251 264 } 252 265 // set the backlog 253 if(ERROR_OCCURRED(listen(listening_id, backlog))){ 254 socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n"); 255 return ERROR_CODE; 266 rc = listen(listening_id, backlog); 267 if (rc != EOK) { 268 socket_print_error(stderr, rc, "Socket listen: ", "\n"); 269 return rc; 256 270 } 257 271 } 258 272 259 273 // bind the listenning socket 260 if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){ 261 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n"); 262 return ERROR_CODE; 263 } 264 265 if(verbose){ 274 rc = bind(listening_id, address, addrlen); 275 if (rc != EOK) { 276 socket_print_error(stderr, rc, "Socket bind: ", "\n"); 277 return rc; 278 } 279 280 if (verbose) 266 281 printf("Socket %d listenning at %d\n", listening_id, port); 267 }268 282 269 283 socket_id = listening_id; … … 271 285 // do count times 272 286 // or indefinitely if set to a negative value 273 while (count){287 while (count) { 274 288 275 289 addrlen = max_length; 276 if (type == SOCK_STREAM){290 if (type == SOCK_STREAM) { 277 291 // acceept a socket if the stream socket is used 278 292 socket_id = accept(listening_id, address, &addrlen); 279 if (socket_id <= 0){293 if (socket_id <= 0) { 280 294 socket_print_error(stderr, socket_id, "Socket accept: ", "\n"); 281 } else{282 if (verbose){295 } else { 296 if (verbose) 283 297 printf("Socket %d accepted\n", socket_id); 284 }285 298 } 286 299 } 287 300 288 301 // if the datagram socket is used or the stream socked was accepted 289 if (socket_id > 0){302 if (socket_id > 0) { 290 303 291 304 // receive an echo request 292 305 value = recvfrom(socket_id, data, size, 0, address, &addrlen); 293 if (value < 0){306 if (value < 0) { 294 307 socket_print_error(stderr, value, "Socket receive: ", "\n"); 295 } else{308 } else { 296 309 length = (size_t) value; 297 if (verbose){310 if (verbose) { 298 311 // print the header 299 312 300 313 // get the source port and prepare the address buffer 301 314 address_start = NULL; 302 switch (address->sa_family){303 304 305 306 307 308 309 310 311 312 315 switch (address->sa_family) { 316 case AF_INET: 317 port = ntohs(address_in->sin_port); 318 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 319 break; 320 case AF_INET6: 321 port = ntohs(address_in6->sin6_port); 322 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 323 break; 324 default: 325 fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family); 313 326 } 314 327 // parse the source address 315 if(address_start){ 316 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ 317 fprintf(stderr, "Received address error %d\n", ERROR_CODE); 318 }else{ 328 if (address_start) { 329 rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)); 330 if (rc != EOK) { 331 fprintf(stderr, "Received address error %d\n", rc); 332 } else { 319 333 data[length] = '\0'; 320 334 printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data); … … 324 338 325 339 // answer the request either with the static reply or the original data 326 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){ 327 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 328 } 329 340 rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen); 341 if (rc != EOK) 342 socket_print_error(stderr, rc, "Socket send: ", "\n"); 330 343 } 331 344 332 345 // close the accepted stream socket 333 if (type == SOCK_STREAM){334 if(ERROR_OCCURRED(closesocket(socket_id))){335 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");336 }346 if (type == SOCK_STREAM) { 347 rc = closesocket(socket_id); 348 if (rc != EOK) 349 socket_print_error(stderr, rc, "Close socket: ", "\n"); 337 350 } 338 351 … … 340 353 341 354 // decrease the count if positive 342 if (count > 0){343 -- count;344 if (verbose){355 if (count > 0) { 356 count--; 357 if (verbose) 345 358 printf("Waiting for next %d packet(s)\n", count); 346 } 347 } 348 } 349 350 if(verbose){ 359 } 360 } 361 362 if (verbose) 351 363 printf("Closing the socket\n"); 352 }353 364 354 365 // close the listenning socket 355 if(ERROR_OCCURRED(closesocket(listening_id))){ 356 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n"); 357 return ERROR_CODE; 358 } 359 360 if(verbose){ 366 rc = closesocket(listening_id); 367 if (rc != EOK) { 368 socket_print_error(stderr, rc, "Close socket: ", "\n"); 369 return rc; 370 } 371 372 if (verbose) 361 373 printf("Exiting\n"); 362 }363 374 364 375 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.