Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 174 lines (142 sloc) 4.547 kb
83dc1ab From Carles Kishimoto <carles.kishimoto@gmail.com>:
hannes authored
1 /*
2 * Copyright (c) 1998-2007 The TCPDUMP project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that: (1) source code
6 * distributions retain the above copyright notice and this paragraph
7 * in its entirety, and (2) distributions including binary code include
8 * the above copyright notice and this paragraph in its entirety in
9 * the documentation or other materials provided with the distribution.
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
14 *
15 * UNIDIRECTIONAL LINK DETECTION (UDLD) as per
16 * http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt
17 *
18 * Original code by Carles Kishimoto <carles.kishimoto@gmail.com>
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <tcpdump-stdinc.h>
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "interface.h"
31 #include "addrtoname.h"
32 #include "extract.h"
33 #include "nlpid.h"
34
35 #define UDLD_HEADER_LEN 4
36 #define UDLD_DEVICE_ID_TLV 0x0001
37 #define UDLD_PORT_ID_TLV 0x0002
38 #define UDLD_ECHO_TLV 0x0003
39 #define UDLD_MESSAGE_INTERVAL_TLV 0x0004
40 #define UDLD_TIMEOUT_INTERVAL_TLV 0x0005
41 #define UDLD_DEVICE_NAME_TLV 0x0006
42 #define UDLD_SEQ_NUMBER_TLV 0x0007
43
44 static struct tok udld_tlv_values[] = {
45 { UDLD_DEVICE_ID_TLV, "Device-ID TLV"},
46 { UDLD_PORT_ID_TLV, "Port-ID TLV"},
47 { UDLD_ECHO_TLV, "Echo TLV"},
48 { UDLD_MESSAGE_INTERVAL_TLV, "Message Interval TLV"},
49 { UDLD_TIMEOUT_INTERVAL_TLV, "Timeout Interval TLV"},
50 { UDLD_DEVICE_NAME_TLV, "Device Name TLV"},
51 { UDLD_SEQ_NUMBER_TLV,"Sequence Number TLV"},
52 { 0, NULL}
53 };
54
55 static struct tok udld_code_values[] = {
56 { 0x00, "Reserved"},
57 { 0x01, "Probe message"},
58 { 0x02, "Echo message"},
59 { 0x03, "Flush message"},
60 { 0, NULL}
61 };
62
63 static struct tok udld_flags_values[] = {
64 { 0x00, "RT"},
65 { 0x01, "RSY"},
66 { 0, NULL}
67 };
68
69 /*
70 *
71 * 0 1 2 3
72 * 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
73 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 * | Ver | Opcode | Flags | Checksum |
75 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 * | List of TLVs (variable length list) |
77 * | ... |
78 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79 *
80 */
81
82 #define UDLD_EXTRACT_VERSION(x) (((x)&0xe0)>>5)
83 #define UDLD_EXTRACT_OPCODE(x) ((x)&0x1f)
84
85 void
86 udld_print (const u_char *pptr, u_int length)
87 {
88 int code, type, len;
89 const u_char *tptr;
90
91 if (length < UDLD_HEADER_LEN)
92 goto trunc;
93
94 tptr = pptr;
95
96 if (!TTEST2(*tptr, UDLD_HEADER_LEN))
97 goto trunc;
98
99 code = UDLD_EXTRACT_OPCODE(*tptr);
100
101 printf("UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u",
102 UDLD_EXTRACT_VERSION(*tptr),
103 tok2str(udld_code_values, "Reserved", code),
104 code,
105 bittok2str(udld_flags_values, "none", *(tptr+1)),
106 *(tptr+1),
107 length);
108
109 /*
110 * In non-verbose mode, just print version and opcode type
111 */
112 if (vflag < 1) {
113 return;
114 }
115
116 printf("\n\tChecksum 0x%04x (unverified)", EXTRACT_16BITS(tptr+2));
117
118 tptr += UDLD_HEADER_LEN;
119
120 while (tptr < (pptr+length)) {
121
122 if (!TTEST2(*tptr, 4))
123 goto trunc;
124
125 type = EXTRACT_16BITS(tptr);
126 len = EXTRACT_16BITS(tptr+2);
127 len -= 4;
128 tptr += 4;
129
130 /* infinite loop check */
131 if (type == 0 || len == 0) {
132 return;
133 }
134
135 printf("\n\t%s (0x%04x) TLV, length %u",
136 tok2str(udld_tlv_values, "Unknown", type),
137 type, len);
138
139 switch (type) {
140 case UDLD_DEVICE_ID_TLV:
141 case UDLD_PORT_ID_TLV:
142 case UDLD_ECHO_TLV:
143 case UDLD_DEVICE_NAME_TLV:
144 printf(", %s", tptr);
145 break;
146
147 case UDLD_MESSAGE_INTERVAL_TLV:
148 case UDLD_TIMEOUT_INTERVAL_TLV:
149 printf(", %us", (*tptr));
150 break;
151
152 case UDLD_SEQ_NUMBER_TLV:
153 printf(", %u", EXTRACT_32BITS(tptr));
154 break;
155
156 default:
157 break;
158 }
159 tptr += len;
160 }
161
162 return;
163
164 trunc:
165 printf("[|udld]");
166 }
167
168 /*
169 * Local Variables:
170 * c-style: whitesmith
171 * c-basic-offset: 4
172 * End:
173 */
Something went wrong with that request. Please try again.