Subject: Changes to link layer input routines
To: None <tech-net@netbsd.org>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-net
Date: 05/14/1999 15:28:42
Hi folks...

I have an application which is using a protocol family, which needs to have
Ethernet headers intact on the packet when it is read by userspace.

Unfortunately, ether_input() and friends are structured such that they assume
the header has been stripped of (or was never in the front of the packet to
begin with).  Other protocol input routines do the same thing (e.g.
token_input(), hippi_input()), while others (e.g. arc_input()) do not.

What I'd like to do is make it uniform, and place another function pointer
in the ifnet structure (*if_input)(struct ifnet *, struct mbuf *).  This
might have other utility, too, like allowing packet filters/compressors
or whatever to easily insert themselves into the flow.

Diffs that do this are appended below.  Note that I'll have to bump the
version number, and we'll have to be more careful when porting drivers
from other OSs.  Thankfully, the signature of the function is different,
so the difference will be easy to spot.

Problems:

	(1) I've only tested this with a couple of different interfaces
	    at this time.  I'll try and test it with more before I commit
	    it.

	(2) atm_input() can't change without lots of reworking.  I don't
	    have the time or equipment to do that right now (though I
	    recently got ahold of one of the cards supported by the
	    "en" driver, so I might be able to tackle this at some
	    point).

	(3) The VAX Unibus and Q-bus Ethernet drivers confused the h*ll
	    out of me, and I didn't even try to clean up the way they
	    use separate Unibus mapping registers for the Ethernet header
	    and the actual packet.  (Wacky, it's not like they even support
	    trailers in the driver!)

Anyhow, I'd appreciate feedback, and if you want to test the diffs (HEAR
THIS, TOKEN RING USERS!), I'd appreciate a report on if I broke anything.

Thanks!

        -- Jason R. Thorpe <thorpej@nas.nasa.gov>

Index: arch/alpha/a12/if_ade.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/a12/if_ade.c,v
retrieving revision 1.2
diff -c -r1.2 if_ade.c
*** if_ade.c	1999/04/10 01:21:36	1.2
--- if_ade.c	1999/05/12 00:43:54
***************
*** 3389,3395 ****
--- 3389,3397 ----
  		    goto next;
  	    accept = 1;
  	    sc->tulip_flags |= TULIP_RXACT;
+ #if !defined(__NetBSD__)
  	    total_len -= sizeof(struct ether_header);
+ #endif
  	} else {
  	    ifp->if_ierrors++;
  	    if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) {
***************
*** 3465,3475 ****
--- 3467,3483 ----
  		eh.ether_type = ntohs(eh.ether_type);
  #endif
  #if !defined(TULIP_COPY_RXDATA)
+ #if defined(__NetBSD__)
+ 		ms->m_pkthdr.len = total_len;
+ 		ms->m_pkthdr.rcvif = ifp;
+ 		(*ifp->if_input)(ifp, ms);
+ #else
  		ms->m_data += sizeof(struct ether_header);
  		ms->m_len -= sizeof(struct ether_header);
  		ms->m_pkthdr.len = total_len;
  		ms->m_pkthdr.rcvif = ifp;
  		ether_input(ifp, &eh, ms);
+ #endif /* __NetBSD__ */
  #ifdef LCLDMA
  #error LCLDMA requires TULIP_COPY_RXDATA
  #endif
***************
*** 3477,3490 ****
--- 3485,3504 ----
  #ifdef BIG_PACKET
  #error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
  #endif
+ #if !defined(__NetBSD__)
  		if (ms == me)
  		    bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header),
  			  mtod(m0, caddr_t), total_len);
  		else
+ #endif /* __NetBSD__ */
  		    m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
  		m0->m_len = m0->m_pkthdr.len = total_len;
  		m0->m_pkthdr.rcvif = ifp;
+ #if defined(__NetBSD__)
+ 		(*ifp->if_input)(ifp, m0);
+ #else
  		ether_input(ifp, &eh, m0);
+ #endif
  		m0 = ms;
  #endif
  	    }
Index: arch/amiga/dev/if_ed.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/dev/if_ed.c,v
retrieving revision 1.31
diff -c -r1.31 if_ed.c
*** if_ed.c	1999/03/25 23:10:13	1.31
--- if_ed.c	1999/05/12 00:43:57
***************
*** 1027,1035 ****
  	}
  #endif
  
! 	/* Fix up data start offset in mbuf to point past ether header. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 1027,1033 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
Index: arch/amiga/dev/if_es.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/dev/if_es.c,v
retrieving revision 1.22
diff -c -r1.22 if_es.c
*** if_es.c	1998/07/05 06:49:03	1.22
--- if_es.c	1999/05/12 00:43:57
***************
*** 732,742 ****
  		}
  	}
  #endif
! 	top->m_pkthdr.len -= sizeof (*eh);
! 	top->m_len -= sizeof (*eh);
! 	top->m_data += sizeof (*eh);
! 
! 	ether_input(ifp, eh, top);
  #ifdef ESDEBUG
  	if (--sc->sc_smcbusy) {
  		printf("%s: esintr busy on exit\n", sc->sc_dev.dv_xname);
--- 732,738 ----
  		}
  	}
  #endif
! 	(*ifp->if_input)(ifp, top);
  #ifdef ESDEBUG
  	if (--sc->sc_smcbusy) {
  		printf("%s: esintr busy on exit\n", sc->sc_dev.dv_xname);
Index: arch/amiga/dev/if_qn.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/dev/if_qn.c,v
retrieving revision 1.17
diff -c -r1.17 if_qn.c
*** if_qn.c	1999/03/25 23:10:53	1.17
--- if_qn.c	1999/05/12 00:44:00
***************
*** 643,650 ****
  	}
  #endif
  
! 	m_adj(head, sizeof(struct ether_header));
! 	ether_input(ifp, eh, head);
  	return;
  
  bad:
--- 643,649 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, head);
  	return;
  
  bad:
Index: arch/arm32/podulebus/if_ea.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm32/podulebus/if_ea.c,v
retrieving revision 1.21
diff -c -r1.21 if_ea.c
*** if_ea.c	1999/03/25 23:11:51	1.21
--- if_ea.c	1999/05/12 00:44:02
***************
*** 1321,1329 ****
  
  	ifp = &sc->sc_ethercom.ec_if;
  	eh = (struct ether_header *)buf;
- 	len -= sizeof(struct ether_header);
- 	if (len <= 0)
- 		return;
  
  	/* Pull packet off interface. */
  	m = eaget(buf, len, ifp);
--- 1321,1326 ----
***************
*** 1336,1343 ****
  	 * If so, hand off the raw packet to bpf.
  	 */
  	if (ifp->if_bpf) {
! 		bpf_tap(ifp->if_bpf, buf, len + sizeof(struct ether_header));
! /*		bpf_mtap(ifp->if_bpf, m);*/
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
--- 1333,1339 ----
  	 * If so, hand off the raw packet to bpf.
  	 */
  	if (ifp->if_bpf) {
! 		bpf_mtap(ifp->if_bpf, m);
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
***************
*** 1354,1360 ****
  	}
  #endif
  
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 1350,1356 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
***************
*** 1374,1380 ****
          register caddr_t cp = buf;
          char *epkt;
  
-         buf += sizeof(struct ether_header);
          cp = buf;
          epkt = cp + totlen;
  
--- 1370,1375 ----
Index: arch/arm32/podulebus/if_eb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm32/podulebus/if_eb.c,v
retrieving revision 1.21
diff -c -r1.21 if_eb.c
*** if_eb.c	1999/03/25 23:11:52	1.21
--- if_eb.c	1999/05/12 00:44:02
***************
*** 1335,1343 ****
  
  	ifp = &sc->sc_ethercom.ec_if;
  	eh = (struct ether_header *)buf;
- 	len -= sizeof(struct ether_header);
- 	if (len <= 0)
- 		return;
  
  	/* Pull packet off interface. */
  	m = ebget(buf, len, ifp);
--- 1335,1340 ----
***************
*** 1350,1357 ****
  	 * If so, hand off the raw packet to bpf.
  	 */
  	if (ifp->if_bpf) {
! 		bpf_tap(ifp->if_bpf, buf, len + sizeof(struct ether_header));
! /*		bpf_mtap(ifp->if_bpf, m);*/
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
--- 1347,1353 ----
  	 * If so, hand off the raw packet to bpf.
  	 */
  	if (ifp->if_bpf) {
! 		bpf_mtap(ifp->if_bpf, m);
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
***************
*** 1368,1374 ****
  	}
  #endif
  
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 1364,1370 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
***************
*** 1388,1394 ****
          register caddr_t cp = buf;
          char *epkt;
  
-         buf += sizeof(struct ether_header);
          cp = buf;
          epkt = cp + totlen;
  
--- 1384,1389 ----
Index: arch/arm32/podulebus/if_ie.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm32/podulebus/if_ie.c,v
retrieving revision 1.22
diff -c -r1.22 if_ie.c
*** if_ie.c	1999/03/25 23:11:52	1.22
--- if_ie.c	1999/05/12 00:44:02
***************
*** 1116,1127 ****
  }
  
  struct mbuf *
! ieget(struct ie_softc *sc, struct ether_header *ehp, int *to_bpf )
  {
      struct mbuf *top, **mp, *m;
      int head;
      int resid, totlen, thisrboff, thismboff;
      int len;
  
      totlen = ie_packet_len(sc);
  
--- 1116,1128 ----
  }
  
  struct mbuf *
! ieget(struct ie_softc *sc, int *to_bpf )
  {
      struct mbuf *top, **mp, *m;
      int head;
      int resid, totlen, thisrboff, thismboff;
      int len;
+     struct ether_header eh;
  
      totlen = ie_packet_len(sc);
  
***************
*** 1137,1147 ****
      head = sc->rbhead;
  
      /* Read the ethernet header */
!     ie2host ( sc, sc->cbuffs[head], (caddr_t)ehp, sizeof *ehp );
  
      /* Check if the packet is for us */
  
!     resid = totlen -= (thisrboff = sizeof *ehp);
  
      MGETHDR ( m, M_DONTWAIT, MT_DATA );
      if ( m==0 )
--- 1138,1148 ----
      head = sc->rbhead;
  
      /* Read the ethernet header */
!     ie2host ( sc, sc->cbuffs[head], (caddr_t)&eh, sizeof eh );
  
      /* Check if the packet is for us */
  
!     resid = totlen;
  
      MGETHDR ( m, M_DONTWAIT, MT_DATA );
      if ( m==0 )
***************
*** 1181,1186 ****
--- 1182,1195 ----
      thismboff = 0;
  
      /*
+      * Copy the Ethernet header into the mbuf chain.
+      */
+     memcpy(mtod(m, caddr_t), &eh, sizeof(struct ether_header));
+     thismboff = sizeof(struct ether_header);
+     thisrboff = sizeof(struct ether_header);
+     resid -= sizeof(struct ether_header);
+ 
+     /*
       * Now we take the mbuf chain (hopefully only one mbuf most of the
       * time) and stuff the data into it.  There are no possible failures at
       * or after this point.
***************
*** 1271,1277 ****
      struct ie_recv_frame_desc rfd;
      struct mbuf *m=0;
      struct ifnet *ifp;
-     struct ether_header eh;
      int last;
  
      ifp = &sc->sc_ethercom.ec_if;
--- 1280,1285 ----
***************
*** 1300,1306 ****
      sc->rfhead = ( sc->rfhead + 1 ) % NFRAMES;
  
      if ( status & IE_FD_OK ) {
! 	m = ieget(sc, &eh, 0);
  	ie_drop_packet_buffer(sc);
      }
  
--- 1308,1314 ----
      sc->rfhead = ( sc->rfhead + 1 ) % NFRAMES;
  
      if ( status & IE_FD_OK ) {
! 	m = ieget(sc, 0);
  	ie_drop_packet_buffer(sc);
      }
  
***************
*** 1309,1326 ****
  	return;
      }
  
- /*
-     printf ( "%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
- 		ether_sprintf(eh.ether_shost), (u_int)eh.ether_type );
- */
- 
  #if NBFILTER > 0
      if ( ifp->if_bpf ) {
  	bpf_mtap(ifp->if_bpf, m );
      };
  #endif
  
!     ether_input ( ifp, &eh, m );
      ifp->if_ipackets++;
  }
  
--- 1317,1329 ----
  	return;
      }
  
  #if NBFILTER > 0
      if ( ifp->if_bpf ) {
  	bpf_mtap(ifp->if_bpf, m );
      };
  #endif
  
