Package: iptraf Version: 3.0.0-6 Severity: normal Tags: patch Hello,
This bug has been bugging me for a while and I finally chased it down. I'd send a report upstream, but the original source won't compile for me, so I can only test the Debian-patched version. According to the HTML docs, "filters are used to control the information displayed by all facilities." When iptraf has a TCP/UDP port filter applied, though, most of the services don't show any traffic flow at all, even when the filter should be accepting some traffic. Here's a list of what services work properly: IP traffic monitor Statistical breakdowns --> By TCP/UDP port Here's a list of what services do not work: General interface statistics Detailed interface statistics Statistical breakdowns --> By packet size LAN station monitor Steps to reproduce: 1. Run iptraf and make a new filter: --> Filters... --> IP... --> Define new filter. Name the filter "tcp port 80" (for example), and hit enter. Set the source port to 80 (so it says "80 to 0") Put a "Y" in the protocol matching field for TCP. Leave the rest of the fields alone and hit <Enter> to accept. Hit <Ctrl-X> to exit. 2. Apply the new "tcp port 80" filter: --> Apply filter... --> tcp port 80 Now hit <X> a couple times to go back to the main menu. 3. Go to the IP traffic monitor. You should see only TCP port 80 traffic. I suggest starting a download in another terminal to make a reliable stream of traffic: $ wget -O /dev/null --limit-rate=2k \ http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.3.tar.bz2 4. Once you've verified that the filter is correctly filtering, hit <X> to go back to the main menu and then go to the General interface statistics. Notice that none of the interfaces are showing any traffic. 5. Check the other services if you want. IP traffic monitor and the TCP/UDP statistics are the only ones that work. Technical details: Each iptraf service filters packets by calling the processpacket() function. processpacket() is responsible for parsing out the TCP/UDP source and destination ports and calling ipfilter(), which does the actual packet matching work. processpacket() also has a pair of pointer arguments, *sport and *dport, by which it can return the source and destination ports to the caller; a couple services need this, and the rest just set those two arguments to NULL. The problem is that processpacket() only parses out the source and destination ports when *sport and *dport are not NULL. When they are NULL, processpacket() calls ipfilter() with the source/destination port arguments set to 0. ipfilter() then filters out every packet it sees, since none of them appear to match the port defined in the filter. I am attaching two patches that solve the problem in two different ways. The first patch modifies every caller of processpacket() to pass non-NULL pointers for *sport and *dport. I don't think this is as clean as the second patch, but it was my first approach, so I thought I'd send it anyway. The second patch modifies processpacket() to remove the NULL check that prevents the parsing of the TCP/UDP ports. I think this is safe because: a. The ports are only parsed if the protocol is TCP or UDP. b. sport and dport are never dereferenced. c. There's already a separate NULL check before assigning to *sport and *dport Note that it's not necessary to apply both patches. Either one will suffice. I'm not familiar with the iptraf code, but I haven't encountered any problems after applying either patch. I've tested each service with and without a filter applied, and they all seem to work properly. Thanks, Corey -- System Information: Debian Release: 5.0 APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 2.6.28.2 Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1) Shell: /bin/sh linked to /bin/bash Versions of packages iptraf depends on: ii libc6 2.7-18 GNU C Library: Shared libraries ii libncurses5 5.7+20090124-1 shared libraries for terminal hand iptraf recommends no packages. iptraf suggests no packages. -- no debconf information
diff -ur iptraf-3.0.0.orig/src/hostmon.c iptraf-3.0.0/src/hostmon.c --- iptraf-3.0.0.orig/src/hostmon.c 2009-02-03 14:55:53.000000000 -0800 +++ iptraf-3.0.0/src/hostmon.c 2009-02-03 14:53:02.000000000 -0800 @@ -892,8 +892,9 @@ } } if (br > 0) { + unsigned int sport = 0, dport = 0; /* TCP/UDP port values */ pkt_result = processpacket(buf, &ipacket, &br, NULL, - NULL, NULL, &fromaddr, &linktype, + &sport, &dport, &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, ifname, ifptr); diff -ur iptraf-3.0.0.orig/src/ifstats.c iptraf-3.0.0/src/ifstats.c --- iptraf-3.0.0.orig/src/ifstats.c 2009-02-03 14:55:53.000000000 -0800 +++ iptraf-3.0.0/src/ifstats.c 2009-02-03 14:20:41.000000000 -0800 @@ -581,8 +581,9 @@ } } if (br > 0) { + unsigned int sport = 0, dport = 0; /* TCP/UDP port values */ pkt_result = - processpacket(buf, &packet, &br, NULL, NULL, NULL, + processpacket(buf, &packet, &br, NULL, &sport, &dport, &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, ifname, NULL); @@ -1068,8 +1069,9 @@ } if (br > 0) { framelen = br; + unsigned int sport = 0, dport = 0; /* TCP/UDP port values */ pkt_result = processpacket(buf, &packet, &br, NULL, - NULL, NULL, &fromaddr, + &sport, &dport, &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, ifname, iface); diff -ur iptraf-3.0.0.orig/src/pktsize.c iptraf-3.0.0/src/pktsize.c --- iptraf-3.0.0.orig/src/pktsize.c 2009-02-03 14:55:53.000000000 -0800 +++ iptraf-3.0.0/src/pktsize.c 2009-02-03 14:53:38.000000000 -0800 @@ -334,8 +334,9 @@ } } if (br > 0) { + unsigned int sport = 0, dport = 0; /* TCP/UDP port values */ pkt_result = - processpacket(buf, &ipacket, &br, NULL, NULL, NULL, + processpacket(buf, &ipacket, &br, NULL, &sport, &dport, &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, iface, ifname);
diff -ur iptraf-3.0.0.orig/src/packet.c iptraf-3.0.0/src/packet.c --- iptraf-3.0.0.orig/src/packet.c 2009-02-03 14:55:53.000000000 -0800 +++ iptraf-3.0.0/src/packet.c 2009-02-03 15:02:58.000000000 -0800 @@ -395,8 +395,7 @@ if (hdr_check != ip_checksum) return CHECKSUM_ERROR; - if ((ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP) && - (sport != NULL && dport != NULL)) { + if (ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP) { /* * Process TCP/UDP fragments */ Only in iptraf-3.0.0/src: .packet.c.swp