diff --git a/ChangeLog b/ChangeLog index a069d89..135fff6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,56 @@ +2008-10-06 Rakesh Pandit + + * ping/libping.c, ping/ping_common.c, ping/ping_common.h + (ping_set_count, ping_set_sockopt, ping_set_interval): + Moved functions from libping.c to ping_common.c and made + corresponding entries in ping_common.h + + * ping/ping6.c (main): Used ping_set_interval, ping_set_sockopt, + ping_set_count in place of directly modifying struct p. + +2008-10-06 Rakesh Pandit + + * ping/ping_common.h, ping/ping.c, ping/ping_address.c, + ping/ping_echo.c, ping/ping_router.c, ping/ping_timestamp.c, + ping/libping.c: Added common headers from ping related + files (ping.c, ping_address.c, ping_echo.c, ping_router.c, + ping_timestamp.c, libping.c) and ping6.c to ping/ping_common.h. + + * ping/ping.h, ping/ping6.h, ping/ping_common.h (ping_data, + ping_efp): Moved ping_data, ping_efp from ping.h & ping6.h + to ping_common.h + + * ping/libping.c, ping/ping6.c, ping/ping_common.c (_ping_setbuf, + ping_set_data): Moved _ping_setbuf and ping_set_data from libping.c + & ping6.c to ping_common.c + + * ping/ping_common.h (ping_address, event, ping_data): Introduced new + unions ping_address and event in ping_common.h. Replaced ping efp + handler(ping_efp/ping_efp6) with event union and socket address(sockaddr_in/ + sockaddr_in6) with ping_address union. + + * ping/ping_common.h (_PING_BUFLEN, _ping_setbuf, ping_set_data): New arg + use_ipv6 and all callers changed. + +2008-10-06 Rakesh Pandit + + * libicmp/Makefile.am (libicmp_a_SOURCES): Removed libping.c + and ping.h + + * ping/Makefile.am (ping_SOURCES): Added libping.c and ping.h + +2008-10-06 Rakesh Pandit + + * ping/ping6.c (is_root, count, interval, socket_type): + New global variables count, interval & socket_type, similar to ping.c + Initialize to is_root and count to false and DEFAULT_PING_COUNT + respectively. + + * ping/ping6.c (parse_opt): Replaced ping structure usage with global + variables. + + * ping/ping6.c (main): Assigned parsed values to ping structure. + 2008-10-05 Debarshi Ray * libroute/route_linux.c (linux_conv_addr_to_name, linux_modify, diff --git a/libicmp/Makefile.am b/libicmp/Makefile.am index f4fdb5d..a0f4c08 100644 --- a/libicmp/Makefile.am +++ b/libicmp/Makefile.am @@ -18,10 +18,9 @@ noinst_LIBRARIES = libicmp.a -libicmp_a_SOURCES = libping.c \ - icmp_echo.c \ +libicmp_a_SOURCES = icmp_echo.c \ icmp_timestamp.c \ icmp_address.c \ icmp_cksum.c -noinst_HEADERS = icmp.h ping.h +noinst_HEADERS = icmp.h diff --git a/libicmp/libping.c b/libicmp/libping.c deleted file mode 100644 index 5d817d3..0000000 --- a/libicmp/libping.c +++ /dev/null @@ -1,365 +0,0 @@ -/* Copyright (C) 1998, 2001, 2005, 2007 Free Software Foundation, Inc. - - This file is part of Netutils. - - Netutils is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - Netutils is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Netutils; see the file COPYING. If not, write - to the Free Software Foundation, Inc., 51 Franklin Street, - Fifth Floor, Boston, MA 02110-1301 USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include -/*#include -- deliberately not including this */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ping.h" - -static void _ping_freebuf (PING * p); -static int _ping_setbuf (PING * p); -static size_t _ping_packetsize (PING * p); - -size_t -_ping_packetsize (PING * p) -{ - if (p->ping_type == ICMP_TIMESTAMP || p->ping_type == ICMP_TIMESTAMPREPLY) - return 20; - return 8 + p->ping_datalen; -} - -PING * -ping_init (int type, int ident) -{ - int fd; - struct protoent *proto; - PING *p; - - /* Initialize raw ICMP socket */ - proto = getprotobyname ("icmp"); - if (!proto) - { - fprintf (stderr, "ping: unknown protocol icmp.\n"); - return NULL; - } - - fd = socket (AF_INET, SOCK_RAW, proto->p_proto); - if (fd < 0) - { - if (errno == EPERM) - fprintf (stderr, "ping: ping must run as root\n"); - return NULL; - } - - /* Allocate PING structure and initialize it to default values */ - p = malloc (sizeof (*p)); - if (!p) - { - close (fd); - return p; - } - - memset (p, 0, sizeof (*p)); - - p->ping_fd = fd; - p->ping_type = type; - p->ping_count = 0; - p->ping_interval = PING_DEFAULT_INTERVAL; - p->ping_datalen = sizeof (icmphdr_t); - /* Make sure we use only 16 bits in this field, id for icmp is a u_short. */ - p->ping_ident = ident & 0xFFFF; - p->ping_cktab_size = PING_CKTABSIZE; - return p; -} - -void -ping_reset (PING * p) -{ - p->ping_num_xmit = 0; - p->ping_num_recv = 0; - p->ping_num_rept = 0; -} - -void -ping_set_type (PING * p, int type) -{ - p->ping_type = type; -} - -void -ping_set_datalen (PING * p, size_t len) -{ - _ping_freebuf (p); - p->ping_datalen = len; -} - -void -_ping_freebuf (PING * p) -{ - if (p->ping_buffer) - { - free (p->ping_buffer); - p->ping_buffer = NULL; - } - if (p->ping_cktab) - { - free (p->ping_cktab); - p->ping_cktab = NULL; - } -} - -int -_ping_setbuf (PING * p) -{ - if (!p->ping_buffer) - { - p->ping_buffer = malloc (_PING_BUFLEN (p)); - if (!p->ping_buffer) - return -1; - } - if (!p->ping_cktab) - { - p->ping_cktab = malloc (p->ping_cktab_size); - if (!p->ping_cktab) - return -1; - memset (p->ping_cktab, 0, p->ping_cktab_size); - } - return 0; -} - -int -ping_set_data (PING * p, void *data, size_t off, size_t len) -{ - icmphdr_t *icmp; - - if (_ping_setbuf (p)) - return -1; - if (p->ping_datalen < off + len) - return -1; - icmp = (icmphdr_t *) p->ping_buffer; - memcpy (icmp->icmp_data + off, data, len); - return 0; -} - -void -ping_unset_data (PING * p) -{ - _ping_freebuf (p); -} - -int -ping_xmit (PING * p) -{ - int i, buflen; - - if (_ping_setbuf (p)) - return -1; - - buflen = _ping_packetsize (p); - - /* Mark sequence number as sent */ - _PING_CLR (p, p->ping_num_xmit % p->ping_cktab_size); - - /* Encode ICMP header */ - switch (p->ping_type) - { - case ICMP_ECHO: - icmp_echo_encode (p->ping_buffer, buflen, p->ping_ident, - p->ping_num_xmit); - break; - - case ICMP_TIMESTAMP: - icmp_timestamp_encode (p->ping_buffer, buflen, p->ping_ident, - p->ping_num_xmit); - break; - - case ICMP_ADDRESS: - icmp_address_encode (p->ping_buffer, buflen, p->ping_ident, - p->ping_num_xmit); - break; - - default: - icmp_generic_encode (p->ping_buffer, buflen, p->ping_type, - p->ping_ident, p->ping_num_xmit); - break; - } - - i = sendto (p->ping_fd, (char *) p->ping_buffer, buflen, 0, - (struct sockaddr *) &p->ping_dest, sizeof (struct sockaddr_in)); - if (i < 0) - perror ("ping: sendto"); - else - { - p->ping_num_xmit++; - if (i != buflen) - printf ("ping: wrote %s %d chars, ret=%d\n", - p->ping_hostname, buflen, i); - } - return 0; -} - -static int -my_echo_reply (PING * p, icmphdr_t * icmp) -{ - struct ip *orig_ip = &icmp->icmp_ip; - icmphdr_t *orig_icmp = (icmphdr_t *) (orig_ip + 1); - - return (orig_ip->ip_dst.s_addr == p->ping_dest.sin_addr.s_addr - && orig_ip->ip_p == IPPROTO_ICMP - && orig_icmp->icmp_type == ICMP_ECHO - && orig_icmp->icmp_id == p->ping_ident); -} - -int -ping_recv (PING * p) -{ - int fromlen = sizeof (p->ping_from); - int n, rc; - icmphdr_t *icmp; - struct ip *ip; - int dupflag; - - n = recvfrom (p->ping_fd, - (char *) p->ping_buffer, _PING_BUFLEN (p), 0, - (struct sockaddr *) &p->ping_from, &fromlen); - if (n < 0) - return -1; - - rc = icmp_generic_decode (p->ping_buffer, n, &ip, &icmp); - if (rc < 0) - { - /*FIXME: conditional */ - fprintf (stderr, "packet too short (%d bytes) from %s\n", n, - inet_ntoa (p->ping_from.sin_addr)); - return -1; - } - - switch (icmp->icmp_type) - { - case ICMP_ECHOREPLY: - case ICMP_TIMESTAMPREPLY: - case ICMP_ADDRESSREPLY: - /* case ICMP_ROUTERADV: */ - - if (icmp->icmp_id != p->ping_ident) - return -1; - - if (rc) - fprintf (stderr, "checksum mismatch from %s\n", - inet_ntoa (p->ping_from.sin_addr)); - - p->ping_num_recv++; - if (_PING_TST (p, icmp->icmp_seq % p->ping_cktab_size)) - { - p->ping_num_rept++; - p->ping_num_recv--; - dupflag = 1; - } - else - { - _PING_SET (p, icmp->icmp_seq % p->ping_cktab_size); - dupflag = 0; - } - - if (p->ping_event) - (*p->ping_event) (dupflag ? PEV_DUPLICATE : PEV_RESPONSE, - p->ping_closure, - &p->ping_dest, &p->ping_from, ip, icmp, n); - break; - - case ICMP_ECHO: - case ICMP_TIMESTAMP: - case ICMP_ADDRESS: - return -1; - - default: - if (!my_echo_reply (p, icmp)) - return -1; - - if (p->ping_event) - (*p->ping_event) (PEV_NOECHO, - p->ping_closure, - &p->ping_dest, &p->ping_from, ip, icmp, n); - } - return 0; -} - -void -ping_set_event_handler (PING * ping, ping_efp pf, void *closure) -{ - ping->ping_event = pf; - ping->ping_closure = closure; -} - -void -ping_set_count (PING * ping, size_t count) -{ - ping->ping_count = count; -} - -void -ping_set_sockopt (PING * ping, int opt, void *val, int valsize) -{ - setsockopt (ping->ping_fd, SOL_SOCKET, opt, (char *) &val, valsize); -} - -void -ping_set_interval (PING * ping, size_t interval) -{ - ping->ping_interval = interval; -} - -void -ping_set_packetsize (PING * ping, size_t size) -{ - ping->ping_datalen = size; -} - -int -ping_set_dest (PING * ping, char *host) -{ - struct sockaddr_in *s_in = &ping->ping_dest; - s_in->sin_family = AF_INET; - if (inet_aton (host, &s_in->sin_addr)) - ping->ping_hostname = strdup (host); - else - { - struct hostent *hp = gethostbyname (host); - if (!hp) - return 1; - - s_in->sin_family = hp->h_addrtype; - if (hp->h_length > (int) sizeof (s_in->sin_addr)) - hp->h_length = sizeof (s_in->sin_addr); - - memcpy (&s_in->sin_addr, hp->h_addr, hp->h_length); - ping->ping_hostname = strdup (hp->h_name); - } - return 0; -} diff --git a/libicmp/ping.h b/libicmp/ping.h deleted file mode 100644 index 448908b..0000000 --- a/libicmp/ping.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (C) 1998, 2007 Free Software Foundation, Inc. - - This file is part of Netutils. - - Netutils is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - Netutils is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Netutils; see the file COPYING. If not, write - to the Free Software Foundation, Inc., 51 Franklin Street, - Fifth Floor, Boston, MA 02110-1301 USA. */ - -typedef struct ping_data PING; -typedef int (*ping_efp) (int code, - void *closure, - struct sockaddr_in * dest, - struct sockaddr_in * from, - struct ip * ip, icmphdr_t * icmp, int datalen); - - -struct ping_data -{ - int ping_fd; /* Raw socket descriptor */ - int ping_type; /* Type of packets to send */ - size_t ping_count; /* Number of packets to send */ - size_t ping_interval; /* Number of seconds to wait between sending pkts */ - struct sockaddr_in ping_dest; /* whom to ping */ - char *ping_hostname; /* Printable hostname */ - size_t ping_datalen; /* Length of data */ - int ping_ident; /* Our identifier */ - - ping_efp ping_event; /* User-defined handler */ - void *ping_closure; /* User-defined data */ - - /* Runtime info */ - int ping_cktab_size; - char *ping_cktab; - - u_char *ping_buffer; /* I/O buffer */ - struct sockaddr_in ping_from; - long ping_num_xmit; /* Number of packets transmitted */ - long ping_num_recv; /* Number of packets received */ - long ping_num_rept; /* Number of duplicates received */ -}; - -#define PEV_RESPONSE 0 -#define PEV_DUPLICATE 1 -#define PEV_NOECHO 2 - -#define PING_DEFAULT_INTERVAL 1000 /* Milliseconds */ -#define PING_PRECISION 1000 /* Millisecond precision */ -#define PING_CKTABSIZE 128 -#define PING_SET_INTERVAL(t,i) do {\ - (t).tv_sec = (i)/PING_PRECISION;\ - (t).tv_usec = ((i)%PING_PRECISION)*(1000000/PING_PRECISION) ;\ -} while (0) - -#define _PING_BUFLEN(p) ((p)->ping_datalen + sizeof (icmphdr_t)) - -#define _C_BIT(p,bit) (p)->ping_cktab[(bit)>>3] /* byte in ck array */ -#define _C_MASK(bit) (1 << ((bit) & 0x07)) - -#define _PING_SET(p,bit) (_C_BIT (p,bit) |= _C_MASK (bit)) -#define _PING_CLR(p,bit) (_C_BIT (p,bit) &= (~_C_MASK (bit))) -#define _PING_TST(p,bit) (_C_BIT (p,bit) & _C_MASK (bit)) - -PING *ping_init (int type, int ident); -void ping_reset (PING * p); -void ping_set_type (PING * p, int type); -void ping_set_count (PING * ping, size_t count); -void ping_set_sockopt (PING * ping, int opt, void *val, int valsize); -void ping_set_interval (PING * ping, size_t interval); -void ping_set_packetsize (PING * ping, size_t size); -int ping_set_dest (PING * ping, char *host); -int ping_set_pattern (PING * p, int len, u_char * pat); -void ping_set_event_handler (PING * ping, ping_efp fp, void *closure); -int ping_set_data (PING * p, void *data, size_t off, size_t len); -void ping_set_datalen (PING * p, size_t len); -void ping_unset_data (PING * p); -int ping_recv (PING * p); -int ping_xmit (PING * p); diff --git a/ping/Makefile.am b/ping/Makefile.am index 7789599..c4e0c7a 100644 --- a/ping/Makefile.am +++ b/ping/Makefile.am @@ -29,7 +29,7 @@ INCLUDES = -I$(top_srcdir)/lib -I../lib -I$(top_srcdir)/libicmp \ -I$(top_srcdir)/libinetutils ping_SOURCES = ping.c ping_common.c ping_echo.c ping_address.c \ - ping_router.c ping_timestamp.c ping_common.h ping_impl.h + ping_router.c ping_timestamp.c ping_common.h ping_impl.h ping.h libping.c ping6_SOURCES = ping6.c ping_common.c ping_common.h ping6.h SUIDMODE = -o root -m 4775 diff --git a/ping/ping.c b/ping/ping.c index 105c2f8..3c4582f 100644 --- a/ping/ping.c +++ b/ping/ping.c @@ -28,9 +28,6 @@ #include #include -#include -#include -#include /*#include -- deliberately not including this */ #ifdef HAVE_NETINET_IP_VAR_H # include @@ -48,9 +45,7 @@ #include #include -#include #include -#include "ping_common.h" #include "ping_impl.h" #include "libinetutils.h" @@ -412,13 +407,13 @@ send_echo (PING * ping) { struct timeval tv; gettimeofday (&tv, NULL); - ping_set_data (ping, &tv, 0, sizeof (tv)); + ping_set_data (ping, &tv, 0, sizeof (tv), USE_IPV6); off += sizeof (tv); } if (data_buffer) ping_set_data (ping, data_buffer, off, data_length > PING_HEADER_LEN ? - data_length - PING_HEADER_LEN : data_length); + data_length - PING_HEADER_LEN : data_length, USE_IPV6); return ping_xmit (ping); } diff --git a/ping/ping6.c b/ping/ping6.c index bb4ae16..6217bdb 100644 --- a/ping/ping6.c +++ b/ping/ping6.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -42,17 +41,19 @@ #include #include -#include "ping_common.h" #include "ping6.h" #include "libinetutils.h" static PING *ping; -bool is_root; +bool is_root = false; unsigned char *data_buffer; u_char *patptr; int one = 1; int pattern_len = 16; size_t data_length = PING_DATALEN; +size_t count = DEFAULT_PING_COUNT; +size_t interval; +int socket_type; static unsigned int options; static unsigned long preload = 0; @@ -96,15 +97,16 @@ parse_opt (int key, char *arg, struct argp_state *state) { char *endptr; u_char pattern[16]; + double v; switch (key) { case 'c': - ping->ping_count = ping_cvt_number (arg, 0, 0); + count = ping_cvt_number (arg, 0, 0); break; case 'd': - setsockopt (ping->ping_fd, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)); + socket_type = SO_DEBUG; break; case 'f': @@ -117,7 +119,7 @@ parse_opt (int key, char *arg, struct argp_state *state) case 'i': options |= OPT_INTERVAL; - ping->ping_interval = ping_cvt_number (arg, 0, 0); + interval = ping_cvt_number (arg, 0, 0); break; case 'l': @@ -144,7 +146,7 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case 'r': - setsockopt (ping->ping_fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof (one)); + socket_type = SO_DEBUG; break; case 's': @@ -188,6 +190,16 @@ main (int argc, char **argv) argc -= index; argv += index; + if (count != 0) + ping_set_count (ping, count); + + if (socket_type != 0) + ping_set_sockopt (ping, socket_type, &one, sizeof (one)); + + if (options & OPT_INTERVAL) + ping_set_interval (ping, interval); + + init_data_buffer (patptr, pattern_len); while (argc--) @@ -356,13 +368,13 @@ send_echo (PING * ping) { struct timeval tv; gettimeofday (&tv, NULL); - ping_set_data (ping, &tv, 0, sizeof (tv)); + ping_set_data (ping, &tv, 0, sizeof (tv), USE_IPV6); off += sizeof (tv); } if (data_buffer) ping_set_data (ping, data_buffer, off, data_length > PING_HEADER_LEN ? - data_length - PING_HEADER_LEN : data_length); + data_length - PING_HEADER_LEN : data_length, USE_IPV6); return ping_xmit (ping); } @@ -417,8 +429,8 @@ ping_echo (char *hostname) if (ping_set_dest (ping, hostname)) error (EXIT_FAILURE, 0, "unknown host %s", hostname); - err = getnameinfo ((struct sockaddr *) &ping->ping_dest, - sizeof (ping->ping_dest), buffer, + err = getnameinfo ((struct sockaddr *) &ping->ping_dest.ping_sockaddr6, + sizeof (ping->ping_dest.ping_sockaddr6), buffer, sizeof (buffer), NULL, 0, NI_NUMERICHOST); if (err) { @@ -729,43 +741,12 @@ ping_init (int type, int ident) } static int -_ping_setbuf (PING * p) -{ - if (!p->ping_buffer) - { - p->ping_buffer = malloc (_PING_BUFLEN (p)); - if (!p->ping_buffer) - return -1; - } - if (!p->ping_cktab) - { - p->ping_cktab = malloc (p->ping_cktab_size); - if (!p->ping_cktab) - return -1; - memset (p->ping_cktab, 0, p->ping_cktab_size); - } - return 0; -} - -static int -ping_set_data (PING * p, void *data, size_t off, size_t len) -{ - if (_ping_setbuf (p)) - return -1; - if (p->ping_datalen < off + len) - return -1; - memcpy (p->ping_buffer + sizeof (struct icmp6_hdr) + off, data, len); - - return 0; -} - -static int ping_xmit (PING * p) { int i, buflen; struct icmp6_hdr *icmp6; - if (_ping_setbuf (p)) + if (_ping_setbuf (p, USE_IPV6)) return -1; buflen = p->ping_datalen + sizeof (struct icmp6_hdr); @@ -782,7 +763,7 @@ ping_xmit (PING * p) icmp6->icmp6_seq = htons (p->ping_num_xmit); i = sendto (p->ping_fd, (char *) p->ping_buffer, buflen, 0, - (struct sockaddr *) &p->ping_dest, sizeof (p->ping_dest)); + (struct sockaddr *) &p->ping_dest, sizeof (p->ping_dest.ping_sockaddr6)); if (i < 0) perror ("ping: sendto"); else @@ -802,7 +783,7 @@ my_echo_reply (PING * p, struct icmp6_hdr *icmp6) struct ip6_hdr *orig_ip = (struct ip6_hdr *) (icmp6 + 1); struct icmp6_hdr *orig_icmp = (struct icmp6_hdr *) (orig_ip + 1); - return IN6_ARE_ADDR_EQUAL (&orig_ip->ip6_dst, &ping->ping_dest.sin6_addr) + return IN6_ARE_ADDR_EQUAL (&orig_ip->ip6_dst, &ping->ping_dest.ping_sockaddr6.sin6_addr) && orig_ip->ip6_nxt == IPPROTO_ICMPV6 && orig_icmp->icmp6_type == ICMP6_ECHO_REQUEST && orig_icmp->icmp6_id == htons (p->ping_ident); @@ -820,9 +801,9 @@ ping_recv (PING * p) char cmsg_data[1024]; iov.iov_base = p->ping_buffer; - iov.iov_len = _PING_BUFLEN (p); - msg.msg_name = &p->ping_from; - msg.msg_namelen = sizeof (p->ping_from); + iov.iov_len = _PING_BUFLEN (p, USE_IPV6); + msg.msg_name = &p->ping_from.ping_sockaddr6; + msg.msg_namelen = sizeof (p->ping_from.ping_sockaddr6); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = cmsg_data; @@ -863,8 +844,8 @@ ping_recv (PING * p) dupflag = 0; } - print_echo (dupflag, hops, p->ping_closure, &p->ping_dest, - &p->ping_from, icmp6, n); + print_echo (dupflag, hops, p->ping_closure, &p->ping_dest.ping_sockaddr6, + &p->ping_from.ping_sockaddr6, icmp6, n); } else @@ -873,7 +854,7 @@ ping_recv (PING * p) if (!my_echo_reply (p, icmp6)) return -1; /* It's not for us. */ - print_icmp_error (&p->ping_from, icmp6, n); + print_icmp_error (&p->ping_from.ping_sockaddr6, icmp6, n); } return 0; @@ -893,7 +874,7 @@ ping_set_dest (PING * ping, char *host) if (err) return 1; - memcpy (&ping->ping_dest, result->ai_addr, result->ai_addrlen); + memcpy (&ping->ping_dest.ping_sockaddr6, result->ai_addr, result->ai_addrlen); freeaddrinfo (result); diff --git a/ping/ping6.h b/ping/ping6.h index e69ab23..13e761a 100644 --- a/ping/ping6.h +++ b/ping/ping6.h @@ -17,39 +17,7 @@ to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include -#include - -typedef struct ping_data PING; -typedef int (*ping_efp) (int code, void *closure, struct sockaddr_in6 * dest, - struct sockaddr_in6 * from, struct icmp6_hdr * icmp, - int datalen); - - -struct ping_data -{ - int ping_fd; /* Raw socket descriptor */ - int ping_type; /* Type of packets to send */ - int ping_count; /* Number of packets to send */ - int ping_interval; /* Number of seconds to wait between sending pkts */ - struct sockaddr_in6 ping_dest; /* whom to ping */ - char *ping_hostname; /* Printable hostname */ - size_t ping_datalen; /* Length of data */ - int ping_ident; /* Our identifier */ - - ping_efp ping_event; /* User-defined handler */ - void *ping_closure; /* User-defined data */ - - /* Runtime info */ - int ping_cktab_size; - char *ping_cktab; - - u_char *ping_buffer; /* I/O buffer */ - struct sockaddr_in6 ping_from; - long ping_num_xmit; /* Number of packets transmitted */ - long ping_num_recv; /* Number of packets received */ - long ping_num_rept; /* Number of duplicates received */ -}; +#include "ping_common.h" struct ping_stat { @@ -80,7 +48,7 @@ struct ping_stat #define PING_DATALEN (64 - PING_HEADER_LEN) /* default data length */ #define PING_MAX_DATALEN (65535 - sizeof (struct icmp6_hdr)) -#define _PING_BUFLEN(p) ((p)->ping_datalen + sizeof (struct icmp6_hdr)) +#define USE_IPV6 1 #define _C_BIT(p,bit) (p)->ping_cktab[(bit)>>3] /* byte in ck array */ #define _C_MASK(bit) (1 << ((bit) & 0x07)) @@ -91,7 +59,6 @@ struct ping_stat static PING *ping_init (int type, int ident); static int ping_set_dest (PING * ping, char *host); -static int ping_set_data (PING * p, void *data, size_t off, size_t len); static int ping_recv (PING * p); static int ping_xmit (PING * p); diff --git a/ping/ping_address.c b/ping/ping_address.c index 875707c..282b364 100644 --- a/ping/ping_address.c +++ b/ping/ping_address.c @@ -28,9 +28,6 @@ #include #include -#include -#include -#include /*#include -- deliberately not including this */ #ifdef HAVE_NETINET_IP_VAR_H # include @@ -45,12 +42,9 @@ #include #include -#include #include #include -#include "ping_common.h" - static int recv_address (int code, void *closure, struct sockaddr_in *dest, struct sockaddr_in *from, struct ip *ip, icmphdr_t * icmp, int datalen); @@ -74,7 +68,7 @@ ping_address (char *hostname) error (EXIT_FAILURE, 0, "unknown host"); printf ("PING %s (%s): sending address mask request\n", - ping->ping_hostname, inet_ntoa (ping->ping_dest.sin_addr)); + ping->ping_hostname, inet_ntoa (ping->ping_dest.ping_sockaddr.sin_addr)); return ping_run (ping, address_finish); } diff --git a/ping/ping_common.c b/ping/ping_common.c index c644b2a..995411d 100644 --- a/ping/ping_common.c +++ b/ping/ping_common.c @@ -137,3 +137,60 @@ nsqrt (double a, double prec) return x1; } + + +int +_ping_setbuf (PING * p, bool use_ipv6) +{ + if (!p->ping_buffer) { + p->ping_buffer = malloc (_PING_BUFLEN (p, use_ipv6)); + if (!p->ping_buffer) + return -1; + } + if (!p->ping_cktab) { + p->ping_cktab = malloc (p->ping_cktab_size); + if (!p->ping_cktab) + return -1; + memset (p->ping_cktab, 0, p->ping_cktab_size); + } + return 0; +} + +int +ping_set_data (PING * p, void *data, size_t off, size_t len, bool use_ipv6) +{ + icmphdr_t *icmp; + + if (_ping_setbuf (p, use_ipv6)) + return -1; + if (p->ping_datalen < off + len) + return -1; + + if(use_ipv6) { + icmp = (struct icmp6_hdr *) p->ping_buffer; + } else { + icmp = (icmphdr_t *) p->ping_buffer; + } + memcpy (icmp->icmp_data + off, data, len); + + return 0; +} + +void +ping_set_count (PING * ping, size_t count) +{ + ping->ping_count = count; +} + +void +ping_set_sockopt (PING * ping, int opt, void *val, int valsize) +{ + setsockopt (ping->ping_fd, SOL_SOCKET, opt, (char *) &val, valsize); +} + +void +ping_set_interval (PING * ping, size_t interval) +{ + ping->ping_interval = interval; +} + diff --git a/ping/ping_common.h b/ping/ping_common.h index 7cb16ce..e65e84b 100644 --- a/ping/ping_common.h +++ b/ping/ping_common.h @@ -17,8 +17,66 @@ to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include +#include +#include +#include +#include + +#include + #define DEFAULT_PING_COUNT 4 +/* Not sure about this step*/ +#define _PING_BUFLEN(p, use_ipv6) ((use_ipv6)? ((p)->ping_datalen + sizeof (struct icmp6_hdr)) : \ + ((p)->ping_datalen + sizeof (icmphdr_t))) + +typedef int (*ping_efp6) (int code, void *closure, struct sockaddr_in6 * dest, + struct sockaddr_in6 * from, struct icmp6_hdr * icmp, + int datalen); + +typedef int (*ping_efp) (int code, + void *closure, + struct sockaddr_in * dest, + struct sockaddr_in * from, + struct ip * ip, icmphdr_t * icmp, int datalen); + +union event { + ping_efp6 handler6; + ping_efp handler; +}; + +union ping_address { + struct sockaddr_in ping_sockaddr; + struct sockaddr_in6 ping_sockaddr6; +}; + +typedef struct ping_data PING; +struct ping_data +{ + int ping_fd; /* Raw socket descriptor */ + int ping_type; /* Type of packets to send */ + size_t ping_count; /* Number of packets to send */ + size_t ping_interval; /* Number of seconds to wait between sending pkts */ + union ping_address ping_dest; /* whom to ping */ + char *ping_hostname; /* Printable hostname */ + size_t ping_datalen; /* Length of data */ + int ping_ident; /* Our identifier */ + + union event ping_event; /* User-defined handler */ + void *ping_closure; /* User-defined data */ + + /* Runtime info */ + int ping_cktab_size; + char *ping_cktab; + + u_char *ping_buffer; /* I/O buffer */ + union ping_address ping_from; + long ping_num_xmit; /* Number of packets transmitted */ + long ping_num_recv; /* Number of packets received */ + long ping_num_rept; /* Number of duplicates received */ +}; + void tvsub (struct timeval *out, struct timeval *in); double nabs (double a); double nsqrt (double a, double prec); @@ -29,3 +87,9 @@ void init_data_buffer (unsigned char *pat, int len); void decode_pattern (const char *text, int *pattern_len, unsigned char *pattern_data); + +int _ping_setbuf (PING * p, bool use_ipv6); +int ping_set_data (PING *p, void *data, size_t off, size_t len, bool use_ipv6); +void ping_set_count (PING * ping, size_t count); +void ping_set_sockopt (PING * ping, int opt, void *val, int valsize); +void ping_set_interval (PING * ping, size_t interval); diff --git a/ping/ping_echo.c b/ping/ping_echo.c index 4f86a02..c2c25e5 100644 --- a/ping/ping_echo.c +++ b/ping/ping_echo.c @@ -27,9 +27,6 @@ #include #include -#include -#include -#include /*#include -- deliberately not including this */ #ifdef HAVE_NETINET_IP_VAR_H # include @@ -45,9 +42,7 @@ #include #include -#include #include -#include "ping_common.h" #include "ping_impl.h" #define NROUTES 9 /* number of record route slots */ @@ -109,7 +104,7 @@ ping_echo (char *hostname) printf ("PING %s (%s): %d data bytes\n", ping->ping_hostname, - inet_ntoa (ping->ping_dest.sin_addr), data_length); + inet_ntoa (ping->ping_dest.ping_sockaddr.sin_addr), data_length); status = ping_run (ping, echo_finish); free (ping->ping_hostname); @@ -375,7 +370,7 @@ print_icmp_header (struct sockaddr_in *from, orig_ip = &icmp->icmp_ip; if (!(options & OPT_VERBOSE - || orig_ip->ip_dst.s_addr == ping->ping_dest.sin_addr.s_addr)) + || orig_ip->ip_dst.s_addr == ping->ping_dest.ping_sockaddr.sin_addr.s_addr)) return; printf ("%d bytes from %s: ", len - hlen, s = ipaddr2str (from->sin_addr)); diff --git a/ping/ping_router.c b/ping/ping_router.c index 528da1f..6b496c4 100644 --- a/ping/ping_router.c +++ b/ping/ping_router.c @@ -27,9 +27,6 @@ #include #include -#include -#include -#include /*#include -- deliberately not including this */ #ifdef HAVE_NETINET_IP_VAR_H # include @@ -44,7 +41,6 @@ #include #include -#include #include #include diff --git a/ping/ping_timestamp.c b/ping/ping_timestamp.c index 3c81309..e778041 100644 --- a/ping/ping_timestamp.c +++ b/ping/ping_timestamp.c @@ -27,9 +27,6 @@ #include #include -#include -#include -#include /*#include -- deliberately not including this */ #ifdef HAVE_NETINET_IP_VAR_H # include @@ -44,12 +41,9 @@ #include #include -#include #include #include -#include "ping_common.h" - static int recv_timestamp (int code, void *closure, struct sockaddr_in *dest, struct sockaddr_in *from, struct ip *ip, icmphdr_t * icmp, int datalen); @@ -70,7 +64,7 @@ ping_timestamp (char *hostname) error (EXIT_FAILURE, 0, "unknown host"); printf ("PING %s (%s): sending timestamp requests\n", - ping->ping_hostname, inet_ntoa (ping->ping_dest.sin_addr)); + ping->ping_hostname, inet_ntoa (ping->ping_dest.ping_sockaddr.sin_addr)); return ping_run (ping, timestamp_finish); }