summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--netdissect.h20
-rw-r--r--print-pktap.c11
-rw-r--r--print-ppi.c11
-rw-r--r--print.c97
-rw-r--r--print.h2
5 files changed, 115 insertions, 26 deletions
diff --git a/netdissect.h b/netdissect.h
index c25e8cbe..64b86d4f 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -164,7 +164,15 @@ typedef struct netdissect_options netdissect_options;
#define IF_PRINTER_ARGS (netdissect_options *, const struct pcap_pkthdr *, const u_char *)
-typedef u_int (*if_printer) IF_PRINTER_ARGS;
+typedef u_int (*uint_if_printer) IF_PRINTER_ARGS;
+typedef void (*void_if_printer) IF_PRINTER_ARGS;
+
+/* pointer to the uint_if_printer or the void_if_printer function */
+typedef union {
+ uint_if_printer uint_printer;
+ void_if_printer void_printer;
+ void* printer; /* generic when testing if NULL or not */
+} if_printer_t;
/*
* In case the data in a buffer needs to be processed by being decrypted,
@@ -227,6 +235,7 @@ struct netdissect_options {
int ndo_packettype; /* as specified by -T */
int ndo_snaplen;
+ int ndo_ll_header_length; /* link-layer header length */
/*global pointers to beginning and end of current packet (during printing) */
const u_char *ndo_packetp;
@@ -235,8 +244,9 @@ struct netdissect_options {
/* stack of saved packet boundary and buffer information */
struct netdissect_saved_packet_info *ndo_packet_info_stack;
- /* pointer to the if_printer function */
- if_printer ndo_if_printer;
+ /* pointer to the uint_if_printer or the void_if_printer function */
+ if_printer_t ndo_if_printer;
+ int ndo_void_printer; /* void_if_printer ? (FALSE/TRUE) */
/* pointer to void function to output stuff */
void (*ndo_default_print)(netdissect_options *,
@@ -443,7 +453,9 @@ extern int unaligned_memcmp(const void *, const void *, size_t);
extern const char *tok2strary_internal(const char **, int, const char *, int);
#define tok2strary(a,f,i) tok2strary_internal(a, sizeof(a)/sizeof(a[0]),f,i)
-extern if_printer lookup_printer(int);
+extern uint_if_printer lookup_uint_printer(int);
+extern void_if_printer lookup_void_printer(int);
+extern if_printer_t lookup_printer(netdissect_options *, int);
#define ND_DEBUG {printf(" [%s:%d %s] ", __FILE__, __LINE__, __FUNCTION__); fflush(stdout);}
diff --git a/print-pktap.c b/print-pktap.c
index af3b3973..182378ef 100644
--- a/print-pktap.c
+++ b/print-pktap.c
@@ -102,7 +102,7 @@ pktap_if_print(netdissect_options *ndo,
uint32_t dlt, hdrlen, rectype;
u_int caplen = h->caplen;
u_int length = h->len;
- if_printer printer;
+ if_printer_t printer;
const pktap_header_t *hdr;
struct pcap_pkthdr nhdr;
@@ -145,11 +145,16 @@ pktap_if_print(netdissect_options *ndo,
break;
case PKT_REC_PACKET:
- if ((printer = lookup_printer(dlt)) != NULL) {
+ printer = lookup_printer(ndo, dlt);
+ if (printer.printer != NULL) {
nhdr = *h;
nhdr.caplen = caplen;
nhdr.len = length;
- hdrlen += printer(ndo, &nhdr, p);
+ if (ndo->ndo_void_printer == TRUE) {
+ printer.void_printer(ndo, &nhdr, p);
+ hdrlen += ndo->ndo_ll_header_length;
+ } else
+ hdrlen += printer.uint_printer(ndo, &nhdr, p);
} else {
if (!ndo->ndo_eflag)
pktap_header_print(ndo, (const u_char *)hdr,
diff --git a/print-ppi.c b/print-ppi.c
index 8f47fcfc..fe85fa51 100644
--- a/print-ppi.c
+++ b/print-ppi.c
@@ -54,7 +54,7 @@ static u_int
ppi_print(netdissect_options *ndo,
const struct pcap_pkthdr *h, const u_char *p)
{
- if_printer printer;
+ if_printer_t printer;
const ppi_header_t *hdr;
u_int caplen = h->caplen;
u_int length = h->len;
@@ -94,11 +94,16 @@ ppi_print(netdissect_options *ndo,
caplen -= len;
p += len;
- if ((printer = lookup_printer(dlt)) != NULL) {
+ printer = lookup_printer(ndo, dlt);
+ if (printer.printer != NULL) {
nhdr = *h;
nhdr.caplen = caplen;
nhdr.len = length;
- hdrlen = printer(ndo, &nhdr, p);
+ if (ndo->ndo_void_printer == TRUE) {
+ printer.void_printer(ndo, &nhdr, p);
+ hdrlen = ndo->ndo_ll_header_length;
+ } else
+ hdrlen = printer.uint_printer(ndo, &nhdr, p);
} else {
if (!ndo->ndo_eflag)
ppi_header_print(ndo, (const u_char *)hdr, length + len);
diff --git a/print.c b/print.c
index 418658ea..e272ce9a 100644
--- a/print.c
+++ b/print.c
@@ -42,12 +42,17 @@
#include "pcap-missing.h"
-struct printer {
- if_printer f;
+struct uint_printer {
+ uint_if_printer f;
int type;
};
-static const struct printer printers[] = {
+struct void_printer {
+ void_if_printer f;
+ int type;
+};
+
+static const struct uint_printer uint_printers[] = {
{ ether_if_print, DLT_EN10MB },
#ifdef DLT_IPNET
{ ipnet_if_print, DLT_IPNET },
@@ -249,6 +254,10 @@ static const struct printer printers[] = {
{ NULL, 0 },
};
+static const struct void_printer void_printers[] = {
+ { NULL, 0 },
+};
+
static void ndo_default_print(netdissect_options *ndo, const u_char *bp,
u_int length);
@@ -272,12 +281,49 @@ init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask)
init_checksum();
}
-if_printer
-lookup_printer(int type)
+uint_if_printer
+lookup_uint_printer(int type)
+{
+ const struct uint_printer *p;
+
+ for (p = uint_printers; p->f; ++p)
+ if (type == p->type)
+ return p->f;
+
+#if defined(DLT_USER2) && defined(DLT_PKTAP)
+ /*
+ * Apple incorrectly chose to use DLT_USER2 for their PKTAP
+ * header.
+ *
+ * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin-
+ * based OSes or the same value as LINKTYPE_PKTAP as it is on
+ * other OSes, to LINKTYPE_PKTAP, so files written with
+ * this version of libpcap for a DLT_PKTAP capture have a link-
+ * layer header type of LINKTYPE_PKTAP.
+ *
+ * However, files written on OS X Mavericks for a DLT_PKTAP
+ * capture have a link-layer header type of LINKTYPE_USER2.
+ * If we don't have a printer for DLT_USER2, and type is
+ * DLT_USER2, we look up the printer for DLT_PKTAP and use
+ * that.
+ */
+ if (type == DLT_USER2) {
+ for (p = uint_printers; p->f; ++p)
+ if (DLT_PKTAP == p->type)
+ return p->f;
+ }
+#endif
+
+ return NULL;
+ /* NOTREACHED */
+}
+
+void_if_printer
+lookup_void_printer(int type)
{
- const struct printer *p;
+ const struct void_printer *p;
- for (p = printers; p->f; ++p)
+ for (p = void_printers; p->f; ++p)
if (type == p->type)
return p->f;
@@ -299,7 +345,7 @@ lookup_printer(int type)
* that.
*/
if (type == DLT_USER2) {
- for (p = printers; p->f; ++p)
+ for (p = void_printers; p->f; ++p)
if (DLT_PKTAP == p->type)
return p->f;
}
@@ -309,20 +355,35 @@ lookup_printer(int type)
/* NOTREACHED */
}
+if_printer_t
+lookup_printer(netdissect_options *ndo, int type)
+{
+ if_printer_t printer;
+
+ printer.void_printer = lookup_void_printer(type);
+ ndo->ndo_void_printer = TRUE;
+ if (printer.void_printer == NULL) {
+ printer.uint_printer = lookup_uint_printer(type);
+ ndo->ndo_void_printer = FALSE;
+ }
+ return printer;
+}
+
int
has_printer(int type)
{
- return (lookup_printer(type) != NULL);
+ return (lookup_void_printer(type) != NULL ||
+ lookup_uint_printer(type) != NULL);
}
-if_printer
+if_printer_t
get_if_printer(netdissect_options *ndo, int type)
{
const char *dltname;
- if_printer printer;
+ if_printer_t printer;
- printer = lookup_printer(type);
- if (printer == NULL) {
+ printer = lookup_printer(ndo, type);
+ if (printer.printer == NULL) {
dltname = pcap_datalink_val_to_name(type);
if (dltname != NULL)
(*ndo->ndo_error)(ndo, S_ERR_ND_NO_PRINTER,
@@ -339,7 +400,7 @@ void
pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
const u_char *sp, u_int packets_captured)
{
- u_int hdrlen = 0;
+ u_int hdrlen;
int invalid_header = 0;
if (ndo->ndo_packet_number)
@@ -409,12 +470,18 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
ndo->ndo_snapend = sp + h->caplen;
ndo->ndo_protocol = "";
+ ndo->ndo_ll_header_length = 0;
if (setjmp(ndo->ndo_truncated) == 0) {
/* Print the packet. */
- hdrlen = (ndo->ndo_if_printer)(ndo, h, sp);
+ if (ndo->ndo_void_printer == TRUE) {
+ (ndo->ndo_if_printer.void_printer)(ndo, h, sp);
+ hdrlen = ndo->ndo_ll_header_length;
+ } else
+ hdrlen = (ndo->ndo_if_printer.uint_printer)(ndo, h, sp);
} else {
/* A printer quit because the packet was truncated; report it */
ND_PRINT(" [|%s]", ndo->ndo_protocol);
+ hdrlen = ndo->ndo_ll_header_length;
}
/*
diff --git a/print.h b/print.h
index 70ea9f8e..5e67b33a 100644
--- a/print.h
+++ b/print.h
@@ -32,7 +32,7 @@ void init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask);
int has_printer(int type);
-if_printer get_if_printer(netdissect_options *ndo, int type);
+if_printer_t get_if_printer(netdissect_options *ndo, int type);
void pretty_print_packet(netdissect_options *ndo,
const struct pcap_pkthdr *h, const u_char *sp,