Hoist a bunch of stuff that should be done by all if_print routines into
tcpdump.c.  Have if_print routines return the length of the link-layer
header, so that the common code knows how to skip the link-layer header
when printing the packet in hex/ASCII.
diff --git a/interface.h b/interface.h
index b42dac2..647403d 100644
--- a/interface.h
+++ b/interface.h
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.202 2002-12-18 09:41:13 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.203 2002-12-19 09:39:10 guy Exp $ (LBL)
  */
 
 #ifndef tcpdump_interface_h
@@ -164,10 +164,6 @@
 
 extern const char *dnaddr_string(u_short);
 
-extern void info(int);
-extern int infodelay;
-extern int infoprint;
-
 extern void error(const char *, ...)
     __attribute__((noreturn, format (printf, 1, 2)));
 extern void warning(const char *, ...) __attribute__ ((format (printf, 1, 2)));
@@ -189,7 +185,7 @@
 
 #include <pcap.h>
 
-extern int print_unknown_data(const u_char *,const char *,int);
+extern int print_unknown_data(const u_char *, const char *,int);
 extern void ascii_print_with_offset(const u_char *, u_int, u_int);
 extern void ascii_print(const u_char *, u_int);
 extern void hex_print_with_offset(const u_char *, u_int, u_int);
@@ -204,8 +200,8 @@
 extern void arp_print(const u_char *, u_int, u_int);
 extern void atalk_print(const u_char *, u_int);
 extern void atm_print(u_int, u_int, u_int, const u_char *, u_int, u_int);
-extern void atm_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
-extern void sunatm_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern u_int atm_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int sunatm_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void bootp_print(const u_char *, u_short, u_short, u_int);
 extern void bgp_print(const u_char *, int);
 extern void beep_print(const u_char *, u_int);
@@ -213,25 +209,20 @@
 extern void decnet_print(const u_char *, u_int, u_int);
 extern void default_print(const u_char *, u_int);
 extern void default_print_unaligned(const u_char *, u_int);
-extern void default_print_packet(const u_char *, u_int, u_int);
 extern void dvmrp_print(const u_char *, u_int);
 extern void egp_print(const u_char *);
-extern void pflog_if_print(u_char *, const struct pcap_pkthdr *,
-        const u_char *);
-extern void arcnet_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
+extern u_int pflog_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int arcnet_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void ether_print(const u_char *, u_int, u_int);
-extern void ether_if_print(u_char *, const struct pcap_pkthdr *,
+extern u_int ether_if_print(const struct pcap_pkthdr *,
 	const u_char *);
 extern u_int token_print(const u_char *, u_int, u_int);
-extern void token_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
+extern u_int token_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void fddi_print(const u_char *, u_int, u_int);
-extern void fddi_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
-extern void fr_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
-extern void ieee802_11_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
-extern void ieee802_11_radio_if_print(u_char *, const struct pcap_pkthdr *,
+extern u_int fddi_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int fr_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ieee802_11_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ieee802_11_radio_if_print(const struct pcap_pkthdr *,
 	const u_char *);
 extern void gre_print(const u_char *, u_int);
 extern void icmp_print(const u_char *, u_int, const u_char *);
@@ -239,20 +230,19 @@
 extern void igrp_print(const u_char *, u_int, const u_char *);
 extern void ip_print(const u_char *, u_int);
 extern void ipN_print(const u_char *, u_int);
-extern void ipfc_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern u_int ipfc_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void ipx_print(const u_char *, u_int);
 extern void isoclns_print(const u_char *, u_int, u_int, const u_char *,
 	const u_char *);
 extern void krb_print(const u_char *);
-extern void llap_print(const u_char *, u_int);
-extern void ltalk_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
+extern u_int llap_print(const u_char *, u_int);
+extern u_int ltalk_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void msdp_print(const unsigned char *, u_int);
 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);
 extern void ntp_print(const u_char *, u_int);
-extern void null_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern u_int null_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void ospf_print(const u_char *, u_int, const u_char *);
 extern void pimv1_print(const u_char *, u_int);
 extern void cisco_autorp_print(const u_char *, u_int);
@@ -262,28 +252,21 @@
 extern void pim_print(const u_char *, u_int);
 extern u_int pppoe_print(const u_char *, u_int);
 extern u_int ppp_print(register const u_char *, u_int);
-extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
-extern void ppp_hdlc_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
-extern void ppp_bsdos_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
-extern void pppoe_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
-extern void prism_if_print(u_char *, const struct pcap_pkthdr *,
-	const u_char *);
+extern u_int ppp_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ppp_hdlc_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ppp_bsdos_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int pppoe_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int prism_if_print(const struct pcap_pkthdr *, const u_char *);
 extern int vjc_print(register const char *, u_short);
-extern void raw_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern u_int raw_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void rip_print(const u_char *, u_int);
-extern void sl_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern u_int sl_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void lane_print(const u_char *, u_int, u_int);
-extern void lane_if_print(u_char *, const struct pcap_pkthdr *,const u_char *);
-extern void cip_if_print(u_char *, const struct pcap_pkthdr *,const u_char *);
-extern void sl_bsdos_if_print(u_char *, const struct pcap_pkthdr *,
-    const u_char *);
-extern void chdlc_if_print(u_char *, const struct pcap_pkthdr *,
-    const u_char *);
-extern void chdlc_print(register const u_char *, u_int, u_int);
-extern void sll_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
+extern u_int lane_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int cip_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int sl_bsdos_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int chdlc_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int sll_if_print(const struct pcap_pkthdr *, const u_char *);
 extern void snmp_print(const u_char *, u_int);
 extern void sunrpcrequest_print(const u_char *, u_int, const u_char *);
 extern void tcp_print(const u_char *, u_int, const u_char *, int);
@@ -336,13 +319,3 @@
 
 extern void bpf_dump(struct bpf_program *, int);
 #endif
-
-
-
-
-
-
-
-
-
-
diff --git a/print-802_11.c b/print-802_11.c
index b54b27f..73b52b9 100644
--- a/print-802_11.c
+++ b/print-802_11.c
@@ -22,7 +22,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.18 2002-12-18 09:41:14 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.19 2002-12-19 09:39:10 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -795,19 +795,17 @@
 	}
 }
 
