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