!     (*ifp->if_input)(ifp, m);
      ifp->if_ipackets++;
  }
  
Index: arch/arm32/rc7500/if_es.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm32/rc7500/if_es.c,v
retrieving revision 1.15
diff -c -r1.15 if_es.c
*** if_es.c	1999/03/16 10:55:42	1.15
--- if_es.c	1999/05/12 00:44:05
***************
*** 642,648 ****
  	}
  #endif
  
- 	pktlen -= sizeof(struct ether_header);
  	ifp = &sc->sc_ethercom.ec_if;
  	ifp->if_ipackets++;
  	MGETHDR(m, M_DONTWAIT, MT_DATA);
--- 642,647 ----
***************
*** 656,662 ****
  
  	eh = (struct ether_header *) pktbuf;
  
! 	b = pktbuf + sizeof(struct ether_header);
  
  	while (pktlen > 0) {
  		if (top) {
--- 655,661 ----
  
  	eh = (struct ether_header *) pktbuf;
  
! 	b = pktbuf;
  
  	while (pktlen > 0) {
  		if (top) {
***************
*** 686,693 ****
  	 * the raw packet to bpf.
  	 */
  	if (sc->sc_ethercom.ec_if.if_bpf) {
! 		bpf_tap(sc->sc_ethercom.ec_if.if_bpf, pktbuf, pktlen);
! 		/* bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, top);*/
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
--- 685,691 ----
  	 * the raw packet to bpf.
  	 */
  	if (sc->sc_ethercom.ec_if.if_bpf) {
! 		bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, top);
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
***************
*** 704,710 ****
  	}
  #endif
  
! 	ether_input(ifp, eh, top);
  #ifdef ESDEBUG
  	if (--sc->sc_smcbusy) {
  		printf("%s: esintr busy on exit\n", sc->sc_dev.dv_xname);
--- 702,708 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, top);
  #ifdef ESDEBUG
  	if (--sc->sc_smcbusy) {
  		printf("%s: esintr busy on exit\n", sc->sc_dev.dv_xname);
Index: arch/mac68k/dev/if_mc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/dev/if_mc.c,v
retrieving revision 1.12
diff -c -r1.12 if_mc.c
*** if_mc.c	1998/12/22 08:47:05	1.12
--- if_mc.c	1999/05/12 00:44:21
***************
*** 659,667 ****
  
  	ifp->if_ipackets++;
  
! 	/* Pass the packet up, with the ether header sort-of removed. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 659,666 ----
  
  	ifp->if_ipackets++;
  
! 	/* Pass the packet up. */
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
Index: arch/mac68k/dev/if_sn.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/dev/if_sn.c,v
retrieving revision 1.20
diff -c -r1.20 if_sn.c
*** if_sn.c	1998/12/22 08:47:05	1.20
--- if_sn.c	1999/05/12 00:44:23
***************
*** 77,84 ****
  static __inline__ u_int	sonicput __P((struct sn_softc *sc, struct mbuf *m0,
  			    int mtd_next));
  static __inline__ int	sonic_read __P((struct sn_softc *, caddr_t, int));
! static __inline__ struct mbuf *sonic_get __P((struct sn_softc *,
! 			    struct ether_header *, int));
  
  #undef assert
  #undef _assert
--- 77,83 ----
  static __inline__ u_int	sonicput __P((struct sn_softc *sc, struct mbuf *m0,
  			    int mtd_next));
  static __inline__ int	sonic_read __P((struct sn_softc *, caddr_t, int));
! static __inline__ struct mbuf *sonic_get __P((struct sn_softc *, caddr_t, int));
  
  #undef assert
  #undef _assert
***************
*** 1099,1111 ****
  	int len;
  {
  	struct ifnet *ifp = &sc->sc_if;
! 	struct ether_header *et;
  	struct mbuf *m;
  
  	/*
  	 * Get pointer to ethernet header (in input buffer).
  	 */
! 	et = (struct ether_header *)pkt;
  
  #ifdef SNDEBUG
  	{
--- 1098,1110 ----
  	int len;
  {
  	struct ifnet *ifp = &sc->sc_if;
! 	struct ether_header *eh;
  	struct mbuf *m;
  
  	/*
  	 * Get pointer to ethernet header (in input buffer).
  	 */
! 	eh = (struct ether_header *)pkt;
  
  #ifdef SNDEBUG
  	{
***************
*** 1129,1136 ****
  	 * not destined for us (but be sure to keep broadcast/multicast).
  	 */
  	if (ifp->if_bpf) {
! 		bpf_tap(ifp->if_bpf, pkt,
! 		    len + sizeof(struct ether_header));
  		if ((ifp->if_flags & IFF_PROMISC) != 0 &&
  		    (et->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
  		    bcmp(et->ether_dhost, LLADDR(ifp->if_sadl),
--- 1128,1134 ----
  	 * not destined for us (but be sure to keep broadcast/multicast).
  	 */
  	if (ifp->if_bpf) {
! 		bpf_tap(ifp->if_bpf, pkt, len);
  		if ((ifp->if_flags & IFF_PROMISC) != 0 &&
  		    (et->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
  		    bcmp(et->ether_dhost, LLADDR(ifp->if_sadl),
***************
*** 1138,1164 ****
  			return (0);
  	}
  #endif
! 	m = sonic_get(sc, et, len);
  	if (m == NULL)
  		return (0);
! 	ether_input(ifp, et, m);
  	return (1);
  }
  
- #define sonicdataaddr(eh, off, type)	((type)(((caddr_t)((eh) + 1) + (off))))
- 
  /*
   * munge the received packet into an mbuf chain
   */
  static __inline__ struct mbuf *
! sonic_get(sc, eh, datalen)
  	struct sn_softc *sc;
! 	struct ether_header *eh;
  	int datalen;
  {
  	struct	mbuf *m, *top, **mp;
  	int	len;
- 	caddr_t	pkt = sonicdataaddr(eh, 0, caddr_t);
  
  	MGETHDR(m, M_DONTWAIT, MT_DATA);
  	if (m == 0)
--- 1136,1159 ----
  			return (0);
  	}
  #endif
! 	m = sonic_get(sc, pkt, len);
  	if (m == NULL)
  		return (0);
! 	(*ifp->if_input)(ifp, m);
  	return (1);
  }
  
  /*
   * munge the received packet into an mbuf chain
   */
  static __inline__ struct mbuf *
! sonic_get(sc, pkt, datalen)
  	struct sn_softc *sc;
! 	caddr_t pkt;
  	int datalen;
  {
  	struct	mbuf *m, *top, **mp;
  	int	len;
  
  	MGETHDR(m, M_DONTWAIT, MT_DATA);
  	if (m == 0)
Index: arch/macppc/dev/am79c950.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/am79c950.c,v
retrieving revision 1.6
diff -c -r1.6 am79c950.c
*** am79c950.c	1998/09/03 14:06:06	1.6
--- am79c950.c	1999/05/12 00:44:23
***************
*** 679,687 ****
  
  	ifp->if_ipackets++;
  
! 	/* Pass the packet up, with the ether header sort-of removed. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 679,686 ----
  
  	ifp->if_ipackets++;
  
! 	/* Pass the packet up. */
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
Index: arch/macppc/dev/if_bm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/if_bm.c,v
retrieving revision 1.1
diff -c -r1.1 if_bm.c
*** if_bm.c	1999/01/01 01:27:52	1.1
--- if_bm.c	1999/05/12 00:44:25
***************
*** 457,464 ****
  		if (ifp->if_bpf)
  			bpf_mtap(ifp->if_bpf, m);
  #endif
! 		m_adj(m, sizeof(struct ether_header));
! 		ether_input(ifp, data, m);
  		ifp->if_ipackets++;
  
  next:
--- 457,463 ----
  		if (ifp->if_bpf)
  			bpf_mtap(ifp->if_bpf, m);
  #endif
! 		(*ifp->if_input)(ifp, m);
  		ifp->if_ipackets++;
  
  next:
Index: arch/next68k/dev/mb8795.c
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/dev/mb8795.c,v
retrieving revision 1.10
diff -c -r1.10 mb8795.c
*** mb8795.c	1999/02/28 17:11:52	1.10
--- mb8795.c	1999/05/12 00:44:35
***************
*** 369,380 ****
  				ifp->if_ipackets++;
  				debugipkt++;
  
! 				/* We assume that the header fit entirely in one mbuf. */
! 				eh = mtod(m, struct ether_header *);
! 
! 				/* Pass the packet up, with the ether header sort-of removed. */
! 				m_adj(m, sizeof(struct ether_header));
! 				ether_input(ifp, eh, m);
  			}
  
  			s = spldma();
--- 369,376 ----
  				ifp->if_ipackets++;
  				debugipkt++;
  
! 				/* Pass the packet up. */
! 				(*ifp->if_input)(ifp, m);
  			}
  
  			s = spldma();
Index: arch/pc532/dev/lpt.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pc532/dev/lpt.c,v
retrieving revision 1.29
diff -c -r1.29 lpt.c
*** lpt.c	1999/04/06 19:43:04	1.29
--- lpt.c	1999/05/12 00:44:37
***************
*** 831,839 ****
  			bpf_mtap(ifp->if_bpf, m);
  		}
  #endif
! 		/* We assume the header fit entirely in one mbuf. */
! 		m_adj(m, sizeof(struct ether_header));
! 		ether_input(ifp, eh, m);
  	}
  	splx(s);
  	sc->sc_ifierrs = 0;
--- 831,837 ----
  			bpf_mtap(ifp->if_bpf, m);
  		}
  #endif
! 		(*ifp->if_input)(ifp, m);
  	}
  	splx(s);
  	sc->sc_ifierrs = 0;
Index: arch/sun3/dev/if_ie.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sun3/dev/if_ie.c,v
retrieving revision 1.29
diff -c -r1.29 if_ie.c
*** if_ie.c	1999/03/25 23:13:54	1.29
--- if_ie.c	1999/05/12 00:44:48
***************
*** 212,219 ****
  		struct ether_header *eh, int *));
  static inline int ie_buflen __P((struct ie_softc *, int));
  static inline int ie_packet_len __P((struct ie_softc *));
! static inline struct mbuf * ieget __P((struct ie_softc *sc,
! 		struct ether_header *ehp, int *to_bpf));
  
  
  /*
--- 212,218 ----
  		struct ether_header *eh, int *));
  static inline int ie_buflen __P((struct ie_softc *, int));
  static inline int ie_packet_len __P((struct ie_softc *));
! static inline struct mbuf * ieget __P((struct ie_softc *sc, int *to_bpf));
  
  
  /*
***************
*** 913,927 ****
   * operation considerably.  (Provided that it works, of course.)
   */
  static inline struct mbuf *
! ieget(sc, ehp, to_bpf)
  	struct ie_softc *sc;
- 	struct ether_header *ehp;
  	int *to_bpf;
  {
  	struct mbuf *top, **mp, *m;
  	int len, totlen, resid;
  	int thisrboff, thismboff;
  	int head;
  
  	totlen = ie_packet_len(sc);
  	if (totlen <= 0)
--- 912,926 ----
   * operation considerably.  (Provided that it works, of course.)
   */
  static inline struct mbuf *
! ieget(sc, to_bpf)
  	struct ie_softc *sc;
  	int *to_bpf;
  {
  	struct mbuf *top, **mp, *m;
  	int len, totlen, resid;
  	int thisrboff, thismboff;
  	int head;
+ 	struct ether_header eh;
  
  	totlen = ie_packet_len(sc);
  	if (totlen <= 0)
***************
*** 932,938 ****
  	/*
  	 * Snarf the Ethernet header.
  	 */
! 	(sc->sc_memcpy)((caddr_t)ehp, (caddr_t)sc->cbuffs[head], sizeof(*ehp));
  
  	/*
  	 * As quickly as possible, check if this packet is for us.
--- 931,938 ----
  	/*
  	 * Snarf the Ethernet header.
  	 */
! 	(sc->sc_memcpy)((caddr_t)&eh, (caddr_t)sc->cbuffs[head],
! 	    sizeof(struct ether_header));
  
  	/*
  	 * As quickly as possible, check if this packet is for us.
***************
*** 941,953 ****
  	 * This is only a consideration when FILTER is defined; i.e., when
  	 * we are either running BPF or doing multicasting.
  	 */
! 	if (!check_eh(sc, ehp, to_bpf)) {
  		/* just this case, it's not an error */
  		sc->sc_if.if_ierrors--;
  		return 0;
  	}
  
! 	resid = totlen -= (thisrboff = sizeof *ehp);
  
  	MGETHDR(m, M_DONTWAIT, MT_DATA);
  	if (m == 0)
--- 941,953 ----
  	 * This is only a consideration when FILTER is defined; i.e., when
  	 * we are either running BPF or doing multicasting.
  	 */
! 	if (!check_eh(sc, &eh, to_bpf)) {
  		/* just this case, it's not an error */
  		sc->sc_if.if_ierrors--;
  		return 0;
  	}
  
! 	resid = totlen;
  
  	MGETHDR(m, M_DONTWAIT, MT_DATA);
  	if (m == 0)
***************
*** 987,992 ****
--- 987,1000 ----
  	thismboff = 0;
  
  	/*
+ 	 * Copy the Ethernet header into the mbuf chain.
+ 	 */
+ 	memcpy(mtod(m, caddr_t), &eh, sizeof(struct ether_header));
+ 	thismboff = sizeof(struct ether_header);
+ 	thisrboff = sizeof(struct ether_header);
+ 	resid -= sizeof(struct ether_header);
+ 
+ 	/*
  	 * Now we take the mbuf chain (hopefully only one mbuf most of the
  	 * time) and stuff the data into it.  There are no possible failures
  	 * at or after this point.
***************
*** 1038,1044 ****
  {
  	int status;
  	struct mbuf *m = 0;
- 	struct ether_header eh;
  #if NBPFILTER > 0
  	int bpf_gets_it = 0;
  #endif
--- 1046,1051 ----
***************
*** 1054,1062 ****
  
  	if (status & IE_FD_OK) {
  #if NBPFILTER > 0
! 		m = ieget(sc, &eh, &bpf_gets_it);
  #else
! 		m = ieget(sc, &eh, 0);
  #endif
  		ie_drop_packet_buffer(sc);
  	}
--- 1061,1069 ----
  
  	if (status & IE_FD_OK) {
  #if NBPFILTER > 0
! 		m = ieget(sc, &bpf_gets_it);
  #else
! 		m = ieget(sc, 0);
  #endif
  		ie_drop_packet_buffer(sc);
  	}
***************
*** 1066,1075 ****
  	}
  
  #ifdef IEDEBUG
! 	if (sc->sc_debug & IED_READFRAME)
  		printf("%s: frame from ether %s type 0x%x\n",
  			sc->sc_dev.dv_xname,
! 		    ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
  #endif
  
  #if NBPFILTER > 0
--- 1073,1085 ----
  	}
  
  #ifdef IEDEBUG
! 	if (sc->sc_debug & IED_READFRAME) {
! 		struct ether_header *eh = mtod(m, struct ether_header *);
! 
  		printf("%s: frame from ether %s type 0x%x\n",
  			sc->sc_dev.dv_xname,
! 		    ether_sprintf(eh->ether_shost), (u_int)eh->ether_type);
! 	}
  #endif
  
  #if NBPFILTER > 0
***************
*** 1082,1094 ****
  	 * tho' it will make a copy for tcpdump.)
  	 */
  	if (bpf_gets_it) {
- 		struct mbuf m0;
- 		m0.m_len = sizeof eh;
- 		m0.m_data = (caddr_t)&eh;
- 		m0.m_next = m;
- 
  		/* Pass it up. */
! 		bpf_mtap(sc->sc_if.if_bpf, &m0);
  
  		/*
  		 * A signal passed up from the filtering code indicating that
--- 1092,1099 ----
  	 * tho' it will make a copy for tcpdump.)
  	 */
  	if (bpf_gets_it) {
  		/* Pass it up. */
! 		bpf_mtap(sc->sc_if.if_bpf, m);
  
  		/*
  		 * A signal passed up from the filtering code indicating that
***************
*** 1114,1120 ****
  	/*
  	 * Finally pass this packet up to higher layers.
  	 */
! 	ether_input(&sc->sc_if, &eh, m);
  	sc->sc_if.if_ipackets++;
  }
  
--- 1119,1125 ----
  	/*
  	 * Finally pass this packet up to higher layers.
  	 */
! 	(*ifp->if_input)(&sc->sc_if, m);
  	sc->sc_if.if_ipackets++;
  }
  
Index: arch/vax/if/if_de.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/if/if_de.c,v
retrieving revision 1.35
diff -c -r1.35 if_de.c
*** if_de.c	1998/11/29 14:48:52	1.35
--- if_de.c	1999/05/12 00:44:49
***************
*** 583,590 ****
  	 * information to be at the front.
  	 */
  	m = if_ubaget(&ds->ds_deuba, ifrw, len, &ds->ds_if);
! 	if (m)
! 		ether_input(&ds->ds_if, eh, m);
  }
  /*
   * Process an ioctl request.
--- 583,599 ----
  	 * information to be at the front.
  	 */
  	m = if_ubaget(&ds->ds_deuba, ifrw, len, &ds->ds_if);
! 	if (m) {
! 		/*
! 		 * XXX I'll let ragge make this sane.  I'm not entirely
! 		 * XXX sure what's going on in if_ubaget().
! 		 */
! 		M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
! 		if (m) {
! 			*mtod(m, struct ether_header *) = *eh;
! 			(*ds->ds_if.if_input)(&ds->ds_if, m);
! 		}
! 	}
  }
  /*
   * Process an ioctl request.
Index: arch/vax/if/if_qe.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/if/if_qe.c,v
retrieving revision 1.33
diff -c -r1.33 if_qe.c
*** if_qe.c	1998/11/29 14:48:52	1.33
--- if_qe.c	1999/05/12 00:44:50
***************
*** 1030,1036 ****
--- 1030,1047 ----
  *(((u_long *)m->m_data)+3)
  ; }
  #endif
+ 	if (m == NULL)
+ 		return;
  
+ 	/*
+ 	 * XXX I'll let ragge make this sane.  I'm not entirely
+ 	 * XXX sure what's going on in if_ubaget().
+ 	 */
+ 	M_PREPEND(m, sizeof(struct ether_header), M_DONTWWAIT);
+ 	if (m == NULL)
+ 		return;
+ 	*mtod(m, struct ether_header) = *eh;
+ 
  #if NBPFILTER > 0
  	/*
  	 * Check for a BPF filter; if so, hand it up.
***************
*** 1041,1053 ****
  	 * tho' it will make a copy for tcpdump.)
  	 */
  	if (sc->qe_if.if_bpf) {
- 		struct mbuf m0;
- 		m0.m_len = sizeof (struct ether_header);
- 		m0.m_data = (caddr_t)eh;
- 		m0.m_next = m;
-  
  		/* Pass it up */
! 		bpf_mtap(sc->qe_if.if_bpf, &m0);
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
--- 1052,1059 ----
  	 * tho' it will make a copy for tcpdump.)
  	 */
  	if (sc->qe_if.if_bpf) {
  		/* Pass it up */
! 		bpf_mtap(sc->qe_if.if_bpf, m);
  
  		/*
  		 * Note that the interface cannot be in promiscuous mode if
***************
*** 1064,1071 ****
  	}
  #endif /* NBPFILTER > 0 */
  
! 	if (m)
! 		ether_input((struct ifnet *)&sc->qe_if, eh, m);
  }
  
  /*
--- 1070,1076 ----
  	}
  #endif /* NBPFILTER > 0 */
  
! 	(*sc->qe_if.if_input)(&sc->qe_if, m);
  }
  
  /*
Index: arch/vax/vsa/if_ln.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/vsa/if_ln.c,v
retrieving revision 1.12
diff -c -r1.12 if_ln.c
*** if_ln.c	1999/04/14 23:14:46	1.12
--- if_ln.c	1999/05/12 00:44:51
***************
*** 577,585 ****
  	}
  #endif
  
! 	/* Pass the packet up, with the ether header sort-of removed. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  static inline void
--- 577,584 ----
  	}
  #endif
  
! 	/* Pass the packet up. */
! 	(*ifp->if_input)(ifp, m);
  }
  
  static inline void
Index: arch/x68k/dev/if_se.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/dev/if_se.c,v
retrieving revision 1.7
diff -c -r1.7 if_se.c
*** if_se.c	1999/03/25 23:17:35	1.7
--- if_se.c	1999/05/12 00:44:53
***************
*** 1468,1479 ****
  	}
  #endif
  
! 	/*
! 	 * Fix up data start offset in mbuf to point past ether header
! 	 */
! 	m_adj(head, sizeof(struct ether_header));
! 
! 	ether_input(&sc->sc_arpcom.ac_if, eh, head);
  	return;
  
  bad:	if (head)
--- 1468,1474 ----
  	}
  #endif
  
! 	(*sc->sc_arpcom.ac_if)(&sc->sc_arpcom.ac_if, head);
  	return;
  
  bad:	if (head)
Index: dev/ic/dp8390.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/dp8390.c,v
retrieving revision 1.23
diff -c -r1.23 dp8390.c
*** dp8390.c	1999/03/25 23:18:31	1.23
--- dp8390.c	1999/05/12 00:45:02
***************
*** 983,991 ****
  	}
  #endif
  
! 	/* Fix up data start offset in mbuf to point past ether header. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  
--- 983,989 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, m);
  }
  
  
Index: dev/ic/elink3.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/elink3.c,v
retrieving revision 1.57
diff -c -r1.57 elink3.c
*** elink3.c	1999/04/20 04:40:24	1.57
--- elink3.c	1999/05/12 00:45:02
***************
*** 1504,1513 ****
  		}
  	}
  #endif
! 
! 	/* We assume the header fit entirely in one mbuf. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  
  	/*
  	 * In periods of high traffic we can actually receive enough
--- 1504,1510 ----
  		}
  	}
  #endif
! 	(*ifp->if_input)(ifp, m);
  
  	/*
  	 * In periods of high traffic we can actually receive enough
Index: dev/ic/elinkxl.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/elinkxl.c,v
retrieving revision 1.10
diff -c -r1.10 elinkxl.c
*** elinkxl.c	1999/04/28 17:34:01	1.10
--- elinkxl.c	1999/05/12 00:45:02
***************
*** 1183,1191 ****
  						goto rcvloop;
  					}
  					m->m_pkthdr.rcvif = ifp;
! 					m->m_pkthdr.len = m->m_len =
! 					    total_len -
! 					    sizeof(struct ether_header);
  					eh = mtod(m, struct ether_header *);
  #if NBPFILTER > 0
  					if (ifp->if_bpf) {
--- 1183,1189 ----
  						goto rcvloop;
  					}
  					m->m_pkthdr.rcvif = ifp;
! 					m->m_pkthdr.len = m->m_len = total_len;
  					eh = mtod(m, struct ether_header *);
  #if NBPFILTER > 0
  					if (ifp->if_bpf) {
***************
*** 1209,1217 ****
  						}
  					}
  #endif /* NBPFILTER > 0 */
! 					m->m_data +=
! 					    sizeof(struct ether_header);
! 					ether_input(ifp, eh, m);
  				}
  				goto rcvloop;
  			}
--- 1207,1213 ----
  						}
  					}
  #endif /* NBPFILTER > 0 */
