Ignore:
File:
1 edited

Legend:

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

    r7e752b2 rd9e2e0e  
    2828
    2929/** @addtogroup nettest
    30  * @{
     30 *  @{
    3131 */
    3232
    3333/** @file
    34  * Networking test 2 application - transfer.
    35  */
    36 
    37 #include "nettest.h"
    38 #include "print_error.h"
     34 *  Networking test 2 application - transfer.
     35 */
    3936
    4037#include <malloc.h>
     
    4441#include <time.h>
    4542#include <arg_parse.h>
    46 #include <bool.h>
     43#include <err.h>
    4744
    4845#include <net/in.h>
     
    5249#include <net/socket_parse.h>
    5350
    54 /** Echo module name. */
     51#include "nettest.h"
     52#include "print_error.h"
     53
     54/** Echo module name.
     55 */
    5556#define NAME    "Nettest2"
    5657
    57 /** Packet data pattern. */
     58/** Packet data pattern.
     59 */
    5860#define NETTEST2_TEXT   "Networking test 2 - transfer"
    5961
    60 static size_t size;
    61 static bool verbose;
    62 static sock_type_t type;
    63 static int sockets;
    64 static int messages;
    65 static int family;
    66 static uint16_t port;
    67 
    68 static 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  */
    105 static 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  */
    126 static int nettest2_parse_opt(int argc, char *argv[], int *index)
    127 {
     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 */
     68int main(int argc, char * argv[]);
     69
     70/** Prints the application help.
     71 */
     72void 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 */
     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;
    128103        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 {
     104        int index;
     105        struct timeval time_before;
     106        struct timeval time_after;
     107
     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{
    211172                        nettest2_print_help();
    212173                        return EINVAL;
    213174                }
    214                 break;
    215         default:
    216                 nettest2_print_help();
    217                 return EINVAL;
    218         }
    219 
    220         return EOK;
    221 }
    222 
    223 int main(int argc, char *argv[])
    224 {
    225         struct sockaddr *address;
    226         struct sockaddr_in address_in;
    227         struct sockaddr_in6 address_in6;
    228         socklen_t addrlen;
    229         uint8_t *address_start;
    230 
    231         int *socket_ids;
    232         char *data;
    233         int index;
    234         struct timeval time_before;
    235         struct timeval time_after;
    236 
    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 {
    261                         nettest2_print_help();
    262                         return EINVAL;
    263                 }
    264         }
    265 
    266         /* If not before the last argument containing the address */
    267         if (index >= argc) {
     175        }
     176
     177        // if not before the last argument containing the address
     178        if(index >= argc){
    268179                printf("Command line error: missing address\n");
    269180                nettest2_print_help();
     
    271182        }
    272183
    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);
     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);
    306213                size = 1024;
    307214        }
    308215
    309         /*
    310          * Prepare the buffer. Allocate size bytes plus one for terminating
    311          * null character.
    312          */
     216        // prepare the buffer
     217        // size plus terminating null (\0)
    313218        data = (char *) malloc(size + 1);
    314         if (!data) {
     219        if(! data){
    315220                fprintf(stderr, "Failed to allocate data buffer.\n");
    316221                return ENOMEM;
    317222        }
    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);
     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);
    326228                sockets = 2;
    327229        }
    328230
    329         /*
    330          * Prepare the socket buffer.
    331          * Allocate count entries plus the terminating null (\0)
    332          */
     231        // prepare the socket buffer
     232        // count plus the terminating null (\0)
    333233        socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
    334         if (!socket_ids) {
     234        if(! socket_ids){
    335235                fprintf(stderr, "Failed to allocate receive buffer.\n");
    336236                return ENOMEM;
    337237        }
    338         socket_ids[sockets] = 0;
    339 
    340         if (verbose)
     238        socket_ids[sockets] = NULL;
     239
     240        if(verbose){
    341241                printf("Starting tests\n");
    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)
     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){
    355251                printf("\n");
    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)
     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){
    375267                printf("\tOK\n");
    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)
     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){
    403286                printf("\tOK\n");
    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)
     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){
    413294                printf("\nExiting\n");
     295        }
    414296
    415297        return EOK;
    416298}
    417299
     300void 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
     328void 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
    418341/** @}
    419342 */
Note: See TracChangeset for help on using the changeset viewer.