Ignore:
File:
1 edited

Legend:

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

    r3be62bc r1b053ca2  
    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.
     
    6561 *  @returns EOK on success.
    6662 */
    67 int main(int argc, char * argv[]);
    68 
    69 void echo_print_help(void){
     63int             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 );
     82
     83void echo_print_help( void ){
    7084        printf(
    7185                "Network Echo aplication\n" \
     
    101115}
    102116
    103 int main(int argc, char * argv[]){
     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
     135int main( int argc, char * argv[] ){
    104136        ERROR_DECLARE;
    105137
    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);
    116         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;
    120         socklen_t addrlen;
    121         char address_string[INET6_ADDRSTRLEN];
    122         uint8_t * address_start;
    123         int socket_id;
    124         int listening_id;
    125         char * data;
    126         size_t length;
    127         int index;
    128         size_t reply_length;
    129         int value;
    130 
    131         // print the program label
    132         printf("Task %d - ", task_get_id());
    133         printf("%s\n", NAME);
    134 
    135         // parse the command line arguments
    136         for(index = 1; index < argc; ++ index){
    137                 if(argv[index][0] == '-'){
    138                         switch(argv[index][1]){
    139                                 case 'b':
    140                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &backlog, "accepted sockets queue size", 0));
    141                                         break;
    142                                 case 'c':
    143                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 0));
    144                                         break;
    145                                 case 'f':
    146                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
    147                                         break;
    148                                 case 'h':
    149                                         echo_print_help();
    150                                         return EOK;
    151                                         break;
    152                                 case 'p':
    153                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
    154                                         port = (uint16_t) value;
    155                                         break;
    156                                 case 'r':
    157                                         ERROR_PROPAGATE(parse_parameter_string(argc, argv, &index, &reply, "reply string", 0));
    158                                         break;
    159                                 case 's':
    160                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "receive size", 0));
    161                                         size = (value >= 0) ? (size_t) value : 0;
    162                                         break;
    163                                 case 't':
    164                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
    165                                         type = (sock_type_t) value;
    166                                         break;
    167                                 case 'v':
    168                                         verbose = 1;
    169                                         break;
    170                                 // long options with the double minus sign ('-')
    171                                 case '-':
    172                                         if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
    173                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &backlog, "accepted sockets queue size", 8));
    174                                         }else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
    175                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8));
    176                                         }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));
    178                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    179                                                 echo_print_help();
    180                                                 return EOK;
    181                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    182                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
    183                                                 port = (uint16_t) value;
    184                                         }else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){
    185                                                 ERROR_PROPAGATE(parse_parameter_string(argc, argv, &index, &reply, "reply string", 8));
    186                                         }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
    187                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "receive size", 7));
    188                                                 size = (value >= 0) ? (size_t) value : 0;
    189                                         }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));
    191                                                 type = (sock_type_t) value;
    192                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    193                                                 verbose = 1;
    194                                         }else{
    195                                                 print_unrecognized(index, argv[index] + 2);
    196                                                 echo_print_help();
    197                                                 return EINVAL;
    198                                         }
    199                                         break;
     138        size_t                          size                    = 1024;
     139        int                                     verbose                 = 0;
     140        char *                          reply                   = NULL;
     141        sock_type_t                     type                    = SOCK_DGRAM;
     142        int                                     count                   = -1;
     143        int                                     family                  = PF_INET;
     144        uint16_t                        port                    = 7;
     145        int                                     backlog                 = 3;
     146
     147        socklen_t                       max_length              = sizeof( struct sockaddr_in6 );
     148        uint8_t                         address_data[ max_length ];
     149        struct sockaddr *               address         = ( struct sockaddr * ) address_data;
     150        struct sockaddr_in *    address_in              = ( struct sockaddr_in * ) address;
     151        struct sockaddr_in6 *   address_in6     = ( struct sockaddr_in6 * ) address;
     152        socklen_t                       addrlen;
     153        char                            address_string[ INET6_ADDRSTRLEN ];
     154        uint8_t *                       address_start;
     155        int                                     socket_id;
     156        int                                     listening_id;
     157        char *                          data;
     158        size_t                          length;
     159        int                                     index;
     160        size_t                          reply_length;
     161        int                                     value;
     162
     163        printf( "Task %d - ", task_get_id());
     164        printf( "%s\n", NAME );
     165
     166        for( index = 1; index < argc; ++ index ){
     167                if( argv[ index ][ 0 ] == '-' ){
     168                        switch( argv[ index ][ 1 ] ){
     169                                case 'b':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & backlog, "accepted sockets queue size", 0 ));
     170                                                        break;
     171                                case 'c':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "message count", 0 ));
     172                                                        break;
     173                                case 'f':       ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 0, echo_parse_protocol_family ));
     174                                                        break;
     175                                case 'h':       echo_print_help();
     176                                                        return EOK;
     177                                                        break;
     178                                case 'p':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 0 ));
     179                                                        port = ( uint16_t ) value;
     180                                                        break;
     181                                case 'r':       ERROR_PROPAGATE( parse_parameter_string( argc, argv, & index, & reply, "reply string", 0 ));
     182                                                        break;
     183                                case 's':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "receive size", 0 ));
     184                                                        size = (value >= 0 ) ? ( size_t ) value : 0;
     185                                                        break;
     186                                case 't':       ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 0, echo_parse_socket_type ));
     187                                                        type = ( sock_type_t ) value;
     188                                                        break;
     189                                case 'v':       verbose = 1;
     190                                                        break;
     191                                case '-':       if( str_lcmp( argv[ index ] + 2, "backlog=", 6 ) == 0 ){
     192                                                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & backlog, "accepted sockets queue size", 8 ));
     193                                                        }else if( str_lcmp( argv[ index ] + 2, "count=", 6 ) == 0 ){
     194                                                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & count, "message count", 8 ));
     195                                                        }else if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){
     196                                                                ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 9, echo_parse_protocol_family ));
     197                                                        }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){
     198                                                                echo_print_help();
     199                                                                return EOK;
     200                                                        }else if( str_lcmp( argv[ index ] + 2, "port=", 5 ) == 0 ){
     201                                                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 7 ));
     202                                                                port = ( uint16_t ) value;
     203                                                        }else if( str_lcmp( argv[ index ] + 2, "reply=", 6 ) == 0 ){
     204                                                                ERROR_PROPAGATE( parse_parameter_string( argc, argv, & index, & reply, "reply string", 8 ));
     205                                                        }else if( str_lcmp( argv[ index ] + 2, "size=", 5 ) == 0 ){
     206                                                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "receive size", 7 ));
     207                                                                size = (value >= 0 ) ? ( size_t ) value : 0;
     208                                                        }else if( str_lcmp( argv[ index ] + 2, "type=", 5 ) == 0 ){
     209                                                                ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 7, echo_parse_socket_type ));
     210                                                                type = ( sock_type_t ) value;
     211                                                        }else if( str_lcmp( argv[ index ] + 2, "verbose", 8 ) == 0 ){
     212                                                                verbose = 1;
     213                                                        }else{
     214                                                                print_unrecognized( index, argv[ index ] + 2 );
     215                                                                echo_print_help();
     216                                                                return EINVAL;
     217                                                        }
     218                                                        break;
    200219                                default:
    201                                         print_unrecognized(index, argv[index] + 1);
     220                                        print_unrecognized( index, argv[ index ] + 1 );
    202221                                        echo_print_help();
    203222                                        return EINVAL;
    204223                        }
    205224                }else{
    206                         print_unrecognized(index, argv[index]);
     225                        print_unrecognized( index, argv[ index ] );
    207226                        echo_print_help();
    208227                        return EINVAL;
     
    210229        }
    211230
    212         // check the buffer size
    213         if(size <= 0){
    214                 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
     231        if( size <= 0 ){
     232                fprintf( stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size );
    215233                size = 1024;
    216234        }
    217         // size plus the terminating null (\0)
    218         data = (char *) malloc(size + 1);
    219         if(! data){
    220                 fprintf(stderr, "Failed to allocate receive buffer.\n");
     235        // size plus terminating null (\0)
     236        data = ( char * ) malloc( size + 1 );
     237        if( ! data ){
     238                fprintf( stderr, "Failed to allocate receive buffer.\n" );
    221239                return ENOMEM;
    222240        }
    223241
    224         // set the reply size if set
    225         reply_length = reply ? str_length(reply) : 0;
    226 
    227         // prepare the address buffer
    228         bzero(address_data, max_length);
    229         switch(family){
     242        reply_length = reply ? str_length( reply ) : 0;
     243
     244        listening_id = socket( family, type, 0 );
     245        if( listening_id < 0 ){
     246                socket_print_error( stderr, listening_id, "Socket create: ", "\n" );
     247                return listening_id;
     248        }
     249
     250        bzero( address_data, max_length );
     251        switch( family ){
    230252                case PF_INET:
    231253                        address_in->sin_family = AF_INET;
    232                         address_in->sin_port = htons(port);
    233                         addrlen = sizeof(struct sockaddr_in);
     254                        address_in->sin_port = htons( port );
     255                        addrlen = sizeof( struct sockaddr_in );
    234256                        break;
    235257                case PF_INET6:
    236258                        address_in6->sin6_family = AF_INET6;
    237                         address_in6->sin6_port = htons(port);
    238                         addrlen = sizeof(struct sockaddr_in6);
     259                        address_in6->sin6_port = htons( port );
     260                        addrlen = sizeof( struct sockaddr_in6 );
    239261                        break;
    240262                default:
    241                         fprintf(stderr, "Protocol family is not supported\n");
     263                        fprintf( stderr, "Protocol family is not supported\n" );
    242264                        return EAFNOSUPPORT;
    243265        }
    244266
    245         // get a listening socket
    246         listening_id = socket(family, type, 0);
    247         if(listening_id < 0){
    248                 socket_print_error(stderr, listening_id, "Socket create: ", "\n");
     267        listening_id = socket( family, type, 0 );
     268        if( listening_id < 0 ){
     269                socket_print_error( stderr, listening_id, "Socket create: ", "\n" );
    249270                return listening_id;
    250271        }
    251272
    252         // if the stream socket is used
    253         if(type == SOCK_STREAM){
    254                 // check the backlog
    255                 if(backlog <= 0){
    256                         fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
     273        if( type == SOCK_STREAM ){
     274                if( backlog <= 0 ){
     275                        fprintf( stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size );
    257276                        backlog = 3;
    258277                }
    259                 // set the backlog
    260                 if(ERROR_OCCURRED(listen(listening_id, backlog))){
    261                         socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
     278                if( ERROR_OCCURRED( listen( listening_id, backlog ))){
     279                        socket_print_error( stderr, ERROR_CODE, "Socket listen: ", "\n" );
    262280                        return ERROR_CODE;
    263281                }
    264282        }
    265283
    266         // bind the listenning socket
    267         if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
    268                 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
     284        if( ERROR_OCCURRED( bind( listening_id, address, addrlen ))){
     285                socket_print_error( stderr, ERROR_CODE, "Socket bind: ", "\n" );
    269286                return ERROR_CODE;
    270287        }
    271288
    272         if(verbose){
    273                 printf("Socket %d listenning at %d\n", listening_id, port);
    274         }
     289        if( verbose ) printf( "Socket %d listenning at %d\n", listening_id, port );
    275290
    276291        socket_id = listening_id;
    277292
    278         // do count times
    279         // or indefinitely if set to a negative value
    280         while(count){
    281 
     293        while( count ){
    282294                addrlen = max_length;
    283                 if(type == SOCK_STREAM){
    284                         // acceept a socket if the stream socket is used
    285                         socket_id = accept(listening_id, address, &addrlen);
    286                         if(socket_id <= 0){
    287                                 socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
     295                if( type == SOCK_STREAM ){
     296                        socket_id = accept( listening_id, address, & addrlen );
     297                        if( socket_id <= 0 ){
     298                                socket_print_error( stderr, socket_id, "Socket accept: ", "\n" );
    288299                        }else{
    289                                 if(verbose){
    290                                         printf("Socket %d accepted\n", socket_id);
    291                                 }
     300                                if( verbose ) printf( "Socket %d accepted\n", socket_id );
    292301                        }
    293302                }
    294 
    295                 // if the datagram socket is used or the stream socked was accepted
    296                 if(socket_id > 0){
    297 
    298                         // receive an echo request
    299                         value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    300                         if(value < 0){
    301                                 socket_print_error(stderr, value, "Socket receive: ", "\n");
     303                if( socket_id > 0 ){
     304                        value = recvfrom( socket_id, data, size, 0, address, & addrlen );
     305                        if( value < 0 ){
     306                                socket_print_error( stderr, value, "Socket receive: ", "\n" );
    302307                        }else{
    303                                 length = (size_t) value;
    304                                 if(verbose){
    305                                         // print the header
    306 
    307                                         // get the source port and prepare the address buffer
     308                                length = ( size_t ) value;
     309                                if( verbose ){
    308310                                        address_start = NULL;
    309                                         switch(address->sa_family){
     311                                        switch( address->sa_family ){
    310312                                                case AF_INET:
    311                                                         port = ntohs(address_in->sin_port);
    312                                                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
     313                                                        port = ntohs( address_in->sin_port );
     314                                                        address_start = ( uint8_t * ) & address_in->sin_addr.s_addr;
    313315                                                        break;
    314316                                                case AF_INET6:
    315                                                         port = ntohs(address_in6->sin6_port);
    316                                                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
     317                                                        port = ntohs( address_in6->sin6_port );
     318                                                        address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr;
    317319                                                        break;
    318320                                                default:
    319                                                         fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
     321                                                        fprintf( stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family );
    320322                                        }
    321                                         // parse the source address
    322                                         if(address_start){
    323                                                 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
    324                                                         fprintf(stderr, "Received address error %d\n", ERROR_CODE);
     323                                        if( address_start ){
     324                                                if( ERROR_OCCURRED( inet_ntop( address->sa_family, address_start, address_string, sizeof( address_string )))){
     325                                                        fprintf( stderr, "Received address error %d\n", ERROR_CODE );
    325326                                                }else{
    326                                                         data[length] = '\0';
    327                                                         printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data);
     327                                                        data[ length ] = '\0';
     328                                                        printf( "Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data );
    328329                                                }
    329330                                        }
    330331                                }
    331 
    332                                 // answer the request either with the static reply or the original data
    333                                 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
    334                                         socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    335                                 }
    336 
    337                         }
    338 
    339                         // close the accepted stream socket
    340                         if(type == SOCK_STREAM){
    341                                 if(ERROR_OCCURRED(closesocket(socket_id))){
    342                                         socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
     332                                if( ERROR_OCCURRED( sendto( socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen ))){
     333                                        socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
    343334                                }
    344335                        }
    345 
    346                 }
    347 
    348                 // decrease the count if positive
    349                 if(count > 0){
     336                        if( type == SOCK_STREAM ){
     337                                if( ERROR_OCCURRED( closesocket( socket_id ))){
     338                                        socket_print_error( stderr, ERROR_CODE, "Close socket: ", "\n" );
     339                                }
     340                        }
     341                }
     342                if( count > 0 ){
    350343                        -- count;
    351                         if(verbose){
    352                                 printf("Waiting for next %d packet(s)\n", count);
    353                         }
    354                 }
    355         }
    356 
    357         if(verbose){
    358                 printf("Closing the socket\n");
    359         }
    360 
    361         // close the listenning socket
    362         if(ERROR_OCCURRED(closesocket(listening_id))){
    363                 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
     344                        if( verbose ) printf( "Waiting for next %d packet(s)\n", count );
     345                }
     346        }
     347
     348        if( verbose ) printf( "Closing the socket\n" );
     349
     350        if( ERROR_OCCURRED( closesocket( listening_id ))){
     351                socket_print_error( stderr, ERROR_CODE, "Close socket: ", "\n" );
    364352                return ERROR_CODE;
    365353        }
    366354
    367         if(verbose){
    368                 printf("Exiting\n");
    369         }
     355        if( verbose ) printf( "Exiting\n" );
    370356
    371357        return EOK;
Note: See TracChangeset for help on using the changeset viewer.