diff --git a/ChangeLog b/ChangeLog
index a069d89..135fff6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2008-10-06  Rakesh Pandit  <rakesh.pandit@gmail.com>
+
+	* 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  <rakesh.pandit@gmail.com>
+
+	* 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  <rakesh.pandit@gmail.com>
+
+	* 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  <rakesh.pandit@gmail.com>
+
+	* 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  <rishi@gnu.org>
 
 	* 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 <config.h>
-#endif
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <signal.h>
-
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-/*#include <netinet/ip_icmp.h> -- deliberately not including this */
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include <icmp.h>
-#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 <sys/time.h>
 #include <signal.h>
 
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
 /*#include <netinet/ip_icmp.h>  -- deliberately not including this */
 #ifdef HAVE_NETINET_IP_VAR_H
 # include <netinet/ip_var.h>
@@ -48,9 +45,7 @@
 #include <limits.h>
 
 #include <argp.h>
-#include <icmp.h>
 #include <ping.h>
-#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 <netdb.h>
 #include <unistd.h>
 #include <stdlib.h>
-#include <stdbool.h>
 #include <string.h>
 #include <stdio.h>
 #include <argp.h>
@@ -42,17 +41,19 @@
 #include <limits.h>
 
 #include <xalloc.h>
-#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 <netinet/in.h>
-#include <netinet/icmp6.h>
-
-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 <sys/time.h>
 #include <signal.h>
 
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
 /*#include <netinet/ip_icmp.h>  -- deliberately not including this */
 #ifdef HAVE_NETINET_IP_VAR_H
 # include <netinet/ip_var.h>
@@ -45,12 +42,9 @@
 #include <ctype.h>
 #include <errno.h>
 
-#include <icmp.h>
 #include <ping.h>
 #include <ping_impl.h>
 
-#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 <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/icmp6.h>
+#include <icmp.h>
+
+#include <stdbool.h>
+
 #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 <sys/time.h>
 #include <signal.h>
 
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
 /*#include <netinet/ip_icmp.h>  -- deliberately not including this */
 #ifdef HAVE_NETINET_IP_VAR_H
 # include <netinet/ip_var.h>
@@ -45,9 +42,7 @@
 #include <errno.h>
 #include <limits.h>
 
-#include <icmp.h>
 #include <ping.h>
-#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 <sys/time.h>
 #include <signal.h>
 
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
 /*#include <netinet/ip_icmp.h>  -- deliberately not including this */
 #ifdef HAVE_NETINET_IP_VAR_H
 # include <netinet/ip_var.h>
@@ -44,7 +41,6 @@
 #include <ctype.h>
 #include <errno.h>
 
-#include <icmp.h>
 #include <ping.h>
 #include <ping_impl.h>
 
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 <sys/time.h>
 #include <signal.h>
 
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
 /*#include <netinet/ip_icmp.h>  -- deliberately not including this */
 #ifdef HAVE_NETINET_IP_VAR_H
 # include <netinet/ip_var.h>
@@ -44,12 +41,9 @@
 #include <ctype.h>
 #include <errno.h>
 
-#include <icmp.h>
 #include <ping.h>
 #include <ping_impl.h>
 
-#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);
 }
