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