Bring in efibootmgr(8) from FreeBSD.
[dragonfly.git] / contrib / tcpdump / print-tipc.c
1 /*
2  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  */
21
22 /* \summary: Transparent Inter-Process Communication (TIPC) protocol printer */
23
24 /*
25  * specification:
26  *      http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html
27  *      http://tipc.sourceforge.net/doc/tipc_message_formats.html
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <netdissect-stdinc.h>
35
36 #include "netdissect.h"
37 #include "ether.h"
38 #include "ethertype.h"
39 #include "extract.h"
40
41 static const char tstr[] = "[|TIPC]";
42
43 #define TIPC_USER_LOW_IMPORTANCE        0
44 #define TIPC_USER_MEDIUM_IMPORTANCE     1
45 #define TIPC_USER_HIGH_IMPORTANCE       2
46 #define TIPC_USER_CRITICAL_IMPORTANCE   3
47 #define TIPC_USER_BCAST_PROTOCOL        5
48 #define TIPC_USER_MSG_BUNDLER           6
49 #define TIPC_USER_LINK_PROTOCOL         7
50 #define TIPC_USER_CONN_MANAGER          8
51 #define TIPC_USER_CHANGEOVER_PROTOCOL   10
52 #define TIPC_USER_NAME_DISTRIBUTOR      11
53 #define TIPC_USER_MSG_FRAGMENTER        12
54 #define TIPC_USER_LINK_CONFIG           13
55
56 #define TIPC_CONN_MSG                   0
57 #define TIPC_DIRECT_MSG                 1
58 #define TIPC_NAMED_MSG                  2
59 #define TIPC_MCAST_MSG                  3
60
61 #define TIPC_ZONE(addr)         (((addr) >> 24) & 0xFF)
62 #define TIPC_CLUSTER(addr)      (((addr) >> 12) & 0xFFF)
63 #define TIPC_NODE(addr)         (((addr) >> 0) & 0xFFF)
64
65 struct tipc_pkthdr {
66         uint32_t w0;
67         uint32_t w1;
68 };
69
70 #define TIPC_VER(w0)            (((w0) >> 29) & 0x07)
71 #define TIPC_USER(w0)           (((w0) >> 25) & 0x0F)
72 #define TIPC_HSIZE(w0)          (((w0) >> 21) & 0x0F)
73 #define TIPC_MSIZE(w0)          (((w0) >> 0) & 0xFFFF)
74 #define TIPC_MTYPE(w1)          (((w1) >> 29) & 0x07)
75 #define TIPC_BROADCAST_ACK(w1)  (((w1) >> 0) & 0xFFFF)
76 #define TIPC_LINK_ACK(w2)       (((w2) >> 16) & 0xFFFF)
77 #define TIPC_LINK_SEQ(w2)       (((w2) >> 0) & 0xFFFF)
78
79 static const struct tok tipcuser_values[] = {
80     { TIPC_USER_LOW_IMPORTANCE,      "Low Importance Data payload" },
81     { TIPC_USER_MEDIUM_IMPORTANCE,   "Medium Importance Data payload" },
82     { TIPC_USER_HIGH_IMPORTANCE,     "High Importance Data payload" },
83     { TIPC_USER_CRITICAL_IMPORTANCE, "Critical Importance Data payload" },
84     { TIPC_USER_BCAST_PROTOCOL,      "Broadcast Link Protocol internal" },
85     { TIPC_USER_MSG_BUNDLER,         "Message Bundler Protocol internal" },
86     { TIPC_USER_LINK_PROTOCOL,       "Link State Protocol internal" },
87     { TIPC_USER_CONN_MANAGER,        "Connection Manager internal" },
88     { TIPC_USER_CHANGEOVER_PROTOCOL, "Link Changeover Protocol internal" },
89     { TIPC_USER_NAME_DISTRIBUTOR,    "Name Table Update Protocol internal" },
90     { TIPC_USER_MSG_FRAGMENTER,      "Message Fragmentation Protocol internal" },
91     { TIPC_USER_LINK_CONFIG,         "Neighbor Detection Protocol internal" },
92     { 0, NULL }
93 };
94
95 static const struct tok tipcmtype_values[] = {
96     { TIPC_CONN_MSG,   "CONN_MSG" },
97     { TIPC_DIRECT_MSG, "MCAST_MSG" },
98     { TIPC_NAMED_MSG,  "NAMED_MSG" },
99     { TIPC_MCAST_MSG,  "DIRECT_MSG" },
100     { 0, NULL }
101 };
102
103 static const struct tok tipc_linkconf_mtype_values[] = {
104     { 0,   "Link request" },
105     { 1,   "Link response" },
106     { 0, NULL }
107 };
108
109 struct payload_tipc_pkthdr {
110         uint32_t w0;
111         uint32_t w1;
112         uint32_t w2;
113         uint32_t prev_node;
114         uint32_t orig_port;
115         uint32_t dest_port;
116         uint32_t orig_node;
117         uint32_t dest_node;
118         uint32_t name_type;
119         uint32_t w9;
120         uint32_t wA;
121 };
122
123 struct  internal_tipc_pkthdr {
124         uint32_t w0;
125         uint32_t w1;
126         uint32_t w2;
127         uint32_t prev_node;
128         uint32_t w4;
129         uint32_t w5;
130         uint32_t orig_node;
131         uint32_t dest_node;
132         uint32_t trans_seq;
133         uint32_t w9;
134 };
135
136 #define TIPC_SEQ_GAP(w1)        (((w1) >> 16) & 0x1FFF)
137 #define TIPC_BC_GAP_AFTER(w2)   (((w2) >> 16) & 0xFFFF)
138 #define TIPC_BC_GAP_TO(w2)      (((w2) >> 0) & 0xFFFF)
139 #define TIPC_LAST_SENT_FRAG(w4) (((w4) >> 16) & 0xFFFF)
140 #define TIPC_NEXT_SENT_FRAG(w4) (((w4) >> 0) & 0xFFFF)
141 #define TIPC_SESS_NO(w5)        (((w5) >> 16) & 0xFFFF)
142 #define TIPC_MSG_CNT(w9)        (((w9) >> 16) & 0xFFFF)
143 #define TIPC_LINK_TOL(w9)       (((w9) >> 0) & 0xFFFF)
144
145 struct link_conf_tipc_pkthdr {
146         uint32_t w0;
147         uint32_t w1;
148         uint32_t dest_domain;
149         uint32_t prev_node;
150         uint32_t ntwrk_id;
151         uint32_t w5;
152         uint8_t media_address[16];
153 };
154
155 #define TIPC_NODE_SIG(w1)       (((w1) >> 0) & 0xFFFF)
156 #define TIPC_MEDIA_ID(w5)       (((w5) >> 0) & 0xFF)
157
158 static void
159 print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap)
160 {
161         uint32_t w0, w1, w2;
162         u_int user;
163         u_int hsize;
164         u_int msize;
165         u_int mtype;
166         u_int broadcast_ack;
167         u_int link_ack;
168         u_int link_seq;
169         u_int prev_node;
170         u_int orig_port;
171         u_int dest_port;
172         u_int orig_node;
173         u_int dest_node;
174
175         ND_TCHECK(ap->dest_port);
176         w0 = EXTRACT_32BITS(&ap->w0);
177         user = TIPC_USER(w0);
178         hsize = TIPC_HSIZE(w0);
179         msize = TIPC_MSIZE(w0);
180         w1 = EXTRACT_32BITS(&ap->w1);
181         mtype = TIPC_MTYPE(w1);
182         prev_node = EXTRACT_32BITS(&ap->prev_node);
183         orig_port = EXTRACT_32BITS(&ap->orig_port);
184         dest_port = EXTRACT_32BITS(&ap->dest_port);
185         if (hsize <= 6) {
186                 ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
187                     TIPC_VER(w0),
188                     TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
189                     orig_port, dest_port,
190                     hsize*4, msize,
191                     tok2str(tipcuser_values, "unknown", user),
192                     tok2str(tipcmtype_values, "Unknown", mtype)));
193         } else {
194                 ND_TCHECK(ap->dest_node);
195                 orig_node = EXTRACT_32BITS(&ap->orig_node);
196                 dest_node = EXTRACT_32BITS(&ap->dest_node);
197                 ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
198                     TIPC_VER(w0),
199                     TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
200                     orig_port,
201                     TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
202                     dest_port,
203                     hsize*4, msize,
204                     tok2str(tipcuser_values, "unknown", user),
205                     tok2str(tipcmtype_values, "Unknown", mtype)));
206
207                 if (ndo->ndo_vflag) {
208                         broadcast_ack = TIPC_BROADCAST_ACK(w1);
209                         w2 = EXTRACT_32BITS(&ap->w2);
210                         link_ack = TIPC_LINK_ACK(w2);
211                         link_seq = TIPC_LINK_SEQ(w2);
212                         ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u",
213                             TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
214                             broadcast_ack, link_ack, link_seq));
215                 }
216         }
217         return;
218
219 trunc:
220         ND_PRINT((ndo, "%s", tstr));
221 }
222
223 static void
224 print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap)
225 {
226         uint32_t w0, w1, w2, w4, w5, w9;
227         u_int user;
228         u_int hsize;
229         u_int msize;
230         u_int mtype;
231         u_int seq_gap;
232         u_int broadcast_ack;
233         u_int bc_gap_after;
234         u_int bc_gap_to;
235         u_int prev_node;
236         u_int last_sent_frag;
237         u_int next_sent_frag;
238         u_int sess_no;
239         u_int orig_node;
240         u_int dest_node;
241         u_int trans_seq;
242         u_int msg_cnt;
243         u_int link_tol;
244
245         ND_TCHECK(ap->dest_node);
246         w0 = EXTRACT_32BITS(&ap->w0);
247         user = TIPC_USER(w0);
248         hsize = TIPC_HSIZE(w0);
249         msize = TIPC_MSIZE(w0);
250         w1 = EXTRACT_32BITS(&ap->w1);
251         mtype = TIPC_MTYPE(w1);
252         orig_node = EXTRACT_32BITS(&ap->orig_node);
253         dest_node = EXTRACT_32BITS(&ap->dest_node);
254         ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)",
255             TIPC_VER(w0),
256             TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
257             TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
258             hsize*4, msize,
259             tok2str(tipcuser_values, "unknown", user),
260             tok2str(tipcmtype_values, "Unknown", mtype), w1));
261
262         if (ndo->ndo_vflag) {
263                 ND_TCHECK(*ap);
264                 seq_gap = TIPC_SEQ_GAP(w1);
265                 broadcast_ack = TIPC_BROADCAST_ACK(w1);
266                 w2 = EXTRACT_32BITS(&ap->w2);
267                 bc_gap_after = TIPC_BC_GAP_AFTER(w2);
268                 bc_gap_to = TIPC_BC_GAP_TO(w2);
269                 prev_node = EXTRACT_32BITS(&ap->prev_node);
270                 w4 = EXTRACT_32BITS(&ap->w4);
271                 last_sent_frag = TIPC_LAST_SENT_FRAG(w4);
272                 next_sent_frag = TIPC_NEXT_SENT_FRAG(w4);
273                 w5 = EXTRACT_32BITS(&ap->w5);
274                 sess_no = TIPC_SESS_NO(w5);
275                 trans_seq = EXTRACT_32BITS(&ap->trans_seq);
276                 w9 = EXTRACT_32BITS(&ap->w9);
277                 msg_cnt = TIPC_MSG_CNT(w9);
278                 link_tol = TIPC_LINK_TOL(w9);
279                 ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u,  Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u",
280                     TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
281                     sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to,
282                     last_sent_frag, next_sent_frag, trans_seq, msg_cnt,
283                     link_tol));
284         }
285         return;
286
287 trunc:
288         ND_PRINT((ndo, "%s", tstr));
289 }
290
291 static void
292 print_link_conf(netdissect_options *ndo, const struct link_conf_tipc_pkthdr *ap)
293 {
294         uint32_t w0, w1, w5;
295         u_int user;
296         u_int hsize;
297         u_int msize;
298         u_int mtype;
299         u_int node_sig;
300         u_int prev_node;
301         u_int dest_domain;
302         u_int ntwrk_id;
303         u_int media_id;
304
305         ND_TCHECK(ap->prev_node);
306         w0 = EXTRACT_32BITS(&ap->w0);
307         user = TIPC_USER(w0);
308         hsize = TIPC_HSIZE(w0);
309         msize = TIPC_MSIZE(w0);
310         w1 = EXTRACT_32BITS(&ap->w1);
311         mtype = TIPC_MTYPE(w1);
312         dest_domain = EXTRACT_32BITS(&ap->dest_domain);
313         prev_node = EXTRACT_32BITS(&ap->prev_node);
314
315         ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
316             TIPC_VER(w0),
317             TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
318             TIPC_ZONE(dest_domain), TIPC_CLUSTER(dest_domain), TIPC_NODE(dest_domain),
319             hsize*4, msize,
320             tok2str(tipcuser_values, "unknown", user),
321             tok2str(tipc_linkconf_mtype_values, "Unknown", mtype)));
322         if (ndo->ndo_vflag) {
323                 ND_TCHECK(ap->w5);
324                 node_sig = TIPC_NODE_SIG(w1);
325                 ntwrk_id = EXTRACT_32BITS(&ap->ntwrk_id);
326                 w5 = EXTRACT_32BITS(&ap->w5);
327                 media_id = TIPC_MEDIA_ID(w5);
328                 ND_PRINT((ndo, "\n\tNodeSignature %u, network_id %u, media_id %u",
329                     node_sig, ntwrk_id, media_id));
330         }
331         return;
332
333 trunc:
334         ND_PRINT((ndo, "%s", tstr));
335 }
336
337 void
338 tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_,
339     u_int caplen _U_)
340 {
341         const struct tipc_pkthdr *ap;
342         uint32_t w0;
343         u_int user;
344
345         ap = (const struct tipc_pkthdr *)bp;
346         ND_TCHECK(ap->w0);
347         w0 = EXTRACT_32BITS(&ap->w0);
348         user = TIPC_USER(w0);
349
350         switch (user)
351         {
352                 case TIPC_USER_LOW_IMPORTANCE:
353                 case TIPC_USER_MEDIUM_IMPORTANCE:
354                 case TIPC_USER_HIGH_IMPORTANCE:
355                 case TIPC_USER_CRITICAL_IMPORTANCE:
356                 case TIPC_USER_NAME_DISTRIBUTOR:
357                 case TIPC_USER_CONN_MANAGER:
358                         print_payload(ndo, (const struct payload_tipc_pkthdr *)bp);
359                         break;
360
361                 case TIPC_USER_LINK_CONFIG:
362                         print_link_conf(ndo, (const struct link_conf_tipc_pkthdr *)bp);
363                         break;
364
365                 case TIPC_USER_BCAST_PROTOCOL:
366                 case TIPC_USER_MSG_BUNDLER:
367                 case TIPC_USER_LINK_PROTOCOL:
368                 case TIPC_USER_CHANGEOVER_PROTOCOL:
369                 case TIPC_USER_MSG_FRAGMENTER:
370                         print_internal(ndo, (const struct internal_tipc_pkthdr *)bp);
371                         break;
372
373         }
374         return;
375
376 trunc:
377         ND_PRINT((ndo, "%s", tstr));
378 }
379
380 /*
381  * Local Variables:
382  * c-style: bsd
383  * End:
384  */
385