Ignore:
File:
1 edited

Legend:

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

    rd9e2e0e r7e752b2  
    2828
    2929/** @addtogroup nettest
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Networking test 2 application - transfer.
    35  */
     34 * Networking test 2 application - transfer.
     35 */
     36
     37#include "nettest.h"
     38#include "print_error.h"
    3639
    3740#include <malloc.h>
     
    4144#include <time.h>
    4245#include <arg_parse.h>
    43 #include <err.h>
     46#include <bool.h>
    4447
    4548#include <net/in.h>
     
    4952#include <net/socket_parse.h>
    5053
    51 #include "nettest.h"
    52 #include "print_error.h"
    53 
    54 /** Echo module name.
    55  */
     54/** Echo module name. */
    5655#define NAME    "Nettest2"
    5756
    58 /** Packet data pattern.
    59  */
     57/** Packet data pattern. */
    6058#define NETTEST2_TEXT   "Networking test 2 - transfer"
    6159
    62 /** Module entry point.
    63  *  Starts testing.
    64  *  @param[in] argc The number of command line parameters.
    65  *  @param[in] argv The command line parameters.
    66  *  @returns EOK on success.
    67  */
    68 int main(int argc, char * argv[]);
    69 
    70 /** Prints the application help.
    71  */
    72 void nettest2_print_help(void);
    73 
    74 /** Refreshes the data.
    75  *  Fills the data block with the NETTEST1_TEXT pattern.
    76  *  @param[out] data The data block.
    77  *  @param[in] size The data block size in bytes.
    78  */
    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;
     60static size_t size;
     61static bool verbose;
     62static sock_type_t type;
     63static int sockets;
     64static int messages;
     65static int family;
     66static uint16_t port;
     67
     68static void nettest2_print_help(void)
     69{
     70        printf(
     71            "Network Networking test 2 aplication - UDP transfer\n"
     72            "Usage: echo [options] address\n"
     73            "Where options are:\n"
     74            "-f protocol_family | --family=protocol_family\n"
     75            "\tThe listenning socket protocol family. Only the PF_INET and "
     76            "PF_INET6 are supported.\n"
     77            "\n"
     78            "-h | --help\n"
     79            "\tShow this application help.\n"
     80            "\n"
     81            "-m count | --messages=count\n"
     82            "\tThe number of messages to send and receive per socket. The "
     83            "default is 10.\n"
     84            "\n"
     85            "-n sockets | --sockets=count\n"
     86            "\tThe number of sockets to use. The default is 10.\n"
     87            "\n"
     88            "-p port_number | --port=port_number\n"
     89            "\tThe port number the application should send messages to. The "
     90            "default is 7.\n"
     91            "\n"
     92            "-s packet_size | --size=packet_size\n"
     93            "\tThe packet data size the application sends. The default is 29 "
     94            "bytes.\n"
     95            "\n"
     96            "-v | --verbose\n"
     97            "\tShow all output messages.\n");
     98}
     99
     100/** Fill buffer with the NETTEST2_TEXT pattern.
     101 *
     102 * @param buffer        Data buffer.
     103 * @param size          Buffer size in bytes.
     104 */
     105static void nettest2_fill_buffer(char *buffer, size_t size)
     106{
     107        size_t length;
     108
     109        length = 0;
     110        while (size > length + sizeof(NETTEST2_TEXT) - 1) {
     111                memcpy(buffer + length, NETTEST2_TEXT,
     112                    sizeof(NETTEST2_TEXT) - 1);
     113                length += sizeof(NETTEST2_TEXT) - 1;
     114        }
     115
     116        memcpy(buffer + length, NETTEST2_TEXT, size - length);
     117        buffer[size] = '\0';
     118}
     119
     120/** Parse one command-line option.
     121 *
     122 * @param argc          Number of all command-line arguments.
     123 * @param argv          All command-line arguments.
     124 * @param index         Current argument index (in, out).
     125 */
     126static int nettest2_parse_opt(int argc, char *argv[], int *index)
     127{
     128        int value;
     129        int rc;
     130
     131        switch (argv[*index][1]) {
     132        /*
     133         * Short options with only one letter
     134         */
     135        case 'f':
     136                rc = arg_parse_name_int(argc, argv, index, &family, 0,
     137                    socket_parse_protocol_family);
     138                if (rc != EOK)
     139                        return rc;
     140                break;
     141        case 'h':
     142                nettest2_print_help();
     143                return EOK;
     144                break;
     145        case 'm':
     146                rc = arg_parse_int(argc, argv, index, &messages, 0);
     147                if (rc != EOK)
     148                        return rc;
     149                break;
     150        case 'n':
     151                rc = arg_parse_int(argc, argv, index, &sockets, 0);
     152                if (rc != EOK)
     153                        return rc;
     154                break;
     155        case 'p':
     156                rc = arg_parse_int(argc, argv, index, &value, 0);
     157                if (rc != EOK)
     158                        return rc;
     159                port = (uint16_t) value;
     160                break;
     161        case 's':
     162                rc = arg_parse_int(argc, argv, index, &value, 0);
     163                if (rc != EOK)
     164                        return rc;
     165                size = (value >= 0) ? (size_t) value : 0;
     166                break;
     167        case 't':
     168                rc = arg_parse_name_int(argc, argv, index, &value, 0,
     169                    socket_parse_socket_type);
     170                if (rc != EOK)
     171                        return rc;
     172                type = (sock_type_t) value;
     173                break;
     174        case 'v':
     175                verbose = true;
     176                break;
     177        /*
     178         * Long options with double dash ('-')
     179         */
     180        case '-':
     181                if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) {
     182                        rc = arg_parse_name_int(argc, argv, index, &family, 9,
     183                            socket_parse_protocol_family);
     184                        if (rc != EOK)
     185                                return rc;
     186                } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) {
     187                        nettest2_print_help();
     188                        return EOK;
     189                } else if (str_lcmp(argv[*index] + 2, "messages=", 6) == 0) {
     190                        rc = arg_parse_int(argc, argv, index, &messages, 8);
     191                        if (rc != EOK)
     192                                return rc;
     193                } else if (str_lcmp(argv[*index] + 2, "sockets=", 6) == 0) {
     194                        rc = arg_parse_int(argc, argv, index, &sockets, 8);
     195                        if (rc != EOK)
     196                                return rc;
     197                } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) {
     198                        rc = arg_parse_int(argc, argv, index, &value, 7);
     199                        if (rc != EOK)
     200                                return rc;
     201                        port = (uint16_t) value;
     202                } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) {
     203                        rc = arg_parse_name_int(argc, argv, index, &value, 7,
     204                            socket_parse_socket_type);
     205                        if (rc != EOK)
     206                                return rc;
     207                        type = (sock_type_t) value;
     208                } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) {
     209                        verbose = 1;
     210                } else {
     211                        nettest2_print_help();
     212                        return EINVAL;
     213                }
     214                break;
     215        default:
     216                nettest2_print_help();
     217                return EINVAL;
     218        }
     219
     220        return EOK;
     221}
     222
     223int main(int argc, char *argv[])
     224{
     225        struct sockaddr *address;
     226        struct sockaddr_in address_in;
     227        struct sockaddr_in6 address_in6;
    97228        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;
     229        uint8_t *address_start;
     230
     231        int *socket_ids;
     232        char *data;
    104233        int index;
    105234        struct timeval time_before;
    106235        struct timeval time_after;
    107236
    108         // parse the command line arguments
    109         // stop before the last argument if it does not start with the minus sign ('-')
    110         for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
    111                 // options should start with the minus sign ('-')
    112                 if(argv[index][0] == '-'){
    113                         switch(argv[index][1]){
    114                                 // short options with only one letter
    115                                 case 'f':
    116                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    117                                         break;
    118                                 case 'h':
    119                                         nettest2_print_help();
    120                                         return EOK;
    121                                         break;
    122                                 case 'm':
    123                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0));
    124                                         break;
    125                                 case 'n':
    126                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0));
    127                                         break;
    128                                 case 'p':
    129                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    130                                         port = (uint16_t) value;
    131                                         break;
    132                                 case 's':
    133                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    134                                         size = (value >= 0) ? (size_t) value : 0;
    135                                         break;
    136                                 case 't':
    137                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
    138                                         type = (sock_type_t) value;
    139                                         break;
    140                                 case 'v':
    141                                         verbose = 1;
    142                                         break;
    143                                 // long options with the double minus sign ('-')
    144                                 case '-':
    145                                         if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    146                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    147                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    148                                                 nettest2_print_help();
    149                                                 return EOK;
    150                                         }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
    151                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8));
    152                                         }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
    153                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8));
    154                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    155                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    156                                                 port = (uint16_t) value;
    157                                         }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    158                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    159                                                 type = (sock_type_t) value;
    160                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    161                                                 verbose = 1;
    162                                         }else{
    163                                                 nettest2_print_help();
    164                                                 return EINVAL;
    165                                         }
    166                                         break;
    167                                 default:
    168                                         nettest2_print_help();
    169                                         return EINVAL;
    170                         }
    171                 }else{
     237        int rc;
     238
     239        size = 28;
     240        verbose = false;
     241        type = SOCK_DGRAM;
     242        sockets = 10;
     243        messages = 10;
     244        family = PF_INET;
     245        port = 7;
     246
     247        /*
     248         * Parse the command line arguments.
     249         *
     250         * Stop before the last argument if it does not start with dash ('-')
     251         */
     252        for (index = 1; (index < argc - 1) || ((index == argc - 1) &&
     253            (argv[index][0] == '-')); ++index) {
     254
     255                /* Options should start with dash ('-') */
     256                if (argv[index][0] == '-') {
     257                        rc = nettest2_parse_opt(argc, argv, &index);
     258                        if (rc != EOK)
     259                                return rc;
     260                } else {
    172261                        nettest2_print_help();
    173262                        return EINVAL;
     
    175264        }
    176265
    177         // if not before the last argument containing the address
    178         if(index >= argc){
     266        /* If not before the last argument containing the address */
     267        if (index >= argc) {
    179268                printf("Command line error: missing address\n");
    180269                nettest2_print_help();
     
    182271        }
    183272
    184         // prepare the address buffer
    185         bzero(address_data, max_length);
    186         switch(family){
    187                 case PF_INET:
    188                         address_in->sin_family = AF_INET;
    189                         address_in->sin_port = htons(port);
    190                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    191                         addrlen = sizeof(struct sockaddr_in);
    192                         break;
    193                 case PF_INET6:
    194                         address_in6->sin6_family = AF_INET6;
    195                         address_in6->sin6_port = htons(port);
    196                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    197                         addrlen = sizeof(struct sockaddr_in6);
    198                         break;
    199                 default:
    200                         fprintf(stderr, "Address family is not supported\n");
    201                         return EAFNOSUPPORT;
    202         }
    203 
    204         // parse the last argument which should contain the address
    205         if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    206                 fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
    207                 return ERROR_CODE;
    208         }
    209 
    210         // check the buffer size
    211         if(size <= 0){
    212                 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
     273        /* Prepare the address buffer */
     274
     275        switch (family) {
     276        case PF_INET:
     277                address_in.sin_family = AF_INET;
     278                address_in.sin_port = htons(port);
     279                address = (struct sockaddr *) &address_in;
     280                addrlen = sizeof(address_in);
     281                address_start = (uint8_t *) &address_in.sin_addr.s_addr;
     282                break;
     283        case PF_INET6:
     284                address_in6.sin6_family = AF_INET6;
     285                address_in6.sin6_port = htons(port);
     286                address = (struct sockaddr *) &address_in6;
     287                addrlen = sizeof(address_in6);
     288                address_start = (uint8_t *) &address_in6.sin6_addr.s6_addr;
     289                break;
     290        default:
     291                fprintf(stderr, "Address family is not supported\n");
     292                return EAFNOSUPPORT;
     293        }
     294
     295        /* Parse the last argument which should contain the address. */
     296        rc = inet_pton(family, argv[argc - 1], address_start);
     297        if (rc != EOK) {
     298                fprintf(stderr, "Address parse error %d\n", rc);
     299                return rc;
     300        }
     301
     302        /* Check data buffer size. */
     303        if (size <= 0) {
     304                fprintf(stderr, "Data buffer size too small (%zu). Using 1024 "
     305                    "bytes instead.\n", size);
    213306                size = 1024;
    214307        }
    215308
    216         // prepare the buffer
    217         // size plus terminating null (\0)
     309        /*
     310         * Prepare the buffer. Allocate size bytes plus one for terminating
     311         * null character.
     312         */
    218313        data = (char *) malloc(size + 1);
    219         if(! data){
     314        if (!data) {
    220315                fprintf(stderr, "Failed to allocate data buffer.\n");
    221316                return ENOMEM;
    222317        }
    223         nettest2_refresh_data(data, size);
    224 
    225         // check the socket count
    226         if(sockets <= 0){
    227                 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
     318
     319        /* Fill buffer with a pattern. */
     320        nettest2_fill_buffer(data, size);
     321
     322        /* Check socket count. */
     323        if (sockets <= 0) {
     324                fprintf(stderr, "Socket count too small (%d). Using "
     325                    "2 instead.\n", sockets);
    228326                sockets = 2;
    229327        }
    230328
    231         // prepare the socket buffer
    232         // count plus the terminating null (\0)
     329        /*
     330         * Prepare the socket buffer.
     331         * Allocate count entries plus the terminating null (\0)
     332         */
    233333        socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
    234         if(! socket_ids){
     334        if (!socket_ids) {
    235335                fprintf(stderr, "Failed to allocate receive buffer.\n");
    236336                return ENOMEM;
    237337        }
    238         socket_ids[sockets] = NULL;
    239 
    240         if(verbose){
     338        socket_ids[sockets] = 0;
     339
     340        if (verbose)
    241341                printf("Starting tests\n");
    242         }
    243 
    244         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    245 
    246         if(type == SOCK_STREAM){
    247                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
    248         }
    249 
    250         if(verbose){
     342
     343        rc = sockets_create(verbose, socket_ids, sockets, family, type);
     344        if (rc != EOK)
     345                return rc;
     346
     347        if (type == SOCK_STREAM) {
     348                rc = sockets_connect(verbose, socket_ids, sockets,
     349                    address, addrlen);
     350                if (rc != EOK)
     351                        return rc;
     352        }
     353
     354        if (verbose)
    251355                printf("\n");
    252         }
    253 
    254         if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    255                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    256                 return ERROR_CODE;
    257         }
    258 
    259         ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    260 
    261         if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    262                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    263                 return ERROR_CODE;
    264         }
    265 
    266         if(verbose){
     356
     357        rc = gettimeofday(&time_before, NULL);
     358        if (rc != EOK) {
     359                fprintf(stderr, "Get time of day error %d\n", rc);
     360                return rc;
     361        }
     362
     363        rc = sockets_sendto_recvfrom(verbose, socket_ids, sockets, address,
     364            &addrlen, data, size, messages);
     365        if (rc != EOK)
     366                return rc;
     367
     368        rc = gettimeofday(&time_after, NULL);
     369        if (rc != EOK) {
     370                fprintf(stderr, "Get time of day error %d\n", rc);
     371                return rc;
     372        }
     373
     374        if (verbose)
    267375                printf("\tOK\n");
    268         }
    269 
    270         printf("sendto + recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before));
    271 
    272         if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    273                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    274                 return ERROR_CODE;
    275         }
    276 
    277         ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages));
    278         ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    279 
    280         if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    281                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    282                 return ERROR_CODE;
    283         }
    284 
    285         if(verbose){
     376
     377        printf("sendto + recvfrom tested in %ld microseconds\n",
     378            tv_sub(&time_after, &time_before));
     379
     380        rc = gettimeofday(&time_before, NULL);
     381        if (rc != EOK) {
     382                fprintf(stderr, "Get time of day error %d\n", rc);
     383                return rc;
     384        }
     385
     386        rc = sockets_sendto(verbose, socket_ids, sockets, address, addrlen,
     387            data, size, messages);
     388        if (rc != EOK)
     389                return rc;
     390
     391        rc = sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen,
     392            data, size, messages);
     393        if (rc != EOK)
     394                return rc;
     395
     396        rc = gettimeofday(&time_after, NULL);
     397        if (rc != EOK) {
     398                fprintf(stderr, "Get time of day error %d\n", rc);
     399                return rc;
     400        }
     401
     402        if (verbose)
    286403                printf("\tOK\n");
    287         }
    288 
    289         printf("sendto, recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before));
    290 
    291         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    292 
    293         if(verbose){
     404
     405        printf("sendto, recvfrom tested in %ld microseconds\n",
     406            tv_sub(&time_after, &time_before));
     407
     408        rc = sockets_close(verbose, socket_ids, sockets);
     409        if (rc != EOK)
     410                return rc;
     411
     412        if (verbose)
    294413                printf("\nExiting\n");
    295         }
    296414
    297415        return EOK;
    298416}
    299417
    300 void nettest2_print_help(void){
    301         printf(
    302                 "Network Networking test 2 aplication - UDP transfer\n" \
    303                 "Usage: echo [options] numeric_address\n" \
    304                 "Where options are:\n" \
    305                 "-f protocol_family | --family=protocol_family\n" \
    306                 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
    307                 "\n" \
    308                 "-h | --help\n" \
    309                 "\tShow this application help.\n"
    310                 "\n" \
    311                 "-m count | --messages=count\n" \
    312                 "\tThe number of messages to send and receive per socket. The default is 10.\n" \
    313                 "\n" \
    314                 "-n sockets | --sockets=count\n" \
    315                 "\tThe number of sockets to use. The default is 10.\n" \
    316                 "\n" \
    317                 "-p port_number | --port=port_number\n" \
    318                 "\tThe port number the application should send messages to. The default is 7.\n" \
    319                 "\n" \
    320                 "-s packet_size | --size=packet_size\n" \
    321                 "\tThe packet data size the application sends. The default is 29 bytes.\n" \
    322                 "\n" \
    323                 "-v | --verbose\n" \
    324                 "\tShow all output messages.\n"
    325         );
    326 }
    327 
    328 void nettest2_refresh_data(char * data, size_t size){
    329         size_t length;
    330 
    331         // fill the data
    332         length = 0;
    333         while(size > length + sizeof(NETTEST2_TEXT) - 1){
    334                 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);
    335                 length += sizeof(NETTEST2_TEXT) - 1;
    336         }
    337         memcpy(data + length, NETTEST2_TEXT, size - length);
    338         data[size] = '\0';
    339 }
    340 
    341418/** @}
    342419 */
Note: See TracChangeset for help on using the changeset viewer.