1119895Sanholt/*
2152909Sanholt * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3152909Sanholt *	The Regents of the University of California.  All rights reserved.
4139749Simp *
5119895Sanholt * Redistribution and use in source and binary forms, with or without
6119895Sanholt * modification, are permitted provided that: (1) source code distributions
7119895Sanholt * retain the above copyright notice and this paragraph in its entirety, (2)
8119895Sanholt * distributions including binary code include the above copyright notice and
9119895Sanholt * this paragraph in its entirety in the documentation or other materials
10119895Sanholt * provided with the distribution, and (3) all advertising materials mentioning
11119895Sanholt * features or use of this software display the following acknowledgement:
12119895Sanholt * ``This product includes software developed by the University of California,
13119895Sanholt * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14145132Sanholt * the University nor the names of its contributors may be used to endorse
15119895Sanholt * or promote products derived from this software without specific prior
16119895Sanholt * written permission.
17119895Sanholt * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18145132Sanholt * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19119895Sanholt * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20119895Sanholt */
21119895Sanholt#ifndef lint
22119895Sanholtstatic const char rcsid[] _U_ =
23119895Sanholt    "@(#) $Header: /tcpdump/master/tcpdump/print-ap1394.c,v 1.5 2006-02-11 22:12:06 hannes Exp $ (LBL)";
24119895Sanholt#endif
25119895Sanholt
26145132Sanholt#ifdef HAVE_CONFIG_H
27119895Sanholt#include "config.h"
28119895Sanholt#endif
29145132Sanholt
30119895Sanholt#include <tcpdump-stdinc.h>
31119895Sanholt
32152909Sanholt#include <stdio.h>
33152909Sanholt#include <pcap.h>
34152909Sanholt
35119895Sanholt#include "interface.h"
36119895Sanholt#include "extract.h"
37119895Sanholt#include "addrtoname.h"
38119895Sanholt#include "ethertype.h"
39119895Sanholt
40119895Sanholt/*
41119895Sanholt * Structure of a header for Apple's IP-over-IEEE 1384 BPF header.
42126533Sobrien */
43119895Sanholt#define FIREWIRE_EUI64_LEN	8
44119895Sanholtstruct firewire_header {
45119895Sanholt	u_char  firewire_dhost[FIREWIRE_EUI64_LEN];
46119895Sanholt	u_char  firewire_shost[FIREWIRE_EUI64_LEN];
47119895Sanholt	u_short firewire_type;
48119895Sanholt};
49119895Sanholt
50119895Sanholt/*
51119895Sanholt * Length of that header; note that some compilers may pad
52119895Sanholt * "struct firewire_header" to a multiple of 4 bytes, for example, so
53119895Sanholt * "sizeof (struct firewire_header)" may not give the right answer.
54119895Sanholt */
55119895Sanholt#define FIREWIRE_HDRLEN		18
56119895Sanholt
57145132Sanholtstatic inline void
58145132Sanholtap1394_hdr_print(register const u_char *bp, u_int length)
59145132Sanholt{
60145132Sanholt	register const struct firewire_header *fp;
61145132Sanholt	u_int16_t firewire_type;
62119895Sanholt
63119895Sanholt	fp = (const struct firewire_header *)bp;
64119895Sanholt
65145132Sanholt	(void)printf("%s > %s",
66119895Sanholt		     linkaddr_string(fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN),
67119895Sanholt		     linkaddr_string(fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN));
68119895Sanholt
69119895Sanholt	firewire_type = EXTRACT_16BITS(&fp->firewire_type);
70119895Sanholt	if (!qflag) {
71119895Sanholt		(void)printf(", ethertype %s (0x%04x)",
72119895Sanholt			       tok2str(ethertype_values,"Unknown", firewire_type),
73119895Sanholt                               firewire_type);
74119895Sanholt        } else {
75119895Sanholt                (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type));
76119895Sanholt        }
77119895Sanholt
78119895Sanholt	(void)printf(", length %u: ", length);
79119895Sanholt}
80157617Sanholt
81145132Sanholt/*
82145132Sanholt * This is the top level routine of the printer.  'p' points
83119895Sanholt * to the ether header of the packet, 'h->ts' is the timestamp,
84119895Sanholt * 'h->len' is the length of the packet off the wire, and 'h->caplen'
85119895Sanholt * is the number of bytes actually captured.
86119895Sanholt */
87119895Sanholtu_int
88119895Sanholtap1394_if_print(const struct pcap_pkthdr *h, const u_char *p)
89119895Sanholt{
90145132Sanholt	u_int length = h->len;
91119895Sanholt	u_int caplen = h->caplen;
92145132Sanholt	struct firewire_header *fp;
93145132Sanholt	u_short ether_type;
94119895Sanholt
95119895Sanholt	if (caplen < FIREWIRE_HDRLEN) {
96119895Sanholt		printf("[|ap1394]");
97119895Sanholt		return FIREWIRE_HDRLEN;
98119895Sanholt	}
99119895Sanholt
100119895Sanholt	if (eflag)
101119895Sanholt		ap1394_hdr_print(p, length);
102119895Sanholt
103119895Sanholt	length -= FIREWIRE_HDRLEN;
104119895Sanholt	caplen -= FIREWIRE_HDRLEN;
105119895Sanholt	fp = (struct firewire_header *)p;
106119895Sanholt	p += FIREWIRE_HDRLEN;
107119895Sanholt
108119895Sanholt	ether_type = EXTRACT_16BITS(&fp->firewire_type);
109119895Sanholt	if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) {
110119895Sanholt		/* ether_type not known, print raw packet */
111119895Sanholt		if (!eflag)
112119895Sanholt			ap1394_hdr_print((u_char *)fp, length + FIREWIRE_HDRLEN);
113119895Sanholt
114119895Sanholt		if (!suppress_default_print)
115119895Sanholt			default_print(p, caplen);
116145132Sanholt	}
117119895Sanholt
118119895Sanholt	return FIREWIRE_HDRLEN;
119119895Sanholt}
120145132Sanholt