Changes in uspace/app/netecho/netecho.c [a8e5051:d9e2e0e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/netecho/netecho.c
ra8e5051 rd9e2e0e 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 … … 51 51 #include "print_error.h" 52 52 53 /** Network echo module name. */ 53 /** Network echo module name. 54 */ 54 55 #define NAME "Network Echo" 55 56 56 static void echo_print_help(void) 57 { 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){ 58 70 printf( 59 71 "Network Echo aplication\n" \ … … 89 101 } 90 102 91 int main(int argc, char *argv[]) 92 { 103 int main(int argc, char * argv[]){ 93 104 ERROR_DECLARE; 94 105 95 size_t size 96 int verbose 97 char * reply= NULL;98 sock_type_t type 99 int count 100 int family 101 uint16_t port 102 int backlog 103 104 socklen_t max_length 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); 105 116 uint8_t address_data[max_length]; 106 struct sockaddr * address= (struct sockaddr *) address_data;107 struct sockaddr_in * address_in= (struct sockaddr_in *) address;108 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; 109 120 socklen_t addrlen; 110 121 char address_string[INET6_ADDRSTRLEN]; 111 uint8_t * address_start;122 uint8_t * address_start; 112 123 int socket_id; 113 124 int listening_id; 114 char * data;125 char * data; 115 126 size_t length; 116 127 int index; … … 119 130 120 131 // parse the command line arguments 121 for (index = 1; index < argc; ++ index) { 122 if (argv[index][0] == '-') { 123 switch (argv[index][1]) { 124 case 'b': 125 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0)); 126 break; 127 case 'c': 128 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0)); 129 break; 130 case 'f': 131 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family)); 132 break; 133 case 'h': 134 echo_print_help(); 135 return EOK; 136 break; 137 case 'p': 138 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 139 port = (uint16_t) value; 140 break; 141 case 'r': 142 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0)); 143 break; 144 case 's': 145 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 146 size = (value >= 0) ? (size_t) value : 0; 147 break; 148 case 't': 149 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 150 type = (sock_type_t) value; 151 break; 152 case 'v': 153 verbose = 1; 154 break; 155 // long options with the double minus sign ('-') 156 case '-': 157 if (str_lcmp(argv[index] + 2, "backlog=", 6) == 0) { 158 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8)); 159 } else if (str_lcmp(argv[index] + 2, "count=", 6) == 0) { 160 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8)); 161 } else if (str_lcmp(argv[index] + 2, "family=", 7) == 0) { 162 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family)); 163 } 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': 164 145 echo_print_help(); 165 146 return EOK; 166 } else if (str_lcmp(argv[index] + 2, "port=", 5) == 0) { 167 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 147 break; 148 case 'p': 149 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 168 150 port = (uint16_t) value; 169 } else if (str_lcmp(argv[index] + 2, "reply=", 6) == 0) { 170 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8)); 171 } else if (str_lcmp(argv[index] + 2, "size=", 5) == 0) { 172 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 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)); 173 157 size = (value >= 0) ? (size_t) value : 0; 174 } else if (str_lcmp(argv[index] + 2, "type=", 5) == 0) { 175 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type)); 158 break; 159 case 't': 160 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 176 161 type = (sock_type_t) value; 177 } else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) { 162 break; 163 case 'v': 178 164 verbose = 1; 179 } 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: 180 196 echo_print_help(); 181 197 return EINVAL; 182 } 183 break; 184 default: 185 echo_print_help(); 186 return EINVAL; 187 } 188 } else { 198 } 199 }else{ 189 200 echo_print_help(); 190 201 return EINVAL; … … 193 204 194 205 // check the buffer size 195 if (size <= 0){206 if(size <= 0){ 196 207 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size); 197 208 size = 1024; … … 199 210 // size plus the terminating null (\0) 200 211 data = (char *) malloc(size + 1); 201 if (!data){212 if(! data){ 202 213 fprintf(stderr, "Failed to allocate receive buffer.\n"); 203 214 return ENOMEM; … … 209 220 // prepare the address buffer 210 221 bzero(address_data, max_length); 211 switch (family){212 case PF_INET:213 address_in->sin_family = AF_INET;214 address_in->sin_port = htons(port);215 addrlen = sizeof(struct sockaddr_in);216 break;217 case PF_INET6:218 address_in6->sin6_family = AF_INET6;219 address_in6->sin6_port = htons(port);220 addrlen = sizeof(struct sockaddr_in6);221 break;222 default:223 fprintf(stderr, "Protocol family is not supported\n");224 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; 225 236 } 226 237 227 238 // get a listening socket 228 239 listening_id = socket(family, type, 0); 229 if (listening_id < 0){240 if(listening_id < 0){ 230 241 socket_print_error(stderr, listening_id, "Socket create: ", "\n"); 231 242 return listening_id; … … 233 244 234 245 // if the stream socket is used 235 if (type == SOCK_STREAM){246 if(type == SOCK_STREAM){ 236 247 // check the backlog 237 if (backlog <= 0){248 if(backlog <= 0){ 238 249 fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size); 239 250 backlog = 3; 240 251 } 241 252 // set the backlog 242 if (ERROR_OCCURRED(listen(listening_id, backlog))){253 if(ERROR_OCCURRED(listen(listening_id, backlog))){ 243 254 socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n"); 244 255 return ERROR_CODE; … … 247 258 248 259 // bind the listenning socket 249 if (ERROR_OCCURRED(bind(listening_id, address, addrlen))){260 if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){ 250 261 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n"); 251 262 return ERROR_CODE; 252 263 } 253 264 254 if (verbose)265 if(verbose){ 255 266 printf("Socket %d listenning at %d\n", listening_id, port); 267 } 256 268 257 269 socket_id = listening_id; … … 259 271 // do count times 260 272 // or indefinitely if set to a negative value 261 while (count){273 while(count){ 262 274 263 275 addrlen = max_length; 264 if (type == SOCK_STREAM){276 if(type == SOCK_STREAM){ 265 277 // acceept a socket if the stream socket is used 266 278 socket_id = accept(listening_id, address, &addrlen); 267 if (socket_id <= 0){279 if(socket_id <= 0){ 268 280 socket_print_error(stderr, socket_id, "Socket accept: ", "\n"); 269 } else{270 if (verbose)281 }else{ 282 if(verbose){ 271 283 printf("Socket %d accepted\n", socket_id); 284 } 272 285 } 273 286 } 274 287 275 288 // if the datagram socket is used or the stream socked was accepted 276 if (socket_id > 0){289 if(socket_id > 0){ 277 290 278 291 // receive an echo request 279 292 value = recvfrom(socket_id, data, size, 0, address, &addrlen); 280 if (value < 0){293 if(value < 0){ 281 294 socket_print_error(stderr, value, "Socket receive: ", "\n"); 282 } else{295 }else{ 283 296 length = (size_t) value; 284 if (verbose){297 if(verbose){ 285 298 // print the header 286 299 287 300 // get the source port and prepare the address buffer 288 301 address_start = NULL; 289 switch (address->sa_family){290 case AF_INET:291 port = ntohs(address_in->sin_port);292 address_start = (uint8_t *) &address_in->sin_addr.s_addr;293 break;294 case AF_INET6:295 port = ntohs(address_in6->sin6_port);296 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;297 break;298 default:299 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); 300 313 } 301 314 // parse the source address 302 if (address_start){303 if (ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){315 if(address_start){ 316 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ 304 317 fprintf(stderr, "Received address error %d\n", ERROR_CODE); 305 } else{318 }else{ 306 319 data[length] = '\0'; 307 320 printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data); … … 311 324 312 325 // answer the request either with the static reply or the original data 313 if (ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen)))326 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){ 314 327 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 328 } 329 315 330 } 316 331 317 332 // close the accepted stream socket 318 if (type == SOCK_STREAM){319 if (ERROR_OCCURRED(closesocket(socket_id)))333 if(type == SOCK_STREAM){ 334 if(ERROR_OCCURRED(closesocket(socket_id))){ 320 335 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n"); 336 } 321 337 } 322 338 … … 324 340 325 341 // decrease the count if positive 326 if (count > 0){327 count--;328 if (verbose)342 if(count > 0){ 343 -- count; 344 if(verbose){ 329 345 printf("Waiting for next %d packet(s)\n", count); 330 } 331 } 332 333 if (verbose) 346 } 347 } 348 } 349 350 if(verbose){ 334 351 printf("Closing the socket\n"); 352 } 335 353 336 354 // close the listenning socket 337 if (ERROR_OCCURRED(closesocket(listening_id))){355 if(ERROR_OCCURRED(closesocket(listening_id))){ 338 356 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n"); 339 357 return ERROR_CODE; 340 358 } 341 359 342 if (verbose)360 if(verbose){ 343 361 printf("Exiting\n"); 362 } 344 363 345 364 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.