15b0fe478SBruce M Simpson /* 25b0fe478SBruce M Simpson * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 35b0fe478SBruce M Simpson * The Regents of the University of California. All rights reserved. 45b0fe478SBruce M Simpson * 55b0fe478SBruce M Simpson * Redistribution and use in source and binary forms, with or without 65b0fe478SBruce M Simpson * modification, are permitted provided that: (1) source code distributions 75b0fe478SBruce M Simpson * retain the above copyright notice and this paragraph in its entirety, (2) 85b0fe478SBruce M Simpson * distributions including binary code include the above copyright notice and 95b0fe478SBruce M Simpson * this paragraph in its entirety in the documentation or other materials 105b0fe478SBruce M Simpson * provided with the distribution, and (3) all advertising materials mentioning 115b0fe478SBruce M Simpson * features or use of this software display the following acknowledgement: 125b0fe478SBruce M Simpson * ``This product includes software developed by the University of California, 135b0fe478SBruce M Simpson * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 145b0fe478SBruce M Simpson * the University nor the names of its contributors may be used to endorse 155b0fe478SBruce M Simpson * or promote products derived from this software without specific prior 165b0fe478SBruce M Simpson * written permission. 175b0fe478SBruce M Simpson * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 185b0fe478SBruce M Simpson * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 195b0fe478SBruce M Simpson * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 205b0fe478SBruce M Simpson */ 215b0fe478SBruce M Simpson 223340d773SGleb Smirnoff /* \summary: IP over Fibre Channel printer */ 233340d773SGleb Smirnoff 243340d773SGleb Smirnoff /* specification: RFC 2625 */ 253340d773SGleb Smirnoff 265b0fe478SBruce M Simpson #ifdef HAVE_CONFIG_H 27*ee67461eSJoseph Mingrone #include <config.h> 285b0fe478SBruce M Simpson #endif 295b0fe478SBruce M Simpson 30*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 315b0fe478SBruce M Simpson 325b0fe478SBruce M Simpson #include <string.h> 335b0fe478SBruce M Simpson 34*ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK 353340d773SGleb Smirnoff #include "netdissect.h" 365b0fe478SBruce M Simpson #include "addrtoname.h" 375b0fe478SBruce M Simpson 385b0fe478SBruce M Simpson 393c602fabSXin LI struct ipfc_header { 40*ee67461eSJoseph Mingrone nd_byte ipfc_dhost[2+MAC_ADDR_LEN]; 41*ee67461eSJoseph Mingrone nd_byte ipfc_shost[2+MAC_ADDR_LEN]; 423c602fabSXin LI }; 433c602fabSXin LI 443c602fabSXin LI #define IPFC_HDRLEN 16 453c602fabSXin LI 465b0fe478SBruce M Simpson /* Extract src, dst addresses */ 47*ee67461eSJoseph Mingrone static void 485b0fe478SBruce M Simpson extract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc, 495b0fe478SBruce M Simpson char *ipfcdst) 505b0fe478SBruce M Simpson { 515b0fe478SBruce M Simpson /* 525b0fe478SBruce M Simpson * We assume that, as per RFC 2625, the lower 48 bits of the 535b0fe478SBruce M Simpson * source and destination addresses are MAC addresses. 545b0fe478SBruce M Simpson */ 55*ee67461eSJoseph Mingrone memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], MAC_ADDR_LEN); 56*ee67461eSJoseph Mingrone memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], MAC_ADDR_LEN); 575b0fe478SBruce M Simpson } 585b0fe478SBruce M Simpson 595b0fe478SBruce M Simpson /* 605b0fe478SBruce M Simpson * Print the Network_Header 615b0fe478SBruce M Simpson */ 62*ee67461eSJoseph Mingrone static void 633c602fabSXin LI ipfc_hdr_print(netdissect_options *ndo, 64*ee67461eSJoseph Mingrone const struct ipfc_header *ipfcp _U_, u_int length, 65*ee67461eSJoseph Mingrone const u_char *ipfcsrc, const u_char *ipfcdst) 665b0fe478SBruce M Simpson { 675b0fe478SBruce M Simpson const char *srcname, *dstname; 685b0fe478SBruce M Simpson 693c602fabSXin LI srcname = etheraddr_string(ndo, ipfcsrc); 703c602fabSXin LI dstname = etheraddr_string(ndo, ipfcdst); 715b0fe478SBruce M Simpson 725b0fe478SBruce M Simpson /* 733340d773SGleb Smirnoff * XXX - should we show the upper 16 bits of the addresses? 743340d773SGleb Smirnoff * Do so only if "vflag" is set? 753340d773SGleb Smirnoff * Section 3.3 "FC Port and Node Network Addresses" says that 763340d773SGleb Smirnoff * 773340d773SGleb Smirnoff * In this specification, both the Source and Destination 783340d773SGleb Smirnoff * 4-bit NAA identifiers SHALL be set to binary '0001' 793340d773SGleb Smirnoff * indicating that an IEEE 48-bit MAC address is contained 803340d773SGleb Smirnoff * in the lower 48 bits of the network address fields. The 813340d773SGleb Smirnoff * high order 12 bits in the network address fields SHALL 823340d773SGleb Smirnoff * be set to 0x0000. 833340d773SGleb Smirnoff * 843340d773SGleb Smirnoff * so, for captures following this specification, the upper 16 853340d773SGleb Smirnoff * bits should be 0x1000, followed by a MAC address. 865b0fe478SBruce M Simpson */ 87*ee67461eSJoseph Mingrone ND_PRINT("%s > %s, length %u: ", srcname, dstname, length); 885b0fe478SBruce M Simpson } 895b0fe478SBruce M Simpson 903340d773SGleb Smirnoff static u_int 913c602fabSXin LI ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) 925b0fe478SBruce M Simpson { 935b0fe478SBruce M Simpson const struct ipfc_header *ipfcp = (const struct ipfc_header *)p; 94*ee67461eSJoseph Mingrone nd_mac_addr srcmac, dstmac; 953340d773SGleb Smirnoff struct lladdr_info src, dst; 963340d773SGleb Smirnoff int llc_hdrlen; 975b0fe478SBruce M Simpson 98*ee67461eSJoseph Mingrone ndo->ndo_protocol = "ipfc"; 99*ee67461eSJoseph Mingrone ND_TCHECK_LEN(p, IPFC_HDRLEN); 1005b0fe478SBruce M Simpson /* 1015b0fe478SBruce M Simpson * Get the network addresses into a canonical form 1025b0fe478SBruce M Simpson */ 103*ee67461eSJoseph Mingrone extract_ipfc_addrs(ipfcp, (char *)srcmac, (char *)dstmac); 1045b0fe478SBruce M Simpson 1053c602fabSXin LI if (ndo->ndo_eflag) 106*ee67461eSJoseph Mingrone ipfc_hdr_print(ndo, ipfcp, length, srcmac, dstmac); 1075b0fe478SBruce M Simpson 108*ee67461eSJoseph Mingrone src.addr = srcmac; 1093340d773SGleb Smirnoff src.addr_string = etheraddr_string; 110*ee67461eSJoseph Mingrone dst.addr = dstmac; 1113340d773SGleb Smirnoff dst.addr_string = etheraddr_string; 1123340d773SGleb Smirnoff 1135b0fe478SBruce M Simpson /* Skip over Network_Header */ 1145b0fe478SBruce M Simpson length -= IPFC_HDRLEN; 1155b0fe478SBruce M Simpson p += IPFC_HDRLEN; 1165b0fe478SBruce M Simpson caplen -= IPFC_HDRLEN; 1175b0fe478SBruce M Simpson 1185b0fe478SBruce M Simpson /* Try to print the LLC-layer header & higher layers */ 1193340d773SGleb Smirnoff llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); 1203340d773SGleb Smirnoff if (llc_hdrlen < 0) { 1215b0fe478SBruce M Simpson /* 1225b0fe478SBruce M Simpson * Some kinds of LLC packet we cannot 1235b0fe478SBruce M Simpson * handle intelligently 1245b0fe478SBruce M Simpson */ 1253c602fabSXin LI if (!ndo->ndo_suppress_default_print) 1263c602fabSXin LI ND_DEFAULTPRINT(p, caplen); 1273340d773SGleb Smirnoff llc_hdrlen = -llc_hdrlen; 1285b0fe478SBruce M Simpson } 1293340d773SGleb Smirnoff return (IPFC_HDRLEN + llc_hdrlen); 1305b0fe478SBruce M Simpson } 1315b0fe478SBruce M Simpson 1325b0fe478SBruce M Simpson /* 1335b0fe478SBruce M Simpson * This is the top level routine of the printer. 'p' points 1345b0fe478SBruce M Simpson * to the Network_Header of the packet, 'h->ts' is the timestamp, 1351de50e9fSSam Leffler * 'h->len' is the length of the packet off the wire, and 'h->caplen' 1365b0fe478SBruce M Simpson * is the number of bytes actually captured. 1375b0fe478SBruce M Simpson */ 138*ee67461eSJoseph Mingrone void 139*ee67461eSJoseph Mingrone ipfc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) 1405b0fe478SBruce M Simpson { 141*ee67461eSJoseph Mingrone ndo->ndo_protocol = "ipfc"; 142*ee67461eSJoseph Mingrone ndo->ndo_ll_hdr_len += ipfc_print(ndo, p, h->len, h->caplen); 1435b0fe478SBruce M Simpson } 144