xref: /freebsd/contrib/tcpdump/print-ipfc.c (revision 5b0fe47811aa43b75fc69dbf7338cace232a4d48)
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 
225b0fe478SBruce M Simpson #ifndef lint
235b0fe478SBruce M Simpson static const char rcsid[] _U_ =
245b0fe478SBruce M Simpson     "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.4.2.2 2003/11/16 08:51:28 guy Exp $ (LBL)";
255b0fe478SBruce M Simpson #endif
265b0fe478SBruce M Simpson 
275b0fe478SBruce M Simpson #ifdef HAVE_CONFIG_H
285b0fe478SBruce M Simpson #include "config.h"
295b0fe478SBruce M Simpson #endif
305b0fe478SBruce M Simpson 
315b0fe478SBruce M Simpson #include <tcpdump-stdinc.h>
325b0fe478SBruce M Simpson 
335b0fe478SBruce M Simpson #include <pcap.h>
345b0fe478SBruce M Simpson #include <stdio.h>
355b0fe478SBruce M Simpson #include <string.h>
365b0fe478SBruce M Simpson 
375b0fe478SBruce M Simpson #include "interface.h"
385b0fe478SBruce M Simpson #include "addrtoname.h"
395b0fe478SBruce M Simpson #include "ethertype.h"
405b0fe478SBruce M Simpson 
415b0fe478SBruce M Simpson #include "ether.h"
425b0fe478SBruce M Simpson #include "ipfc.h"
435b0fe478SBruce M Simpson 
445b0fe478SBruce M Simpson /*
455b0fe478SBruce M Simpson  * RFC 2625 IP-over-Fibre Channel.
465b0fe478SBruce M Simpson  */
475b0fe478SBruce M Simpson 
485b0fe478SBruce M Simpson /* Extract src, dst addresses */
495b0fe478SBruce M Simpson static inline void
505b0fe478SBruce M Simpson extract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc,
515b0fe478SBruce M Simpson     char *ipfcdst)
525b0fe478SBruce M Simpson {
535b0fe478SBruce M Simpson 	/*
545b0fe478SBruce M Simpson 	 * We assume that, as per RFC 2625, the lower 48 bits of the
555b0fe478SBruce M Simpson 	 * source and destination addresses are MAC addresses.
565b0fe478SBruce M Simpson 	 */
575b0fe478SBruce M Simpson 	memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6);
585b0fe478SBruce M Simpson 	memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6);
595b0fe478SBruce M Simpson }
605b0fe478SBruce M Simpson 
615b0fe478SBruce M Simpson /*
625b0fe478SBruce M Simpson  * Print the Network_Header
635b0fe478SBruce M Simpson  */
645b0fe478SBruce M Simpson static inline void
655b0fe478SBruce M Simpson ipfc_hdr_print(register const struct ipfc_header *ipfcp _U_,
665b0fe478SBruce M Simpson 	   register u_int length, register const u_char *ipfcsrc,
675b0fe478SBruce M Simpson 	   register const u_char *ipfcdst)
685b0fe478SBruce M Simpson {
695b0fe478SBruce M Simpson 	const char *srcname, *dstname;
705b0fe478SBruce M Simpson 
715b0fe478SBruce M Simpson 	srcname = etheraddr_string(ipfcsrc);
725b0fe478SBruce M Simpson 	dstname = etheraddr_string(ipfcdst);
735b0fe478SBruce M Simpson 
745b0fe478SBruce M Simpson 	/*
755b0fe478SBruce M Simpson 	 * XXX - show the upper 16 bits?  Do so only if "vflag" is set?
765b0fe478SBruce M Simpson 	 */
775b0fe478SBruce M Simpson 	(void) printf("%s %s %d: ", srcname, dstname, length);
785b0fe478SBruce M Simpson }
795b0fe478SBruce M Simpson 
805b0fe478SBruce M Simpson static void
815b0fe478SBruce M Simpson ipfc_print(const u_char *p, u_int length, u_int caplen)
825b0fe478SBruce M Simpson {
835b0fe478SBruce M Simpson 	const struct ipfc_header *ipfcp = (const struct ipfc_header *)p;
845b0fe478SBruce M Simpson 	struct ether_header ehdr;
855b0fe478SBruce M Simpson 	u_short extracted_ethertype;
865b0fe478SBruce M Simpson 
875b0fe478SBruce M Simpson 	if (caplen < IPFC_HDRLEN) {
885b0fe478SBruce M Simpson 		printf("[|ipfc]");
895b0fe478SBruce M Simpson 		return;
905b0fe478SBruce M Simpson 	}
915b0fe478SBruce M Simpson 	/*
925b0fe478SBruce M Simpson 	 * Get the network addresses into a canonical form
935b0fe478SBruce M Simpson 	 */
945b0fe478SBruce M Simpson 	extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
955b0fe478SBruce M Simpson 
965b0fe478SBruce M Simpson 	if (eflag)
975b0fe478SBruce M Simpson 		ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
985b0fe478SBruce M Simpson 
995b0fe478SBruce M Simpson 	/* Skip over Network_Header */
1005b0fe478SBruce M Simpson 	length -= IPFC_HDRLEN;
1015b0fe478SBruce M Simpson 	p += IPFC_HDRLEN;
1025b0fe478SBruce M Simpson 	caplen -= IPFC_HDRLEN;
1035b0fe478SBruce M Simpson 
1045b0fe478SBruce M Simpson 	/* Frame Control field determines interpretation of packet */
1055b0fe478SBruce M Simpson 	extracted_ethertype = 0;
1065b0fe478SBruce M Simpson 	/* Try to print the LLC-layer header & higher layers */
1075b0fe478SBruce M Simpson 	if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
1085b0fe478SBruce M Simpson 	    &extracted_ethertype) == 0) {
1095b0fe478SBruce M Simpson 		/*
1105b0fe478SBruce M Simpson 		 * Some kinds of LLC packet we cannot
1115b0fe478SBruce M Simpson 		 * handle intelligently
1125b0fe478SBruce M Simpson 		 */
1135b0fe478SBruce M Simpson 		if (!eflag)
1145b0fe478SBruce M Simpson 			ipfc_hdr_print(ipfcp, length + IPFC_HDRLEN,
1155b0fe478SBruce M Simpson 			    ESRC(&ehdr), EDST(&ehdr));
1165b0fe478SBruce M Simpson 		if (extracted_ethertype) {
1175b0fe478SBruce M Simpson 			printf("(LLC %s) ",
1185b0fe478SBruce M Simpson 		etherproto_string(htons(extracted_ethertype)));
1195b0fe478SBruce M Simpson 		}
1205b0fe478SBruce M Simpson 		if (!xflag && !qflag)
1215b0fe478SBruce M Simpson 			default_print(p, caplen);
1225b0fe478SBruce M Simpson 	}
1235b0fe478SBruce M Simpson }
1245b0fe478SBruce M Simpson 
1255b0fe478SBruce M Simpson /*
1265b0fe478SBruce M Simpson  * This is the top level routine of the printer.  'p' points
1275b0fe478SBruce M Simpson  * to the Network_Header of the packet, 'h->ts' is the timestamp,
1285b0fe478SBruce M Simpson  * 'h->length' is the length of the packet off the wire, and 'h->caplen'
1295b0fe478SBruce M Simpson  * is the number of bytes actually captured.
1305b0fe478SBruce M Simpson  */
1315b0fe478SBruce M Simpson u_int
1325b0fe478SBruce M Simpson ipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
1335b0fe478SBruce M Simpson {
1345b0fe478SBruce M Simpson 	ipfc_print(p, h->len, h->caplen);
1355b0fe478SBruce M Simpson 
1365b0fe478SBruce M Simpson 	return (IPFC_HDRLEN);
1375b0fe478SBruce M Simpson }
138