-static void
+static u_int
 ieee802_11_print(const u_char *p, u_int length, u_int caplen)
 {
 	u_int16_t fc;
 	u_int HEADER_LENGTH;
-	const u_char *orig_p;
-	u_int orig_caplen;
 	const u_int8_t *src, *dst;
 	u_short extracted_ethertype;
 
 	if (caplen < IEEE802_11_FC_LEN) {
 		printf("[|802.11]");
-		return;
+		return caplen;
 	}
 
 	fc = EXTRACT_LE_16BITS(p);
@@ -815,26 +813,12 @@
 
 	if (caplen < HEADER_LENGTH) {
 		printf("[|802.11]");
-		return;
+		return HEADER_LENGTH;
 	}
 
 	ieee_802_11_hdr_print(fc, p, &src, &dst);
 
 	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	/*
-	 * Save the information for the full packet, so we can print
-	 * everything if "-e" and "-x" are both specified.
-	 */
-	orig_p = p;
-	orig_caplen = caplen;
-
-	/*
 	 * Go past the 802.11 header.
 	 */
 	length -= HEADER_LENGTH;
@@ -846,14 +830,14 @@
 		if (!mgmt_body_print(fc,
 		    (const struct mgmt_header_t *)(p - HEADER_LENGTH), p)) {
 			printf("[|802.11]");
-			return;
+			return HEADER_LENGTH;
 		}
 		break;
 
 	case T_CTRL:
 		if (!ctrl_body_print(fc, p - HEADER_LENGTH)) {
 			printf("[|802.11]");
-			return;
+			return HEADER_LENGTH;
 		}
 		break;
 
@@ -862,7 +846,7 @@
 		if (FC_WEP(fc)) {
 			if (!wep_print(p)) {
 				printf("[|802.11]");
-				return;
+				return HEADER_LENGTH;
 			}
 		} else {
 			if (llc_print(p, length, caplen, dst, src,
@@ -890,8 +874,7 @@
 		break;
 	}
 
-	if (xflag)
-		default_print_packet(orig_p, orig_caplen, HEADER_LENGTH);
+	return HEADER_LENGTH;
 }
 
 /*
@@ -900,24 +883,13 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-ieee802_11_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
-	u_int caplen = h->caplen;
-	u_int length = h->len;
-
-	++infodelay;
-	ts_print(&h->ts);
-
-	ieee802_11_print(p, length, caplen);
-
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return ieee802_11_print(p, h->len, h->caplen);
 }
 
-static void
+static u_int
 ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
 {
 	u_int32_t caphdr_len;
@@ -930,16 +902,16 @@
 		 * cookie or capture header length!
 		 */
 		printf("[|802.11]");
-		return;
+		return caplen;
 	}
 
 	if (caplen < caphdr_len) {
 		printf("[|802.11]");
-		return;
+		return caplen;
 	}
 
-	ieee802_11_print(p + caphdr_len, length - caphdr_len,
-	    caplen - caphdr_len);
+	return caphdr_len + ieee802_11_print(p + caphdr_len,
+	    length - caphdr_len, caplen - caphdr_len);
 }
 
 #define PRISM_HDR_LEN		144
@@ -958,39 +930,30 @@
  * ARPHRD_IEEE80211_PRISM is used for DLT_IEEE802_11_RADIO, and
  * the first 4 bytes of the header are used to indicate which it is).
  */
-void
-prism_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int caplen = h->caplen;
 	u_int length = h->len;
 	u_int32_t msgcode;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < 4) {
 		printf("[|802.11]");
-		goto out;
+		return caplen;
 	}
 
 	msgcode = EXTRACT_32BITS(p);
 	if (msgcode == WLANCAP_MAGIC_COOKIE_V1)
-		ieee802_11_radio_print(p, length, caplen);
+		return ieee802_11_radio_print(p, length, caplen);
 	else {
 		if (caplen < PRISM_HDR_LEN) {
 			printf("[|802.11]");
-			goto out;
+			return caplen;
 		}
 
-		ieee802_11_print(p + PRISM_HDR_LEN, length - PRISM_HDR_LEN,
-		    caplen - PRISM_HDR_LEN);
+		return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
+		    length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN);
 	}
-
-out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
 }
 
 /*
@@ -998,26 +961,16 @@
  * header, containing information such as radio information, which we
  * currently ignore.
  */
-void
-ieee802_11_radio_if_print(u_char *user _U_, const struct pcap_pkthdr *h,
-    const u_char *p)
+u_int
+ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int caplen = h->caplen;
 	u_int length = h->len;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < 8) {
 		printf("[|802.11]");
-		goto out;
+		return caplen;
 	}
 
-	ieee802_11_radio_print(p, length, caplen);
-
-out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return ieee802_11_radio_print(p, length, caplen);
 }
diff --git a/print-arcnet.c b/print-arcnet.c
index 7f1db3e..50d7bf8 100644
--- a/print-arcnet.c
+++ b/print-arcnet.c
@@ -22,7 +22,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.12 2002-12-18 09:41:14 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.13 2002-12-19 09:39:10 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -106,25 +106,20 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-arcnet_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int caplen = h->caplen;
 	u_int length = h->len;
-	const u_char *orig_p;
-	u_int orig_caplen;
 	const struct arc_header *ap;
 
 	int phds, flag = 0, archdrlen = 0;
 	u_int seqid = 0;
 	u_char arc_type;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < ARC_HDRLEN) {
 		printf("[|arcnet]");
-		goto out;
+		return (caplen);
 	}
 
 	ap = (const struct arc_header *)p;
