Changeset 4775


Ignore:
Timestamp:
11/09/08 19:39:20 (8 years ago)
Author:
werner
Message:

Make it a bit more convenient to use.

  • the host can now be by specified by name
  • new option -p port to set the port number by name or number
  • receiver prints statistics if interrupted by SIGINT
Location:
developers/werner/owping
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • developers/werner/owping/README

    r4764 r4775  
    1111Receiver: 
    1212 
    13 % owping 
     13% owping [-p port] 
    1414 
    1515Sender: 
    1616 
    17 % owping [-c count] ip_address 
     17% owping [-c count] [-p port] ipv4_address 
    1818 
    1919 
     
    3131  compares this with the inter-arrival time it measures. 
    3232 
    33 - receiver should also handle SIGINT, and print statistics 
    34  
    3533- receiver should count gaps in the sequence numbers 
    36  
    37 - should support host name resolution 
    38  
    39 - should support setting the port number 
  • developers/werner/owping/owping.c

    r4764 r4775  
    1616#include <stdio.h> 
    1717#include <unistd.h> 
     18#include <string.h> 
     19#include <netdb.h> 
    1820#include <arpa/inet.h> 
    1921 
     
    2123 
    2224 
    23 #define PORT 23867 
     25#define DEFAULT_PORT 23867 
    2426 
    2527 
    2628static void usage(const char *name) 
    2729{ 
    28     fprintf(stderr, "usage: %s [[-c count] ip_address]\n", name); 
     30    fprintf(stderr, "usage: %s [-p port] [[-c count] ipv4_address]\n", name); 
    2931    exit(1); 
    3032} 
     
    3436{ 
    3537    struct sockaddr_in addr; 
    36     int count = -1; 
     38    long count = -1; 
     39    unsigned long port = DEFAULT_PORT; 
    3740    int c; 
    3841    char *end; 
    3942 
    40     while ((c = getopt(argc, argv, "c:")) != EOF) 
     43    addr.sin_family = AF_INET; 
     44    addr.sin_addr.s_addr = INADDR_ANY; 
     45    addr.sin_port = htons(DEFAULT_PORT); 
     46 
     47    while ((c = getopt(argc, argv, "c:p:")) != EOF) 
    4148        switch (c) { 
    4249        case 'c': 
    4350            count = strtoul(optarg, &end, 10); 
    44             if (*end) 
    45                 usage(*argv); 
     51            if (*end || count < 0 || count > INT_MAX) { 
     52                fprintf(stderr, "%s: invalid port\n", optarg); 
     53                exit(1); 
     54            } 
     55            break; 
     56        case 'p': 
     57            port = strtoul(optarg, &end, 10); 
     58            if (!*end && port && port <= 0xffff) 
     59                addr.sin_port = htons(port); 
     60            else { 
     61                struct servent *se; 
     62 
     63                se = getservbyname(optarg, "udp"); 
     64                if (!se) { 
     65                    fprintf(stderr, "%s: unknown port\n", optarg); 
     66                    exit(1); 
     67                } 
     68                addr.sin_port = se->s_port; 
     69            } 
    4670            break; 
    4771        default: 
     
    5175    switch (argc-optind) { 
    5276    case 0: 
    53         rx(PORT); 
     77        rx((const struct sockaddr_in *) &addr); 
    5478        break; 
    5579    case 1: 
    5680        addr.sin_family = AF_INET; 
    5781        addr.sin_addr.s_addr = inet_addr(argv[optind]); 
    58         addr.sin_port = htons(PORT); 
    59         if (addr.sin_addr.s_addr == (in_addr_t) -1) 
    60             usage(*argv); 
    61         tx(addr, count); 
     82        addr.sin_port = htons(port); 
     83        if (addr.sin_addr.s_addr == (in_addr_t) -1) { 
     84            struct hostent *he; 
     85 
     86            he = gethostbyname(argv[optind]); 
     87            if (!he || he->h_addrtype != AF_INET) { 
     88                fprintf(stderr, "%s: unknown host\n", argv[optind]); 
     89                exit(1); 
     90            } 
     91            memcpy(&addr.sin_addr.s_addr, he->h_addr, he->h_length); 
     92        } 
     93        tx((const struct sockaddr_in *) &addr, count); 
    6294        break; 
    6395    default: 
  • developers/werner/owping/owping.h

    r4763 r4775  
    2727 
    2828 
    29 void tx(struct sockaddr_in addr, int num); 
    30 void rx(int port); 
     29void tx(const struct sockaddr_in *addr, int num); 
     30void rx(const struct sockaddr_in *addr); 
    3131 
    3232#endif /* OWPING_H */ 
  • developers/werner/owping/rx.c

    r4764 r4775  
    1515#include <stdlib.h> 
    1616#include <stdio.h> 
     17#include <unistd.h> 
    1718#include <string.h> 
    1819#include <math.h> 
     20#include <signal.h> 
    1921#include <sys/time.h> 
    2022#include <sys/socket.h> 
     
    2931    double sum, sq; 
    3032    int n; 
    31 }; 
     33} stats_itf, stats_user; 
    3234 
    3335 
     
    4244    double avg = stats->sum/stats->n; 
    4345 
    44     printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms (%d packets)\n", 
     46    printf("%s min/avg/max/sdev = %.3f/%.3f/%.3f/%.3f ms\n", 
    4547      label, 
    4648      stats->min/1000.0, avg/1000.0, stats->max/1000.0, 
    47       sqrt(stats->sq/stats->n-avg*avg)/1000.0, 
    48       stats->n); 
     49      sqrt(stats->sq/stats->n-avg*avg)/1000.0); 
    4950} 
    5051 
     
    7879 
    7980 
    80 void rx(int port) 
     81static void finish(void) 
    8182{ 
    82     struct stats stats_itf, stats_user; 
    83     struct sockaddr_in addr; 
     83    printf("received %d packets\n", stats_itf.n); 
     84    stats_print("itf:", &stats_itf); 
     85    stats_print("app:", &stats_user); 
     86} 
     87 
     88 
     89static void handler(int sig) 
     90{ 
     91    finish(); 
     92    _exit(0); 
     93} 
     94 
     95 
     96static void block(int how) 
     97{ 
     98    sigset_t set; 
     99 
     100    if (sigemptyset(&set) < 0) { 
     101        perror("sigemptyset"); 
     102        exit(1); 
     103    } 
     104    if (sigaddset(&set, SIGINT) < 0) { 
     105        perror("sigaddset"); 
     106        exit(1); 
     107    } 
     108    if (sigprocmask(how, &set, NULL) < 0) { 
     109        perror("sigprocmask"); 
     110        exit(1); 
     111    } 
     112} 
     113 
     114 
     115void rx(const struct sockaddr_in *addr) 
     116{ 
     117    struct sockaddr_in src; 
    84118    int s; 
    85119 
     
    90124    } 
    91125 
    92     addr.sin_family = AF_INET; 
    93     addr.sin_addr.s_addr = INADDR_ANY; 
    94     addr.sin_port = htons(port); 
    95     if (bind(s, (const struct sockaddr *) &addr, sizeof(addr)) < 0) { 
     126    if (bind(s, (const struct sockaddr *) addr, sizeof(*addr)) < 0) { 
    96127        perror("bind"); 
    97128        exit(1); 
     
    101132    stats_init(&stats_user); 
    102133 
     134    if (atexit(finish)) { 
     135        perror("atexit"); 
     136        exit(1); 
     137    } 
     138    if (signal(SIGINT, handler) == SIG_ERR) { 
     139        perror("signal(SIGINT)"); 
     140        exit(1); 
     141    } 
     142 
    103143    while (1) { 
    104144        struct owping buf; 
     
    107147        struct timeval t_src, t_itf, t_user; 
    108148 
    109         addr_len = sizeof(addr); 
     149        addr_len = sizeof(src); 
    110150        got = recvfrom(s, &buf, sizeof(buf), 0, 
    111           (struct sockaddr *) &addr, &addr_len); 
     151          (struct sockaddr *) &src, &addr_len); 
    112152        if (got < 0) { 
    113153            perror("recvmsg"); 
     
    129169            exit(1); 
    130170        } 
     171        block(SIG_BLOCK); 
    131172        printf("seq=%u from %s:", (unsigned) ntohl(buf.seq), 
    132           inet_ntoa(addr.sin_addr)); 
     173          inet_ntoa(src.sin_addr)); 
    133174        t_src.tv_sec = ntohl(buf.tv_sec); 
    134175        t_src.tv_usec = ntohl(buf.tv_usec); 
     
    136177        delta(t_src, t_user, &stats_user); 
    137178        putchar('\n'); 
     179        block(SIG_UNBLOCK); 
    138180    } 
    139     stats_print("itf:", &stats_itf); 
    140     stats_print("app:", &stats_user); 
    141  
    142181} 
  • developers/werner/owping/tx.c

    r4764 r4775  
    4040 
    4141 
    42 void tx(struct sockaddr_in addr, int num) 
     42void tx(const struct sockaddr_in *addr, int num) 
    4343{ 
    4444    ssize_t sent; 
     
    5151    } 
    5252 
    53     if (connect(s, (const struct sockaddr *) &addr, sizeof(addr)) < 0) { 
     53    if (connect(s, (const struct sockaddr *) addr, sizeof(*addr)) < 0) { 
    5454        perror("connect"); 
    5555        exit(1); 
Note: See TracChangeset for help on using the changeset viewer.