* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.8 2005-07-07 01:22:19 guy Exp $ (LBL)";
-#endif
+/* \summary: IP over Fibre Channel printer */
+
+/* specification: RFC 2625 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
-#include <pcap.h>
-#include <stdio.h>
#include <string.h>
-#include "interface.h"
+#include "netdissect.h"
#include "addrtoname.h"
-#include "ethertype.h"
#include "ether.h"
-#include "ipfc.h"
-/*
- * RFC 2625 IP-over-Fibre Channel.
- */
+struct ipfc_header {
+ u_char ipfc_dhost[8];
+ u_char ipfc_shost[8];
+};
+
+#define IPFC_HDRLEN 16
/* Extract src, dst addresses */
static inline void
* Print the Network_Header
*/
static inline void
-ipfc_hdr_print(register const struct ipfc_header *ipfcp _U_,
+ipfc_hdr_print(netdissect_options *ndo,
+ register const struct ipfc_header *ipfcp _U_,
register u_int length, register const u_char *ipfcsrc,
register const u_char *ipfcdst)
{
const char *srcname, *dstname;
- srcname = etheraddr_string(ipfcsrc);
- dstname = etheraddr_string(ipfcdst);
+ srcname = etheraddr_string(ndo, ipfcsrc);
+ dstname = etheraddr_string(ndo, ipfcdst);
/*
- * XXX - show the upper 16 bits? Do so only if "vflag" is set?
+ * XXX - should we show the upper 16 bits of the addresses?
+ * Do so only if "vflag" is set?
+ * Section 3.3 "FC Port and Node Network Addresses" says that
+ *
+ * In this specification, both the Source and Destination
+ * 4-bit NAA identifiers SHALL be set to binary '0001'
+ * indicating that an IEEE 48-bit MAC address is contained
+ * in the lower 48 bits of the network address fields. The
+ * high order 12 bits in the network address fields SHALL
+ * be set to 0x0000.
+ *
+ * so, for captures following this specification, the upper 16
+ * bits should be 0x1000, followed by a MAC address.
*/
- (void) printf("%s %s %d: ", srcname, dstname, length);
+ ND_PRINT((ndo, "%s > %s, length %u: ", srcname, dstname, length));
}
-static void
-ipfc_print(const u_char *p, u_int length, u_int caplen)
+static u_int
+ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
{
const struct ipfc_header *ipfcp = (const struct ipfc_header *)p;
struct ether_header ehdr;
- u_short extracted_ethertype;
+ struct lladdr_info src, dst;
+ int llc_hdrlen;
if (caplen < IPFC_HDRLEN) {
- printf("[|ipfc]");
- return;
+ ND_PRINT((ndo, "[|ipfc]"));
+ return (caplen);
}
/*
* Get the network addresses into a canonical form
*/
extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
- if (eflag)
- ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
+ if (ndo->ndo_eflag)
+ ipfc_hdr_print(ndo, ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
+
+ src.addr = ESRC(&ehdr);
+ src.addr_string = etheraddr_string;
+ dst.addr = EDST(&ehdr);
+ dst.addr_string = etheraddr_string;
/* Skip over Network_Header */
length -= IPFC_HDRLEN;
p += IPFC_HDRLEN;
caplen -= IPFC_HDRLEN;
- /* Frame Control field determines interpretation of packet */
- extracted_ethertype = 0;
/* Try to print the LLC-layer header & higher layers */
- if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
- &extracted_ethertype) == 0) {
+ llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
+ if (llc_hdrlen < 0) {
/*
* Some kinds of LLC packet we cannot
* handle intelligently
*/
- if (!eflag)
- ipfc_hdr_print(ipfcp, length + IPFC_HDRLEN,
- ESRC(&ehdr), EDST(&ehdr));
- if (extracted_ethertype) {
- printf("(LLC %s) ",
- etherproto_string(htons(extracted_ethertype)));
- }
- if (!suppress_default_print)
- default_print(p, caplen);
+ if (!ndo->ndo_suppress_default_print)
+ ND_DEFAULTPRINT(p, caplen);
+ llc_hdrlen = -llc_hdrlen;
}
+ return (IPFC_HDRLEN + llc_hdrlen);
}
/*
* is the number of bytes actually captured.
*/
u_int
-ipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+ipfc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
{
- ipfc_print(p, h->len, h->caplen);
-
- return (IPFC_HDRLEN);
+ return (ipfc_print(ndo, p, h->len, h->caplen));
}