diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/attrs.h iptraf-2.7.0/src/attrs.h
--- iptraf-2.7.0.orig/src/attrs.h	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/attrs.h	2005-07-18 19:03:48.000000000 -0400
@@ -28,3 +28,8 @@
 extern int ARPATTR;
 extern int GREATTR;
 extern int UNKNATTR;
+
+#ifdef USE_IPV6
+extern int IPV6ATTR;
+extern int ICMPV6ATTR;
+#endif
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/deskman.c iptraf-2.7.0/src/deskman.c
--- iptraf-2.7.0.orig/src/deskman.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/deskman.c	2005-07-18 19:03:48.000000000 -0400
@@ -56,6 +56,11 @@
 int ARPATTR;
 int UNKNATTR;
 
+#ifdef USE_IPV6
+int IPV6ATTR;
+int ICMPV6ATTR;
+#endif
+
 
 /*  draw the basic desktop common to my screen-oriented programs */
 
@@ -88,7 +93,12 @@
     PANEL *panel;
     int ch;
 
+#ifdef USE_IPV6
+    win = newwin(17, 52, (LINES - 17) / 2, (COLS - 52) / 2);
+#else
     win = newwin(15, 50, (LINES - 15) / 2, (COLS - 50) / 2);
+#endif
+
     panel = new_panel(win);
 
     tx_stdwinset(win);
@@ -105,10 +115,18 @@
     mvwprintw(win, 8, 2, "This program is open-source software released");
     mvwprintw(win, 9, 2, "under the terms of the GNU General Public");
     mvwprintw(win, 10, 2, "Public License Version 2 or any later version.");
+#ifdef USE_IPV6
+    mvwprintw(win, 13, 2, "IPv6 support by Guy Martin <gmsoft@tuxicoman.be>");
+#endif
     mvwprintw(win, 11, 2, "See the included LICENSE file for details.");
 
     wattrset(win, HIGHATTR);
+
+#ifdef USE_IPV6
+    mvwprintw(win, 15, 2, ANYKEY_MSG);
+#else
     mvwprintw(win, 13, 2, ANYKEY_MSG);
+#endif
 
     update_panels();
     doupdate();
@@ -220,6 +238,9 @@
 	init_pair(16, COLOR_WHITE, COLOR_CYAN);
 	init_pair(17, COLOR_YELLOW, COLOR_CYAN);
         init_pair(18, COLOR_GREEN, COLOR_BLACK);
+#ifdef USE_IPV6
+	init_pair(19, COLOR_WHITE, COLOR_BLUE);
+#endif
         
 	STDATTR = COLOR_PAIR(14) | A_BOLD;
 	HIGHATTR = COLOR_PAIR(3) | A_BOLD;
@@ -247,6 +268,10 @@
 	IGRPATTR = COLOR_PAIR(16) | A_BOLD;
 	ARPATTR = COLOR_PAIR(5) | A_BOLD;
 	GREATTR = COLOR_PAIR(1);
+#ifdef USE_IPV6
+	ICMPV6ATTR = COLOR_PAIR(19) | A_BOLD;
+	IPV6ATTR = COLOR_PAIR(19);
+#endif
 	UNKNATTR = COLOR_PAIR(4) | A_BOLD;
     } else {
 	STDATTR = A_REVERSE;
@@ -275,6 +300,9 @@
 	IGRPATTR = A_REVERSE;
 	ARPATTR = A_BOLD;
 	GREATTR = A_BOLD;
+#ifdef USE_IPV6
+	ICMPV6ATTR = A_REVERSE;
+#endif
 	UNKNATTR = A_BOLD;
     }
     
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/ifstats.c iptraf-2.7.0/src/ifstats.c
--- iptraf-2.7.0.orig/src/ifstats.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/ifstats.c	2005-07-18 19:08:32.000000000 -0400
@@ -34,6 +34,9 @@
 #include <linux/if_packet.h>
 #include <net/if.h>
 #include <netinet/ip.h>
+#ifdef USE_IPV6
+# include <netinet/ip6.h>
+#endif
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 #include <linux/if_ether.h>
@@ -252,7 +255,11 @@
 
     wattrset(table->statwin, HIGHATTR);
     do {
+#ifdef USE_IPV6
+	wmove(table->statwin, ptmp->index - idx, 60 * COLS / 80);
+#else
 	wmove(table->statwin, ptmp->index - idx, 52 * COLS / 80);
+#endif
 	if (unit == KBITS) {
 	    ptmp->rate =
 		((float) (ptmp->spanbr * 8 / 1000)) /
@@ -286,13 +293,31 @@
     wmove(win, target_row, 1);
     wprintw(win, "%s", ptmp->ifname);
     wattrset(win, HIGHATTR);
+#ifdef USE_IPV6
+    wmove(win, target_row, 9  * COLS / 80);
+#else
     wmove(win, target_row, 12 * COLS / 80);
+#endif
     printlargenum(ptmp->total, win);
+#ifdef USE_IPV6
+    wmove(win, target_row, 19 * COLS / 80);
+#else
     wmove(win, target_row, 22 * COLS / 80);
+#endif
     printlargenum(ptmp->iptotal, win);
+#ifdef USE_IPV6
+    wmove(win, target_row, 29 * COLS / 80);
+    printlargenum(ptmp->ip6total, win);
+    wmove(win, target_row, 39 * COLS / 80);
+#else
     wmove(win, target_row, 32 * COLS / 80);
+#endif
     printlargenum(ptmp->noniptotal, win);
+#ifdef USE_IPV6
+    wmove(win, target_row, 29 * COLS / 80);
+#else
     wmove(win, target_row, 42 * COLS / 80);
+#endif
     wprintw(win, "%8lu", ptmp->badtotal);
 }
 
@@ -320,15 +345,35 @@
 {
     wmove(win, 0, 1);
     wprintw(win, " Iface ");
+#ifdef USE_IPV6
+    wmove(win, 0, 12 * COLS / 80);
+#else
     wmove(win, 0, 16 * COLS / 80);
+#endif
     wprintw(win, " Total ");
+#ifdef USE_IPV6
+    wmove(win, 0, 22 * COLS / 80);
+    wprintw(win, " IPv4 ");
+    wmove(win, 0, 32 * COLS / 80);
+    wprintw(win, " IPv6 ");
+    wmove(win, 0, 42 * COLS / 80);
+#else
     wmove(win, 0, 29 * COLS / 80);
+#endif
     wprintw(win, " IP ");
     wmove(win, 0, 36 * COLS / 80);
     wprintw(win, " NonIP ");
+#ifdef USE_IPV6
+    wmove(win, 0, 51 * COLS / 80);
+#else
     wmove(win, 0, 45 * COLS / 80);
+#endif
     wprintw(win, " BadIP ");
+#ifdef USE_IPV6
+    wmove(win, 0, 65 * COLS / 80);
+#else
     wmove(win, 0, 55 * COLS / 80);
+#endif
     wprintw(win, " Activity ");
 }
 
@@ -422,6 +467,10 @@
     char *packet;
     int pkt_result = 0;
 
+#ifdef USE_IPV6
+    unsigned int iphlen;
+#endif
+
     struct sockaddr_ll fromaddr;
     unsigned short linktype;
     
@@ -557,6 +606,20 @@
 
 		if (pkt_result == INVALID_PACKET)
 		    continue;
+
+#ifdef USE_IPV6
+                if ((options->v6inv4asv6) && (fromaddr.sll_protocol == ETH_P_IP)
+                   && ((struct iphdr *) packet)->protocol == IPPROTO_IPV6 ) {
+                       iphlen = ((struct iphdr *) packet)->ihl * 4;
+                       fromaddr.sll_protocol = htons(ETH_P_IPV6);
+                       memmove(buf, buf + iphlen, MAX_PACKET_SIZE - iphlen);
+                       // Reprocess the IPv6 packet
+                       pkt_result = processpacket(buf, &packet, &br, NULL, &sport, &dport,
+                           &fromaddr, &linktype, ofilter, ifname, NULL);
+                       if (pkt_result == INVALID_PACKET)
+                           continue;
+               }
+#endif
 		
 		positionptr(&table, &ptmp, ifname);
 
@@ -572,6 +635,10 @@
 			(ptmp->badtotal)++;
 			continue;
 	            }
+#ifdef USE_IPV6
+		} else if (fromaddr.sll_protocol == ETH_P_IPV6) {
+		    ptmp->ip6total++;
+#endif
 		} else {
 		    (ptmp->noniptotal)++;
 		}
@@ -650,6 +717,22 @@
 	      "Packets      Bytes     Packets      Bytes     Packets      Bytes");
     wattrset(win, STDATTR);
     mvwprintw(win, 4, 2, "Total:");
