Changeset 3be62bc in mainline


Ignore:
Timestamp:
2010-03-09T22:23:18Z (15 years ago)
Author:
Lukas Mejdrech <lukasmejdrech@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9f2ea28
Parents:
a8a13d0
Message:
  • net app command line argument checks, * code reorganization
Location:
uspace/srv/net/app
Files:
2 added
10 edited

Legend:

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

    ra8a13d0 r3be62bc  
    5555#define NAME    "Echo"
    5656
     57/** Prints the application help.
     58 */
     59void echo_print_help(void);
     60
    5761/** Module entry point.
    5862 *  Reads command line parameters and starts listenning.
     
    6266 */
    6367int main(int argc, char * argv[]);
    64 
    65 /** Prints the application help.
    66  */
    67 void echo_print_help(void);
    68 
    69 /** Translates the character string to the protocol family number.
    70  *  @param[in] name The protocol family name.
    71  *  @returns The corresponding protocol family number.
    72  *  @returns EPFNOSUPPORTED if the protocol family is not supported.
    73  */
    74 int echo_parse_protocol_family(const char * name);
    75 
    76 /** Translates the character string to the socket type number.
    77  *  @param[in] name The socket type name.
    78  *  @returns The corresponding socket type number.
    79  *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
    80  */
    81 int echo_parse_socket_type(const char * name);
    8268
    8369void echo_print_help(void){
     
    115101}
    116102
    117 int echo_parse_protocol_family(const char * name){
    118         if(str_lcmp(name, "PF_INET", 7) == 0){
    119                 return PF_INET;
    120         }else if(str_lcmp(name, "PF_INET6", 8) == 0){
    121                 return PF_INET6;
    122         }
    123         return EPFNOSUPPORT;
    124 }
    125 
    126 int echo_parse_socket_type(const char * name){
    127         if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
    128                 return SOCK_DGRAM;
    129         }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
    130                 return SOCK_STREAM;
    131         }
    132         return ESOCKTNOSUPPORT;
    133 }
    134 
    135103int main(int argc, char * argv[]){
    136104        ERROR_DECLARE;
     
    138106        size_t size                     = 1024;
    139107        int verbose                     = 0;
    140         char * reply                    = NULL;
    141         sock_type_t type                        = SOCK_DGRAM;
     108        char * reply            = NULL;
     109        sock_type_t type        = SOCK_DGRAM;
    142110        int count                       = -1;
    143111        int family                      = PF_INET;
    144         uint16_t port                   = 7;
     112        uint16_t port           = 7;
    145113        int backlog                     = 3;
    146114
    147         socklen_t max_length            = sizeof(struct sockaddr_in6);
     115        socklen_t max_length                            = sizeof(struct sockaddr_in6);
    148116        uint8_t address_data[max_length];
    149         struct sockaddr * address               = (struct sockaddr *) address_data;
     117        struct sockaddr * address                       = (struct sockaddr *) address_data;
    150118        struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    151119        struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     
    155123        int socket_id;
    156124        int listening_id;
    157         char *                          data;
     125        char * data;
    158126        size_t length;
    159127        int index;
     
    161129        int value;
    162130
     131        // print the program label
    163132        printf("Task %d - ", task_get_id());
    164133        printf("%s\n", NAME);
    165134
     135        // parse the command line arguments
    166136        for(index = 1; index < argc; ++ index){
    167137                if(argv[index][0] == '-'){
     
    174144                                        break;
    175145                                case 'f':
    176                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, echo_parse_protocol_family));
     146                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
    177147                                        break;
    178148                                case 'h':
     
    192162                                        break;
    193163                                case 't':
    194                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, echo_parse_socket_type));
     164                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
    195165                                        type = (sock_type_t) value;
    196166                                        break;
     
    198168                                        verbose = 1;
    199169                                        break;
     170                                // long options with the double minus sign ('-')
    200171                                case '-':
    201172                                        if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
     
    204175                                                ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8));
    205176                                        }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    206                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, echo_parse_protocol_family));
     177                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
    207178                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    208179                                                echo_print_help();
     
    217188                                                size = (value >= 0) ? (size_t) value : 0;
    218189                                        }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    219                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, echo_parse_socket_type));
     190                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
    220191                                                type = (sock_type_t) value;
    221192                                        }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
     
    239210        }
    240211
     212        // check the buffer size
    241213        if(size <= 0){
    242214                fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
    243215                size = 1024;
    244216        }
    245         // size plus terminating null (\0)
     217        // size plus the terminating null (\0)
    246218        data = (char *) malloc(size + 1);
    247219        if(! data){
     
    250222        }
    251223
     224        // set the reply size if set
    252225        reply_length = reply ? str_length(reply) : 0;
    253226
    254         listening_id = socket(family, type, 0);
    255         if(listening_id < 0){
    256                 socket_print_error(stderr, listening_id, "Socket create: ", "\n");
    257                 return listening_id;
    258         }
    259 
     227        // prepare the address buffer
    260228        bzero(address_data, max_length);
    261229        switch(family){
     
    275243        }
    276244
     245        // get a listening socket
    277246        listening_id = socket(family, type, 0);
    278247        if(listening_id < 0){
     
    281250        }
    282251
     252        // if the stream socket is used
    283253        if(type == SOCK_STREAM){
     254                // check the backlog
    284255                if(backlog <= 0){
    285256                        fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
    286257                        backlog = 3;
    287258                }
     259                // set the backlog
    288260                if(ERROR_OCCURRED(listen(listening_id, backlog))){
    289261                        socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
     
    292264        }
    293265
     266        // bind the listenning socket
    294267        if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
    295268                socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
     
    303276        socket_id = listening_id;
    304277
     278        // do count times
     279        // or indefinitely if set to a negative value
    305280        while(count){
     281
    306282                addrlen = max_length;
    307283                if(type == SOCK_STREAM){
     284                        // acceept a socket if the stream socket is used
    308285                        socket_id = accept(listening_id, address, &addrlen);
    309286                        if(socket_id <= 0){
     
    315292                        }
    316293                }
     294
     295                // if the datagram socket is used or the stream socked was accepted
    317296                if(socket_id > 0){
     297
     298                        // receive an echo request
    318299                        value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    319300                        if(value < 0){
     
    322303                                length = (size_t) value;
    323304                                if(verbose){
     305                                        // print the header
     306
     307                                        // get the source port and prepare the address buffer
    324308                                        address_start = NULL;
    325309                                        switch(address->sa_family){
     
    335319                                                        fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
    336320                                        }
     321                                        // parse the source address
    337322                                        if(address_start){
    338323                                                if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
     
    344329                                        }
    345330                                }
     331
     332                                // answer the request either with the static reply or the original data
    346333                                if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
    347334                                        socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    348335                                }
    349                         }
     336
     337                        }
     338
     339                        // close the accepted stream socket
    350340                        if(type == SOCK_STREAM){
    351341                                if(ERROR_OCCURRED(closesocket(socket_id))){
     
    353343                                }
    354344                        }
    355                 }
     345
     346                }
     347
     348                // decrease the count if positive
    356349                if(count > 0){
    357350                        -- count;
     
    366359        }
    367360
     361        // close the listenning socket
    368362        if(ERROR_OCCURRED(closesocket(listening_id))){
    369363                socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
  • uspace/srv/net/app/nettest1/Makefile

    ra8a13d0 r3be62bc  
    4040SOURCES = \
    4141        $(NAME).c \
     42        $(NET_BASE)app/nettest.c \
    4243        $(NET_BASE)app/parse.c \
    4344        $(NET_BASE)app/print_error.c
  • uspace/srv/net/app/nettest1/nettest1.c

    ra8a13d0 r3be62bc  
    4848#include "../../err.h"
    4949
     50#include "../nettest.h"
    5051#include "../parse.h"
    5152#include "../print_error.h"
     
    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 nettest1_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){
    176         printf(
    177                 "Network Networking test 1 aplication - sockets\n" \
    178                 "Usage: echo [options] numeric_address\n" \
    179                 "Where options are:\n" \
    180                 "-f protocol_family | --family=protocol_family\n" \
    181                 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
    182                 "\n" \
    183                 "-h | --help\n" \
    184                 "\tShow this application help.\n"
    185                 "\n" \
    186                 "-m count | --messages=count\n" \
    187                 "\tThe number of messages to send and receive per socket. The default is 10.\n" \
    188                 "\n" \
    189                 "-n sockets | --sockets=count\n" \
    190                 "\tThe number of sockets to use. The default is 10.\n" \
    191                 "\n" \
    192                 "-p port_number | --port=port_number\n" \
    193                 "\tThe port number the application should send messages to. The default is 7.\n" \
    194                 "\n" \
    195                 "-s packet_size | --size=packet_size\n" \
    196                 "\tThe packet data size the application sends. The default is 28 bytes.\n" \
    197                 "\n" \
    198                 "-v | --verbose\n" \
    199                 "\tShow all output messages.\n"
    200         );
    201 }
    202 
    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;
    223 
    224         // fill the data
    225         length = 0;
    226         while(size > length + sizeof(NETTEST1_TEXT) - 1){
    227                 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1);
    228                 length += sizeof(NETTEST1_TEXT) - 1;
    229         }
    230         memcpy(data + length, NETTEST1_TEXT, size - length);
    231         data[size] = '\0';
    232 }
    233 
    234 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){
    235         int index;
    236 
    237         if(verbose){
    238                 printf("Create\t");
    239         }
    240         fflush(stdout);
    241         for(index = 0; index < sockets; ++ index){
    242                 socket_ids[index] = socket(family, type, 0);
    243                 if(socket_ids[index] < 0){
    244                         printf("Socket %d (%d) error:\n", index, socket_ids[index]);
    245                         socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n");
    246                         return socket_ids[index];
    247                 }
    248                 if(verbose){
    249                         print_mark(index);
    250                 }
    251         }
    252         return EOK;
    253 }
    254 
    255 int sockets_close(int verbose, int * socket_ids, int sockets){
    256         ERROR_DECLARE;
    257 
    258         int index;
    259 
    260         if(verbose){
    261                 printf("\tClose\t");
    262         }
    263         fflush(stdout);
    264         for(index = 0; index < sockets; ++ index){
    265                 if(ERROR_OCCURRED(closesocket(socket_ids[index]))){
    266                         printf("Socket %d (%d) error:\n", index, socket_ids[index]);
    267                         socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n");
    268                         return ERROR_CODE;
    269                 }
    270                 if(verbose){
    271                         print_mark(index);
    272                 }
    273         }
    274         return EOK;
    275 }
    276 
    277 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){
    278         ERROR_DECLARE;
    279 
    280         int index;
    281 
    282         if(verbose){
    283                 printf("\tConnect\t");
    284         }
    285         fflush(stdout);
    286         for(index = 0; index < sockets; ++ index){
    287                 if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){
    288                         socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n");
    289                         return ERROR_CODE;
    290                 }
    291                 if(verbose){
    292                         print_mark(index);
    293                 }
    294         }
    295         return EOK;
    296 }
    297 
    298 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){
    299         ERROR_DECLARE;
    300 
    301         int index;
    302         int message;
    303 
    304         if(verbose){
    305                 printf("\tSendto\t");
    306         }
    307         fflush(stdout);
    308         for(index = 0; index < sockets; ++ index){
    309                 for(message = 0; message < messages; ++ message){
    310                         if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){
    311                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    312                                 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    313                                 return ERROR_CODE;
    314                         }
    315                 }
    316                 if(verbose){
    317                         print_mark(index);
    318                 }
    319         }
    320         return EOK;
    321 }
    322 
    323 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
    324         int value;
    325         int index;
    326         int message;
    327 
    328         if(verbose){
    329                 printf("\tRecvfrom\t");
    330         }
    331         fflush(stdout);
    332         for(index = 0; index < sockets; ++ index){
    333                 for(message = 0; message < messages; ++ message){
    334                         value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
    335                         if(value < 0){
    336                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    337                                 socket_print_error(stderr, value, "Socket receive: ", "\n");
    338                                 return value;
    339                         }
    340                 }
    341                 if(verbose){
    342                         print_mark(index);
    343                 }
    344         }
    345         return EOK;
    346 }
    347 
    348 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
    349         ERROR_DECLARE;
    350 
    351         int value;
    352         int index;
    353         int message;
    354 
    355         if(verbose){
    356                 printf("\tSendto and recvfrom\t");
    357         }
    358         fflush(stdout);
    359         for(index = 0; index < sockets; ++ index){
    360                 for(message = 0; message < messages; ++ message){
    361                         if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){
    362                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    363                                 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    364                                 return ERROR_CODE;
    365                         }
    366                         value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
    367                         if(value < 0){
    368                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    369                                 socket_print_error(stderr, value, "Socket receive: ", "\n");
    370                                 return value;
    371                         }
    372                 }
    373                 if(verbose){
    374                         print_mark(index);
    375                 }
    376         }
    377         return EOK;
    378 }
    379 
    380 void print_mark(int index){
    381         if((index + 1) % 10){
    382                 printf("*");
    383         }else{
    384                 printf("|");
    385         }
    386         fflush(stdout);
    387 }
     79void nettest1_refresh_data(char * data, size_t size);
    38880
    38981int main(int argc, char * argv[]){
     
    39284        size_t size                     = 27;
    39385        int verbose                     = 0;
    394         sock_type_t type                        = SOCK_DGRAM;
     86        sock_type_t type        = SOCK_DGRAM;
    39587        int sockets                     = 10;
    39688        int messages            = 10;
    39789        int family                      = PF_INET;
    398         uint16_t port                   = 7;
    399 
    400         socklen_t max_length            = sizeof(struct sockaddr_in6);
     90        uint16_t port           = 7;
     91
     92        socklen_t max_length                            = sizeof(struct sockaddr_in6);
    40193        uint8_t address_data[max_length];
    402         struct sockaddr * address               = (struct sockaddr *) address_data;
     94        struct sockaddr * address                       = (struct sockaddr *) address_data;
    40395        struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    40496        struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
    40597        socklen_t addrlen;
    406 //      char                            address_string[INET6_ADDRSTRLEN];
     98//      char address_string[INET6_ADDRSTRLEN];
    40799        uint8_t * address_start;
    408100
    409101        int * socket_ids;
    410         char *                          data;
     102        char * data;
    411103        int value;
    412104        int index;
     
    414106        struct timeval time_after;
    415107
     108        // print the program label
    416109        printf("Task %d - ", task_get_id());
    417110        printf("%s\n", NAME);
    418111
    419         if(argc <= 1){
    420                 print_help();
    421                 return EINVAL;
    422         }
    423 
    424         for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){
     112        // parse the command line arguments
     113        // stop before the last argument if it does not start with the minus sign ('-')
     114        for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
     115                // options should start with the minus sign ('-')
    425116                if(argv[index][0] == '-'){
    426117                        switch(argv[index][1]){
     118                                // short options with only one letter
    427119                                case 'f':
    428120                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
    429121                                        break;
    430122                                case 'h':
    431                                         print_help();
     123                                        nettest1_print_help();
    432124                                        return EOK;
    433125                                        break;
     
    453145                                        verbose = 1;
    454146                                        break;
     147                                // long options with the double minus sign ('-')
    455148                                case '-':
    456149                                        if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    457150                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
    458151                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    459                                                 print_help();
     152                                                nettest1_print_help();
    460153                                                return EOK;
    461154                                        }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
     
    473166                                        }else{
    474167                                                print_unrecognized(index, argv[index] + 2);
    475                                                 print_help();
     168                                                nettest1_print_help();
    476169                                                return EINVAL;
    477170                                        }
     
    479172                                default:
    480173                                        print_unrecognized(index, argv[index] + 1);
    481                                         print_help();
     174                                        nettest1_print_help();
    482175                                        return EINVAL;
    483176                        }
    484177                }else{
    485178                        print_unrecognized(index, argv[index]);
    486                         print_help();
     179                        nettest1_print_help();
    487180                        return EINVAL;
    488181                }
    489182        }
    490183
     184        // if not before the last argument containing the address
     185        if(index >= argc){
     186                printf("Command line error: missing address\n");
     187                nettest1_print_help();
     188                return EINVAL;
     189        }
     190
     191        // prepare the address buffer
    491192        bzero(address_data, max_length);
    492193        switch(family){
     
    508209        }
    509210
     211        // parse the last argument which should contain the address
    510212        if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    511213                fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
     
    513215        }
    514216
     217        // check the buffer size
    515218        if(size <= 0){
    516219                fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
    517220                size = 1024;
    518221        }
    519         // size plus terminating null (\0)
     222
     223        // prepare the buffer
     224        // size plus the terminating null (\0)
    520225        data = (char *) malloc(size + 1);
    521226        if(! data){
     
    523228                return ENOMEM;
    524229        }
    525         refresh_data(data, size);
    526 
     230        nettest1_refresh_data(data, size);
     231
     232        // check the socket count
    527233        if(sockets <= 0){
    528234                fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
    529235                sockets = 2;
    530236        }
    531         // count plus terminating null (\0)
     237
     238        // prepare the socket buffer
     239        // count plus the terminating null (\0)
    532240        socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
    533241        if(! socket_ids){
     
    673381}
    674382
     383void nettest1_print_help(void){
     384        printf(
     385                "Network Networking test 1 aplication - sockets\n" \
     386                "Usage: echo [options] numeric_address\n" \
     387                "Where options are:\n" \
     388                "-f protocol_family | --family=protocol_family\n" \
     389                "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
     390                "\n" \
     391                "-h | --help\n" \
     392                "\tShow this application help.\n"
     393                "\n" \
     394                "-m count | --messages=count\n" \
     395                "\tThe number of messages to send and receive per socket. The default is 10.\n" \
     396                "\n" \
     397                "-n sockets | --sockets=count\n" \
     398                "\tThe number of sockets to use. The default is 10.\n" \
     399                "\n" \
     400                "-p port_number | --port=port_number\n" \
     401                "\tThe port number the application should send messages to. The default is 7.\n" \
     402                "\n" \
     403                "-s packet_size | --size=packet_size\n" \
     404                "\tThe packet data size the application sends. The default is 28 bytes.\n" \
     405                "\n" \
     406                "-v | --verbose\n" \
     407                "\tShow all output messages.\n"
     408        );
     409}
     410
     411void nettest1_refresh_data(char * data, size_t size){
     412        size_t length;
     413
     414        // fill the data
     415        length = 0;
     416        while(size > length + sizeof(NETTEST1_TEXT) - 1){
     417                memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1);
     418                length += sizeof(NETTEST1_TEXT) - 1;
     419        }
     420        memcpy(data + length, NETTEST1_TEXT, size - length);
     421        data[size] = '\0';
     422}
     423
    675424/** @}
    676425 */
  • uspace/srv/net/app/nettest2/Makefile

    ra8a13d0 r3be62bc  
    4040SOURCES = \
    4141        $(NAME).c \
     42        $(NET_BASE)app/nettest.c \
    4243        $(NET_BASE)app/parse.c \
    4344        $(NET_BASE)app/print_error.c
  • uspace/srv/net/app/nettest2/nettest2.c

    ra8a13d0 r3be62bc  
    4848#include "../../err.h"
    4949
     50#include "../nettest.h"
    5051#include "../parse.h"
    5152#include "../print_error.h"
     
    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){
    176         printf(
    177                 "Network Networking test 2 aplication - UDP transfer\n" \
    178                 "Usage: echo [options] numeric_address\n" \
    179                 "Where options are:\n" \
    180                 "-f protocol_family | --family=protocol_family\n" \
    181                 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
    182                 "\n" \
    183                 "-h | --help\n" \
    184                 "\tShow this application help.\n"
    185                 "\n" \
    186                 "-m count | --messages=count\n" \
    187                 "\tThe number of messages to send and receive per socket. The default is 10.\n" \
    188                 "\n" \
    189                 "-n sockets | --sockets=count\n" \
    190                 "\tThe number of sockets to use. The default is 10.\n" \
    191                 "\n" \
    192                 "-p port_number | --port=port_number\n" \
    193                 "\tThe port number the application should send messages to. The default is 7.\n" \
    194                 "\n" \
    195                 "-s packet_size | --size=packet_size\n" \
    196                 "\tThe packet data size the application sends. The default is 29 bytes.\n" \
    197                 "\n" \
    198                 "-v | --verbose\n" \
    199                 "\tShow all output messages.\n"
    200         );
    201 }
    202 
    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;
    223 
    224         // fill the data
    225         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';
    232 }
    233 
    234 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){
    235         int index;
    236 
    237         if(verbose){
    238                 printf("Create\t");
    239         }
    240         fflush(stdout);
    241         for(index = 0; index < sockets; ++ index){
    242                 socket_ids[index] = socket(family, type, 0);
    243                 if(socket_ids[index] < 0){
    244                         printf("Socket %d (%d) error:\n", index, socket_ids[index]);
    245                         socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n");
    246                         return socket_ids[index];
    247                 }
    248                 if(verbose){
    249                         print_mark(index);
    250                 }
    251         }
    252         return EOK;
    253 }
    254 
    255 int sockets_close(int verbose, int * socket_ids, int sockets){
    256         ERROR_DECLARE;
    257 
    258         int index;
    259 
    260         if(verbose){
    261                 printf("\tClose\t");
    262         }
    263         fflush(stdout);
    264         for(index = 0; index < sockets; ++ index){
    265                 if(ERROR_OCCURRED(closesocket(socket_ids[index]))){
    266                         printf("Socket %d (%d) error:\n", index, socket_ids[index]);
    267                         socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n");
    268                         return ERROR_CODE;
    269                 }
    270                 if(verbose){
    271                         print_mark(index);
    272                 }
    273         }
    274         return EOK;
    275 }
    276 
    277 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){
    278         ERROR_DECLARE;
    279 
    280         int index;
    281 
    282         if(verbose){
    283                 printf("\tConnect\t");
    284         }
    285         fflush(stdout);
    286         for(index = 0; index < sockets; ++ index){
    287                 if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){
    288                         socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n");
    289                         return ERROR_CODE;
    290                 }
    291                 if(verbose){
    292                         print_mark(index);
    293                 }
    294         }
    295         return EOK;
    296 }
    297 
    298 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){
    299         ERROR_DECLARE;
    300 
    301         int index;
    302         int message;
    303 
    304         if(verbose){
    305                 printf("\tSendto\t");
    306         }
    307         fflush(stdout);
    308         for(index = 0; index < sockets; ++ index){
    309                 for(message = 0; message < messages; ++ message){
    310                         if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){
    311                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    312                                 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    313                                 return ERROR_CODE;
    314                         }
    315                 }
    316                 if(verbose){
    317                         print_mark(index);
    318                 }
    319         }
    320         return EOK;
    321 }
    322 
    323 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
    324         int value;
    325         int index;
    326         int message;
    327 
    328         if(verbose){
    329                 printf("\tRecvfrom\t");
    330         }
    331         fflush(stdout);
    332         for(index = 0; index < sockets; ++ index){
    333                 for(message = 0; message < messages; ++ message){
    334                         value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
    335                         if(value < 0){
    336                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    337                                 socket_print_error(stderr, value, "Socket receive: ", "\n");
    338                                 return value;
    339                         }
    340                 }
    341                 if(verbose){
    342                         print_mark(index);
    343                 }
    344         }
    345         return EOK;
    346 }
    347 
    348 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
    349         ERROR_DECLARE;
    350 
    351         int value;
    352         int index;
    353         int message;
    354 
    355         if(verbose){
    356                 printf("\tSendto and recvfrom\t");
    357         }
    358         fflush(stdout);
    359         for(index = 0; index < sockets; ++ index){
    360                 for(message = 0; message < messages; ++ message){
    361                         if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){
    362                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    363                                 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    364                                 return ERROR_CODE;
    365                         }
    366                         value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
    367                         if(value < 0){
    368                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    369                                 socket_print_error(stderr, value, "Socket receive: ", "\n");
    370                                 return value;
    371                         }
    372                 }
    373                 if(verbose){
    374                         print_mark(index);
    375                 }
    376         }
    377         return EOK;
    378 }
    379 
    380 void print_mark(int index){
    381         if((index + 1) % 10){
    382                 printf("*");
    383         }else{
    384                 printf("|");
    385         }
    386         fflush(stdout);
    387 }
     79void nettest2_refresh_data(char * data, size_t size);
    38880
    38981int main(int argc, char * argv[]){
     
    39284        size_t size                     = 28;
    39385        int verbose                     = 0;
    394         sock_type_t type                        = SOCK_DGRAM;
     86        sock_type_t type        = SOCK_DGRAM;
    39587        int sockets                     = 10;
    39688        int messages            = 10;
    39789        int family                      = PF_INET;
    398         uint16_t port                   = 7;
    399 
    400         socklen_t max_length            = sizeof(struct sockaddr_in6);
     90        uint16_t port           = 7;
     91
     92        socklen_t max_length                            = sizeof(struct sockaddr_in6);
    40193        uint8_t address_data[max_length];
    402         struct sockaddr * address               = (struct sockaddr *) address_data;
     94        struct sockaddr * address                       = (struct sockaddr *) address_data;
    40395        struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    40496        struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
    40597        socklen_t addrlen;
    406 //      char                            address_string[INET6_ADDRSTRLEN];
     98//      char address_string[INET6_ADDRSTRLEN];
    40799        uint8_t * address_start;
    408100
    409101        int * socket_ids;
    410         char *                          data;
     102        char * data;
    411103        int value;
    412104        int index;
     
    417109        printf("%s\n", NAME);
    418110
    419         if(argc <= 1){
    420                 print_help();
    421                 return EINVAL;
    422         }
    423 
    424         for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){
     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 ('-')
    425115                if(argv[index][0] == '-'){
    426116                        switch(argv[index][1]){
     117                                // short options with only one letter
    427118                                case 'f':
    428119                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
    429120                                        break;
    430121                                case 'h':
    431                                         print_help();
     122                                        nettest2_print_help();
    432123                                        return EOK;
    433124                                        break;
     
    453144                                        verbose = 1;
    454145                                        break;
     146                                // long options with the double minus sign ('-')
    455147                                case '-':
    456148                                        if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    457149                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
    458150                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    459                                                 print_help();
     151                                                nettest2_print_help();
    460152                                                return EOK;
    461153                                        }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
     
    473165                                        }else{
    474166                                                print_unrecognized(index, argv[index] + 2);
    475                                                 print_help();
     167                                                nettest2_print_help();
    476168                                                return EINVAL;
    477169                                        }
     
    479171                                default:
    480172                                        print_unrecognized(index, argv[index] + 1);
    481                                         print_help();
     173                                        nettest2_print_help();
    482174                                        return EINVAL;
    483175                        }
    484176                }else{
    485177                        print_unrecognized(index, argv[index]);
    486                         print_help();
     178                        nettest2_print_help();
    487179                        return EINVAL;
    488180                }
    489181        }
    490182
     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
    491191        bzero(address_data, max_length);
    492192        switch(family){
     
    508208        }
    509209
     210        // parse the last argument which should contain the address
    510211        if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    511212                fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
     
    513214        }
    514215
     216        // check the buffer size
    515217        if(size <= 0){
    516218                fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
    517219                size = 1024;
    518220        }
     221
     222        // prepare the buffer
    519223        // size plus terminating null (\0)
    520224        data = (char *) malloc(size + 1);
     
    523227                return ENOMEM;
    524228        }
    525         refresh_data(data, size);
    526 
     229        nettest2_refresh_data(data, size);
     230
     231        // check the socket count
    527232        if(sockets <= 0){
    528233                fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
    529234                sockets = 2;
    530235        }
    531         // count plus terminating null (\0)
     236
     237        // prepare the socket buffer
     238        // count plus the terminating null (\0)
    532239        socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
    533240        if(! socket_ids){
     
    597304}
    598305
     306void nettest2_print_help(void){
     307        printf(
     308                "Network Networking test 2 aplication - UDP transfer\n" \
     309                "Usage: echo [options] numeric_address\n" \
     310                "Where options are:\n" \
     311                "-f protocol_family | --family=protocol_family\n" \
     312                "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
     313                "\n" \
     314                "-h | --help\n" \
     315                "\tShow this application help.\n"
     316                "\n" \
     317                "-m count | --messages=count\n" \
     318                "\tThe number of messages to send and receive per socket. The default is 10.\n" \
     319                "\n" \
     320                "-n sockets | --sockets=count\n" \
     321                "\tThe number of sockets to use. The default is 10.\n" \
     322                "\n" \
     323                "-p port_number | --port=port_number\n" \
     324                "\tThe port number the application should send messages to. The default is 7.\n" \
     325                "\n" \
     326                "-s packet_size | --size=packet_size\n" \
     327                "\tThe packet data size the application sends. The default is 29 bytes.\n" \
     328                "\n" \
     329                "-v | --verbose\n" \
     330                "\tShow all output messages.\n"
     331        );
     332}
     333
     334void nettest2_refresh_data(char * data, size_t size){
     335        size_t length;
     336
     337        // fill the data
     338        length = 0;
     339        while(size > length + sizeof(NETTEST2_TEXT) - 1){
     340                memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);
     341                length += sizeof(NETTEST2_TEXT) - 1;
     342        }
     343        memcpy(data + length, NETTEST2_TEXT, size - length);
     344        data[size] = '\0';
     345}
     346
    599347/** @}
    600348 */
  • uspace/srv/net/app/parse.c

    ra8a13d0 r3be62bc  
    3838#include <string.h>
    3939
     40#include "../include/socket.h"
     41
    4042#include "../err.h"
    4143
    4244#include "parse.h"
     45
     46int parse_address_family(const char * name){
     47        if(str_lcmp(name, "AF_INET", 7) == 0){
     48                return AF_INET;
     49        }else if(str_lcmp(name, "AF_INET6", 8) == 0){
     50                return AF_INET6;
     51        }
     52        return EAFNOSUPPORT;
     53}
    4354
    4455int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset){
     
    6172}
    6273
    63 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){
    64         if(offset){
    65                 *value = argv[*index] + offset;
    66         }else if((*index) + 1 < argc){
    67                 ++ (*index);
    68                 *value = argv[*index];
    69         }else{
    70                 fprintf(stderr, "Command line error: missing %s\n", name);
    71                 return EINVAL;
    72         }
    73         return EOK;
    74 }
    75 
    7674int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value)){
    7775        ERROR_DECLARE;
     
    8886}
    8987
     88int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){
     89        if(offset){
     90                *value = argv[*index] + offset;
     91        }else if((*index) + 1 < argc){
     92                ++ (*index);
     93                *value = argv[*index];
     94        }else{
     95                fprintf(stderr, "Command line error: missing %s\n", name);
     96                return EINVAL;
     97        }
     98        return EOK;
     99}
     100
     101int parse_protocol_family(const char * name){
     102        if(str_lcmp(name, "PF_INET", 7) == 0){
     103                return PF_INET;
     104        }else if(str_lcmp(name, "PF_INET6", 8) == 0){
     105                return PF_INET6;
     106        }
     107        return EPFNOSUPPORT;
     108}
     109
     110int parse_socket_type(const char * name){
     111        if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
     112                return SOCK_DGRAM;
     113        }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
     114                return SOCK_STREAM;
     115        }
     116        return ESOCKTNOSUPPORT;
     117}
     118
    90119void print_unrecognized(int index, const char * parameter){
    91         fprintf(stderr, "Command line error - unrecognized parameter (%d: %s)\n", index, parameter);
     120        fprintf(stderr, "Command line error: unrecognized argument (%d: %s)\n", index, parameter);
    92121}
    93122
  • uspace/srv/net/app/parse.h

    ra8a13d0 r3be62bc  
    3838#define __NET_APP_PARSE__
    3939
    40 /** Prints the parameter unrecognized message and the application help.
    41  *  @param[in] index The index of the parameter.
    42  *  @param[in] parameter The parameter name.
     40#include "../include/socket.h"
     41
     42/** Translates the character string to the address family number.
     43 *  @param[in] name The address family name.
     44 *  @returns The corresponding address family number.
     45 *  @returns EAFNOSUPPORTED if the address family is not supported.
    4346 */
    44 void print_unrecognized(int index, const char * parameter);
     47int parse_address_family(const char * name);
    4548
    4649/** Parses the next parameter as an integral number.
     
    5861 */
    5962int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset);
    60 
    61 /** Parses the next parameter as a character string.
    62  *  The actual parameter is pointed by the index.
    63  *  Uses the offseted actual parameter value if the offset is set or the next one if not.
    64  *  Increments the actual index by the number of processed parameters.
    65  *  @param[in] argc The total number of the parameters.
    66  *  @param[in] argv The parameters.
    67  *  @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.
    68  *  @param[out] value The parsed parameter value.
    69  *  @param[in] name The parameter name to be printed on errors.
    70  *  @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.
    71  *  @returns EOK on success.
    72  *  @returns EINVAL if the parameter is missing.
    73  */
    74 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset);
    7563
    7664/** Parses the next named parameter as an integral number.
     
    9280int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value));
    9381
     82/** Parses the next parameter as a character string.
     83 *  The actual parameter is pointed by the index.
     84 *  Uses the offseted actual parameter value if the offset is set or the next one if not.
     85 *  Increments the actual index by the number of processed parameters.
     86 *  @param[in] argc The total number of the parameters.
     87 *  @param[in] argv The parameters.
     88 *  @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.
     89 *  @param[out] value The parsed parameter value.
     90 *  @param[in] name The parameter name to be printed on errors.
     91 *  @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.
     92 *  @returns EOK on success.
     93 *  @returns EINVAL if the parameter is missing.
     94 */
     95int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset);
     96
     97/** Translates the character string to the protocol family number.
     98 *  @param[in] name The protocol family name.
     99 *  @returns The corresponding protocol family number.
     100 *  @returns EPFNOSUPPORTED if the protocol family is not supported.
     101 */
     102int parse_protocol_family(const char * name);
     103
     104/** Translates the character string to the socket type number.
     105 *  @param[in] name The socket type name.
     106 *  @returns The corresponding socket type number.
     107 *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
     108 */
     109int parse_socket_type(const char * name);
     110
     111/** Prints the parameter unrecognized message and the application help.
     112 *  @param[in] index The index of the parameter.
     113 *  @param[in] parameter The parameter name.
     114 */
     115void print_unrecognized(int index, const char * parameter);
     116
    94117#endif
    95118
  • uspace/srv/net/app/ping/ping.c

    ra8a13d0 r3be62bc  
    3939#include <task.h>
    4040#include <time.h>
     41#include <ipc/ipc.h>
    4142#include <ipc/services.h>
    4243
     
    6768/** Prints the application help.
    6869 */
    69 void print_help(void);
    70 
    71 /** Translates the character string to the address family number.
    72  *  @param[in] name The address family name.
    73  *  @returns The corresponding address family number.
    74  *  @returns EAFNOSUPPORTED if the address family is not supported.
    75  */
    76 int parse_address_family(const char * name);
    77 
    78 void print_help(void){
    79         printf(
    80                 "Network Ping aplication\n" \
    81                 "Usage: ping [options] numeric_address\n" \
    82                 "Where options are:\n" \
    83                 "\n" \
    84                 "-c request_count | --count=request_count\n" \
    85                 "\tThe number of packets the application sends. The default is three (3).\n" \
    86                 "\n" \
    87                 "--dont_fragment\n" \
    88                 "\tDisable packet fragmentation.\n"
    89                 "\n" \
    90                 "-f address_family | --family=address_family\n" \
    91                 "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n"
    92                 "\n" \
    93                 "-h | --help\n" \
    94                 "\tShow this application help.\n"
    95                 "\n" \
    96                 "-s packet_size | --size=packet_size\n" \
    97                 "\tThe packet data size the application sends. The default is 38 bytes.\n" \
    98                 "\n" \
    99                 "-t timeout | --timeout=timeout\n" \
    100                 "\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \
    101                 "\n" \
    102                 "--tos=tos\n" \
    103                 "\tThe type of service to be used.\n" \
    104                 "\n" \
    105                 "--ttl=ttl\n" \
    106                 "\tThe time to live to be used.\n" \
    107                 "\n" \
    108                 "-v | --verbose\n" \
    109                 "\tShow all output messages.\n"
    110         );
    111 }
    112 
    113 int parse_address_family(const char * name){
    114         if(str_lcmp(name, "AF_INET", 7) == 0){
    115                 return AF_INET;
    116         }else if(str_lcmp(name, "AF_INET6", 8) == 0){
    117                 return AF_INET6;
    118         }
    119         return EAFNOSUPPORT;
    120 }
     70void ping_print_help(void);
    12171
    12272int main(int argc, char * argv[]){
     
    12676        int verbose                     = 0;
    12777        int dont_fragment       = 0;
    128         ip_ttl_t ttl                            = 0;
    129         ip_tos_t tos                            = 0;
     78        ip_ttl_t ttl            = 0;
     79        ip_tos_t tos            = 0;
    13080        int count                       = 3;
    131         suseconds_t timeout                     = 3000;
     81        suseconds_t timeout     = 3000;
    13282        int family                      = AF_INET;
    13383
    134         socklen_t max_length            = sizeof(struct sockaddr_in6);
     84        socklen_t max_length                            = sizeof(struct sockaddr_in6);
    13585        uint8_t address_data[max_length];
    136         struct sockaddr * address               = (struct sockaddr *) address_data;
     86        struct sockaddr * address                       = (struct sockaddr *) address_data;
    13787        struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    13888        struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     
    14797        int index;
    14898
     99        // print the program label
    149100        printf("Task %d - ", task_get_id());
    150101        printf("%s\n", NAME);
    151102
    152         if(argc <= 1){
    153                 print_help();
    154                 return EINVAL;
    155         }
    156 
    157         for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){
     103        // parse the command line arguments
     104        // stop before the last argument if it does not start with the minus sign ('-')
     105        for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
     106                // options should start with the minus sign ('-')
    158107                if(argv[index][0] == '-'){
    159108                        switch(argv[index][1]){
     109                                // short options with only one letter
    160110                                case 'c':
    161111                                        ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "count", 0));
     
    165115                                        break;
    166116                                case 'h':
    167                                         print_help();
     117                                        ping_print_help();
    168118                                        return EOK;
    169119                                        break;
     
    179129                                        verbose = 1;
    180130                                        break;
     131                                // long options with the double minus sign ('-')
    181132                                case '-':
    182133                                        if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
     
    187138                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 9, parse_address_family));
    188139                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    189                                                 print_help();
     140                                                ping_print_help();
    190141                                                return EOK;
    191142                                        }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
     
    205156                                        }else{
    206157                                                print_unrecognized(index, argv[index] + 2);
    207                                                 print_help();
     158                                                ping_print_help();
    208159                                                return EINVAL;
    209160                                        }
     
    211162                                default:
    212163                                        print_unrecognized(index, argv[index] + 1);
    213                                         print_help();
     164                                        ping_print_help();
    214165                                        return EINVAL;
    215166                        }
    216167                }else{
    217168                        print_unrecognized(index, argv[index]);
    218                         print_help();
     169                        ping_print_help();
    219170                        return EINVAL;
    220171                }
    221172        }
    222173
     174        // if not before the last argument containing the address
     175        if(index >= argc){
     176                printf("Command line error: missing address\n");
     177                ping_print_help();
     178                return EINVAL;
     179        }
     180
     181        // prepare the address buffer
    223182        bzero(address_data, max_length);
    224183        switch(family){
     
    238197        }
    239198
     199        // parse the last argument which should contain the address
    240200        if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    241201                fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
     
    243203        }
    244204
     205        // connect to the ICMP module
    245206        icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
    246207        if(icmp_phone < 0){
     
    249210        }
    250211
     212        // print the ping header
    251213        printf("PING %d bytes of data\n", size);
    252214        if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
     
    256218        }
    257219
     220        // do count times
    258221        while(count > 0){
     222
     223                // get the starting time
    259224                if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    260225                        fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
     226                        // release the ICMP phone
     227                        ipc_hangup(icmp_phone);
    261228                        return ERROR_CODE;
    262229                }
     230
     231                // request the ping
    263232                result = icmp_echo_msg(icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen);
     233
     234                // get the ending time
    264235                if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    265236                        fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
     237                        // release the ICMP phone
     238                        ipc_hangup(icmp_phone);
    266239                        return ERROR_CODE;
    267240                }
     241
     242                // print the result
    268243                switch(result){
    269244                        case ICMP_ECHO:
     
    283258        }
    284259
     260        // release the ICMP phone
     261        ipc_hangup(icmp_phone);
     262
    285263        return EOK;
    286264}
    287265
     266void ping_print_help(void){
     267        printf(
     268                "Network Ping aplication\n" \
     269                "Usage: ping [options] numeric_address\n" \
     270                "Where options are:\n" \
     271                "\n" \
     272                "-c request_count | --count=request_count\n" \
     273                "\tThe number of packets the application sends. The default is three (3).\n" \
     274                "\n" \
     275                "--dont_fragment\n" \
     276                "\tDisable packet fragmentation.\n"
     277                "\n" \
     278                "-f address_family | --family=address_family\n" \
     279                "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n"
     280                "\n" \
     281                "-h | --help\n" \
     282                "\tShow this application help.\n"
     283                "\n" \
     284                "-s packet_size | --size=packet_size\n" \
     285                "\tThe packet data size the application sends. The default is 38 bytes.\n" \
     286                "\n" \
     287                "-t timeout | --timeout=timeout\n" \
     288                "\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \
     289                "\n" \
     290                "--tos=tos\n" \
     291                "\tThe type of service to be used.\n" \
     292                "\n" \
     293                "--ttl=ttl\n" \
     294                "\tThe time to live to be used.\n" \
     295                "\n" \
     296                "-v | --verbose\n" \
     297                "\tShow all output messages.\n"
     298        );
     299}
     300
    288301/** @}
    289302 */
  • uspace/srv/net/app/print_error.c

    ra8a13d0 r3be62bc  
    4141
    4242#include "print_error.h"
    43 
    44 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
    45         if(IS_ICMP_ERROR(error_code)){
    46                 icmp_print_error(output, error_code, prefix, suffix);
    47         }else if(IS_SOCKET_ERROR(error_code)){
    48                 socket_print_error(output, error_code, prefix, suffix);
    49         }
    50 }
    5143
    5244void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
     
    10193}
    10294
     95void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
     96        if(IS_ICMP_ERROR(error_code)){
     97                icmp_print_error(output, error_code, prefix, suffix);
     98        }else if(IS_SOCKET_ERROR(error_code)){
     99                socket_print_error(output, error_code, prefix, suffix);
     100        }
     101}
     102
    103103void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
    104104        if(output){
  • uspace/srv/net/app/print_error.h

    ra8a13d0 r3be62bc  
    5050#define IS_SOCKET_ERROR(error_code)     ((error_code) < 0)
    5151
     52/** Prints the specific ICMP error description.
     53 *  @param[in] output The description output stream. May be NULL.
     54 *  @param[in] error_code The ICMP error code.
     55 *  @param[in] prefix The error description prefix. May be NULL.
     56 *  @param[in] suffix The error description suffix. May be NULL.
     57 */
     58void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
     59
    5260/** Prints the error description.
    5361 *  Supports ICMP and socket error codes.
     
    5866 */
    5967void print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
    60 
    61 /** Prints the specific ICMP error description.
    62  *  @param[in] output The description output stream. May be NULL.
    63  *  @param[in] error_code The ICMP error code.
    64  *  @param[in] prefix The error description prefix. May be NULL.
    65  *  @param[in] suffix The error description suffix. May be NULL.
    66  */
    67 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
    6868
    6969/** Prints the specific socket error description.
Note: See TracChangeset for help on using the changeset viewer.