Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/app/echo/echo.c

    r3be62bc raadf01e  
    5555#define NAME    "Echo"
    5656
    57 /** Prints the application help.
    58  */
    59 void echo_print_help(void);
    60 
    6157/** Module entry point.
    6258 *  Reads command line parameters and starts listenning.
     
    6662 */
    6763int main(int argc, char * argv[]);
     64
     65/** Prints the application help.
     66 */
     67void 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 */
     74int 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 */
     81int echo_parse_socket_type(const char * name);
    6882
    6983void echo_print_help(void){
     
    101115}
    102116
     117int 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
     126int 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
    103135int main(int argc, char * argv[]){
    104136        ERROR_DECLARE;
     
    106138        size_t size                     = 1024;
    107139        int verbose                     = 0;
    108         char * reply            = NULL;
    109         sock_type_t type        = SOCK_DGRAM;
     140        char * reply                    = NULL;
     141        sock_type_t type                        = SOCK_DGRAM;
    110142        int count                       = -1;
    111143        int family                      = PF_INET;
    112         uint16_t port           = 7;
     144        uint16_t port                   = 7;
    113145        int backlog                     = 3;
    114146
    115         socklen_t max_length                            = sizeof(struct sockaddr_in6);
     147        socklen_t max_length            = sizeof(struct sockaddr_in6);
    116148        uint8_t address_data[max_length];
    117         struct sockaddr * address                       = (struct sockaddr *) address_data;
     149        struct sockaddr * address               = (struct sockaddr *) address_data;
    118150        struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    119151        struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     
    123155        int socket_id;
    124156        int listening_id;
    125         char * data;
     157        char *                          data;
    126158        size_t length;
    127159        int index;
     
    129161        int value;
    130162
    131         // print the program label
    132163        printf("Task %d - ", task_get_id());
    133164        printf("%s\n", NAME);
    134165
    135         // parse the command line arguments
    136166        for(index = 1; index < argc; ++ index){
    137167                if(argv[index][0] == '-'){
     
    144174                                        break;
    145175                                case 'f':
    146                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
     176                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, echo_parse_protocol_family));
    147177                                        break;
    148178                                case 'h':
     
    162192                                        break;
    163193                                case 't':
    164                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
     194                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, echo_parse_socket_type));
    165195                                        type = (sock_type_t) value;
    166196                                        break;
     
    168198                                        verbose = 1;
    169199                                        break;
    170                                 // long options with the double minus sign ('-')
    171200                                case '-':
    172201                                        if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
     
    175204                                                ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8));
    176205                                        }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    177                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
     206                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, echo_parse_protocol_family));
    178207                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    179208                                                echo_print_help();
     
    188217                                                size = (value >= 0) ? (size_t) value : 0;
    189218                                        }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    190                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
     219                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, echo_parse_socket_type));
    191220                                                type = (sock_type_t) value;
    192221                                        }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
     
    210239        }
    211240
    212         // check the buffer size
    213241        if(size <= 0){
    214242                fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
    215243                size = 1024;
    216244        }
    217         // size plus the terminating null (\0)
     245        // size plus terminating null (\0)
    218246        data = (char *) malloc(size + 1);
    219247        if(! data){
     
    222250        }
    223251
    224         // set the reply size if set
    225252        reply_length = reply ? str_length(reply) : 0;
    226253
    227         // prepare the address buffer
     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
    228260        bzero(address_data, max_length);
    229261        switch(family){
     
    243275        }
    244276
    245         // get a listening socket
    246277        listening_id = socket(family, type, 0);
    247278        if(listening_id < 0){
     
    250281        }
    251282
    252         // if the stream socket is used
    253283        if(type == SOCK_STREAM){
    254                 // check the backlog
    255284                if(backlog <= 0){
    256285                        fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
    257286                        backlog = 3;
    258287                }
    259                 // set the backlog
    260288                if(ERROR_OCCURRED(listen(listening_id, backlog))){
    261289                        socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
     
    264292        }
    265293
    266         // bind the listenning socket
    267294        if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
    268295                socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
     
    276303        socket_id = listening_id;
    277304
    278         // do count times
    279         // or indefinitely if set to a negative value
    280305        while(count){
    281 
    282306                addrlen = max_length;
    283307                if(type == SOCK_STREAM){
    284                         // acceept a socket if the stream socket is used
    285308                        socket_id = accept(listening_id, address, &addrlen);
    286309                        if(socket_id <= 0){
     
    292315                        }
    293316                }
    294 
    295                 // if the datagram socket is used or the stream socked was accepted
    296317                if(socket_id > 0){
    297 
    298                         // receive an echo request
    299318                        value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    300319                        if(value < 0){
     
    303322                                length = (size_t) value;
    304323                                if(verbose){
    305                                         // print the header
    306 
    307                                         // get the source port and prepare the address buffer
    308324                                        address_start = NULL;
    309325                                        switch(address->sa_family){
     
    319335                                                        fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
    320336                                        }
    321                                         // parse the source address
    322337                                        if(address_start){
    323338                                                if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
     
    329344                                        }
    330345                                }
    331 
    332                                 // answer the request either with the static reply or the original data
    333346                                if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
    334347                                        socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    335348                                }
    336 
    337                         }
    338 
    339                         // close the accepted stream socket
     349                        }
    340350                        if(type == SOCK_STREAM){
    341351                                if(ERROR_OCCURRED(closesocket(socket_id))){
     
    343353                                }
    344354                        }
    345 
    346                 }
    347 
    348                 // decrease the count if positive
     355                }
    349356                if(count > 0){
    350357                        -- count;
     
    359366        }
    360367
    361         // close the listenning socket
    362368        if(ERROR_OCCURRED(closesocket(listening_id))){
    363369                socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
Note: See TracChangeset for help on using the changeset viewer.