! 					(*ifp->if_input)(ifp, m);
  				}
  				goto rcvloop;
  			}
Index: dev/ic/i82586.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/i82586.c,v
retrieving revision 1.20
diff -c -r1.20 i82586.c
*** i82586.c	1999/02/17 03:41:00	1.20
--- i82586.c	1999/05/12 00:45:02
***************
*** 201,208 ****
  						struct ifmediareq *));
  
  static int 	ie_readframe		__P((struct ie_softc *, int));
! static struct mbuf *ieget 		__P((struct ie_softc *,
! 					     struct ether_header *, int *,
  					     int, int));
  static int	i82586_get_rbd_list	__P((struct ie_softc *,
  					     u_int16_t *, u_int16_t *, int *));
--- 201,207 ----
  						struct ifmediareq *));
  
  static int 	ie_readframe		__P((struct ie_softc *, int));
! static struct mbuf *ieget 		__P((struct ie_softc *, int *,
  					     int, int));
  static int	i82586_get_rbd_list	__P((struct ie_softc *,
  					     u_int16_t *, u_int16_t *, int *));
***************
*** 1074,1082 ****
   * operation considerably.  (Provided that it works, of course.)
   */
  static __inline struct mbuf *
! ieget(sc, ehp, to_bpf, head, totlen)
  	struct ie_softc *sc;
