Changes in uspace/app/netecho/netecho.c [481b212:2721a75] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/netecho/netecho.c
r481b212 r2721a75 28 28 29 29 /** @addtogroup netecho 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * Network echo application.35 * Answers received packets.34 * Network echo application. 35 * Answers received packets. 36 36 */ 37 37 … … 42 42 #include <arg_parse.h> 43 43 44 #include <net/in.h> 45 #include <net/in6.h> 46 #include <net/inet.h> 47 #include <net/socket.h> 48 #include <net/socket_parse.h> 44 #include <in.h> 45 #include <in6.h> 46 #include <inet.h> 47 #include <socket.h> 48 #include <net_err.h> 49 #include <socket_parse.h> 49 50 50 51 #include "print_error.h" 51 52 52 /** Network echo module name. */ 53 /** Network echo module name. 54 */ 53 55 #define NAME "Network Echo" 54 56 55 static void echo_print_help(void) 56 { 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){ 57 70 printf( 58 71 "Network Echo aplication\n" \ … … 88 101 } 89 102 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); 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); 102 116 uint8_t address_data[max_length]; 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;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; 106 120 socklen_t addrlen; 107 121 char address_string[INET6_ADDRSTRLEN]; 108 uint8_t * address_start;122 uint8_t * address_start; 109 123 int socket_id; 110 124 int listening_id; 111 char * data;125 char * data; 112 126 size_t length; 113 127 int index; 114 128 size_t reply_length; 115 129 int value; 116 int rc;117 130 118 131 // parse the command line arguments 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 if (rc != EOK) 176 return rc; 177 } else if (str_lcmp(argv[index] + 2, "family=", 7) == 0) { 178 rc = arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family); 179 if (rc != EOK) 180 return rc; 181 } else if (str_lcmp(argv[index] + 2, "help", 5) == 0) { 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': 182 145 echo_print_help(); 183 146 return EOK; 184 } else if (str_lcmp(argv[index] + 2, "port=", 5) == 0) { 185 rc = arg_parse_int(argc, argv, &index, &value, 7); 186 if (rc != EOK) 187 return rc; 147 break; 148 case 'p': 149 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 188 150 port = (uint16_t) value; 189 } else if (str_lcmp(argv[index] + 2, "reply=", 6) == 0) { 190 rc = arg_parse_string(argc, argv, &index, &reply, 8); 191 if (rc != EOK) 192 return rc; 193 } else if (str_lcmp(argv[index] + 2, "size=", 5) == 0) { 194 rc = arg_parse_int(argc, argv, &index, &value, 7); 195 if (rc != EOK) 196 return rc; 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)); 197 157 size = (value >= 0) ? (size_t) value : 0; 198 } else if (str_lcmp(argv[index] + 2, "type=", 5) == 0) { 199 rc = arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type); 200 if (rc != EOK) 201 return rc; 158 break; 159 case 't': 160 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 202 161 type = (sock_type_t) value; 203 } else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) { 162 break; 163 case 'v': 204 164 verbose = 1; 205 } else { 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: 206 196 echo_print_help(); 207 197 return EINVAL; 208 } 209 break; 210 default: 211 echo_print_help(); 212 return EINVAL; 213 } 214 } else { 198 } 199 }else{ 215 200 echo_print_help(); 216 201 return EINVAL; … … 219 204 220 205 // check the buffer size 221 if (size <= 0){206 if(size <= 0){ 222 207 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size); 223 208 size = 1024; … … 225 210 // size plus the terminating null (\0) 226 211 data = (char *) malloc(size + 1); 227 if (!data){212 if(! data){ 228 213 fprintf(stderr, "Failed to allocate receive buffer.\n"); 229 214 return ENOMEM; … … 235 220 // prepare the address buffer 236 221 bzero(address_data, max_length); 237 switch (family){238 case PF_INET:239 address_in->sin_family = AF_INET;240 address_in->sin_port = htons(port);241 addrlen = sizeof(struct sockaddr_in);242 break;243 case PF_INET6:244 address_in6->sin6_family = AF_INET6;245 address_in6->sin6_port = htons(port);246 addrlen = sizeof(struct sockaddr_in6);247 break;248 default:249 fprintf(stderr, "Protocol family is not supported\n");250 return EAFNOSUPPORT;222 switch(family){ 223 case PF_INET: 224 address_in->sin_family = AF_INET; 225 address_in->sin_port = htons(port); 226 addrlen = sizeof(struct sockaddr_in); 227 break; 228 case PF_INET6: 229 address_in6->sin6_family = AF_INET6; 230 address_in6->sin6_port = htons(port); 231 addrlen = sizeof(struct sockaddr_in6); 232 break; 233 default: 234 fprintf(stderr, "Protocol family is not supported\n"); 235 return EAFNOSUPPORT; 251 236 } 252 237 253 238 // get a listening socket 254 239 listening_id = socket(family, type, 0); 255 if (listening_id < 0){240 if(listening_id < 0){ 256 241 socket_print_error(stderr, listening_id, "Socket create: ", "\n"); 257 242 return listening_id; … … 259 244 260 245 // if the stream socket is used 261 if (type == SOCK_STREAM){246 if(type == SOCK_STREAM){ 262 247 // check the backlog 263 if (backlog <= 0){248 if(backlog <= 0){ 264 249 fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size); 265 250 backlog = 3; 266 251 } 267 252 // set the backlog 268 rc = listen(listening_id, backlog); 269 if (rc != EOK) { 270 socket_print_error(stderr, rc, "Socket listen: ", "\n"); 271 return rc; 253 if(ERROR_OCCURRED(listen(listening_id, backlog))){ 254 socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n"); 255 return ERROR_CODE; 272 256 } 273 257 } 274 258 275 259 // bind the listenning socket 276 rc = bind(listening_id, address, addrlen); 277 if (rc != EOK) { 278 socket_print_error(stderr, rc, "Socket bind: ", "\n"); 279 return rc; 280 } 281 282 if (verbose) 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){ 283 266 printf("Socket %d listenning at %d\n", listening_id, port); 267 } 284 268 285 269 socket_id = listening_id; … … 287 271 // do count times 288 272 // or indefinitely if set to a negative value 289 while (count){273 while(count){ 290 274 291 275 addrlen = max_length; 292 if (type == SOCK_STREAM){276 if(type == SOCK_STREAM){ 293 277 // acceept a socket if the stream socket is used 294 278 socket_id = accept(listening_id, address, &addrlen); 295 if (socket_id <= 0){279 if(socket_id <= 0){ 296 280 socket_print_error(stderr, socket_id, "Socket accept: ", "\n"); 297 } else{298 if (verbose)281 }else{ 282 if(verbose){ 299 283 printf("Socket %d accepted\n", socket_id); 284 } 300 285 } 301 286 } 302 287 303 288 // if the datagram socket is used or the stream socked was accepted 304 if (socket_id > 0){289 if(socket_id > 0){ 305 290 306 291 // receive an echo request 307 292 value = recvfrom(socket_id, data, size, 0, address, &addrlen); 308 if (value < 0){293 if(value < 0){ 309 294 socket_print_error(stderr, value, "Socket receive: ", "\n"); 310 } else{295 }else{ 311 296 length = (size_t) value; 312 if (verbose){297 if(verbose){ 313 298 // print the header 314 299 315 300 // get the source port and prepare the address buffer 316 301 address_start = NULL; 317 switch (address->sa_family){318 case AF_INET:319 port = ntohs(address_in->sin_port);320 address_start = (uint8_t *) &address_in->sin_addr.s_addr;321 break;322 case AF_INET6:323 port = ntohs(address_in6->sin6_port);324 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;325 break;326 default:327 fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);302 switch(address->sa_family){ 303 case AF_INET: 304 port = ntohs(address_in->sin_port); 305 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 306 break; 307 case AF_INET6: 308 port = ntohs(address_in6->sin6_port); 309 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 310 break; 311 default: 312 fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family); 328 313 } 329 314 // parse the source address 330 if (address_start) { 331 rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)); 332 if (rc != EOK) { 333 fprintf(stderr, "Received address error %d\n", rc); 334 } else { 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{ 335 319 data[length] = '\0'; 336 320 printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data); … … 340 324 341 325 // answer the request either with the static reply or the original data 342 rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen); 343 if (rc != EOK) 344 socket_print_error(stderr, rc, "Socket send: ", "\n"); 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 345 330 } 346 331 347 332 // close the accepted stream socket 348 if (type == SOCK_STREAM){349 rc = closesocket(socket_id);350 if (rc != EOK)351 socket_print_error(stderr, rc, "Close socket: ", "\n");333 if(type == SOCK_STREAM){ 334 if(ERROR_OCCURRED(closesocket(socket_id))){ 335 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n"); 336 } 352 337 } 353 338 … … 355 340 356 341 // decrease the count if positive 357 if (count > 0){358 count--;359 if (verbose)342 if(count > 0){ 343 -- count; 344 if(verbose){ 360 345 printf("Waiting for next %d packet(s)\n", count); 361 } 362 } 363 364 if (verbose) 346 } 347 } 348 } 349 350 if(verbose){ 365 351 printf("Closing the socket\n"); 352 } 366 353 367 354 // close the listenning socket 368 rc = closesocket(listening_id); 369 if (rc != EOK) { 370 socket_print_error(stderr, rc, "Close socket: ", "\n"); 371 return rc; 372 } 373 374 if (verbose) 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){ 375 361 printf("Exiting\n"); 362 } 376 363 377 364 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.