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 "); + mvwprintw(win, 14, 2, "inspired by 2.7.0 diff by Guy Martin "); 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 #include #include +#include #include #include #include @@ -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 #include #include +#include +#include #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 #include #include +#include +#include #include #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 #include #include +#include #include #include #include @@ -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 #include #include +#include #include #include #include @@ -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,