1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
|
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code
* distributions retain the above copyright notice and this paragraph
* in its entirety, and (2) distributions including binary code include
* the above copyright notice and this paragraph in its entirety in
* the documentation or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
* LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* Original code by Hannes Gredler (hannes@juniper.net)
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.4.2.2 2003/11/16 08:51:31 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <tcpdump-stdinc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "interface.h"
#include "extract.h"
#include "addrtoname.h"
/*
* ldp common header
*
* 0 1 2 3
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Version | PDU Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | LDP Identifier |
* + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
struct ldp_common_header {
u_int8_t version[2];
u_int8_t pdu_length[2];
u_int8_t lsr_id[4];
u_int8_t label_space[2];
};
#define LDP_VERSION 1
/*
* ldp message header
*
* 0 1 2 3
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |U| Message Type | Message Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Message ID |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | Mandatory Parameters |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | Optional Parameters |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct ldp_msg_header {
u_int8_t type[2];
u_int8_t length[2];
u_int8_t id[4];
};
#define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff)
#define LDP_MASK_U_BIT(x) ((x)&0x8000)
#define LDP_MSG_NOTIF 0x0001
#define LDP_MSG_HELLO 0x0100
#define LDP_MSG_INIT 0x0200
#define LDP_MSG_KEEPALIVE 0x0201
#define LDP_MSG_ADDRESS 0x0300
#define LDP_MSG_ADDRESS_WITHDRAW 0x0301
#define LDP_MSG_LABEL_MAPPING 0x0400
#define LDP_MSG_LABEL_REQUEST 0x0401
#define LDP_MSG_LABEL_WITHDRAW 0x0402
#define LDP_MSG_LABEL_RELEASE 0x0403
#define LDP_MSG_LABEL_ABORT_REQUEST 0x0404
#define LDP_VENDOR_PRIVATE_MIN 0x3e00
#define LDP_VENDOR_PRIVATE_MAX 0x3eff
#define LDP_EXPERIMENTAL_MIN 0x3f00
#define LDP_EXPERIMENTAL_MAX 0x3fff
static const struct tok ldp_msg_values[] = {
{ LDP_MSG_NOTIF, "Notification" },
{ LDP_MSG_HELLO, "Hello" },
{ LDP_MSG_INIT, "Initialization" },
{ LDP_MSG_KEEPALIVE, "Keepalive" },
{ LDP_MSG_ADDRESS, "Address" },
{ LDP_MSG_ADDRESS_WITHDRAW, "Address Widthdraw" },
{ LDP_MSG_LABEL_MAPPING, "Label Mapping" },
{ LDP_MSG_LABEL_REQUEST, "Label Request" },
{ LDP_MSG_LABEL_WITHDRAW, "Label Withdraw" },
{ LDP_MSG_LABEL_RELEASE, "Label Release" },
{ LDP_MSG_LABEL_ABORT_REQUEST, "Label Abort Request" },
{ 0, NULL}
};
#define LDP_MASK_TLV_TYPE(x) ((x)&0x3fff)
#define LDP_MASK_F_BIT(x) ((x)&0x4000)
#define LDP_TLV_FEC 0x0100
#define LDP_TLV_ADDRESS_LIST 0x0101
#define LDP_TLV_HOP_COUNT 0x0103
#define LDP_TLV_PATH_VECTOR 0x0104
#define LDP_TLV_GENERIC_LABEL 0x0200
#define LDP_TLV_ATM_LABEL 0x0201
#define LDP_TLV_FR_LABEL 0x0202
#define LDP_TLV_STATUS 0x0300
#define LDP_TLV_EXTD_STATUS 0x0301
#define LDP_TLV_RETURNED_PDU 0x0302
#define LDP_TLV_RETURNED_MSG 0x0303
#define LDP_TLV_COMMON_HELLO 0x0400
#define LDP_TLV_IPV4_TRANSPORT_ADDR 0x0401
#define LDP_TLV_CONFIG_SEQ_NUMBER 0x0402
#define LDP_TLV_IPV6_TRANSPORT_ADDR 0x0403
#define LDP_TLV_COMMON_SESSION 0x0500
#define LDP_TLV_ATM_SESSION_PARM 0x0501
#define LDP_TLV_FR_SESSION_PARM 0x0502
#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600
static const struct tok ldp_tlv_values[] = {
{ LDP_TLV_FEC, "FEC" },
{ LDP_TLV_ADDRESS_LIST, "Address List" },
{ LDP_TLV_HOP_COUNT, "Hop Count" },
{ LDP_TLV_PATH_VECTOR, "Path Vector" },
{ LDP_TLV_GENERIC_LABEL, "Generic Label" },
{ LDP_TLV_ATM_LABEL, "ATM Label" },
{ LDP_TLV_FR_LABEL, "Frame-Relay Label" },
{ LDP_TLV_STATUS, "Status" },
{ LDP_TLV_EXTD_STATUS, "Extended Status" },
{ LDP_TLV_RETURNED_PDU, "Returned PDU" },
{ LDP_TLV_RETURNED_MSG, "Returned Message" },
{ LDP_TLV_COMMON_HELLO, "Common Hello Parameters" },
{ LDP_TLV_IPV4_TRANSPORT_ADDR, "IPv4 Transport Address" },
{ LDP_TLV_CONFIG_SEQ_NUMBER, "Configuration Sequence Number" },
{ LDP_TLV_IPV6_TRANSPORT_ADDR, "IPv6 Transport Address" },
{ LDP_TLV_COMMON_SESSION, "Common Session Parameters" },
{ LDP_TLV_ATM_SESSION_PARM, "ATM Session Parameters" },
{ LDP_TLV_FR_SESSION_PARM, "Frame-Relay Session Parameters" },
{ LDP_TLV_LABEL_REQUEST_MSG_ID, "Label Request Message ID" },
{ 0, NULL}
};
#define FALSE 0
#define TRUE 1
int ldp_tlv_print(register const u_char *);
/*
* ldp tlv header
*
* 0 1 2 3
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |U|F| Type | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* | Value |
* ~ ~
* | |
* | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
int
ldp_tlv_print(register const u_char *tptr) {
struct ldp_tlv_header {
u_int8_t type[2];
u_int8_t length[2];
};
const struct ldp_tlv_header *ldp_tlv_header;
u_short tlv_type,tlv_len,tlv_tlen;
ldp_tlv_header = (const struct ldp_tlv_header *)tptr;
tlv_len=EXTRACT_16BITS(ldp_tlv_header->length);
tlv_tlen=tlv_len;
tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type));
/* FIXME vendor private / experimental check */
printf("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
tok2str(ldp_tlv_values,
"Unknown",
tlv_type),
tlv_type,
tlv_len,
LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore",
LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't");
tptr+=sizeof(struct ldp_tlv_header);
switch(tlv_type) {
case LDP_TLV_COMMON_HELLO:
printf("\n\t Hold Time: %us, Flags: [%s Hello%s]",
EXTRACT_16BITS(tptr),
(EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link",
(EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : "");
break;
case LDP_TLV_IPV4_TRANSPORT_ADDR:
printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr));
break;
#ifdef INET6
case LDP_TLV_IPV6_TRANSPORT_ADDR:
printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr));
break;
#endif
case LDP_TLV_CONFIG_SEQ_NUMBER:
printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr));
break;
/*
* FIXME those are the defined TLVs that lack a decoder
* you are welcome to contribute code ;-)
*/
case LDP_TLV_FEC:
case LDP_TLV_ADDRESS_LIST:
case LDP_TLV_HOP_COUNT:
case LDP_TLV_PATH_VECTOR:
case LDP_TLV_GENERIC_LABEL:
case LDP_TLV_ATM_LABEL:
case LDP_TLV_FR_LABEL:
case LDP_TLV_STATUS:
case LDP_TLV_EXTD_STATUS:
case LDP_TLV_RETURNED_PDU:
case LDP_TLV_RETURNED_MSG:
case LDP_TLV_COMMON_SESSION:
case LDP_TLV_ATM_SESSION_PARM:
case LDP_TLV_FR_SESSION_PARM:
case LDP_TLV_LABEL_REQUEST_MSG_ID:
default:
if (vflag <= 1)
print_unknown_data(tptr,"\n\t ",tlv_tlen);
break;
}
return(tlv_len+4); /* Type & Length fields not included */
}
void
ldp_print(register const u_char *pptr, register u_int len) {
const struct ldp_common_header *ldp_com_header;
const struct ldp_msg_header *ldp_msg_header;
const u_char *tptr,*msg_tptr;
u_short tlen;
u_short msg_len,msg_type,msg_tlen;
int hexdump,processed;
tptr=pptr;
ldp_com_header = (const struct ldp_common_header *)pptr;
TCHECK(*ldp_com_header);
/*
* Sanity checking of the header.
*/
if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) {
printf("LDP version %u packet not supported",
EXTRACT_16BITS(&ldp_com_header->version));
return;
}
/* print the LSR-ID, label-space & length */
printf("%sLDP, Label-Space-ID: %s:%u, length: %u",
(vflag < 1) ? "" : "\n\t",
ipaddr_string(&ldp_com_header->lsr_id),
EXTRACT_16BITS(&ldp_com_header->label_space),
len);
/* bail out if non-verbose */
if (vflag < 1)
return;
/* ok they seem to want to know everything - lets fully decode it */
tlen=EXTRACT_16BITS(ldp_com_header->pdu_length);
tptr+=sizeof(const struct ldp_common_header);
tlen-=sizeof(const struct ldp_common_header);
while(tlen>0) {
/* did we capture enough for fully decoding the msg header ? */
if (!TTEST2(*tptr, sizeof(struct ldp_msg_header)))
goto trunc;
ldp_msg_header = (const struct ldp_msg_header *)tptr;
msg_len=EXTRACT_16BITS(ldp_msg_header->length);
msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type));
/* FIXME vendor private / experimental check */
printf("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
tok2str(ldp_msg_values,
"Unknown",
msg_type),
msg_type,
msg_len,
EXTRACT_32BITS(&ldp_msg_header->id),
LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore");
msg_tptr=tptr+sizeof(struct ldp_msg_header);
msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */
/* did we capture enough for fully decoding the message ? */
if (!TTEST2(*tptr, msg_len))
goto trunc;
hexdump=FALSE;
switch(msg_type) {
case LDP_MSG_HELLO:
while(msg_tlen >= 4) {
processed = ldp_tlv_print(msg_tptr);
if (processed == 0)
break;
msg_tlen-=processed;
msg_tptr+=processed;
}
break;
/*
* FIXME those are the defined messages that lack a decoder
* you are welcome to contribute code ;-)
*/
case LDP_MSG_NOTIF:
case LDP_MSG_INIT:
case LDP_MSG_KEEPALIVE:
case LDP_MSG_ADDRESS:
case LDP_MSG_ADDRESS_WITHDRAW:
case LDP_MSG_LABEL_MAPPING:
case LDP_MSG_LABEL_REQUEST:
case LDP_MSG_LABEL_WITHDRAW:
case LDP_MSG_LABEL_RELEASE:
case LDP_MSG_LABEL_ABORT_REQUEST:
default:
if (vflag <= 1)
print_unknown_data(msg_tptr,"\n\t ",msg_tlen);
break;
}
/* do we want to see an additionally hexdump ? */
if (vflag > 1 || hexdump==TRUE)
print_unknown_data(tptr+sizeof(sizeof(struct ldp_msg_header)),"\n\t ",
msg_len);
tptr+=msg_len;
tlen-=msg_len;
}
return;
trunc:
printf("\n\t\t packet exceeded snapshot");
}
|