12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef lint
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ =
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.7.2.2 2005/11/13 12:12:59 guy Exp $ (LBL)";
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <pcap.h>
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ethertype.h"
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ether.h"
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ipfc.h"
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * RFC 2625 IP-over-Fibre Channel.
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Extract src, dst addresses */
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic inline void
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectextract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc,
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    char *ipfcdst)
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/*
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 * We assume that, as per RFC 2625, the lower 48 bits of the
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 * source and destination addresses are MAC addresses.
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 */
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6);
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6);
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Print the Network_Header
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic inline void
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectipfc_hdr_print(register const struct ipfc_header *ipfcp _U_,
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	   register u_int length, register const u_char *ipfcsrc,
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	   register const u_char *ipfcdst)
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const char *srcname, *dstname;
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	srcname = etheraddr_string(ipfcsrc);
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	dstname = etheraddr_string(ipfcdst);
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/*
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 * XXX - show the upper 16 bits?  Do so only if "vflag" is set?
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 */
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(void) printf("%s %s %d: ", srcname, dstname, length);
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectipfc_print(const u_char *p, u_int length, u_int caplen)
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const struct ipfc_header *ipfcp = (const struct ipfc_header *)p;
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ether_header ehdr;
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_short extracted_ethertype;
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (caplen < IPFC_HDRLEN) {
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf("[|ipfc]");
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/*
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 * Get the network addresses into a canonical form
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	 */
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (eflag)
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Skip over Network_Header */
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	length -= IPFC_HDRLEN;
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p += IPFC_HDRLEN;
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	caplen -= IPFC_HDRLEN;
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Try to print the LLC-layer header & higher layers */
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	    &extracted_ethertype) == 0) {
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/*
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 * Some kinds of LLC packet we cannot
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 * handle intelligently
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		 */
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (!eflag)
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			ipfc_hdr_print(ipfcp, length + IPFC_HDRLEN,
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			    ESRC(&ehdr), EDST(&ehdr));
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (extracted_ethertype) {
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("(LLC %s) ",
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		etherproto_string(htons(extracted_ethertype)));
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (!suppress_default_print)
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			default_print(p, caplen);
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * This is the top level routine of the printer.  'p' points
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * to the Network_Header of the packet, 'h->ts' is the timestamp,
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * 'h->len' is the length of the packet off the wire, and 'h->caplen'
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * is the number of bytes actually captured.
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectu_int
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ipfc_print(p, h->len, h->caplen);
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (IPFC_HDRLEN);
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
136