xref: /netbsd-src/external/bsd/tcpdump/dist/print-ipoib.c (revision c41df9f6167ea7cd2f761f0a97783c8267cb8847)
1*d881c474Schristos /*
2*d881c474Schristos  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
3*d881c474Schristos  *	1997, 2000, 2011, 2012
4*d881c474Schristos  *	The Regents of the University of California.  All rights reserved.
5*d881c474Schristos  *
6*d881c474Schristos  * Redistribution and use in source and binary forms, with or without
7*d881c474Schristos  * modification, are permitted provided that: (1) source code distributions
8*d881c474Schristos  * retain the above copyright notice and this paragraph in its entirety, (2)
9*d881c474Schristos  * distributions including binary code include the above copyright notice and
10*d881c474Schristos  * this paragraph in its entirety in the documentation or other materials
11*d881c474Schristos  * provided with the distribution, and (3) all advertising materials mentioning
12*d881c474Schristos  * features or use of this software display the following acknowledgement:
13*d881c474Schristos  * ``This product includes software developed by the University of California,
14*d881c474Schristos  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15*d881c474Schristos  * the University nor the names of its contributors may be used to endorse
16*d881c474Schristos  * or promote products derived from this software without specific prior
17*d881c474Schristos  * written permission.
18*d881c474Schristos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19*d881c474Schristos  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20*d881c474Schristos  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21*d881c474Schristos  */
22*d881c474Schristos /*
23*d881c474Schristos  * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
24*d881c474Schristos  */
25*d881c474Schristos 
26*d881c474Schristos /* \summary: IP-over-InfiniBand (IPoIB) printer */
27*d881c474Schristos 
28*d881c474Schristos #include <config.h>
29*d881c474Schristos 
30*d881c474Schristos #include "netdissect-stdinc.h"
31*d881c474Schristos 
32*d881c474Schristos #include "netdissect.h"
33*d881c474Schristos #include "extract.h"
34*d881c474Schristos #include "addrtoname.h"
35*d881c474Schristos 
36*d881c474Schristos 
37*d881c474Schristos extern const struct tok ethertype_values[];
38*d881c474Schristos 
39*d881c474Schristos #define	IPOIB_HDRLEN	44
40*d881c474Schristos 
41*d881c474Schristos static inline void
42*d881c474Schristos ipoib_hdr_print(netdissect_options *ndo, const u_char *bp, u_int length)
43*d881c474Schristos {
44*d881c474Schristos 	uint16_t ether_type;
45*d881c474Schristos 
46*d881c474Schristos 	ether_type = GET_BE_U_2(bp + 40);
47*d881c474Schristos 	if (!ndo->ndo_qflag) {
48*d881c474Schristos 		ND_PRINT(", ethertype %s (0x%04x)",
49*d881c474Schristos 			     tok2str(ethertype_values,"Unknown", ether_type),
50*d881c474Schristos 			     ether_type);
51*d881c474Schristos 	} else {
52*d881c474Schristos 		ND_PRINT(", ethertype %s",
53*d881c474Schristos 			     tok2str(ethertype_values,"Unknown", ether_type));
54*d881c474Schristos 	}
55*d881c474Schristos 
56*d881c474Schristos 	ND_PRINT(", length %u: ", length);
57*d881c474Schristos }
58*d881c474Schristos 
59*d881c474Schristos /*
60*d881c474Schristos  * Print an InfiniBand frame.
61*d881c474Schristos  * This might be encapsulated within another frame; we might be passed
62*d881c474Schristos  * a pointer to a function that can print header information for that
63*d881c474Schristos  * frame's protocol, and an argument to pass to that function.
64*d881c474Schristos  */
65*d881c474Schristos static void
66*d881c474Schristos ipoib_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
67*d881c474Schristos     void (*print_encap_header)(const u_char *), const u_char *encap_header_arg)
68*d881c474Schristos {
69*d881c474Schristos 	const u_char *orig_hdr = p;
70*d881c474Schristos 	u_int orig_length;
71*d881c474Schristos 	u_short ether_type;
72*d881c474Schristos 
73*d881c474Schristos 	if (caplen < IPOIB_HDRLEN) {
74*d881c474Schristos 		nd_print_trunc(ndo);
75*d881c474Schristos 		ndo->ndo_ll_hdr_len += caplen;
76*d881c474Schristos 		return;
77*d881c474Schristos 	}
78*d881c474Schristos 
79*d881c474Schristos 	if (length < IPOIB_HDRLEN) {
80*d881c474Schristos 		nd_print_trunc(ndo);
81*d881c474Schristos 		ndo->ndo_ll_hdr_len += length;
82*d881c474Schristos 		return;
83*d881c474Schristos 	}
84*d881c474Schristos 
85*d881c474Schristos 	if (ndo->ndo_eflag) {
86*d881c474Schristos 		nd_print_protocol_caps(ndo);
87*d881c474Schristos 		if (print_encap_header != NULL)
88*d881c474Schristos 			(*print_encap_header)(encap_header_arg);
89*d881c474Schristos 		ipoib_hdr_print(ndo, p, length);
90*d881c474Schristos 	}
91*d881c474Schristos 	orig_length = length;
92*d881c474Schristos 
93*d881c474Schristos 	ndo->ndo_ll_hdr_len += IPOIB_HDRLEN;
94*d881c474Schristos 	length -= IPOIB_HDRLEN;
95*d881c474Schristos 	caplen -= IPOIB_HDRLEN;
96*d881c474Schristos 	ether_type = GET_BE_U_2(p + 40);
97*d881c474Schristos 	p += IPOIB_HDRLEN;
98*d881c474Schristos 
99*d881c474Schristos 	if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
100*d881c474Schristos 		/* ether_type not known, print raw packet */
101*d881c474Schristos 		if (!ndo->ndo_eflag) {
102*d881c474Schristos 			if (print_encap_header != NULL)
103*d881c474Schristos 				(*print_encap_header)(encap_header_arg);
104*d881c474Schristos 			ipoib_hdr_print(ndo, orig_hdr , orig_length);
105*d881c474Schristos 		}
106*d881c474Schristos 
107*d881c474Schristos 		if (!ndo->ndo_suppress_default_print)
108*d881c474Schristos 			ND_DEFAULTPRINT(p, caplen);
109*d881c474Schristos 	}
110*d881c474Schristos }
111*d881c474Schristos 
112*d881c474Schristos /*
113*d881c474Schristos  * This is the top level routine of the printer.  'p' points
114*d881c474Schristos  * to the ether header of the packet, 'h->ts' is the timestamp,
115*d881c474Schristos  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
116*d881c474Schristos  * is the number of bytes actually captured.
117*d881c474Schristos  */
118*d881c474Schristos void
119*d881c474Schristos ipoib_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
120*d881c474Schristos {
121*d881c474Schristos 	ndo->ndo_protocol = "ipoib";
122*d881c474Schristos 	ipoib_print(ndo, p, h->len, h->caplen, NULL, NULL);
123*d881c474Schristos }
124