+#ifdef USE_IPV6
+    mvwprintw(win, 5, 2, "IPv4:");
+    mvwprintw(win, 6, 2, "IPv6:");
+    mvwprintw(win, 7, 2, "TCP:");
+    mvwprintw(win, 8, 2, "UDP:");
+    mvwprintw(win, 9, 2, "ICMP:");
+    mvwprintw(win, 10, 2, "Other IP:");
+    mvwprintw(win, 11, 2, "Non-IP:");
+    mvwprintw(win, 14, 2, "Total rates:");
+    mvwprintw(win, 17, 2, "Incoming rates:");
+    mvwprintw(win, 20, 2, "Outgoing rates:");
+
+    mvwprintw(win, 14, 45, "Broadcast packets:");
+    mvwprintw(win, 15, 45, "Broadcast bytes:");
+    mvwprintw(win, 19, 45, "IP checksum errors:");
+#else
     mvwprintw(win, 5, 2, "IP:");
     mvwprintw(win, 6, 2, "TCP:");
     mvwprintw(win, 7, 2, "UDP:");
@@ -663,6 +746,7 @@
     mvwprintw(win, 13, 45, "Broadcast packets:");
     mvwprintw(win, 14, 45, "Broadcast bytes:");
     mvwprintw(win, 18, 45, "IP checksum errors:");
+#endif
 
     update_panels();
     doupdate();
@@ -703,38 +787,87 @@
 		 totals->iptotal_in, totals->ipbtotal_in,
 		 totals->iptotal_out, totals->ipbtotal_out);
 
