summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2016-11-16 13:47:27 +0000
committerreyk <reyk@openbsd.org>2016-11-16 13:47:27 +0000
commit7a61d4b0b602572c95a5b96f09678a2dda2ae243 (patch)
tree1858659280d5980cd47a6532151d132af54348e2
parentFix calculation of whether we need a region for drawing a cell (only if (diff)
downloadwireguard-openbsd-7a61d4b0b602572c95a5b96f09678a2dda2ae243.tar.xz
wireguard-openbsd-7a61d4b0b602572c95a5b96f09678a2dda2ae243.zip
Add new DLT_OPENFLOW link-type to allow using tcpdump to debug switch(4),
eg. tcpdump -y openflow -i switch0 Includes a minor bump for libpcap. Feedback and OK rzalamena@
-rw-r--r--lib/libpcap/gencode.c7
-rw-r--r--lib/libpcap/pcap.c3
-rw-r--r--lib/libpcap/shlib_version2
-rw-r--r--sys/net/bpf.h4
-rw-r--r--sys/net/if_switch.c13
-rw-r--r--sys/net/if_switch.h4
-rw-r--r--sys/net/switchofp.c23
-rw-r--r--usr.sbin/tcpdump/interface.h7
-rw-r--r--usr.sbin/tcpdump/print-ofp.c54
-rw-r--r--usr.sbin/tcpdump/print-tcp.c4
-rw-r--r--usr.sbin/tcpdump/tcpdump.c3
11 files changed, 100 insertions, 24 deletions
diff --git a/lib/libpcap/gencode.c b/lib/libpcap/gencode.c
index df09868fc90..5dcbc8ac8e7 100644
--- a/lib/libpcap/gencode.c
+++ b/lib/libpcap/gencode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gencode.c,v 1.44 2015/12/22 19:51:04 mmcc Exp $ */
+/* $OpenBSD: gencode.c,v 1.45 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
@@ -782,6 +782,11 @@ init_linktype(type)
off_nl = 4;
return;
+ case DLT_OPENFLOW:
+ off_linktype = -1;
+ off_nl = 4;
+ return;
+
case DLT_RAW:
off_linktype = -1;
off_nl = 0;
diff --git a/lib/libpcap/pcap.c b/lib/libpcap/pcap.c
index 0a41bc43b88..41bda730f4d 100644
--- a/lib/libpcap/pcap.c
+++ b/lib/libpcap/pcap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcap.c,v 1.19 2016/04/06 08:02:56 jasper Exp $ */
+/* $OpenBSD: pcap.c,v 1.20 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
@@ -325,6 +325,7 @@ DLT_CHOICE(DLT_PPP_ETHER, "PPP over Ethernet; session only w/o ether header"),
DLT_CHOICE(DLT_IEEE802_11, "IEEE 802.11 wireless"),
DLT_CHOICE(DLT_PFLOG, "Packet filter logging, by pcap people"),
DLT_CHOICE(DLT_IEEE802_11_RADIO, "IEEE 802.11 plus WLAN header"),
+DLT_CHOICE(DLT_OPENFLOW, "OpenFlow"),
#undef DLT_CHOICE
{ NULL, NULL, -1}
};
diff --git a/lib/libpcap/shlib_version b/lib/libpcap/shlib_version
index 00604e64e7d..51876cfb75f 100644
--- a/lib/libpcap/shlib_version
+++ b/lib/libpcap/shlib_version
@@ -1,2 +1,2 @@
major=8
-minor=1
+minor=2
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index 8d193f0f8f5..41b90098f1f 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpf.h,v 1.59 2016/10/30 17:46:34 phessler Exp $ */
+/* $OpenBSD: bpf.h,v 1.60 2016/11/16 13:47:27 reyk Exp $ */
/* $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $ */
/*
@@ -185,7 +185,9 @@ struct bpf_hdr {
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
#define DLT_PFLOG 117 /* Packet filter logging, by pcap people */
#define DLT_IEEE802_11_RADIO 127 /* IEEE 802.11 plus WLAN header */
+#define DLT_USER0 147 /* Reserved for private use */
#define DLT_MPLS 219 /* MPLS Provider Edge header */
+#define DLT_OPENFLOW DLT_USER0
/*
* The instruction encodings.
diff --git a/sys/net/if_switch.c b/sys/net/if_switch.c
index 28aeed4a5e9..5e62cbb8c27 100644
--- a/sys/net/if_switch.c
+++ b/sys/net/if_switch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_switch.c,v 1.12 2016/11/10 17:32:40 rzalamena Exp $ */
+/* $OpenBSD: if_switch.c,v 1.13 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 2016 Kazuya GODA <goda@openbsd.org>
@@ -187,8 +187,6 @@ switch_clone_create(struct if_clone *ifc, int unit)
return (ENOMEM);
}
- swofp_create(sc);
-
if_attach(ifp);
if_alloc_sadl(ifp);
@@ -196,6 +194,8 @@ switch_clone_create(struct if_clone *ifc, int unit)
bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
#endif
+ swofp_create(sc);
+
LIST_INSERT_HEAD(&switch_list, sc, sc_switch_next);
log(LOG_INFO, "%s: switch created\n", ifp->if_xname);
@@ -1529,6 +1529,13 @@ switch_flow_classifier_dump(struct switch_softc *sc,
}
int
+switch_mtap(caddr_t arg, struct mbuf *m, int dir)
+{
+ /* prepend 32 bit "controller to switch" field */
+ return bpf_mtap_af(arg, dir == BPF_DIRECTION_IN ? 1 : 0, m, dir);
+}
+
+int
ofp_split_mbuf(struct mbuf *m, struct mbuf **mtail)
{
struct ofp_header *oh;
diff --git a/sys/net/if_switch.h b/sys/net/if_switch.h
index 586b8e02f2d..60012a1fda0 100644
--- a/sys/net/if_switch.h
+++ b/sys/net/if_switch.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_switch.h,v 1.8 2016/11/11 16:19:09 rzalamena Exp $ */
+/* $OpenBSD: if_switch.h,v 1.9 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 2016 Kazuya GODA <goda@openbsd.org>
@@ -201,6 +201,7 @@ struct switch_softc {
struct switch_dev *sc_swdev; /* char device */
struct bstp_state *sc_stp; /* STP state */
struct swofp_ofs *sc_ofs; /* OpenFlow */
+ caddr_t sc_ofbpf; /* DLT_OPENFLOW */
TAILQ_HEAD(,switch_port) sc_swpo_list; /* port */
LIST_ENTRY(switch_softc) sc_switch_next; /* switch link */
void (*switch_process_forward)(
@@ -219,6 +220,7 @@ void switch_swfcl_free(struct switch_flow_classify *);
struct mbuf
*switch_flow_classifier(struct mbuf *, uint32_t,
struct switch_flow_classify *);
+int switch_mtap(caddr_t, struct mbuf *, int);
int ofp_split_mbuf(struct mbuf *, struct mbuf **);
/* switchctl.c */
diff --git a/sys/net/switchofp.c b/sys/net/switchofp.c
index 4cbfcb10883..acb185c3432 100644
--- a/sys/net/switchofp.c
+++ b/sys/net/switchofp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: switchofp.c,v 1.30 2016/11/10 17:32:40 rzalamena Exp $ */
+/* $OpenBSD: switchofp.c,v 1.31 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 2016 Kazuya GODA <goda@openbsd.org>
@@ -18,6 +18,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "bpfilter.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
@@ -45,6 +47,10 @@
#include <net/if_vlan_var.h>
#include <net/ofp.h>
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
/*
* per-frame matching logs provide a helpful for isolating a problem or debuging
* on runtime but it has potentiality which degrade performance and overflow
@@ -978,6 +984,11 @@ swofp_create(struct switch_softc *sc)
sc->sc_capabilities |= SWITCH_CAP_OFP;
sc->switch_process_forward = swofp_forward_ofs;
+#if NBPFILTER > 0
+ bpfattach(&sc->sc_ofbpf, &sc->sc_if, DLT_OPENFLOW,
+ sizeof(struct ofp_header));
+#endif
+
DPRINTF(sc, "enable OpenFlow switch capability\n");
return (0);
@@ -4478,6 +4489,11 @@ swofp_input(struct switch_softc *sc, struct mbuf *m)
swofp_mtype_str(oh->oh_type), ntohl(oh->oh_xid),
ntohs(oh->oh_length));
+#if NBPFILTER > 0
+ if (sc->sc_ofbpf)
+ switch_mtap(sc->sc_ofbpf, m, BPF_DIRECTION_IN);
+#endif
+
handler = swofp_lookup_msg_handler(oh->oh_type);
if (handler)
(*handler)(sc, m);
@@ -4503,6 +4519,11 @@ swofp_output(struct switch_softc *sc, struct mbuf *m)
swofp_mtype_str(oh->oh_type), ntohl(oh->oh_xid),
ntohs(oh->oh_length));
+#if NBPFILTER > 0
+ if (sc->sc_ofbpf)
+ switch_mtap(sc->sc_ofbpf, m, BPF_DIRECTION_OUT);
+#endif
+
if (sc->sc_swdev->swdev_output(sc, m) != 0)
return (ENOBUFS);
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h
index 20718806201..384f5277ca0 100644
--- a/usr.sbin/tcpdump/interface.h
+++ b/usr.sbin/tcpdump/interface.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.h,v 1.68 2016/10/22 20:55:04 rzalamena Exp $ */
+/* $OpenBSD: interface.h,v 1.69 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -20,7 +20,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Id: interface.h,v 1.68 2016/10/22 20:55:04 rzalamena Exp $ (LBL)
+ * @(#) $Id: interface.h,v 1.69 2016/11/16 13:47:27 reyk Exp $ (LBL)
*/
#ifndef tcpdump_interface_h
@@ -274,7 +274,8 @@ extern void mpls_print(const u_char *, u_int);
extern void lldp_print(const u_char *, u_int);
extern void slow_print(const u_char *, u_int);
extern void gtp_print(const u_char *, u_int, u_short, u_short);
-extern void ofp_print(const u_char *);
+extern void ofp_print(const u_char *, u_int);
+extern void ofp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *);
#ifdef INET6
extern void ip6_print(const u_char *, u_int);
diff --git a/usr.sbin/tcpdump/print-ofp.c b/usr.sbin/tcpdump/print-ofp.c
index 226fc94736f..ddb57c06d23 100644
--- a/usr.sbin/tcpdump/print-ofp.c
+++ b/usr.sbin/tcpdump/print-ofp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-ofp.c,v 1.2 2016/10/25 08:43:15 rzalamena Exp $ */
+/* $OpenBSD: print-ofp.c,v 1.3 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 2016 Rafael Zalamena <rzalamena@openbsd.org>
@@ -21,7 +21,9 @@
#include <endian.h>
#include <stddef.h>
#include <stdio.h>
+#include <pcap.h>
+#include "extract.h"
#include "interface.h"
/* Size of action header without the padding. */
@@ -155,7 +157,7 @@ ofp_print_error(const u_char *bp, u_int length)
/* If there are still bytes left, print the optional error data. */
if (length) {
printf(" error data:");
- ofp_print(bp);
+ ofp_print(bp, length);
}
}
@@ -508,21 +510,55 @@ parse_next_instruction:
}
void
-ofp_print(const u_char *bp)
+ofp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
- struct ofp_header *oh;
- unsigned int ohlen;
- u_int length;
+ uint32_t toswitch;
+ unsigned int length;
- length = snapend - bp;
+ ts_print(&h->ts);
+
+ packetp = p;
+ snapend = p + h->caplen;
+ length = snapend - p;
+
+ if (length < 4)
+ goto trunc;
+ toswitch = EXTRACT_32BITS(p);
+
+ if (toswitch)
+ printf("controller -> %s", device);
+ else
+ printf("%s -> controller", device);
+
+ ofp_print(p + 4, length - 4);
+ goto out;
+
+ trunc:
+ printf("[|OpenFlow]");
+
+ out:
+ if (xflag)
+ default_print(p, (u_int)h->len);
+ putchar('\n');
+}
+
+void
+ofp_print(const u_char *bp, u_int length)
+{
+ struct ofp_header *oh;
+ unsigned int ohlen, snaplen;
+
+ /* The captured data might be smaller than indicated */
+ snaplen = snapend - bp;
+ length = min(snaplen, length);
if (length < sizeof(*oh)) {
- printf(" OpenFlow(truncated)");
+ printf("[|OpenFlow]");
return;
}
oh = (struct ofp_header *)bp;
ohlen = ntohs(oh->oh_length);
- printf(" OpenFlow(ver %#02x type %d len %d xid %u)",
+ printf(": OpenFlow(ver %#02x type %d len %d xid %u)",
oh->oh_version, oh->oh_type, ohlen, ntohl(oh->oh_xid));
switch (oh->oh_version) {
diff --git a/usr.sbin/tcpdump/print-tcp.c b/usr.sbin/tcpdump/print-tcp.c
index 1655ef21406..16928ed0d8a 100644
--- a/usr.sbin/tcpdump/print-tcp.c
+++ b/usr.sbin/tcpdump/print-tcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-tcp.c,v 1.36 2016/10/22 20:55:04 rzalamena Exp $ */
+/* $OpenBSD: print-tcp.c,v 1.37 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -671,7 +671,7 @@ tcp_print(const u_char *bp, u_int length, const u_char *bp2)
bgp_print(bp, length);
else if (sport == OLD_OFP_PORT || dport == OLD_OFP_PORT ||
sport == OFP_PORT || dport == OFP_PORT)
- ofp_print(bp);
+ ofp_print(bp, length);
#if 0
else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT)
nbt_tcp_print(bp, length);
diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c
index b7b4d14e364..5a5d2c600f9 100644
--- a/usr.sbin/tcpdump/tcpdump.c
+++ b/usr.sbin/tcpdump/tcpdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcpdump.c,v 1.78 2015/12/22 21:01:07 mmcc Exp $ */
+/* $OpenBSD: tcpdump.c,v 1.79 2016/11/16 13:47:27 reyk Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -126,6 +126,7 @@ static struct printer printers[] = {
{ ppp_ether_if_print, DLT_PPP_ETHER },
{ ieee802_11_if_print, DLT_IEEE802_11 },
{ ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
+ { ofp_if_print, DLT_OPENFLOW },
{ NULL, 0 },
};