- 	struct ether_header *ehp;
  	int *to_bpf;
  	int head;
  	int totlen;
--- 1073,1080 ----
   * operation considerably.  (Provided that it works, of course.)
   */
  static __inline struct mbuf *
! ieget(sc, to_bpf, head, totlen)
  	struct ie_softc *sc;
  	int *to_bpf;
  	int head;
  	int totlen;
***************
*** 1084,1094 ****
  	struct mbuf *m, *m0, *newm;
  	int len, resid;
  	int thisrboff, thismboff;
  
  	/*
  	 * Snarf the Ethernet header.
  	 */
! 	(sc->memcopyin)(sc, ehp, IE_RBUF_ADDR(sc, head), sizeof *ehp);
  
  	/*
  	 * As quickly as possible, check if this packet is for us.
--- 1082,1094 ----
  	struct mbuf *m, *m0, *newm;
  	int len, resid;
  	int thisrboff, thismboff;
+ 	struct ether_header eh;
  
  	/*
  	 * Snarf the Ethernet header.
  	 */
! 	(sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head),
! 	    sizeof(struct ether_header));
  
  	/*
  	 * As quickly as possible, check if this packet is for us.
***************
*** 1097,1109 ****
  	 * This is only a consideration when FILTER is defined; i.e., when
  	 * we are either running BPF or doing multicasting.
  	 */
! 	if (!check_eh(sc, ehp, to_bpf)) {
  		/* just this case, it's not an error */
  		sc->sc_ethercom.ec_if.if_ierrors--;
  		return (0);
  	}
  
! 	resid = totlen -= (thisrboff = sizeof *ehp);
  
  	MGETHDR(m0, M_DONTWAIT, MT_DATA);
  	if (m0 == 0)
--- 1097,1109 ----
  	 * This is only a consideration when FILTER is defined; i.e., when
  	 * we are either running BPF or doing multicasting.
  	 */
! 	if (!check_eh(sc, &eh, to_bpf)) {
  		/* just this case, it's not an error */
  		sc->sc_ethercom.ec_if.if_ierrors--;
  		return (0);
  	}
  
! 	resid = totlen;
  
  	MGETHDR(m0, M_DONTWAIT, MT_DATA);
  	if (m0 == 0)
***************
*** 1141,1146 ****
--- 1141,1154 ----
  	thismboff = 0;
  
  	/*
+ 	 * Copy the Ethernet header into the mbuf chain.
+ 	 */
+ 	memcpy(mtod(m, caddr_t), &eh, sizeof(struct ether_header));
+ 	thismboff = sizeof(struct ether_header);
+ 	thisrboff = sizeof(struct ether_header);
+ 	resid -= sizeof(struct ether_header);
+ 
+ 	/*
  	 * Now we take the mbuf chain (hopefully only one mbuf most of the
  	 * time) and stuff the data into it.  There are no possible failures
  	 * at or after this point.
***************
*** 1196,1202 ****
  	int num;		/* frame number to read */
  {
  	struct mbuf *m;
- 	struct ether_header eh;
  	u_int16_t bstart, bend;
  	int pktlen;
  #if NBPFILTER > 0
--- 1204,1209 ----
***************
*** 1209,1217 ****
  	}
  
  #if NBPFILTER > 0
! 	m = ieget(sc, &eh, &bpf_gets_it, bstart, pktlen);
  #else
! 	m = ieget(sc, &eh, 0, bstart, pktlen);
  #endif
  	i82586_release_rbd_list(sc, bstart, bend);
  
--- 1216,1224 ----
  	}
  
  #if NBPFILTER > 0
! 	m = ieget(sc, &bpf_gets_it, bstart, pktlen);
  #else
! 	m = ieget(sc, 0, bstart, pktlen);
  #endif
  	i82586_release_rbd_list(sc, bstart, bend);
  
***************
*** 1221,1232 ****
  	}
  
  #ifdef I82586_DEBUG
! 	if (sc->sc_debug & IED_READFRAME)
  		printf("%s: frame from ether %s type 0x%x len %d\n",
  			sc->sc_dev.dv_xname,
! 			ether_sprintf(eh.ether_shost),
! 			(u_int)eh.ether_type,
  			pktlen);
  #endif
  
  #if NBPFILTER > 0
--- 1228,1242 ----
  	}
  
  #ifdef I82586_DEBUG
