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

Reply via email to