@@ -146,14 +141,14 @@
 		if (caplen < ARC_HDRNEWLEN) {
 			arcnet_print(p, length, 0, 0, 0);
 			printf("[|phds]");
-			goto out;
+			return (caplen);
 		}
 
 		if (ap->arc_flag == 0xff) {
 			if (caplen < ARC_HDRNEWLEN_EXC) {
 				arcnet_print(p, length, 0, 0, 0);
 				printf("[|phds extended]");
-				goto out;
+				return (caplen);
 			}
 			flag = ap->arc_flag2;
 			seqid = ap->arc_seqid2;
@@ -170,20 +165,6 @@
 		arcnet_print(p, length, phds, flag, seqid);
 
 	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	/*
-	 * Save the information for the full packet, so we can print
-	 * everything if "-e" and "-x" are both specified.
-	 */
-	orig_p = p;
-	orig_caplen = caplen;
-
-	/*
 	 * Go past the ARCNET header.
 	 */
 	length -= archdrlen;
@@ -191,22 +172,12 @@
 	p += archdrlen;
 
 	if (phds && flag && (flag & 1) == 0)
-		goto out2;
+		return (archdrlen);
 
-	if (!arcnet_encap_print(arc_type, p, length, caplen)) {
+	if (!arcnet_encap_print(arc_type, p, length, caplen))
 		default_print(p, caplen);
-		goto out;
-	}
 
- out2:
-	if (xflag)
-		default_print_packet(orig_p, orig_caplen, archdrlen);
-
- out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (archdrlen);
 }
 
 /*
diff --git a/print-atalk.c b/print-atalk.c
index e415f9a..b497065 100644
--- a/print-atalk.c
+++ b/print-atalk.c
@@ -23,7 +23,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.77 2002-12-11 07:13:57 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.78 2002-12-19 09:39:11 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -81,31 +81,23 @@
 /*
  * Print LLAP packets received on a physical LocalTalk interface.
  */
-void
-ltalk_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+ltalk_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
-	snapend = p + h->caplen;
-	++infodelay;
-	ts_print(&h->ts);
-	llap_print(p, h->caplen);
-	if(xflag)
-		default_print(p, h->caplen);
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (llap_print(p, h->caplen));
 }
 
 /*
  * Print AppleTalk LLAP packets.
  */
-void
+u_int
 llap_print(register const u_char *bp, u_int length)
 {
 	register const struct LAP *lp;
 	register const struct atDDP *dp;
 	register const struct atShortDDP *sdp;
 	u_short snet;
+	u_int hdrlen;
 
 	/*
 	 * Our packet is on a 4-byte boundary, as we're either called
@@ -118,12 +110,13 @@
 	lp = (const struct LAP *)bp;
 	bp += sizeof(*lp);
 	length -= sizeof(*lp);
+	hdrlen = sizeof(*lp);
 	switch (lp->type) {
 
 	case lapShortDDP:
 		if (length < ddpSSize) {
 			(void)printf(" [|sddp %d]", length);
-			return;
+			return (length);
 		}
 		sdp = (const struct atShortDDP *)bp;
 		printf("%s.%s",
@@ -132,13 +125,14 @@
 		    ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt));
 		bp += ddpSSize;
 		length -= ddpSSize;
+		hdrlen += ddpSSize;
 		ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
 		break;
 
 	case lapDDP:
 		if (length < ddpSize) {
 			(void)printf(" [|ddp %d]", length);
-			return;
+			return (length);
 		}
 		dp = (const struct atDDP *)bp;
 		snet = EXTRACT_16BITS(&dp->srcNet);
@@ -149,6 +143,7 @@
 		    ddpskt_string(dp->dstSkt));
 		bp += ddpSize;
 		length -= ddpSize;
+		hdrlen += ddpSize;
 		ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
 		break;
 
@@ -163,6 +158,7 @@
 		    lp->src, lp->dst, lp->type, length);
 		break;
 	}
+	return (hdrlen);
 }
 
 /*
diff --git a/print-atm.c b/print-atm.c
index 5b41cc7..f797872 100644
--- a/print-atm.c
+++ b/print-atm.c
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.32 2002-12-18 09:41:14 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.33 2002-12-19 09:39:11 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -75,29 +75,20 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-atm_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+atm_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int caplen = h->caplen;
 	u_int length = h->len;
 	u_int32_t llchdr;
-
-	++infodelay;
-	ts_print(&h->ts);
+	u_int hdrlen = 0;
 
 	if (caplen < 8) {
 		printf("[|atm]");
-		goto out;
+		return (caplen);
 	}
 
 	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	/*
 	 * Extract the presumed LLC header into a variable, for quick
 	 * testing.
 	 * Then check for a header that's neither a header for a SNAP
@@ -133,15 +124,10 @@
 		p += 20;
 		length -= 20;
 		caplen -= 20;
+		hdrlen += 20;
 	}
 	atm_llc_print(p, length, caplen);
-	if (xflag)
-		default_print(p, caplen);
- out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (hdrlen);
 }
 
 /*
@@ -210,40 +196,33 @@
 	if (eflag)
 		printf("VPI:%u VCI:%u ", vpi, vci);
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	if (vpi == 0) {
 		switch (vci) {
 
 		case PPC:
 			sig_print(p, caplen);
-			goto out;
+			return;
 
 		case BCC:
 			printf("broadcast sig: ");
-			goto out;
+			return;
 
 		case OAMF4SC:
 			printf("oamF4(segment): ");
-			goto out;
+			return;
 
 		case OAMF4EC:
 			printf("oamF4(end): ");
-			goto out;
+			return;
 
 		case METAC:
 			printf("meta: ");
-			goto out;
+			return;
 
 		case ILMIC:
 			printf("ilmi: ");
 			snmp_print(p, length);
-			goto out;
+			return;
 		}
 	}
 
@@ -261,8 +240,4 @@
 		lane_print(p, length, caplen);
 		break;
 	}
-
-out:
-	if (xflag)
-		default_print(p, caplen);
 }
diff --git a/print-chdlc.c b/print-chdlc.c
index 5bd4bdb..14d325a 100644
--- a/print-chdlc.c
+++ b/print-chdlc.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.26 2002-12-18 09:41:15 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.27 2002-12-19 09:39:11 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -43,40 +43,17 @@
 static void chdlc_slarp_print(const u_char *, u_int);
 
 /* Standard CHDLC printer */
-void
-chdlc_if_print(u_char *user _U_, const struct pcap_pkthdr *h,
-	     register const u_char *p)
+u_int
+chdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
 	register u_int length = h->len;
 	register u_int caplen = h->caplen;
-
-	++infodelay;
-	ts_print(&h->ts);
-
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	chdlc_print(p, length, caplen);
-
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
-}
-
-void
-chdlc_print(register const u_char *p, u_int length, u_int caplen)
-{
 	const struct ip *ip;
 	u_int proto;
 
 	if (caplen < CHDLC_HDRLEN) {
 		printf("[|chdlc]");
-		return;
+		return (caplen);
 	}
 
 	proto = EXTRACT_16BITS(&p[2]);
@@ -131,8 +108,8 @@
                 printf("unknown CHDLC protocol (0x%04x)", proto);
                 break;
 	}
