Ignore:
Timestamp:
2010-03-13T12:17:02Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6ba20a6b
Parents:
d0febca (diff), 2070570 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    rd0febca r7715994  
    4848#include "../../err.h"
    4949
     50#include "../nettest.h"
    5051#include "../parse.h"
    5152#include "../print_error.h"
     
    6566 *  @returns EOK on success.
    6667 */
    67 int             main( int argc, char * argv[] );
     68int main(int argc, char * argv[]);
    6869
    6970/** Prints the application help.
    7071 */
    71 void    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  */
    78 int             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  */
    85 int             parse_socket_type( const char * name );
     72void nettest2_print_help(void);
    8673
    8774/** Refreshes the data.
     
    9077 *  @param[in] size The data block size in bytes.
    9178 */
    92 void    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  */
    103 int     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  */
    112 int     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  */
    123 int     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  */
    137 int     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  */
    151 int     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  */
    167 int     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  */
    173 void    print_mark( int index );
    174 
    175 void print_help( void ){
     79void nettest2_refresh_data(char * data, size_t size);
     80
     81int 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
     306void nettest2_print_help(void){
    176307        printf(
    177308                "Network Networking test 2 aplication - UDP transfer\n" \
     
    201332}
    202333
    203 int 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 
    212 int 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 
    221 void refresh_data( char * data, size_t size ){
    222         size_t  length;
     334void nettest2_refresh_data(char * data, size_t size){
     335        size_t length;
    223336
    224337        // fill the data
    225338        length = 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';
     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';
    232345}
    233346
    234 int 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 
    251 int 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 
    269 int 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 
    286 int 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 
    307 int 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 
    328 int 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 
    356 void print_mark( int index ){
    357         if(( index + 1 ) % 10 ){
    358                 printf( "*" );
    359         }else{
    360                 printf( "|" );
    361         }
    362         fflush( stdout );
    363 }
    364 
    365 int 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;
    554 }
    555 
    556347/** @}
    557348 */
Note: See TracChangeset for help on using the changeset viewer.