Changeset b40bfac in mainline for uspace/app/netecho/netecho.c


Ignore:
Timestamp:
2010-11-08T07:13:25Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63a1e60
Parents:
d70a463 (diff), 3da12d74 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

File:
1 edited

Legend:

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

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup netecho
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Network echo application.
    35  *  Answers received packets.
     34 * Network echo application.
     35 * Answers received packets.
    3636 */
    3737
     
    4141#include <task.h>
    4242#include <arg_parse.h>
    43 #include <err.h>
    4443
    4544#include <net/in.h>
     
    5150#include "print_error.h"
    5251
    53 /** Network echo module name.
    54  */
     52/** Network echo module name. */
    5553#define NAME    "Network Echo"
    5654
    57 /** Prints the application help.
    58  */
    59 void echo_print_help(void);
    60 
    61 /** Module entry point.
    62  *  Reads command line parameters and starts listenning.
    63  *  @param[in] argc The number of command line parameters.
    64  *  @param[in] argv The command line parameters.
    65  *  @returns EOK on success.
    66  */
    67 int main(int argc, char * argv[]);
    68 
    69 void echo_print_help(void){
     55static void echo_print_help(void)
     56{
    7057        printf(
    7158                "Network Echo aplication\n" \
     
    10188}
    10289
    103 int main(int argc, char * argv[]){
    104         ERROR_DECLARE;
    105 
    106         size_t size                     = 1024;
    107         int verbose                     = 0;
    108         char * reply            = NULL;
    109         sock_type_t type        = SOCK_DGRAM;
    110         int count                       = -1;
    111         int family                      = PF_INET;
    112         uint16_t port           = 7;
    113         int backlog                     = 3;
    114 
    115         socklen_t max_length                            = sizeof(struct sockaddr_in6);
     90int main(int argc, char *argv[])
     91{
     92        size_t size = 1024;
     93        int verbose = 0;
     94        char *reply = NULL;
     95        sock_type_t type = SOCK_DGRAM;
     96        int count = -1;
     97        int family = PF_INET;
     98        uint16_t port = 7;
     99        int backlog = 3;
     100
     101        socklen_t max_length = sizeof(struct sockaddr_in6);
    116102        uint8_t address_data[max_length];
    117         struct sockaddr * address                       = (struct sockaddr *) address_data;
    118         struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    119         struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     103        struct sockaddr *address = (struct sockaddr *) address_data;
     104        struct sockaddr_in *address_in = (struct sockaddr_in *) address;
     105        struct sockaddr_in6 *address_in6 = (struct sockaddr_in6 *) address;
    120106        socklen_t addrlen;
    121107        char address_string[INET6_ADDRSTRLEN];
    122         uint8_t * address_start;
     108        uint8_t *address_start;
    123109        int socket_id;
    124110        int listening_id;
    125         char * data;
     111        char *data;
    126112        size_t length;
    127113        int index;
    128114        size_t reply_length;
    129115        int value;
     116        int rc;
    130117
    131118        // parse the command line arguments
    132         for(index = 1; index < argc; ++ index){
    133                 if(argv[index][0] == '-'){
    134                         switch(argv[index][1]){
    135                                 case 'b':
    136                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0));
    137                                         break;
    138                                 case 'c':
    139                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0));
    140                                         break;
    141                                 case 'f':
    142                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    143                                         break;
    144                                 case 'h':
     119        for (index = 1; index < argc; ++ index) {
     120                if (argv[index][0] == '-') {
     121                        switch (argv[index][1]) {
     122                        case 'b':
     123                                rc = arg_parse_int(argc, argv, &index, &backlog, 0);
     124                                if (rc != EOK)
     125                                        return rc;
     126                                break;
     127                        case 'c':
     128                                rc = arg_parse_int(argc, argv, &index, &count, 0);
     129                                if (rc != EOK)
     130                                        return rc;
     131                                break;
     132                        case 'f':
     133                                rc = arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family);
     134                                if (rc != EOK)
     135                                        return rc;
     136                                break;
     137                        case 'h':
     138                                echo_print_help();
     139                                return EOK;
     140                                break;
     141                        case 'p':
     142                                rc = arg_parse_int(argc, argv, &index, &value, 0);
     143                                if (rc != EOK)
     144                                        return rc;
     145                                port = (uint16_t) value;
     146                                break;
     147                        case 'r':
     148                                rc = arg_parse_string(argc, argv, &index, &reply, 0);
     149                                if (rc != EOK)
     150                                        return rc;
     151                                break;
     152                        case 's':
     153                                rc = arg_parse_int(argc, argv, &index, &value, 0);
     154                                if (rc != EOK)
     155                                        return rc;
     156                                size = (value >= 0) ? (size_t) value : 0;
     157                                break;
     158                        case 't':
     159                                rc = arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type);
     160                                if (rc != EOK)
     161                                        return rc;
     162                                type = (sock_type_t) value;
     163                                break;
     164                        case 'v':
     165                                verbose = 1;
     166                                break;
     167                        // long options with the double minus sign ('-')
     168                        case '-':
     169                                if (str_lcmp(argv[index] + 2, "backlog=", 6) == 0) {
     170                                        rc = arg_parse_int(argc, argv, &index, &backlog, 8);
     171                                        if (rc != EOK)
     172                                                return rc;
     173                                } else if (str_lcmp(argv[index] + 2, "count=", 6) == 0) {
     174                                        rc = arg_parse_int(argc, argv, &index, &count, 8);
     175                                } else if (str_lcmp(argv[index] + 2, "family=", 7) == 0) {
     176                                        rc = arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family);
     177                                        if (rc != EOK)
     178                                                return rc;
     179                                } else if (str_lcmp(argv[index] + 2, "help", 5) == 0) {
    145180                                        echo_print_help();
    146181                                        return EOK;
    147                                         break;
    148                                 case 'p':
    149                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
     182                                } else if (str_lcmp(argv[index] + 2, "port=", 5) == 0) {
     183                                        rc = arg_parse_int(argc, argv, &index, &value, 7);
     184                                        if (rc != EOK)
     185                                                return rc;
    150186                                        port = (uint16_t) value;
    151                                         break;
    152                                 case 'r':
    153                                         ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0));
    154                                         break;
    155                                 case 's':
    156                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
     187                                } else if (str_lcmp(argv[index] + 2, "reply=", 6) == 0) {
     188                                        rc = arg_parse_string(argc, argv, &index, &reply, 8);
     189                                        if (rc != EOK)
     190                                                return rc;
     191                                } else if (str_lcmp(argv[index] + 2, "size=", 5) == 0) {
     192                                        rc = arg_parse_int(argc, argv, &index, &value, 7);
     193                                        if (rc != EOK)
     194                                                return rc;
    157195                                        size = (value >= 0) ? (size_t) value : 0;
    158                                         break;
    159                                 case 't':
    160                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
     196                                } else if (str_lcmp(argv[index] + 2, "type=", 5) == 0) {
     197                                        rc = arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type);
     198                                        if (rc != EOK)
     199                                                return rc;
    161200                                        type = (sock_type_t) value;
    162                                         break;
    163                                 case 'v':
     201                                } else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) {
    164202                                        verbose = 1;
    165                                         break;
    166                                 // long options with the double minus sign ('-')
    167                                 case '-':
    168                                         if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
    169                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8));
    170                                         }else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
    171                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8));
    172                                         }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    173                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    174                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    175                                                 echo_print_help();
    176                                                 return EOK;
    177                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    178                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    179                                                 port = (uint16_t) value;
    180                                         }else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){
    181                                                 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8));
    182                                         }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
    183                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    184                                                 size = (value >= 0) ? (size_t) value : 0;
    185                                         }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    186                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    187                                                 type = (sock_type_t) value;
    188                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    189                                                 verbose = 1;
    190                                         }else{
    191                                                 echo_print_help();
    192                                                 return EINVAL;
    193                                         }
    194                                         break;
    195                                 default:
     203                                } else {
    196204                                        echo_print_help();
    197205                                        return EINVAL;
     206                                }
     207                                break;
     208                        default:
     209                                echo_print_help();
     210                                return EINVAL;
    198211                        }
    199                 }else{
     212                } else {
    200213                        echo_print_help();
    201214                        return EINVAL;
     
    204217
    205218        // check the buffer size
    206         if(size <= 0){
     219        if (size <= 0) {
    207220                fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
    208221                size = 1024;
     
    210223        // size plus the terminating null (\0)
    211224        data = (char *) malloc(size + 1);
    212         if(! data){
     225        if (!data) {
    213226                fprintf(stderr, "Failed to allocate receive buffer.\n");
    214227                return ENOMEM;
     
    220233        // prepare the address buffer
    221234        bzero(address_data, max_length);
    222         switch(family){
    223                 case PF_INET:
    224                         address_in->sin_family = AF_INET;
    225                         address_in->sin_port = htons(port);
    226                         addrlen = sizeof(struct sockaddr_in);
    227                         break;
    228                 case PF_INET6:
    229                         address_in6->sin6_family = AF_INET6;
    230                         address_in6->sin6_port = htons(port);
    231                         addrlen = sizeof(struct sockaddr_in6);
    232                         break;
    233                 default:
    234                         fprintf(stderr, "Protocol family is not supported\n");
    235                         return EAFNOSUPPORT;
     235        switch (family) {
     236        case PF_INET:
     237                address_in->sin_family = AF_INET;
     238                address_in->sin_port = htons(port);
     239                addrlen = sizeof(struct sockaddr_in);
     240                break;
     241        case PF_INET6:
     242                address_in6->sin6_family = AF_INET6;
     243                address_in6->sin6_port = htons(port);
     244                addrlen = sizeof(struct sockaddr_in6);
     245                break;
     246        default:
     247                fprintf(stderr, "Protocol family is not supported\n");
     248                return EAFNOSUPPORT;
    236249        }
    237250
    238251        // get a listening socket
    239252        listening_id = socket(family, type, 0);
    240         if(listening_id < 0){
     253        if (listening_id < 0) {
    241254                socket_print_error(stderr, listening_id, "Socket create: ", "\n");
    242255                return listening_id;
     
    244257
    245258        // if the stream socket is used
    246         if(type == SOCK_STREAM){
     259        if (type == SOCK_STREAM) {
    247260                // check the backlog
    248                 if(backlog <= 0){
     261                if (backlog <= 0) {
    249262                        fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
    250263                        backlog = 3;
    251264                }
    252265                // set the backlog
    253                 if(ERROR_OCCURRED(listen(listening_id, backlog))){
    254                         socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
    255                         return ERROR_CODE;
     266                rc = listen(listening_id, backlog);
     267                if (rc != EOK) {
     268                        socket_print_error(stderr, rc, "Socket listen: ", "\n");
     269                        return rc;
    256270                }
    257271        }
    258272
    259273        // bind the listenning socket
    260         if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
    261                 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
    262                 return ERROR_CODE;
    263         }
    264 
    265         if(verbose){
     274        rc = bind(listening_id, address, addrlen);
     275        if (rc != EOK) {
     276                socket_print_error(stderr, rc, "Socket bind: ", "\n");
     277                return rc;
     278        }
     279
     280        if (verbose)
    266281                printf("Socket %d listenning at %d\n", listening_id, port);
    267         }
    268282
    269283        socket_id = listening_id;
     
    271285        // do count times
    272286        // or indefinitely if set to a negative value
    273         while(count){
     287        while (count) {
    274288
    275289                addrlen = max_length;
    276                 if(type == SOCK_STREAM){
     290                if (type == SOCK_STREAM) {
    277291                        // acceept a socket if the stream socket is used
    278292                        socket_id = accept(listening_id, address, &addrlen);
    279                         if(socket_id <= 0){
     293                        if (socket_id <= 0) {
    280294                                socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
    281                         }else{
    282                                 if(verbose){
     295                        } else {
     296                                if (verbose)
    283297                                        printf("Socket %d accepted\n", socket_id);
    284                                 }
    285298                        }
    286299                }
    287300
    288301                // if the datagram socket is used or the stream socked was accepted
    289                 if(socket_id > 0){
     302                if (socket_id > 0) {
    290303
    291304                        // receive an echo request
    292305                        value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    293                         if(value < 0){
     306                        if (value < 0) {
    294307                                socket_print_error(stderr, value, "Socket receive: ", "\n");
    295                         }else{
     308                        } else {
    296309                                length = (size_t) value;
    297                                 if(verbose){
     310                                if (verbose) {
    298311                                        // print the header
    299312
    300313                                        // get the source port and prepare the address buffer
    301314                                        address_start = NULL;
    302                                         switch(address->sa_family){
    303                                                 case AF_INET:
    304                                                         port = ntohs(address_in->sin_port);
    305                                                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    306                                                         break;
    307                                                 case AF_INET6:
    308                                                         port = ntohs(address_in6->sin6_port);
    309                                                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    310                                                         break;
    311                                                 default:
    312                                                         fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
     315                                        switch (address->sa_family) {
     316                                        case AF_INET:
     317                                                port = ntohs(address_in->sin_port);
     318                                                address_start = (uint8_t *) &address_in->sin_addr.s_addr;
     319                                                break;
     320                                        case AF_INET6:
     321                                                port = ntohs(address_in6->sin6_port);
     322                                                address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
     323                                                break;
     324                                        default:
     325                                                fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
    313326                                        }
    314327                                        // parse the source address
    315                                         if(address_start){
    316                                                 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
    317                                                         fprintf(stderr, "Received address error %d\n", ERROR_CODE);
    318                                                 }else{
     328                                        if (address_start) {
     329                                                rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string));
     330                                                if (rc != EOK) {
     331                                                        fprintf(stderr, "Received address error %d\n", rc);
     332                                                } else {
    319333                                                        data[length] = '\0';
    320334                                                        printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data);
     
    324338
    325339                                // answer the request either with the static reply or the original data
    326                                 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
    327                                         socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    328                                 }
    329 
     340                                rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen);
     341                                if (rc != EOK)
     342                                        socket_print_error(stderr, rc, "Socket send: ", "\n");
    330343                        }
    331344
    332345                        // close the accepted stream socket
    333                         if(type == SOCK_STREAM){
    334                                 if(ERROR_OCCURRED(closesocket(socket_id))){
    335                                         socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
    336                                 }
     346                        if (type == SOCK_STREAM) {
     347                                rc = closesocket(socket_id);
     348                                if (rc != EOK)
     349                                        socket_print_error(stderr, rc, "Close socket: ", "\n");
    337350                        }
    338351
     
    340353
    341354                // decrease the count if positive
    342                 if(count > 0){
    343                         -- count;
    344                         if(verbose){
     355                if (count > 0) {
     356                        count--;
     357                        if (verbose)
    345358                                printf("Waiting for next %d packet(s)\n", count);
    346                         }
    347                 }
    348         }
    349 
    350         if(verbose){
     359                }
     360        }
     361
     362        if (verbose)
    351363                printf("Closing the socket\n");
    352         }
    353364
    354365        // close the listenning socket
    355         if(ERROR_OCCURRED(closesocket(listening_id))){
    356                 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
    357                 return ERROR_CODE;
    358         }
    359 
    360         if(verbose){
     366        rc = closesocket(listening_id);
     367        if (rc != EOK) {
     368                socket_print_error(stderr, rc, "Close socket: ", "\n");
     369                return rc;
     370        }
     371
     372        if (verbose)
    361373                printf("Exiting\n");
    362         }
    363374
    364375        return EOK;
Note: See TracChangeset for help on using the changeset viewer.