-	if (xflag)
-		default_print_packet(p, caplen, CHDLC_HDRLEN);
+
+	return (CHDLC_HDRLEN);
 }
 
 struct cisco_slarp {
diff --git a/print-cip.c b/print-cip.c
index 2798698..9e656a1 100644
--- a/print-cip.c
+++ b/print-cip.c
@@ -22,7 +22,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.20 2002-12-18 08:53:20 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.21 2002-12-19 09:39:12 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -66,31 +66,21 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-cip_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+cip_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int caplen = h->caplen;
 	u_int length = h->len;
 	u_short extracted_ethertype;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
 		printf("[|cip]");
-		goto out;
+		return (0);
 	}
 
 	if (eflag)
 		cip_print(length);
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) {
 		/*
 		 * LLC header is present.  Try to print it & higher layers.
@@ -114,11 +104,5 @@
 		ip_print(p, length);
 	}
 
-	if (xflag)
-		default_print(p, caplen);
- out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (0);
 }
diff --git a/print-ether.c b/print-ether.c
index fdd7964..2826c7b 100644
--- a/print-ether.c
+++ b/print-ether.c
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.75 2002-12-18 09:41:15 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.76 2002-12-19 09:39:12 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -74,13 +74,6 @@
 	if (eflag)
 		ether_hdr_print(p, length);
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	length -= ETHER_HDRLEN;
 	caplen -= ETHER_HDRLEN;
 	ep = (struct ether_header *)p;
@@ -122,28 +115,12 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-ether_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+ether_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
-	u_int caplen = h->caplen;
-	u_int length = h->len;
+	ether_print(p, h->len, h->caplen);
 
-	++infodelay;
-	ts_print(&h->ts);
-
-	ether_print(p, length, caplen);
-
-	/*
-	 * If "-x" was specified, print packet data in hex.
-	 */
-	if (xflag)
-		default_print_packet(p, caplen, ETHER_HDRLEN);
-
-	putchar('\n');
-
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (ETHER_HDRLEN);
 }
 
 /*
diff --git a/print-fddi.c b/print-fddi.c
index 0bd439a..315eb33 100644
--- a/print-fddi.c
+++ b/print-fddi.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.60 2002-12-18 09:41:15 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.61 2002-12-19 09:39:12 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -255,13 +255,6 @@
 	 */
 	extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	if (eflag)
 		fddi_hdr_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
 
@@ -308,27 +301,10 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-fddi_if_print(u_char *pcap _U_, const struct pcap_pkthdr *h,
-	      register const u_char *p)
+u_int
+fddi_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
-	u_int caplen = h->caplen;
-	u_int length = h->len;
+	fddi_print(p, h->len, h->caplen);
 
-	++infodelay;
-	ts_print(&h->ts);
-
-	fddi_print(p, length, caplen);
-
-	/*
-	 * If "-x" was specified, print packet data in hex.
-	 */
-	if (xflag)
-		default_print_packet(p, caplen, FDDI_HDRLEN);
-
-	putchar('\n');
-
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (FDDI_HDRLEN);
 }
diff --git a/print-fr.c b/print-fr.c
index 8c27fc2..03f2ce4 100644
--- a/print-fr.c
+++ b/print-fr.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-	"@(#)$Header: /tcpdump/master/tcpdump/print-fr.c,v 1.10 2002-12-18 09:41:16 guy Exp $ (LBL)";
+	"@(#)$Header: /tcpdump/master/tcpdump/print-fr.c,v 1.11 2002-12-19 09:39:12 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -211,44 +211,25 @@
 			     fr_protostring(proto), length);
 }
 
-void
-fr_if_print(u_char *user _U_, const struct pcap_pkthdr *h,
-	     register const u_char *p)
+u_int
+fr_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
 	register u_int length = h->len;
 	register u_int caplen = h->caplen;
-	const u_char *orig_p;
-	u_int orig_caplen;
 	u_char protocol;
 	int layer2_len;
 	u_short extracted_ethertype;
 	u_int32_t orgcode;
 	register u_short et;
 
-	ts_print(&h->ts);
-
 	if (caplen < fr_hdrlen(p)) {
 		printf("[|fr]");
-		goto out;
+		return (caplen);
 	}
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	if (eflag)
 		fr_hdr_print(p, length);
 