! 	if (sc->sc_debug & IED_READFRAME) {
! 		struct ether_header *eh = mtod(m, struct ether_header *);
! 
  		printf("%s: frame from ether %s type 0x%x len %d\n",
  			sc->sc_dev.dv_xname,
! 			ether_sprintf(eh->ether_shost),
! 			(u_int)eh->ether_type,
  			pktlen);
+ 	}
  #endif
  
  #if NBPFILTER > 0
***************
*** 1239,1251 ****
  	 * tho' it will make a copy for tcpdump.)
  	 */
  	if (bpf_gets_it) {
- 		struct mbuf m0;
- 		m0.m_len = sizeof eh;
- 		m0.m_data = (caddr_t)&eh;
- 		m0.m_next = m;
- 
  		/* Pass it up. */
! 		bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, &m0);
  
  		/*
  		 * A signal passed up from the filtering code indicating that
--- 1249,1256 ----
  	 * tho' it will make a copy for tcpdump.)
  	 */
  	if (bpf_gets_it) {
  		/* Pass it up. */
! 		bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, m);
  
  		/*
  		 * A signal passed up from the filtering code indicating that
***************
*** 1263,1269 ****
  	/*
  	 * Finally pass this packet up to higher layers.
  	 */
! 	ether_input(&sc->sc_ethercom.ec_if, &eh, m);
  	sc->sc_ethercom.ec_if.if_ipackets++;
  	return (0);
  }
--- 1268,1274 ----
  	/*
  	 * Finally pass this packet up to higher layers.
  	 */
! 	(*sc->sc_ethercom.ec_if.if_input)(&sc->sc_ethercom.ec_if, m);
  	sc->sc_ethercom.ec_if.if_ipackets++;
  	return (0);
  }
Index: dev/ic/lance.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/lance.c,v
retrieving revision 1.8
diff -c -r1.8 lance.c
*** lance.c	1999/04/30 18:15:04	1.8
--- lance.c	1999/05/12 00:45:03
***************
*** 528,536 ****
  	}
  #endif
  
! 	/* Pass the packet up, with the ether header sort-of removed. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  #undef	ifp
--- 528,535 ----
  	}
  #endif
  
! 	/* Pass the packet up. */
! 	(*ifp->if_input)(ifp, m);
  }
  
  #undef	ifp
Index: dev/ic/lemac.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/lemac.c,v
retrieving revision 1.11
diff -c -r1.11 lemac.c
*** lemac.c	1999/02/28 17:10:53	1.11
--- lemac.c	1999/05/12 00:45:03
***************
*** 334,343 ****
  	return;
      }
  #endif
!     m->m_pkthdr.len = m->m_len = length - sizeof(eh);
!     m->m_data += sizeof(eh);
      m->m_pkthdr.rcvif = &sc->sc_if;
!     ether_input(&sc->sc_if, &eh, m);
  }
  
  static void
--- 334,342 ----
  	return;
      }
  #endif
!     m->m_pkthdr.len = m->m_len = length;
      m->m_pkthdr.rcvif = &sc->sc_if;
!     (*sc->sc_if.if_input)(&sc->sc_if, m);
  }
  
  static void
Index: dev/ic/mb86960.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mb86960.c,v
retrieving revision 1.32
diff -c -r1.32 mb86960.c
*** mb86960.c	1999/03/25 23:19:16	1.32
--- mb86960.c	1999/05/12 00:45:03
***************
*** 1390,1398 ****
  	}
  #endif
  
! 	/* Fix up data start offset in mbuf to point past ether header. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  	return (1);
  }
  
--- 1390,1396 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, m);
  	return (1);
  }
  
Index: dev/ic/pdq_ifsubr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/pdq_ifsubr.c,v
retrieving revision 1.24
diff -c -r1.24 pdq_ifsubr.c
*** pdq_ifsubr.c	1998/09/28 18:01:44	1.24
--- pdq_ifsubr.c	1999/05/12 00:45:03
***************
*** 239,245 ****
      int drop)
  {
      pdq_softc_t *sc = pdq->pdq_os_ctx;
!     struct fddi_header *fh = mtod(m, struct fddi_header *);
  
      sc->sc_if.if_ipackets++;
  #if defined(PDQ_BUS_DMA)
--- 239,245 ----
      int drop)
  {
      pdq_softc_t *sc = pdq->pdq_os_ctx;
!     struct fddi_header *fh;
  
      sc->sc_if.if_ipackets++;
  #if defined(PDQ_BUS_DMA)
***************
*** 265,280 ****
      if (sc->sc_bpf != NULL)
  	PDQ_BPF_MTAP(sc, m);
  #endif
      if (drop || (fh->fddi_fc & (FDDIFC_L|FDDIFC_F)) != FDDIFC_LLC_ASYNC) {
  	PDQ_OS_DATABUF_FREE(pdq, m);
  	return;
      }
  
-     m->m_data += sizeof(struct fddi_header);
-     m->m_len  -= sizeof(struct fddi_header);
-     m->m_pkthdr.len -= sizeof(struct fddi_header);
      m->m_pkthdr.rcvif = &sc->sc_if;
!     fddi_input(&sc->sc_if, fh, m);
  }
  
  void
--- 265,278 ----
      if (sc->sc_bpf != NULL)
  	PDQ_BPF_MTAP(sc, m);
  #endif
+     fh = mtod(m, struct fddi_header *);
      if (drop || (fh->fddi_fc & (FDDIFC_L|FDDIFC_F)) != FDDIFC_LLC_ASYNC) {
  	PDQ_OS_DATABUF_FREE(pdq, m);
  	return;
      }
  
      m->m_pkthdr.rcvif = &sc->sc_if;
!     (*sc->sc_if.if_input)(&sc->sc_if, m);
  }
  
  void
Index: dev/ic/rrunner.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/rrunner.c,v
retrieving revision 1.9
diff -c -r1.9 rrunner.c
*** rrunner.c	1999/03/24 05:51:20	1.9
--- rrunner.c	1999/05/12 00:45:03
***************
*** 2405,2411 ****
  {
  	struct ifnet *ifp = &sc->sc_if;
  	struct esh_snap_ring_ctl *recv = &sc->sc_snap_recv;
- 	struct hippi_header *hh;
  	int start_consumer = recv->ec_consumer;
  	u_int16_t control;
  
--- 2405,2410 ----
***************
*** 2489,2498 ****
  				if ((ifp->if_flags & IFF_RUNNING) == 0) {
  					m_freem(m);
  				} else {
! 					m = m_pullup(m, sizeof(struct hippi_header *));
! 					hh = mtod(m, struct hippi_header *);
! 					m_adj(m, sizeof(struct hippi_header));
! 					hippi_input(ifp, hh, m);
  				}
  			} else {
  				ifp->if_ierrors++;
--- 2488,2496 ----
  				if ((ifp->if_flags & IFF_RUNNING) == 0) {
  					m_freem(m);
  				} else {
! 					m = m_pullup(m,
! 					    sizeof(struct hippi_header));
! 					(*ifp->if_input)(ifp, m);
  				}
  			} else {
  				ifp->if_ierrors++;
Index: dev/ic/smc83c170.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/smc83c170.c,v
retrieving revision 1.15
diff -c -r1.15 smc83c170.c
*** smc83c170.c	1999/03/25 23:19:59	1.15
--- smc83c170.c	1999/05/12 00:45:04
***************
*** 736,744 ****
  			}
  #endif /* NPBFILTER > 0 */
  			
! 			/* Remove the Ethernet header and pass it on. */
! 			m_adj(m, sizeof(struct ether_header));
! 			ether_input(ifp, eh, m);
  		}
  
  		/* Update the recieve pointer. */
--- 736,743 ----
  			}
  #endif /* NPBFILTER > 0 */
  			
! 			/* Pass it on. */
! 			(*ifp->if_input)(ifp, m);
  		}
  
  		/* Update the recieve pointer. */
Index: dev/ic/smc91cxx.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/smc91cxx.c,v
retrieving revision 1.16
diff -c -r1.16 smc91cxx.c
*** smc91cxx.c	1999/03/25 23:20:22	1.16
--- smc91cxx.c	1999/05/12 00:45:04
***************
*** 940,952 ****
  	}
  #endif
  
! 	/*
! 	 * Strip the ethernet header.
! 	 */
! 	m->m_pkthdr.len = m->m_len = packetlen - sizeof(struct ether_header);
! 	m->m_data += sizeof(struct ether_header);
! 
! 	ether_input(ifp, eh, m);
  
   out:
  	/*
--- 940,947 ----
  	}
  #endif
  
! 	m->m_pkthdr.len = m->m_len = packetlen;
! 	(*ifp->if_input)(ifp, m);
  
   out:
  	/*
Index: dev/ic/tropic.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/tropic.c,v
retrieving revision 1.3
diff -c -r1.3 tropic.c
*** tropic.c	1999/04/29 15:47:02	1.3
--- tropic.c	1999/05/12 00:45:04
***************
*** 1173,1179 ****
  	struct rbcb *rbc = &sc->rbc;
  	struct mbuf *m;
  	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
- 	struct token_header *trh;
  
  #ifdef TROPICDEBUG
  	printf("tr_rint: arb.command = %x, arb.station_id= %x\n",
--- 1173,1178 ----
***************
*** 1260,1275 ****
  		ACA_SETB(sc, ACA_ISRA_o, RESP_IN_ASB);
  		++ifp->if_ipackets;
  
- 		trh = mtod(m, struct token_header *);
  #if NBPFILTER > 0
  		if (ifp->if_bpf)
  			bpf_mtap(ifp->if_bpf, m);
  #endif
! 		/*
! 		 * lan_hdr_len = sizeof(*trh) + riflen
! 		 */
! 		m_adj(m, (ARB_INB(sc, arb, ARB_RXD_LANHDRLEN)));
! 		token_input(ifp, trh, m);
  	}
  }
  
--- 1259,1269 ----
  		ACA_SETB(sc, ACA_ISRA_o, RESP_IN_ASB);
  		++ifp->if_ipackets;
  
  #if NBPFILTER > 0
  		if (ifp->if_bpf)
  			bpf_mtap(ifp->if_bpf, m);
  #endif
! 		(*ifp->if_input)(ifp, m);
  	}
  }
  
Index: dev/isa/cs89x0.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/cs89x0.c,v
retrieving revision 1.9
diff -c -r1.9 cs89x0.c
*** cs89x0.c	1999/03/30 21:02:41	1.9
--- cs89x0.c	1999/05/12 00:45:04
***************
*** 1589,1600 ****
  	}
  #endif
  
