SPECS/iptraf/iptraf-3.0.1-ipv6.patch
61fc1de6
 diff -up iptraf-3.0.1/src/attrs.h.ipv6 iptraf-3.0.1/src/attrs.h
 --- iptraf-3.0.1/src/attrs.h.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/attrs.h	2008-09-02 13:57:02.000000000 +0200
 @@ -29,3 +29,5 @@ extern int ARPATTR;
  extern int GREATTR;
  extern int UNKNIPATTR;
  extern int UNKNATTR;
 +extern int IPV6ATTR;
 +extern int ICMPV6ATTR;
 diff -up iptraf-3.0.1/src/deskman.c.ipv6 iptraf-3.0.1/src/deskman.c
 --- iptraf-3.0.1/src/deskman.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/deskman.c	2008-09-02 13:57:02.000000000 +0200
 @@ -56,7 +56,8 @@ int GREATTR;
  int ARPATTR;
  int UNKNIPATTR;
  int UNKNATTR;
 -
 +int IPV6ATTR;
 +int ICMPV6ATTR;
  
  /*  draw the basic desktop common to my screen-oriented programs */
  
 @@ -89,7 +90,8 @@ void about()
      PANEL *panel;
      int ch;
  
 -    win = newwin(15, 50, (LINES - 15) / 2, (COLS - 50) / 2);
 +    win = newwin(18, 62, (LINES - 17) / 2, (COLS - 62) / 2);
 +
      panel = new_panel(win);
  
      tx_stdwinset(win);
 @@ -108,9 +110,12 @@ void about()
      mvwprintw(win, 10, 2,
                "Public License Version 2 or any later version.");
      mvwprintw(win, 11, 2, "See the included LICENSE file for details.");
 +    mvwprintw(win, 13, 2, "IPv6 support by Markus Ullmann <mail@markus-ullmann.de>");
 +    mvwprintw(win, 14, 2, "inspired by 2.7.0 diff by Guy Martin <gmsoft@tuxicoman.be>");
  
      wattrset(win, HIGHATTR);
 -    mvwprintw(win, 13, 2, ANYKEY_MSG);
 +
 +    mvwprintw(win, 16, 2, ANYKEY_MSG);
  
      update_panels();
      doupdate();
 @@ -252,6 +257,8 @@ void standardcolors(int color)
          ARPATTR = COLOR_PAIR(5) | A_BOLD;
          GREATTR = COLOR_PAIR(1);
          UNKNIPATTR = COLOR_PAIR(19) | A_BOLD;
 +	ICMPV6ATTR = COLOR_PAIR(19) | A_BOLD;
 +	IPV6ATTR = COLOR_PAIR(19);
          UNKNATTR = COLOR_PAIR(4) | A_BOLD;
      } else {
          STDATTR = A_REVERSE;
 @@ -281,6 +288,7 @@ void standardcolors(int color)
          ARPATTR = A_BOLD;
          GREATTR = A_BOLD;
          UNKNIPATTR = A_BOLD;
 +	ICMPV6ATTR = A_REVERSE;
          UNKNATTR = A_BOLD;
      }
  
 diff -up iptraf-3.0.1/src/ifstats.c.ipv6 iptraf-3.0.1/src/ifstats.c
 --- iptraf-3.0.1/src/ifstats.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/ifstats.c	2008-09-02 13:57:02.000000000 +0200
 @@ -1,4 +1,3 @@
 -
  /***
  
  ifstats.c	- the interface statistics module
 @@ -34,6 +33,7 @@ details.
  #include <linux/if_packet.h>
  #include <net/if.h>
  #include <netinet/ip.h>
 +#include <netinet/ip6.h>
  #include <netinet/tcp.h>
  #include <netinet/udp.h>
  #include <linux/if_ether.h>
 @@ -252,7 +252,7 @@ void updaterates(struct iftab *table, in
  
      wattrset(table->statwin, HIGHATTR);
      do {
 -        wmove(table->statwin, ptmp->index - idx, 52 * COLS / 80);
 +	wmove(table->statwin, ptmp->index - idx, 60 * COLS / 80);
          if (unit == KBITS) {
              ptmp->rate =
                  ((float) (ptmp->spanbr * 8 / 1000)) /
 @@ -286,13 +286,15 @@ void printifentry(struct iflist *ptmp, W
      wmove(win, target_row, 1);
      wprintw(win, "%s", ptmp->ifname);
      wattrset(win, HIGHATTR);
 -    wmove(win, target_row, 12 * COLS / 80);
 +    wmove(win, target_row, 9  * COLS / 80);
      printlargenum(ptmp->total, win);
 -    wmove(win, target_row, 22 * COLS / 80);
 +    wmove(win, target_row, 19 * COLS / 80);
      printlargenum(ptmp->iptotal, win);
 -    wmove(win, target_row, 32 * COLS / 80);
 +    wmove(win, target_row, 29 * COLS / 80);
 +    printlargenum(ptmp->ip6total, win);
 +    wmove(win, target_row, 39 * COLS / 80);
      printlargenum(ptmp->noniptotal, win);
 -    wmove(win, target_row, 42 * COLS / 80);
 +    wmove(win, target_row, 29 * COLS / 80);
      wprintw(win, "%8lu", ptmp->badtotal);
  }
  
 @@ -320,15 +322,19 @@ void labelstats(WINDOW * win)
  {
      wmove(win, 0, 1);
      wprintw(win, " Iface ");
 -    wmove(win, 0, 16 * COLS / 80);
 +    wmove(win, 0, 12 * COLS / 80);
      wprintw(win, " Total ");
 -    wmove(win, 0, 29 * COLS / 80);
 +    wmove(win, 0, 22 * COLS / 80);
 +    wprintw(win, " IPv4 ");
 +    wmove(win, 0, 32 * COLS / 80);
 +    wprintw(win, " IPv6 ");
 +    wmove(win, 0, 42 * COLS / 80);
      wprintw(win, " IP ");
      wmove(win, 0, 36 * COLS / 80);
      wprintw(win, " NonIP ");
 -    wmove(win, 0, 45 * COLS / 80);
 +    wmove(win, 0, 51 * COLS / 80);
      wprintw(win, " BadIP ");
 -    wmove(win, 0, 55 * COLS / 80);
 +    wmove(win, 0, 65 * COLS / 80);
      wprintw(win, " Activity ");
  }
  
 @@ -422,6 +428,8 @@ void ifstats(const struct OPTIONS *optio
      char *packet;
      int pkt_result = 0;
  
 +    unsigned int iphlen;
 +
      struct sockaddr_ll fromaddr;
      unsigned short linktype;
  
 @@ -590,6 +598,18 @@ void ifstats(const struct OPTIONS *optio
                      && pkt_result != MORE_FRAGMENTS)
                      continue;
  
 +		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, NULL, NULL,
 +                                  &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, ifname, NULL);
 +	                if (pkt_result != PACKET_OK
 +    	                && pkt_result != MORE_FRAGMENTS)
 +        	        continue;
 +    	        }
                  positionptr(&table, &ptmp, ifname);
  
                  ptmp->total++;
 @@ -604,6 +624,8 @@ void ifstats(const struct OPTIONS *optio
                          (ptmp->badtotal)++;
                          continue;
                      }
 +                } else if (fromaddr.sll_protocol == ETH_P_IPV6) {
 +                    ptmp->ip6total++;
                  } else {
                      (ptmp->noniptotal)++;
                  }
 @@ -654,19 +676,20 @@ void printdetlabels(WINDOW * win, struct
                "Packets      Bytes     Packets      Bytes     Packets      Bytes");
      wattrset(win, STDATTR);
      mvwprintw(win, 4, 2, "Total:");
 -    mvwprintw(win, 5, 2, "IP:");
 -    mvwprintw(win, 6, 2, "TCP:");
 -    mvwprintw(win, 7, 2, "UDP:");
 -    mvwprintw(win, 8, 2, "ICMP:");
 -    mvwprintw(win, 9, 2, "Other IP:");
 -    mvwprintw(win, 10, 2, "Non-IP:");
 -    mvwprintw(win, 13, 2, "Total rates:");
 -    mvwprintw(win, 16, 2, "Incoming rates:");
 -    mvwprintw(win, 19, 2, "Outgoing rates:");
 -
 -    mvwprintw(win, 13, 45, "Broadcast packets:");
 -    mvwprintw(win, 14, 45, "Broadcast bytes:");
 -    mvwprintw(win, 18, 45, "IP checksum errors:");
 +    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:");
  
      update_panels();
      doupdate();
 @@ -707,38 +730,41 @@ void printdetails(struct iftotals *total
                   totals->iptotal_in, totals->ipbtotal_in,
                   totals->iptotal_out, totals->ipbtotal_out);
  
 -    printstatrow(win, 6, totals->tcptotal, totals->tcpbtotal,
 +    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);
 +		 totals->tcptotal_out, totals->tcpbtotal_out);
  
 -    printstatrow(win, 7, totals->udptotal, totals->udpbtotal,
 +    printstatrow(win, 8, totals->udptotal, totals->udpbtotal,
                   totals->udptotal_in, totals->udpbtotal_in,
                   totals->udptotal_out, totals->udpbtotal_out);
  
 -    printstatrow(win, 8, totals->icmptotal, totals->icmpbtotal,
 +    printstatrow(win, 9, totals->icmptotal, totals->icmpbtotal,
                   totals->icmptotal_in, totals->icmpbtotal_in,
                   totals->icmptotal_out, totals->icmpbtotal_out);
  
 -    printstatrow(win, 9, totals->othtotal, totals->othbtotal,
 +    printstatrow(win, 10, totals->othtotal, totals->othbtotal,
                   totals->othtotal_in, totals->othbtotal_in,
                   totals->othtotal_out, totals->othbtotal_out);
  
      /* Print non-IP totals */
  
 -    printstatrow(win, 10, totals->noniptotal, totals->nonipbtotal,
 +    printstatrow(win, 11, totals->noniptotal, totals->nonipbtotal,
                   totals->noniptotal_in, totals->nonipbtotal_in,
                   totals->noniptotal_out, totals->nonipbtotal_out);
  
      /* Broadcast totals */
 -
 -    wmove(win, 13, 67);
 -    printlargenum(totals->bcast, win);
      wmove(win, 14, 67);
 +    printlargenum(totals->bcast, win);
 +    wmove(win, 15, 67);
      printlargenum(totals->bcastbytes, win);
  
      /* Bad packet count */
  
 -    mvwprintw(win, 18, 68, "%8lu", totals->badtotal);
 +    mvwprintw(win, 19, 68, "%8lu", totals->badtotal);
  }
  
  
 @@ -757,6 +783,7 @@ void detstats(char *iface, const struct 
      char buf[MAX_PACKET_SIZE];
      char *packet;
      struct iphdr *ipacket = NULL;
 +    struct ip6_hdr *ip6packet = NULL;
      char *tpacket;
      unsigned int iphlen;
  
 @@ -962,15 +989,15 @@ void detstats(char *iface, const struct 
              starttime = now;
  
              wattrset(statwin, HIGHATTR);
 -            mvwprintw(statwin, 13, 19, "%8.1f %s/sec", activity,
 +            mvwprintw(statwin, 14, 19, "%8.1f %s/sec", activity,
                        unitstring);
 -            mvwprintw(statwin, 14, 19, "%8.1f packets/sec", pps);
 -            mvwprintw(statwin, 16, 19, "%8.1f %s/sec", activity_in,
 +            mvwprintw(statwin, 15, 19, "%8.1f packets/sec", pps);
 +            mvwprintw(statwin, 17, 19, "%8.1f %s/sec", activity_in,
                        unitstring);
 -            mvwprintw(statwin, 17, 19, "%8.1f packets/sec", pps_in);
 -            mvwprintw(statwin, 19, 19, "%8.1f %s/sec", activity_out,
 +            mvwprintw(statwin, 18, 19, "%8.1f packets/sec", pps_in);
 +            mvwprintw(statwin, 20, 19, "%8.1f %s/sec", activity_out,
                        unitstring);
 -            mvwprintw(statwin, 20, 19, "%8.1f packets/sec", pps_out);
 +            mvwprintw(statwin, 21, 19, "%8.1f packets/sec", pps_out);
  
              if (activity > peakactivity)
                  peakactivity = activity;
 @@ -1077,6 +1104,18 @@ void detstats(char *iface, const struct 
              if (pkt_result != PACKET_OK && pkt_result != MORE_FRAGMENTS)
                  continue;
  
 +            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, NULL, NULL,
 +                              &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, ifname, NULL);
 +                    if (pkt_result != PACKET_OK && pkt_result != MORE_FRAGMENTS)
 +                        continue;
 +            }
 +
              totals.total++;
              totals.bytestotal += framelen;
  
 @@ -1185,8 +1224,73 @@ void detstats(char *iface, const struct 
                      }
                      break;
                  }
 +            } 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;
 +                }
              } else {
 -                totals.noniptotal++;
 +		 totals.noniptotal++;
                  totals.nonipbtotal += br;
  
                  if (fromaddr.sll_pkttype == PACKET_OUTGOING) {
 diff -up iptraf-3.0.1/src/ifstats.h.ipv6 iptraf-3.0.1/src/ifstats.h
 --- iptraf-3.0.1/src/ifstats.h.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/ifstats.h	2008-09-02 13:57:02.000000000 +0200
 @@ -9,6 +9,7 @@ struct iflist {
      char ifname[8];
      unsigned int encap;
      unsigned long long iptotal;
 +    unsigned long long ip6total;
      unsigned long badtotal;
      unsigned long long noniptotal;
      unsigned long long total;
 @@ -49,6 +50,13 @@ struct iftotals {
      unsigned long long ipbtotal_in;
      unsigned long long ipbtotal_out;
  
 +    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;
 +
      unsigned long long noniptotal;
      unsigned long long nonipbtotal;
      unsigned long long noniptotal_in;
 diff -up iptraf-3.0.1/src/itrafmon.c.ipv6 iptraf-3.0.1/src/itrafmon.c
 --- iptraf-3.0.1/src/itrafmon.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/itrafmon.c	2008-09-02 13:57:02.000000000 +0200
 @@ -23,6 +23,8 @@ details.
  #include <ctype.h>
  #include <winops.h>
  #include <labels.h>
 +#include <netinet/ip6.h>
 +#include <netinet/icmp6.h>
  #include "options.h"
  #include "tcptable.h"
  #include "othptab.h"
 @@ -578,6 +580,9 @@ void ipmon(struct OPTIONS *options,
      char tpacket[MAX_PACKET_SIZE];      /* raw packet data */
      char *packet = NULL;        /* network packet ptr */
      struct iphdr *ippacket;
 +    struct ip6_hdr *ip6packet;
 +    unsigned int protocol;
 +    unsigned int frag_off;
      struct tcphdr *transpacket; /* IP-encapsulated packet */
      unsigned int sport = 0, dport = 0;  /* TCP/UDP port values */
      char sp_buf[10];
 @@ -1046,9 +1051,9 @@ void ipmon(struct OPTIONS *options,
              if (pkt_result != PACKET_OK)
                  continue;
  
 -            if (fromaddr.sll_protocol != ETH_P_IP) {
 +            if ((fromaddr.sll_protocol != ETH_P_IP) && (fromaddr.sll_protocol != ETH_P_IPV6)) {
                  othpent = add_othp_entry(&othptbl, &table,
 -                                         0, 0, NOT_IP,
 +                                         0, 0, NULL, NULL, NOT_IP,
                                           fromaddr.sll_protocol,
                                           linktype, (char *) tpacket,
                                           (char *) packet, br, ifname, 0, 0,
 @@ -1056,23 +1061,52 @@ void ipmon(struct OPTIONS *options,
                                           options->servnames, 0, &nomem);
                  continue;
              } else {
 +                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, MATCH_OPPOSITE_ALWAYS, ifname, ifptr);
 +                        if (pkt_result != PACKET_OK)
 +                            continue;
 +                }
 +                if (fromaddr.sll_protocol == ETH_P_IP) {
                  ippacket = (struct iphdr *) packet;
                  iphlen = ippacket->ihl * 4;
 +                    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;
 +                }
                  transpacket = (struct tcphdr *) (packet + iphlen);
  
 -                if (ippacket->protocol == IPPROTO_TCP) {
 +        	if (protocol == IPPROTO_TCP) {
  
 +                if (ippacket != NULL)
                      tcpentry =
                          in_table(&table, ippacket->saddr, ippacket->daddr,
 -                                 ntohs(sport), ntohs(dport), ifname,
 -                                 logging, logfile, &nomem, options);
 +                            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),
 +                             ntohs(sport), ntohs(dport), ifname,
 +                             logging, logfile, &nomem, options);
  
                      /* 
                       * Add a new entry if it doesn't exist, and, 
                       * to reduce the chances of stales, not a FIN.
                       */
  
 -                    if ((ntohs(ippacket->frag_off) & 0x3fff) == 0) {    /* first frag only */
 +                    if ((ntohs(frag_off) & 0x3fff) == 0) {  /* first frag only */
                          totalhlen = iphlen + transpacket->doff * 4;
  
                          if ((tcpentry == NULL) && (!(transpacket->fin))) {
 @@ -1084,17 +1118,26 @@ void ipmon(struct OPTIONS *options,
  
                              if (!nomem) {
                                  wasempty = (table.head == NULL);
 +                                if (ippacket != NULL)
                                  tcpentry = addentry(&table, (unsigned long)
                                                      ippacket->saddr,
                                                      (unsigned long)
 -                                                    ippacket->daddr, sport,
 +                                                    ippacket->daddr,
 +                                                    NULL, NULL, sport,
                                                      dport,
                                                      ippacket->protocol,
                                                      ifname, &revlook,
                                                      rvnfd,
                                                      options->servnames,
                                                      &nomem);
 -
 +                                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);
                                  if (tcpentry != NULL) {
                                      printentry(&table,
                                                 tcpentry->oth_connection,
 @@ -1152,12 +1195,18 @@ void ipmon(struct OPTIONS *options,
                                  p_sstat = tcpentry->s_fstat;
                                  p_dstat = tcpentry->d_fstat;
                              }
 +                            if (ippacket != NULL)
                              updateentry(&table, tcpentry, transpacket,
                                          tpacket, linktype, readlen, br,
                                          ippacket->frag_off, logging,
                                          &revlook, rvnfd, options, logfile,
                                          &nomem);
 -
 +                            else
 +                            updateentry(&table, tcpentry, transpacket, tpacket,
 +                                     linktype, readlen,
 +                                     readlen, 0, logging,
 +                                     &revlook, rvnfd, options, logfile,
 +                                     &nomem);
                              /*
                               * Log first packet of a TCP connection except if
                               * it's a RST, which was already logged earlier in
 @@ -1213,7 +1262,7 @@ void ipmon(struct OPTIONS *options,
                                             screen_idx, mode);
                          }
                      }
 -                } else {        /* now for the other IP protocols */
 +            	} else if (ippacket != NULL) {
                      fragment = ((ntohs(ippacket->frag_off) & 0x1fff) != 0);
  
                      if (ippacket->protocol == IPPROTO_ICMP) {
 @@ -1234,7 +1283,7 @@ void ipmon(struct OPTIONS *options,
  
                      othpent =
                          add_othp_entry(&othptbl, &table, ippacket->saddr,
 -                                       ippacket->daddr, IS_IP,
 +                                       ippacket->daddr, NULL, NULL, IS_IP,
                                         ippacket->protocol, linktype,
                                         (char *) tpacket,
                                         (char *) transpacket, readlen,
 @@ -1242,6 +1291,21 @@ void ipmon(struct OPTIONS *options,
                                         options->timeout, logging, logfile,
                                         options->servnames, fragment,
                                         &nomem);
 +
 +            } 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);
                  }
              }
          }
 diff -up iptraf-3.0.1/src/landesc.c.ipv6 iptraf-3.0.1/src/landesc.c
 --- iptraf-3.0.1/src/landesc.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/landesc.c	2008-09-02 13:57:02.000000000 +0200
 @@ -208,7 +208,7 @@ void savedesclist(struct desclist *list,
      else if (linktype == LINK_FDDI)
          fd = fopen(FDDIFILE, "w");
  
 -    if (fd < 0) {
 +    if (fd <= 0) {
          etherr();
          return;
      }
 diff -up iptraf-3.0.1/src/options.c.ipv6 iptraf-3.0.1/src/options.c
 --- iptraf-3.0.1/src/options.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/options.c	2008-09-02 13:57:02.000000000 +0200
 @@ -41,7 +41,7 @@ details.
  
  void makeoptionmenu(struct MENU *menu)
  {
 -    tx_initmenu(menu, 19, 40, (LINES - 19) / 2 - 1, (COLS - 40) / 16,
 +    tx_initmenu(menu, 20, 40, (LINES - 19) / 2 - 1, (COLS - 40) / 16,
                  BOXATTR, STDATTR, HIGHATTR, BARSTDATTR, BARHIGHATTR,
                  DESCATTR);
      tx_additem(menu, " ^R^everse DNS lookups",
 @@ -58,6 +58,8 @@ void makeoptionmenu(struct MENU *menu)
                 "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");
 +    tx_additem(menu, " ^S^how v6-in-v4 traffic as IPv6",
 +               "Toggled display of IPv6 tunnel in IPv4 as IPv6 traffic");
      tx_additem(menu, NULL, NULL);
      tx_additem(menu, " ^T^imers...", "Configures timeouts and intervals");
      tx_additem(menu, NULL, NULL);
 @@ -131,6 +133,8 @@ void indicatesetting(int row, struct OPT
      case 7:
          printoptonoff(options->mac, win);
          break;
 +    case 8:
 +        printoptonoff(options->v6inv4asv6, win);
      }
  
  }
 @@ -168,6 +172,7 @@ void setdefaultopts(struct OPTIONS *opti
      options->logspan = 3600;
      options->updrate = 0;
      options->closedint = 0;
 +    options->v6inv4asv6 = 1;
  }
  
  void loadoptions(struct OPTIONS *options)
 @@ -189,17 +194,17 @@ void loadoptions(struct OPTIONS *options
  void updatetimes(struct OPTIONS *options, WINDOW * win)
  {
      wattrset(win, HIGHATTR);
 -    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);
 +    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);
  }
  
  void showoptions(struct OPTIONS *options, WINDOW * win)
  {
      int i;
  
 -    for (i = 1; i <= 7; i++)
 +    for (i = 1; i <= 8; i++)
          indicatesetting(i, options, win);
  
      updatetimes(options, win);
 @@ -272,13 +277,13 @@ void setoptions(struct OPTIONS *options,
      }
      makeoptionmenu(&menu);
  
 -    statwin = newwin(14, 35, (LINES - 19) / 2 - 1, (COLS - 40) / 16 + 40);
 +    statwin = newwin(15, 35, (LINES - 19) / 2 - 1, (COLS - 40) / 16 + 40);
      statpanel = new_panel(statwin);
  
      wattrset(statwin, BOXATTR);
      tx_colorwin(statwin);
      tx_box(statwin, ACS_VLINE, ACS_HLINE);
 -    wmove(statwin, 8, 1);
 +    wmove(statwin, 9, 1);
      whline(statwin, ACS_HLINE, 33);
      mvwprintw(statwin, 0, 1, " Current Settings ");
      wattrset(statwin, STDATTR);
 @@ -289,10 +294,11 @@ void setoptions(struct OPTIONS *options,
      mvwprintw(statwin, 5, 2, "Logging:");
      mvwprintw(statwin, 6, 2, "Activity mode:");
      mvwprintw(statwin, 7, 2, "MAC addresses:");
 -    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:");
 +    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:");
      showoptions(options, statwin);
  
      do {
 @@ -321,7 +327,10 @@ void setoptions(struct OPTIONS *options,
          case 7:
              options->mac = ~(options->mac);
              break;
 -        case 9:
 +        case 8:
 +            options->v6inv4asv6 = ~(options->v6inv4asv6);
 +            break;
 +        case 10:
              maketimermenu(&timermenu);
              trow = 1;
              do {
 @@ -362,22 +371,22 @@ void setoptions(struct OPTIONS *options,
              update_panels();
              doupdate();
              break;
 -        case 11:
 +        case 12:
              addmoreports(ports);
              break;
 -        case 12:
 +        case 13:
              removeaport(ports);
              break;
 -        case 14:
 +        case 15:
              ethdescmgr(LINK_ETHERNET);
              break;
 -        case 15:
 +        case 16:
              ethdescmgr(LINK_FDDI);
              break;
          }
  
          indicatesetting(row, options, statwin);
 -    } while (row != 17);
 +    } while (row != 18);
  
      tx_destroymenu(&menu);
      del_panel(statpanel);
 diff -up iptraf-3.0.1/src/options.h.ipv6 iptraf-3.0.1/src/options.h
 --- iptraf-3.0.1/src/options.h.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/options.h	2008-09-02 13:57:02.000000000 +0200
 @@ -2,7 +2,7 @@
  struct OPTIONS {
      unsigned int color:1,
          logging:1,
 -        revlook:1, servnames:1, promisc:1, actmode:1, mac:1, dummy:9;
 +        revlook:1, servnames:1, promisc:1, actmode:1, mac:1, v6inv4asv6:1, dummy:8;
      unsigned int timeout;
      unsigned int logspan;
      unsigned int updrate;
 diff -up iptraf-3.0.1/src/othptab.c.ipv6 iptraf-3.0.1/src/othptab.c
 --- iptraf-3.0.1/src/othptab.c.ipv6	2008-09-02 13:57:02.000000000 +0200
 +++ iptraf-3.0.1/src/othptab.c	2008-09-02 13:57:02.000000000 +0200
 @@ -23,6 +23,8 @@ details.
  #include <netinet/if_tr.h>
  #include <linux/netdevice.h>
  #include <netinet/if_fddi.h>
 +#include <netinet/ip6.h>
 +#include <netinet/icmp6.h>
  #include <winops.h>
  #include "arphdr.h"
  #include "options.h"
 @@ -82,16 +84,12 @@ void process_dest_unreach(struct tcptabl
                            char *ifname, int *nomem)
  {
      struct iphdr *ip;
 +    struct ip6_hdr *ip6;
      struct tcphdr *tcp;
      struct tcptableent *tcpentry;
  
      ip = (struct iphdr *) (packet + 8);
  
 -    if (ip->protocol != IPPROTO_TCP)
 -        return;
 -
 -    tcp = (struct tcphdr *) (packet + 8 + (ip->ihl * 4));
 -
      /* 
       * 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
 @@ -99,9 +97,23 @@ void process_dest_unreach(struct tcptabl
       * and set its internal timeout variable to 0.
       */
  
 -    tcpentry = in_table(table, ip->saddr, ip->daddr,
 +    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,
                          ntohs(tcp->source), ntohs(tcp->dest), ifname,
                          0, NULL, nomem, NULL);
 +    } 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);
 +    }
  
      if (tcpentry != NULL) {
          tcpentry->stat = tcpentry->oth_connection->stat = FLAG_RST;
 @@ -112,6 +124,7 @@ void process_dest_unreach(struct tcptabl
  struct othptabent *add_othp_entry(struct othptable *table,
                                    struct tcptable *tcptab,
                                    unsigned long saddr, unsigned long daddr,
 +				  struct in6_addr *s6addr, struct in6_addr *d6addr,
                                    int is_ip, int protocol,
                                    unsigned short linkproto, char *packet,
                                    char *packet2, unsigned int br,
 @@ -158,10 +171,18 @@ struct othptabent *add_othp_entry(struct
      if (is_ip) {
          new_entry->saddr = isaddr.s_addr = saddr;
          new_entry->daddr = idaddr.s_addr = daddr;
 -
 -        revname(rev_lookup, &isaddr, new_entry->s_fqdn, rvnfd);
 -        revname(rev_lookup, &idaddr, new_entry->d_fqdn, rvnfd);
 -
 +        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);
          if (!fragment) {
              if (protocol == IPPROTO_ICMP) {
                  new_entry->un.icmp.type =
 @@ -420,6 +441,14 @@ void printothpentry(struct othptable *ta
          wattrset(table->othpwin, GREATTR);
          strcpy(protname, "GRE");
          break;
 +     case IPPROTO_ICMPV6:
 +        wattrset(table->othpwin, ICMPV6ATTR);
 +        strcpy(protname, "ICMPv6");
 +        break;
 +     case IPPROTO_IPV6:
 +        wattrset(table->othpwin, IPV6ATTR);
 +        strcpy(protname, "IPv6 tun");
 +        break;
      default:
          wattrset(table->othpwin, UNKNIPATTR);
          protptr = getprotobynumber(entry->protocol);
 @@ -525,7 +554,71 @@ void printothpentry(struct othptable *ta
                  strcpy(description, "bad/unkn");
                  break;
              }
 -
 +        } 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;
 +            }
          } else if (entry->protocol == IPPROTO_OSPFIGP) {
              switch (entry->un.ospf.type) {
              case OSPF_TYPE_HELLO:
 @@ -569,11 +662,11 @@ void printothpentry(struct othptable *ta
      strcat(msgstring, scratchpad);
  
      if ((entry->protocol == IPPROTO_UDP) && (!(entry->fragment))) {
 -        sprintf(scratchpad, "from %.25s:%s to %.25s:%s",
 +        sprintf(scratchpad, "from %.40s:%s to %.40s:%s",
                  entry->s_fqdn, entry->un.udp.s_sname,
                  entry->d_fqdn, entry->un.udp.d_sname);
      } else {
 -        sprintf(scratchpad, "from %.25s to %.25s", entry->s_fqdn,
 +        sprintf(scratchpad, "from %.40s to %.40s", entry->s_fqdn,
                  entry->d_fqdn);
      }
  
 diff -up iptraf-3.0.1/src/othptab.h.ipv6 iptraf-3.0.1/src/othptab.h
 --- iptraf-3.0.1/src/othptab.h.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/othptab.h	2008-09-02 13:57:02.000000000 +0200
 @@ -34,6 +34,8 @@ Copyright (c) Gerard Paul Java 1997
  struct othptabent {
      unsigned long int saddr;
      unsigned long int daddr;
 +    struct in6_addr s6addr;
 +    struct in6_addr d6addr;
      char smacaddr[15];
      char dmacaddr[15];
      unsigned short linkproto;
 @@ -69,6 +71,10 @@ struct othptabent {
              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 +139,9 @@ void process_dest_unreach(struct tcptabl
  struct othptabent *add_othp_entry(struct othptable *table,
                                    struct tcptable *tcptab,
                                    unsigned long saddr,
 -                                  unsigned long daddr, int is_ip,
 -                                  int protocol, unsigned short linkproto,
 -                                  char *packet, char *netpacket,
 +                                  unsigned long daddr, struct in6_addr *s6addr,
 +				  struct in6_addr *d6addr, int is_ip, int protocol, 
 +				  unsigned short linkproto, char *packet, char *netpacket,
                                    unsigned int br, char *ifname,
                                    int *rev_lookup, int rvnamedon,
                                    unsigned int tm, int logging,
 diff -up iptraf-3.0.1/src/packet.c.ipv6 iptraf-3.0.1/src/packet.c
 --- iptraf-3.0.1/src/packet.c.ipv6	2007-09-25 11:21:18.000000000 +0200
 +++ iptraf-3.0.1/src/packet.c	2008-09-02 13:57:02.000000000 +0200
 @@ -28,6 +28,7 @@ details.
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <netinet/ip.h>
 +#include <netinet/ip6.h>
  #include <netinet/tcp.h>
  #include <sys/time.h>
  #include <net/if_arp.h>
 @@ -303,6 +304,7 @@ int processpacket(char *tpacket, char **
  {
      static char aligned_buf[ALIGNED_BUF_LEN];
      struct iphdr *ip;
 +    struct ip6_hdr *ip6;
      int hdr_check;
      register int ip_checksum;
      register int iphlen;
 @@ -356,7 +358,7 @@ int processpacket(char *tpacket, char **
       * Apply non-IP packet filter
       */
  
 -    if (fromaddr->sll_protocol != ETH_P_IP) {
 +    if ((fromaddr->sll_protocol != ETH_P_IP) && (fromaddr->sll_protocol != ETH_P_IPV6)) {
          if ((fromaddr->sll_protocol == ETH_P_ARP) ||
              (fromaddr->sll_protocol == ETH_P_RARP)) {
              if (!nonipfilter(filter, fromaddr->sll_protocol)) {
 @@ -370,9 +372,7 @@ int processpacket(char *tpacket, char **
          return PACKET_OK;
      }
  
 -    /*
 -     * TODO: Insert IPv6 processing code here
 -     */
 +    if (fromaddr->sll_protocol == ETH_P_IP) {
  
      /*
       * At this point, we're now processing IP packets.  Start by getting
 @@ -389,7 +389,7 @@ int processpacket(char *tpacket, char **
      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) &&
 @@ -453,9 +453,28 @@ int processpacket(char *tpacket, char **
                                             ip->protocol, match_opposite,
                                             &(filter->fl))))
              return PACKET_FILTERED;
 -    }
 -
 -    return PACKET_OK;
 +      }
 +      return PACKET_OK;
 +     }
 +     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;
  }
  
  void pkt_cleanup(void)
 diff -up iptraf-3.0.1/src/revname.c.ipv6 iptraf-3.0.1/src/revname.c
 --- iptraf-3.0.1/src/revname.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/revname.c	2008-09-02 13:57:02.000000000 +0200
 @@ -153,7 +153,7 @@ void close_rvn_socket(int fd)
      }
  }
  
 -int revname(int *lookup, struct in_addr *saddr, char *target, int rvnfd)
 +int revname(int *lookup, struct in_addr *saddr, struct in6_addr *s6addr, char *target, int rvnfd)
  {
      struct hostent *he;
      struct rvn rpkt;
 @@ -173,6 +173,11 @@ int revname(int *lookup, struct in_addr 
              rpkt.type = RVN_REQUEST;
              rpkt.saddr.s_addr = saddr->s_addr;
  
 +           if (s6addr != NULL)
 +               memcpy(rpkt.s6addr.s6_addr, s6addr->s6_addr, 16);
 +           else
 +               memset(rpkt.s6addr.s6_addr, 0, 4);
 +
              sendto(rvnfd, &rpkt, sizeof(struct rvn), 0,
                     (struct sockaddr *) &su,
                     sizeof(su.sun_family) + strlen(su.sun_path));
 @@ -197,7 +202,10 @@ int revname(int *lookup, struct in_addr 
              } while ((br < 0) && (errno == EINTR));
  
              if (br < 0) {
 +                if (saddr->s_addr != 0)
                  strcpy(target, inet_ntoa(*saddr));
 +                else
 +                    inet_ntop(AF_INET6, s6addr, target, 44);
                  printipcerr();
                  *lookup = 0;
                  return RESOLVED;
 @@ -205,18 +213,26 @@ int revname(int *lookup, struct in_addr 
              strncpy(target, rpkt.fqdn, 44);
              return (rpkt.ready);
          } else {
 -            he = gethostbyaddr((char *) saddr,
 -                               sizeof(struct in_addr), AF_INET);
 +           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);
  
 -            if (he == NULL)
 +            if (he == NULL) {
 +                if (saddr->s_addr != 0)
                  strcpy(target, inet_ntoa(*saddr));
              else
 +                inet_ntop(AF_INET6, s6addr, target, 44);
 +            } else {
                  strncpy(target, he->h_name, 44);
 +            }
  
              return RESOLVED;
          }
      } else {
 -        strcpy(target, inet_ntoa(*saddr));
 -        return RESOLVED;
 +        if (saddr->s_addr != 0 || s6addr == NULL)
 +            strcpy(target, inet_ntoa(*saddr));
 +        else
 +            inet_ntop(AF_INET6, s6addr, target, 44);
      }
  }
 diff -up iptraf-3.0.1/src/revname.h.ipv6 iptraf-3.0.1/src/revname.h
 --- iptraf-3.0.1/src/revname.h.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/revname.h	2008-09-02 13:57:02.000000000 +0200
 @@ -8,4 +8,5 @@ int rvnamedactive();
  int killrvnamed();
  void open_rvn_socket(int *fd);
  void close_rvn_socket(int fd);
 -int revname(int *lookup, struct in_addr *saddr, char *target, int rvnfd);
 +
 +int revname(int *lookup, struct in_addr *saddr, struct in6_addr *s6addr, char *target, int rvnfd);
 diff -up iptraf-3.0.1/src/rvnamed.c.ipv6 iptraf-3.0.1/src/rvnamed.c
 --- iptraf-3.0.1/src/rvnamed.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/rvnamed.c	2008-09-02 13:57:02.000000000 +0200
 @@ -55,6 +55,7 @@ details.
  
  struct hosts {
      unsigned long addr;
 +    uint8_t addr6[16];
      char fqdn[45];
      int ready;
  };
 @@ -93,12 +94,17 @@ void process_rvn_packet(struct rvn *rvnp
  
      ccfd = socket(PF_UNIX, SOCK_DGRAM, 0);
  
 -    he = gethostbyaddr((char *) &(rvnpacket->saddr),
 -                       sizeof(struct in_addr), AF_INET);
 +    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);
  
 -    if (he == NULL)
 +    if (he == NULL) {
 +      if (rvnpacket->saddr.s_addr != 0)
          strcpy(rvnpacket->fqdn, inet_ntoa(rvnpacket->saddr));
 -    else {
 +      else
 +           inet_ntop(AF_INET6, &(rvnpacket->s6addr), rvnpacket->fqdn, sizeof(rvnpacket->fqdn));
 +    } else {
          bzero(rvnpacket->fqdn, 45);
          strncpy(rvnpacket->fqdn, he->h_name, 44);
      }
 @@ -122,10 +128,14 @@ int name_resolved(struct rvn *rvnpacket,
      unsigned int i = 0;
  
      while (i != lastfree) {
 +        if (rvnpacket->saddr.s_addr != 0) {
          if ((rvnpacket->saddr.s_addr == hostlist[i].addr)
              && (hostlist[i].ready == RESOLVED))
              return i;
 -
 +        } else {
 +            if (!memcmp(rvnpacket->s6addr.s6_addr, hostlist[i].addr6, sizeof(hostlist[i].addr6)))
 +            return i;
 +        }
          i++;
      }
  
 @@ -300,7 +310,8 @@ int main(void)
                  hi = 0;
  
                  while (hi <= lastfree) {
 -                    if (hostlist[hi].addr == rvnpacket.saddr.s_addr)
 +                    if ((hostlist[hi].addr == rvnpacket.saddr.s_addr) &&
 +                        !memcmp(rvnpacket.s6addr.s6_addr, hostlist[hi].addr6, sizeof(hostlist[hi].addr6)))
                          break;
                      hi++;
                  }
 @@ -313,6 +324,7 @@ int main(void)
                          hostindex = 0;
  
                      hostlist[hi].addr = rvnpacket.saddr.s_addr;
 +                    memcpy(hostlist[hi].addr6, rvnpacket.s6addr.s6_addr, sizeof(hostlist[hi].addr6));
                  }
                  strncpy(hostlist[hi].fqdn, rvnpacket.fqdn, 44);
  
 @@ -400,6 +412,8 @@ int main(void)
                                   */
                                  hostlist[hostindex].addr =
                                      rvnpacket.saddr.s_addr;
 +                                memcpy(hostlist[hostindex].addr6, rvnpacket.s6addr.s6_addr,
 +                                        sizeof(hostlist[hostindex].addr6));
                                  hostlist[hostindex].ready = RESOLVING;
  
                                  maxlogged = 0;
 @@ -455,7 +469,10 @@ int main(void)
                          }
                          rvnpacket.type = RVN_REPLY;
                          bzero(rvnpacket.fqdn, 45);
 +                        if (rvnpacket.saddr.s_addr != 0)
                          strcpy(rvnpacket.fqdn, inet_ntoa(rvnpacket.saddr));
 +                        else
 +                            inet_ntop(AF_INET6, &rvnpacket.s6addr, rvnpacket.fqdn, sizeof(rvnpacket.fqdn));
                          rvnpacket.ready = RESOLVING;
  
                          br = sendto(ifd, &rvnpacket, sizeof(struct rvn), 0,
 diff -up iptraf-3.0.1/src/rvnamed.h.ipv6 iptraf-3.0.1/src/rvnamed.h
 --- iptraf-3.0.1/src/rvnamed.h.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/rvnamed.h	2008-09-02 13:57:02.000000000 +0200
 @@ -22,5 +22,6 @@ struct rvn {
      int type;
      int ready;
      struct in_addr saddr;
 +    struct in6_addr s6addr;
      char fqdn[45];
  };
 diff -up iptraf-3.0.1/src/serv.c.ipv6 iptraf-3.0.1/src/serv.c
 --- iptraf-3.0.1/src/serv.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/serv.c	2008-09-02 13:57:02.000000000 +0200
 @@ -31,6 +31,7 @@ details.
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <netinet/ip.h>
 +#include <netinet/ip6.h>
  #include <netinet/udp.h>
  #include <linux/if_packet.h>
  #include <linux/if_ether.h>
 @@ -1032,6 +1033,8 @@ void servmon(char *ifname, struct portta
              if (pkt_result != PACKET_OK)
                  continue;
  
 +	    if (fromaddr.sll_protocol == ETH_P_IP) {
 +
              if ((((struct iphdr *) ipacket)->protocol == IPPROTO_TCP)
                  || (((struct iphdr *) ipacket)->protocol == IPPROTO_UDP)) {
                  updateportent(&list, ((struct iphdr *) ipacket)->protocol,
 @@ -1049,6 +1052,26 @@ void servmon(char *ifname, struct portta
                  }
              }
          }
 +        } else {
 +            if ((((struct ip6_hdr *) ipacket)->ip6_nxt == IPPROTO_TCP)
 +                || (((struct ip6_hdr *) ipacket)->ip6_nxt ==
 +                    IPPROTO_UDP)) {
 +                updateportent(&list, ((struct ip6_hdr *) ipacket)->ip6_nxt,
 +                    ntohs(sport),
 +                    ntohs(((struct ip6_hdr *) ipacket)->ip6_plen + 40),
 +                    idx, 0, ports, options->servnames);
 +                updateportent(&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;
 +                }
 +            }
 +        }
      }
  
      if (logging) {
 diff -up iptraf-3.0.1/src/tcptable.c.ipv6 iptraf-3.0.1/src/tcptable.c
 --- iptraf-3.0.1/src/tcptable.c.ipv6	2005-09-13 08:42:54.000000000 +0200
 +++ iptraf-3.0.1/src/tcptable.c	2008-09-02 13:57:02.000000000 +0200
 @@ -59,8 +59,8 @@ void setlabels(WINDOW * win, int mode)
   * The hash function for the TCP hash table
   */
  
 -unsigned int tcp_hash(unsigned long saddr, unsigned int sport,
 -                      unsigned long daddr, unsigned int dport,
 +unsigned int tcp_hash(unsigned long saddr, uint32_t *s6addr, unsigned int sport,
 +                      unsigned long daddr, uint32_t *d6addr, unsigned int dport,
                        char *ifname)
  {
      int i;
 @@ -69,6 +69,13 @@ unsigned int tcp_hash(unsigned long sadd
      for (i = 0; i <= strlen(ifname) - 1; i++)
          ifsum += ifname[i];
  
 +    if (s6addr != 0 && d6addr != 0) {
 +       for (i = 0; i < 4; i++) {
 +               saddr ^= s6addr[i];
 +               daddr ^= d6addr[i];
 +       }
 +    }
 +
      return ((ifsum + (4 * saddr) + (3 * sport) +
               (2 * daddr) + dport) % ENTRIES_IN_HASH_TABLE);
  }
 @@ -139,8 +146,8 @@ int add_tcp_hash_entry(struct tcptable *
      unsigned int hp;            /* hash position in table */
      struct tcp_hashentry *ptmp;
  
 -    hp = tcp_hash(entry->saddr.s_addr, entry->sport,
 -                  entry->daddr.s_addr, entry->dport, entry->ifname);
 +    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);
  
      ptmp = malloc(sizeof(struct tcp_hashentry));
      bzero(ptmp, sizeof(struct tcp_hashentry));
 @@ -215,6 +222,8 @@ void del_tcp_hash_node(struct tcptable *
  struct tcptableent *addentry(struct tcptable *table,
                               unsigned long int saddr,
                               unsigned long int daddr,
 +                             uint8_t *s6addr,
 +                             uint8_t *d6addr,
                               unsigned int sport, unsigned int dport,
                               int protocol,
                               char *ifname, int *rev_lookup,
 @@ -311,8 +320,22 @@ struct tcptableent *addentry(struct tcpt
  
      new_entry->saddr.s_addr = new_entry->oth_connection->daddr.s_addr =
          saddr;
 +    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);
 +    }
      new_entry->daddr.s_addr = new_entry->oth_connection->saddr.s_addr =
          daddr;
 +    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);
 +    }
      new_entry->protocol = protocol;
  
      /*
 @@ -349,9 +372,10 @@ struct tcptableent *addentry(struct tcpt
  
      new_entry->stat = new_entry->oth_connection->stat = 0;
  
 -    new_entry->s_fstat = revname(rev_lookup, &(new_entry->saddr),
 +    new_entry->s_fstat = revname(rev_lookup, &(new_entry->saddr), &new_entry->s6addr,
                                   new_entry->s_fqdn, rvnfd);
 -    new_entry->d_fstat = revname(rev_lookup, &(new_entry->daddr),
 +
 +    new_entry->d_fstat = revname(rev_lookup, &(new_entry->daddr), &new_entry->d6addr,
                                   new_entry->d_fqdn, rvnfd);
  
      /*
 @@ -490,7 +514,8 @@ void write_timeout_log(int logging, FILE
  }
  
  struct tcptableent *in_table(struct tcptable *table, unsigned long saddr,
 -                             unsigned long daddr, unsigned int sport,
 +                             unsigned long daddr, uint8_t *s6addr,
 +                             uint8_t *d6addr, unsigned int sport,
                               unsigned int dport, char *ifname,
                               int logging, FILE * logfile,
                               int *nomem, struct OPTIONS *opts)
 @@ -503,6 +528,9 @@ struct tcptableent *in_table(struct tcpt
      time_t now;
      time_t timeout;
  
 +    int sfree = 0;
 +    int dfree = 0;
 +
      if (opts != NULL)
          timeout = opts->timeout;
      else
 @@ -515,12 +543,24 @@ struct tcptableent *in_table(struct tcpt
       * Determine hash table index for this set of addresses and ports
       */
  
 -    hp = tcp_hash(saddr, sport, daddr, dport, ifname);
 +    hp = tcp_hash(saddr, (uint32_t*) s6addr, sport, daddr, (uint32_t*) d6addr, dport, ifname);
      hashptr = table->hash_table[hp];
  
 +    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;
 +    }
      while (hashptr != NULL) {
          if ((hashptr->tcpnode->saddr.s_addr == saddr) &&
 +            (!memcmp(&hashptr->tcpnode->s6addr.s6_addr, s6addr, 16)) &&
              (hashptr->tcpnode->daddr.s_addr == daddr) &&
 +            (!memcmp(&hashptr->tcpnode->d6addr.s6_addr, d6addr, 16)) &&
              (hashptr->tcpnode->sport == sport) &&
              (hashptr->tcpnode->dport == dport) &&
              (strcmp(hashptr->tcpnode->ifname, ifname) == 0))
 @@ -549,6 +589,9 @@ struct tcptableent *in_table(struct tcpt
          hashptr = hashptr->next_entry;
      }
  
 +    if (sfree) free(s6addr);
 +    if (dfree) free(d6addr);
 +
      if (hashptr != NULL) {      /* needed to avoid SIGSEGV */
          if ((((hashptr->tcpnode->finsent == 2) &&
                (hashptr->tcpnode->oth_connection->finsent == 2))) ||
 @@ -579,13 +622,13 @@ void updateentry(struct tcptable *table,
      char newmacaddr[15];
  
      if (tableentry->s_fstat != RESOLVED) {
 -        tableentry->s_fstat = revname(revlook, &(tableentry->saddr),
 +        tableentry->s_fstat = revname(revlook, &(tableentry->saddr), &(tableentry->s6addr),
                                        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) {
 -        tableentry->d_fstat = revname(revlook, &(tableentry->daddr),
 +       tableentry->d_fstat = revname(revlook, &(tableentry->daddr), &(tableentry->d6addr),
                                        tableentry->d_fqdn, rvnfd);
          strcpy(tableentry->oth_connection->s_fqdn, tableentry->d_fqdn);
          tableentry->oth_connection->s_fstat = tableentry->d_fstat;
 diff -up iptraf-3.0.1/src/tcptable.h.ipv6 iptraf-3.0.1/src/tcptable.h
 --- iptraf-3.0.1/src/tcptable.h.ipv6	2008-09-02 13:57:02.000000000 +0200
 +++ iptraf-3.0.1/src/tcptable.h	2008-09-02 13:57:02.000000000 +0200
 @@ -47,6 +47,8 @@
  struct tcptableent {
      struct in_addr saddr;
      struct in_addr daddr;
 +    struct in6_addr s6addr;
 +    struct in6_addr d6addr;
      char s_fqdn[45];            /* fully-qualified domain names */
      char d_fqdn[45];
      int s_fstat;
 @@ -121,6 +123,7 @@ void init_tcp_table(struct tcptable *tab
  struct tcptableent *addentry(struct tcptable *table,
                               unsigned long int saddr,
                               unsigned long int daddr,
 +                             uint8_t *s6addr, uint8_t *d6addr,
                               unsigned int sport, unsigned int dport,
                               int protocol,
                               char *ifname, int *rev_lookup, int rvnamedon,
 @@ -128,6 +131,7 @@ struct tcptableent *addentry(struct tcpt
  
  struct tcptableent *in_table(struct tcptable *table,
                               unsigned long saddr, unsigned long daddr,
 +                             uint8_t *s6addr, uint8_t *d6addr,
                               unsigned int sport, unsigned int dport,
                               char *ifname,
                               int logging, FILE * logfile, int *nomem,