]> The Tcpdump Group git mirrors - tcpdump/blob - print-juniper.c
dismiss NETDISSECT_REWORKED macro
[tcpdump] / print-juniper.c
1 /* NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp */
2
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 * Original code by Hannes Gredler (hannes@juniper.net)
16 */
17
18 #ifndef lint
19 #else
20 __RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp ");
21 #endif
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <tcpdump-stdinc.h>
28
29 #include "interface.h"
30 #include "addrtoname.h"
31 #include "extract.h"
32 #include "ppp.h"
33 #include "llc.h"
34 #include "nlpid.h"
35 #include "ethertype.h"
36 #include "atm.h"
37
38 #define JUNIPER_BPF_OUT 0 /* Outgoing packet */
39 #define JUNIPER_BPF_IN 1 /* Incoming packet */
40 #define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */
41 #define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */
42 #define JUNIPER_BPF_IIF 0x4 /* IIF is valid */
43 #define JUNIPER_BPF_FILTER 0x40 /* BPF filtering is supported */
44 #define JUNIPER_BPF_EXT 0x80 /* extensions present */
45 #define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */
46
47 #define JUNIPER_LSQ_COOKIE_RE (1 << 3)
48 #define JUNIPER_LSQ_COOKIE_DIR (1 << 2)
49 #define JUNIPER_LSQ_L3_PROTO_SHIFT 4
50 #define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
51 #define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
52 #define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
53 #define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
54 #define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
55 #define AS_PIC_COOKIE_LEN 8
56
57 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
58 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
59 #define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
60 #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
61 #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
62
63 static const struct tok juniper_ipsec_type_values[] = {
64 { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" },
65 { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" },
66 { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE, "ESP AUTH" },
67 { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE, "AH AUTH" },
68 { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" },
69 { 0, NULL}
70 };
71
72 static const struct tok juniper_direction_values[] = {
73 { JUNIPER_BPF_IN, "In"},
74 { JUNIPER_BPF_OUT, "Out"},
75 { 0, NULL}
76 };
77
78 /* codepoints for encoding extensions to a .pcap file */
79 enum {
80 JUNIPER_EXT_TLV_IFD_IDX = 1,
81 JUNIPER_EXT_TLV_IFD_NAME = 2,
82 JUNIPER_EXT_TLV_IFD_MEDIATYPE = 3,
83 JUNIPER_EXT_TLV_IFL_IDX = 4,
84 JUNIPER_EXT_TLV_IFL_UNIT = 5,
85 JUNIPER_EXT_TLV_IFL_ENCAPS = 6,
86 JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE = 7,
87 JUNIPER_EXT_TLV_TTP_IFL_ENCAPS = 8
88 };
89
90 /* 1 byte type and 1-byte length */
91 #define JUNIPER_EXT_TLV_OVERHEAD 2
92
93 static const struct tok jnx_ext_tlv_values[] = {
94 { JUNIPER_EXT_TLV_IFD_IDX, "Device Interface Index" },
95 { JUNIPER_EXT_TLV_IFD_NAME,"Device Interface Name" },
96 { JUNIPER_EXT_TLV_IFD_MEDIATYPE, "Device Media Type" },
97 { JUNIPER_EXT_TLV_IFL_IDX, "Logical Interface Index" },
98 { JUNIPER_EXT_TLV_IFL_UNIT,"Logical Unit Number" },
99 { JUNIPER_EXT_TLV_IFL_ENCAPS, "Logical Interface Encapsulation" },
100 { JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" },
101 { JUNIPER_EXT_TLV_TTP_IFL_ENCAPS, "TTP derived Logical Interface Encapsulation" },
102 { 0, NULL }
103 };
104
105 static const struct tok jnx_flag_values[] = {
106 { JUNIPER_BPF_EXT, "Ext" },
107 { JUNIPER_BPF_FILTER, "Filter" },
108 { JUNIPER_BPF_IIF, "IIF" },
109 { JUNIPER_BPF_NO_L2, "no-L2" },
110 { JUNIPER_BPF_PKT_IN, "In" },
111 { 0, NULL }
112 };
113
114 #define JUNIPER_IFML_ETHER 1
115 #define JUNIPER_IFML_FDDI 2
116 #define JUNIPER_IFML_TOKENRING 3
117 #define JUNIPER_IFML_PPP 4
118 #define JUNIPER_IFML_FRAMERELAY 5
119 #define JUNIPER_IFML_CISCOHDLC 6
120 #define JUNIPER_IFML_SMDSDXI 7
121 #define JUNIPER_IFML_ATMPVC 8
122 #define JUNIPER_IFML_PPP_CCC 9
123 #define JUNIPER_IFML_FRAMERELAY_CCC 10
124 #define JUNIPER_IFML_IPIP 11
125 #define JUNIPER_IFML_GRE 12
126 #define JUNIPER_IFML_PIM 13
127 #define JUNIPER_IFML_PIMD 14
128 #define JUNIPER_IFML_CISCOHDLC_CCC 15
129 #define JUNIPER_IFML_VLAN_CCC 16
130 #define JUNIPER_IFML_MLPPP 17
131 #define JUNIPER_IFML_MLFR 18
132 #define JUNIPER_IFML_ML 19
133 #define JUNIPER_IFML_LSI 20
134 #define JUNIPER_IFML_DFE 21
135 #define JUNIPER_IFML_ATM_CELLRELAY_CCC 22
136 #define JUNIPER_IFML_CRYPTO 23
137 #define JUNIPER_IFML_GGSN 24
138 #define JUNIPER_IFML_LSI_PPP 25
139 #define JUNIPER_IFML_LSI_CISCOHDLC 26
140 #define JUNIPER_IFML_PPP_TCC 27
141 #define JUNIPER_IFML_FRAMERELAY_TCC 28
142 #define JUNIPER_IFML_CISCOHDLC_TCC 29
143 #define JUNIPER_IFML_ETHERNET_CCC 30
144 #define JUNIPER_IFML_VT 31
145 #define JUNIPER_IFML_EXTENDED_VLAN_CCC 32
146 #define JUNIPER_IFML_ETHER_OVER_ATM 33
147 #define JUNIPER_IFML_MONITOR 34
148 #define JUNIPER_IFML_ETHERNET_TCC 35
149 #define JUNIPER_IFML_VLAN_TCC 36
150 #define JUNIPER_IFML_EXTENDED_VLAN_TCC 37
151 #define JUNIPER_IFML_CONTROLLER 38
152 #define JUNIPER_IFML_MFR 39
153 #define JUNIPER_IFML_LS 40
154 #define JUNIPER_IFML_ETHERNET_VPLS 41
155 #define JUNIPER_IFML_ETHERNET_VLAN_VPLS 42
156 #define JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS 43
157 #define JUNIPER_IFML_LT 44
158 #define JUNIPER_IFML_SERVICES 45
159 #define JUNIPER_IFML_ETHER_VPLS_OVER_ATM 46
160 #define JUNIPER_IFML_FR_PORT_CCC 47
161 #define JUNIPER_IFML_FRAMERELAY_EXT_CCC 48
162 #define JUNIPER_IFML_FRAMERELAY_EXT_TCC 49
163 #define JUNIPER_IFML_FRAMERELAY_FLEX 50
164 #define JUNIPER_IFML_GGSNI 51
165 #define JUNIPER_IFML_ETHERNET_FLEX 52
166 #define JUNIPER_IFML_COLLECTOR 53
167 #define JUNIPER_IFML_AGGREGATOR 54
168 #define JUNIPER_IFML_LAPD 55
169 #define JUNIPER_IFML_PPPOE 56
170 #define JUNIPER_IFML_PPP_SUBORDINATE 57
171 #define JUNIPER_IFML_CISCOHDLC_SUBORDINATE 58
172 #define JUNIPER_IFML_DFC 59
173 #define JUNIPER_IFML_PICPEER 60
174
175 static const struct tok juniper_ifmt_values[] = {
176 { JUNIPER_IFML_ETHER, "Ethernet" },
177 { JUNIPER_IFML_FDDI, "FDDI" },
178 { JUNIPER_IFML_TOKENRING, "Token-Ring" },
179 { JUNIPER_IFML_PPP, "PPP" },
180 { JUNIPER_IFML_PPP_SUBORDINATE, "PPP-Subordinate" },
181 { JUNIPER_IFML_FRAMERELAY, "Frame-Relay" },
182 { JUNIPER_IFML_CISCOHDLC, "Cisco-HDLC" },
183 { JUNIPER_IFML_SMDSDXI, "SMDS-DXI" },
184 { JUNIPER_IFML_ATMPVC, "ATM-PVC" },
185 { JUNIPER_IFML_PPP_CCC, "PPP-CCC" },
186 { JUNIPER_IFML_FRAMERELAY_CCC, "Frame-Relay-CCC" },
187 { JUNIPER_IFML_FRAMERELAY_EXT_CCC, "Extended FR-CCC" },
188 { JUNIPER_IFML_IPIP, "IP-over-IP" },
189 { JUNIPER_IFML_GRE, "GRE" },
190 { JUNIPER_IFML_PIM, "PIM-Encapsulator" },
191 { JUNIPER_IFML_PIMD, "PIM-Decapsulator" },
192 { JUNIPER_IFML_CISCOHDLC_CCC, "Cisco-HDLC-CCC" },
193 { JUNIPER_IFML_VLAN_CCC, "VLAN-CCC" },
194 { JUNIPER_IFML_EXTENDED_VLAN_CCC, "Extended-VLAN-CCC" },
195 { JUNIPER_IFML_MLPPP, "Multilink-PPP" },
196 { JUNIPER_IFML_MLFR, "Multilink-FR" },
197 { JUNIPER_IFML_MFR, "Multilink-FR-UNI-NNI" },
198 { JUNIPER_IFML_ML, "Multilink" },
199 { JUNIPER_IFML_LS, "LinkService" },
200 { JUNIPER_IFML_LSI, "LSI" },
201 { JUNIPER_IFML_ATM_CELLRELAY_CCC, "ATM-CCC-Cell-Relay" },
202 { JUNIPER_IFML_CRYPTO, "IPSEC-over-IP" },
203 { JUNIPER_IFML_GGSN, "GGSN" },
204 { JUNIPER_IFML_PPP_TCC, "PPP-TCC" },
205 { JUNIPER_IFML_FRAMERELAY_TCC, "Frame-Relay-TCC" },
206 { JUNIPER_IFML_FRAMERELAY_EXT_TCC, "Extended FR-TCC" },
207 { JUNIPER_IFML_CISCOHDLC_TCC, "Cisco-HDLC-TCC" },
208 { JUNIPER_IFML_ETHERNET_CCC, "Ethernet-CCC" },
209 { JUNIPER_IFML_VT, "VPN-Loopback-tunnel" },
210 { JUNIPER_IFML_ETHER_OVER_ATM, "Ethernet-over-ATM" },
211 { JUNIPER_IFML_ETHER_VPLS_OVER_ATM, "Ethernet-VPLS-over-ATM" },
212 { JUNIPER_IFML_MONITOR, "Monitor" },
213 { JUNIPER_IFML_ETHERNET_TCC, "Ethernet-TCC" },
214 { JUNIPER_IFML_VLAN_TCC, "VLAN-TCC" },
215 { JUNIPER_IFML_EXTENDED_VLAN_TCC, "Extended-VLAN-TCC" },
216 { JUNIPER_IFML_CONTROLLER, "Controller" },
217 { JUNIPER_IFML_ETHERNET_VPLS, "VPLS" },
218 { JUNIPER_IFML_ETHERNET_VLAN_VPLS, "VLAN-VPLS" },
219 { JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS, "Extended-VLAN-VPLS" },
220 { JUNIPER_IFML_LT, "Logical-tunnel" },
221 { JUNIPER_IFML_SERVICES, "General-Services" },
222 { JUNIPER_IFML_PPPOE, "PPPoE" },
223 { JUNIPER_IFML_ETHERNET_FLEX, "Flexible-Ethernet-Services" },
224 { JUNIPER_IFML_FRAMERELAY_FLEX, "Flexible-FrameRelay" },
225 { JUNIPER_IFML_COLLECTOR, "Flow-collection" },
226 { JUNIPER_IFML_PICPEER, "PIC Peer" },
227 { JUNIPER_IFML_DFC, "Dynamic-Flow-Capture" },
228 {0, NULL}
229 };
230
231 #define JUNIPER_IFLE_ATM_SNAP 2
232 #define JUNIPER_IFLE_ATM_NLPID 3
233 #define JUNIPER_IFLE_ATM_VCMUX 4
234 #define JUNIPER_IFLE_ATM_LLC 5
235 #define JUNIPER_IFLE_ATM_PPP_VCMUX 6
236 #define JUNIPER_IFLE_ATM_PPP_LLC 7
237 #define JUNIPER_IFLE_ATM_PPP_FUNI 8
238 #define JUNIPER_IFLE_ATM_CCC 9
239 #define JUNIPER_IFLE_FR_NLPID 10
240 #define JUNIPER_IFLE_FR_SNAP 11
241 #define JUNIPER_IFLE_FR_PPP 12
242 #define JUNIPER_IFLE_FR_CCC 13
243 #define JUNIPER_IFLE_ENET2 14
244 #define JUNIPER_IFLE_IEEE8023_SNAP 15
245 #define JUNIPER_IFLE_IEEE8023_LLC 16
246 #define JUNIPER_IFLE_PPP 17
247 #define JUNIPER_IFLE_CISCOHDLC 18
248 #define JUNIPER_IFLE_PPP_CCC 19
249 #define JUNIPER_IFLE_IPIP_NULL 20
250 #define JUNIPER_IFLE_PIM_NULL 21
251 #define JUNIPER_IFLE_GRE_NULL 22
252 #define JUNIPER_IFLE_GRE_PPP 23
253 #define JUNIPER_IFLE_PIMD_DECAPS 24
254 #define JUNIPER_IFLE_CISCOHDLC_CCC 25
255 #define JUNIPER_IFLE_ATM_CISCO_NLPID 26
256 #define JUNIPER_IFLE_VLAN_CCC 27
257 #define JUNIPER_IFLE_MLPPP 28
258 #define JUNIPER_IFLE_MLFR 29
259 #define JUNIPER_IFLE_LSI_NULL 30
260 #define JUNIPER_IFLE_AGGREGATE_UNUSED 31
261 #define JUNIPER_IFLE_ATM_CELLRELAY_CCC 32
262 #define JUNIPER_IFLE_CRYPTO 33
263 #define JUNIPER_IFLE_GGSN 34
264 #define JUNIPER_IFLE_ATM_TCC 35
265 #define JUNIPER_IFLE_FR_TCC 36
266 #define JUNIPER_IFLE_PPP_TCC 37
267 #define JUNIPER_IFLE_CISCOHDLC_TCC 38
268 #define JUNIPER_IFLE_ETHERNET_CCC 39
269 #define JUNIPER_IFLE_VT 40
270 #define JUNIPER_IFLE_ATM_EOA_LLC 41
271 #define JUNIPER_IFLE_EXTENDED_VLAN_CCC 42
272 #define JUNIPER_IFLE_ATM_SNAP_TCC 43
273 #define JUNIPER_IFLE_MONITOR 44
274 #define JUNIPER_IFLE_ETHERNET_TCC 45
275 #define JUNIPER_IFLE_VLAN_TCC 46
276 #define JUNIPER_IFLE_EXTENDED_VLAN_TCC 47
277 #define JUNIPER_IFLE_MFR 48
278 #define JUNIPER_IFLE_ETHERNET_VPLS 49
279 #define JUNIPER_IFLE_ETHERNET_VLAN_VPLS 50
280 #define JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS 51
281 #define JUNIPER_IFLE_SERVICES 52
282 #define JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC 53
283 #define JUNIPER_IFLE_FR_PORT_CCC 54
284 #define JUNIPER_IFLE_ATM_MLPPP_LLC 55
285 #define JUNIPER_IFLE_ATM_EOA_CCC 56
286 #define JUNIPER_IFLE_LT_VLAN 57
287 #define JUNIPER_IFLE_COLLECTOR 58
288 #define JUNIPER_IFLE_AGGREGATOR 59
289 #define JUNIPER_IFLE_LAPD 60
290 #define JUNIPER_IFLE_ATM_PPPOE_LLC 61
291 #define JUNIPER_IFLE_ETHERNET_PPPOE 62
292 #define JUNIPER_IFLE_PPPOE 63
293 #define JUNIPER_IFLE_PPP_SUBORDINATE 64
294 #define JUNIPER_IFLE_CISCOHDLC_SUBORDINATE 65
295 #define JUNIPER_IFLE_DFC 66
296 #define JUNIPER_IFLE_PICPEER 67
297
298 static const struct tok juniper_ifle_values[] = {
299 { JUNIPER_IFLE_AGGREGATOR, "Aggregator" },
300 { JUNIPER_IFLE_ATM_CCC, "CCC over ATM" },
301 { JUNIPER_IFLE_ATM_CELLRELAY_CCC, "ATM CCC Cell Relay" },
302 { JUNIPER_IFLE_ATM_CISCO_NLPID, "CISCO compatible NLPID" },
303 { JUNIPER_IFLE_ATM_EOA_CCC, "Ethernet over ATM CCC" },
304 { JUNIPER_IFLE_ATM_EOA_LLC, "Ethernet over ATM LLC" },
305 { JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC, "Ethernet VPLS over ATM LLC" },
306 { JUNIPER_IFLE_ATM_LLC, "ATM LLC" },
307 { JUNIPER_IFLE_ATM_MLPPP_LLC, "MLPPP over ATM LLC" },
308 { JUNIPER_IFLE_ATM_NLPID, "ATM NLPID" },
309 { JUNIPER_IFLE_ATM_PPPOE_LLC, "PPPoE over ATM LLC" },
310 { JUNIPER_IFLE_ATM_PPP_FUNI, "PPP over FUNI" },
311 { JUNIPER_IFLE_ATM_PPP_LLC, "PPP over ATM LLC" },
312 { JUNIPER_IFLE_ATM_PPP_VCMUX, "PPP over ATM VCMUX" },
313 { JUNIPER_IFLE_ATM_SNAP, "ATM SNAP" },
314 { JUNIPER_IFLE_ATM_SNAP_TCC, "ATM SNAP TCC" },
315 { JUNIPER_IFLE_ATM_TCC, "ATM VCMUX TCC" },
316 { JUNIPER_IFLE_ATM_VCMUX, "ATM VCMUX" },
317 { JUNIPER_IFLE_CISCOHDLC, "C-HDLC" },
318 { JUNIPER_IFLE_CISCOHDLC_CCC, "C-HDLC CCC" },
319 { JUNIPER_IFLE_CISCOHDLC_SUBORDINATE, "C-HDLC via dialer" },
320 { JUNIPER_IFLE_CISCOHDLC_TCC, "C-HDLC TCC" },
321 { JUNIPER_IFLE_COLLECTOR, "Collector" },
322 { JUNIPER_IFLE_CRYPTO, "Crypto" },
323 { JUNIPER_IFLE_ENET2, "Ethernet" },
324 { JUNIPER_IFLE_ETHERNET_CCC, "Ethernet CCC" },
325 { JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS, "Extended VLAN VPLS" },
326 { JUNIPER_IFLE_ETHERNET_PPPOE, "PPPoE over Ethernet" },
327 { JUNIPER_IFLE_ETHERNET_TCC, "Ethernet TCC" },
328 { JUNIPER_IFLE_ETHERNET_VLAN_VPLS, "VLAN VPLS" },
329 { JUNIPER_IFLE_ETHERNET_VPLS, "VPLS" },
330 { JUNIPER_IFLE_EXTENDED_VLAN_CCC, "Extended VLAN CCC" },
331 { JUNIPER_IFLE_EXTENDED_VLAN_TCC, "Extended VLAN TCC" },
332 { JUNIPER_IFLE_FR_CCC, "FR CCC" },
333 { JUNIPER_IFLE_FR_NLPID, "FR NLPID" },
334 { JUNIPER_IFLE_FR_PORT_CCC, "FR CCC" },
335 { JUNIPER_IFLE_FR_PPP, "FR PPP" },
336 { JUNIPER_IFLE_FR_SNAP, "FR SNAP" },
337 { JUNIPER_IFLE_FR_TCC, "FR TCC" },
338 { JUNIPER_IFLE_GGSN, "GGSN" },
339 { JUNIPER_IFLE_GRE_NULL, "GRE NULL" },
340 { JUNIPER_IFLE_GRE_PPP, "PPP over GRE" },
341 { JUNIPER_IFLE_IPIP_NULL, "IPIP" },
342 { JUNIPER_IFLE_LAPD, "LAPD" },
343 { JUNIPER_IFLE_LSI_NULL, "LSI Null" },
344 { JUNIPER_IFLE_LT_VLAN, "LT VLAN" },
345 { JUNIPER_IFLE_MFR, "MFR" },
346 { JUNIPER_IFLE_MLFR, "MLFR" },
347 { JUNIPER_IFLE_MLPPP, "MLPPP" },
348 { JUNIPER_IFLE_MONITOR, "Monitor" },
349 { JUNIPER_IFLE_PIMD_DECAPS, "PIMd" },
350 { JUNIPER_IFLE_PIM_NULL, "PIM Null" },
351 { JUNIPER_IFLE_PPP, "PPP" },
352 { JUNIPER_IFLE_PPPOE, "PPPoE" },
353 { JUNIPER_IFLE_PPP_CCC, "PPP CCC" },
354 { JUNIPER_IFLE_PPP_SUBORDINATE, "" },
355 { JUNIPER_IFLE_PPP_TCC, "PPP TCC" },
356 { JUNIPER_IFLE_SERVICES, "General Services" },
357 { JUNIPER_IFLE_VLAN_CCC, "VLAN CCC" },
358 { JUNIPER_IFLE_VLAN_TCC, "VLAN TCC" },
359 { JUNIPER_IFLE_VT, "VT" },
360 {0, NULL}
361 };
362
363 struct juniper_cookie_table_t {
364 uint32_t pictype; /* pic type */
365 uint8_t cookie_len; /* cookie len */
366 const char *s; /* pic name */
367 };
368
369 static const struct juniper_cookie_table_t juniper_cookie_table[] = {
370 #ifdef DLT_JUNIPER_ATM1
371 { DLT_JUNIPER_ATM1, 4, "ATM1"},
372 #endif
373 #ifdef DLT_JUNIPER_ATM2
374 { DLT_JUNIPER_ATM2, 8, "ATM2"},
375 #endif
376 #ifdef DLT_JUNIPER_MLPPP
377 { DLT_JUNIPER_MLPPP, 2, "MLPPP"},
378 #endif
379 #ifdef DLT_JUNIPER_MLFR
380 { DLT_JUNIPER_MLFR, 2, "MLFR"},
381 #endif
382 #ifdef DLT_JUNIPER_MFR
383 { DLT_JUNIPER_MFR, 4, "MFR"},
384 #endif
385 #ifdef DLT_JUNIPER_PPPOE
386 { DLT_JUNIPER_PPPOE, 0, "PPPoE"},
387 #endif
388 #ifdef DLT_JUNIPER_PPPOE_ATM
389 { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"},
390 #endif
391 #ifdef DLT_JUNIPER_GGSN
392 { DLT_JUNIPER_GGSN, 8, "GGSN"},
393 #endif
394 #ifdef DLT_JUNIPER_MONITOR
395 { DLT_JUNIPER_MONITOR, 8, "MONITOR"},
396 #endif
397 #ifdef DLT_JUNIPER_SERVICES
398 { DLT_JUNIPER_SERVICES, 8, "AS"},
399 #endif
400 #ifdef DLT_JUNIPER_ES
401 { DLT_JUNIPER_ES, 0, "ES"},
402 #endif
403 { 0, 0, NULL }
404 };
405
406 struct juniper_l2info_t {
407 uint32_t length;
408 uint32_t caplen;
409 uint32_t pictype;
410 uint8_t direction;
411 uint8_t header_len;
412 uint8_t cookie_len;
413 uint8_t cookie_type;
414 uint8_t cookie[8];
415 uint8_t bundle;
416 uint16_t proto;
417 uint8_t flags;
418 };
419
420 #define LS_COOKIE_ID 0x54
421 #define AS_COOKIE_ID 0x47
422 #define LS_MLFR_COOKIE_LEN 4
423 #define ML_MLFR_COOKIE_LEN 2
424 #define LS_MFR_COOKIE_LEN 6
425 #define ATM1_COOKIE_LEN 4
426 #define ATM2_COOKIE_LEN 8
427
428 #define ATM2_PKT_TYPE_MASK 0x70
429 #define ATM2_GAP_COUNT_MASK 0x3F
430
431 #define JUNIPER_PROTO_NULL 1
432 #define JUNIPER_PROTO_IPV4 2
433 #define JUNIPER_PROTO_IPV6 6
434
435 #define MFR_BE_MASK 0xc0
436
437 static const struct tok juniper_protocol_values[] = {
438 { JUNIPER_PROTO_NULL, "Null" },
439 { JUNIPER_PROTO_IPV4, "IPv4" },
440 { JUNIPER_PROTO_IPV6, "IPv6" },
441 { 0, NULL}
442 };
443
444 static int ip_heuristic_guess(netdissect_options *, register const u_char *, u_int);
445 static int juniper_ppp_heuristic_guess(netdissect_options *, register const u_char *, u_int);
446 static int juniper_parse_header(netdissect_options *, const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *);
447
448 #ifdef DLT_JUNIPER_GGSN
449 u_int
450 juniper_ggsn_print(netdissect_options *ndo,
451 const struct pcap_pkthdr *h, register const u_char *p)
452 {
453 struct juniper_l2info_t l2info;
454 struct juniper_ggsn_header {
455 uint8_t svc_id;
456 uint8_t flags_len;
457 uint8_t proto;
458 uint8_t flags;
459 uint8_t vlan_id[2];
460 uint8_t res[2];
461 };
462 const struct juniper_ggsn_header *gh;
463
464 l2info.pictype = DLT_JUNIPER_GGSN;
465 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
466 return l2info.header_len;
467
468 p+=l2info.header_len;
469 gh = (struct juniper_ggsn_header *)&l2info.cookie;
470
471 if (ndo->ndo_eflag) {
472 ND_PRINT((ndo, "proto %s (%u), vlan %u: ",
473 tok2str(juniper_protocol_values,"Unknown",gh->proto),
474 gh->proto,
475 EXTRACT_16BITS(&gh->vlan_id[0])));
476 }
477
478 switch (gh->proto) {
479 case JUNIPER_PROTO_IPV4:
480 ip_print(ndo, p, l2info.length);
481 break;
482 case JUNIPER_PROTO_IPV6:
483 ip6_print(ndo, p, l2info.length);
484 break;
485 default:
486 if (!ndo->ndo_eflag)
487 ND_PRINT((ndo, "unknown GGSN proto (%u)", gh->proto));
488 }
489
490 return l2info.header_len;
491 }
492 #endif
493
494 #ifdef DLT_JUNIPER_ES
495 u_int
496 juniper_es_print(netdissect_options *ndo,
497 const struct pcap_pkthdr *h, register const u_char *p)
498 {
499 struct juniper_l2info_t l2info;
500 struct juniper_ipsec_header {
501 uint8_t sa_index[2];
502 uint8_t ttl;
503 uint8_t type;
504 uint8_t spi[4];
505 uint8_t src_ip[4];
506 uint8_t dst_ip[4];
507 };
508 u_int rewrite_len,es_type_bundle;
509 const struct juniper_ipsec_header *ih;
510
511 l2info.pictype = DLT_JUNIPER_ES;
512 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
513 return l2info.header_len;
514
515 p+=l2info.header_len;
516 ih = (struct juniper_ipsec_header *)p;
517
518 switch (ih->type) {
519 case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
520 case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
521 rewrite_len = 0;
522 es_type_bundle = 1;
523 break;
524 case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE:
525 case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE:
526 case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE:
527 rewrite_len = 16;
528 es_type_bundle = 0;
529 break;
530 default:
531 ND_PRINT((ndo, "ES Invalid type %u, length %u",
532 ih->type,
533 l2info.length));
534 return l2info.header_len;
535 }
536
537 l2info.length-=rewrite_len;
538 p+=rewrite_len;
539
540 if (ndo->ndo_eflag) {
541 if (!es_type_bundle) {
542 ND_PRINT((ndo, "ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
543 EXTRACT_16BITS(&ih->sa_index),
544 ih->ttl,
545 tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
546 ih->type,
547 EXTRACT_32BITS(&ih->spi),
548 ipaddr_string(ndo, &ih->src_ip),
549 ipaddr_string(ndo, &ih->dst_ip),
550 l2info.length));
551 } else {
552 ND_PRINT((ndo, "ES SA, index %u, ttl %u type %s (%u), length %u\n",
553 EXTRACT_16BITS(&ih->sa_index),
554 ih->ttl,
555 tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
556 ih->type,
557 l2info.length));
558 }
559 }
560
561 ip_print(ndo, p, l2info.length);
562 return l2info.header_len;
563 }
564 #endif
565
566 #ifdef DLT_JUNIPER_MONITOR
567 u_int
568 juniper_monitor_print(netdissect_options *ndo,
569 const struct pcap_pkthdr *h, register const u_char *p)
570 {
571 struct juniper_l2info_t l2info;
572 struct juniper_monitor_header {
573 uint8_t pkt_type;
574 uint8_t padding;
575 uint8_t iif[2];
576 uint8_t service_id[4];
577 };
578 const struct juniper_monitor_header *mh;
579
580 l2info.pictype = DLT_JUNIPER_MONITOR;
581 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
582 return l2info.header_len;
583
584 p+=l2info.header_len;
585 mh = (struct juniper_monitor_header *)p;
586
587 if (ndo->ndo_eflag)
588 ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ",
589 EXTRACT_32BITS(&mh->service_id),
590 EXTRACT_16BITS(&mh->iif),
591 mh->pkt_type));
592
593 /* no proto field - lets guess by first byte of IP header*/
594 ip_heuristic_guess (ndo, p, l2info.length);
595
596 return l2info.header_len;
597 }
598 #endif
599
600 #ifdef DLT_JUNIPER_SERVICES
601 u_int
602 juniper_services_print(netdissect_options *ndo,
603 const struct pcap_pkthdr *h, register const u_char *p)
604 {
605 struct juniper_l2info_t l2info;
606 struct juniper_services_header {
607 uint8_t svc_id;
608 uint8_t flags_len;
609 uint8_t svc_set_id[2];
610 uint8_t dir_iif[4];
611 };
612 const struct juniper_services_header *sh;
613
614 l2info.pictype = DLT_JUNIPER_SERVICES;
615 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
616 return l2info.header_len;
617
618 p+=l2info.header_len;
619 sh = (struct juniper_services_header *)p;
620
621 if (ndo->ndo_eflag)
622 ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
623 sh->svc_id,
624 sh->flags_len,
625 EXTRACT_16BITS(&sh->svc_set_id),
626 EXTRACT_24BITS(&sh->dir_iif[1])));
627
628 /* no proto field - lets guess by first byte of IP header*/
629 ip_heuristic_guess (ndo, p, l2info.length);
630
631 return l2info.header_len;
632 }
633 #endif
634
635 #ifdef DLT_JUNIPER_PPPOE
636 u_int
637 juniper_pppoe_print(netdissect_options *ndo,
638 const struct pcap_pkthdr *h, register const u_char *p)
639 {
640 struct juniper_l2info_t l2info;
641
642 l2info.pictype = DLT_JUNIPER_PPPOE;
643 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
644 return l2info.header_len;
645
646 p+=l2info.header_len;
647 /* this DLT contains nothing but raw ethernet frames */
648 ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
649 return l2info.header_len;
650 }
651 #endif
652
653 #ifdef DLT_JUNIPER_ETHER
654 u_int
655 juniper_ether_print(netdissect_options *ndo,
656 const struct pcap_pkthdr *h, register const u_char *p)
657 {
658 struct juniper_l2info_t l2info;
659
660 l2info.pictype = DLT_JUNIPER_ETHER;
661 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
662 return l2info.header_len;
663
664 p+=l2info.header_len;
665 /* this DLT contains nothing but raw Ethernet frames */
666 ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
667 return l2info.header_len;
668 }
669 #endif
670
671 #ifdef DLT_JUNIPER_PPP
672 u_int
673 juniper_ppp_print(netdissect_options *ndo,
674 const struct pcap_pkthdr *h, register const u_char *p)
675 {
676 struct juniper_l2info_t l2info;
677
678 l2info.pictype = DLT_JUNIPER_PPP;
679 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
680 return l2info.header_len;
681
682 p+=l2info.header_len;
683 /* this DLT contains nothing but raw ppp frames */
684 ppp_print(ndo, p, l2info.length);
685 return l2info.header_len;
686 }
687 #endif
688
689 #ifdef DLT_JUNIPER_FRELAY
690 u_int
691 juniper_frelay_print(netdissect_options *ndo,
692 const struct pcap_pkthdr *h, register const u_char *p)
693 {
694 struct juniper_l2info_t l2info;
695
696 l2info.pictype = DLT_JUNIPER_FRELAY;
697 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
698 return l2info.header_len;
699
700 p+=l2info.header_len;
701 /* this DLT contains nothing but raw frame-relay frames */
702 fr_print(ndo, p, l2info.length);
703 return l2info.header_len;
704 }
705 #endif
706
707 #ifdef DLT_JUNIPER_CHDLC
708 u_int
709 juniper_chdlc_print(netdissect_options *ndo,
710 const struct pcap_pkthdr *h, register const u_char *p)
711 {
712 struct juniper_l2info_t l2info;
713
714 l2info.pictype = DLT_JUNIPER_CHDLC;
715 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
716 return l2info.header_len;
717
718 p+=l2info.header_len;
719 /* this DLT contains nothing but raw c-hdlc frames */
720 chdlc_print(ndo, p, l2info.length);
721 return l2info.header_len;
722 }
723 #endif
724
725 #ifdef DLT_JUNIPER_PPPOE_ATM
726 u_int
727 juniper_pppoe_atm_print(netdissect_options *ndo,
728 const struct pcap_pkthdr *h, register const u_char *p)
729 {
730 struct juniper_l2info_t l2info;
731 uint16_t extracted_ethertype;
732
733 l2info.pictype = DLT_JUNIPER_PPPOE_ATM;
734 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
735 return l2info.header_len;
736
737 p+=l2info.header_len;
738
739 extracted_ethertype = EXTRACT_16BITS(p);
740 /* this DLT contains nothing but raw PPPoE frames,
741 * prepended with a type field*/
742 if (ethertype_print(ndo, extracted_ethertype,
743 p+ETHERTYPE_LEN,
744 l2info.length-ETHERTYPE_LEN,
745 l2info.caplen-ETHERTYPE_LEN) == 0)
746 /* ether_type not known, probably it wasn't one */
747 ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype));
748
749 return l2info.header_len;
750 }
751 #endif
752
753 #ifdef DLT_JUNIPER_MLPPP
754 u_int
755 juniper_mlppp_print(netdissect_options *ndo,
756 const struct pcap_pkthdr *h, register const u_char *p)
757 {
758 struct juniper_l2info_t l2info;
759
760 l2info.pictype = DLT_JUNIPER_MLPPP;
761 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
762 return l2info.header_len;
763
764 /* suppress Bundle-ID if frame was captured on a child-link
765 * best indicator if the cookie looks like a proto */
766 if (ndo->ndo_eflag &&
767 EXTRACT_16BITS(&l2info.cookie) != PPP_OSI &&
768 EXTRACT_16BITS(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL))
769 ND_PRINT((ndo, "Bundle-ID %u: ", l2info.bundle));
770
771 p+=l2info.header_len;
772
773 /* first try the LSQ protos */
774 switch(l2info.proto) {
775 case JUNIPER_LSQ_L3_PROTO_IPV4:
776 /* IP traffic going to the RE would not have a cookie
777 * -> this must be incoming IS-IS over PPP
778 */
779 if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR))
780 ppp_print(ndo, p, l2info.length);
781 else
782 ip_print(ndo, p, l2info.length);
783 return l2info.header_len;
784 case JUNIPER_LSQ_L3_PROTO_IPV6:
785 ip6_print(ndo, p,l2info.length);
786 return l2info.header_len;
787 case JUNIPER_LSQ_L3_PROTO_MPLS:
788 mpls_print(ndo, p, l2info.length);
789 return l2info.header_len;
790 case JUNIPER_LSQ_L3_PROTO_ISO:
791 isoclns_print(ndo, p, l2info.length, l2info.caplen);
792 return l2info.header_len;
793 default:
794 break;
795 }
796
797 /* zero length cookie ? */
798 switch (EXTRACT_16BITS(&l2info.cookie)) {
799 case PPP_OSI:
800 ppp_print(ndo, p - 2, l2info.length + 2);
801 break;
802 case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */
803 default:
804 ppp_print(ndo, p, l2info.length);
805 break;
806 }
807
808 return l2info.header_len;
809 }
810 #endif
811
812
813 #ifdef DLT_JUNIPER_MFR
814 u_int
815 juniper_mfr_print(netdissect_options *ndo,
816 const struct pcap_pkthdr *h, register const u_char *p)
817 {
818 struct juniper_l2info_t l2info;
819
820 l2info.pictype = DLT_JUNIPER_MFR;
821 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
822 return l2info.header_len;
823
824 p+=l2info.header_len;
825
826 /* child-link ? */
827 if (l2info.cookie_len == 0) {
828 mfr_print(ndo, p, l2info.length);
829 return l2info.header_len;
830 }
831
832 /* first try the LSQ protos */
833 if (l2info.cookie_len == AS_PIC_COOKIE_LEN) {
834 switch(l2info.proto) {
835 case JUNIPER_LSQ_L3_PROTO_IPV4:
836 ip_print(ndo, p, l2info.length);
837 return l2info.header_len;
838 case JUNIPER_LSQ_L3_PROTO_IPV6:
839 ip6_print(ndo, p,l2info.length);
840 return l2info.header_len;
841 case JUNIPER_LSQ_L3_PROTO_MPLS:
842 mpls_print(ndo, p, l2info.length);
843 return l2info.header_len;
844 case JUNIPER_LSQ_L3_PROTO_ISO:
845 isoclns_print(ndo, p, l2info.length, l2info.caplen);
846 return l2info.header_len;
847 default:
848 break;
849 }
850 return l2info.header_len;
851 }
852
853 /* suppress Bundle-ID if frame was captured on a child-link */
854 if (ndo->ndo_eflag && EXTRACT_32BITS(l2info.cookie) != 1)
855 ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle));
856 switch (l2info.proto) {
857 case (LLCSAP_ISONS<<8 | LLCSAP_ISONS):
858 isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
859 break;
860 case (LLC_UI<<8 | NLPID_Q933):
861 case (LLC_UI<<8 | NLPID_IP):
862 case (LLC_UI<<8 | NLPID_IP6):
863 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
864 isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
865 break;
866 default:
867 ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
868 }
869
870 return l2info.header_len;
871 }
872 #endif
873
874 #ifdef DLT_JUNIPER_MLFR
875 u_int
876 juniper_mlfr_print(netdissect_options *ndo,
877 const struct pcap_pkthdr *h, register const u_char *p)
878 {
879 struct juniper_l2info_t l2info;
880
881 l2info.pictype = DLT_JUNIPER_MLFR;
882 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
883 return l2info.header_len;
884
885 p+=l2info.header_len;
886
887 /* suppress Bundle-ID if frame was captured on a child-link */
888 if (ndo->ndo_eflag && EXTRACT_32BITS(l2info.cookie) != 1)
889 ND_PRINT((ndo, "Bundle-ID %u, ", l2info.bundle));
890 switch (l2info.proto) {
891 case (LLC_UI):
892 case (LLC_UI<<8):
893 isoclns_print(ndo, p, l2info.length, l2info.caplen);
894 break;
895 case (LLC_UI<<8 | NLPID_Q933):
896 case (LLC_UI<<8 | NLPID_IP):
897 case (LLC_UI<<8 | NLPID_IP6):
898 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
899 isoclns_print(ndo, p - 1, l2info.length + 1, l2info.caplen + 1);
900 break;
901 default:
902 ND_PRINT((ndo, "unknown protocol 0x%04x, length %u", l2info.proto, l2info.length));
903 }
904
905 return l2info.header_len;
906 }
907 #endif
908
909 /*
910 * ATM1 PIC cookie format
911 *
912 * +-----+-------------------------+-------------------------------+
913 * |fmtid| vc index | channel ID |
914 * +-----+-------------------------+-------------------------------+
915 */
916
917 #ifdef DLT_JUNIPER_ATM1
918 u_int
919 juniper_atm1_print(netdissect_options *ndo,
920 const struct pcap_pkthdr *h, register const u_char *p)
921 {
922 uint16_t extracted_ethertype;
923
924 struct juniper_l2info_t l2info;
925
926 l2info.pictype = DLT_JUNIPER_ATM1;
927 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
928 return l2info.header_len;
929
930 p+=l2info.header_len;
931
932 if (l2info.cookie[0] == 0x80) { /* OAM cell ? */
933 oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC);
934 return l2info.header_len;
935 }
936
937 if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
938 EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
939
940 if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL,
941 &extracted_ethertype) != 0)
942 return l2info.header_len;
943 }
944
945 if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
946 isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
947 /* FIXME check if frame was recognized */
948 return l2info.header_len;
949 }
950
951 if (ip_heuristic_guess(ndo, p, l2info.length) != 0) /* last try - vcmux encaps ? */
952 return l2info.header_len;
953
954 return l2info.header_len;
955 }
956 #endif
957
958 /*
959 * ATM2 PIC cookie format
960 *
961 * +-------------------------------+---------+---+-----+-----------+
962 * | channel ID | reserv |AAL| CCRQ| gap cnt |
963 * +-------------------------------+---------+---+-----+-----------+
964 */
965
966 #ifdef DLT_JUNIPER_ATM2
967 u_int
968 juniper_atm2_print(netdissect_options *ndo,
969 const struct pcap_pkthdr *h, register const u_char *p)
970 {
971 uint16_t extracted_ethertype;
972
973 struct juniper_l2info_t l2info;
974
975 l2info.pictype = DLT_JUNIPER_ATM2;
976 if (juniper_parse_header(ndo, p, h, &l2info) == 0)
977 return l2info.header_len;
978
979 p+=l2info.header_len;
980
981 if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */
982 oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC);
983 return l2info.header_len;
984 }
985
986 if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
987 EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
988
989 if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL,
990 &extracted_ethertype) != 0)
991 return l2info.header_len;
992 }
993
994 if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */
995 (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) {
996 ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
997 return l2info.header_len;
998 }
999
1000 if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
1001 isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
1002 /* FIXME check if frame was recognized */
1003 return l2info.header_len;
1004 }
1005
1006 if(juniper_ppp_heuristic_guess(ndo, p, l2info.length) != 0) /* PPPoA vcmux encaps ? */
1007 return l2info.header_len;
1008
1009 if (ip_heuristic_guess(ndo, p, l2info.length) != 0) /* last try - vcmux encaps ? */
1010 return l2info.header_len;
1011
1012 return l2info.header_len;
1013 }
1014 #endif
1015
1016
1017 /* try to guess, based on all PPP protos that are supported in
1018 * a juniper router if the payload data is encapsulated using PPP */
1019 static int
1020 juniper_ppp_heuristic_guess(netdissect_options *ndo,
1021 register const u_char *p, u_int length)
1022 {
1023 switch(EXTRACT_16BITS(p)) {
1024 case PPP_IP :
1025 case PPP_OSI :
1026 case PPP_MPLS_UCAST :
1027 case PPP_MPLS_MCAST :
1028 case PPP_IPCP :
1029 case PPP_OSICP :
1030 case PPP_MPLSCP :
1031 case PPP_LCP :
1032 case PPP_PAP :
1033 case PPP_CHAP :
1034 case PPP_ML :
1035 #ifdef INET6
1036 case PPP_IPV6 :
1037 case PPP_IPV6CP :
1038 #endif
1039 ppp_print(ndo, p, length);
1040 break;
1041
1042 default:
1043 return 0; /* did not find a ppp header */
1044 break;
1045 }
1046 return 1; /* we printed a ppp packet */
1047 }
1048
1049 static int
1050 ip_heuristic_guess(netdissect_options *ndo,
1051 register const u_char *p, u_int length)
1052 {
1053 switch(p[0]) {
1054 case 0x45:
1055 case 0x46:
1056 case 0x47:
1057 case 0x48:
1058 case 0x49:
1059 case 0x4a:
1060 case 0x4b:
1061 case 0x4c:
1062 case 0x4d:
1063 case 0x4e:
1064 case 0x4f:
1065 ip_print(ndo, p, length);
1066 break;
1067 case 0x60:
1068 case 0x61:
1069 case 0x62:
1070 case 0x63:
1071 case 0x64:
1072 case 0x65:
1073 case 0x66:
1074 case 0x67:
1075 case 0x68:
1076 case 0x69:
1077 case 0x6a:
1078 case 0x6b:
1079 case 0x6c:
1080 case 0x6d:
1081 case 0x6e:
1082 case 0x6f:
1083 ip6_print(ndo, p, length);
1084 break;
1085 default:
1086 return 0; /* did not find a ip header */
1087 break;
1088 }
1089 return 1; /* we printed an v4/v6 packet */
1090 }
1091
1092 static int
1093 juniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len)
1094 {
1095 int tlv_value;
1096
1097 /* TLVs < 128 are little endian encoded */
1098 if (tlv_type < 128) {
1099 switch (tlv_len) {
1100 case 1:
1101 tlv_value = *p;
1102 break;
1103 case 2:
1104 tlv_value = EXTRACT_LE_16BITS(p);
1105 break;
1106 case 3:
1107 tlv_value = EXTRACT_LE_24BITS(p);
1108 break;
1109 case 4:
1110 tlv_value = EXTRACT_LE_32BITS(p);
1111 break;
1112 default:
1113 tlv_value = -1;
1114 break;
1115 }
1116 } else {
1117 /* TLVs >= 128 are big endian encoded */
1118 switch (tlv_len) {
1119 case 1:
1120 tlv_value = *p;
1121 break;
1122 case 2:
1123 tlv_value = EXTRACT_16BITS(p);
1124 break;
1125 case 3:
1126 tlv_value = EXTRACT_24BITS(p);
1127 break;
1128 case 4:
1129 tlv_value = EXTRACT_32BITS(p);
1130 break;
1131 default:
1132 tlv_value = -1;
1133 break;
1134 }
1135 }
1136 return tlv_value;
1137 }
1138
1139 static int
1140 juniper_parse_header(netdissect_options *ndo,
1141 const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info)
1142 {
1143 const struct juniper_cookie_table_t *lp = juniper_cookie_table;
1144 u_int idx, jnx_ext_len, jnx_header_len = 0;
1145 uint8_t tlv_type,tlv_len;
1146 uint32_t control_word;
1147 int tlv_value;
1148 const u_char *tptr;
1149
1150
1151 l2info->header_len = 0;
1152 l2info->cookie_len = 0;
1153 l2info->proto = 0;
1154
1155
1156 l2info->length = h->len;
1157 l2info->caplen = h->caplen;
1158 ND_TCHECK2(p[0], 4);
1159 l2info->flags = p[3];
1160 l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
1161
1162 if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
1163 ND_PRINT((ndo, "no magic-number found!"));
1164 return 0;
1165 }
1166
1167 if (ndo->ndo_eflag) /* print direction */
1168 ND_PRINT((ndo, "%3s ", tok2str(juniper_direction_values, "---", l2info->direction)));
1169
1170 /* magic number + flags */
1171 jnx_header_len = 4;
1172
1173 if (ndo->ndo_vflag > 1)
1174 ND_PRINT((ndo, "\n\tJuniper PCAP Flags [%s]",
1175 bittok2str(jnx_flag_values, "none", l2info->flags)));
1176
1177 /* extensions present ? - calculate how much bytes to skip */
1178 if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {
1179
1180 tptr = p+jnx_header_len;
1181
1182 /* ok to read extension length ? */
1183 ND_TCHECK2(tptr[0], 2);
1184 jnx_ext_len = EXTRACT_16BITS(tptr);
1185 jnx_header_len += 2;
1186 tptr +=2;
1187
1188 /* nail up the total length -
1189 * just in case something goes wrong
1190 * with TLV parsing */
1191 jnx_header_len += jnx_ext_len;
1192
1193 if (ndo->ndo_vflag > 1)
1194 ND_PRINT((ndo, ", PCAP Extension(s) total length %u", jnx_ext_len));
1195
1196 ND_TCHECK2(tptr[0], jnx_ext_len);
1197 while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) {
1198 tlv_type = *(tptr++);
1199 tlv_len = *(tptr++);
1200 tlv_value = 0;
1201
1202 /* sanity check */
1203 if (tlv_type == 0 || tlv_len == 0)
1204 break;
1205
1206 if (ndo->ndo_vflag > 1)
1207 ND_PRINT((ndo, "\n\t %s Extension TLV #%u, length %u, value ",
1208 tok2str(jnx_ext_tlv_values,"Unknown",tlv_type),
1209 tlv_type,
1210 tlv_len));
1211
1212 tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len);
1213 switch (tlv_type) {
1214 case JUNIPER_EXT_TLV_IFD_NAME:
1215 /* FIXME */
1216 break;
1217 case JUNIPER_EXT_TLV_IFD_MEDIATYPE:
1218 case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE:
1219 if (tlv_value != -1) {
1220 if (ndo->ndo_vflag > 1)
1221 ND_PRINT((ndo, "%s (%u)",
1222 tok2str(juniper_ifmt_values, "Unknown", tlv_value),
1223 tlv_value));
1224 }
1225 break;
1226 case JUNIPER_EXT_TLV_IFL_ENCAPS:
1227 case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS:
1228 if (tlv_value != -1) {
1229 if (ndo->ndo_vflag > 1)
1230 ND_PRINT((ndo, "%s (%u)",
1231 tok2str(juniper_ifle_values, "Unknown", tlv_value),
1232 tlv_value));
1233 }
1234 break;
1235 case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */
1236 case JUNIPER_EXT_TLV_IFL_UNIT:
1237 case JUNIPER_EXT_TLV_IFD_IDX:
1238 default:
1239 if (tlv_value != -1) {
1240 if (ndo->ndo_vflag > 1)
1241 ND_PRINT((ndo, "%u", tlv_value));
1242 }
1243 break;
1244 }
1245
1246 tptr+=tlv_len;
1247 jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD;
1248 }
1249
1250 if (ndo->ndo_vflag > 1)
1251 ND_PRINT((ndo, "\n\t-----original packet-----\n\t"));
1252 }
1253
1254 if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {
1255 if (ndo->ndo_eflag)
1256 ND_PRINT((ndo, "no-L2-hdr, "));
1257
1258 /* there is no link-layer present -
1259 * perform the v4/v6 heuristics
1260 * to figure out what it is
1261 */
1262 ND_TCHECK2(p[jnx_header_len + 4], 1);
1263 if (ip_heuristic_guess(ndo, p + jnx_header_len + 4,
1264 l2info->length - (jnx_header_len + 4)) == 0)
1265 ND_PRINT((ndo, "no IP-hdr found!"));
1266
1267 l2info->header_len=jnx_header_len+4;
1268 return 0; /* stop parsing the output further */
1269
1270 }
1271 l2info->header_len = jnx_header_len;
1272 p+=l2info->header_len;
1273 l2info->length -= l2info->header_len;
1274 l2info->caplen -= l2info->header_len;
1275
1276 /* search through the cookie table and copy values matching for our PIC type */
1277 while (lp->s != NULL) {
1278 if (lp->pictype == l2info->pictype) {
1279
1280 l2info->cookie_len += lp->cookie_len;
1281
1282 switch (p[0]) {
1283 case LS_COOKIE_ID:
1284 l2info->cookie_type = LS_COOKIE_ID;
1285 l2info->cookie_len += 2;
1286 break;
1287 case AS_COOKIE_ID:
1288 l2info->cookie_type = AS_COOKIE_ID;
1289 l2info->cookie_len = 8;
1290 break;
1291
1292 default:
1293 l2info->bundle = l2info->cookie[0];
1294 break;
1295 }
1296
1297
1298 #ifdef DLT_JUNIPER_MFR
1299 /* MFR child links don't carry cookies */
1300 if (l2info->pictype == DLT_JUNIPER_MFR &&
1301 (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
1302 l2info->cookie_len = 0;
1303 }
1304 #endif
1305
1306 l2info->header_len += l2info->cookie_len;
1307 l2info->length -= l2info->cookie_len;
1308 l2info->caplen -= l2info->cookie_len;
1309
1310 if (ndo->ndo_eflag)
1311 ND_PRINT((ndo, "%s-PIC, cookie-len %u",
1312 lp->s,
1313 l2info->cookie_len));
1314
1315 if (l2info->cookie_len > 0) {
1316 ND_TCHECK2(p[0], l2info->cookie_len);
1317 if (ndo->ndo_eflag)
1318 ND_PRINT((ndo, ", cookie 0x"));
1319 for (idx = 0; idx < l2info->cookie_len; idx++) {
1320 l2info->cookie[idx] = p[idx]; /* copy cookie data */
1321 if (ndo->ndo_eflag) ND_PRINT((ndo, "%02x", p[idx]));
1322 }
1323 }
1324
1325 if (ndo->ndo_eflag) ND_PRINT((ndo, ": ")); /* print demarc b/w L2/L3*/
1326
1327
1328 l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len);
1329 break;
1330 }
1331 ++lp;
1332 }
1333 p+=l2info->cookie_len;
1334
1335 /* DLT_ specific parsing */
1336 switch(l2info->pictype) {
1337 #ifdef DLT_JUNIPER_MLPPP
1338 case DLT_JUNIPER_MLPPP:
1339 switch (l2info->cookie_type) {
1340 case LS_COOKIE_ID:
1341 l2info->bundle = l2info->cookie[1];
1342 break;
1343 case AS_COOKIE_ID:
1344 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
1345 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
1346 break;
1347 default:
1348 l2info->bundle = l2info->cookie[0];
1349 break;
1350 }
1351 break;
1352 #endif
1353 #ifdef DLT_JUNIPER_MLFR
1354 case DLT_JUNIPER_MLFR:
1355 switch (l2info->cookie_type) {
1356 case LS_COOKIE_ID:
1357 l2info->bundle = l2info->cookie[1];
1358 l2info->proto = EXTRACT_16BITS(p);
1359 l2info->header_len += 2;
1360 l2info->length -= 2;
1361 l2info->caplen -= 2;
1362 break;
1363 case AS_COOKIE_ID:
1364 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
1365 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
1366 break;
1367 default:
1368 l2info->bundle = l2info->cookie[0];
1369 l2info->header_len += 2;
1370 l2info->length -= 2;
1371 l2info->caplen -= 2;
1372 break;
1373 }
1374 break;
1375 #endif
1376 #ifdef DLT_JUNIPER_MFR
1377 case DLT_JUNIPER_MFR:
1378 switch (l2info->cookie_type) {
1379 case LS_COOKIE_ID:
1380 l2info->bundle = l2info->cookie[1];
1381 l2info->proto = EXTRACT_16BITS(p);
1382 l2info->header_len += 2;
1383 l2info->length -= 2;
1384 l2info->caplen -= 2;
1385 break;
1386 case AS_COOKIE_ID:
1387 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
1388 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
1389 break;
1390 default:
1391 l2info->bundle = l2info->cookie[0];
1392 break;
1393 }
1394 break;
1395 #endif
1396 #ifdef DLT_JUNIPER_ATM2
1397 case DLT_JUNIPER_ATM2:
1398 ND_TCHECK2(p[0], 4);
1399 /* ATM cell relay control word present ? */
1400 if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
1401 control_word = EXTRACT_32BITS(p);
1402 /* some control word heuristics */
1403 switch(control_word) {
1404 case 0: /* zero control word */
1405 case 0x08000000: /* < JUNOS 7.4 control-word */
1406 case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
1407 l2info->header_len += 4;
1408 break;
1409 default:
1410 break;
1411 }
1412
1413 if (ndo->ndo_eflag)
1414 ND_PRINT((ndo, "control-word 0x%08x ", control_word));
1415 }
1416 break;
1417 #endif
1418 #ifdef DLT_JUNIPER_GGSN
1419 case DLT_JUNIPER_GGSN:
1420 break;
1421 #endif
1422 #ifdef DLT_JUNIPER_ATM1
1423 case DLT_JUNIPER_ATM1:
1424 break;
1425 #endif
1426 #ifdef DLT_JUNIPER_PPP
1427 case DLT_JUNIPER_PPP:
1428 break;
1429 #endif
1430 #ifdef DLT_JUNIPER_CHDLC
1431 case DLT_JUNIPER_CHDLC:
1432 break;
1433 #endif
1434 #ifdef DLT_JUNIPER_ETHER
1435 case DLT_JUNIPER_ETHER:
1436 break;
1437 #endif
1438 #ifdef DLT_JUNIPER_FRELAY
1439 case DLT_JUNIPER_FRELAY:
1440 break;
1441 #endif
1442
1443 default:
1444 ND_PRINT((ndo, "Unknown Juniper DLT_ type %u: ", l2info->pictype));
1445 break;
1446 }
1447
1448 if (ndo->ndo_eflag > 1)
1449 ND_PRINT((ndo, "hlen %u, proto 0x%04x, ", l2info->header_len, l2info->proto));
1450
1451 return 1; /* everything went ok so far. continue parsing */
1452 trunc:
1453 ND_PRINT((ndo, "[|juniper_hdr], length %u", h->len));
1454 return 0;
1455 }
1456
1457
1458 /*
1459 * Local Variables:
1460 * c-style: whitesmith
1461 * c-basic-offset: 4
1462 * End:
1463 */