! 	/*
! 	 * Pass the packet up, with the ether header sort-of removed. ie.
! 	 * adjust the data pointer to point to the data.
! 	 */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  void 
--- 1589,1596 ----
  	}
  #endif
  
! 	/* Pass the packet up. */
! 	(*ifp->if_input)(ifp, m);
  }
  
  void 
Index: dev/isa/if_eg.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/if_eg.c,v
retrieving revision 1.46
diff -c -r1.46 if_eg.c
*** if_eg.c	1999/03/25 23:21:38	1.46
--- if_eg.c	1999/05/12 00:45:04
***************
*** 798,806 ****
  	}
  #endif
  
! 	/* We assume the header fit entirely in one mbuf. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 798,804 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
Index: dev/isa/if_el.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/if_el.c,v
retrieving revision 1.57
diff -c -r1.57 if_el.c
*** if_el.c	1999/03/25 23:21:38	1.57
--- if_el.c	1999/05/12 00:45:04
***************
*** 622,630 ****
  	}
  #endif
  
! 	/* We assume that the header fit entirely in one mbuf. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 622,628 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
Index: dev/isa/if_iy.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/if_iy.c,v
retrieving revision 1.33
diff -c -r1.33 if_iy.c
*** if_iy.c	1999/03/25 23:21:38	1.33
--- if_iy.c	1999/05/12 00:45:05
***************
*** 976,983 ****
  		}
  	}
  #endif
! 	m_adj(top, sizeof(struct ether_header));
! 	ether_input(ifp, eh, top);
  	return;
  
  dropped:
--- 976,982 ----
  		}
  	}
  #endif
! 	(*ifp->if_input)(ifp, top);
  	return;
  
  dropped:
Index: dev/ofw/ofnet.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofnet.c,v
retrieving revision 1.16
diff -c -r1.16 ofnet.c
*** ofnet.c	1999/05/04 23:56:54	1.16
--- ofnet.c	1999/05/12 00:45:06
***************
*** 176,182 ****
  	struct ofnet_softc *of;
  {
  	struct ifnet *ifp = &of->sc_ethercom.ec_if;
- 	struct ether_header *eh;
  	struct mbuf *m, **mp, *head;
  	int l, len;
  	char *bufp;
--- 176,181 ----
***************
*** 256,270 ****
  		}
  		if (head == 0)
  			continue;
- 		eh = mtod(head, struct ether_header *);
  
  #if NBPFILTER > 0
  		if (ifp->if_bpf)
  			bpf_mtap(ifp->if_bpf, m);
  #endif
- 		m_adj(head, sizeof(struct ether_header));
  		ifp->if_ipackets++;
! 		ether_input(ifp, eh, head);
  	}
  }
  
--- 255,267 ----
  		}
  		if (head == 0)
  			continue;
  
  #if NBPFILTER > 0
  		if (ifp->if_bpf)
  			bpf_mtap(ifp->if_bpf, m);
  #endif
  		ifp->if_ipackets++;
! 		(*ifp->if_input)(ifp, head);
  	}
  }
  
Index: dev/pci/files.pci
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/files.pci,v
retrieving revision 1.54
diff -c -r1.54 files.pci
*** files.pci	1999/03/25 00:51:53	1.54
--- files.pci	1999/05/12 00:45:06
***************
*** 188,190 ****
--- 188,195 ----
  device	vr: ether, ifnet, arp, mii
  attach	vr at pci
  file	dev/pci/if_vr.c			vr
+ 
+ # SiS 900 Fast Ethernet controllers
+ device	sip: ether, ifnet, arp, mii
+ attach	sip at pci
+ file	dev/pci/if_sip.c		sip
Index: dev/pci/if_de.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_de.c,v
retrieving revision 1.84
diff -c -r1.84 if_de.c
*** if_de.c	1999/04/12 04:31:55	1.84
--- if_de.c	1999/05/12 00:45:06
***************
*** 3567,3573 ****
--- 3567,3575 ----
  		    && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr))
  		    goto next;
  	    accept = 1;
+ #if !defined(__NetBSD__)
  	    total_len -= sizeof(struct ether_header);
+ #endif
  	} else {
  	    ifp->if_ierrors++;
  	    if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) {
***************
*** 3662,3684 ****
--- 3664,3698 ----
  		eh.ether_type = ntohs(eh.ether_type);
  #endif
  #if !defined(TULIP_COPY_RXDATA)
+ #if defined(__NetBSD__)
+ 		ms->m_pkthdr.len = total_len;
+ 		ms->m_pkthdr.rcvif = ifp;
+ 		(*ifp->if_input)(ifp, ms);
+ #else
  		ms->m_data += sizeof(struct ether_header);
  		ms->m_len -= sizeof(struct ether_header);
  		ms->m_pkthdr.len = total_len;
  		ms->m_pkthdr.rcvif = ifp;
  		ether_input(ifp, &eh, ms);
+ #endif /* __NetBSD__ */
  #else
  #ifdef BIG_PACKET
  #error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
  #endif
+ #if !defined(__NetBSD__)
  		if (ms == me)
  		    bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header),
  			  mtod(m0, caddr_t), total_len);
  		else
+ #endif /* __NetBSD__ */
  		    m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
  		m0->m_len = m0->m_pkthdr.len = total_len;
  		m0->m_pkthdr.rcvif = ifp;
+ #if defined(__NetBSD__)
+ 		(*ifp->if_input)(ifp, m0);
+ #else
  		ether_input(ifp, &eh, m0);
+ #endif /* __NetBSD__ */
  		m0 = ms;
  #endif
  	    }
Index: dev/pci/if_fxp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_fxp.c,v
retrieving revision 1.33
diff -c -r1.33 if_fxp.c
*** if_fxp.c	1999/03/23 23:18:50	1.33
--- if_fxp.c	1999/05/12 00:45:07
***************
*** 944,952 ****
  						goto rcvloop;
  					}
  					m->m_pkthdr.rcvif = ifp;
! 					m->m_pkthdr.len = m->m_len =
! 					    total_len -
! 					    sizeof(struct ether_header);
  					eh = mtod(m, struct ether_header *);
  #if NBPFILTER > 0
  					if (ifp->if_bpf) {
--- 944,950 ----
  						goto rcvloop;
  					}
  					m->m_pkthdr.rcvif = ifp;
! 					m->m_pkthdr.len = m->m_len = total_len;
  					eh = mtod(m, struct ether_header *);
  #if NBPFILTER > 0
  					if (ifp->if_bpf) {
***************
*** 968,976 ****
  						}
  					}
  #endif /* NBPFILTER > 0 */
! 					m->m_data +=
! 					    sizeof(struct ether_header);
! 					ether_input(ifp, eh, m);
  				}
  				goto rcvloop;
  			}
--- 966,972 ----
  						}
  					}
  #endif /* NBPFILTER > 0 */
! 					(*ifp->if_input)(ifp, m);
  				}
  				goto rcvloop;
  			}
Index: dev/pci/if_tl.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_tl.c,v
retrieving revision 1.23
diff -c -r1.23 if_tl.c
*** if_tl.c	1999/03/25 16:15:00	1.23
--- if_tl.c	1999/05/12 00:45:07
***************
*** 947,954 ****
  					continue;
  				}
  				m->m_pkthdr.rcvif = ifp;
! 				m->m_pkthdr.len = m->m_len =
! 					size - sizeof(struct ether_header);
  				eh = mtod(m, struct ether_header *);
  #ifdef TLDEBUG_RX
  				printf("tl_intr: Rx packet:\n");
--- 947,953 ----
  					continue;
  				}
  				m->m_pkthdr.rcvif = ifp;
! 				m->m_pkthdr.len = m->m_len = size;
  				eh = mtod(m, struct ether_header *);
  #ifdef TLDEBUG_RX
  				printf("tl_intr: Rx packet:\n");
***************
*** 973,980 ****
  					}
  				}
  #endif /* NBPFILTER > 0 */
! 				m->m_data += sizeof(struct ether_header);
! 				ether_input(ifp, eh, m);
  			}
  		}
  #ifdef TLDEBUG_RX
--- 972,978 ----
  					}
  				}
  #endif /* NBPFILTER > 0 */
! 				(*ifp->if_input)(ifp, m);
  			}
  		}
  #ifdef TLDEBUG_RX
Index: dev/pci/if_vr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.21
diff -c -r1.21 if_vr.c
*** if_vr.c	1999/04/26 23:19:10	1.21
--- if_vr.c	1999/05/12 00:45:07
***************
*** 863,871 ****
  			}
  		}
  #endif
! 		/* Remove header from mbuf and pass it on. */
! 		m_adj(m, sizeof(struct ether_header));
! 		ether_input(ifp, eh, m);
  	}
  
  	/* Update the receive pointer. */
--- 863,870 ----
  			}
  		}
  #endif
! 		/* Pass it on. */
! 		(*ifp->if_input)(ifp, m);
  	}
  
  	/* Update the receive pointer. */
Index: dev/pcmcia/if_cnw.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pcmcia/if_cnw.c,v
retrieving revision 1.1
diff -c -r1.1 if_cnw.c
*** if_cnw.c	1999/01/01 19:30:03	1.1
--- if_cnw.c	1999/05/12 00:45:08
***************
*** 680,688 ****
  			continue;
  		}
  
! 		/* Pass the packet up, with the ether header sort-of removed */
! 		m_adj(m, sizeof(struct ether_header));
! 		ether_input(ifp, eh, m);
  	}
  }
  
--- 680,687 ----
  			continue;
  		}
  
! 		/* Pass the packet up. */
! 		(*ifp->if_input)(ifp, m);
  	}
  }
  
