tcpdump mailing list archives

tcpdump: patches required for OpenSolaris/SXCE build >= 125


From: Darren Reed <Darren.Reed () Sun COM>
Date: Tue, 24 Nov 2009 16:54:31 -0800

The patches attached to this email are required to get a fully working tcpdump
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:

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

Cheers,
Darren

--- Makefile.in.dist    Sun Aug 31 19:44:11 2008
+++ Makefile.in Wed Sep 16 10:37:48 2009
@@ -77,7 +77,7 @@
        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 \
--- interface.h.orig    Sun Aug 31 19:44:14 2008
+++ interface.h Fri Jul 31 18:37:02 2009
@@ -332,7 +332,11 @@
 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);
 
+
 #ifdef INET6
 extern void ip6_print(const u_char *, u_int);
 extern void ip6_opt_print(const u_char *, int);
diff -Nu ipnet.h ipnet.h
--- ipnet.h     1969-12-31 16:00:00.000000000 -0800
+++ ipnet.h     2009-07-22 14:59:11.821073000 -0700
@@ -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 -Nu print-ipnet.c print-ipnet.c
--- print-ipnet.c       1969-12-31 16:00:00.000000000 -0800
+++ print-ipnet.c       2009-07-22 14:59:13.613693000 -0700
@@ -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 */
diff -Nu tcpdump.c tcpdump.c
--- tcpdump.c.dist      2009-07-17 22:51:51.964577000 -0700
+++ tcpdump.c   2009-07-22 15:11:03.076784000 -0700
@@ -282,6 +282,9 @@
 #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 },
 };
 
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.

Current thread: