Changeset 2721a75 in mainline


Ignore:
Timestamp:
2010-04-09T16:29:07Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1ef0fc3
Parents:
ddfcfeb2
Message:

ping overhaul:

  • coding style
  • shorter and better readable main()
  • tool output is much similar to GNU's ping, demonstrating what functionality is still missing

related changes:

  • rename strerror.h → str_error.h for consistency
  • replace network apps' specific command-line parsing functions with a generalized libc versions
Location:
uspace
Files:
2 added
8 deleted
12 edited
2 moved

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/exec.c

    rddfcfeb2 r2721a75  
    4040#include <str.h>
    4141#include <fcntl.h>
    42 #include <strerror.h>
     42#include <str_error.h>
    4343
    4444#include "config.h"
  • uspace/app/netecho/Makefile

    rddfcfeb2 r2721a75  
    3535SOURCES = \
    3636        netecho.c \
    37         parse.c \
    3837        print_error.c
    3938
  • uspace/app/netecho/netecho.c

    rddfcfeb2 r2721a75  
    4040#include <str.h>
    4141#include <task.h>
     42#include <arg_parse.h>
    4243
    4344#include <in.h>
     
    4647#include <socket.h>
    4748#include <net_err.h>
    48 
    49 #include "parse.h"
     49#include <socket_parse.h>
     50
    5051#include "print_error.h"
    5152
     
    133134                        switch(argv[index][1]){
    134135                                case 'b':
    135                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &backlog, "accepted sockets queue size", 0));
     136                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0));
    136137                                        break;
    137138                                case 'c':
    138                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 0));
     139                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0));
    139140                                        break;
    140141                                case 'f':
    141                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
     142                                        ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    142143                                        break;
    143144                                case 'h':
     
    146147                                        break;
    147148                                case 'p':
    148                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
     149                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    149150                                        port = (uint16_t) value;
    150151                                        break;
    151152                                case 'r':
    152                                         ERROR_PROPAGATE(parse_parameter_string(argc, argv, &index, &reply, "reply string", 0));
     153                                        ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0));
    153154                                        break;
    154155                                case 's':
    155                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "receive size", 0));
     156                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    156157                                        size = (value >= 0) ? (size_t) value : 0;
    157158                                        break;
    158159                                case 't':
    159                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
     160                                        ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
    160161                                        type = (sock_type_t) value;
    161162                                        break;
     
    166167                                case '-':
    167168                                        if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
    168                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &backlog, "accepted sockets queue size", 8));
     169                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8));
    169170                                        }else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
    170                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8));
     171                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8));
    171172                                        }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    172                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
     173                                                ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    173174                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    174175                                                echo_print_help();
    175176                                                return EOK;
    176177                                        }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    177                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
     178                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    178179                                                port = (uint16_t) value;
    179180                                        }else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){
    180                                                 ERROR_PROPAGATE(parse_parameter_string(argc, argv, &index, &reply, "reply string", 8));
     181                                                ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8));
    181182                                        }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
    182                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "receive size", 7));
     183                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    183184                                                size = (value >= 0) ? (size_t) value : 0;
    184185                                        }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    185                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
     186                                                ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    186187                                                type = (sock_type_t) value;
    187188                                        }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    188189                                                verbose = 1;
    189190                                        }else{
    190                                                 print_unrecognized(index, argv[index] + 2);
    191191                                                echo_print_help();
    192192                                                return EINVAL;
     
    194194                                        break;
    195195                                default:
    196                                         print_unrecognized(index, argv[index] + 1);
    197196                                        echo_print_help();
    198197                                        return EINVAL;
    199198                        }
    200199                }else{
    201                         print_unrecognized(index, argv[index]);
    202200                        echo_print_help();
    203201                        return EINVAL;
  • uspace/app/nettest1/Makefile

    rddfcfeb2 r2721a75  
    3636        nettest1.c \
    3737        nettest.c \
    38         parse.c \
    3938        print_error.c
    4039
  • uspace/app/nettest1/nettest1.c

    rddfcfeb2 r2721a75  
    4040#include <task.h>
    4141#include <time.h>
     42#include <arg_parse.h>
    4243
    4344#include <in.h>
     
    4647#include <socket.h>
    4748#include <net_err.h>
     49#include <socket_parse.h>
    4850
    4951#include "nettest.h"
    50 #include "parse.h"
    5152#include "print_error.h"
    5253
     
    113114                                // short options with only one letter
    114115                                case 'f':
    115                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
     116                                        ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    116117                                        break;
    117118                                case 'h':
     
    120121                                        break;
    121122                                case 'm':
    122                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 0));
     123                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0));
    123124                                        break;
    124125                                case 'n':
    125                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 0));
     126                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0));
    126127                                        break;
    127128                                case 'p':
    128                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
     129                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    129130                                        port = (uint16_t) value;
    130131                                        break;
    131132                                case 's':
    132                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
     133                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    133134                                        size = (value >= 0) ? (size_t) value : 0;
    134135                                        break;
    135136                                case 't':
    136                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
     137                                        ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
    137138                                        type = (sock_type_t) value;
    138139                                        break;
     
    143144                                case '-':
    144145                                        if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    145                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
     146                                                ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    146147                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    147148                                                nettest1_print_help();
    148149                                                return EOK;
    149150                                        }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
    150                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 8));
     151                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8));
    151152                                        }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
    152                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 8));
     153                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8));
    153154                                        }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    154                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
     155                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    155156                                                port = (uint16_t) value;
    156157                                        }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    157                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
     158                                                ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    158159                                                type = (sock_type_t) value;
    159160                                        }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    160161                                                verbose = 1;
    161162                                        }else{
    162                                                 print_unrecognized(index, argv[index] + 2);
    163163                                                nettest1_print_help();
    164164                                                return EINVAL;
     
    166166                                        break;
    167167                                default:
    168                                         print_unrecognized(index, argv[index] + 1);
    169168                                        nettest1_print_help();
    170169                                        return EINVAL;
    171170                        }
    172171                }else{
    173                         print_unrecognized(index, argv[index]);
    174172                        nettest1_print_help();
    175173                        return EINVAL;
  • uspace/app/nettest2/Makefile

    rddfcfeb2 r2721a75  
    3636        nettest2.c \
    3737        nettest.c \
    38         parse.c \
    3938        print_error.c
    4039
  • uspace/app/nettest2/nettest2.c

    rddfcfeb2 r2721a75  
    4040#include <task.h>
    4141#include <time.h>
     42#include <arg_parse.h>
    4243
    4344#include <in.h>
     
    4647#include <socket.h>
    4748#include <net_err.h>
     49#include <socket_parse.h>
    4850
    4951#include "nettest.h"
    50 #include "parse.h"
    5152#include "print_error.h"
    5253
     
    113114                                // short options with only one letter
    114115                                case 'f':
    115                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
     116                                        ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    116117                                        break;
    117118                                case 'h':
     
    120121                                        break;
    121122                                case 'm':
    122                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 0));
     123                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0));
    123124                                        break;
    124125                                case 'n':
    125                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 0));
     126                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0));
    126127                                        break;
    127128                                case 'p':
    128                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0));
     129                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    129130                                        port = (uint16_t) value;
    130131                                        break;
    131132                                case 's':
    132                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
     133                                        ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    133134                                        size = (value >= 0) ? (size_t) value : 0;
    134135                                        break;
    135136                                case 't':
    136                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
     137                                        ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
    137138                                        type = (sock_type_t) value;
    138139                                        break;
     
    143144                                case '-':
    144145                                        if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    145                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
     146                                                ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    146147                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    147148                                                nettest2_print_help();
    148149                                                return EOK;
    149150                                        }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
    150                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 8));
     151                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8));
    151152                                        }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
    152                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 8));
     153                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8));
    153154                                        }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    154                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7));
     155                                                ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    155156                                                port = (uint16_t) value;
    156157                                        }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    157                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
     158                                                ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    158159                                                type = (sock_type_t) value;
    159160                                        }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    160161                                                verbose = 1;
    161162                                        }else{
    162                                                 print_unrecognized(index, argv[index] + 2);
    163163                                                nettest2_print_help();
    164164                                                return EINVAL;
     
    166166                                        break;
    167167                                default:
    168                                         print_unrecognized(index, argv[index] + 1);
    169168                                        nettest2_print_help();
    170169                                        return EINVAL;
    171170                        }
    172171                }else{
    173                         print_unrecognized(index, argv[index]);
    174172                        nettest2_print_help();
    175173                        return EINVAL;
  • uspace/app/ping/Makefile

    rddfcfeb2 r2721a75  
    3535SOURCES = \
    3636        ping.c \
    37         parse.c \
    3837        print_error.c
    3938
  • uspace/app/ping/ping.c

    rddfcfeb2 r2721a75  
    2828
    2929/** @addtogroup ping
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Ping application.
     34 * Packet Internet Network Grouper.
    3535 */
    3636
     
    4141#include <ipc/ipc.h>
    4242#include <ipc/services.h>
     43#include <str_error.h>
     44#include <arg_parse.h>
    4345
    4446#include <icmp_api.h>
     
    4850#include <ip_codes.h>
    4951#include <socket_errno.h>
    50 #include <net_err.h>
    51 
    52 #include "parse.h"
     52#include <socket_parse.h>
     53
    5354#include "print_error.h"
    5455
    55 /** Echo module name.
     56#define NAME  "ping"
     57
     58#define CL_OK           0
     59#define CL_USAGE        -1
     60#define CL_MISSING      -2
     61#define CL_INVALID      -3
     62#define CL_UNSUPPORTED  -4
     63#define CL_ERROR        -5
     64
     65/** Ping configuration
     66 *
    5667 */
    57 #define NAME    "Ping"
    58 
    59 /** Module entry point.
    60  *  Reads command line parameters and pings.
    61  *  @param[in] argc The number of command line parameters.
    62  *  @param[in] argv The command line parameters.
    63  *  @returns EOK on success.
    64  */
    65 int main(int argc, char * argv[]);
    66 
    67 /** Prints the application help.
    68  */
    69 void ping_print_help(void);
    70 
    71 int main(int argc, char * argv[]){
    72         ERROR_DECLARE;
    73 
    74         size_t size                     = 38;
    75         int verbose                     = 0;
    76         int dont_fragment       = 0;
    77         ip_ttl_t ttl            = 0;
    78         ip_tos_t tos            = 0;
    79         int count                       = 3;
    80         suseconds_t timeout     = 3000;
    81         int family                      = AF_INET;
    82 
    83         socklen_t max_length                            = sizeof(struct sockaddr_in6);
    84         uint8_t address_data[max_length];
    85         struct sockaddr * address                       = (struct sockaddr *) address_data;
    86         struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    87         struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
    88         socklen_t addrlen;
    89         char address_string[INET6_ADDRSTRLEN];
    90         uint8_t * address_start;
    91         int icmp_phone;
    92         struct timeval time_before;
    93         struct timeval time_after;
    94         int result;
    95         int value;
    96         int index;
    97 
    98         // parse the command line arguments
    99         // stop before the last argument if it does not start with the minus sign ('-')
    100         for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
    101                 // options should start with the minus sign ('-')
    102                 if(argv[index][0] == '-'){
    103                         switch(argv[index][1]){
    104                                 // short options with only one letter
    105                                 case 'c':
    106                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "count", 0));
    107                                         break;
    108                                 case 'f':
    109                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 0, parse_address_family));
    110                                         break;
    111                                 case 'h':
    112                                         ping_print_help();
    113                                         return EOK;
    114                                         break;
    115                                 case 's':
    116                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0));
    117                                         size = (value >= 0) ? (size_t) value : 0;
    118                                         break;
    119                                 case 't':
    120                                         ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "timeout", 0));
    121                                         timeout = (value >= 0) ? (suseconds_t) value : 0;
    122                                         break;
    123                                 case 'v':
    124                                         verbose = 1;
    125                                         break;
    126                                 // long options with the double minus sign ('-')
    127                                 case '-':
    128                                         if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
    129                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "received count", 8));
    130                                         }else if(str_lcmp(argv[index] + 2, "dont_fragment", 13) == 0){
    131                                                 dont_fragment = 1;
    132                                         }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    133                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 9, parse_address_family));
    134                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    135                                                 ping_print_help();
    136                                                 return EOK;
    137                                         }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
    138                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 7));
    139                                                 size = (value >= 0) ? (size_t) value : 0;
    140                                         }else if(str_lcmp(argv[index] + 2, "timeout=", 8) == 0){
    141                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "timeout", 7));
    142                                                 timeout = (value >= 0) ? (suseconds_t) value : 0;
    143                                         }else if(str_lcmp(argv[index] + 2, "tos=", 4) == 0){
    144                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "type of service", 7));
    145                                                 tos = (value >= 0) ? (ip_tos_t) value : 0;
    146                                         }else if(str_lcmp(argv[index] + 2, "ttl=", 4) == 0){
    147                                                 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "time to live", 7));
    148                                                 ttl = (value >= 0) ? (ip_ttl_t) value : 0;
    149                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    150                                                 verbose = 1;
    151                                         }else{
    152                                                 print_unrecognized(index, argv[index] + 2);
    153                                                 ping_print_help();
    154                                                 return EINVAL;
    155                                         }
    156                                         break;
    157                                 default:
    158                                         print_unrecognized(index, argv[index] + 1);
    159                                         ping_print_help();
    160                                         return EINVAL;
    161                         }
    162                 }else{
    163                         print_unrecognized(index, argv[index]);
    164                         ping_print_help();
    165                         return EINVAL;
    166                 }
    167         }
    168 
    169         // if not before the last argument containing the address
    170         if(index >= argc){
    171                 printf("Command line error: missing address\n");
    172                 ping_print_help();
    173                 return EINVAL;
    174         }
    175 
    176         // prepare the address buffer
    177         bzero(address_data, max_length);
    178         switch(family){
    179                 case AF_INET:
    180                         address_in->sin_family = AF_INET;
    181                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    182                         addrlen = sizeof(struct sockaddr_in);
     68typedef struct {
     69        bool verbose;               /**< Verbose printouts. */
     70        size_t size;                /**< Outgoing packet size. */
     71        unsigned int count;         /**< Number of packets to send. */
     72        suseconds_t timeout;        /**< Reply wait timeout. */
     73        int af;                     /**< Address family. */
     74        ip_tos_t tos;               /**< Type of service. */
     75        ip_ttl_t ttl;               /**< Time-to-live. */
     76        bool fragments;             /**< Fragmentation. */
     77       
     78        char *dest_addr;            /**< Destination address. */
     79        struct sockaddr_in dest;    /**< IPv4 destionation. */
     80        struct sockaddr_in6 dest6;  /**< IPv6 destionation. */
     81       
     82        struct sockaddr *dest_raw;  /**< Raw destination address. */
     83        socklen_t dest_len;         /**< Raw destination address length. */
     84       
     85        /** Converted address string. */
     86        char dest_str[INET6_ADDRSTRLEN];
     87} ping_config_t;
     88
     89
     90static void usage(void)
     91{
     92        printf(
     93            "Usage: ping [-c count] [-s size] [-W timeout] [-f family] [-t ttl]\n" \
     94            "            [-Q tos] [--dont_fragment] destination\n" \
     95            "\n" \
     96            "Options:\n" \
     97            "\t-c count\n" \
     98            "\t--count=count\n" \
     99            "\t\tNumber of outgoing packets (default: 4)\n" \
     100            "\n" \
     101            "\t-s size\n" \
     102            "\t--size=bytes\n" \
     103            "\t\tOutgoing packet size (default: 56 bytes)\n" \
     104            "\n" \
     105            "\t-W timeout\n" \
     106            "\t--timeout=ms\n" \
     107            "\t\tReply wait timeout (default: 3000 ms)\n" \
     108            "\n" \
     109            "\t-f family\n" \
     110            "\t--family=family\n" \
     111            "\t\tDestination address family, AF_INET or AF_INET6 (default: AF_INET)\n" \
     112            "\n" \
     113            "\t-t ttl\n" \
     114            "\t--ttl=ttl\n" \
     115            "\t\tOutgoing packet time-to-live (default: 0)\n" \
     116            "\n" \
     117            "\t-Q tos\n" \
     118            "\t--tos=tos\n" \
     119            "\t\tOutgoing packet type of service (default: 0)\n" \
     120            "\n" \
     121            "\t--dont_fragment\n" \
     122            "\t\tDisable packet fragmentation (default: enabled)\n" \
     123            "\n" \
     124            "\t-v\n" \
     125            "\t--verbose\n" \
     126            "\t\tVerbose operation\n" \
     127            "\n" \
     128            "\t-h\n" \
     129            "\t--help\n" \
     130            "\t\tPrint this usage information\n"
     131        );
     132}
     133
     134static int arg_short_long(const char *arg, const char *ashort,
     135    const char *along)
     136{
     137        if (str_cmp(arg, ashort) == 0)
     138                return 0;
     139       
     140        if (str_lcmp(arg, along, str_length(along)) == 0)
     141                return str_length(along);
     142       
     143        return -1;
     144}
     145
     146static int args_parse(int argc, char *argv[], ping_config_t *config)
     147{
     148        if (argc < 2)
     149                return CL_USAGE;
     150       
     151        int i;
     152        int ret;
     153       
     154        for (i = 1; i < argc; i++) {
     155               
     156                /* Not an option */
     157                if (argv[i][0] != '-')
    183158                        break;
    184                 case AF_INET6:
    185                         address_in6->sin6_family = AF_INET6;
    186                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    187                         addrlen = sizeof(struct sockaddr_in6);
     159               
     160                /* Options terminator */
     161                if (str_cmp(argv[i], "--") == 0) {
     162                        i++;
     163                        break;
     164                }
     165               
     166                int off;
     167                int tmp;
     168               
     169                /* Usage */
     170                if ((off = arg_short_long(argv[i], "-h", "--help")) != -1)
     171                        return CL_USAGE;
     172               
     173                /* Verbose */
     174                if ((off = arg_short_long(argv[i], "-v", "--verbose")) != -1) {
     175                        config->verbose = true;
     176                        continue;
     177                }
     178               
     179                /* Don't fragment */
     180                if (str_cmp(argv[i], "--dont_fragment") == 0) {
     181                        config->fragments = false;
     182                        continue;
     183                }
     184               
     185                /* Count */
     186                if ((off = arg_short_long(argv[i], "-c", "--count=")) != -1) {
     187                        ret = arg_parse_int(argc, argv, &i, &tmp, off);
     188                       
     189                        if ((ret != EOK) || (tmp < 0))
     190                                return i;
     191                       
     192                        config->count = (unsigned int) tmp;
     193                        continue;
     194                }
     195               
     196                /* Outgoing packet size */
     197                if ((off = arg_short_long(argv[i], "-s", "--size=")) != -1) {
     198                        ret = arg_parse_int(argc, argv, &i, &tmp, off);
     199                       
     200                        if ((ret != EOK) || (tmp < 0))
     201                                return i;
     202                       
     203                        config->size = (size_t) tmp;
     204                        continue;
     205                }
     206               
     207                /* Reply wait timeout */
     208                if ((off = arg_short_long(argv[i], "-W", "--timeout=")) != -1) {
     209                        ret = arg_parse_int(argc, argv, &i, &tmp, off);
     210                       
     211                        if ((ret != EOK) || (tmp < 0))
     212                                return i;
     213                       
     214                        config->timeout = (suseconds_t) tmp;
     215                        continue;
     216                }
     217               
     218                /* Address family */
     219                if ((off = arg_short_long(argv[i], "-f", "--family=")) != -1) {
     220                        ret = arg_parse_name_int(argc, argv, &i, &config->af, off,
     221                            socket_parse_address_family);
     222                       
     223                        if (ret != EOK)
     224                                return i;
     225                       
     226                        continue;
     227                }
     228               
     229                /* Type of service */
     230                if ((off = arg_short_long(argv[i], "-Q", "--tos=")) != -1) {
     231                        ret = arg_parse_name_int(argc, argv, &i, &tmp, off,
     232                            socket_parse_address_family);
     233                       
     234                        if ((ret != EOK) || (tmp < 0))
     235                                return i;
     236                       
     237                        config->tos = (ip_tos_t) tmp;
     238                        continue;
     239                }
     240               
     241                /* Time to live */
     242                if ((off = arg_short_long(argv[i], "-t", "--ttl=")) != -1) {
     243                        ret = arg_parse_name_int(argc, argv, &i, &tmp, off,
     244                            socket_parse_address_family);
     245                       
     246                        if ((ret != EOK) || (tmp < 0))
     247                                return i;
     248                       
     249                        config->ttl = (ip_ttl_t) tmp;
     250                        continue;
     251                }
     252        }
     253       
     254        if (i >= argc)
     255                return CL_MISSING;
     256       
     257        config->dest_addr = argv[i];
     258       
     259        /* Resolve destionation address */
     260        switch (config->af) {
     261        case AF_INET:
     262                config->dest_raw = (struct sockaddr *) &config->dest;
     263                config->dest_len = sizeof(config->dest);
     264                config->dest.sin_family = config->af;
     265                ret = inet_pton(config->af, config->dest_addr,
     266                    (uint8_t *) &config->dest.sin_addr.s_addr);
     267                break;
     268        case AF_INET6:
     269                config->dest_raw = (struct sockaddr *) &config->dest6;
     270                config->dest_len = sizeof(config->dest6);
     271                config->dest6.sin6_family = config->af;
     272                ret = inet_pton(config->af, config->dest_addr,
     273                    (uint8_t *) &config->dest6.sin6_addr.s6_addr);
     274                break;
     275        default:
     276                return CL_UNSUPPORTED;
     277        }
     278       
     279        if (ret != EOK)
     280                return CL_INVALID;
     281       
     282        /* Convert destination address back to string */
     283        switch (config->af) {
     284        case AF_INET:
     285                ret = inet_ntop(config->af,
     286                    (uint8_t *) &config->dest.sin_addr.s_addr,
     287                    config->dest_str, sizeof(config->dest_str));
     288                break;
     289        case AF_INET6:
     290                ret = inet_ntop(config->af,
     291                    (uint8_t *) &config->dest6.sin6_addr.s6_addr,
     292                    config->dest_str, sizeof(config->dest_str));
     293                break;
     294        default:
     295                return CL_UNSUPPORTED;
     296        }
     297       
     298        if (ret != EOK)
     299                return CL_ERROR;
     300       
     301        return CL_OK;
     302}
     303
     304int main(int argc, char *argv[])
     305{
     306        ping_config_t config;
     307       
     308        /* Default configuration */
     309        config.verbose = false;
     310        config.size = 56;
     311        config.count = 4;
     312        config.timeout = 3000;
     313        config.af = AF_INET;
     314        config.tos = 0;
     315        config.ttl = 0;
     316        config.fragments = true;
     317       
     318        int ret = args_parse(argc, argv, &config);
     319       
     320        switch (ret) {
     321        case CL_OK:
     322                break;
     323        case CL_USAGE:
     324                usage();
     325                return 0;
     326        case CL_MISSING:
     327                fprintf(stderr, "%s: Destination address missing\n", NAME);
     328                return 1;
     329        case CL_INVALID:
     330                fprintf(stderr, "%s: Destination address '%s' invalid or malformed\n",
     331                    NAME, config.dest_addr);
     332                return 2;
     333        case CL_UNSUPPORTED:
     334                fprintf(stderr, "%s: Destination address '%s' unsupported\n",
     335                    NAME, config.dest_addr);
     336                return 3;
     337        case CL_ERROR:
     338                fprintf(stderr, "%s: Destination address '%s' error\n",
     339                    NAME, config.dest_addr);
     340                return 4;
     341        default:
     342                fprintf(stderr, "%s: Unknown or invalid option '%s'\n", NAME,
     343                    argv[ret]);
     344                return 5;
     345        }
     346       
     347        printf("PING %s (%s) %u(%u) bytes of data\n", config.dest_addr,
     348            config.dest_str, config.size, config.size);
     349       
     350        int icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
     351        if (icmp_phone < 0) {
     352                fprintf(stderr, "%s: Unable to connect to ICMP service (%s)\n", NAME,
     353                    str_error(icmp_phone));
     354                return icmp_phone;
     355        }
     356       
     357        unsigned int seq;
     358        for (seq = 0; seq < config.count; seq++) {
     359                struct timeval t0;
     360                ret = gettimeofday(&t0, NULL);
     361                if (ret != EOK) {
     362                        fprintf(stderr, "%s: gettimeofday failed (%s)\n", NAME,
     363                            str_error(ret));
     364                       
     365                        ipc_hangup(icmp_phone);
     366                        return ret;
     367                }
     368               
     369                /* Ping! */
     370                int result = icmp_echo_msg(icmp_phone, config.size, config.timeout,
     371                    config.ttl, config.tos, !config.fragments, config.dest_raw,
     372                    config.dest_len);
     373               
     374                struct timeval t1;
     375                ret = gettimeofday(&t1, NULL);
     376                if (ret != EOK) {
     377                        fprintf(stderr, "%s: gettimeofday failed (%s)\n", NAME,
     378                            str_error(ret));
     379                       
     380                        ipc_hangup(icmp_phone);
     381                        return ret;
     382                }
     383               
     384                suseconds_t elapsed = tv_sub(&t1, &t0);
     385               
     386                switch (result) {
     387                case ICMP_ECHO:
     388                        printf("%u bytes from ? (?): icmp_seq=%u ttl=? time=%u.%04u\n",
     389                                config.size, seq, elapsed / 1000, elapsed % 1000);
     390                        break;
     391                case ETIMEOUT:
     392                        printf("%u bytes from ? (?): icmp_seq=%u Timed out\n",
     393                                config.size, seq);
    188394                        break;
    189395                default:
    190                         fprintf(stderr, "Address family is not supported\n");
    191                         return EAFNOSUPPORT;
    192         }
    193 
    194         // parse the last argument which should contain the address
    195         if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    196                 fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
    197                 return ERROR_CODE;
    198         }
    199 
    200         // connect to the ICMP module
    201         icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
    202         if(icmp_phone < 0){
    203                 fprintf(stderr, "ICMP connect error %d\n", icmp_phone);
    204                 return icmp_phone;
    205         }
    206 
    207         // print the ping header
    208         printf("PING %d bytes of data\n", size);
    209         if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
    210                 fprintf(stderr, "Address error %d\n", ERROR_CODE);
    211         }else{
    212                 printf("Address %s:\n", address_string);
    213         }
    214 
    215         // do count times
    216         while(count > 0){
    217 
    218                 // get the starting time
    219                 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    220                         fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    221                         // release the ICMP phone
    222                         ipc_hangup(icmp_phone);
    223                         return ERROR_CODE;
    224                 }
    225 
    226                 // request the ping
    227                 result = icmp_echo_msg(icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen);
    228 
    229                 // get the ending time
    230                 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    231                         fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    232                         // release the ICMP phone
    233                         ipc_hangup(icmp_phone);
    234                         return ERROR_CODE;
    235                 }
    236 
    237                 // print the result
    238                 switch(result){
    239                         case ICMP_ECHO:
    240                                 printf("Ping round trip time %d miliseconds\n", tv_sub(&time_after, &time_before) / 1000);
    241                                 break;
    242                         case ETIMEOUT:
    243                                 printf("Timed out.\n");
    244                                 break;
    245                         default:
    246                                 print_error(stdout, result, NULL, "\n");
    247                 }
    248                 -- count;
    249         }
    250 
    251         if(verbose){
    252                 printf("Exiting\n");
    253         }
    254 
    255         // release the ICMP phone
     396                        print_error(stdout, result, NULL, "\n");
     397                }
     398        }
     399       
    256400        ipc_hangup(icmp_phone);
    257 
    258         return EOK;
    259 }
    260 
    261 void ping_print_help(void){
    262         printf(
    263                 "Network Ping aplication\n" \
    264                 "Usage: ping [options] numeric_address\n" \
    265                 "Where options are:\n" \
    266                 "\n" \
    267                 "-c request_count | --count=request_count\n" \
    268                 "\tThe number of packets the application sends. The default is three (3).\n" \
    269                 "\n" \
    270                 "--dont_fragment\n" \
    271                 "\tDisable packet fragmentation.\n"
    272                 "\n" \
    273                 "-f address_family | --family=address_family\n" \
    274                 "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n"
    275                 "\n" \
    276                 "-h | --help\n" \
    277                 "\tShow this application help.\n"
    278                 "\n" \
    279                 "-s packet_size | --size=packet_size\n" \
    280                 "\tThe packet data size the application sends. The default is 38 bytes.\n" \
    281                 "\n" \
    282                 "-t timeout | --timeout=timeout\n" \
    283                 "\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \
    284                 "\n" \
    285                 "--tos=tos\n" \
    286                 "\tThe type of service to be used.\n" \
    287                 "\n" \
    288                 "--ttl=ttl\n" \
    289                 "\tThe time to live to be used.\n" \
    290                 "\n" \
    291                 "-v | --verbose\n" \
    292                 "\tShow all output messages.\n"
    293         );
     401       
     402        return 0;
    294403}
    295404
  • uspace/lib/c/Makefile

    rddfcfeb2 r2721a75  
    6161        generic/mem.c \
    6262        generic/str.c \
     63        generic/str_error.c \
    6364        generic/fibril.c \
    6465        generic/fibril_synch.c \
     
    9495        generic/vfs/canonify.c \
    9596        generic/stacktrace.c \
    96         generic/strerror.c
     97        generic/arg_parse.c
    9798
    9899SOURCES = \
  • uspace/lib/c/generic/str_error.c

    rddfcfeb2 r2721a75  
    3333 */
    3434
    35 #include <strerror.h>
     35#include <str_error.h>
    3636#include <stdio.h>
    3737#include <fibril.h>
  • uspace/lib/socket/Makefile

    rddfcfeb2 r2721a75  
    3535        generic/socket_client.c \
    3636        generic/socket_core.c \
     37        generic/socket_parse.c \
    3738        generic/inet.c \
    3839        generic/net_modules.c \
  • uspace/lib/socket/include/net_err.h

    rddfcfeb2 r2721a75  
    4242#ifdef CONFIG_DEBUG
    4343        #include <stdio.h>
    44         #include <strerror.h>
     44        #include <str_error.h>
    4545#endif
    4646
Note: See TracChangeset for help on using the changeset viewer.