Index: dev/sbus/be.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sbus/be.c,v
retrieving revision 1.5
diff -c -r1.5 be.c
*** be.c	1999/03/23 00:27:09	1.5
--- be.c	1999/05/12 00:45:08
***************
*** 504,510 ****
  	int idx, len;
  {
  	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
- 	struct ether_header *eh;
  	struct mbuf *m;
  
  	if (len <= sizeof(struct ether_header) ||
--- 504,509 ----
***************
*** 527,535 ****
  	}
  	ifp->if_ipackets++;
  
- 	/* We assume that the header fits entirely in one mbuf. */
- 	eh = mtod(m, struct ether_header *);
- 
  #if NBPFILTER > 0
  	/*
  	 * Check if there's a BPF listener on this interface.
--- 526,531 ----
***************
*** 538,546 ****
  	if (ifp->if_bpf)
  		bpf_mtap(ifp->if_bpf, m);
  #endif
! 	/* Pass the packet up, with the ether header sort-of removed. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 534,541 ----
  	if (ifp->if_bpf)
  		bpf_mtap(ifp->if_bpf, m);
  #endif
! 	/* Pass the packet up. */
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
Index: dev/sbus/qe.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sbus/qe.c,v
retrieving revision 1.5
diff -c -r1.5 qe.c
*** qe.c	1999/03/23 00:27:09	1.5
--- qe.c	1999/05/12 00:45:08
***************
*** 403,409 ****
  	int idx, len;
  {
  	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
- 	struct ether_header *eh;
  	struct mbuf *m;
  
  	if (len <= sizeof(struct ether_header) ||
--- 403,408 ----
***************
*** 426,434 ****
  	}
  	ifp->if_ipackets++;
  
- 	/* We assume that the header fit entirely in one mbuf. */
- 	eh = mtod(m, struct ether_header *);
- 
  #if NBPFILTER > 0
  	/*
  	 * Check if there's a BPF listener on this interface.
--- 425,430 ----
***************
*** 437,445 ****
  	if (ifp->if_bpf)
  		bpf_mtap(ifp->if_bpf, m);
  #endif
! 	/* Pass the packet up, with the ether header sort-of removed. */
! 	m_adj(m, sizeof(struct ether_header));
! 	ether_input(ifp, eh, m);
  }
  
  /*
--- 433,440 ----
  	if (ifp->if_bpf)
  		bpf_mtap(ifp->if_bpf, m);
  #endif
! 	/* Pass the packet up. */
! 	(*ifp->if_input)(ifp, m);
  }
  
  /*
Index: dev/scsipi/if_se.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/if_se.c,v
retrieving revision 1.23
diff -c -r1.23 if_se.c
*** if_se.c	1998/12/12 17:08:14	1.23
--- if_se.c	1999/05/12 00:45:09
***************
*** 710,718 ****
  		}
  #endif
  
! 		/* Pass the packet up, with the ether header sort-of removed. */
! 		m_adj(m, sizeof(struct ether_header));
! 		ether_input(ifp, eh, m);
  
  	next_packet:
  		data += len;
--- 710,717 ----
  		}
  #endif
  
! 		/* Pass the packet up. */
! 		(*ifp->if_input)(ifp, m);
  
  	next_packet:
  		data += len;
Index: ipkdb/ipkdb_if.c
===================================================================
RCS file: /cvsroot/src/sys/ipkdb/ipkdb_if.c,v
retrieving revision 1.8
diff -c -r1.8 ipkdb_if.c
*** ipkdb_if.c	1998/07/05 22:29:52	1.8
--- ipkdb_if.c	1999/05/12 00:45:11
***************
*** 202,213 ****
  	}
  #endif
  
! 	/*
! 	 * Fix up data start offset in mbuf to point past ether header
! 	 */
! 	m_adj(head, sizeof(struct ether_header));
! 
! 	ether_input(ifp, eh, head);
  	return 1;
  
  bad:
--- 202,208 ----
  	}
  #endif
  
! 	(*ifp->if_input)(ifp, head);
  	return 1;
  
  bad:
Index: net/if.h
===================================================================
RCS file: /cvsroot/src/sys/net/if.h,v
retrieving revision 1.35
diff -c -r1.35 if.h
*** if.h	1999/03/27 01:24:49	1.35
--- if.h	1999/05/12 00:45:20
***************
*** 129,134 ****
--- 129,136 ----
  	int	(*if_output)		/* output routine (enqueue) */
  		__P((struct ifnet *, struct mbuf *, struct sockaddr *,
  		     struct rtentry *));
+ 	void	(*if_input)		/* input routine (from h/w driver) */
+ 		__P((struct ifnet *, struct mbuf *));
  	void	(*if_start)		/* initiate output routine */
  		__P((struct ifnet *));
  	int	(*if_ioctl)		/* ioctl routine */
***************
*** 368,374 ****
  struct ifnet_head ifnet;
  
  void	ether_ifattach __P((struct ifnet *, const u_int8_t *));
! void	ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *));
  int	ether_output __P((struct ifnet *,
  	   struct mbuf *, struct sockaddr *, struct rtentry *));
  char	*ether_sprintf __P((const u_char *));
--- 370,376 ----
  struct ifnet_head ifnet;
  
  void	ether_ifattach __P((struct ifnet *, const u_int8_t *));
! void	ether_input __P((struct ifnet *, struct mbuf *));
  int	ether_output __P((struct ifnet *,
  	   struct mbuf *, struct sockaddr *, struct rtentry *));
  char	*ether_sprintf __P((const u_char *));
Index: net/if_arcsubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_arcsubr.c,v
retrieving revision 1.20
diff -c -r1.20 if_arcsubr.c
*** if_arcsubr.c	1999/02/25 11:20:34	1.20
--- if_arcsubr.c	1999/05/12 00:45:20
***************
*** 636,641 ****
--- 636,643 ----
  		    ifp->if_xname, arc_phdsmtu);
  
  	ifp->if_mtu = (ifp->if_flags & IFF_LINK0 ? arc_phdsmtu : ARCMTU);
+ 	ifp->if_output = arc_output;
+ 	ifp->if_input = arc_input;
  	ac = (struct arccom *)ifp;
  	ac->ac_seqid = (time.tv_sec) & 0xFFFF; /* try to make seqid unique */
  	if (lla == 0) {
Index: net/if_atmsubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_atmsubr.c,v
retrieving revision 1.18
diff -c -r1.18 if_atmsubr.c
*** if_atmsubr.c	1998/07/05 22:48:07	1.18
--- if_atmsubr.c	1999/05/12 00:45:21
***************
*** 307,312 ****
--- 307,315 ----
  	ifp->if_hdrlen = 0;
  	ifp->if_mtu = ATMMTU;
  	ifp->if_output = atm_output;
+ #if 0 /* XXX XXX XXX */
+ 	ifp->if_input = atm_input;
+ #endif
  
  #if defined(__NetBSD__) || defined(__OpenBSD__)
  	for (ifa = ifp->if_addrlist.tqh_first; ifa != 0;
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_ethersubr.c,v
retrieving revision 1.41
diff -c -r1.41 if_ethersubr.c
*** if_ethersubr.c	1999/03/10 21:05:08	1.41
--- if_ethersubr.c	1999/05/12 00:45:21
***************
*** 433,450 ****
  
  /*
   * Process a received Ethernet packet;
!  * the packet is in the mbuf chain m without
!  * the ether header, which is provided separately.
   */
  void
! ether_input(ifp, eh, m)
  	struct ifnet *ifp;
- 	struct ether_header *eh;
  	struct mbuf *m;
  {
  	struct ifqueue *inq;
  	u_int16_t etype;
  	int s;
  #if defined (ISO) || defined (LLC) || defined(NETATALK)
  	struct llc *l;
  #endif
--- 433,450 ----
  
  /*
   * Process a received Ethernet packet;
!  * the packet is in the mbuf chain m with
!  * the ether header.
   */
  void
! ether_input(ifp, m)
  	struct ifnet *ifp;
  	struct mbuf *m;
  {
  	struct ifqueue *inq;
  	u_int16_t etype;
  	int s;
+ 	struct ether_header *eh;
  #if defined (ISO) || defined (LLC) || defined(NETATALK)
  	struct llc *l;
  #endif
***************
*** 453,460 ****
  		m_freem(m);
  		return;
  	}
  	ifp->if_lastchange = time;
! 	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
  	if (eh->ether_dhost[0] & 1) {
  		if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
  		    sizeof(etherbroadcastaddr)) == 0)
--- 453,463 ----
  		m_freem(m);
  		return;
  	}
+ 
+ 	eh = mtod(m, struct ether_header *);
+ 
  	ifp->if_lastchange = time;
! 	ifp->if_ibytes += m->m_pkthdr.len;
  	if (eh->ether_dhost[0] & 1) {
  		if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
  		    sizeof(etherbroadcastaddr)) == 0)
***************
*** 466,471 ****
--- 469,478 ----
  		ifp->if_imcasts++;
  
  	etype = ntohs(eh->ether_type);
