tcpdump mailing list archives

Re: [Patch/Workaround?] pcap-usb-linux.c


From: Jean-Louis <jelot-tcpdump () jelot it>
Date: Thu, 30 Oct 2008 12:48:42 +0100

Jean-Louis ha scritto:
Jean-Louis ha scritto:
today I have found some bug on pcap-usb-linux.c

now i can try to tell you which are


in accordance with usbmon.txt in "mmap mode" the data is at

&mmap_area[vec[i]] + 64;

rather than

&mmap_area[vec[i]] + 48;

with mmap ther'is 16Byte filled with 0 first to the real data...

so if i.e. I have caplen = 18Byte, in file.pcap I have 16Byte with garbage (0x00) and only 2Byte with real data other 16Byte of real data is lost.

the mmap mode is *default* with kernel >= 2.6.25-rc8-mm1

I'm newbie with libpcap and I don't know how I can fix that without degrading performance

I have patched this bug, but seems to be workaround-ish

so now pcap file is ok
Index: pcap-usb-linux.c
===================================================================
RCS file: /home/jean-louis/cvsroot/libpcap/pcap-usb-linux.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -c -r1.5 -r1.6
*** pcap-usb-linux.c    29 Oct 2008 19:54:46 -0000      1.5
--- pcap-usb-linux.c    30 Oct 2008 11:35:54 -0000      1.6
***************
*** 173,180 ****
        if (len < 0) 
                return 0;
  
!       handle->buffer = mmap(0, len, PROT_READ, MAP_SHARED, handle->fd, 0);
!       return handle->buffer != MAP_FAILED;
  }
  
  pcap_t *
--- 173,180 ----
        if (len < 0) 
                return 0;
  
!       handle->bp = mmap(0, len, PROT_READ, MAP_SHARED, handle->fd, 0);
!       return handle->bp != MAP_FAILED;
  }
  
  pcap_t *
***************
*** 231,248 ****
                        handle->stats_op = usb_stats_linux_bin;
                        handle->read_op = usb_read_linux_mmap;
                        handle->cleanup_op = usb_cleanup_linux_mmap;
- 
-                       /*
-                        * "handle->fd" is a real file, so "select()" and
-                        * "poll()" work on it.
-                        */
-                       handle->selectable_fd = handle->fd;
-                       return 0;
                }
! 
!               /* can't mmap, use plain binary interface access */
!               handle->stats_op = usb_stats_linux_bin;
!               handle->read_op = usb_read_linux_bin;
        }
        else {
                /*Binary interface not available, try open text interface */
--- 231,242 ----
                        handle->stats_op = usb_stats_linux_bin;
                        handle->read_op = usb_read_linux_mmap;
                        handle->cleanup_op = usb_cleanup_linux_mmap;
                }
!               else {
!                       /* can't mmap, use plain binary interface access */
!                       handle->stats_op = usb_stats_linux_bin;
!                       handle->read_op = usb_read_linux_bin;
!               }
        }
        else {
                /*Binary interface not available, try open text interface */
***************
*** 267,278 ****
--- 261,275 ----
  
        /* for plain binary access and text access we need to allocate the read
         * buffer */
+       /* for mmap binary access we need to allocate the storing buffer for remove unneeded
+        * byte filled with 0 (workaround-ish)*/
        handle->buffer = malloc(handle->bufsize);
        if (!handle->buffer) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                         "malloc: %s", pcap_strerror(errno));
                return PCAP_ERROR;
        }
+ 
        return 0;
  }
  
***************
*** 679,685 ****
                nflush = fetch.nfetch;
                for (i=0; i<fetch.nfetch; ++i) {
                        /* discard filler */
!                       hdr = (pcap_usb_header*) &handle->buffer[vec[i]];
                        if (hdr->event_type == '@') 
                                continue;
  
--- 676,682 ----
                nflush = fetch.nfetch;
                for (i=0; i<fetch.nfetch; ++i) {
                        /* discard filler */
!                       hdr = (pcap_usb_header*) &handle->bp[vec[i]];
                        if (hdr->event_type == '@') 
                                continue;
  
***************
*** 695,702 ****
                        pkth.ts.tv_sec = hdr->ts_sec;
                        pkth.ts.tv_usec = hdr->ts_usec;
  
                        handle->md.packets_read++;
!                       callback(user, &pkth, (u_char*) hdr);
                        packets++;
                }
  
--- 692,704 ----
                        pkth.ts.tv_sec = hdr->ts_sec;
                        pkth.ts.tv_usec = hdr->ts_usec;
  
+                       /* copy header and data in buffer 
+                        * for remove byte filled with 0 (workaroud-ish) */
+                       memcpy(handle->buffer, &handle->bp[vec[i]], 48);
+                       memcpy(handle->buffer + 48, &handle->bp[vec[i]] + 64, clen);
+ 
                        handle->md.packets_read++;
!                       callback(user, &pkth, (u_char*) handle->buffer);
                        packets++;
                }
  
***************
*** 713,720 ****
  static void
  usb_cleanup_linux_mmap(pcap_t* handle)
  {
!       /* buffer must not be freed because it's memory mapped */
        /* XXX - does it need to be unmapped? */
!       handle->buffer = NULL;
        pcap_cleanup_live_common(handle);
  }
--- 715,726 ----
  static void
  usb_cleanup_linux_mmap(pcap_t* handle)
  {
!       /* bp must not be freed because it's memory mapped */
        /* XXX - does it need to be unmapped? */
!       handle->bp = NULL;
        pcap_cleanup_live_common(handle);
+ 
+       /* buffer must be freed, we have allocated this for store header and data 
+        * without byte filled with 0 (workaround-ish) */
+       free(handle->buffer); 
  }
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.

Current thread: