2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that: (1) source code
4 * distributions retain the above copyright notice and this paragraph
5 * in its entirety, and (2) distributions including binary code include
6 * the above copyright notice and this paragraph in its entirety in
7 * the documentation or other materials provided with the distribution.
8 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE.
13 * Original code by Hannes Gredler (hannes@juniper.net)
17 static const char rcsid
[] _U_
=
18 "@(#) $Header: /tcpdump/master/tcpdump/print-lmp.c,v 1.1 2004-04-19 21:17:13 hannes Exp $";
25 #include <tcpdump-stdinc.h>
31 #include "interface.h"
33 #include "addrtoname.h"
39 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | Vers | (Reserved) | Flags | Msg Type |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * | LMP Length | (Reserved) |
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 struct lmp_common_header
{
48 u_int8_t version_res
[2];
56 #define LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
58 static const struct tok lmp_header_flag_values
[] = {
59 { 0x00, "Control Channel Down"},
60 { 0x02, "LMP restart"},
64 #define LMP_MSGTYPE_CONFIG 1
65 #define LMP_MSGTYPE_CONFIG_ACK 2
66 #define LMP_MSGTYPE_CONFIG_NACK 3
67 #define LMP_MSGTYPE_HELLO 4
68 #define LMP_MSGTYPE_VERIFY_BEGIN 5
69 #define LMP_MSGTYPE_VERIFY_BEGIN_ACK 6
70 #define LMP_MSGTYPE_VERIFY_BEGIN_NACK 7
71 #define LMP_MSGTYPE_VERIFY_END 8
72 #define LMP_MSGTYPE_VERIFY_END_ACK 9
73 #define LMP_MSGTYPE_TEST 10
74 #define LMP_MSGTYPE_TEST_STATUS_SUCCESS 11
75 #define LMP_MSGTYPE_TEST_STATUS_FAILURE 12
76 #define LMP_MSGTYPE_TEST_STATUS_ACK 13
77 #define LMP_MSGTYPE_LINK_SUMMARY 14
78 #define LMP_MSGTYPE_LINK_SUMMARY_ACK 15
79 #define LMP_MSGTYPE_LINK_SUMMARY_NACK 16
80 #define LMP_MSGTYPE_CHANNEL_STATUS 17
81 #define LMP_MSGTYPE_CHANNEL_STATUS_ACK 18
82 #define LMP_MSGTYPE_CHANNEL_STATUS_REQ 19
83 #define LMP_MSGTYPE_CHANNEL_STATUS_RESP 20
85 static const struct tok lmp_msg_type_values
[] = {
86 { LMP_MSGTYPE_CONFIG
, "Config"},
87 { LMP_MSGTYPE_CONFIG_ACK
, "Config ACK"},
88 { LMP_MSGTYPE_CONFIG_NACK
, "Config NACK"},
89 { LMP_MSGTYPE_HELLO
, "Hello"},
90 { LMP_MSGTYPE_VERIFY_BEGIN
, "Begin Verify"},
91 { LMP_MSGTYPE_VERIFY_BEGIN_ACK
, "Begin Verify ACK"},
92 { LMP_MSGTYPE_VERIFY_BEGIN_NACK
, "Begin Verify NACK"},
93 { LMP_MSGTYPE_VERIFY_END
, "End Verify"},
94 { LMP_MSGTYPE_VERIFY_END_ACK
, "End Verify ACK"},
95 { LMP_MSGTYPE_TEST
, "Test"},
96 { LMP_MSGTYPE_TEST_STATUS_SUCCESS
, "Test Status Success"},
97 { LMP_MSGTYPE_TEST_STATUS_FAILURE
, "Test Status Failure"},
98 { LMP_MSGTYPE_TEST_STATUS_ACK
, "Test Status ACK"},
99 { LMP_MSGTYPE_LINK_SUMMARY
, "Link Summary"},
100 { LMP_MSGTYPE_LINK_SUMMARY_ACK
, "Link Summary ACK"},
101 { LMP_MSGTYPE_LINK_SUMMARY_NACK
, "Link Summary NACK"},
102 { LMP_MSGTYPE_CHANNEL_STATUS
, "Channel Status"},
103 { LMP_MSGTYPE_CHANNEL_STATUS_ACK
, "Channel Status ACK"},
104 { LMP_MSGTYPE_CHANNEL_STATUS_REQ
, "Channel Status Request"},
105 { LMP_MSGTYPE_CHANNEL_STATUS_RESP
, "Channel Status Response"},
113 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
114 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115 * |N| C-Type | Class | Length |
116 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118 * // (object contents) //
120 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123 struct lmp_object_header
{
129 #define LMP_OBJ_CC_ID 1
130 #define LMP_OBJ_NODE_ID 2
131 #define LMP_OBJ_LINK_ID 3
132 #define LMP_OBJ_INTERFACE_ID 4
133 #define LMP_OBJ_MESSAGE_ID 5
134 #define LMP_OBJ_CONFIG 6
135 #define LMP_OBJ_HELLO 7
136 #define LMP_OBJ_VERIFY_BEGIN 8
137 #define LMP_OBJ_VERIFY_BEGIN_ACK 9
138 #define LMP_OBJ_VERIFY_ID 10
139 #define LMP_OBJ_TE_LINK 11
140 #define LMP_OBJ_DATA_LINK 12
141 #define LMP_OBJ_CHANNEL_STATUS 13
142 #define LMP_OBJ_CHANNEL_STATUS_REQ 14
143 #define LMP_OBJ_ERROR_CODE 15
145 static const struct tok lmp_obj_values
[] = {
146 { LMP_OBJ_CC_ID
, "Control Channel ID" },
147 { LMP_OBJ_NODE_ID
, "Node ID" },
148 { LMP_OBJ_LINK_ID
, "Link ID" },
149 { LMP_OBJ_INTERFACE_ID
, "Interface ID" },
150 { LMP_OBJ_MESSAGE_ID
, "Message ID" },
151 { LMP_OBJ_CONFIG
, "Configuration" },
152 { LMP_OBJ_HELLO
, "Hello" },
153 { LMP_OBJ_VERIFY_BEGIN
, "Verify Begin" },
154 { LMP_OBJ_VERIFY_BEGIN_ACK
, "Verify Begin ACK" },
155 { LMP_OBJ_VERIFY_ID
, "Verify ID" },
156 { LMP_OBJ_TE_LINK
, "TE Link" },
157 { LMP_OBJ_DATA_LINK
, "Data Link" },
158 { LMP_OBJ_CHANNEL_STATUS
, "Channel Status" },
159 { LMP_OBJ_CHANNEL_STATUS_REQ
, "Channel Status Request" },
160 { LMP_OBJ_ERROR_CODE
, "Error Code" },
164 #define LMP_CTYPE_IPV4 1
165 #define LMP_CTYPE_IPV6 2
167 #define LMP_CTYPE_LOC 1
168 #define LMP_CTYPE_RMT 2
169 #define LMP_CTYPE_UNMD 3
171 #define LMP_CTYPE_IPV4_LOC 1
172 #define LMP_CTYPE_IPV4_RMT 2
173 #define LMP_CTYPE_IPV6_LOC 3
174 #define LMP_CTYPE_IPV6_RMT 4
175 #define LMP_CTYPE_UNMD_LOC 5
176 #define LMP_CTYPE_UNMD_RMT 6
178 #define LMP_CTYPE_1 1
179 #define LMP_CTYPE_2 2
185 * the ctypes are not globally unique so for
186 * translating it to strings we build a table based
187 * on objects offsetted by the ctype
190 static const struct tok lmp_ctype_values
[] = {
191 { 256*LMP_OBJ_CC_ID
+LMP_CTYPE_LOC
, "Local" },
192 { 256*LMP_OBJ_CC_ID
+LMP_CTYPE_RMT
, "Remote" },
193 { 256*LMP_OBJ_NODE_ID
+LMP_CTYPE_LOC
, "Local" },
194 { 256*LMP_OBJ_NODE_ID
+LMP_CTYPE_RMT
, "Remote" },
195 { 256*LMP_OBJ_LINK_ID
+LMP_CTYPE_IPV4_LOC
, "IPv4 Local" },
196 { 256*LMP_OBJ_LINK_ID
+LMP_CTYPE_IPV4_RMT
, "IPv4 Remote" },
197 { 256*LMP_OBJ_LINK_ID
+LMP_CTYPE_IPV6_LOC
, "IPv6 Local" },
198 { 256*LMP_OBJ_LINK_ID
+LMP_CTYPE_IPV6_RMT
, "IPv6 Remote" },
199 { 256*LMP_OBJ_LINK_ID
+LMP_CTYPE_UNMD_LOC
, "Unnumbered Local" },
200 { 256*LMP_OBJ_LINK_ID
+LMP_CTYPE_UNMD_RMT
, "Unnumbered Remote" },
201 { 256*LMP_OBJ_INTERFACE_ID
+LMP_CTYPE_IPV4_LOC
, "IPv4 Local" },
202 { 256*LMP_OBJ_INTERFACE_ID
+LMP_CTYPE_IPV4_RMT
, "IPv4 Remote" },
203 { 256*LMP_OBJ_INTERFACE_ID
+LMP_CTYPE_IPV6_LOC
, "IPv6 Local" },
204 { 256*LMP_OBJ_INTERFACE_ID
+LMP_CTYPE_IPV6_RMT
, "IPv6 Remote" },
205 { 256*LMP_OBJ_INTERFACE_ID
+LMP_CTYPE_UNMD_LOC
, "Unnumbered Local" },
206 { 256*LMP_OBJ_INTERFACE_ID
+LMP_CTYPE_UNMD_RMT
, "Unnumbered Remote" },
207 { 256*LMP_OBJ_MESSAGE_ID
+LMP_CTYPE_1
, "1" },
208 { 256*LMP_OBJ_MESSAGE_ID
+LMP_CTYPE_2
, "2" },
209 { 256*LMP_OBJ_CONFIG
+LMP_CTYPE_1
, "1" },
210 { 256*LMP_OBJ_HELLO
+LMP_CTYPE_1
, "1" },
211 { 256*LMP_OBJ_VERIFY_BEGIN
+LMP_CTYPE_1
, "1" },
212 { 256*LMP_OBJ_VERIFY_BEGIN_ACK
+LMP_CTYPE_1
, "1" },
213 { 256*LMP_OBJ_VERIFY_ID
+LMP_CTYPE_1
, "1" },
214 { 256*LMP_OBJ_TE_LINK
+LMP_CTYPE_IPV4
, "IPv4" },
215 { 256*LMP_OBJ_TE_LINK
+LMP_CTYPE_IPV6
, "IPv6" },
216 { 256*LMP_OBJ_TE_LINK
+LMP_CTYPE_UNMD
, "Unnumbered" },
217 { 256*LMP_OBJ_DATA_LINK
+LMP_CTYPE_IPV4
, "IPv4" },
218 { 256*LMP_OBJ_DATA_LINK
+LMP_CTYPE_IPV6
, "IPv6" },
219 { 256*LMP_OBJ_DATA_LINK
+LMP_CTYPE_UNMD
, "Unnumbered" },
220 { 256*LMP_OBJ_CHANNEL_STATUS
+LMP_CTYPE_IPV4
, "IPv4" },
221 { 256*LMP_OBJ_CHANNEL_STATUS
+LMP_CTYPE_IPV6
, "IPv6" },
222 { 256*LMP_OBJ_CHANNEL_STATUS
+LMP_CTYPE_UNMD
, "Unnumbered" },
223 { 256*LMP_OBJ_CHANNEL_STATUS_REQ
+LMP_CTYPE_IPV4
, "IPv4" },
224 { 256*LMP_OBJ_CHANNEL_STATUS_REQ
+LMP_CTYPE_IPV6
, "IPv6" },
225 { 256*LMP_OBJ_CHANNEL_STATUS_REQ
+LMP_CTYPE_UNMD
, "Unnumbered" },
226 { 256*LMP_OBJ_ERROR_CODE
+LMP_CTYPE_1
, "1" },
227 { 256*LMP_OBJ_ERROR_CODE
+LMP_CTYPE_2
, "2" },
232 lmp_print(register const u_char
*pptr
, register u_int len
) {
234 const struct lmp_common_header
*lmp_com_header
;
235 const struct lmp_object_header
*lmp_obj_header
;
236 const u_char
*tptr
,*obj_tptr
;
237 u_short tlen
,lmp_obj_len
,lmp_obj_ctype
,obj_tlen
;
241 lmp_com_header
= (const struct lmp_common_header
*)pptr
;
242 TCHECK(*lmp_com_header
);
245 * Sanity checking of the header.
247 if (LMP_EXTRACT_VERSION(lmp_com_header
->version_res
[0]) != LMP_VERSION
) {
248 printf("LMP version %u packet not supported",
249 LMP_EXTRACT_VERSION(lmp_com_header
->version_res
[0]));
253 /* in non-verbose mode just lets print the basic Message Type*/
255 printf("LMPv%u %s Message, length: %u",
256 LMP_EXTRACT_VERSION(lmp_com_header
->version_res
[0]),
257 tok2str(lmp_msg_type_values
, "unknown (%u)",lmp_com_header
->msg_type
),
262 /* ok they seem to want to know everything - lets fully decode it */
264 tlen
=EXTRACT_16BITS(lmp_com_header
->length
);
266 printf("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u",
267 LMP_EXTRACT_VERSION(lmp_com_header
->version_res
[0]),
268 tok2str(lmp_msg_type_values
, "unknown, type: %u",lmp_com_header
->msg_type
),
269 bittok2str(lmp_header_flag_values
,"none",lmp_com_header
->flags
),
272 tptr
+=sizeof(const struct lmp_common_header
);
273 tlen
-=sizeof(const struct lmp_common_header
);
276 /* did we capture enough for fully decoding the object header ? */
277 if (!TTEST2(*tptr
, sizeof(struct lmp_object_header
)))
280 lmp_obj_header
= (const struct lmp_object_header
*)tptr
;
281 lmp_obj_len
=EXTRACT_16BITS(lmp_obj_header
->length
);
282 lmp_obj_ctype
=(lmp_obj_header
->ctype
)&0x7f;
284 if(lmp_obj_len
% 4 || lmp_obj_len
< 4)
287 printf("\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
288 tok2str(lmp_obj_values
,
290 lmp_obj_header
->class_num
),
291 lmp_obj_header
->class_num
,
292 tok2str(lmp_ctype_values
,
294 ((lmp_obj_header
->class_num
)<<8)+lmp_obj_ctype
),
296 (lmp_obj_header
->ctype
)&0x80 ? "" : "non-",
299 obj_tptr
=tptr
+sizeof(struct lmp_object_header
);
300 obj_tlen
=lmp_obj_len
-sizeof(struct lmp_object_header
);
302 /* did we capture enough for fully decoding the object ? */
303 if (!TTEST2(*tptr
, lmp_obj_len
))
307 switch(lmp_obj_header
->class_num
) {
310 switch(lmp_obj_ctype
) {
313 printf("\n\t Control Channel ID: %u (0x%08x)",
314 EXTRACT_32BITS(obj_tptr
),
315 EXTRACT_32BITS(obj_tptr
));
323 case LMP_OBJ_LINK_ID
:
324 case LMP_OBJ_INTERFACE_ID
:
325 switch(lmp_obj_ctype
) {
326 case LMP_CTYPE_IPV4_LOC
:
327 case LMP_CTYPE_IPV4_RMT
:
328 printf("\n\t IPv4 Link ID: %s (0x%08x)",
329 ipaddr_string(obj_tptr
),
330 EXTRACT_32BITS(obj_tptr
));
333 case LMP_CTYPE_IPV6_LOC
:
334 case LMP_CTYPE_IPV6_RMT
:
335 printf("\n\t IPv6 Link ID: %s (0x%08x)",
336 ip6addr_string(obj_tptr
),
337 EXTRACT_32BITS(obj_tptr
));
340 case LMP_CTYPE_UNMD_LOC
:
341 case LMP_CTYPE_UNMD_RMT
:
342 printf("\n\t Link ID: %u (0x%08x)",
343 EXTRACT_32BITS(obj_tptr
),
344 EXTRACT_32BITS(obj_tptr
));
351 case LMP_OBJ_MESSAGE_ID
:
352 switch(lmp_obj_ctype
) {
354 printf("\n\t Message ID: %u (0x%08x)",
355 EXTRACT_32BITS(obj_tptr
),
356 EXTRACT_32BITS(obj_tptr
));
359 printf("\n\t Message ID Ack: %u (0x%08x)",
360 EXTRACT_32BITS(obj_tptr
),
361 EXTRACT_32BITS(obj_tptr
));
368 case LMP_OBJ_NODE_ID
:
369 switch(lmp_obj_ctype
) {
372 printf("\n\t Node ID: %s (0x%08x)",
373 ipaddr_string(obj_tptr
),
374 EXTRACT_32BITS(obj_tptr
));
383 * FIXME those are the defined objects that lack a decoder
384 * you are welcome to contribute code ;-)
389 case LMP_OBJ_VERIFY_BEGIN
:
390 case LMP_OBJ_VERIFY_BEGIN_ACK
:
391 case LMP_OBJ_VERIFY_ID
:
392 case LMP_OBJ_TE_LINK
:
393 case LMP_OBJ_DATA_LINK
:
394 case LMP_OBJ_CHANNEL_STATUS
:
395 case LMP_OBJ_CHANNEL_STATUS_REQ
:
396 case LMP_OBJ_ERROR_CODE
:
400 print_unknown_data(obj_tptr
,"\n\t ",obj_tlen
);
403 /* do we want to see an additionally hexdump ? */
404 if (vflag
> 1 || hexdump
==TRUE
)
405 print_unknown_data(tptr
+sizeof(sizeof(struct lmp_object_header
)),"\n\t ",
406 lmp_obj_len
-sizeof(struct lmp_object_header
));
413 printf("\n\t\t packet exceeded snapshot");