+/*#ifdef USE_IPV6*/
+/*    printstatrow(win, 6, totals->ip6total, totals->ip6btotal,*/
+/*                totals->ip6total_in, totals->ip6btotal_in,*/
+/*                totals->ip6total_out, totals->ip6btotal_out);*/
+/*    printstatrow(win, 7, totals->tcptotal, totals->tcpbtotal,*/
+/*#else*/
+/*    printstatrow(win, 6, totals->tcptotal, totals->tcpbtotal,*/
+/*                 totals->tcptotal_in, totals->tcpbtotal_in,*/
+/*                 totals->tcptotal_out, totals->tcpbtotal_out);*/
+/*    printstatrow(win, 7, totals->udptotal, totals->udpbtotal,*/
+/*#endif*/
+
+
+#ifdef USE_IPV6
+    printstatrow(win, 6, totals->ip6total, totals->ip6btotal,
+                totals->ip6total_in, totals->ip6btotal_in,
+                totals->ip6total_out, totals->ip6btotal_out);
+
+    printstatrow(win, 7, totals->tcptotal, totals->tcpbtotal,
+                 totals->tcptotal_in, totals->tcpbtotal_in,
+                 totals->tcptotal_out, totals->tcpbtotal_out);
+#else
     printstatrow(win, 6, totals->tcptotal, totals->tcpbtotal,
-		 totals->tcptotal_in, totals->tcpbtotal_in,
-		 totals->tcptotal_out, totals->tcpbtotal_out);
-
+                 totals->tcptotal_in, totals->tcpbtotal_in,
+                 totals->tcptotal_out, totals->tcpbtotal_out);
+#endif
+
+#ifdef USE_IPV6
+    printstatrow(win, 8, totals->udptotal, totals->udpbtotal,
+#else
     printstatrow(win, 7, totals->udptotal, totals->udpbtotal,
+#endif
 		 totals->udptotal_in, totals->udpbtotal_in,
 		 totals->udptotal_out, totals->udpbtotal_out);
 
+#ifdef USE_IPV6
+    printstatrow(win, 9, totals->icmptotal, totals->icmpbtotal,
+#else
     printstatrow(win, 8, totals->icmptotal, totals->icmpbtotal,
+#endif
 		 totals->icmptotal_in, totals->icmpbtotal_in,
 		 totals->icmptotal_out, totals->icmpbtotal_out);
 
+#ifdef USE_IPV6
+    printstatrow(win, 10, totals->othtotal, totals->othbtotal,
+#else
     printstatrow(win, 9, totals->othtotal, totals->othbtotal,
+#endif
 		 totals->othtotal_in, totals->othbtotal_in,
 		 totals->othtotal_out, totals->othbtotal_out);
 
     /* Print non-IP totals */
 
+#ifdef USE_IPV6
+    printstatrow(win, 11, totals->noniptotal, totals->nonipbtotal,
+#else
     printstatrow(win, 10, totals->noniptotal, totals->nonipbtotal,
+#endif
 		 totals->noniptotal_in, totals->nonipbtotal_in,
 		 totals->noniptotal_out, totals->nonipbtotal_out);
     
     /* Broadcast totals */
     
+#ifdef USE_IPV6
+    wmove(win, 14, 67);
+    printlargenum(totals->bcast, win);
+    wmove(win, 15, 67);
+#else
     wmove(win, 13, 67);
     printlargenum(totals->bcast, win);
     wmove(win, 14, 67);
+#endif
     printlargenum(totals->bcastbytes, win);
-    
+
     /* Bad packet count */
 
+#ifdef USE_IPV6
+    mvwprintw(win, 19, 68, "%8lu", totals->badtotal);
+#else
     mvwprintw(win, 18, 68, "%8lu", totals->badtotal);
+#endif
 }
 
 
@@ -753,6 +886,9 @@
     char buf[MAX_PACKET_SIZE];
     char *packet;
     struct iphdr *ipacket = NULL;
+#ifdef USE_IPV6
+    struct ip6_hdr *ip6packet = NULL;
+#endif
     char *tpacket;
     unsigned int iphlen;
     unsigned int sport, dport;
@@ -934,6 +1070,20 @@
             
             if (pkt_result == INVALID_PACKET)
                 continue;
+
+#ifdef USE_IPV6
+            if ((options->v6inv4asv6) && (fromaddr.sll_protocol == ETH_P_IP)
+                && ((struct iphdr *) packet)->protocol == IPPROTO_IPV6 ) {
+                    iphlen = ((struct iphdr *) packet)->ihl * 4;
+                   fromaddr.sll_protocol = htons(ETH_P_IPV6);
+                   memmove(buf, buf + iphlen, MAX_PACKET_SIZE - iphlen);
+                    // Reprocess the IPv6 packet
+                    pkt_result = processpacket(buf, &packet, &br, NULL, &sport, &dport,
+                        &fromaddr, &linktype, ofilter, ifname, NULL);
+                    if (pkt_result == INVALID_PACKET)
+                         continue;
+            }
+#endif
                                  
 	    totals.total++;
 	    totals.bytestotal += framelen;
@@ -1031,6 +1181,73 @@
 		    }
 		    break;
 		}
+#ifdef USE_IPV6
+           } else if (fromaddr.sll_protocol == ETH_P_IPV6) {
+
+                ip6packet = (struct ip6_hdr *) packet;
+                iplen = ntohs(ip6packet->ip6_plen);
+
+                totals.ip6total++;
+                totals.ip6btotal += iplen;
+
+                if (fromaddr.sll_pkttype == PACKET_OUTGOING) {
+                    totals.ip6total_out++;
+                    totals.ip6btotal_out += iplen;
+                } else {
+                    totals.ip6total_in++;
+                    totals.ip6btotal_in += iplen;
+                }
+
+                switch (ip6packet->ip6_nxt) {
+                case IPPROTO_TCP:
+                    totals.tcptotal++;
+                    totals.tcpbtotal += iplen;
+
+                    if (fromaddr.sll_pkttype == PACKET_OUTGOING) {
+                        totals.tcptotal_out++;
+                        totals.tcpbtotal_out += iplen;
+                    } else {
+                        totals.tcptotal_in++;
+                        totals.tcpbtotal_in += iplen;
+                    }
+                    break;
+                case IPPROTO_UDP:
+                    totals.udptotal++;
+                    totals.udpbtotal += iplen;
+
+                    if (fromaddr.sll_pkttype == PACKET_OUTGOING) {
+                        totals.udptotal_out++;
+                        totals.udpbtotal_out += iplen;
+                    } else {
+                        totals.udptotal_in++;
+                        totals.udpbtotal_in += iplen;
+                    }
+                    break;
+                case IPPROTO_ICMPV6:
+                    totals.icmptotal++;
+                    totals.icmpbtotal += iplen;
+                    if (fromaddr.sll_pkttype == PACKET_OUTGOING) {
+                        totals.icmptotal_out++;
+                        totals.icmpbtotal_out += iplen;
+                    } else {
+                        totals.icmptotal_in++;
+                        totals.icmpbtotal_in += iplen;
+                    }
+                    break;
+                default:
+                    totals.othtotal++;
+                    totals.othbtotal += iplen;
+
+                    if (fromaddr.sll_pkttype == PACKET_OUTGOING) {
+                        totals.othtotal_out++;
+                        totals.othbtotal_out += iplen;
+                    } else {
+                        totals.othtotal_in++;
+                        totals.othbtotal_in += iplen;
+                    }
+                    break;
+                }
+#endif
 	    } else {
 		totals.noniptotal++;
 		totals.nonipbtotal += br;
@@ -1080,15 +1297,37 @@
 	    starttime = now;
 
 	    wattrset(statwin, HIGHATTR);
+
+#ifdef USE_IPV6
+	    mvwprintw(statwin, 14, 19, "%8.1f %s/sec", activity,
+#else
 	    mvwprintw(statwin, 13, 19, "%8.1f %s/sec", activity,
+#endif
 		      unitstring);
+
+#ifdef USE_IPV6
+            mvwprintw(statwin, 15, 19, "%8.1f packets/sec", pps);
+            mvwprintw(statwin, 17, 19, "%8.1f %s/sec", activity_in,
+#else
 	    mvwprintw(statwin, 14, 19, "%8.1f packets/sec", pps);
 	    mvwprintw(statwin, 16, 19, "%8.1f %s/sec", activity_in,
+#endif
 		      unitstring);
+
+#ifdef USE_IPV6
+            mvwprintw(statwin, 18, 19, "%8.1f packets/sec", pps_in);
+            mvwprintw(statwin, 20, 19, "%8.1f %s/sec", activity_out,
+#else
 	    mvwprintw(statwin, 17, 19, "%8.1f packets/sec", pps_in);
 	    mvwprintw(statwin, 19, 19, "%8.1f %s/sec", activity_out,
+#endif
 		      unitstring);
+
+#ifdef USE_IPV6
+            mvwprintw(statwin, 21, 19, "%8.1f packets/sec", pps_out);
+#else
 	    mvwprintw(statwin, 20, 19, "%8.1f packets/sec", pps_out);
+#endif
 
 	    if (activity > peakactivity)
 		peakactivity = activity;
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/ifstats.h iptraf-2.7.0/src/ifstats.h
--- iptraf-2.7.0.orig/src/ifstats.h	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/ifstats.h	2005-07-18 19:03:48.000000000 -0400
@@ -9,6 +9,9 @@
     char ifname[8];
     unsigned int encap;
     unsigned long long iptotal;
+#ifdef USE_IPV6
+    unsigned long long ip6total;
+#endif
     unsigned long badtotal;
     unsigned long long noniptotal;
     unsigned long long total;
@@ -49,6 +52,15 @@
     unsigned long long ipbtotal_in;
     unsigned long long ipbtotal_out;
 
+#ifdef USE_IPV6
+    unsigned long long ip6total;
+    unsigned long long ip6btotal;
+    unsigned long long ip6total_in;
+    unsigned long long ip6total_out;
+    unsigned long long ip6btotal_in;
+    unsigned long long ip6btotal_out;
+#endif
+
     unsigned long long noniptotal;
     unsigned long long nonipbtotal;
     unsigned long long noniptotal_in;
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/itrafmon.c iptraf-2.7.0/src/itrafmon.c
--- iptraf-2.7.0.orig/src/itrafmon.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/itrafmon.c	2005-07-18 19:12:59.000000000 -0400
@@ -23,6 +23,12 @@
 #include <ctype.h>
 #include <winops.h>
 #include <labels.h>
+
+#ifdef USE_IPV6
+# include <netinet/ip6.h>
+# include <netinet/icmp6.h>
+#endif
+
 #include "options.h"
 #include "tcptable.h"
 #include "othptab.h"
@@ -565,6 +571,11 @@
     char tpacket[MAX_PACKET_SIZE];	/* raw packet data */
     char *packet = NULL;	/* network packet ptr */
     struct iphdr *ippacket;
+#ifdef USE_IPV6
+    struct ip6_hdr *ip6packet;
+    unsigned int protocol;
+    unsigned int frag_off;
+#endif
     struct tcphdr *transpacket;	/* IP-encapsulated packet */
     unsigned int sport = 0, dport = 0;	/* TCP/UDP port values */
     char sp_buf[10];
@@ -1004,9 +1015,18 @@
             if (pkt_result != PACKET_OK)
                 continue;
                 
+
+#ifdef USE_IPV6
+	    if ((fromaddr.sll_protocol != ETH_P_IP) && (fromaddr.sll_protocol != ETH_P_IPV6)) {
+#else
             if (fromaddr.sll_protocol != ETH_P_IP) {
+#endif
 		othpent = add_othp_entry(&othptbl, &table,
+#ifdef USE_IPV6
+					     0, 0, NULL, NULL, NOT_IP,
+#else
 					     0, 0, NOT_IP,
+#endif
 					     fromaddr.sll_protocol,
 					     linktype, (char *) tpacket,
 					     (char *) packet, br, ifname, 0, 0,
@@ -1015,13 +1035,54 @@
 					     &nomem);
 	        continue;
 	    } else {
+#ifdef USE_IPV6
+                if ((options->v6inv4asv6) && (fromaddr.sll_protocol == ETH_P_IP)
+                    && ((struct iphdr *) packet)->protocol == IPPROTO_IPV6 ) {
+                        iphlen = ((struct iphdr *) packet)->ihl * 4;
+                        fromaddr.sll_protocol = htons(ETH_P_IPV6);
+                        memmove(tpacket, tpacket + iphlen, MAX_PACKET_SIZE - iphlen);
+                        // Reprocess the ipv6 packet
+                        pkt_result = processpacket((char *) tpacket, &packet, &readlen,
+                                        &br, &sport, &dport, &fromaddr,
+                                        &linktype, ofilter, ifname, ifptr);
+                        if (pkt_result != PACKET_OK)
+                            continue;
+                }
+                if (fromaddr.sll_protocol == ETH_P_IP) {
+#endif
 	        ippacket = (struct iphdr *) packet;
 	        iphlen = ippacket->ihl * 4;
+#ifdef USE_IPV6
+                   ip6packet = NULL;
+                   protocol = ippacket->protocol;
+                   frag_off = ippacket->frag_off;
+               } else {
+                   ip6packet = (struct ip6_hdr *) packet;
+                   iphlen = 40;
+                   ippacket = NULL;
+                   protocol = ip6packet->ip6_nxt;
+                   frag_off = 0;
+               }
+#endif
 	        transpacket = (struct tcphdr *) (packet + iphlen);
 
+#ifdef USE_IPV6
+		if (protocol == IPPROTO_TCP) {
+#else
 	        if (ippacket->protocol == IPPROTO_TCP) {
+#endif
 
+#ifdef USE_IPV6
+		if (ippacket != NULL)
+#endif
 		tcpentry = in_table(&table, ippacket->saddr, ippacket->daddr,
+#ifdef USE_IPV6
+                            NULL , NULL,
+                            ntohs(sport), ntohs(dport), ifname,
+                            logging, logfile, &nomem, options);
+               else
+                   tcpentry = in_table(&table, 0, 0, (uint8_t*)(&ip6packet->ip6_src.s6_addr), (uint8_t*)(&ip6packet->ip6_dst.s6_addr),
+#endif
 			     ntohs(sport), ntohs(dport), ifname,
 			     logging, logfile, &nomem, options);
 
@@ -1030,7 +1091,11 @@
 		 * to reduce the chances of stales, not a FIN.
 		 */
 
+#ifdef USE_IPV6
+                if ((ntohs(frag_off) & 0x3fff) == 0) {  /* first frag only */
+#else
 		if ((ntohs(ippacket->frag_off) & 0x3fff) == 0) {	/* first frag only */
+#endif
 		    totalhlen = iphlen + transpacket->doff * 4;
 
 		    if ((tcpentry == NULL) && (!(transpacket->fin))) {
@@ -1042,16 +1107,33 @@
 
 			if (!nomem) {
 			    wasempty = (table.head == NULL);
+#ifdef USE_IPV6
+			    if (ippacket != NULL)
+#endif
 			    tcpentry = addentry(&table,
 						(unsigned long)
 						ippacket->saddr,
 						(unsigned long)
+#ifdef USE_IPV6
+						ippacket->daddr,
+						NULL, NULL, sport,
+#else
 						ippacket->daddr, sport,
+#endif
 						dport, ippacket->protocol,
 						ifname, &revlook,
 						rvnfd, options->servnames,
 						&nomem);
-
+#ifdef USE_IPV6
+			    else
+                            tcpentry = addentry(&table, 0, 0,
+                                                (uint8_t*)(&ip6packet->ip6_src.s6_addr),
+                                                (uint8_t*)(&ip6packet->ip6_dst.s6_addr),
+                                                sport, dport, ip6packet->ip6_nxt,
+                                                ifname, &revlook,
+                                                rvnfd, options->servnames,
+                                                &nomem);
+#endif
 			    if (tcpentry != NULL) {
 				printentry(&table,
 					   tcpentry->oth_connection,
@@ -1095,12 +1177,22 @@
 			    p_sstat = tcpentry->s_fstat;
 			    p_dstat = tcpentry->d_fstat;
 			}
+#ifdef USE_IPV6
+			if (ippacket != NULL)
+#endif
 			updateentry(&table, tcpentry, transpacket, tpacket,
 			            linktype, readlen,
 				    br, ippacket->frag_off, logging,
 				    &revlook, rvnfd, options, logfile,
 				    &nomem);
-
+#ifdef USE_IPV6
+                        else
+                        updateentry(&table, tcpentry, transpacket, tpacket,
+                                    linktype, readlen,
+                                    br, 0, logging,
+                                    &revlook, rvnfd, options, logfile,
+                                    &nomem);
+#endif
 			/*
 			 * Log first packet of a TCP connection except if
 			 * it's a RST, which was already logged earlier in
@@ -1152,7 +1244,11 @@
 				       screen_idx, mode);
 		    }
 		}
+#ifdef USE_IPV6
+	    } else if (ippacket != NULL) {
+#else
 	    } else {		/* now for the other IP protocols */
+#endif
 		fragment = ((ntohs(ippacket->frag_off) & 0x1fff) != 0);
 		
 		if (ippacket->protocol == IPPROTO_ICMP) {
@@ -1172,13 +1268,35 @@
 
 		    othpent =
 			add_othp_entry(&othptbl, &table, ippacket->saddr,
+#ifdef USE_IPV6
+				       ippacket->daddr, NULL, NULL, IS_IP,
+#else
 				       ippacket->daddr, IS_IP,
+#endif
 				       ippacket->protocol, linktype,
 				       (char *) tpacket, (char *) transpacket,
 				       readlen, ifname, &revlook,
 				       rvnfd, options->timeout, logging, logfile,
 				       options->servnames, fragment,
 				       &nomem);
+
+#ifdef USE_IPV6
+
+           } else {
+                 if (ip6packet->ip6_nxt == IPPROTO_ICMPV6) {
+                   if (((struct icmp6_hdr *) transpacket)->icmp6_type == ICMP6_DST_UNREACH)
+                       process_dest_unreach(&table, (char *) transpacket,
+                           ifname, &nomem);
+               }
+               othpent =
+                   add_othp_entry(&othptbl, &table, 0, 0, &ip6packet->ip6_src,
+                                  &ip6packet->ip6_dst, IS_IP,
+                                  ip6packet->ip6_nxt, linktype,
+                                  (char *) tpacket, (char *) transpacket,
+                                  readlen, ifname, &revlook,
+                                  rvnfd, options->timeout, logging, logfile,
+                                  options->servnames, fragment, &nomem);
+#endif
 		}
 	    }
 	}
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/landesc.c iptraf-2.7.0/src/landesc.c
--- iptraf-2.7.0.orig/src/landesc.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/landesc.c	2005-07-18 19:03:48.000000000 -0400
@@ -207,7 +207,11 @@
     else if (linktype == LINK_FDDI)
 	fd = fopen(FDDIFILE, "w");
 
+#ifdef USE_IPV6
+    if (fd <= 0) {
+#else
     if (fd < 0) {
+#endif
 	etherr();
 	return;
     }
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/options.c iptraf-2.7.0/src/options.c
--- iptraf-2.7.0.orig/src/options.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/options.c	2005-07-18 19:03:48.000000000 -0400
@@ -41,7 +41,11 @@
 
 void makeoptionmenu(struct MENU *menu)
 {
+#ifdef USE_IPV6
+    tx_initmenu(menu, 20, 40, (LINES - 19) / 2 - 1, (COLS - 40) / 16,
+#else
     tx_initmenu(menu, 19, 40, (LINES - 19) / 2 - 1, (COLS - 40) / 16,
+#endif
         BOXATTR, STDATTR, HIGHATTR, BARSTDATTR, BARHIGHATTR, DESCATTR);
     tx_additem(menu, " ^R^everse DNS lookups",
 	    "Toggles resolution of IP addresses into host names");
@@ -57,6 +61,10 @@
 	    "Toggles activity indicators between kbits/s and kbytes/s");
     tx_additem(menu, " Source ^M^AC addrs in traffic monitor",
             "Toggles display of source MAC addresses in the IP Traffic Monitor");
+#ifdef USE_IPV6
+    tx_additem(menu, " ^S^how v6-in-v4 traffic as IPv6",
+           "Toggled display of IPv6 tunnel in IPv4 as IPv6 traffic");
+#endif
     tx_additem(menu, NULL, NULL);
     tx_additem(menu, " ^T^imers...", "Configures timeouts and intervals");
     tx_additem(menu, NULL, NULL);
@@ -128,6 +136,10 @@
     case 7:
         printoptonoff(options->mac, win);
         break;
+#ifdef USE_IPV6
+    case 8:
+        printoptonoff(options->v6inv4asv6, win);
+#endif
     }
    
 }
@@ -165,6 +177,9 @@
     options->logspan = 3600;
     options->updrate = 0;
     options->closedint = 0;
+#ifdef USE_IPV6
+    options->v6inv4asv6 = 1;
+#endif
 }
 
 void loadoptions(struct OPTIONS *options)
@@ -186,17 +201,28 @@
 void updatetimes(struct OPTIONS *options, WINDOW * win)
 {
     wattrset(win, HIGHATTR);
+#ifdef USE_IPV6
+    mvwprintw(win, 10, 25, "%3u mins", options->timeout);
+    mvwprintw(win, 11, 25, "%3u mins", options->logspan / 60);
+    mvwprintw(win, 12, 25, "%3u secs", options->updrate);
+    mvwprintw(win, 13, 25, "%3u mins", options->closedint);
+#else
     mvwprintw(win, 9, 25, "%3u mins", options->timeout);
     mvwprintw(win, 10, 25, "%3u mins", options->logspan / 60);
     mvwprintw(win, 11, 25, "%3u secs", options->updrate);
     mvwprintw(win, 12, 25, "%3u mins", options->closedint);
+#endif
 }
 
 void showoptions(struct OPTIONS *options, WINDOW * win)
 {
     int i;
 
+#ifdef USE_IPV6
+    for (i = 1; i <= 8; i++)
+#else
     for (i = 1; i <= 7; i++)
+#endif
 	indicatesetting(i, options, win);
 
     updatetimes(options, win);
@@ -269,13 +295,21 @@
     }
     makeoptionmenu(&menu);
     
+#ifdef USE_IPV6
+    statwin = newwin(15, 35, (LINES - 19) / 2 - 1, (COLS - 40) / 16 + 40);
+#else
     statwin = newwin(14, 35, (LINES - 19) / 2 - 1, (COLS - 40) / 16 + 40);
+#endif
     statpanel = new_panel(statwin);
 
     wattrset(statwin, BOXATTR);
     tx_colorwin(statwin);
     box(statwin, ACS_VLINE, ACS_HLINE);
+#ifdef USE_IPV6
+    wmove(statwin, 9, 1);
+#else
     wmove(statwin, 8, 1);
+#endif
     whline(statwin, ACS_HLINE, 33);
     mvwprintw(statwin, 0, 1, " Current Settings ");
     wattrset(statwin, STDATTR);
@@ -286,10 +320,18 @@
     mvwprintw(statwin, 5, 2, "Logging:");
     mvwprintw(statwin, 6, 2, "Activity mode:");
     mvwprintw(statwin, 7, 2, "MAC addresses:");
+#ifdef USE_IPV6
+    mvwprintw(statwin, 8, 2, "v6-in-v4 as IPv6:");
+    mvwprintw(statwin, 10, 2, "TCP timeout:");
+    mvwprintw(statwin, 11, 2, "Log interval:");
+    mvwprintw(statwin, 12, 2, "Update interval:");
+    mvwprintw(statwin, 13, 2, "Closed/idle persist:");
+#else
     mvwprintw(statwin, 9, 2, "TCP timeout:");
     mvwprintw(statwin, 10, 2, "Log interval:");
     mvwprintw(statwin, 11, 2, "Update interval:");
     mvwprintw(statwin, 12, 2, "Closed/idle persist:");
+#endif
     showoptions(options, statwin);
 
     do {
@@ -318,7 +360,14 @@
 	case 7:
 	    options->mac = ~(options->mac);
 	    break;
+#ifdef USE_IPV6
+	case 8:
+            options->v6inv4asv6 = ~(options->v6inv4asv6);
+            break;
+        case 10:
+#else
 	case 9:
+#endif
             maketimermenu(&timermenu);
 	    do {
 	        tx_showmenu(&timermenu);
@@ -357,22 +406,42 @@
 	    update_panels();
 	    doupdate();
 	    break;
+#ifdef USE_IPV6
+	case 12:
+#else
 	case 11:
+#endif
 	    addmoreports(ports);
 	    break;
+#ifdef USE_IPV6
+	case 13:
+#else
 	case 12:
+#endif
 	    removeaport(ports);
 	    break;
+#ifdef USE_IPV6
+	case 15:
+#else
 	case 14:
+#endif
 	    ethdescmgr(LINK_ETHERNET);
 	    break;
+#ifdef USE_IPV6
+	case 16:
+#else
 	case 15:
+#endif
 	    ethdescmgr(LINK_FDDI);
 	    break;
 	}
 
 	indicatesetting(row, options, statwin);
+#ifdef USE_IPV6
+    } while (row != 18);
+#else
     } while (row != 17);
+#endif
 
     tx_destroymenu(&menu);
     del_panel(statpanel);
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/options.h iptraf-2.7.0/src/options.h
--- iptraf-2.7.0.orig/src/options.h	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/options.h	2005-07-18 19:03:48.000000000 -0400
@@ -7,7 +7,12 @@
                  promisc:1,
                  actmode:1,
                  mac:1,
+#ifdef USE_IPV6
+                 v6inv4asv6:1,
+                 dummy:8;
+#else
                  dummy:9;
+#endif
     unsigned int timeout;
     unsigned int logspan;
     unsigned int updrate;
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/othptab.c iptraf-2.7.0/src/othptab.c
--- iptraf-2.7.0.orig/src/othptab.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/othptab.c	2005-07-18 19:03:48.000000000 -0400
@@ -20,6 +20,12 @@
 #include <linux/if_ether.h>
 #include <linux/if_tr.h>
 #include <linux/if_fddi.h>
+
+#ifdef USE_IPV6
+# include <netinet/ip6.h>
+# include <netinet/icmp6.h>
+#endif
+
 #include <winops.h>
 #include "arphdr.h"
 #include "options.h"
@@ -79,16 +85,20 @@
 			  char *ifname, int *nomem)
 {
     struct iphdr *ip;
+#ifdef USE_IPV6
+    struct ip6_hdr *ip6;
+#endif
     struct tcphdr *tcp;
     struct tcptableent *tcpentry;
 
     ip = (struct iphdr *) (packet + 8);
 
+#ifndef USE_IPV6
     if (ip->protocol != IPPROTO_TCP)
 	return;
 
     tcp = (struct tcphdr *) (packet + 8 + (ip->ihl * 4));
-
+#endif
     /* 
      * We really won't be making use of nomem here.  Timeout checking
      * won't be performed either, so we just pass NULL as the pointer
@@ -96,10 +106,31 @@
      * and set its internal timeout variable to 0.
      */
 
+#ifdef USE_IPV6
+    if (ip->version == 6)
+    {
+       ip6 = (struct ip6_hdr *) (packet + 8);
+       if (ip6->ip6_nxt != IPPROTO_TCP)
+           return;
+       tcp = (struct tcphdr *) (packet + 48);
+       tcpentry = in_table(table, 0, 0, ip6->ip6_src.s6_addr, ip6->ip6_dst.s6_addr,
+#else
     tcpentry = in_table(table, ip->saddr, ip->daddr,
+#endif
 			ntohs(tcp->source), ntohs(tcp->dest), ifname,
 			0, NULL, nomem, NULL);
 
+#ifdef USE_IPV6
+    } else {
+        if (ip->protocol != IPPROTO_TCP)
+           return;
+       tcp = (struct tcphdr *) (packet + 8 + (ip->ihl * 4));
+       tcpentry = in_table(table, ip->saddr, ip->daddr, NULL, NULL,
+                       ntohs(tcp->source), ntohs(tcp->dest), ifname,
+                       0, NULL, nomem, NULL);
+    }
+#endif
+
     if (tcpentry != NULL) {
 	tcpentry->stat = tcpentry->oth_connection->stat = FLAG_RST;
 	addtoclosedlist(table, tcpentry, nomem);
@@ -109,6 +140,9 @@
 struct othptabent *add_othp_entry(struct othptable *table,
 				  struct tcptable *tcptab,
 				  unsigned long saddr, unsigned long daddr,
+#ifdef USE_IPV6
+                                  struct in6_addr *s6addr, struct in6_addr *d6addr,
+#endif
 				  int is_ip, int protocol,
 				  unsigned short linkproto, char *packet,
 				  char *packet2, unsigned int br,
@@ -156,8 +190,23 @@
 	new_entry->saddr = isaddr.s_addr = saddr;
 	new_entry->daddr = idaddr.s_addr = daddr;
 
+#ifdef USE_IPV6
+        if (s6addr != NULL)
+            memcpy(&new_entry->s6addr, s6addr, 16);
+        else
+            memset(&new_entry->s6addr, 0, 16);
+ 
+        if (d6addr != NULL)
+            memcpy(&new_entry->d6addr, d6addr, 16);
+        else
+            memset(&new_entry->s6addr, 0, 16);
+
+        revname(rev_lookup, &isaddr, s6addr, new_entry->s_fqdn, rvnfd);
+        revname(rev_lookup, &idaddr, d6addr, new_entry->d_fqdn, rvnfd);
+#else
 	revname(rev_lookup, &isaddr, new_entry->s_fqdn, rvnfd);
 	revname(rev_lookup, &idaddr, new_entry->d_fqdn, rvnfd);
+#endif
 
 	if (!fragment) {
 	    if (protocol == IPPROTO_ICMP) {
@@ -165,6 +214,15 @@
 		    ((struct icmphdr *) packet2)->type;
 		new_entry->un.icmp.code =
 		    ((struct icmphdr *) packet2)->code;
+
+#ifdef USE_IPV6
+            } else if (protocol == IPPROTO_ICMPV6) {
+                new_entry->un.icmp6.type =
+                    ((struct icmp6_hdr *) packet2)->icmp6_type;
+                new_entry->un.icmp6.code =
+                    ((struct icmp6_hdr *) packet2)->icmp6_code;
+#endif
+
 	    } else if (protocol == IPPROTO_UDP) {
 		servlook(servnames, ((struct udphdr *) packet2)->source,
 			 IPPROTO_UDP, new_entry->un.udp.s_sname, 10);
@@ -418,6 +476,16 @@
         wattrset(table->othpwin, GREATTR);
         strcpy(protname, "GRE");
         break;
+#ifdef USE_IPV6
+     case IPPROTO_ICMPV6:
+        wattrset(table->othpwin, ICMPV6ATTR);
+        strcpy(protname, "ICMPv6");
+        break;
+     case IPPROTO_IPV6:
+        wattrset(table->othpwin, IPV6ATTR);
+        strcpy(protname, "IPv6 tun");
+        break;
+#endif
     default:
 	wattrset(table->othpwin, UNKNATTR);
 	sprintf(protname, "IP protocol");
@@ -518,7 +586,73 @@
 		strcpy(description, "bad/unkn");
 		break;
 	    }
-
+#ifdef USE_IPV6
+       } else if (entry->protocol == IPPROTO_ICMPV6) {
+           switch (entry->un.icmp6.type) {
+           case ICMP6_DST_UNREACH:
+               strcpy(description, "dest unrch");
+               switch (entry->un.icmp6.code) {
+               case ICMP6_DST_UNREACH_NOROUTE:
+                   strcpy(additional, "no route");
+                   break;
+               case ICMP6_DST_UNREACH_ADMIN:
+                   strcpy(additional, "admin");
+                   break;
+               case ICMP6_DST_UNREACH_NOTNEIGHBOR:
+                   strcpy(additional, "not neigh");
+                   break;
+               case ICMP6_DST_UNREACH_ADDR:
+                   strcpy(additional, "unreach addr");
+                   break;
+               case ICMP6_DST_UNREACH_NOPORT:
+                   strcpy(additional, "no port");
+                   break;
+               }
+               break;
+           case ICMP6_PACKET_TOO_BIG:
+               strcpy(description, "pkt too big");
+               break;
+           case ICMP6_TIME_EXCEEDED:
+               strcpy(description, "time exceeded");
+               break;
+           case ICMP6_PARAM_PROB:
+               strcpy(description, "param prob");
+               break;
+           case ICMP6_ECHO_REQUEST:
+               strcpy(description, "echo req");
+               break;
+           case ICMP6_ECHO_REPLY:
+               strcpy(description, "echo rply");
+               break;
+           case ND_ROUTER_SOLICIT:
+               strcpy(description, "router sol");
+               break;
+           case ND_ROUTER_ADVERT:
+               strcpy(description, "router adv");
+               break;
+           case ICMP6_MEMBERSHIP_QUERY:
+               strcpy(description, "mbrship query");
+               break;
+           case ICMP6_MEMBERSHIP_REPORT:
+               strcpy(description, "mbrship report");
+               break;
+           case ICMP6_MEMBERSHIP_REDUCTION:
+               strcpy(description, "mbrship reduc");
+               break;
+           case ND_NEIGHBOR_SOLICIT:
+               strcpy(description, "neigh sol");
+               break;
+           case ND_NEIGHBOR_ADVERT:
+               strcpy(description, "neigh adv");
+               break;
+           case ND_REDIRECT:
+               strcpy(description, "redirect");
+               break;
+           default:
+               strcpy(description, "bad/unkn");
+               break;
+           }
+#endif
 	} else if (entry->protocol == IPPROTO_OSPFIGP) {
 	    switch (entry->un.ospf.type) {
 	    case OSPF_TYPE_HELLO:
@@ -562,11 +696,19 @@
     strcat(msgstring, scratchpad);
 
     if ((entry->protocol == IPPROTO_UDP) && (!(entry->fragment))) {
+#ifdef USE_IPV6
+        sprintf(scratchpad, "from %.40s:%s to %.40s:%s",
+#else
 	sprintf(scratchpad, "from %.25s:%s to %.25s:%s",
+#endif
 		entry->s_fqdn, entry->un.udp.s_sname,
 		entry->d_fqdn, entry->un.udp.d_sname);
     } else {
+#ifdef USE_IPV6
+        sprintf(scratchpad, "from %.40s to %.40s", entry->s_fqdn,
+#else
 	sprintf(scratchpad, "from %.25s to %.25s", entry->s_fqdn,
+#endif
 		entry->d_fqdn);
     }
 
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/othptab.h iptraf-2.7.0/src/othptab.h
--- iptraf-2.7.0.orig/src/othptab.h	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/othptab.h	2005-07-18 19:03:48.000000000 -0400
@@ -34,6 +34,10 @@
 struct othptabent {
     unsigned long int saddr;
     unsigned long int daddr;
+#ifdef USE_IPV6
+    struct in6_addr s6addr;
+    struct in6_addr d6addr;
+#endif
     char smacaddr[15];
     char dmacaddr[15];
     unsigned short linkproto;
@@ -69,6 +73,10 @@
 	    char src_mac_address[6];
 	    char dest_mac_address[6];
 	} rarp;
+        struct {
+            uint8_t     type;
+            uint8_t     code;
+        } icmp6;
     } un;
     unsigned int type;
     unsigned int code;
@@ -133,9 +141,15 @@
 struct othptabent *add_othp_entry(struct othptable *table,
 				  struct tcptable *tcptab,
 				  unsigned long saddr,
+#ifdef USE_IPV6
+                                  unsigned long daddr, struct in6_addr *s6addr,
+                                  struct in6_addr *d6addr, int is_ip,int protocol,
+                                  unsigned short linkproto, char *packet,char *netpacket,
+#else
 				  unsigned long daddr, int is_ip,
 				  int protocol, unsigned short linkproto,
 				  char *packet,char *netpacket,
+#endif
 				  unsigned int br, char *ifname,
 				  int *rev_lookup, int rvnamedon, 
 				  unsigned int tm, int logging,
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/packet.c iptraf-2.7.0/src/packet.c
--- iptraf-2.7.0.orig/src/packet.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/packet.c	2005-07-18 19:03:48.000000000 -0400
@@ -28,6 +28,9 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#ifdef USE_IPV6
+# include <netinet/ip6.h>
+#endif
 #include <netinet/tcp.h>
 #include <sys/time.h>
 #include <net/if_arp.h>
@@ -279,6 +282,9 @@
 {
     static char aligned_buf[ALIGNED_BUF_LEN];
     struct iphdr *ip;
+#ifdef USE_IPV6
+    struct ip6_hdr *ip6;
+#endif
     int hdr_check;
     register int ip_checksum;
     register int iphlen;
@@ -328,7 +334,11 @@
      * Apply non-IP packet filter
      */
      
+#ifdef USE_IPV6
+    if ((fromaddr->sll_protocol != ETH_P_IP) && (fromaddr->sll_protocol != ETH_P_IPV6)) {
+#else
     if (fromaddr->sll_protocol != ETH_P_IP) {
+#endif
         if ((fromaddr->sll_protocol == ETH_P_ARP) ||
            (fromaddr->sll_protocol == ETH_P_RARP)) {
             if (!othfilterok(ofilter, fromaddr->sll_protocol, 0, 0, 0, 0)) {
@@ -342,7 +352,10 @@
         return PACKET_OK;
     }
 
-    
+#ifdef USE_IPV6
+    if (fromaddr->sll_protocol == ETH_P_IP) {
+#endif
+
     /*
      * At this point, we're now processing IP packets.  Start by getting
      * IP header and length.
@@ -358,7 +371,7 @@
     ip->check = 0;
     hdr_check = in_cksum((u_short *) ip, iphlen);
     
-    if (hdr_check != ip_checksum)
+    if ((hdr_check != ip_checksum))
         return CHECKSUM_ERROR;
     
     if ((ip->protocol == IPPROTO_TCP) || (ip->protocol == IPPROTO_UDP)) {
@@ -426,6 +439,27 @@
          if (!othfilterok(ofilter, ip->protocol, ip->saddr, ip->daddr, 0, 0))
              return INVALID_PACKET;
      }
+#ifdef USE_IPV6
+    } else if (fromaddr->sll_protocol == ETH_P_IPV6) {
+        ip6 = (struct ip6_hdr *) (*packet);
+       iphlen = 40;
+       //TODO: Filter packets
+       if (ip6->ip6_nxt == IPPROTO_TCP) {
+           in_ip.tcp = (struct tcphdr *) ((char *) ip6 + iphlen);
+           if (sport != NULL)
+               *sport = in_ip.tcp->source;
+           if (dport != NULL)
+               *dport = in_ip.tcp->dest;
+       } else if (ip6->ip6_nxt == IPPROTO_UDP) {
+           in_ip.udp = (struct udphdr *) ((char *) ip6 + iphlen);
+           if (sport != NULL)
+               *sport = in_ip.udp->source;
+           if (dport != NULL)
+               *dport = in_ip.udp->dest;
+       }
+       return PACKET_OK;
+    }
+#endif
      return PACKET_OK;
 }
 
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/revname.c iptraf-2.7.0/src/revname.c
--- iptraf-2.7.0.orig/src/revname.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/revname.c	2005-07-18 19:03:48.000000000 -0400
@@ -153,7 +153,11 @@
     }
 }
 
+#ifdef USE_IPV6
+int revname(int *lookup, struct in_addr *saddr, struct in6_addr *s6addr, char *target, int rvnfd)
+#else
 int revname(int *lookup, struct in_addr *saddr, char *target, int rvnfd)
+#endif
 {
     struct hostent *he;
     struct rvn rpkt;
@@ -172,6 +176,13 @@
 
 	    rpkt.type = RVN_REQUEST;
 	    rpkt.saddr.s_addr = saddr->s_addr;
+
+#ifdef USE_IPV6
+           if (s6addr != NULL)
+               memcpy(rpkt.s6addr.s6_addr, s6addr->s6_addr, 16);
+           else
+               memset(rpkt.s6addr.s6_addr, 0, 4);
+#endif
 	    
 	    sendto(rvnfd, &rpkt, sizeof(struct rvn), 0,
 		   (struct sockaddr *) &su,
@@ -197,7 +208,14 @@
 	    } while ((br < 0) && (errno == EINTR));
 
 	    if (br < 0) {
+#ifdef USE_IPV6
+		if (saddr->s_addr != 0)
+#endif
 		strcpy(target, inet_ntoa(*saddr));
+#ifdef USE_IPV6
+		else
+		    inet_ntop(AF_INET6, s6addr, target, 44);
+#endif
 		printipcerr();
 		*lookup = 0;
 		return RESOLVED;
@@ -205,18 +223,44 @@
 	    strncpy(target, rpkt.fqdn, 44);
 	    return (rpkt.ready);
 	} else {
+#ifdef USE_IPV6
+           if (saddr->s_addr != 0)
+               he = gethostbyaddr((char *) saddr, sizeof(struct in_addr), AF_INET);
+           else
+               he = gethostbyaddr((char *) s6addr, sizeof(struct in6_addr), AF_INET6);
+#else
 	    he = gethostbyaddr((char *) saddr,
 			       sizeof(struct in_addr), AF_INET);
+#endif
 
+#ifdef USE_IPV6
+	    if (he == NULL) {
+		if (saddr->s_addr != 0)
+#else
 	    if (he == NULL)
+#endif
 		strcpy(target, inet_ntoa(*saddr));
 	    else
+#ifdef USE_IPV6
+		inet_ntop(AF_INET6, s6addr, target, 44);
+	    } else {
+#endif
 		strncpy(target, he->h_name, 44);
+#ifdef USE_IPV6
+	    }
+#endif
 
 	    return RESOLVED;
 	}
     } else {
+#ifdef USE_IPV6
+        if (saddr->s_addr != 0 || s6addr == NULL)
+	    strcpy(target, inet_ntoa(*saddr));
+        else
+            inet_ntop(AF_INET6, s6addr, target, 44);
+#else
 	strcpy(target, inet_ntoa(*saddr));
 	return RESOLVED;
+#endif
     }
 }
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/revname.h iptraf-2.7.0/src/revname.h
--- iptraf-2.7.0.orig/src/revname.h	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/revname.h	2005-07-18 19:03:48.000000000 -0400
@@ -8,4 +8,9 @@
 int killrvnamed();
 void open_rvn_socket(int *fd);
 void close_rvn_socket(int fd);
+
+#ifdef USE_IPV6
+int revname(int *lookup, struct in_addr *saddr, struct in6_addr *s6addr, char *target, int rvnfd);
+#else
 int revname(int *lookup, struct in_addr *saddr, char *target, int rvnfd);
+#endif
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/rvnamed.c iptraf-2.7.0/src/rvnamed.c
--- iptraf-2.7.0.orig/src/rvnamed.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/rvnamed.c	2005-07-18 19:22:32.000000000 -0400
@@ -55,6 +55,9 @@
 
 struct hosts {
     unsigned long addr;
+#ifdef USE_IPV6
+    uint8_t addr6[16];
+#endif
     char fqdn[45];
     int ready;
 };
@@ -93,12 +96,30 @@
 
     ccfd = socket(PF_UNIX, SOCK_DGRAM, 0);
 
+#ifdef USE_IPV6
+    if (rvnpacket->saddr.s_addr != 0)
+       he = gethostbyaddr((char *) &(rvnpacket->saddr), sizeof(struct in_addr), AF_INET);
+    else
+       he = gethostbyaddr((char *) &(rvnpacket->s6addr), sizeof(struct in6_addr), AF_INET6);
+#else
     he = gethostbyaddr((char *) &(rvnpacket->saddr),
 		       sizeof(struct in_addr), AF_INET);
+#endif
 
+#ifdef USE_IPV6
+    if (he == NULL) {
+	if (rvnpacket->saddr.s_addr != 0)
+#else
     if (he == NULL)
+#endif
 	strcpy(rvnpacket->fqdn, inet_ntoa(rvnpacket->saddr));
+#ifdef USE_IPV6
+       else
+           inet_ntop(AF_INET6, &(rvnpacket->s6addr), rvnpacket->fqdn, sizeof(rvnpacket->fqdn));
+    } else {
+#else
     else {
+#endif
 	bzero(rvnpacket->fqdn, 45);
 	strncpy(rvnpacket->fqdn, he->h_name, 44);
     }
@@ -122,10 +143,19 @@
     unsigned int i = 0;
 
     while (i != lastfree) {
+#ifdef USE_IPV6
+	if (rvnpacket->saddr.s_addr != 0) {
+#endif
 	if ((rvnpacket->saddr.s_addr == hostlist[i].addr)
 	    && (hostlist[i].ready == RESOLVED))
 	    return i;
-
+#ifdef USE_IPV6
+       } else {
+           if ((!memcmp(rvnpacket->s6addr.s6_addr, hostlist[i].addr6, sizeof(hostlist[i].addr6)))
+               && (hostlist[i].ready == RESOLVED))
+           return i;
+       }
+#endif
 	i++;
     }
 
@@ -143,9 +173,17 @@
     unsigned int i = 0;
 
     while (i != lastfree) {
+#ifdef USE_IPV6
+        if (rvnpacket->saddr.s_addr != 0) {
+#endif
 	if (rvnpacket->saddr.s_addr == hostlist[i].addr)
 	    break;
-
+#ifdef USE_IPV6
+       } else {
+           if (!memcmp(rvnpacket->s6addr.s6_addr, hostlist[i].addr6, sizeof(hostlist[i].addr6)))
+               break;
+       }
+#endif
 	i++;
     }
 
@@ -302,7 +340,12 @@
 		hi = 0;
 
 		while (hi <= lastfree) {
+#ifdef USE_IPV6
+		    if ((hostlist[hi].addr == rvnpacket.saddr.s_addr) &&
+			    !memcmp(rvnpacket.s6addr.s6_addr, hostlist[hi].addr6, sizeof(hostlist[hi].addr6)))
+#else
 		    if (hostlist[hi].addr == rvnpacket.saddr.s_addr)
+#endif
 			break;
 		    hi++;
 		}
@@ -315,6 +358,9 @@
 			hostindex = 0;
 
 		    hostlist[hi].addr = rvnpacket.saddr.s_addr;
+#ifdef USE_IPV6
+                    memcpy(hostlist[hi].addr6, rvnpacket.s6addr.s6_addr, sizeof(hostlist[hi].addr6));
+#endif
 		}
 		strncpy(hostlist[hi].fqdn, rvnpacket.fqdn, 44);
 
@@ -398,6 +444,10 @@
 			         */
 			        hostlist[hostindex].addr =
 				    rvnpacket.saddr.s_addr;
+#ifdef USE_IPV6
+				memcpy(hostlist[hostindex].addr6, rvnpacket.s6addr.s6_addr,
+					sizeof(hostlist[hostindex].addr6));
+#endif
 			        hostlist[hostindex].ready = RESOLVING;
 
                                 maxlogged = 0;
@@ -452,7 +502,14 @@
 			}
 			rvnpacket.type = RVN_REPLY;
 			bzero(rvnpacket.fqdn, 45);
+#ifdef USE_IPV6
+			if (rvnpacket.saddr.s_addr != 0)
+#endif
 			strcpy(rvnpacket.fqdn, inet_ntoa(rvnpacket.saddr));
+#ifdef USE_IPV6
+			else
+			    inet_ntop(AF_INET6, &rvnpacket.s6addr, rvnpacket.fqdn, sizeof(rvnpacket.fqdn));
+#endif
 			rvnpacket.ready = RESOLVING;
 
 			br = sendto(ifd, &rvnpacket, sizeof(struct rvn), 0,
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/rvnamed.h iptraf-2.7.0/src/rvnamed.h
--- iptraf-2.7.0.orig/src/rvnamed.h	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/rvnamed.h	2005-07-18 19:03:48.000000000 -0400
@@ -22,5 +22,8 @@
     int type;
     int ready;
     struct in_addr saddr;
+#ifdef USE_IPV6
+    struct in6_addr s6addr;
+#endif
     char fqdn[45];
 };
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/serv.c iptraf-2.7.0/src/serv.c
--- iptraf-2.7.0.orig/src/serv.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/serv.c	2005-07-18 19:21:06.000000000 -0400
@@ -31,6 +31,9 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
+#ifdef USE_IPV6
+# include <netinet/ip6.h>
+#endif
 #include <netinet/udp.h>
 #include <linux/if_packet.h>
 #include <linux/if_ether.h>
@@ -939,6 +942,10 @@
             if (pkt_result != PACKET_OK)
 		    continue;
 
+#ifdef USE_IPV6
+	    if (fromaddr.sll_protocol == ETH_P_IP) {
+#endif
+
             if ((((struct iphdr *) ipacket)->protocol == IPPROTO_TCP)
 		    || (((struct iphdr *) ipacket)->protocol ==
 			IPPROTO_UDP)) {
@@ -958,6 +965,28 @@
                     list.baridx = 1;
                 }        
 	    }
+#ifdef USE_IPV6
+	    } else {
+               if ((((struct ip6_hdr *) ipacket)->ip6_nxt == IPPROTO_TCP)
+                       || (((struct ip6_hdr *) ipacket)->ip6_nxt ==
+                           IPPROTO_UDP)) {
+                   printport(&list, ((struct ip6_hdr *) ipacket)->ip6_nxt,
+                           ntohs(sport),
+                           ntohs(((struct ip6_hdr *) ipacket)->ip6_plen + 40),
+                           idx, 0, ports, options->servnames);
+                   printport(&list, ((struct ip6_hdr *) ipacket)->ip6_nxt,
+                           ntohs(dport),
+                           ntohs(((struct ip6_hdr *) ipacket)->ip6_plen + 40),
+                           idx, 1, ports, options->servnames);
+                if ((list.barptr == NULL) && (list.head != NULL)) {
+                    set_barptr((char **) &(list.barptr), (char *) list.head,
+                            &(list.head->starttime), (char *) &(list.head->spans),
+                            sizeof(struct serv_spans), statwin, &statcleared, statx);
+                    list.baridx = 1;
+               }
+               }
+           }
+#endif
 	}
 	gettimeofday(&tv, NULL);
 	now = tv.tv_sec;
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/tcptable.c iptraf-2.7.0/src/tcptable.c
--- iptraf-2.7.0.orig/src/tcptable.c	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/tcptable.c	2005-07-18 19:03:48.000000000 -0400
@@ -59,8 +59,13 @@
  * The hash function for the TCP hash table
  */
 
+#ifdef USE_IPV6
+unsigned int tcp_hash(unsigned long saddr, uint32_t *s6addr, unsigned int sport,
+                     unsigned long daddr, uint32_t *d6addr, unsigned int dport,
+#else
 unsigned int tcp_hash(unsigned long saddr, unsigned int sport,
 		      unsigned long daddr, unsigned int dport,
+#endif
 		      char *ifname)
 {
     int i;
@@ -69,6 +74,15 @@
     for (i = 0; i <= strlen(ifname) - 1; i++)
 	ifsum += ifname[i];
 
+#ifdef USE_IPV6
+    if (s6addr != 0 && d6addr != 0) {
+       for (i = 0; i < 4; i++) {
+               saddr ^= s6addr[i];
+               daddr ^= d6addr[i];
+       }
+    }
+#endif
+
     return ((ifsum + (4 * saddr) + (3 * sport) +
 	     (2 * daddr) + dport) % ENTRIES_IN_HASH_TABLE);
 }
@@ -139,8 +153,13 @@
     unsigned int hp;		/* hash position in table */
     struct tcp_hashentry *ptmp;
 
+#ifdef USE_IPV6
+    hp = tcp_hash(entry->saddr.s_addr, entry->s6addr.s6_addr32, entry->sport,
+                 entry->daddr.s_addr, entry->d6addr.s6_addr32, entry->dport, entry->ifname);
+#else
     hp = tcp_hash(entry->saddr.s_addr, entry->sport,
 		  entry->daddr.s_addr, entry->dport, entry->ifname);
+#endif
 
     ptmp = malloc(sizeof(struct tcp_hashentry));
     bzero(ptmp, sizeof(struct tcp_hashentry));
@@ -215,6 +234,10 @@
 struct tcptableent *addentry(struct tcptable *table,
 			     unsigned long int saddr,
 			     unsigned long int daddr,
+#ifdef USE_IPV6
+                             uint8_t *s6addr,
+                             uint8_t *d6addr,
+#endif
 			     unsigned int sport, unsigned int dport,
 			     int protocol,  
 			     char *ifname, int *rev_lookup,
@@ -311,8 +334,26 @@
 
     new_entry->saddr.s_addr = new_entry->oth_connection->daddr.s_addr =
 	saddr;
+#ifdef USE_IPV6
+    if (s6addr == NULL) {
+       memset(&new_entry->s6addr, 0, 16);
+       memset(&new_entry->oth_connection->d6addr, 0, 16);
+    } else {
+       memcpy(&new_entry->s6addr, s6addr, 16);
+       memcpy(&new_entry->oth_connection->d6addr, s6addr, 16);
+    }
+#endif
     new_entry->daddr.s_addr = new_entry->oth_connection->saddr.s_addr =
 	daddr;
+#ifdef USE_IPV6
+    if (d6addr == NULL) {
+       memset(&new_entry->d6addr, 0, 16);
+       memset(&new_entry->oth_connection->s6addr, 0, 16);
+    } else {
+       memcpy(&new_entry->d6addr, d6addr, 16);
+       memcpy(&new_entry->oth_connection->s6addr, d6addr, 16);
+    }
+#endif
     new_entry->protocol = protocol;
 
     /*
@@ -349,9 +390,18 @@
 
     new_entry->stat = new_entry->oth_connection->stat = 0;
 
+#ifdef USE_IPV6
+    new_entry->s_fstat = revname(rev_lookup, &(new_entry->saddr), &new_entry->s6addr,
+#else
     new_entry->s_fstat = revname(rev_lookup, &(new_entry->saddr),
+#endif
 				 new_entry->s_fqdn, rvnfd);
+
+#ifdef USE_IPV6
+    new_entry->d_fstat = revname(rev_lookup, &(new_entry->daddr), &new_entry->d6addr,
+#else
     new_entry->d_fstat = revname(rev_lookup, &(new_entry->daddr),
+#endif
 				 new_entry->d_fqdn, rvnfd);
 
     /*
@@ -489,7 +539,12 @@
 }
 
 struct tcptableent *in_table(struct tcptable *table, unsigned long saddr,
+#ifdef USE_IPV6
+                             unsigned long daddr, uint8_t *s6addr,
+                             uint8_t *d6addr, unsigned int sport,
+#else
 			     unsigned long daddr, unsigned int sport,
+#endif
 			     unsigned int dport, char *ifname,
 			     int logging, FILE * logfile,
 			     int *nomem, struct OPTIONS *opts)
@@ -501,6 +556,11 @@
 
     time_t now;
     time_t timeout;
+
+#ifdef USE_IPV6
+    int sfree = 0; //Should free s6addr
+    int dfree = 0; //Should free d6addr
+#endif
     
     if (opts != NULL)
         timeout = opts->timeout;
@@ -514,12 +574,35 @@
      * Determine hash table index for this set of addresses and ports
      */
 
+#ifdef USE_IPV6
+    hp = tcp_hash(saddr, (uint32_t*) s6addr, sport, daddr, (uint32_t*) d6addr, dport, ifname);
+#else
     hp = tcp_hash(saddr, sport, daddr, dport, ifname);
+#endif
     hashptr = table->hash_table[hp];
 
+#ifdef USE_IPV6
+    if (s6addr == NULL) {
+       s6addr = malloc(sizeof(struct in6_addr));
+       memset(s6addr, 0, 16);
+       sfree = 1;
+    }
+    if (d6addr == NULL) {
+       d6addr = malloc(sizeof(struct in6_addr));
+       memset(d6addr, 0, 16);
+       dfree = 1;
+    }
+#endif
+
     while (hashptr != NULL) {
 	if ((hashptr->tcpnode->saddr.s_addr == saddr) &&
+#ifdef USE_IPV6
+           (!memcmp(&hashptr->tcpnode->s6addr.s6_addr, s6addr, 16)) &&
+#endif
 	    (hashptr->tcpnode->daddr.s_addr == daddr) &&
+#ifdef USE_IPV6
+           (!memcmp(&hashptr->tcpnode->d6addr.s6_addr, d6addr, 16)) &&
+#endif
 	    (hashptr->tcpnode->sport == sport) &&
 	    (hashptr->tcpnode->dport == dport) &&
 	    (strcmp(hashptr->tcpnode->ifname, ifname) == 0))
@@ -546,6 +629,11 @@
 	hashptr = hashptr->next_entry;
     }
 
+#ifdef USE_IPV6
+    if (sfree) free(s6addr);
+    if (dfree) free(d6addr);
+#endif
+
     if (hashptr != NULL) {	/* needed to avoid SIGSEGV */
 	if ((((hashptr->tcpnode->finsent == 2) &&
 	      (hashptr->tcpnode->oth_connection->finsent == 2))) ||
@@ -576,13 +664,21 @@
     char newmacaddr[15];
 
     if (tableentry->s_fstat != RESOLVED) {
+#ifdef USE_IPV6
+        tableentry->s_fstat = revname(revlook, &(tableentry->saddr), &(tableentry->s6addr),
+#else
 	tableentry->s_fstat = revname(revlook, &(tableentry->saddr),
+#endif
 				      tableentry->s_fqdn, rvnfd);
 	strcpy(tableentry->oth_connection->d_fqdn, tableentry->s_fqdn);
 	tableentry->oth_connection->d_fstat = tableentry->s_fstat;
     }
     if (tableentry->d_fstat != RESOLVED) {
+#ifdef USE_IPV6
+       tableentry->d_fstat = revname(revlook, &(tableentry->daddr), &(tableentry->d6addr),
+#else
 	tableentry->d_fstat = revname(revlook, &(tableentry->daddr),
+#endif
 				      tableentry->d_fqdn, rvnfd);
 	strcpy(tableentry->oth_connection->s_fqdn, tableentry->d_fqdn);
 	tableentry->oth_connection->s_fstat = tableentry->d_fstat;
diff --exclude='*~' --exclude='.*' -I '$Id:' -urN iptraf-2.7.0.orig/src/tcptable.h iptraf-2.7.0/src/tcptable.h
--- iptraf-2.7.0.orig/src/tcptable.h	2005-07-18 19:03:33.000000000 -0400
+++ iptraf-2.7.0/src/tcptable.h	2005-07-18 19:03:48.000000000 -0400
@@ -46,6 +46,10 @@
 struct tcptableent {
     struct in_addr saddr;
     struct in_addr daddr;
+#ifdef USE_IPV6
+    struct in6_addr s6addr;
+    struct in6_addr d6addr;
+#endif
     char s_fqdn[45];		/* fully-qualified domain names */
     char d_fqdn[45];
     int s_fstat;
@@ -120,6 +124,9 @@
 struct tcptableent *addentry(struct tcptable *table,
 			     unsigned long int saddr,
 			     unsigned long int daddr,
+#ifdef USE_IPV6
+			     uint8_t *s6addr, uint8_t *d6addr,
+#endif
 			     unsigned int sport, unsigned int dport,
 			     int protocol,
 			     char *ifname, int *rev_lookup, int rvnamedon,
@@ -128,6 +135,9 @@
 
 struct tcptableent *in_table(struct tcptable *table,
 			     unsigned long saddr, unsigned long daddr,
+#ifdef USE_IPV6
+                             uint8_t *s6addr, uint8_t *d6addr,
+#endif
 			     unsigned int sport, unsigned int dport,
 			     char *ifname,
 			     int logging, FILE * logfile, int *nomem,