+ 
+ 	/* Strip off the Ethernet header. */
+ 	m_adj(m, sizeof(struct ether_header));
+ 
  	switch (etype) {
  #ifdef INET
  	case ETHERTYPE_IP:
***************
*** 694,699 ****
--- 701,707 ----
  	ifp->if_hdrlen = 14;
  	ifp->if_mtu = ETHERMTU;
  	ifp->if_output = ether_output;
+ 	ifp->if_input = ether_input;
  	if ((sdl = ifp->if_sadl) &&
  	    sdl->sdl_family == AF_LINK) {
  		sdl->sdl_type = IFT_ETHER;
Index: net/if_fddi.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_fddi.h,v
retrieving revision 1.6
diff -c -r1.6 if_fddi.h
*** if_fddi.h	1998/09/20 02:36:09	1.6
--- if_fddi.h	1999/05/12 00:45:21
***************
*** 92,98 ****
  #else
  void    fddi_ifattach __P((struct ifnet *));
  #endif
! void    fddi_input __P((struct ifnet *, struct fddi_header *, struct mbuf *));
  int     fddi_output __P((struct ifnet *,
             struct mbuf *, struct sockaddr *, struct rtentry *)); 
  
--- 92,98 ----
  #else
  void    fddi_ifattach __P((struct ifnet *));
  #endif
! void    fddi_input __P((struct ifnet *, struct mbuf *));
  int     fddi_output __P((struct ifnet *,
             struct mbuf *, struct sockaddr *, struct rtentry *)); 
  
Index: net/if_fddisubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_fddisubr.c,v
retrieving revision 1.25
diff -c -r1.25 if_fddisubr.c
*** if_fddisubr.c	1998/12/10 15:51:48	1.25
--- if_fddisubr.c	1999/05/12 00:45:21
***************
*** 532,556 ****
  
  /*
   * Process a received FDDI packet;
!  * the packet is in the mbuf chain m without
!  * the fddi header, which is provided separately.
   */
  void
! fddi_input(ifp, fh, m)
  	struct ifnet *ifp;
- 	register struct fddi_header *fh;
  	struct mbuf *m;
  {
  	register struct ifqueue *inq;
  	register struct llc *l;
  	int s;
  
  	if ((ifp->if_flags & IFF_UP) == 0) {
  		m_freem(m);
  		return;
  	}
  	ifp->if_lastchange = time;
! 	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*fh);
  	if (fh->fddi_dhost[0] & 1) {
  		if (bcmp((caddr_t)fddibroadcastaddr, (caddr_t)fh->fddi_dhost,
  		    sizeof(fddibroadcastaddr)) == 0)
--- 532,559 ----
  
  /*
   * Process a received FDDI packet;
!  * the packet is in the mbuf chain m with
!  * the fddi header.
   */
  void
! fddi_input(ifp, m)
  	struct ifnet *ifp;
  	struct mbuf *m;
  {
  	register struct ifqueue *inq;
  	register struct llc *l;
+ 	struct fddi_header *fh;
  	int s;
  
  	if ((ifp->if_flags & IFF_UP) == 0) {
  		m_freem(m);
  		return;
  	}
+ 
+ 	fh = mtod(m, struct fddi_header *);
+ 
  	ifp->if_lastchange = time;
! 	ifp->if_ibytes += m->m_pkthdr.len;
  	if (fh->fddi_dhost[0] & 1) {
  		if (bcmp((caddr_t)fddibroadcastaddr, (caddr_t)fh->fddi_dhost,
  		    sizeof(fddibroadcastaddr)) == 0)
***************
*** 575,580 ****
--- 578,586 ----
  		m->m_flags |= M_LINK0;
  #endif
  
+ 	/* Strip off the FDDI header. */
+ 	m_adj(m, sizeof(struct fddi_header));
+ 
  	l = mtod(m, struct llc *);
  	switch (l->llc_dsap) {
  #if defined(INET) || defined(NS) || defined(DECNET) || defined(IPX) || defined(NETATALK)
***************
*** 784,789 ****
--- 790,797 ----
  	ifp->if_addrlen = 6;
  	ifp->if_hdrlen = 21;
  	ifp->if_mtu = FDDIMTU;
+ 	ifp->if_output = fddi_output;
+ 	ifp->if_input = fddi_input;
  	ifp->if_baudrate = 100000000;
  #ifdef IFF_NOTRAILERS
  	ifp->if_flags |= IFF_NOTRAILERS;
Index: net/if_hippi.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_hippi.h,v
retrieving revision 1.4
diff -c -r1.4 if_hippi.h
*** if_hippi.h	1998/05/29 13:37:39	1.4
--- if_hippi.h	1999/05/12 00:45:21
***************
*** 82,89 ****
  
  #ifdef _KERNEL
  void    hippi_ifattach __P((struct ifnet *, caddr_t));
! void    hippi_input __P((struct ifnet *, struct hippi_header *, 
! 			 struct mbuf *));
  void    hippi_ip_input __P((struct ifnet *, struct mbuf *));
  int     hippi_output __P((struct ifnet *,
  		  struct mbuf *, struct sockaddr *, struct rtentry *)); 
--- 82,88 ----
  
  #ifdef _KERNEL
  void    hippi_ifattach __P((struct ifnet *, caddr_t));
! void    hippi_input __P((struct ifnet *, struct mbuf *));
  void    hippi_ip_input __P((struct ifnet *, struct mbuf *));
  int     hippi_output __P((struct ifnet *,
  		  struct mbuf *, struct sockaddr *, struct rtentry *)); 
Index: net/if_hippisubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_hippisubr.c,v
retrieving revision 1.2
diff -c -r1.2 if_hippisubr.c
*** if_hippisubr.c	1998/07/05 00:51:26	1.2
--- if_hippisubr.c	1999/05/12 00:45:21
***************
*** 226,244 ****
  
  /*
   * Process a received HIPPI packet;
!  * the packet is in the mbuf chain m without
!  * the HIPPI header, which is provided separately.
   */
  
  void
! hippi_input(ifp, hh, m)
  	struct ifnet *ifp;
- 	struct hippi_header *hh;
  	struct mbuf *m;
  {
  	register struct ifqueue *inq;
  	register struct llc *l;
  	u_int16_t htype;
  	int s;
  
  	if ((ifp->if_flags & IFF_UP) == 0) {
--- 226,244 ----
  
  /*
   * Process a received HIPPI packet;
!  * the packet is in the mbuf chain m with
!  * the HIPPI header.
   */
  
  void
! hippi_input(ifp, m)
  	struct ifnet *ifp;
  	struct mbuf *m;
  {
  	register struct ifqueue *inq;
  	register struct llc *l;
  	u_int16_t htype;
+ 	struct hippi_header *hh;
  	int s;
  
  	if ((ifp->if_flags & IFF_UP) == 0) {
***************
*** 249,255 ****
  	/* XXX:  need to check flags and drop if bogus! */
  
  	ifp->if_lastchange = time;
! 	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*hh);
  	if (hh->hi_le.le_dest_addr[0] & 1) {
  		if (bcmp((caddr_t)etherbroadcastaddr, 
  			 (caddr_t)hh->hi_le.le_dest_addr,
--- 249,255 ----
  	/* XXX:  need to check flags and drop if bogus! */
  
  	ifp->if_lastchange = time;
! 	ifp->if_ibytes += m->m_pkthdr.len;
  	if (hh->hi_le.le_dest_addr[0] & 1) {
  		if (bcmp((caddr_t)etherbroadcastaddr, 
  			 (caddr_t)hh->hi_le.le_dest_addr,
***************
*** 261,266 ****
--- 261,271 ----
  	if (m->m_flags & (M_BCAST|M_MCAST))
  		ifp->if_imcasts++;
  
+ 	hh = mtod(m, struct hippi_header *);
+ 
+ 	/* Skip past the HIPPI header. */
+ 	m_adj(m, sizeof(struct hippi_header));
+ 
  	l = mtod(m, struct llc *);
  	if (l->llc_dsap != LLC_SNAP_LSAP) {
  		m_freem(m);
***************
*** 335,340 ****
--- 340,346 ----
  	ifp->if_hdrlen = sizeof(struct hippi_header) + 8; /* add CCI */
  	ifp->if_mtu = HIPPIMTU;
  	ifp->if_output = hippi_output;
+ 	ifp->if_input = hippi_input;
  	if ((sdl = ifp->if_sadl) &&
  	    sdl->sdl_family == AF_LINK) {
  		sdl->sdl_type = IFT_HIPPI;
Index: net/if_token.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_token.h,v
retrieving revision 1.3
diff -c -r1.3 if_token.h
*** if_token.h	1999/04/08 15:53:31	1.3
--- if_token.h	1999/05/12 00:45:21
***************
*** 116,122 ****
  #define	token_sprintf		ether_sprintf
  
  void    token_ifattach __P((struct ifnet *, caddr_t));
! void    token_input __P((struct ifnet *, struct token_header *, struct mbuf *));
  int     token_output __P((struct ifnet *,
             struct mbuf *, struct sockaddr *, struct rtentry *)); 
  
--- 116,122 ----
  #define	token_sprintf		ether_sprintf
  
  void    token_ifattach __P((struct ifnet *, caddr_t));
! void    token_input __P((struct ifnet *, struct mbuf *));
  int     token_output __P((struct ifnet *,
             struct mbuf *, struct sockaddr *, struct rtentry *)); 
  
Index: net/if_tokensubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_tokensubr.c,v
retrieving revision 1.4
diff -c -r1.4 if_tokensubr.c
*** if_tokensubr.c	1999/04/08 15:53:31	1.4
--- if_tokensubr.c	1999/05/12 00:45:22
***************
*** 463,490 ****
  
  /*
   * Process a received token ring packet;
!  * the packet is in the mbuf chain m without
!  * the token ring header, which is provided separately.
   */
  void
! token_input(ifp, trh, m)
  	struct ifnet *ifp;
- 	register struct token_header *trh;
  	struct mbuf *m;
  {
  	register struct ifqueue *inq;
  	register struct llc *l;
! 	int s;
  
  	if ((ifp->if_flags & IFF_UP) == 0) {
  		m_freem(m);
  		return;
  	}
  	ifp->if_lastchange = time;
! /*
!  * XXX (m->m_data - (char *) trh) assumes trh is in the same buf
!  */
! 	ifp->if_ibytes += m->m_pkthdr.len + (m->m_data - (char *) trh);
  	if (bcmp((caddr_t)tokenbroadcastaddr, (caddr_t)trh->token_dhost,
  	    sizeof(tokenbroadcastaddr)) == 0)
  		m->m_flags |= M_BCAST;
--- 463,487 ----
  
  /*
   * Process a received token ring packet;
!  * the packet is in the mbuf chain m with
!  * the token ring header.
   */
  void
! token_input(ifp, m)
  	struct ifnet *ifp;
  	struct mbuf *m;
  {
  	register struct ifqueue *inq;
  	register struct llc *l;
! 	struct token_header *trh;
! 	int s, lan_hdr_len;
  
  	if ((ifp->if_flags & IFF_UP) == 0) {
  		m_freem(m);
  		return;
  	}
  	ifp->if_lastchange = time;
! 	ifp->if_ibytes += m->m_pkthdr.len;
  	if (bcmp((caddr_t)tokenbroadcastaddr, (caddr_t)trh->token_dhost,
  	    sizeof(tokenbroadcastaddr)) == 0)
  		m->m_flags |= M_BCAST;
***************
*** 493,498 ****
--- 490,507 ----
  	if (m->m_flags & (M_BCAST|M_MCAST))
  		ifp->if_imcasts++;
  
+ 	trh = mtod(m, struct token_header *);
+ 
+ 	/* Skip past the Token Ring header and RIF. */
+ 	lan_hdr_len = sizeof(struct token_header);
+ 	if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
+ 		struct token_rif *trrif;
+ 
+ 		trrif = TOKEN_RIF(trh);
+ 		lan_hdr_len += (ntohs(trrif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
+ 	}
+ 	m_adj(m, lan_hdr_len);
+ 
  	l = mtod(m, struct llc *);
  	switch (l->llc_dsap) {
  #if defined(INET) || defined(NS) || defined(DECNET)
***************
*** 668,673 ****
--- 677,683 ----
  	ifp->if_hdrlen = 14;
  	ifp->if_mtu = ISO88025_MTU;
  	ifp->if_output = token_output;
+ 	ifp->if_input = token_input;
  	ifp->if_broadcastaddr = tokenbroadcastaddr;
  #ifdef IFF_NOTRAILERS
  	ifp->if_flags |= IFF_NOTRAILERS;