From d1d0fe1d98ceaf0f31f9084c542c5789f31c2aee Mon Sep 17 00:00:00 2001 From: guy Date: Fri, 18 Oct 2002 08:46:13 +0000 Subject: [PATCH] Add support for RFC 2625 IP-over-Fibre Channel, mapping all the Linux ARPHRD_FC* types to it. --- bpf/net/bpf.h | 5 ++-- gencode.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++---- pcap-linux.c | 26 ++++++++++++++++- pcap.3 | 6 +++- savefile.c | 4 +-- 5 files changed, 106 insertions(+), 12 deletions(-) diff --git a/bpf/net/bpf.h b/bpf/net/bpf.h index f97951c..94ca189 100644 --- a/bpf/net/bpf.h +++ b/bpf/net/bpf.h @@ -37,7 +37,7 @@ * * @(#)bpf.h 7.1 (Berkeley) 5/7/91 * - * @(#) $Header: /tcpdump/master/libpcap/bpf/net/Attic/bpf.h,v 1.62 2002-10-09 13:28:27 hannes Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/bpf/net/Attic/bpf.h,v 1.63 2002-10-18 08:46:15 guy Exp $ (LBL) */ #ifndef BPF_MAJOR_VERSION @@ -340,8 +340,7 @@ struct bpf_hdr { #define DLT_HHDLC 121 /* - * Reserved for RFC 2625 IP-over-Fibre Channel, as per a request from - * Don Lee . + * This is for RFC 2625 IP-over-Fibre Channel. * * This is not for use with raw Fibre Channel, where the link-layer * header starts with a Fibre Channel frame header; it's for IP-over-FC, diff --git a/gencode.c b/gencode.c index 9a5fe74..08e89fe 100644 --- a/gencode.c +++ b/gencode.c @@ -21,7 +21,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.179 2002-08-11 18:27:13 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.180 2002-10-18 08:46:13 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -173,6 +173,7 @@ static struct block *gen_ehostop(const u_char *, int); static struct block *gen_fhostop(const u_char *, int); static struct block *gen_thostop(const u_char *, int); static struct block *gen_wlanhostop(const u_char *, int); +static struct block *gen_ipfchostop(const u_char *, int); static struct block *gen_dnhostop(bpf_u_int32, int, u_int); static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int); #ifdef INET6 @@ -887,6 +888,22 @@ init_linktype(type) off_nl_nosnap = 0; /* no 802.2 LLC */ return; + case DLT_IP_OVER_FC: + /* + * RFC 2625 IP-over-Fibre-Channel doesn't really have a + * link-level type field. We set "off_linktype" to the + * offset of the LLC header. + * + * To check for Ethernet types, we assume that SSAP = SNAP + * is being used and pick out the encapsulated Ethernet type. + * XXX - should we generate code to check for SNAP? RFC + * 2625 says SNAP should be used. + */ + off_linktype = 16; + off_nl = 24; /* IPFC+802.2+SNAP */ + off_nl_nosnap = 19; /* IPFC+802.2 */ + return; + case DLT_FRELAY: /* * XXX - we should set this to handle SNAP-encapsulated @@ -1130,6 +1147,7 @@ gen_linktype(proto) case DLT_IEEE802: case DLT_ATM_RFC1483: case DLT_ATM_CLIP: + case DLT_IP_OVER_FC: return gen_llc(proto); break; @@ -2234,6 +2252,42 @@ gen_wlanhostop(eaddr, dir) /* NOTREACHED */ } +/* + * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel. + * (We assume that the addresses are IEEE 48-bit MAC addresses, + * as the RFC states.) + */ +static struct block * +gen_ipfchostop(eaddr, dir) + register const u_char *eaddr; + register int dir; +{ + register struct block *b0, *b1; + + switch (dir) { + case Q_SRC: + return gen_bcmp(10, 6, eaddr); + + case Q_DST: + return gen_bcmp(2, 6, eaddr); + + case Q_AND: + b0 = gen_ipfchostop(eaddr, Q_SRC); + b1 = gen_ipfchostop(eaddr, Q_DST); + gen_and(b0, b1); + return b1; + + case Q_DEFAULT: + case Q_OR: + b0 = gen_ipfchostop(eaddr, Q_SRC); + b1 = gen_ipfchostop(eaddr, Q_DST); + gen_or(b0, b1); + return b1; + } + abort(); + /* NOTREACHED */ +} + /* * This is quite tricky because there may be pad bytes in front of the * DECNET header, and then there are two possible data packet formats that @@ -2592,9 +2646,11 @@ gen_gateway(eaddr, alist, proto, dir) */ b0 = gen_ehostop(eaddr, Q_OR); gen_and(b1, b0); - } else + } else if (linktype == DLT_IP_OVER_FC) + b0 = gen_ipfchostop(eaddr, Q_OR); + else bpf_error( - "'gateway' supported only on ethernet/FDDI/token ring/802.11"); + "'gateway' supported only on ethernet/FDDI/token ring/802.11/Fibre Channel"); b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR); while (*alist) { @@ -3581,6 +3637,15 @@ gen_scode(name, q) free(eaddr); return b; + case DLT_IP_OVER_FC: + eaddr = pcap_ether_hostton(name); + if (eaddr == NULL) + bpf_error( + "unknown Fibre Channel host '%s'", name); + b = gen_ipfchostop(eaddr, dir); + free(eaddr); + return b; + case DLT_SUNATM: if (!is_lane) break; @@ -3604,7 +3669,7 @@ gen_scode(name, q) return b; } - bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE supports link-level host name"); + bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name"); } else if (proto == Q_DECNET) { unsigned short dn_addr = __pcap_nametodnaddr(name); /* @@ -3981,7 +4046,9 @@ gen_ecode(eaddr, q) gen_and(tmp, b); return b; } - bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE"); + if (linktype == DLT_IP_OVER_FC) + return gen_ipfchostop(eaddr, (int)q.dir); + bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel"); } bpf_error("ethernet address used in non-ether expression"); /* NOTREACHED */ diff --git a/pcap-linux.c b/pcap-linux.c index fb86388..00bd29f 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -26,7 +26,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.84 2002-07-12 07:51:15 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.85 2002-10-18 08:46:14 guy Exp $ (LBL)"; #endif /* @@ -1096,6 +1096,30 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok) handle->linktype = DLT_LTALK; break; +#ifndef ARPHRD_FCPP +#define ARPHRD_FCPP 784 +#endif + case ARPHRD_FCPP: +#ifndef ARPHRD_FCAL +#define ARPHRD_FCAL 785 +#endif + case ARPHRD_FCAL: +#ifndef ARPHRD_FCPL +#define ARPHRD_FCPL 786 +#endif + case ARPHRD_FCPL: +#ifndef ARPHRD_FCFABRIC +#define ARPHRD_FCFABRIC 787 +#endif + case ARPHRD_FCFABRIC: + /* + * We assume that those all mean RFC 2625 IP-over- + * Fibre Channel, with the RFC 2625 header at + * the beginning of the packet. + */ + handle->linktype = DLT_IP_OVER_FC; + break; + default: handle->linktype = -1; break; diff --git a/pcap.3 b/pcap.3 index d801e9d..9b9f6f1 100644 --- a/pcap.3 +++ b/pcap.3 @@ -1,4 +1,4 @@ -.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.38 2002-09-18 19:07:57 guy Exp $ +.\" @(#) $Header: /tcpdump/master/libpcap/Attic/pcap.3,v 1.39 2002-10-18 08:46:15 guy Exp $ .\" .\" Copyright (c) 1994, 1996, 1997 .\" The Regents of the University of California. All rights reserved. @@ -752,6 +752,10 @@ a 1-byte VPI value; .LP a 2-byte VCI field, in network byte order. .RE +.TP 5 +.B DLT_IP_OVER_FC +RFC 2625 IP-over-Fibre Channel, with the link-layer header being the +Network_Header as described in that RFC. .PP .B pcap_snapshot() returns the snapshot length specified when diff --git a/savefile.c b/savefile.c index d26cab0..7175ab4 100644 --- a/savefile.c +++ b/savefile.c @@ -30,7 +30,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.67 2002-10-09 19:02:56 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.68 2002-10-18 08:46:15 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -164,6 +164,7 @@ static const char rcsid[] = #define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */ #define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */ #define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */ +#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ #define LINKTYPE_SUNATM 123 /* Solaris+SunATM */ /* @@ -176,7 +177,6 @@ static const char rcsid[] = #define LINKTYPE_IPFILTER 116 /* IP Filter capture files */ #define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */ #define LINKTYPE_HHDLC 121 /* Siemens HiPath HDLC */ -#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */ #define LINKTYPE_RIO 123 /* RapidIO */ #define LINKTYPE_PCI_EXP 124 /* PCI Express */ #define LINKTYPE_AURORA 125 /* Xilinx Aurora link layer */