On Wed, 22 Aug 2001, Guy Harris wrote:

hi,

Wouldn't a malloc(snaplen) in pcap_open_live() suffice?
Malloc-calls can be removed from new and old function then.
Thats how I would do it :)
Need to get a clean cvs-tree, the current I have
has too many own patches, so I cant send you
a clean diff now.

Sebastian

> > new and old function should only handle the PACKET_SOCKET vs.
> > PF_PACKET case IMHO.
> > Do you agree?
> 
> I.e., do something along the lines of what this patch does?
> 
> Index: pcap-linux.c
> ===================================================================
> RCS file: /tcpdump/master/libpcap/pcap-linux.c,v
> retrieving revision 1.61
> diff -c -r1.61 pcap-linux.c
> *** pcap-linux.c      2001/07/29 18:25:47     1.61
> --- pcap-linux.c      2001/08/22 21:18:42
> ***************
> *** 178,186 ****
>   pcap_t *
>   pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
>   {
>           /* Allocate a handle for this session. */
>   
> !     pcap_t  *handle = malloc(sizeof(*handle));
>       if (handle == NULL) {
>               snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
>                        pcap_strerror(errno));
> --- 178,190 ----
>   pcap_t *
>   pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
>   {
> +     pcap_t          *handle;
> +     int             mtu;
> +     struct utsname  utsname;
> + 
>           /* Allocate a handle for this session. */
>   
> !     handle = malloc(sizeof(*handle));
>       if (handle == NULL) {
>               snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
>                        pcap_strerror(errno));
> ***************
> *** 234,239 ****
> --- 238,317 ----
>               return NULL;
>       }
>   
> +     /* Compute the buffersize */
> + 
> +     mtu     = iface_get_mtu(handle->fd, device, ebuf);
> +     if (mtu == -1) {
> +             close(handle->fd);
> +             free(handle->md.device);
> +             free(handle);
> +             return NULL;
> +     }
> +     handle->bufsize  = MAX_LINKHEADER_SIZE + mtu;
> +     if (handle->bufsize < handle->snapshot)
> +             handle->bufsize = handle->snapshot;
> + 
> +     /* Allocate the buffer */
> + 
> +     handle->buffer   = malloc(handle->bufsize + handle->offset);
> +     if (!handle->buffer) {
> +             snprintf(ebuf, PCAP_ERRBUF_SIZE,
> +                      "malloc: %s", pcap_strerror(errno));
> +             close(handle->fd);
> +             free(handle->md.device);
> +             free(handle);
> +             return NULL;
> +     }
> + 
> +     /*
> +      * If we're using SOCKET_PACKET, this might be a 2.0[.x] kernel,
> +      * and might require special handling - check.
> +      */
> +     if (handle->md.sock_packet && (uname(&utsname) < 0 ||
> +         strncmp(utsname.release, "2.0", 3) == 0)) {
> +             /*
> +              * We're using a SOCK_PACKET structure, and either
> +              * we couldn't find out what kernel release this is,
> +              * or it's a 2.0[.x] kernel.
> +              *
> +              * In the 2.0[.x] kernel, a "recvfrom()" on
> +              * a SOCK_PACKET socket, with MSG_TRUNC set, will
> +              * return the number of bytes read, so if we pass
> +              * a length based on the snapshot length, it'll
> +              * return the number of bytes from the packet
> +              * copied to userland, not the actual length
> +              * of the packet.
> +              *
> +              * This means that, for example, the IP dissector
> +              * in tcpdump will get handed a packet length less
> +              * than the length in the IP header, and will
> +              * complain about "truncated-ip".
> +              *
> +              * So we don't bother trying to copy from the
> +              * kernel only the bytes in which we're interested,
> +              * but instead copy them all, just as the older
> +              * versions of libpcap for Linux did.
> +              *
> +              * That's just one of many problems with packet capture
> +              * on 2.0[.x] kernels; you really want a 2.2[.x]
> +              * or later kernel if you want packet capture to
> +              * work well.
> +              */
> +             handle->md.readlen = handle->bufsize;
> +     } else {
> +             /*
> +              * This is a 2.2[.x] or later kernel (we know that
> +              * either because we're not using a SOCK_PACKET
> +              * socket - PF_PACKET is supported only in 2.2
> +              * and later kernels - or because we checked the
> +              * kernel version).
> +              *
> +              * We can safely pass "recvfrom()" a byte count
> +              * based on the snapshot length.
> +              */
> +             handle->md.readlen = handle->snapshot;
> +     }
> + 
>       return handle;
>   }
>   
> ***************
> *** 783,789 ****
>             int to_ms, char *ebuf)
>   {
>   #ifdef HAVE_PF_PACKET_SOCKETS
> !     int                     sock_fd = -1, device_id, mtu, arptype;
>       struct packet_mreq      mr;
>   
>       /* One shot loop used for error handling - bail out with break */
> --- 861,867 ----
>             int to_ms, char *ebuf)
>   {
>   #ifdef HAVE_PF_PACKET_SOCKETS
> !     int                     sock_fd = -1, device_id, arptype;
>       struct packet_mreq      mr;
>   
>       /* One shot loop used for error handling - bail out with break */
> ***************
> *** 929,962 ****
>                       }
>               }
>   #endif
> - 
> -             /* Compute the buffersize */
>   
> !             mtu     = iface_get_mtu(sock_fd, device, ebuf);
> !             if (mtu == -1)
> !                     break;
> !             handle->bufsize  = MAX_LINKHEADER_SIZE + mtu;
> ! 
> !             /* Fill in the pcap structure */
>   
>               handle->fd       = sock_fd;
>   
> -             handle->buffer   = malloc(handle->bufsize + handle->offset);
> -             if (!handle->buffer) {
> -                     snprintf(ebuf, PCAP_ERRBUF_SIZE,
> -                              "malloc: %s", pcap_strerror(errno));
> -                     break;
> -             }
> - 
> -             /*
> -              * This is a 2.2 or later kernel, as it has PF_PACKET;
> -              * "recvfrom()", when passed the MSG_TRUNC flag, will
> -              * return the actual length of the packet, not the
> -              * number of bytes from the packet copied to userland,
> -              * so we can safely pass it a byte count based on the
> -              * snapshot length.
> -              */
> -             handle->md.readlen = handle->snapshot;
>               return 1;
>   
>       } while(0);
> --- 1007,1017 ----
>                       }
>               }
>   #endif
>   
> !             /* Save the socket FD in the pcap structure */
>   
>               handle->fd       = sock_fd;
>   
>               return 1;
>   
>       } while(0);
> ***************
> *** 1131,1138 ****
>   live_open_old(pcap_t *handle, char *device, int promisc, 
>             int to_ms, char *ebuf)
>   {
> !     int             sock_fd = -1, mtu, arptype;
> !     struct utsname  utsname;
>       struct ifreq    ifr;
>   
>       do {
> --- 1186,1192 ----
>   live_open_old(pcap_t *handle, char *device, int promisc, 
>             int to_ms, char *ebuf)
>   {
> !     int             sock_fd = -1, arptype;
>       struct ifreq    ifr;
>   
>       do {
> ***************
> *** 1215,1243 ****
>                       }
>               }
>   
> -             /* Compute the buffersize */
> - 
> -             mtu     = iface_get_mtu(sock_fd, device, ebuf);
> -             if (mtu == -1)
> -                     break;
> -             handle->bufsize  = MAX_LINKHEADER_SIZE + mtu;
> -             if (handle->bufsize < handle->snapshot)
> -                     handle->bufsize = handle->snapshot;
> - 
>               /* All done - fill in the pcap handle */
>   
>               arptype = iface_get_arptype(sock_fd, device, ebuf);
>               if (arptype == -1)
>                       break;
>   
>               /*
>                * Default value for offset to align link-layer payload
>                * on a 4-byte boundary.
>                */
>               handle->offset   = 0;
>   
> -             handle->fd       = sock_fd;
> - 
>               /*
>                * XXX - handle ISDN types here?  We can't fall back on
>                * cooked sockets, so we'd have to figure out from the
> --- 1269,1290 ----
>                       }
>               }
>   
>               /* All done - fill in the pcap handle */
>   
>               arptype = iface_get_arptype(sock_fd, device, ebuf);
>               if (arptype == -1)
>                       break;
>   
> +             /* Save the socket FD in the pcap structure */
> + 
> +             handle->fd       = sock_fd;
> + 
>               /*
>                * Default value for offset to align link-layer payload
>                * on a 4-byte boundary.
>                */
>               handle->offset   = 0;
>   
>               /*
>                * XXX - handle ISDN types here?  We can't fall back on
>                * cooked sockets, so we'd have to figure out from the
> ***************
> *** 1254,1310 ****
>                                "interface type of %s not supported", device);
>                       break;
>               }
> -             handle->buffer   = malloc(handle->bufsize + handle->offset);
> -             if (!handle->buffer) {
> -                     snprintf(ebuf, PCAP_ERRBUF_SIZE,
> -                              "malloc: %s", pcap_strerror(errno));
> -                     break;
> -             }
>   
> -             /*
> -              * This might be a 2.0[.x] kernel - check.
> -              */
> -             if (uname(&utsname) < 0 ||
> -                 strncmp(utsname.release, "2.0", 3) == 0) {
> -                     /*
> -                      * Either we couldn't find out what kernel release
> -                      * this is, or it's a 2.0[.x] kernel.
> -                      *
> -                      * In the 2.0[.x] kernel, a "recvfrom()" on
> -                      * a SOCK_PACKET socket, with MSG_TRUNC set, will
> -                      * return the number of bytes read, so if we pass
> -                      * a length based on the snapshot length, it'll
> -                      * return the number of bytes from the packet
> -                      * copied to userland, not the actual length
> -                      * of the packet.
> -                      *
> -                      * This means that, for example, the IP dissector
> -                      * in tcpdump will get handed a packet length less
> -                      * than the length in the IP header, and will
> -                      * complain about "truncated-ip".
> -                      *
> -                      * So we don't bother trying to copy from the
> -                      * kernel only the bytes in which we're interested,
> -                      * but instead copy them all, just as the older
> -                      * versions of libpcap for Linux did.
> -                      *
> -                      * Just one of many problems with packet capture
> -                      * on 2.0[.x] kernels; you really want a 2.2[.x]
> -                      * or later kernel if you want packet capture to
> -                      * work well.
> -                      */
> -                     handle->md.readlen = handle->bufsize;
> -             } else {
> -                     /*
> -                      * This is a 2.2[.x] or later kernel (although
> -                      * why we're using SOCK_PACKET on such a system
> -                      * is unknown to me).
> -                      *
> -                      * We can safely pass "recvfrom()" a byte count
> -                      * based on the snapshot length.
> -                      */
> -                     handle->md.readlen = handle->snapshot;
> -             }
>               return 1;
>   
>       } while (0);
> --- 1301,1307 ----
> 

---
"Please stop the earth. Let me off."
 

-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe

Reply via email to