Date: Tue, 14 Apr 1998 00:47:50 +0200 From: sthaug@nethelp.no To: freebsd-current@FreeBSD.ORG Subject: Fixes for tcpdump with LPIP encapsulation Message-ID: <17850.892507670@verdi.nethelp.no>
next in thread | raw e-mail | index | archive | help
Having recently bought a laptop, I've been using the parallel port and
the LPIP encapsulation quite a bit. I found that tcpdump was completely
broken for LPIP encapsulation, like this:
tcpdump: WARNING: compensating for unaligned libpcap packets
00:21:22.606701 truncated-ip - 2777 bytes missing!3.1.192.168 > 3.2.8.0: (frag 0:2859@63496+) [tos 0x54]
00:21:22.608240 [|ip]
This is one ping and its reply, and *should* look like:
00:23:27.306352 192.168.3.1 > 192.168.3.2: icmp: echo request
00:23:27.308098 192.168.3.2 > 192.168.3.1: icmp: echo reply
There are several problems with the current BPF code in the LPIP (lpt)
driver:
- The DLT_NULL link layer type is just plain wrong for LPIP, because
LPIP has a two byte (0x0800) "type" header in front of the packet, while
tcpdump expects DLT_NULL to mean a four byte type header.
- The code to send a packet calls bpf_mtap after the bytes have been
sent, but at that point the length fields in the mbufs have been counted
down to -1.
- The code to send a packet makes an extra mbuf with the two byte type
header to satisfy BPF - but tcpdump expects this in network byte order.
I fixed the problem with the link layer type by defining a *new* link
layer type (DLT_LPIP). This seems to me to be the cleanest solution
(alternatives: remove the two byte header and use DLT_RAW, or expand it
to four bytes, and use DLT_NULL). Unfortunately it's also the solution
which touches the most files (changes needed for libpcap and tcpdump).
Thus I'd like to have some comments from the good people on -current on
whether this is the correct way of solving the problem, before I feed
the changes back to the tcpdump/libpcap maintainers.
Below are patches for these problems, affecting the following files:
sys/i386/isa/lpt.c
sys/net/bpf.c
sys/net/bpf.h
usr.sbin/tcpdump/tcpdump/Makefile
contrib/libpcap/gencode.c
contrib/libpcap/bpf/net/bpf.h
contrib/tcpdump/tcpdump.c
contrib/tcpdump/print-lpip.c
contrib/tcpdump/interface.h
plus the changed sys/net/bpf.h should also go into /usr/include/net.
I've added some missing link types from the current LBL version of
tcpdump/libpcap, and put the new link type at the first free entry.
contrib/tcpdump/print-lpip.c is a new file, modeled after print-raw.c
I've kept the same copyright notice even if this may not be strictly
correct. Feel free to tack on the copyright that's most suitable if
these changes are accepted.
The same patches can be used almost unchanged for 2.2.6. print-lpip.c
needs to have
#include <net/ethernet.h>
changed to
#include <netinet/if_ether.h>
Steinar Haug, Nethelp consulting, sthaug@nethelp.no
----------------------------------------------------------------------
*** sys/i386/isa/lpt.c.orig Tue Dec 2 22:06:24 1997
--- sys/i386/isa/lpt.c Mon Apr 13 14:12:32 1998
***************
*** 878,884 ****
printf("lp%d: TCP/IP capable interface\n", unit);
#if NBPFILTER > 0
! bpfattach(ifp, DLT_NULL, LPIPHDRLEN);
#endif
}
/*
--- 878,884 ----
printf("lp%d: TCP/IP capable interface\n", unit);
#if NBPFILTER > 0
! bpfattach(ifp, DLT_LPIP, LPIPHDRLEN);
#endif
}
/*
***************
*** 1314,1321 ****
mm = m;
do {
cp = mtod(mm,u_char *);
! while (mm->m_len--)
if (lpoutbyte(*cp++, LPMAXSPIN2, lpt_data_port, lpt_stat_port))
goto end;
} while ((mm = mm->m_next));
--- 1314,1322 ----
mm = m;
do {
+ int l = mm->m_len;
cp = mtod(mm,u_char *);
! while (l--)
if (lpoutbyte(*cp++, LPMAXSPIN2, lpt_data_port, lpt_stat_port))
goto end;
} while ((mm = mm->m_next));
***************
*** 1342,1348 ****
* try to free it or keep a pointer to it).
*/
struct mbuf m0;
! u_short hdr = 0x800;
m0.m_next = m;
m0.m_len = 2;
--- 1343,1349 ----
* try to free it or keep a pointer to it).
*/
struct mbuf m0;
! u_short hdr = htons(0x800);
m0.m_next = m;
m0.m_len = 2;
*** sys/net/bpf.c.orig Tue Nov 18 17:29:53 1997
--- sys/net/bpf.c Mon Apr 13 14:12:32 1998
***************
*** 190,195 ****
--- 190,196 ----
break;
case DLT_NULL:
+ case DLT_LPIP:
sockp->sa_family = AF_UNSPEC;
hlen = 0;
break;
*** sys/net/bpf.h.orig Sat Feb 22 10:40:55 1997
--- sys/net/bpf.h Mon Apr 13 14:12:32 1998
***************
*** 146,151 ****
--- 146,155 ----
#define DLT_PPP 9 /* Point-to-point Protocol */
#define DLT_FDDI 10 /* FDDI */
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
+ #define DLT_RAW 12 /* raw IP */
+ #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
+ #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
+ #define DLT_LPIP 15 /* BSD parallel port "encapsulation" */
/*
* The instruction encodings.
*** usr.sbin/tcpdump/tcpdump/Makefile.orig Tue May 27 04:21:28 1997
--- usr.sbin/tcpdump/tcpdump/Makefile Mon Apr 13 15:38:56 1998
***************
*** 11,17 ****
print-decnet.c print-domain.c print-dvmrp.c print-egp.c \
print-ether.c print-fddi.c print-gre.c print-icmp.c \
print-igrp.c print-ip.c print-ipx.c print-isoclns.c print-krb.c \
! print-llc.c print-nfs.c print-ntp.c print-null.c print-ospf.c \
print-pim.c print-ppp.c print-rip.c print-sl.c print-snmp.c \
print-sunrpc.c print-tcp.c print-tftp.c print-udp.c print-wb.c \
addrtoname.c bpf_dump.c machdep.c parsenfsfh.c util.c
--- 11,17 ----
print-decnet.c print-domain.c print-dvmrp.c print-egp.c \
print-ether.c print-fddi.c print-gre.c print-icmp.c \
print-igrp.c print-ip.c print-ipx.c print-isoclns.c print-krb.c \
! print-llc.c print-lpip.c print-nfs.c print-ntp.c print-null.c print-ospf.c \
print-pim.c print-ppp.c print-rip.c print-sl.c print-snmp.c \
print-sunrpc.c print-tcp.c print-tftp.c print-udp.c print-wb.c \
addrtoname.c bpf_dump.c machdep.c parsenfsfh.c util.c
*** contrib/libpcap/gencode.c.orig Tue May 27 02:05:20 1997
--- contrib/libpcap/gencode.c Mon Apr 13 15:34:59 1998
***************
*** 519,524 ****
--- 519,529 ----
off_linktype = -1;
off_nl = 0;
return;
+
+ case DLT_LPIP:
+ off_linktype = -1;
+ off_nl = 2;
+ return;
}
bpf_error("unknown data link type 0x%x", linktype);
/* NOTREACHED */
*** contrib/libpcap/bpf/net/bpf.h.orig Tue May 27 02:01:11 1997
--- contrib/libpcap/bpf/net/bpf.h Mon Apr 13 23:59:22 1998
***************
*** 170,175 ****
--- 170,178 ----
#define DLT_FDDI 10 /* FDDI */
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
#define DLT_RAW 12 /* raw IP */
+ #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
+ #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
+ #define DLT_LPIP 15 /* BSD parallel port "encapsulation" */
/*
* The instruction encondings.
*** contrib/tcpdump/tcpdump.c.orig Tue May 27 04:11:29 1997
--- contrib/tcpdump/tcpdump.c Mon Apr 13 15:33:42 1998
***************
*** 98,103 ****
--- 98,104 ----
{ fddi_if_print, DLT_FDDI },
{ null_if_print, DLT_NULL },
{ atm_if_print, DLT_ATM_RFC1483 },
+ { lpip_if_print, DLT_LPIP },
{ NULL, 0 },
};
*** contrib/tcpdump/print-lpip.c.orig Mon Apr 13 15:33:42 1998
--- contrib/tcpdump/print-lpip.c Tue Apr 14 00:01:40 1998
***************
*** 0 ****
--- 1,90 ----
+ /*
+ * Copyright (c) 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+ #include <sys/param.h>
+ #include <sys/time.h>
+ #include <sys/socket.h>
+ #include <sys/file.h>
+ #include <sys/ioctl.h>
+
+ #if __STDC__
+ struct mbuf;
+ struct rtentry;
+ #endif
+ #include <net/if.h>
+
+ #include <netinet/in.h>
+ #include <netinet/in_systm.h>
+ #include <netinet/ip.h>
+ #include <net/ethernet.h>
+ #include <netinet/ip_var.h>
+ #include <netinet/udp.h>
+ #include <netinet/udp_var.h>
+ #include <netinet/tcp.h>
+ #include <netinet/tcpip.h>
+
+ #include <pcap.h>
+ #include <stdio.h>
+ #include <string.h>
+
+ #include "addrtoname.h"
+ #include "interface.h"
+
+ #ifndef AF_NS
+ #define AF_NS 6 /* XEROX NS protocols */
+ #endif
+
+ /*
+ * The DLT_LPIP packet has a two byte header containing 0x0800, followed
+ * by a raw IP packet.
+ */
+ #define LPIP_HDRLEN 2
+
+ void
+ lpip_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+ {
+ u_int length = h->len;
+ u_int caplen = h->caplen;
+ const struct ip *ip;
+
+ ts_print(&h->ts);
+
+ /*
+ * Some printers want to get back at the link level addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ packetp = p;
+ snapend = p + caplen;
+
+ length -= LPIP_HDRLEN;
+
+ ip = (struct ip *)(p + LPIP_HDRLEN);
+
+ if (eflag)
+ printf("ip: ");
+
+ ip_print((const u_char *)ip, length);
+
+ if (xflag)
+ default_print(p, caplen);
+ putchar('\n');
+ }
*** contrib/tcpdump/interface.h.orig Tue May 27 04:11:11 1997
--- contrib/tcpdump/interface.h Mon Apr 13 15:33:42 1998
***************
*** 185,190 ****
--- 185,191 ----
extern void isoclns_print(const u_char *, u_int, u_int, const u_char *,
const u_char *);
extern void krb_print(const u_char *, u_int);
+ extern void lpip_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
extern void nfsreply_print(const u_char *, u_int, const u_char *);
extern void nfsreq_print(const u_char *, u_int, const u_char *);
extern void ns_print(const u_char *, u_int);
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?17850.892507670>