-	/*
-	 * Save the information for the full packet, so we can print
-	 * everything if "-e" and "-x" are both specified.
-	 */
-	orig_p = p;
-	orig_caplen = caplen;
-
 	protocol = FR_PROTOCOL(p);
 	layer2_len = LAYER2_LEN(p);
 	p += layer2_len;
@@ -296,10 +277,7 @@
 			default_print(p, caplen);
 	}
 
-	if (xflag)
-		default_print_packet(orig_p, orig_caplen, layer2_len);
-out:
-	putchar('\n');
+	return (layer2_len);
 }
 
 /*
diff --git a/print-ipfc.c b/print-ipfc.c
index 3da01d6..7c527e3 100644
--- a/print-ipfc.c
+++ b/print-ipfc.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.3 2002-12-18 09:41:16 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.4 2002-12-19 09:39:13 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -93,13 +93,6 @@
 	 */
 	extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	if (eflag)
 		ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
 
@@ -130,32 +123,15 @@
 }
 
 /*
- * This is the top level routine of the printer.  'sp' is the points
- * to the Network_Header of the packet, 'tvp' is the timestamp,
- * 'length' is the length of the packet off the wire, and 'caplen'
+ * This is the top level routine of the printer.  'p' points
+ * to the Network_Header of the packet, 'h->ts' is the timestamp,
+ * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-ipfc_if_print(u_char *pcap _U_, const struct pcap_pkthdr *h,
-	      register const u_char *p)
+u_int
+ipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
-	u_int caplen = h->caplen;
-	u_int length = h->len;
+	ipfc_print(p, h->len, h->caplen);
 
-	++infodelay;
-	ts_print(&h->ts);
-
-	ipfc_print(p, length, caplen);
-
-	/*
-	 * If "-x" was specified, print packet data in hex.
-	 */
-	if (xflag)
-		default_print_packet(p, caplen, IPFC_HDRLEN);
-
-	putchar('\n');
-
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (IPFC_HDRLEN);
 }
diff --git a/print-lane.c b/print-lane.c
index c727b9f..3a21c14 100644
--- a/print-lane.c
+++ b/print-lane.c
@@ -22,7 +22,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-lane.c,v 1.19 2002-12-18 09:41:16 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-lane.c,v 1.20 2002-12-19 09:39:13 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -122,13 +122,6 @@
 		lane_hdr_print(p, length);
 
 	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	/*
 	 * Go past the LANE header.
 	 */
 	length -= sizeof(struct lecdatahdr_8023);
@@ -166,26 +159,10 @@
 	}
 }
 
-void
-lane_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+lane_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
-	int caplen = h->caplen;
-	int length = h->len;
+	lane_print(p, h->len, h->caplen);
 
-	++infodelay;
-	ts_print(&h->ts);
-
-	lane_print(p, length, caplen);
-
-	/*
-	 * If "-x" was specified, print packet data in hex.
-	 */
-	if (xflag)
-		default_print_packet(p, caplen,
-		    sizeof(struct lecdatahdr_8023));
-
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (sizeof(struct lecdatahdr_8023));
 }
diff --git a/print-null.c b/print-null.c
index 064408a..6b7ffe7 100644
--- a/print-null.c
+++ b/print-null.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.46 2002-12-18 09:41:16 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.47 2002-12-19 09:39:13 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -96,17 +96,13 @@
 #define	SWAPLONG(y) \
 ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
 
-void
-null_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+null_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int length = h->len;
-	u_int caplen = h->caplen;
 	const struct ip *ip;
 	u_int family;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	memcpy((char *)&family, (char *)p, sizeof(family));
 
 	/*
@@ -120,13 +116,6 @@
 	if ((family & 0xFFFF0000) != 0)
 		family = SWAPLONG(family);
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	length -= NULL_HDRLEN;
 
 	ip = (struct ip *)(p + NULL_HDRLEN);
@@ -148,11 +137,6 @@
 		break;
 	}
 
-	if (xflag)
-		default_print_packet(p, caplen, NULL_HDRLEN);
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (NULL_HDRLEN);
 }
 
diff --git a/print-pflog.c b/print-pflog.c
index 61d5dc9..d0ac305 100644
--- a/print-pflog.c
+++ b/print-pflog.c
@@ -23,7 +23,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-pflog.c,v 1.6 2002-12-18 09:41:17 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-pflog.c,v 1.7 2002-12-19 09:39:14 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -96,38 +96,19 @@
 	    hdr->ifname);
 }
 
-void
-pflog_if_print(u_char *user _U_, const struct pcap_pkthdr *h,
-     register const u_char *p)
+u_int
+pflog_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
 	u_int length = h->len;
 	u_int caplen = h->caplen;
-	const u_char *orig_p;
-	u_int orig_caplen;
 	const struct pfloghdr *hdr;
 	u_int8_t af;
 
-	ts_print(&h->ts);
-
 	if (caplen < PFLOG_HDRLEN) {
 		printf("[|pflog]");
-		goto out;
+		return (caplen);
 	}
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	/*
-	 * Save the information for the full packet, so we can print
-	 * everything if "-e" and "-x" are both specified.
-	 */
-	orig_p = p;
-	orig_caplen = caplen;
-
 	hdr = (const struct pfloghdr *)p;
 	if (eflag)
 		pflog_print(hdr);
@@ -155,11 +136,5 @@
 			default_print(p, caplen);
 	}
 
-	if (xflag)
-		default_print_packet(orig_p, orig_caplen, PFLOG_HDRLEN);
-out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (PFLOG_HDRLEN);
 }
diff --git a/print-ppp.c b/print-ppp.c
index f7be51d..274e0e3 100644
--- a/print-ppp.c
+++ b/print-ppp.c
@@ -31,7 +31,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.79 2002-12-18 09:41:17 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.80 2002-12-19 09:39:14 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -1040,28 +1040,17 @@
 
 
 /* PPP I/F printer */
