From peter@vk2pj.alcatel.com.au  Fri Jul 10 15:42:38 1998
Received: from gatekeeper.alcatel.com.au (gatekeeper.alcatel.com.au [203.17.66.1])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id PAA04178
          for <FreeBSD-gnats-submit@freebsd.org>; Fri, 10 Jul 1998 15:42:30 -0700 (PDT)
          (envelope-from peter@vk2pj.alcatel.com.au)
Received: from mfg1.cim.alcatel.com.au ("port 4415"@[139.188.23.1])
 by gatekeeper.alcatel.com.au (PMDF V5.1-7 #U2695)
 with ESMTP id <01IZ9O1W35A800091Y@gatekeeper.alcatel.com.au> for
 FreeBSD-gnats-submit@freebsd.org; Sat, 11 Jul 1998 08:41:51 +1000
Received: from cbd.alcatel.com.au by cim.alcatel.com.au (PMDF V5.1-10 #U2695)
 with ESMTP id <01IZ9O1SY23K8WZQTC@cim.alcatel.com.au> for
 FreeBSD-gnats-submit@freebsd.org; Sat, 11 Jul 1998 08:41:48 +1000
Received: from vk2pj.alcatel.com.au ([139.188.118.2])
 by cbd.alcatel.com.au (PMDF V5.1-7 #U2695)
 with ESMTP id <01IZ9O1LGGY88WWNUJ@cbd.alcatel.com.au> for
 FreeBSD-gnats-submit@freebsd.org; Sat, 11 Jul 1998 08:41:44 +1100
Received: (from peter@localhost) by vk2pj.alcatel.com.au (8.8.7/8.7.3)
 id IAA15036; Sat, 11 Jul 1998 08:41:33 +1000 (EST)
Message-Id: <199807102241.IAA15036@vk2pj.alcatel.com.au>
Date: Sat, 11 Jul 1998 08:41:33 +1000 (EST)
From: peter.jeremy@alcatel.com.au
Reply-To: peter.jeremy@alcatel.com.au
To: FreeBSD-gnats-submit@freebsd.org
Subject: tcpdump does not work with parallel line IP
X-Send-Pr-Version: 3.2

>Number:         7241
>Category:       i386
>Synopsis:       tcpdump does not work with parallel line IP
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    des
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jul 10 15:50:01 PDT 1998
>Closed-Date:    Mon Feb 8 12:19:51 PST 1999
>Last-Modified:  Mon Feb  8 12:20:37 PST 1999
>Originator:     Peter Jeremy
>Release:        FreeBSD 2.2.5-RELEASE i386
>Organization:
>Environment:

Two FreeBSD 2.2.5-RELEASE machines connected via parallel IP.  There
are no changes in 2.2.6-RELEASE so the same problem presumably occurs.

>Description:

The tcpdump supplied with 2.2.5-RELEASE (and 2.2.6-RELEASE) cannot
handle parallel IP.  The problem is that the LP code defines itself as
DLT_NULL, which assumes a 4-byte header, although the LP interface
uses a 2-byte header.  Also, the m_len field in the mbuf passed to the
bpfilter has been zeroed during the transmit prcess (3rd patch block
in lpt.c below).  The solution is to define a new interface protocol
type `DLT_LPIP' which has the correct characteristics.

>How-To-Repeat:

Run tcpdump on an lp interface.  The decode will be corrupted.

>Fix:
	
The following patch defines a new DLT_LPIP type and modifies the lp
interface to use it.  This patch should apply to either 2.2.6-RELEASE
or 2.2.5-RELEASE.  In the latter case, the last patch (to the tcpdump
Makefile) will have 1 fuzz line.  There may be offset lines with the
lpt.c patch due to (unrelated) changed to fix the spl() problem
previously corrected (kern/6099, i386/5698).

Note that this patch includes changes to contrib software.  I'm not
certain of the correct procedure to apply FreeBSD changes to contrib
software, so the following may need massaging.  A copy of these
patches have been forwarded to the tcpdump maintainer.

diff -ur 2.2.6/contrib/libpcap/bpf/net/bpf.h 2.2.5/contrib/libpcap/bpf/net/bpf.h
--- 2.2.6/contrib/libpcap/bpf/net/bpf.h	Tue Aug 20 06:36:33 1996
+++ 2.2.5/contrib/libpcap/bpf/net/bpf.h	Sun Jan 18 09:55:53 1998
@@ -165,6 +165,7 @@
 #define DLT_PPP		9	/* Point-to-point Protocol */
 #define DLT_FDDI	10	/* FDDI */
 #define DLT_ATM_RFC1483	11	/* LLC/SNAP encapsulated atm */
+#define DLT_LPIP	12	/* Parallel port TCP/IP */
 
 /*
  * The instruction encondings.
diff -ur 2.2.6/contrib/libpcap/gencode.c 2.2.5/contrib/libpcap/gencode.c
--- 2.2.6/contrib/libpcap/gencode.c	Mon Dec 23 02:03:05 1996
+++ 2.2.5/contrib/libpcap/gencode.c	Sun Jan 18 09:55:53 1998
@@ -513,6 +513,11 @@
 		off_linktype = 6;
 		off_nl = 8;
 		return;
+
+	case DLT_LPIP:
+		off_linktype = 0;
+		off_nl = 2;
+		return;
 	}
 	bpf_error("unknown data link type 0x%x", linktype);
 	/* NOTREACHED */
@@ -562,6 +567,7 @@
 		break;
 
 	case DLT_NULL:
+	case DLT_LPIP:
 		/* XXX */
 		if (proto == ETHERTYPE_IP)
 			return (gen_cmp(0, BPF_W, (bpf_int32)htonl(AF_INET)));
diff -ur 2.2.6/contrib/tcpdump/Makefile.in 2.2.5/contrib/tcpdump/Makefile.in
--- 2.2.6/contrib/tcpdump/Makefile.in	Tue Aug 20 06:34:03 1996
+++ 2.2.5/contrib/tcpdump/Makefile.in	Sun Jan 18 09:55:53 1998
@@ -62,7 +62,7 @@
 	print-sl.c print-ppp.c print-rip.c print-snmp.c \
 	print-ntp.c print-null.c print-egp.c print-ospf.c \
 	print-fddi.c print-llc.c print-sunrpc.c print-wb.c \
-	print-decnet.c print-isoclns.c print-ipx.c \
+	print-decnet.c print-isoclns.c print-lpip.c print-ipx.c \
 	print-atm.c print-dvmrp.c print-pim.c print-krb.c \
 	util.c machdep.c bpf_dump.c parsenfsfh.c
 LOCALSRC =
diff -ur 2.2.6/contrib/tcpdump/interface.h 2.2.5/contrib/tcpdump/interface.h
--- 2.2.6/contrib/tcpdump/interface.h	Wed Mar  4 18:57:52 1998
+++ 2.2.5/contrib/tcpdump/interface.h	Sun Jan 18 09:55:53 1998
@@ -112,6 +103,7 @@
 extern void ether_if_print(u_char *, const struct pcap_pkthdr *,
 	const u_char *);
 extern void fddi_if_print(u_char *, const struct pcap_pkthdr *, const u_char*);
+extern void lpip_if_print(u_char *, const struct pcap_pkthdr *, const u_char*);
 extern void null_if_print(u_char *, const struct pcap_pkthdr *, const u_char*);
 extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
 extern void sl_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
diff -u /dev/null 2.2.5/contrib/tcpdump/print-lpip.c
--- /dev/null	Thu Jul  9 02:05:45 1998
+++ 2.2.5/contrib/tcpdump/print-lpip.c	Sun Jun 29 14:25:25 1997
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 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.
+ */
+
+#ifndef lint
+static char rcsid[] =
+    "@(#)$Header: print-lpip.c,v 1.1";
+#endif
+
+#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 <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "pcap.h"
+
+#define	LPIP_HDRLEN 2
+
+static void
+lpip_print(const u_char *p, const struct ip *ip, u_int length)
+{
+	u_int family;
+
+	memcpy((char *)&family, (char *)p, sizeof(family));
+
+	if (nflag) {
+		/* XXX just dump the header */
+		return;
+	}
+	switch (family) {
+
+	case AF_INET:
+		printf("ip: ");
+		break;
+
+	case AF_NS:
+		printf("ns: ");
+		break;
+
+	default:
+		printf("AF %d: ", family);
+		break;
+	}
+}
+
+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;
+
+	if (length < LPIP_HDRLEN || caplen < LPIP_HDRLEN)
+	  return;
+
+	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)
+		lpip_print(p, ip, length);
+
+	ip_print((const u_char *)ip, length);
+
+	if (xflag)
+		default_print((const u_char *)ip, caplen - LPIP_HDRLEN);
+	putchar('\n');
+}
+

diff -ur 2.2.6/contrib/tcpdump/tcpdump.c 2.2.5/contrib/tcpdump/tcpdump.c
--- 2.2.6/contrib/tcpdump/tcpdump.c	Tue Aug 20 06:34:12 1996
+++ 2.2.5/contrib/tcpdump/tcpdump.c	Sun Jan 18 09:55:53 1998
@@ -97,6 +97,7 @@
 	{ ppp_if_print,		DLT_PPP },
 	{ fddi_if_print,	DLT_FDDI },
 	{ null_if_print,	DLT_NULL },
+	{ lpip_if_print,	DLT_LPIP },
 	{ atm_if_print,		DLT_ATM_RFC1483 },
 	{ NULL,			0 },
 };
diff -ur 2.2.6/sys/i386/isa/lpt.c 2.2.5/sys/i386/isa/lpt.c
--- 2.2.6/sys/i386/isa/lpt.c	Sat Feb 28 15:18:12 1998
+++ 2.2.5/sys/i386/isa/lpt.c	Fri Mar 27 19:08:19 1998
@@ -871,7 +882,7 @@
 	printf("lp%d: TCP/IP capable interface\n", unit);
 
 #if NBPFILTER > 0
-	bpfattach(ifp, DLT_NULL, LPIPHDRLEN);
+	bpfattach(ifp, DLT_LPIP, LPIPHDRLEN);
 #endif
 }
 /*
@@ -1139,6 +1153,7 @@
 	    }
 #if NBPFILTER > 0
 	    if (sc->sc_if.if_bpf) {
+		lprintf("r");
 		bpf_tap(&sc->sc_if, sc->sc_ifbuf, len);
 	    }
 #endif
@@ -1308,7 +1323,8 @@
     mm = m;
     do {
         cp = mtod(mm,u_char *);
-        while (mm->m_len--)
+        i = mm->m_len;
+        while (i--)
 	    if (lpoutbyte(*cp++, LPMAXSPIN2, lpt_data_port, lpt_stat_port))
 	        goto end;
     } while ((mm = mm->m_next));
@@ -1341,6 +1357,7 @@
 	    m0.m_len = 2;
 	    m0.m_data = (char *)&hdr;
 
+	    lprintf("t");
 	    bpf_mtap(ifp, &m0);
 	}
 #endif
diff -ur 2.2.6/sys/net/bpf.c 2.2.5/sys/net/bpf.c
--- 2.2.6/sys/net/bpf.c	Sat Oct  4 09:57:03 1997
+++ 2.2.5/sys/net/bpf.c	Sat Jan 17 19:26:16 1998
@@ -170,7 +170,9 @@
 	 */
 	switch (linktype) {
 
+	case DLT_NULL:
 	case DLT_SLIP:
+	case DLT_LPIP:
 		sockp->sa_family = AF_INET;
 		hlen = 0;
 		break;
@@ -190,11 +192,6 @@
 		/* XXX 4(FORMAC)+6(dst)+6(src)+3(LLC)+5(SNAP) */
 		hlen = 24;
 #endif
-		break;
-
-	case DLT_NULL:
-		sockp->sa_family = AF_UNSPEC;
-		hlen = 0;
 		break;
 
 	default:
diff -ur 2.2.6/sys/net/bpf.h 2.2.5/sys/net/bpf.h
--- 2.2.6/sys/net/bpf.h	Tue Aug 20 06:28:25 1996
+++ 2.2.5/sys/net/bpf.h	Sat Jan 17 19:26:17 1998
@@ -146,6 +146,7 @@
 #define DLT_PPP		9	/* Point-to-point Protocol */
 #define DLT_FDDI	10	/* FDDI */
 #define DLT_ATM_RFC1483	11	/* LLC/SNAP encapsulated atm */
+#define DLT_LPIP	12	/* Parallel port TCP/IP */
 
 /*
  * The instruction encodings.
diff -ur 2.2.6/usr.sbin/tcpdump/tcpdump/Makefile 2.2.5/usr.sbin/tcpdump/tcpdump/Makefile
--- 2.2.6/usr.sbin/tcpdump/tcpdump/Makefile	Thu Jan  1 08:51:55 1998
+++ 2.2.5/usr.sbin/tcpdump/tcpdump/Makefile	Sun Jan 18 09:55:54 1998
@@ -13,8 +13,8 @@
 	print-sl.c print-ppp.c print-rip.c print-snmp.c \
 	print-ntp.c print-null.c print-egp.c print-ospf.c \
 	print-fddi.c print-llc.c print-sunrpc.c print-wb.c \
-	print-decnet.c print-isoclns.c print-ipx.c \
+	print-decnet.c print-isoclns.c print-ipx.c print-lpip.c \
 	print-atm.c print-fr.c print-dvmrp.c print-pim.c print-krb.c \
 	util.c machdep.c bpf_dump.c parsenfsfh.c
 CLEANFILES+=	version.c
 DPADD+=	${LIBL} ${LIBPCAP}
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->feedback 
State-Changed-By: phk 
State-Changed-When: Sat Jul 11 01:21:58 PDT 1998 
State-Changed-Why:  
does this work with both PLIP and CLPIP encapsulation ? 

From: Bill Fenner <fenner@parc.xerox.com>
To: peter.jeremyp@alcatel.com.au, freebsd-gnats-submit@freebsd.org
Cc:  Subject: Re: bin/7241: tcpdump does not work with parallel line IP
Date: Sat, 11 Jul 1998 16:03:00 PDT

 Isn't it easier to fix lpip to use the DLT_NULL encapsulation?
 
   Bill

From: Bill Fenner <fenner@FreeBSD.ORG>
To: freebsd-gnats-submit@FreeBSD.org, peter.jeremy@alcatel.com.au
Cc:  Subject: Re: bin/7241: tcpdump does not work with parallel line IP
Date: Sat, 11 Jul 1998 16:31:38 -0700 (PDT)

 In fact, I just found these diffs in my home directory on freefall; seems
 that I tried to address this issue in early 1997 but didn't find anyone
 to test the patches.  Would you mind testing this patch?
 
 Thanks,
   Bill
 
 Index: sys_i386_isa/lpt.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/i386/isa/lpt.c,v
 retrieving revision 1.58
 diff -c -r1.58 lpt.c
 *** lpt.c	1997/02/22 09:36:51	1.58
 --- lpt.c	1997/03/10 07:59:44
 ***************
 *** 880,886 ****
   	printf("lp%d: TCP/IP capable interface\n", unit);
   
   #if NBPFILTER > 0
 ! 	bpfattach(ifp, DLT_NULL, LPIPHDRLEN);
   #endif
   }
   /*
 --- 880,886 ----
   	printf("lp%d: TCP/IP capable interface\n", unit);
   
   #if NBPFILTER > 0
 ! 	bpfattach(ifp, DLT_NULL, sizeof(u_int));
   #endif
   }
   /*
 ***************
 *** 1102,1107 ****
 --- 1102,1126 ----
   	    sc->sc_if.if_ibytes += len;
   	    top = m_devget(sc->sc_ifbuf + CLPIPHDRLEN, len, 0, &sc->sc_if, 0);
   	    if (top) {
 + #if NBPFILTER > 0
 + 		if (sc->sc_if.if_bpf) {
 + 		    /*
 + 		     * We need to prepend the address family as
 + 		     * a four byte field.  Cons up a dummy header
 + 		     * to pacify bpf.  This is safe because bpf
 + 		     * will only read from the mbuf (i.e., it won't
 + 		     * try to free it or keep a pointer to it).
 + 		     */
 + 		    struct mbuf m0;
 + 		    u_int af = AF_INET;
 + 
 + 		    m0.m_next = top;
 + 		    m0.m_len = 4;
 + 		    m0.m_data = (char *)&af;
 + 
 + 		    bpf_mtap(ifp, &m0);
 + 		}
 + #endif
   	        IF_ENQUEUE(&ipintrq, top);
   	        schednetisr(NETISR_IP);
   	    }
 ***************
 *** 1146,1161 ****
   		IF_DROP(&ipintrq);
   		goto done;
   	    }
 - #if NBPFILTER > 0
 - 	    if (sc->sc_if.if_bpf) {
 - 		bpf_tap(&sc->sc_if, sc->sc_ifbuf, len);
 - 	    }
 - #endif
   	    len -= LPIPHDRLEN;
   	    sc->sc_if.if_ipackets++;
   	    sc->sc_if.if_ibytes += len;
   	    top = m_devget(sc->sc_ifbuf + LPIPHDRLEN, len, 0, &sc->sc_if, 0);
   	    if (top) {
   		    IF_ENQUEUE(&ipintrq, top);
   		    schednetisr(NETISR_IP);
   	    }
 --- 1165,1194 ----
   		IF_DROP(&ipintrq);
   		goto done;
   	    }
   	    len -= LPIPHDRLEN;
   	    sc->sc_if.if_ipackets++;
   	    sc->sc_if.if_ibytes += len;
   	    top = m_devget(sc->sc_ifbuf + LPIPHDRLEN, len, 0, &sc->sc_if, 0);
   	    if (top) {
 + #if NBPFILTER > 0
 + 		    if (sc->sc_if.if_bpf) {
 + 			    /*
 + 			     * We need to prepend the address family as
 + 			     * a four byte field.  Cons up a dummy header
 + 			     * to pacify bpf.  This is safe because bpf
 + 			     * will only read from the mbuf (i.e., it won't
 + 			     * try to free it or keep a pointer to it).
 + 			     */
 + 			    struct mbuf m0;
 + 			    u_int af = AF_INET;
 + 
 + 			    m0.m_next = top;
 + 			    m0.m_len = 4;
 + 			    m0.m_data = (char *)&af;
 + 
 + 			    bpf_mtap(ifp, &m0);
 + 		    }
 + #endif
   		    IF_ENQUEUE(&ipintrq, top);
   		    schednetisr(NETISR_IP);
   	    }
 ***************
 *** 1225,1230 ****
 --- 1258,1283 ----
       /* Suspend (on laptops) or receive-errors might have taken us offline */
       outb(lpt_ctrl_port, LPC_ENA);
   
 + #if NBPFILTER > 0
 +     if (ifp->if_bpf) {
 + 	/*
 + 	 * We need to prepend the address family as
 + 	 * a four byte field.  Cons up a dummy header
 + 	 * to pacify bpf.  This is safe because bpf
 + 	 * will only read from the mbuf (i.e., it won't
 + 	 * try to free it or keep a pointer to it).
 + 	 */
 + 	struct mbuf m0;
 + 	u_int af = AF_INET;
 + 
 + 	m0.m_next = m;
 + 	m0.m_len = 4;
 + 	m0.m_data = (char *)&af;
 + 
 + 	bpf_mtap(ifp, &m0);
 +     }
 + #endif
 + 
       if (ifp->if_flags & IFF_LINK0) {
   
   	if (!(inb(lpt_stat_port) & CLPIP_SHAKE)) {
 ***************
 *** 1334,1358 ****
       } else {
   	ifp->if_opackets++;
   	ifp->if_obytes += m->m_pkthdr.len;
 - #if NBPFILTER > 0
 - 	if (ifp->if_bpf) {
 - 	    /*
 - 	     * We need to prepend the packet type as
 - 	     * a two byte field.  Cons up a dummy header
 - 	     * to pacify bpf.  This is safe because bpf
 - 	     * will only read from the mbuf (i.e., it won't
 - 	     * 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;
 - 	    m0.m_data = (char *)&hdr;
 - 
 - 	    bpf_mtap(ifp, &m0);
 - 	}
 - #endif
       }
   
       m_freem(m);
 --- 1387,1392 ----

From: Peter Jeremy <peter.jeremy@alcatel.com.au>
To: freebsd-gnats-submit@freebsd.org
Cc:  Subject: Re: bin/7241: tcpdump does not work with parallel line IP
Date: Sun, 12 Jul 1998 13:29:24 +1000 (EST)

 Please note that there is a typo in the originator field.  My address
 is peter.jeremy@alcatel.com.au not peter.jeremyp@alcatel.com.au as I
 mis-typed in the submission.
 
 Peter
 --
 Peter Jeremy (VK2PJ)                    peter.jeremy@alcatel.com.au
 Alcatel Australia Limited
 41 Mandible St                          Phone: +61 2 9690 5019
 ALEXANDRIA  NSW  2015                   Fax:   +61 2 9690 5247
Responsible-Changed-From-To: freebsd-bugs->des 
Responsible-Changed-By: des 
Responsible-Changed-When: Sun Feb 7 17:47:08 PST 1999 
Responsible-Changed-Why:  
I'm working on it. 
State-Changed-From-To: feedback->closed 
State-Changed-By: des 
State-Changed-When: Mon Feb 8 12:19:51 PST 1999 
State-Changed-Why:  
Fixed in -stable and -current. 
>Unformatted:
