198524Sfenner/* 298524Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 398524Sfenner * The Regents of the University of California. All rights reserved. 498524Sfenner * 598524Sfenner * Redistribution and use in source and binary forms, with or without 698524Sfenner * modification, are permitted provided that: (1) source code distributions 798524Sfenner * retain the above copyright notice and this paragraph in its entirety, (2) 898524Sfenner * distributions including binary code include the above copyright notice and 998524Sfenner * this paragraph in its entirety in the documentation or other materials 1098524Sfenner * provided with the distribution, and (3) all advertising materials mentioning 1198524Sfenner * features or use of this software display the following acknowledgement: 1298524Sfenner * ``This product includes software developed by the University of California, 1398524Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1498524Sfenner * the University nor the names of its contributors may be used to endorse 1598524Sfenner * or promote products derived from this software without specific prior 1698524Sfenner * written permission. 1798524Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1898524Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1998524Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20127668Sbms * 2198524Sfenner * From: NetBSD: print-arcnet.c,v 1.2 2000/04/24 13:02:28 itojun Exp 2298524Sfenner */ 2398524Sfenner#ifndef lint 24127668Sbmsstatic const char rcsid[] _U_ = 25190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.20 2005-04-06 21:32:38 mcr Exp $ (LBL)"; 2698524Sfenner#endif 2798524Sfenner 2898524Sfenner#ifdef HAVE_CONFIG_H 2998524Sfenner#include "config.h" 3098524Sfenner#endif 3198524Sfenner 32127668Sbms#include <tcpdump-stdinc.h> 3398524Sfenner 3498524Sfenner#include <stdio.h> 3598524Sfenner#include <pcap.h> 3698524Sfenner 3798524Sfenner#include "interface.h" 38214478Srpaulo#include "extract.h" 3998524Sfenner#include "arcnet.h" 4098524Sfenner 41127668Sbmsstatic int arcnet_encap_print(u_char arctype, const u_char *p, 4298524Sfenner u_int length, u_int caplen); 4398524Sfenner 4498524Sfennerstruct tok arctypemap[] = { 4598524Sfenner { ARCTYPE_IP_OLD, "oldip" }, 4698524Sfenner { ARCTYPE_ARP_OLD, "oldarp" }, 4798524Sfenner { ARCTYPE_IP, "ip" }, 4898524Sfenner { ARCTYPE_ARP, "arp" }, 4998524Sfenner { ARCTYPE_REVARP, "rarp" }, 5098524Sfenner { ARCTYPE_ATALK, "atalk" }, 5198524Sfenner { ARCTYPE_BANIAN, "banyan" }, 5298524Sfenner { ARCTYPE_IPX, "ipx" }, 5398524Sfenner { ARCTYPE_INET6, "ipv6" }, 5498524Sfenner { ARCTYPE_DIAGNOSE, "diag" }, 5598524Sfenner { 0, 0 } 5698524Sfenner}; 5798524Sfenner 5898524Sfennerstatic inline void 5998524Sfennerarcnet_print(const u_char *bp, u_int length, int phds, int flag, u_int seqid) 6098524Sfenner{ 6198524Sfenner const struct arc_header *ap; 6298524Sfenner const char *arctypename; 6398524Sfenner 6498524Sfenner 6598524Sfenner ap = (const struct arc_header *)bp; 6698524Sfenner 6798524Sfenner 6898524Sfenner if (qflag) { 6998524Sfenner (void)printf("%02x %02x %d: ", 7098524Sfenner ap->arc_shost, 7198524Sfenner ap->arc_dhost, 7298524Sfenner length); 7398524Sfenner return; 7498524Sfenner } 7598524Sfenner 7698524Sfenner arctypename = tok2str(arctypemap, "%02x", ap->arc_type); 7798524Sfenner 7898524Sfenner if (!phds) { 7998524Sfenner (void)printf("%02x %02x %s %d: ", 8098524Sfenner ap->arc_shost, ap->arc_dhost, arctypename, 8198524Sfenner length); 8298524Sfenner return; 8398524Sfenner } 8498524Sfenner 8598524Sfenner if (flag == 0) { 8698524Sfenner (void)printf("%02x %02x %s seqid %04x %d: ", 8798524Sfenner ap->arc_shost, ap->arc_dhost, arctypename, seqid, 8898524Sfenner length); 8998524Sfenner return; 9098524Sfenner } 9198524Sfenner 9298524Sfenner if (flag & 1) 9398524Sfenner (void)printf("%02x %02x %s seqid %04x " 9498524Sfenner "(first of %d fragments) %d: ", 9598524Sfenner ap->arc_shost, ap->arc_dhost, arctypename, seqid, 9698524Sfenner (flag + 3) / 2, length); 9798524Sfenner else 9898524Sfenner (void)printf("%02x %02x %s seqid %04x " 9998524Sfenner "(fragment %d) %d: ", 10098524Sfenner ap->arc_shost, ap->arc_dhost, arctypename, seqid, 10198524Sfenner flag/2 + 1, length); 10298524Sfenner} 10398524Sfenner 10498524Sfenner/* 105127668Sbms * This is the top level routine of the printer. 'p' points 106127668Sbms * to the ARCNET header of the packet, 'h->ts' is the timestamp, 107146773Ssam * 'h->len' is the length of the packet off the wire, and 'h->caplen' 10898524Sfenner * is the number of bytes actually captured. 10998524Sfenner */ 110127668Sbmsu_int 111127668Sbmsarcnet_if_print(const struct pcap_pkthdr *h, const u_char *p) 11298524Sfenner{ 11398524Sfenner u_int caplen = h->caplen; 11498524Sfenner u_int length = h->len; 11598524Sfenner const struct arc_header *ap; 11698524Sfenner 11798524Sfenner int phds, flag = 0, archdrlen = 0; 11898524Sfenner u_int seqid = 0; 11998524Sfenner u_char arc_type; 12098524Sfenner 12198524Sfenner if (caplen < ARC_HDRLEN) { 12298524Sfenner printf("[|arcnet]"); 123127668Sbms return (caplen); 12498524Sfenner } 12598524Sfenner 12698524Sfenner ap = (const struct arc_header *)p; 12798524Sfenner arc_type = ap->arc_type; 12898524Sfenner 12998524Sfenner switch (arc_type) { 13098524Sfenner default: 13198524Sfenner phds = 1; 13298524Sfenner break; 13398524Sfenner case ARCTYPE_IP_OLD: 13498524Sfenner case ARCTYPE_ARP_OLD: 13598524Sfenner case ARCTYPE_DIAGNOSE: 13698524Sfenner phds = 0; 13798524Sfenner archdrlen = ARC_HDRLEN; 13898524Sfenner break; 13998524Sfenner } 14098524Sfenner 14198524Sfenner if (phds) { 14298524Sfenner if (caplen < ARC_HDRNEWLEN) { 14398524Sfenner arcnet_print(p, length, 0, 0, 0); 14498524Sfenner printf("[|phds]"); 145127668Sbms return (caplen); 14698524Sfenner } 14798524Sfenner 14898524Sfenner if (ap->arc_flag == 0xff) { 14998524Sfenner if (caplen < ARC_HDRNEWLEN_EXC) { 15098524Sfenner arcnet_print(p, length, 0, 0, 0); 15198524Sfenner printf("[|phds extended]"); 152127668Sbms return (caplen); 15398524Sfenner } 15498524Sfenner flag = ap->arc_flag2; 155214478Srpaulo seqid = EXTRACT_16BITS(&ap->arc_seqid2); 15698524Sfenner archdrlen = ARC_HDRNEWLEN_EXC; 15798524Sfenner } else { 15898524Sfenner flag = ap->arc_flag; 159214478Srpaulo seqid = EXTRACT_16BITS(&ap->arc_seqid); 16098524Sfenner archdrlen = ARC_HDRNEWLEN; 16198524Sfenner } 16298524Sfenner } 16398524Sfenner 16498524Sfenner 16598524Sfenner if (eflag) 16698524Sfenner arcnet_print(p, length, phds, flag, seqid); 16798524Sfenner 16898524Sfenner /* 169127668Sbms * Go past the ARCNET header. 17098524Sfenner */ 17198524Sfenner length -= archdrlen; 17298524Sfenner caplen -= archdrlen; 17398524Sfenner p += archdrlen; 17498524Sfenner 175127668Sbms if (phds && flag && (flag & 1) == 0) { 176127668Sbms /* 177127668Sbms * This is a middle fragment. 178127668Sbms */ 179127668Sbms return (archdrlen); 180127668Sbms } 18198524Sfenner 182127668Sbms if (!arcnet_encap_print(arc_type, p, length, caplen)) 18398524Sfenner default_print(p, caplen); 184127668Sbms 185127668Sbms return (archdrlen); 186127668Sbms} 187127668Sbms 188127668Sbms/* 189127668Sbms * This is the top level routine of the printer. 'p' points 190127668Sbms * to the ARCNET header of the packet, 'h->ts' is the timestamp, 191146773Ssam * 'h->len' is the length of the packet off the wire, and 'h->caplen' 192127668Sbms * is the number of bytes actually captured. It is quite similar 193127668Sbms * to the non-Linux style printer except that Linux doesn't ever 194127668Sbms * supply packets that look like exception frames, it always supplies 195127668Sbms * reassembled packets rather than raw frames, and headers have an 196127668Sbms * extra "offset" field between the src/dest and packet type. 197127668Sbms */ 198127668Sbmsu_int 199127668Sbmsarcnet_linux_if_print(const struct pcap_pkthdr *h, const u_char *p) 200127668Sbms{ 201127668Sbms u_int caplen = h->caplen; 202127668Sbms u_int length = h->len; 203127668Sbms const struct arc_linux_header *ap; 204127668Sbms 205127668Sbms int archdrlen = 0; 206127668Sbms u_char arc_type; 207127668Sbms 208127668Sbms if (caplen < ARC_LINUX_HDRLEN) { 209127668Sbms printf("[|arcnet]"); 210127668Sbms return (caplen); 21198524Sfenner } 21298524Sfenner 213127668Sbms ap = (const struct arc_linux_header *)p; 214127668Sbms arc_type = ap->arc_type; 215127668Sbms 216127668Sbms switch (arc_type) { 217127668Sbms default: 218127668Sbms archdrlen = ARC_LINUX_HDRNEWLEN; 219127668Sbms if (caplen < ARC_LINUX_HDRNEWLEN) { 220127668Sbms printf("[|arcnet]"); 221127668Sbms return (caplen); 222127668Sbms } 223127668Sbms break; 224127668Sbms case ARCTYPE_IP_OLD: 225127668Sbms case ARCTYPE_ARP_OLD: 226127668Sbms case ARCTYPE_DIAGNOSE: 227127668Sbms archdrlen = ARC_LINUX_HDRLEN; 228127668Sbms break; 229127668Sbms } 230127668Sbms 231127668Sbms if (eflag) 232127668Sbms arcnet_print(p, length, 0, 0, 0); 233127668Sbms 234127668Sbms /* 235127668Sbms * Go past the ARCNET header. 236127668Sbms */ 237127668Sbms length -= archdrlen; 238127668Sbms caplen -= archdrlen; 239127668Sbms p += archdrlen; 240127668Sbms 241127668Sbms if (!arcnet_encap_print(arc_type, p, length, caplen)) 24298524Sfenner default_print(p, caplen); 24398524Sfenner 244127668Sbms return (archdrlen); 24598524Sfenner} 24698524Sfenner 24798524Sfenner/* 24898524Sfenner * Prints the packet encapsulated in an ARCnet data field, 24998524Sfenner * given the ARCnet system code. 25098524Sfenner * 25198524Sfenner * Returns non-zero if it can do so, zero if the system code is unknown. 25298524Sfenner */ 25398524Sfenner 25498524Sfenner 255127668Sbmsstatic int 25698524Sfennerarcnet_encap_print(u_char arctype, const u_char *p, 25798524Sfenner u_int length, u_int caplen) 25898524Sfenner{ 25998524Sfenner switch (arctype) { 26098524Sfenner 26198524Sfenner case ARCTYPE_IP_OLD: 26298524Sfenner case ARCTYPE_IP: 263146773Ssam ip_print(gndo, p, length); 26498524Sfenner return (1); 26598524Sfenner 26698524Sfenner#ifdef INET6 26798524Sfenner case ARCTYPE_INET6: 268235530Sdelphij ip6_print(gndo, p, length); 26998524Sfenner return (1); 27098524Sfenner#endif /*INET6*/ 27198524Sfenner 27298524Sfenner case ARCTYPE_ARP_OLD: 27398524Sfenner case ARCTYPE_ARP: 27498524Sfenner case ARCTYPE_REVARP: 275235530Sdelphij arp_print(gndo, p, length, caplen); 27698524Sfenner return (1); 27798524Sfenner 27898524Sfenner case ARCTYPE_ATALK: /* XXX was this ever used? */ 27998524Sfenner if (vflag) 28098524Sfenner fputs("et1 ", stdout); 28198524Sfenner atalk_print(p, length); 28298524Sfenner return (1); 28398524Sfenner 284127668Sbms case ARCTYPE_IPX: 285127668Sbms ipx_print(p, length); 286127668Sbms return (1); 287127668Sbms 28898524Sfenner default: 28998524Sfenner return (0); 29098524Sfenner } 29198524Sfenner} 292146773Ssam 293146773Ssam/* 294146773Ssam * Local Variables: 295146773Ssam * c-style: bsd 296146773Ssam * End: 297146773Ssam */ 298146773Ssam 299