- /*
- * Compute the buffer size.
- *
- * If we're using SOCK_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.
- *
- * The buffer therefore needs to be big enough to
- * hold the largest packet we can get from this
- * device. Unfortunately, we can't get the MRU
- * of the network; we can only get the MTU. The
- * MTU may be too small, in which case a packet larger
- * than the buffer size will be truncated *and* we
- * won't get the actual packet size.
- *
- * However, if the snapshot length is larger than
- * the buffer size based on the MTU, we use the
- * snapshot length as the buffer size, instead;
- * this means that with a sufficiently large snapshot
- * length we won't artificially truncate packets
- * to the MTU-based size.
- *
- * This mess 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.
- */
- mtu = iface_get_mtu(handle->fd, device, ebuf);
- if (mtu == -1) {
- pcap_close_linux(handle);
- free(handle);
- return NULL;
- }
- handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
- if (handle->bufsize < handle->snapshot)
- handle->bufsize = handle->snapshot;
- } 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.
- *
- * If we're in cooked mode, make the snapshot length
- * large enough to hold a "cooked mode" header plus
- * 1 byte of packet data (so we don't pass a byte
- * count of 0 to "recvfrom()").
- */
- if (handle->md.cooked) {
- if (handle->snapshot < SLL_HDR_LEN + 1)
- handle->snapshot = SLL_HDR_LEN + 1;
- }
- handle->bufsize = handle->snapshot;
- }
-