1127668Sbms/* 2127668Sbms * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 3127668Sbms * The Regents of the University of California. All rights reserved. 4127668Sbms * 5127668Sbms * Redistribution and use in source and binary forms, with or without 6127668Sbms * modification, are permitted provided that: (1) source code distributions 7127668Sbms * retain the above copyright notice and this paragraph in its entirety, (2) 8127668Sbms * distributions including binary code include the above copyright notice and 9127668Sbms * this paragraph in its entirety in the documentation or other materials 10127668Sbms * provided with the distribution, and (3) all advertising materials mentioning 11127668Sbms * features or use of this software display the following acknowledgement: 12127668Sbms * ``This product includes software developed by the University of California, 13127668Sbms * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14127668Sbms * the University nor the names of its contributors may be used to endorse 15127668Sbms * or promote products derived from this software without specific prior 16127668Sbms * written permission. 17127668Sbms * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18127668Sbms * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19127668Sbms * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20127668Sbms */ 21127668Sbms 22127668Sbms#ifndef lint 23127668Sbmsstatic const char rcsid[] _U_ = 24190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.9 2005-11-13 12:12:42 guy Exp $ (LBL)"; 25127668Sbms#endif 26127668Sbms 27127668Sbms#ifdef HAVE_CONFIG_H 28127668Sbms#include "config.h" 29127668Sbms#endif 30127668Sbms 31127668Sbms#include <tcpdump-stdinc.h> 32127668Sbms 33127668Sbms#include <pcap.h> 34127668Sbms#include <stdio.h> 35127668Sbms#include <string.h> 36127668Sbms 37127668Sbms#include "interface.h" 38127668Sbms#include "addrtoname.h" 39127668Sbms#include "ethertype.h" 40127668Sbms 41127668Sbms#include "ether.h" 42127668Sbms#include "ipfc.h" 43127668Sbms 44127668Sbms/* 45127668Sbms * RFC 2625 IP-over-Fibre Channel. 46127668Sbms */ 47127668Sbms 48127668Sbms/* Extract src, dst addresses */ 49127668Sbmsstatic inline void 50127668Sbmsextract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc, 51127668Sbms char *ipfcdst) 52127668Sbms{ 53127668Sbms /* 54127668Sbms * We assume that, as per RFC 2625, the lower 48 bits of the 55127668Sbms * source and destination addresses are MAC addresses. 56127668Sbms */ 57127668Sbms memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6); 58127668Sbms memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6); 59127668Sbms} 60127668Sbms 61127668Sbms/* 62127668Sbms * Print the Network_Header 63127668Sbms */ 64127668Sbmsstatic inline void 65127668Sbmsipfc_hdr_print(register const struct ipfc_header *ipfcp _U_, 66127668Sbms register u_int length, register const u_char *ipfcsrc, 67127668Sbms register const u_char *ipfcdst) 68127668Sbms{ 69127668Sbms const char *srcname, *dstname; 70127668Sbms 71127668Sbms srcname = etheraddr_string(ipfcsrc); 72127668Sbms dstname = etheraddr_string(ipfcdst); 73127668Sbms 74127668Sbms /* 75127668Sbms * XXX - show the upper 16 bits? Do so only if "vflag" is set? 76127668Sbms */ 77127668Sbms (void) printf("%s %s %d: ", srcname, dstname, length); 78127668Sbms} 79127668Sbms 80127668Sbmsstatic void 81127668Sbmsipfc_print(const u_char *p, u_int length, u_int caplen) 82127668Sbms{ 83127668Sbms const struct ipfc_header *ipfcp = (const struct ipfc_header *)p; 84127668Sbms struct ether_header ehdr; 85127668Sbms u_short extracted_ethertype; 86127668Sbms 87127668Sbms if (caplen < IPFC_HDRLEN) { 88127668Sbms printf("[|ipfc]"); 89127668Sbms return; 90127668Sbms } 91127668Sbms /* 92127668Sbms * Get the network addresses into a canonical form 93127668Sbms */ 94127668Sbms extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); 95127668Sbms 96127668Sbms if (eflag) 97127668Sbms ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr)); 98127668Sbms 99127668Sbms /* Skip over Network_Header */ 100127668Sbms length -= IPFC_HDRLEN; 101127668Sbms p += IPFC_HDRLEN; 102127668Sbms caplen -= IPFC_HDRLEN; 103127668Sbms 104127668Sbms /* Try to print the LLC-layer header & higher layers */ 105127668Sbms if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), 106127668Sbms &extracted_ethertype) == 0) { 107127668Sbms /* 108127668Sbms * Some kinds of LLC packet we cannot 109127668Sbms * handle intelligently 110127668Sbms */ 111127668Sbms if (!eflag) 112127668Sbms ipfc_hdr_print(ipfcp, length + IPFC_HDRLEN, 113127668Sbms ESRC(&ehdr), EDST(&ehdr)); 114127668Sbms if (extracted_ethertype) { 115127668Sbms printf("(LLC %s) ", 116127668Sbms etherproto_string(htons(extracted_ethertype))); 117127668Sbms } 118162017Ssam if (!suppress_default_print) 119127668Sbms default_print(p, caplen); 120127668Sbms } 121127668Sbms} 122127668Sbms 123127668Sbms/* 124127668Sbms * This is the top level routine of the printer. 'p' points 125127668Sbms * to the Network_Header of the packet, 'h->ts' is the timestamp, 126146773Ssam * 'h->len' is the length of the packet off the wire, and 'h->caplen' 127127668Sbms * is the number of bytes actually captured. 128127668Sbms */ 129127668Sbmsu_int 130127668Sbmsipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p) 131127668Sbms{ 132127668Sbms ipfc_print(p, h->len, h->caplen); 133127668Sbms 134127668Sbms return (IPFC_HDRLEN); 135127668Sbms} 136