-void
-ppp_if_print(u_char *user _U_, const struct pcap_pkthdr *h,
-	     register const u_char *p)
+u_int
+ppp_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
 	register u_int length = h->len;
 	register u_int caplen = h->caplen;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < PPP_HDRLEN) {
 		printf("[|ppp]");
-		goto out;
+		return (caplen);
 	}
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 #if 0
 	/*
 	 * XXX: seems to assume that there are 2 octets prepended to an
@@ -1105,13 +1094,7 @@
 
 	ppp_print(p, length);
 
-	if (xflag)
-		default_print(p, caplen);
-out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (0);
 }
 
 /*
@@ -1123,54 +1106,37 @@
  *
  * This handles, for example, DLT_PPP_SERIAL in NetBSD.
  */
-void
-ppp_hdlc_if_print(u_char *user _U_, const struct pcap_pkthdr *h,
-	     register const u_char *p)
+u_int
+ppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
 	register u_int length = h->len;
 	register u_int caplen = h->caplen;
-	const u_char *orig_p;
-	u_int orig_caplen;
 	u_int proto;
-
-	++infodelay;
-	ts_print(&h->ts);
+	u_int hdrlen = 0;
 
 	if (caplen < 2) {
 		printf("[|ppp]");
-		goto out;
+		return (caplen);
 	}
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	/*
-	 * Save the information for the full packet, so we can print
-	 * everything if "-e" and "-x" are both specified.
-	 */
-	orig_p = p;
-	orig_caplen = caplen;
-
 	switch (p[0]) {
 
 	case PPP_ADDRESS:
 		if (caplen < 4) {
 			printf("[|ppp]");
-			goto out;
+			return (caplen);
 		}
 
 		if (eflag)
 			printf("%02x %02x %d ", p[0], p[1], length);
 		p += 2;
 		length -= 2;
+		hdrlen += 2;
 
 		proto = EXTRACT_16BITS(p);
 		p += 2;
 		length -= 2;
+		hdrlen += 2;
 		printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto));
 
 		handle_ppp(proto, p, length);
@@ -1178,14 +1144,14 @@
 
 	case CHDLC_UNICAST:
 	case CHDLC_BCAST:
-		chdlc_print(p, length, caplen);
-		goto out;
+		return (chdlc_if_print(h, p));
 
 	default:
 		if (eflag)
 			printf("%02x %02x %d ", p[0], p[1], length);
 		p += 2;
 		length -= 2;
+		hdrlen += 2;
 
 		/*
 		 * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
@@ -1196,53 +1162,30 @@
 		break;
 	}
 
-	if (xflag)
-		default_print_packet(orig_p, orig_caplen, p - orig_p);
-out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (hdrlen);
 }
 
 #define PPP_BSDI_HDRLEN 24
 
 /* BSD/OS specific PPP printer */
-void
-ppp_bsdos_if_print(u_char *user _U_, const struct pcap_pkthdr *h _U_,
-	     register const u_char *p _U_)
+u_int
+ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_)
 {
+	register int hdrlength;
 #ifdef __bsdi__
 	register u_int length = h->len;
 	register u_int caplen = h->caplen;
-	const u_char *orig_p;
-	register int hdrlength;
 	u_int16_t ptype;
 	const u_char *q;
 	int i;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < PPP_BSDI_HDRLEN) {
 		printf("[|ppp]");
-		goto out;
+		return (caplen)
 	}
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
 	hdrlength = 0;
 
-	/*
-	 * Save the information for the full packet, so we can print
-	 * everything if "-e" and "-x" are both specified.
-	 */
-	orig_p = p;
-
 #if 0
 	if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
 		if (eflag)
@@ -1376,12 +1319,8 @@
 	}
 
 printx:
-	if (xflag)
-		default_print_packet(orig_p, caplen, hdrlength);
-out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+#else /* __bsdi */
+	hdrlength = 0;
 #endif /* __bsdi__ */
+	return (hdrlength);
 }
diff --git a/print-pppoe.c b/print-pppoe.c
index d6bafcf..1b90828 100644
--- a/print-pppoe.c
+++ b/print-pppoe.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-"@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.20 2002-12-18 09:41:17 guy Exp $ (LBL)";
+"@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.21 2002-12-19 09:39:14 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -89,37 +89,10 @@
 
 #define PPPOE_HDRLEN 6
 
-void
-pppoe_if_print(u_char *user _U_, const struct pcap_pkthdr *h,
-	     register const u_char *p)
+u_int
+pppoe_if_print(const struct pcap_pkthdr *h, register const u_char *p)
 {
-	register u_int length = h->len;
-	register u_int caplen = h->caplen;
-	u_int hdr_len;
-
-	++infodelay;
-	ts_print(&h->ts);
-
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	hdr_len = pppoe_print(p, length);
-
-	/*
-	 * If "-x" was specified, print packet data in hex.
-	 */
-	if (xflag)
-		default_print_packet(p, caplen, hdr_len);
-
-	putchar('\n');
-
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (pppoe_print(p, h->len));
 }
 
 u_int
diff --git a/print-raw.c b/print-raw.c
index 88a276f..08cee76 100644
--- a/print-raw.c
+++ b/print-raw.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-raw.c,v 1.38 2002-12-18 08:53:23 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-raw.c,v 1.39 2002-12-19 09:39:15 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -41,31 +41,13 @@
  * The DLT_RAW packet has no header. It contains a raw IP packet.
  */
 
-void
-raw_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+raw_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
-	u_int length = h->len;
-	u_int caplen = h->caplen;
-
-	++infodelay;
-	ts_print(&h->ts);
-
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	if (eflag)
 		printf("ip: ");
 
-	ipN_print(p, length);
+	ipN_print(p, h->len);
 
-	if (xflag)
-		default_print(p, caplen);
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (0);
 }
