]> The Tcpdump Group git mirrors - tcpdump/commitdiff
The patches attached to this email are required to get a fully working tcpdump
authorDarren Reed <[email protected]>
Wed, 25 Nov 2009 02:20:25 +0000 (21:20 -0500)
committerMichael Richardson <[email protected]>
Wed, 25 Nov 2009 02:20:25 +0000 (21:20 -0500)
on OpenSolaris, or Solaris Express Community Edition, build 125 and later.

The attached patch introduces support for printing out the IPNET headers used
for packet capture inside of zones that share their networking with the global
zone and for packets "transmitted" between zones.

tcpdump 4.0.0 will ship with builds 129 and later of OpenSolaris/SXCE and
when run as root with the '-L' option, should behave as below to indicate that
the system is fully functional:

Data link types (use option -y to set):
 DOCSIS (DOCSIS) (printing not supported)
 IPNET (Solaris IPNET)
 EN10MB (Ethernet)

Cheers,
Darren

Makefile.in
interface.h
ipnet.h [new file with mode: 0644]
print-ipnet.c [new file with mode: 0644]
tcpdump.c

index 04efdcd703e98cfe967abd08cee3e9b55fbe523a..ca29ce85f65042b29bd0b2b6c09fc2299a5471fe 100644 (file)
@@ -77,7 +77,7 @@ CSRC =        addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c
        print-eap.c print-eigrp.c\
        print-esp.c print-ether.c print-fddi.c print-fr.c \
        print-gre.c print-hsrp.c print-icmp.c print-igmp.c \
-       print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c \
+       print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c print-ipnet.c \
        print-ipx.c print-isoclns.c print-juniper.c print-krb.c \
        print-l2tp.c print-lane.c print-ldp.c print-lldp.c print-llc.c \
         print-lmp.c print-lspping.c print-lwapp.c \
index 9038b433b1948ca9ebad9e14e3248cd356c1127c..4296823a538f84c4cd687a06745a71ba850ef44d 100644 (file)
@@ -322,6 +322,10 @@ extern void bfd_print(const u_char *, u_int, u_int);
 extern void sip_print(const u_char *, u_int);
 extern void syslog_print(const u_char *, u_int);
 extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void ipnet_print(const u_char *, u_int, u_int);
+extern u_int ipnet_if_print(const struct pcap_pkthdr *, const u_char *);
+extern int ipnet_encap_print(u_short, const u_char *, u_int, u_int);
+
 extern u_int usb_linux_print(const struct pcap_pkthdr *, const u_char *);
 
 #ifdef INET6
diff --git a/ipnet.h b/ipnet.h
new file mode 100644 (file)
index 0000000..ae69284
--- /dev/null
+++ b/ipnet.h
@@ -0,0 +1,13 @@
+typedef struct ipnet_hdr {
+       uint8_t         iph_version;
+       uint8_t         iph_family;
+       uint16_t        iph_htype;
+       uint32_t        iph_pktlen;
+       uint32_t        iph_ifindex;
+       uint32_t        iph_grifindex;
+       uint32_t        iph_zsrc;
+       uint32_t        iph_zdst;
+} ipnet_hdr_t;
+
+#define        IPH_AF_INET     2               /* Matches Solaris's AF_INET */
+#define        IPH_AF_INET6    26              /* Matches Solaris's AF_INET6 */
diff --git a/print-ipnet.c b/print-ipnet.c
new file mode 100644 (file)
index 0000000..56b4978
--- /dev/null
@@ -0,0 +1,132 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ipnet.h"
+
+#ifdef DLT_IPNET
+
+int ipnet_encap_print(u_short, const u_char *, u_int, u_int);
+
+const struct tok ipnet_values[] = {
+       { IPH_AF_INET,          "IPv4" },
+       { IPH_AF_INET6,         "IPv6" },
+       { 0,                    NULL }
+};
+
+static inline void
+ipnet_hdr_print(register const u_char *bp, u_int length)
+{
+       const ipnet_hdr_t *hdr;
+       hdr = (const ipnet_hdr_t *)bp;
+
+       (void)printf("%d > %d", hdr->iph_zsrc, hdr->iph_zdst);
+
+       if (!qflag) {
+               (void)printf(", family %s (%d)",
+                            tok2str(ipnet_values, "Unknown",
+                                    hdr->iph_family),
+                             hdr->iph_family);
+        } else {
+               (void)printf(", %s",
+                            tok2str(ipnet_values,
+                                    "Unknown Ethertype (0x%04x)",
+                                    hdr->iph_family));
+        }
+
+       (void)printf(", length %u: ", length);
+}
+
+void
+ipnet_print(const u_char *p, u_int length, u_int caplen)
+{
+       ipnet_hdr_t *hdr;
+
+       if (caplen < sizeof(ipnet_hdr_t)) {
+               printf("[|ipnet]");
+               return;
+       }
+
+       if (eflag)
+               ipnet_hdr_print(p, length);
+
+       length -= sizeof(ipnet_hdr_t);
+       caplen -= sizeof(ipnet_hdr_t);
+       hdr = (ipnet_hdr_t *)p;
+       p += sizeof(ipnet_hdr_t);
+
+       if (ipnet_encap_print(hdr->iph_family, p, length, caplen) == 0) {
+               if (!eflag)
+                       ipnet_hdr_print((u_char *)hdr,
+                                       length + sizeof(ipnet_hdr_t));
+
+               if (!suppress_default_print)
+                       default_print(p, caplen);
+       } 
+}
+
+/*
+ * This is the top level routine of the printer.  'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ipnet_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+       ipnet_print(p, h->len, h->caplen);
+
+       return (sizeof(ipnet_hdr_t));
+}
+
+/*
+ * Prints the packet encapsulated in an Ethernet data segment
+ * (or an equivalent encapsulation), given the Ethernet type code.
+ *
+ * Returns non-zero if it can do so, zero if the ethertype is unknown.
+ *
+ * The Ethernet type code is passed through a pointer; if it was
+ * ETHERTYPE_8021Q, it gets updated to be the Ethernet type of
+ * the 802.1Q payload, for the benefit of lower layers that might
+ * want to know what it is.
+ */
+
+int
+ipnet_encap_print(u_short family, const u_char *p,
+    u_int length, u_int caplen)
+{
+ recurse:
+
+       switch (family) {
+
+       case IPH_AF_INET:
+               ip_print(gndo, p, length);
+               return (1);
+
+#ifdef INET6
+       case IPH_AF_INET6:
+               ip6_print(p, length);
+               return (1);
+#endif /*INET6*/
+
+       default:
+               return(0);
+       }
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
+
+#endif /* DLT_IPNET */
index 18c7af4b60716cf8dd2ed21fbd290d26a460b7af..25feb7a04457083ffa55abc51ee0c9eb0b1a80e4 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -281,6 +281,9 @@ static struct printer printers[] = {
 #endif
 #if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX_MMAPPED)
        { usb_linux_print, DLT_USB_LINUX_MMAPPED},
+#endif
+#ifdef DLT_IPNET
+       { ipnet_if_print, DLT_IPNET },
 #endif
        { NULL,                 0 },
 };