Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/netecho/netecho.c

    r481b212 r2721a75  
    2828
    2929/** @addtogroup netecho
    30  * @{
     30 *  @{
    3131 */
    3232
    3333/** @file
    34  * Network echo application.
    35  * Answers received packets.
     34 *  Network echo application.
     35 *  Answers received packets.
    3636 */
    3737
     
    4242#include <arg_parse.h>
    4343
    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>
    4950
    5051#include "print_error.h"
    5152
    52 /** Network echo module name. */
     53/** Network echo module name.
     54 */
    5355#define NAME    "Network Echo"
    5456
    55 static void echo_print_help(void)
    56 {
     57/** Prints the application help.
     58 */
     59void 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 */
     67int main(int argc, char * argv[]);
     68
     69void echo_print_help(void){
    5770        printf(
    5871                "Network Echo aplication\n" \
     
    88101}
    89102
    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);
     103int 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);
    102116        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;
    106120        socklen_t addrlen;
    107121        char address_string[INET6_ADDRSTRLEN];
    108         uint8_t *address_start;
     122        uint8_t * address_start;
    109123        int socket_id;
    110124        int listening_id;
    111         char *data;
     125        char * data;
    112126        size_t length;
    113127        int index;
    114128        size_t reply_length;
    115129        int value;
    116         int rc;
    117130
    118131        // 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':
    182145                                        echo_print_help();
    183146                                        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));
    188150                                        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));
    197157                                        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));
    202161                                        type = (sock_type_t) value;
    203                                 } else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) {
     162                                        break;
     163                                case 'v':
    204164                                        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:
    206196                                        echo_print_help();
    207197                                        return EINVAL;
    208                                 }
    209                                 break;
    210                         default:
    211                                 echo_print_help();
    212                                 return EINVAL;
    213                         }
    214                 } else {
     198                        }
     199                }else{
    215200                        echo_print_help();
    216201                        return EINVAL;
     
    219204
    220205        // check the buffer size
    221         if (size <= 0) {
     206        if(size <= 0){
    222207                fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
    223208                size = 1024;
     
    225210        // size plus the terminating null (\0)
    226211        data = (char *) malloc(size + 1);
    227         if (!data) {
     212        if(! data){
    228213                fprintf(stderr, "Failed to allocate receive buffer.\n");
    229214                return ENOMEM;
     
    235220        // prepare the address buffer
    236221        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;
    251236        }
    252237
    253238        // get a listening socket
    254239        listening_id = socket(family, type, 0);
    255         if (listening_id < 0) {
     240        if(listening_id < 0){
    256241                socket_print_error(stderr, listening_id, "Socket create: ", "\n");
    257242                return listening_id;
     
    259244
    260245        // if the stream socket is used
    261         if (type == SOCK_STREAM) {
     246        if(type == SOCK_STREAM){
    262247                // check the backlog
    263                 if (backlog <= 0) {
     248                if(backlog <= 0){
    264249                        fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
    265250                        backlog = 3;
    266251                }
    267252                // 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;
    272256                }
    273257        }
    274258
    275259        // 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){
    283266                printf("Socket %d listenning at %d\n", listening_id, port);
     267        }
    284268
    285269        socket_id = listening_id;
     
    287271        // do count times
    288272        // or indefinitely if set to a negative value
    289         while (count) {
     273        while(count){
    290274
    291275                addrlen = max_length;
    292                 if (type == SOCK_STREAM) {
     276                if(type == SOCK_STREAM){
    293277                        // acceept a socket if the stream socket is used
    294278                        socket_id = accept(listening_id, address, &addrlen);
    295                         if (socket_id <= 0) {
     279                        if(socket_id <= 0){
    296280                                socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
    297                         } else {
    298                                 if (verbose)
     281                        }else{
     282                                if(verbose){
    299283                                        printf("Socket %d accepted\n", socket_id);
     284                                }
    300285                        }
    301286                }
    302287
    303288                // if the datagram socket is used or the stream socked was accepted
    304                 if (socket_id > 0) {
     289                if(socket_id > 0){
    305290
    306291                        // receive an echo request
    307292                        value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    308                         if (value < 0) {
     293                        if(value < 0){
    309294                                socket_print_error(stderr, value, "Socket receive: ", "\n");
    310                         } else {
     295                        }else{
    311296                                length = (size_t) value;
    312                                 if (verbose) {
     297                                if(verbose){
    313298                                        // print the header
    314299
    315300                                        // get the source port and prepare the address buffer
    316301                                        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);
    328313                                        }
    329314                                        // 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{
    335319                                                        data[length] = '\0';
    336320                                                        printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data);
     
    340324
    341325                                // 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
    345330                        }
    346331
    347332                        // 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                                }
    352337                        }
    353338
     
    355340
    356341                // decrease the count if positive
    357                 if (count > 0) {
    358                         count--;
    359                         if (verbose)
     342                if(count > 0){
     343                        -- count;
     344                        if(verbose){
    360345                                printf("Waiting for next %d packet(s)\n", count);
    361                 }
    362         }
    363 
    364         if (verbose)
     346                        }
     347                }
     348        }
     349
     350        if(verbose){
    365351                printf("Closing the socket\n");
     352        }
    366353
    367354        // 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){
    375361                printf("Exiting\n");
     362        }
    376363
    377364        return EOK;
Note: See TracChangeset for help on using the changeset viewer.