diff --git a/print-sl.c b/print-sl.c
index fa6fa0f..e96c535 100644
--- a/print-sl.c
+++ b/print-sl.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.61 2002-12-18 09:41:17 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.62 2002-12-19 09:39:15 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -48,28 +48,18 @@
 static void sliplink_print(const u_char *, const struct ip *, u_int);
 static void compressed_sl_print(const u_char *, const struct ip *, u_int, int);
 
-void
-sl_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+sl_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	register u_int caplen = h->caplen;
 	register u_int length = h->len;
 	register const struct ip *ip;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < SLIP_HDRLEN) {
 		printf("[|slip]");
-		goto out;
+		return (caplen);
 	}
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	length -= SLIP_HDRLEN;
 
 	ip = (struct ip *)(p + SLIP_HDRLEN);
@@ -90,38 +80,21 @@
 		printf ("ip v%d", IP_V(ip));
 	}
 
-	if (xflag)
-		default_print_packet(p, caplen, SLIP_HDRLEN);
- out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (SLIP_HDRLEN);
 }
 
-
-void
-sl_bsdos_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+sl_bsdos_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	register u_int caplen = h->caplen;
 	register u_int length = h->len;
 	register const struct ip *ip;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < SLIP_HDRLEN) {
 		printf("[|slip]");
-		goto out;
+		return (caplen);
 	}
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	length -= SLIP_HDRLEN;
 
 	ip = (struct ip *)(p + SLIP_HDRLEN);
@@ -133,13 +106,7 @@
 
 	ip_print((u_char *)ip, length);
 
-	if (xflag)
-		default_print_packet(p, caplen, SLIP_HDRLEN);
- out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (SLIP_HDRLEN);
 }
 
 static void
diff --git a/print-sll.c b/print-sll.c
index ccb94fb..eaf7797 100644
--- a/print-sll.c
+++ b/print-sll.c
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-sll.c,v 1.11 2002-12-18 09:41:18 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-sll.c,v 1.12 2002-12-19 09:39:16 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -92,20 +92,15 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-sll_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+sll_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int caplen = h->caplen;
 	u_int length = h->len;
-	const u_char *orig_p;
-	u_int orig_caplen;
 	register const struct sll_header *sllp;
 	u_short ether_type;
 	u_short extracted_ethertype;
 
-	++infodelay;
-	ts_print(&h->ts);
-
 	if (caplen < SLL_HDR_LEN) {
 		/*
 		 * XXX - this "can't happen" because "pcap-linux.c" always
@@ -113,7 +108,7 @@
 		 * cooked socket capture.
 		 */
 		printf("[|sll]");
-		goto out;
+		return (caplen);
 	}
 
 	sllp = (const struct sll_header *)p;
@@ -122,20 +117,6 @@
 		sll_print(sllp, length);
 
 	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
-	/*
-	 * Save the information for the full packet, so we can print
-	 * everything if "-e" and "-x" are both specified.
-	 */
-	orig_p = p;
-	orig_caplen = caplen;
-
-	/*
 	 * Go past the cooked-mode header.
 	 */
 	length -= SLL_HDR_LEN;
@@ -193,11 +174,6 @@
 		if (!xflag && !qflag)
 			default_print(p, caplen);
 	}
-	if (xflag)
-		default_print_packet(orig_p, orig_caplen, SLL_HDR_LEN);
- out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+
+	return (SLL_HDR_LEN);
 }
diff --git a/print-sunatm.c b/print-sunatm.c
index 3df26fb..a7ebe06 100644
--- a/print-sunatm.c
+++ b/print-sunatm.c
@@ -31,7 +31,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-sunatm.c,v 1.4 2002-09-05 21:25:49 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-sunatm.c,v 1.5 2002-12-19 09:39:16 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -69,8 +69,8 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-sunatm_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+sunatm_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
 	u_int caplen = h->caplen;
 	u_int length = h->len;
@@ -78,11 +78,9 @@
 	u_char vpi;
 	u_int traftype;
 
- 	ts_print(&h->ts);
-
 	if (caplen < PKT_BEGIN_POS) {
 		printf("[|atm]");
-		goto out;
+		return (caplen);
 	}
 
 	if (eflag) {
@@ -115,9 +113,5 @@
 	length -= PKT_BEGIN_POS;
 	atm_print(vpi, vci, traftype, p, length, caplen);
 
- out:
-	putchar('\n');
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (PKT_BEGIN_POS);
 }
diff --git a/print-token.c b/print-token.c
index 74dc536..6478ff2 100644
--- a/print-token.c
+++ b/print-token.c
@@ -25,7 +25,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.21 2002-12-18 09:41:18 guy Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.22 2002-12-19 09:39:16 guy Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -118,13 +118,6 @@
 	 */
 	extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr));
 
-	/*
-	 * Some printers want to check that they're not walking off the
-	 * end of the packet.
-	 * Rather than pass it all the way down, we set this global.
-	 */
-	snapend = p + caplen;
-
 	/* Adjust for source routing information in the MAC header */
 	if (IS_SOURCE_ROUTED(trp)) {
 		/* Clear source-routed bit */
@@ -195,27 +188,8 @@
  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
  * is the number of bytes actually captured.
  */
-void
-token_if_print(u_char *user _U_, const struct pcap_pkthdr *h, const u_char *p)
+u_int
+token_if_print(const struct pcap_pkthdr *h, const u_char *p)
 {
-	u_int caplen = h->caplen;
-	u_int length = h->len;
-	u_int hdr_len;
-
-	++infodelay;
-	ts_print(&h->ts);
-
-	hdr_len = token_print(p, length, caplen);
-
-	/*
-	 * If "-x" was specified, print packet data in hex.
-	 */
-	if (xflag)
-		default_print_packet(p, caplen, hdr_len);
-
-	putchar('\n');
-
-	--infodelay;
-	if (infoprint)
-		info(0);
+	return (token_print(p, h->len, h->caplen));
 }
diff --git a/tcpdump.c b/tcpdump.c
index 73afb27..a4dde2f 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -30,7 +30,7 @@
     "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
 The Regents of the University of California.  All rights reserved.\n";
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.192 2002-12-19 09:27:57 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.193 2002-12-19 09:39:17 guy Exp $ (LBL)";
 #endif
 
 /*
@@ -97,8 +97,8 @@
 
 int packettype;
 
-int infodelay;
-int infoprint;
+static int infodelay;
+static int infoprint;
 
 char *program_name;
 
@@ -109,6 +109,7 @@
 static void usage(void) __attribute__((noreturn));
 static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn));
 
+static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
 static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
 static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
 
@@ -116,11 +117,15 @@
 RETSIGTYPE requestinfo(int);
 #endif
 
+static void info(int);
+
 /* Length of saved portion of packet. */
 int snaplen = DEFAULT_SNAPLEN;
 
+typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *);
+
 struct printer {
-	pcap_handler f;
+	if_printer f;
 	int type;
 };
 
