Ignore:
File:
1 edited

Legend:

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

    r3be62bc r9d28b9c  
    4848#include "../../err.h"
    4949
    50 #include "../nettest.h"
    5150#include "../parse.h"
    5251#include "../print_error.h"
     
    6665 *  @returns EOK on success.
    6766 */
    68 int main(int argc, char * argv[]);
     67int             main( int argc, char * argv[] );
    6968
    7069/** Prints the application help.
    7170 */
    72 void nettest2_print_help(void);
     71void    print_help( void );
     72
     73/** Translates the character string to the protocol family number.
     74 *  @param[in] name The protocol family name.
     75 *  @returns The corresponding protocol family number.
     76 *  @returns EPFNOSUPPORTED if the protocol family is not supported.
     77 */
     78int             parse_protocol_family( const char * name );
     79
     80/** Translates the character string to the socket type number.
     81 *  @param[in] name The socket type name.
     82 *  @returns The corresponding socket type number.
     83 *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
     84 */
     85int             parse_socket_type( const char * name );
    7386
    7487/** Refreshes the data.
     
    7790 *  @param[in] size The data block size in bytes.
    7891 */
    79 void nettest2_refresh_data(char * data, size_t size);
    80 
    81 int main(int argc, char * argv[]){
    82         ERROR_DECLARE;
    83 
    84         size_t size                     = 28;
    85         int verbose                     = 0;
    86         sock_type_t type        = SOCK_DGRAM;
    87         int sockets                     = 10;
    88         int messages            = 10;
    89         int family                      = PF_INET;
    90         uint16_t port           = 7;
    91 
    92         socklen_t max_length                            = sizeof(struct sockaddr_in6);
    93         uint8_t address_data[max_length];
    94         struct sockaddr * address                       = (struct sockaddr *) address_data;
    95         struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    96         struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
    97         socklen_t addrlen;
    98 //      char address_string[INET6_ADDRSTRLEN];
    99         uint8_t * address_start;
    100 
    101         int * socket_ids;
    102         char * data;
    103         int value;
    104         int index;
    105         struct timeval time_before;
    106         struct timeval time_after;
    107 
    108         printf("Task %d - ", task_get_id());
    109         printf("%s\n", NAME);
    110 
    111         // parse the command line arguments
    112         // stop before the last argument if it does not start with the minus sign ('-')
    113         for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
    114                 // options should start with the minus sign ('-')
    115                 if(argv[index][0] == '-'){
    116                         switch(argv[index][1]){
    117                                 // short options with only one letter
    118                                 case 'f':
    119                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
    120                                         break;
    121                                 case 'h':
    122                                         nettest2_print_help();
    123                                         return EOK;
    124                                         break;
    125                                 case 'm':
    126                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 0));
    127                                         break;
    128                                 case 'n':
    129                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 0));
    130                                         break;
    131                                 case 'p':
    132                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
    133                                         port = (uint16_t) value;
    134                                         break;
    135                                 case 's':
    136                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
    137                                         size = (value >= 0) ? (size_t) value : 0;
    138                                         break;
    139                                 case 't':
    140                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
    141                                         type = (sock_type_t) value;
    142                                         break;
    143                                 case 'v':
    144                                         verbose = 1;
    145                                         break;
    146                                 // long options with the double minus sign ('-')
    147                                 case '-':
    148                                         if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    149                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
    150                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    151                                                 nettest2_print_help();
    152                                                 return EOK;
    153                                         }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
    154                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 8));
    155                                         }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
    156                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 8));
    157                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    158                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
    159                                                 port = (uint16_t) value;
    160                                         }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    161                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
    162                                                 type = (sock_type_t) value;
    163                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    164                                                 verbose = 1;
    165                                         }else{
    166                                                 print_unrecognized(index, argv[index] + 2);
    167                                                 nettest2_print_help();
    168                                                 return EINVAL;
    169                                         }
    170                                         break;
    171                                 default:
    172                                         print_unrecognized(index, argv[index] + 1);
    173                                         nettest2_print_help();
    174                                         return EINVAL;
    175                         }
    176                 }else{
    177                         print_unrecognized(index, argv[index]);
    178                         nettest2_print_help();
    179                         return EINVAL;
    180                 }
    181         }
    182 
    183         // if not before the last argument containing the address
    184         if(index >= argc){
    185                 printf("Command line error: missing address\n");
    186                 nettest2_print_help();
    187                 return EINVAL;
    188         }
    189 
    190         // prepare the address buffer
    191         bzero(address_data, max_length);
    192         switch(family){
    193                 case PF_INET:
    194                         address_in->sin_family = AF_INET;
    195                         address_in->sin_port = htons(port);
    196                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    197                         addrlen = sizeof(struct sockaddr_in);
    198                         break;
    199                 case PF_INET6:
    200                         address_in6->sin6_family = AF_INET6;
    201                         address_in6->sin6_port = htons(port);
    202                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    203                         addrlen = sizeof(struct sockaddr_in6);
    204                         break;
    205                 default:
    206                         fprintf(stderr, "Address family is not supported\n");
    207                         return EAFNOSUPPORT;
    208         }
    209 
    210         // parse the last argument which should contain the address
    211         if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    212                 fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
    213                 return ERROR_CODE;
    214         }
    215 
    216         // check the buffer size
    217         if(size <= 0){
    218                 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
    219                 size = 1024;
    220         }
    221 
    222         // prepare the buffer
    223         // size plus terminating null (\0)
    224         data = (char *) malloc(size + 1);
    225         if(! data){
    226                 fprintf(stderr, "Failed to allocate data buffer.\n");
    227                 return ENOMEM;
    228         }
    229         nettest2_refresh_data(data, size);
    230 
    231         // check the socket count
    232         if(sockets <= 0){
    233                 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
    234                 sockets = 2;
    235         }
    236 
    237         // prepare the socket buffer
    238         // count plus the terminating null (\0)
    239         socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
    240         if(! socket_ids){
    241                 fprintf(stderr, "Failed to allocate receive buffer.\n");
    242                 return ENOMEM;
    243         }
    244         socket_ids[sockets] = NULL;
    245 
    246         if(verbose){
    247                 printf("Starting tests\n");
    248         }
    249 
    250         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    251 
    252         if(type == SOCK_STREAM){
    253                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
    254         }
    255 
    256         if(verbose){
    257                 printf("\n");
    258         }
    259 
    260         if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    261                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    262                 return ERROR_CODE;
    263         }
    264 
    265         ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    266 
    267         if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    268                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    269                 return ERROR_CODE;
    270         }
    271 
    272         if(verbose){
    273                 printf("\tOK\n");
    274         }
    275 
    276         printf("sendto + recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before));
    277 
    278         if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    279                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    280                 return ERROR_CODE;
    281         }
    282 
    283         ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages));
    284         ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    285 
    286         if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    287                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    288                 return ERROR_CODE;
    289         }
    290 
    291         if(verbose){
    292                 printf("\tOK\n");
    293         }
    294 
    295         printf("sendto, recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before));
    296 
    297         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    298 
    299         if(verbose){
    300                 printf("\nExiting\n");
    301         }
    302 
    303         return EOK;
    304 }
    305 
    306 void nettest2_print_help(void){
     92void    refresh_data( char * data, size_t size );
     93
     94/** Creates new sockets.
     95 *  @param[in] verbose A value indicating whether to print out verbose information.
     96 *  @param[out] socket_ids A field to store the socket identifiers.
     97 *  @param[in] sockets The number of sockets to create. Should be at most the size of the field.
     98 *  @param[in] family The socket address family.
     99 *  @param[in] type The socket type.
     100 *  @returns EOK on success.
     101 *  @returns Other error codes as defined for the socket() function.
     102 */
     103int     sockets_create( int verbose, int * socket_ids, int sockets, int family, sock_type_t type );
     104
     105/** Closes sockets.
     106 *  @param[in] verbose A value indicating whether to print out verbose information.
     107 *  @param[in] socket_ids A field of stored socket identifiers.
     108 *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     109 *  @returns EOK on success.
     110 *  @returns Other error codes as defined for the closesocket() function.
     111 */
     112int     sockets_close( int verbose, int * socket_ids, int sockets );
     113
     114/** Connects sockets.
     115 *  @param[in] verbose A value indicating whether to print out verbose information.
     116 *  @param[in] socket_ids A field of stored socket identifiers.
     117 *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     118 *  @param[in] address The destination host address to connect to.
     119 *  @param[in] addrlen The length of the destination address in bytes.
     120 *  @returns EOK on success.
     121 *  @returns Other error codes as defined for the connect() function.
     122 */
     123int     sockets_connect( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen );
     124
     125/** Sends data via sockets.
     126 *  @param[in] verbose A value indicating whether to print out verbose information.
     127 *  @param[in] socket_ids A field of stored socket identifiers.
     128 *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     129 *  @param[in] address The destination host address to send data to.
     130 *  @param[in] addrlen The length of the destination address in bytes.
     131 *  @param[in] data The data to be sent.
     132 *  @param[in] size The data size in bytes.
     133 *  @param[in] messages The number of datagrams per socket to be sent.
     134 *  @returns EOK on success.
     135 *  @returns Other error codes as defined for the sendto() function.
     136 */
     137int     sockets_sendto( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages );
     138
     139/** Receives data via sockets.
     140 *  @param[in] verbose A value indicating whether to print out verbose information.
     141 *  @param[in] socket_ids A field of stored socket identifiers.
     142 *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     143 *  @param[in] address The source host address of received datagrams.
     144 *  @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead.
     145 *  @param[out] data The received data.
     146 *  @param[in] size The maximum data size in bytes.
     147 *  @param[in] messages The number of datagrams per socket to be received.
     148 *  @returns EOK on success.
     149 *  @returns Other error codes as defined for the recvfrom() function.
     150 */
     151int     sockets_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages );
     152
     153/** Sends and receives data via sockets.
     154 *  Each datagram is sent and a reply read consequently.
     155 *  The next datagram is sent after the reply is received.
     156 *  @param[in] verbose A value indicating whether to print out verbose information.
     157 *  @param[in] socket_ids A field of stored socket identifiers.
     158 *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     159 *  @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead.
     160 *  @param[in] addrlen The length of the destination address in bytes.
     161 *  @param[in,out] data The data to be sent. The received data are set instead.
     162 *  @param[in] size The data size in bytes.
     163 *  @param[in] messages The number of datagrams per socket to be received.
     164 *  @returns EOK on success.
     165 *  @returns Other error codes as defined for the recvfrom() function.
     166 */
     167int     sockets_sendto_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages );
     168
     169/** Prints a mark.
     170 *  If the index is a multiple of ten, a different mark is printed.
     171 *  @param[in] index The index of the mark to be printed.
     172 */
     173void    print_mark( int index );
     174
     175void print_help( void ){
    307176        printf(
    308177                "Network Networking test 2 aplication - UDP transfer\n" \
     
    332201}
    333202
    334 void nettest2_refresh_data(char * data, size_t size){
    335         size_t length;
     203int parse_protocol_family( const char * name ){
     204        if( str_lcmp( name, "PF_INET", 7 ) == 0 ){
     205                return PF_INET;
     206        }else if( str_lcmp( name, "PF_INET6", 8 ) == 0 ){
     207                return PF_INET6;
     208        }
     209        return EPFNOSUPPORT;
     210}
     211
     212int parse_socket_type( const char * name ){
     213        if( str_lcmp( name, "SOCK_DGRAM", 11 ) == 0 ){
     214                return SOCK_DGRAM;
     215        }else if( str_lcmp( name, "SOCK_STREAM", 12 ) == 0 ){
     216                return SOCK_STREAM;
     217        }
     218        return ESOCKTNOSUPPORT;
     219}
     220
     221void refresh_data( char * data, size_t size ){
     222        size_t  length;
    336223
    337224        // fill the data
    338225        length = 0;
    339         while(size > length + sizeof(NETTEST2_TEXT) - 1){
    340                 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);
    341                 length += sizeof(NETTEST2_TEXT) - 1;
    342         }
    343         memcpy(data + length, NETTEST2_TEXT, size - length);
    344         data[size] = '\0';
     226        while( size > length + sizeof( NETTEST2_TEXT ) - 1 ){
     227                memcpy( data + length, NETTEST2_TEXT, sizeof( NETTEST2_TEXT ) - 1 );
     228                length += sizeof( NETTEST2_TEXT ) - 1;
     229        }
     230        memcpy( data + length, NETTEST2_TEXT, size - length );
     231        data[ size ] = '\0';
     232}
     233
     234int sockets_create( int verbose, int * socket_ids, int sockets, int family, sock_type_t type ){
     235        int     index;
     236
     237        if( verbose ) printf( "Create\t" );
     238        fflush( stdout );
     239        for( index = 0; index < sockets; ++ index ){
     240                socket_ids[ index ] = socket( family, type, 0 );
     241                if( socket_ids[ index ] < 0 ){
     242                        printf( "Socket %d (%d) error:\n", index, socket_ids[ index ] );
     243                        socket_print_error( stderr, socket_ids[ index ], "Socket create: ", "\n" );
     244                        return socket_ids[ index ];
     245                }
     246                if( verbose ) print_mark( index );
     247        }
     248        return EOK;
     249}
     250
     251int sockets_close( int verbose, int * socket_ids, int sockets ){
     252        ERROR_DECLARE;
     253
     254        int     index;
     255
     256        if( verbose ) printf( "\tClose\t" );
     257        fflush( stdout );
     258        for( index = 0; index < sockets; ++ index ){
     259                if( ERROR_OCCURRED( closesocket( socket_ids[ index ] ))){
     260                        printf( "Socket %d (%d) error:\n", index, socket_ids[ index ] );
     261                        socket_print_error( stderr, ERROR_CODE, "Socket close: ", "\n" );
     262                        return ERROR_CODE;
     263                }
     264                if( verbose ) print_mark( index );
     265        }
     266        return EOK;
     267}
     268
     269int sockets_connect( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen ){
     270        ERROR_DECLARE;
     271
     272        int     index;
     273
     274        if( verbose ) printf( "\tConnect\t" );
     275        fflush( stdout );
     276        for( index = 0; index < sockets; ++ index ){
     277                if( ERROR_OCCURRED( connect( socket_ids[ index ], address, addrlen ))){
     278                        socket_print_error( stderr, ERROR_CODE, "Socket connect: ", "\n" );
     279                        return ERROR_CODE;
     280                }
     281                if( verbose ) print_mark( index );
     282        }
     283        return EOK;
     284}
     285
     286int sockets_sendto( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages ){
     287        ERROR_DECLARE;
     288
     289        int     index;
     290        int     message;
     291
     292        if( verbose ) printf( "\tSendto\t" );
     293        fflush( stdout );
     294        for( index = 0; index < sockets; ++ index ){
     295                for( message = 0; message < messages; ++ message ){
     296                        if( ERROR_OCCURRED( sendto( socket_ids[ index ], data, size, 0, address, addrlen ))){
     297                                printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
     298                                socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
     299                                return ERROR_CODE;
     300                        }
     301                }
     302                if( verbose ) print_mark( index );
     303        }
     304        return EOK;
     305}
     306
     307int sockets_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ){
     308        int     value;
     309        int     index;
     310        int     message;
     311
     312        if( verbose ) printf( "\tRecvfrom\t" );
     313        fflush( stdout );
     314        for( index = 0; index < sockets; ++ index ){
     315                for( message = 0; message < messages; ++ message ){
     316                        value = recvfrom( socket_ids[ index ], data, size, 0, address, addrlen );
     317                        if( value < 0 ){
     318                                printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
     319                                socket_print_error( stderr, value, "Socket receive: ", "\n" );
     320                                return value;
     321                        }
     322                }
     323                if( verbose ) print_mark( index );
     324        }
     325        return EOK;
     326}
     327
     328int sockets_sendto_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ){
     329        ERROR_DECLARE;
     330
     331        int     value;
     332        int     index;
     333        int     message;
     334
     335        if( verbose ) printf( "\tSendto and recvfrom\t" );
     336        fflush( stdout );
     337        for( index = 0; index < sockets; ++ index ){
     338                for( message = 0; message < messages; ++ message ){
     339                        if( ERROR_OCCURRED( sendto( socket_ids[ index ], data, size, 0, address, * addrlen ))){
     340                                printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
     341                                socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
     342                                return ERROR_CODE;
     343                        }
     344                        value = recvfrom( socket_ids[ index ], data, size, 0, address, addrlen );
     345                        if( value < 0 ){
     346                                printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
     347                                socket_print_error( stderr, value, "Socket receive: ", "\n" );
     348                                return value;
     349                        }
     350                }
     351                if( verbose ) print_mark( index );
     352        }
     353        return EOK;
     354}
     355
     356void print_mark( int index ){
     357        if(( index + 1 ) % 10 ){
     358                printf( "*" );
     359        }else{
     360                printf( "|" );
     361        }
     362        fflush( stdout );
     363}
     364
     365int main( int argc, char * argv[] ){
     366        ERROR_DECLARE;
     367
     368        size_t                          size                    = 28;
     369        int                                     verbose                 = 0;
     370        sock_type_t                     type                    = SOCK_DGRAM;
     371        int                                     sockets                 = 10;
     372        int                                     messages                = 10;
     373        int                                     family                  = PF_INET;
     374        uint16_t                        port                    = 7;
     375
     376        socklen_t                       max_length              = sizeof( struct sockaddr_in6 );
     377        uint8_t                         address_data[ max_length ];
     378        struct sockaddr *               address         = ( struct sockaddr * ) address_data;
     379        struct sockaddr_in *    address_in              = ( struct sockaddr_in * ) address;
     380        struct sockaddr_in6 *   address_in6     = ( struct sockaddr_in6 * ) address;
     381        socklen_t                       addrlen;
     382//      char                            address_string[ INET6_ADDRSTRLEN ];
     383        uint8_t *                       address_start;
     384
     385        int *                           socket_ids;
     386        char *                          data;
     387        int                                     value;
     388        int                                     index;
     389        struct timeval          time_before;
     390        struct timeval          time_after;
     391
     392        printf( "Task %d - ", task_get_id());
     393        printf( "%s\n", NAME );
     394
     395        if( argc <= 1 ){
     396                print_help();
     397                return EINVAL;
     398        }
     399
     400        for( index = 1; ( index < argc - 1 ) || (( index == argc ) && ( argv[ index ][ 0 ] == '-' )); ++ index ){
     401                if( argv[ index ][ 0 ] == '-' ){
     402                        switch( argv[ index ][ 1 ] ){
     403                                case 'f':       ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 0, parse_protocol_family ));
     404                                                        break;
     405                                case 'h':       print_help();
     406                                                        return EOK;
     407                                                        break;
     408                                case 'm':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & messages, "message count", 0 ));
     409                                                        break;
     410                                case 'n':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & sockets, "socket count", 0 ));
     411                                                        break;
     412                                case 'p':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 0 ));
     413                                                        port = ( uint16_t ) value;
     414                                                        break;
     415                                case 's':       ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 0 ));
     416                                                        size = (value >= 0 ) ? ( size_t ) value : 0;
     417                                                        break;
     418                                case 't':       ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 0, parse_socket_type ));
     419                                                        type = ( sock_type_t ) value;
     420                                                        break;
     421                                case 'v':       verbose = 1;
     422                                                        break;
     423                                case '-':       if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){
     424                                                                ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 9, parse_protocol_family ));
     425                                                        }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){
     426                                                                print_help();
     427                                                                return EOK;
     428                                                        }else if( str_lcmp( argv[ index ] + 2, "messages=", 6 ) == 0 ){
     429                                                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & messages, "message count", 8 ));
     430                                                        }else if( str_lcmp( argv[ index ] + 2, "sockets=", 6 ) == 0 ){
     431                                                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & sockets, "socket count", 8 ));
     432                                                        }else if( str_lcmp( argv[ index ] + 2, "port=", 5 ) == 0 ){
     433                                                                ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 7 ));
     434                                                                port = ( uint16_t ) value;
     435                                                        }else if( str_lcmp( argv[ index ] + 2, "type=", 5 ) == 0 ){
     436                                                                ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 7, parse_socket_type ));
     437                                                                type = ( sock_type_t ) value;
     438                                                        }else if( str_lcmp( argv[ index ] + 2, "verbose", 8 ) == 0 ){
     439                                                                verbose = 1;
     440                                                        }else{
     441                                                                print_unrecognized( index, argv[ index ] + 2 );
     442                                                                print_help();
     443                                                                return EINVAL;
     444                                                        }
     445                                                        break;
     446                                default:
     447                                        print_unrecognized( index, argv[ index ] + 1 );
     448                                        print_help();
     449                                        return EINVAL;
     450                        }
     451                }else{
     452                        print_unrecognized( index, argv[ index ] );
     453                        print_help();
     454                        return EINVAL;
     455                }
     456        }
     457
     458        bzero( address_data, max_length );
     459        switch( family ){
     460                case PF_INET:
     461                        address_in->sin_family = AF_INET;
     462                        address_in->sin_port = htons( port );
     463                        address_start = ( uint8_t * ) & address_in->sin_addr.s_addr;
     464                        addrlen = sizeof( struct sockaddr_in );
     465                        break;
     466                case PF_INET6:
     467                        address_in6->sin6_family = AF_INET6;
     468                        address_in6->sin6_port = htons( port );
     469                        address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr;
     470                        addrlen = sizeof( struct sockaddr_in6 );
     471                        break;
     472                default:
     473                        fprintf( stderr, "Address family is not supported\n" );
     474                        return EAFNOSUPPORT;
     475        }
     476
     477        if( ERROR_OCCURRED( inet_pton( family, argv[ argc - 1 ], address_start ))){
     478                fprintf( stderr, "Address parse error %d\n", ERROR_CODE );
     479                return ERROR_CODE;
     480        }
     481
     482        if( size <= 0 ){
     483                fprintf( stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size );
     484                size = 1024;
     485        }
     486        // size plus terminating null (\0)
     487        data = ( char * ) malloc( size + 1 );
     488        if( ! data ){
     489                fprintf( stderr, "Failed to allocate data buffer.\n" );
     490                return ENOMEM;
     491        }
     492        refresh_data( data, size );
     493
     494        if( sockets <= 0 ){
     495                fprintf( stderr, "Socket count too small (%d). Using 2 instead.\n", sockets );
     496                sockets = 2;
     497        }
     498        // count plus terminating null (\0)
     499        socket_ids = ( int * ) malloc( sizeof( int ) * ( sockets + 1 ));
     500        if( ! socket_ids ){
     501                fprintf( stderr, "Failed to allocate receive buffer.\n" );
     502                return ENOMEM;
     503        }
     504        socket_ids[ sockets ] = NULL;
     505
     506        if( verbose ) printf( "Starting tests\n" );
     507
     508        ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type ));
     509
     510        if( type == SOCK_STREAM ){
     511                ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, addrlen ));
     512        }
     513
     514        if( verbose ) printf( "\n" );
     515
     516        if( ERROR_OCCURRED( gettimeofday( & time_before, NULL ))){
     517                fprintf( stderr, "Get time of day error %d\n", ERROR_CODE );
     518                return ERROR_CODE;
     519        }
     520
     521        ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, messages ));
     522
     523        if( ERROR_OCCURRED( gettimeofday( & time_after, NULL ))){
     524                fprintf( stderr, "Get time of day error %d\n", ERROR_CODE );
     525                return ERROR_CODE;
     526        }
     527
     528        if( verbose ) printf( "\tOK\n" );
     529
     530        printf( "sendto + recvfrom tested in %d microseconds\n", tv_sub( & time_after, & time_before ));
     531
     532        if( ERROR_OCCURRED( gettimeofday( & time_before, NULL ))){
     533                fprintf( stderr, "Get time of day error %d\n", ERROR_CODE );
     534                return ERROR_CODE;
     535        }
     536
     537        ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, sockets, address, addrlen, data, size, messages ));
     538        ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, messages ));
     539
     540        if( ERROR_OCCURRED( gettimeofday( & time_after, NULL ))){
     541                fprintf( stderr, "Get time of day error %d\n", ERROR_CODE );
     542                return ERROR_CODE;
     543        }
     544
     545        if( verbose ) printf( "\tOK\n" );
     546
     547        printf( "sendto, recvfrom tested in %d microseconds\n", tv_sub( & time_after, & time_before ));
     548
     549        ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets ));
     550
     551        if( verbose ) printf( "\nExiting\n" );
     552
     553        return EOK;
    345554}
    346555
Note: See TracChangeset for help on using the changeset viewer.