@@ -193,7 +198,7 @@
 	{ NULL,			0 },
 };
 
-static pcap_handler
+static if_printer
 lookup_printer(int type)
 {
 	struct printer *p;
@@ -212,6 +217,10 @@
 extern int opterr;
 extern char *optarg;
 
+struct print_info {
+	if_printer printer;
+};
+
 struct dump_info {
 	char	*WFileName;
 	pcap_t	*pd;
@@ -259,12 +268,13 @@
 	register int cnt, op, i;
 	bpf_u_int32 localnet, netmask;
 	register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
+	pcap_handler callback;
 	int type;
-	pcap_handler printer;
 	struct bpf_program fcode;
 #ifndef WIN32
 	RETSIGTYPE (*oldhandler)(int);
 #endif
+	struct print_info printinfo;
 	struct dump_info dumpinfo;
 	u_char *pcap_userdata;
 	char ebuf[PCAP_ERRBUF_SIZE];
@@ -667,26 +677,27 @@
 		if (p == NULL)
 			error("%s", pcap_geterr(pd));
 		if (Cflag != 0) {
-			printer = dump_packet_and_trunc;
+			callback = dump_packet_and_trunc;
 			dumpinfo.WFileName = WFileName;
 			dumpinfo.pd = pd;
 			dumpinfo.p = p;
 			pcap_userdata = (u_char *)&dumpinfo;
 		} else {
-			printer = dump_packet;
+			callback = dump_packet;
 			pcap_userdata = (u_char *)p;
 		}
 	} else {
 		type = pcap_datalink(pd);
-		printer = lookup_printer(type);
-		if (printer == NULL) {
+		printinfo.printer = lookup_printer(type);
+		if (printinfo.printer == NULL) {
 			dlt_name = pcap_datalink_val_to_name(type);
 			if (dlt_name != NULL)
 				error("unsupported data link type %s", dlt_name);
 			else
 				error("unsupported data link type %d", type);
 		}
-		pcap_userdata = 0;
+		callback = print_packet;
+		pcap_userdata = (u_char *)&printinfo;
 	}
 #ifdef SIGINFO
 	(void)setsignal(SIGINFO, requestinfo);
@@ -698,7 +709,7 @@
 		(void)fflush(stderr);
 	}
 #endif /* WIN32 */
-	if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {
+	if (pcap_loop(pd, cnt, callback, pcap_userdata) < 0) {
 		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
 		    program_name, pcap_geterr(pd));
 		cleanup(0);
@@ -726,7 +737,7 @@
 		exit(0);
 }
 
-void
+static void
 info(register int verbose)
 {
 	struct pcap_stat stat;
@@ -824,6 +835,53 @@
 		info(0);
 }
 
+static void
+print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+{
+	struct print_info *print_info;
+	u_int hdrlen;
+
+	++infodelay;
+	ts_print(&h->ts);
+
+	print_info = (struct print_info *)user;
+
+	/*
+	 * Some printers want to check that they're not walking off the
+	 * end of the packet.
+	 * Rather than pass it all the way down, we set this global.
+	 */
+	snapend = sp + h->caplen;
+
+	hdrlen = (*print_info->printer)(h, sp);
+	if (xflag) {
+		/*
+		 * Print the raw packet data.
+		 */
+		if (xflag > 1) {
+			/*
+			 * Include the link-layer header.
+			 */
+			default_print_unaligned(sp, h->caplen);
+		} else {
+			/*
+			 * Don't include the link-layer header - and if
+			 * we have nothing past the link-layer header,
+			 * print nothing.
+			 */
+			if (h->caplen > hdrlen)
+				default_print_unaligned(sp + hdrlen,
+				    h->caplen - hdrlen);
+		}
+	}
+
+	putchar('\n');
+
+	--infodelay;
+	if (infoprint)
+		info(0);
+}
+
 /* Like default_print() but data need not be aligned */
 void
 default_print_unaligned(register const u_char *cp, register u_int length)
@@ -884,31 +942,6 @@
 	default_print_unaligned(bp, length);
 }
 
-/*
- * By default, print the packet out in hex; if eflag is set, print
- * everything, otherwise print everything except for the link-layer
- * header.
- */
-void
-default_print_packet(register const u_char *bp, register u_int length,
-    u_int hdr_length)
-{
-	if (xflag > 1) {
-		/*
-		 * Include the link-layer header.
-		 */
-		default_print_unaligned(bp, length);
-	} else {
-		/*
-		 * Don't include the link-layer header - and if we have
-		 * nothing past the link-layer header, print nothing.
-		 */
-		if (length > hdr_length)
-			default_print_unaligned(bp + hdr_length,
-			    length - hdr_length);
-	}
-}
-
 #ifdef SIGINFO
 RETSIGTYPE requestinfo(int signo _U_)
 {