1190207Srpaulo/*     NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp        */
2190207Srpaulo
3146773Ssam/*
4146773Ssam * Redistribution and use in source and binary forms, with or without
5146773Ssam * modification, are permitted provided that: (1) source code
6146773Ssam * distributions retain the above copyright notice and this paragraph
7146773Ssam * in its entirety, and (2) distributions including binary code include
8146773Ssam * the above copyright notice and this paragraph in its entirety in
9146773Ssam * the documentation or other materials provided with the distribution.
10146773Ssam * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11146773Ssam * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12146773Ssam * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13146773Ssam * FOR A PARTICULAR PURPOSE.
14146773Ssam *
15146773Ssam * Original code by Hannes Gredler (hannes@juniper.net)
16146773Ssam */
17146773Ssam
18146773Ssam#ifndef lint
19146773Ssamstatic const char rcsid[] _U_ =
20190207Srpaulo    "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.34 2007-08-29 02:31:44 mcr Exp $ (LBL)";
21190207Srpaulo#else
22190207Srpaulo__RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp ");
23146773Ssam#endif
24146773Ssam
25146773Ssam#ifdef HAVE_CONFIG_H
26146773Ssam#include "config.h"
27146773Ssam#endif
28146773Ssam
29146773Ssam#include <tcpdump-stdinc.h>
30146773Ssam
31146773Ssam#include <pcap.h>
32146773Ssam#include <stdio.h>
33146773Ssam
34146773Ssam#include "interface.h"
35147899Ssam#include "addrtoname.h"
36146773Ssam#include "extract.h"
37146773Ssam#include "ppp.h"
38146773Ssam#include "llc.h"
39146773Ssam#include "nlpid.h"
40147899Ssam#include "ethertype.h"
41147899Ssam#include "atm.h"
42146773Ssam
43146773Ssam#define JUNIPER_BPF_OUT           0       /* Outgoing packet */
44146773Ssam#define JUNIPER_BPF_IN            1       /* Incoming packet */
45146773Ssam#define JUNIPER_BPF_PKT_IN        0x1     /* Incoming packet */
46146773Ssam#define JUNIPER_BPF_NO_L2         0x2     /* L2 header stripped */
47190207Srpaulo#define JUNIPER_BPF_IIF           0x4     /* IIF is valid */
48190207Srpaulo#define JUNIPER_BPF_FILTER        0x40    /* BPF filtering is supported */
49162017Ssam#define JUNIPER_BPF_EXT           0x80    /* extensions present */
50147899Ssam#define JUNIPER_MGC_NUMBER        0x4d4743 /* = "MGC" */
51146773Ssam
52162017Ssam#define JUNIPER_LSQ_COOKIE_RE         (1 << 3)
53162017Ssam#define JUNIPER_LSQ_COOKIE_DIR        (1 << 2)
54147899Ssam#define JUNIPER_LSQ_L3_PROTO_SHIFT     4
55147899Ssam#define JUNIPER_LSQ_L3_PROTO_MASK     (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
56147899Ssam#define JUNIPER_LSQ_L3_PROTO_IPV4     (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
57147899Ssam#define JUNIPER_LSQ_L3_PROTO_IPV6     (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
58147899Ssam#define JUNIPER_LSQ_L3_PROTO_MPLS     (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
59147899Ssam#define JUNIPER_LSQ_L3_PROTO_ISO      (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
60162017Ssam#define AS_PIC_COOKIE_LEN 8
61147899Ssam
62147899Ssam#define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
63147899Ssam#define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
64147899Ssam#define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
65147899Ssam#define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
66147899Ssam#define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
67147899Ssam
68147899Ssamstatic struct tok juniper_ipsec_type_values[] = {
69147899Ssam    { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" },
70147899Ssam    { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" },
71147899Ssam    { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE, "ESP AUTH" },
72147899Ssam    { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE, "AH AUTH" },
73147899Ssam    { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" },
74147899Ssam    { 0, NULL}
75147899Ssam};
76147899Ssam
77147899Ssamstatic struct tok juniper_direction_values[] = {
78147899Ssam    { JUNIPER_BPF_IN,  "In"},
79147899Ssam    { JUNIPER_BPF_OUT, "Out"},
80147899Ssam    { 0, NULL}
81147899Ssam};
82147899Ssam
83190207Srpaulo/* codepoints for encoding extensions to a .pcap file */
84190207Srpauloenum {
85190207Srpaulo    JUNIPER_EXT_TLV_IFD_IDX = 1,
86190207Srpaulo    JUNIPER_EXT_TLV_IFD_NAME = 2,
87190207Srpaulo    JUNIPER_EXT_TLV_IFD_MEDIATYPE = 3,
88190207Srpaulo    JUNIPER_EXT_TLV_IFL_IDX = 4,
89190207Srpaulo    JUNIPER_EXT_TLV_IFL_UNIT = 5,
90190207Srpaulo    JUNIPER_EXT_TLV_IFL_ENCAPS = 6,
91190207Srpaulo    JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE = 7,
92190207Srpaulo    JUNIPER_EXT_TLV_TTP_IFL_ENCAPS = 8
93190207Srpaulo};
94190207Srpaulo
95190207Srpaulo/* 1 byte type and 1-byte length */
96190207Srpaulo#define JUNIPER_EXT_TLV_OVERHEAD 2
97190207Srpaulo
98190207Srpaulostruct tok jnx_ext_tlv_values[] = {
99190207Srpaulo    { JUNIPER_EXT_TLV_IFD_IDX, "Device Interface Index" },
100190207Srpaulo    { JUNIPER_EXT_TLV_IFD_NAME,"Device Interface Name" },
101190207Srpaulo    { JUNIPER_EXT_TLV_IFD_MEDIATYPE, "Device Media Type" },
102190207Srpaulo    { JUNIPER_EXT_TLV_IFL_IDX, "Logical Interface Index" },
103190207Srpaulo    { JUNIPER_EXT_TLV_IFL_UNIT,"Logical Unit Number" },
104190207Srpaulo    { JUNIPER_EXT_TLV_IFL_ENCAPS, "Logical Interface Encapsulation" },
105190207Srpaulo    { JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" },
106190207Srpaulo    { JUNIPER_EXT_TLV_TTP_IFL_ENCAPS, "TTP derived Logical Interface Encapsulation" },
107190207Srpaulo    { 0, NULL }
108190207Srpaulo};
109190207Srpaulo
110190207Srpaulostruct tok jnx_flag_values[] = {
111190207Srpaulo    { JUNIPER_BPF_EXT, "Ext" },
112190207Srpaulo    { JUNIPER_BPF_FILTER, "Filter" },
113190207Srpaulo    { JUNIPER_BPF_IIF, "IIF" },
114190207Srpaulo    { JUNIPER_BPF_NO_L2, "no-L2" },
115190207Srpaulo    { JUNIPER_BPF_PKT_IN, "In" },
116190207Srpaulo    { 0, NULL }
117190207Srpaulo};
118190207Srpaulo
119190207Srpaulo#define JUNIPER_IFML_ETHER              1
120190207Srpaulo#define JUNIPER_IFML_FDDI               2
121190207Srpaulo#define JUNIPER_IFML_TOKENRING          3
122190207Srpaulo#define JUNIPER_IFML_PPP                4
123190207Srpaulo#define JUNIPER_IFML_FRAMERELAY         5
124190207Srpaulo#define JUNIPER_IFML_CISCOHDLC          6
125190207Srpaulo#define JUNIPER_IFML_SMDSDXI            7
126190207Srpaulo#define JUNIPER_IFML_ATMPVC             8
127190207Srpaulo#define JUNIPER_IFML_PPP_CCC            9
128190207Srpaulo#define JUNIPER_IFML_FRAMERELAY_CCC     10
129190207Srpaulo#define JUNIPER_IFML_IPIP               11
130190207Srpaulo#define JUNIPER_IFML_GRE                12
131190207Srpaulo#define JUNIPER_IFML_PIM                13
132190207Srpaulo#define JUNIPER_IFML_PIMD               14
133190207Srpaulo#define JUNIPER_IFML_CISCOHDLC_CCC      15
134190207Srpaulo#define JUNIPER_IFML_VLAN_CCC           16
135190207Srpaulo#define JUNIPER_IFML_MLPPP              17
136190207Srpaulo#define JUNIPER_IFML_MLFR               18
137190207Srpaulo#define JUNIPER_IFML_ML                 19
138190207Srpaulo#define JUNIPER_IFML_LSI                20
139190207Srpaulo#define JUNIPER_IFML_DFE                21
140190207Srpaulo#define JUNIPER_IFML_ATM_CELLRELAY_CCC  22
141190207Srpaulo#define JUNIPER_IFML_CRYPTO             23
142190207Srpaulo#define JUNIPER_IFML_GGSN               24
143190207Srpaulo#define JUNIPER_IFML_LSI_PPP            25
144190207Srpaulo#define JUNIPER_IFML_LSI_CISCOHDLC      26
145190207Srpaulo#define JUNIPER_IFML_PPP_TCC            27
146190207Srpaulo#define JUNIPER_IFML_FRAMERELAY_TCC     28
147190207Srpaulo#define JUNIPER_IFML_CISCOHDLC_TCC      29
148190207Srpaulo#define JUNIPER_IFML_ETHERNET_CCC       30
149190207Srpaulo#define JUNIPER_IFML_VT                 31
150190207Srpaulo#define JUNIPER_IFML_EXTENDED_VLAN_CCC  32
151190207Srpaulo#define JUNIPER_IFML_ETHER_OVER_ATM     33
152190207Srpaulo#define JUNIPER_IFML_MONITOR            34
153190207Srpaulo#define JUNIPER_IFML_ETHERNET_TCC       35
154190207Srpaulo#define JUNIPER_IFML_VLAN_TCC           36
155190207Srpaulo#define JUNIPER_IFML_EXTENDED_VLAN_TCC  37
156190207Srpaulo#define JUNIPER_IFML_CONTROLLER         38
157190207Srpaulo#define JUNIPER_IFML_MFR                39
158190207Srpaulo#define JUNIPER_IFML_LS                 40
159190207Srpaulo#define JUNIPER_IFML_ETHERNET_VPLS      41
160190207Srpaulo#define JUNIPER_IFML_ETHERNET_VLAN_VPLS 42
161190207Srpaulo#define JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS 43
162190207Srpaulo#define JUNIPER_IFML_LT                 44
163190207Srpaulo#define JUNIPER_IFML_SERVICES           45
164190207Srpaulo#define JUNIPER_IFML_ETHER_VPLS_OVER_ATM 46
165190207Srpaulo#define JUNIPER_IFML_FR_PORT_CCC        47
166190207Srpaulo#define JUNIPER_IFML_FRAMERELAY_EXT_CCC 48
167190207Srpaulo#define JUNIPER_IFML_FRAMERELAY_EXT_TCC 49
168190207Srpaulo#define JUNIPER_IFML_FRAMERELAY_FLEX    50
169190207Srpaulo#define JUNIPER_IFML_GGSNI              51
170190207Srpaulo#define JUNIPER_IFML_ETHERNET_FLEX      52
171190207Srpaulo#define JUNIPER_IFML_COLLECTOR          53
172190207Srpaulo#define JUNIPER_IFML_AGGREGATOR         54
173190207Srpaulo#define JUNIPER_IFML_LAPD               55
174190207Srpaulo#define JUNIPER_IFML_PPPOE              56
175190207Srpaulo#define JUNIPER_IFML_PPP_SUBORDINATE    57
176190207Srpaulo#define JUNIPER_IFML_CISCOHDLC_SUBORDINATE  58
177190207Srpaulo#define JUNIPER_IFML_DFC                59
178190207Srpaulo#define JUNIPER_IFML_PICPEER            60
179190207Srpaulo
180190207Srpaulostruct tok juniper_ifmt_values[] = {
181190207Srpaulo    { JUNIPER_IFML_ETHER, "Ethernet" },
182190207Srpaulo    { JUNIPER_IFML_FDDI, "FDDI" },
183190207Srpaulo    { JUNIPER_IFML_TOKENRING, "Token-Ring" },
184190207Srpaulo    { JUNIPER_IFML_PPP, "PPP" },
185190207Srpaulo    { JUNIPER_IFML_PPP_SUBORDINATE, "PPP-Subordinate" },
186190207Srpaulo    { JUNIPER_IFML_FRAMERELAY, "Frame-Relay" },
187190207Srpaulo    { JUNIPER_IFML_CISCOHDLC, "Cisco-HDLC" },
188190207Srpaulo    { JUNIPER_IFML_SMDSDXI, "SMDS-DXI" },
189190207Srpaulo    { JUNIPER_IFML_ATMPVC, "ATM-PVC" },
190190207Srpaulo    { JUNIPER_IFML_PPP_CCC, "PPP-CCC" },
191190207Srpaulo    { JUNIPER_IFML_FRAMERELAY_CCC, "Frame-Relay-CCC" },
192190207Srpaulo    { JUNIPER_IFML_FRAMERELAY_EXT_CCC, "Extended FR-CCC" },
193190207Srpaulo    { JUNIPER_IFML_IPIP, "IP-over-IP" },
194190207Srpaulo    { JUNIPER_IFML_GRE, "GRE" },
195190207Srpaulo    { JUNIPER_IFML_PIM, "PIM-Encapsulator" },
196190207Srpaulo    { JUNIPER_IFML_PIMD, "PIM-Decapsulator" },
197190207Srpaulo    { JUNIPER_IFML_CISCOHDLC_CCC, "Cisco-HDLC-CCC" },
198190207Srpaulo    { JUNIPER_IFML_VLAN_CCC, "VLAN-CCC" },
199190207Srpaulo    { JUNIPER_IFML_EXTENDED_VLAN_CCC, "Extended-VLAN-CCC" },
200190207Srpaulo    { JUNIPER_IFML_MLPPP, "Multilink-PPP" },
201190207Srpaulo    { JUNIPER_IFML_MLFR, "Multilink-FR" },
202190207Srpaulo    { JUNIPER_IFML_MFR, "Multilink-FR-UNI-NNI" },
203190207Srpaulo    { JUNIPER_IFML_ML, "Multilink" },
204190207Srpaulo    { JUNIPER_IFML_LS, "LinkService" },
205190207Srpaulo    { JUNIPER_IFML_LSI, "LSI" },
206190207Srpaulo    { JUNIPER_IFML_ATM_CELLRELAY_CCC, "ATM-CCC-Cell-Relay" },
207190207Srpaulo    { JUNIPER_IFML_CRYPTO, "IPSEC-over-IP" },
208190207Srpaulo    { JUNIPER_IFML_GGSN, "GGSN" },
209190207Srpaulo    { JUNIPER_IFML_PPP_TCC, "PPP-TCC" },
210190207Srpaulo    { JUNIPER_IFML_FRAMERELAY_TCC, "Frame-Relay-TCC" },
211190207Srpaulo    { JUNIPER_IFML_FRAMERELAY_EXT_TCC, "Extended FR-TCC" },
212190207Srpaulo    { JUNIPER_IFML_CISCOHDLC_TCC, "Cisco-HDLC-TCC" },
213190207Srpaulo    { JUNIPER_IFML_ETHERNET_CCC, "Ethernet-CCC" },
214190207Srpaulo    { JUNIPER_IFML_VT, "VPN-Loopback-tunnel" },
215190207Srpaulo    { JUNIPER_IFML_ETHER_OVER_ATM, "Ethernet-over-ATM" },
216190207Srpaulo    { JUNIPER_IFML_ETHER_VPLS_OVER_ATM, "Ethernet-VPLS-over-ATM" },
217190207Srpaulo    { JUNIPER_IFML_MONITOR, "Monitor" },
218190207Srpaulo    { JUNIPER_IFML_ETHERNET_TCC, "Ethernet-TCC" },
219190207Srpaulo    { JUNIPER_IFML_VLAN_TCC, "VLAN-TCC" },
220190207Srpaulo    { JUNIPER_IFML_EXTENDED_VLAN_TCC, "Extended-VLAN-TCC" },
221190207Srpaulo    { JUNIPER_IFML_CONTROLLER, "Controller" },
222190207Srpaulo    { JUNIPER_IFML_ETHERNET_VPLS, "VPLS" },
223190207Srpaulo    { JUNIPER_IFML_ETHERNET_VLAN_VPLS, "VLAN-VPLS" },
224190207Srpaulo    { JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS, "Extended-VLAN-VPLS" },
225190207Srpaulo    { JUNIPER_IFML_LT, "Logical-tunnel" },
226190207Srpaulo    { JUNIPER_IFML_SERVICES, "General-Services" },
227190207Srpaulo    { JUNIPER_IFML_PPPOE, "PPPoE" },
228190207Srpaulo    { JUNIPER_IFML_ETHERNET_FLEX, "Flexible-Ethernet-Services" },
229190207Srpaulo    { JUNIPER_IFML_FRAMERELAY_FLEX, "Flexible-FrameRelay" },
230190207Srpaulo    { JUNIPER_IFML_COLLECTOR, "Flow-collection" },
231190207Srpaulo    { JUNIPER_IFML_PICPEER, "PIC Peer" },
232190207Srpaulo    { JUNIPER_IFML_DFC, "Dynamic-Flow-Capture" },
233190207Srpaulo    {0,                    NULL}
234190207Srpaulo};
235190207Srpaulo
236190207Srpaulo#define JUNIPER_IFLE_ATM_SNAP           2
237190207Srpaulo#define JUNIPER_IFLE_ATM_NLPID          3
238190207Srpaulo#define JUNIPER_IFLE_ATM_VCMUX          4
239190207Srpaulo#define JUNIPER_IFLE_ATM_LLC            5
240190207Srpaulo#define JUNIPER_IFLE_ATM_PPP_VCMUX      6
241190207Srpaulo#define JUNIPER_IFLE_ATM_PPP_LLC        7
242190207Srpaulo#define JUNIPER_IFLE_ATM_PPP_FUNI       8
243190207Srpaulo#define JUNIPER_IFLE_ATM_CCC            9
244190207Srpaulo#define JUNIPER_IFLE_FR_NLPID           10
245190207Srpaulo#define JUNIPER_IFLE_FR_SNAP            11
246190207Srpaulo#define JUNIPER_IFLE_FR_PPP             12
247190207Srpaulo#define JUNIPER_IFLE_FR_CCC             13
248190207Srpaulo#define JUNIPER_IFLE_ENET2              14
249190207Srpaulo#define JUNIPER_IFLE_IEEE8023_SNAP      15
250190207Srpaulo#define JUNIPER_IFLE_IEEE8023_LLC       16
251190207Srpaulo#define JUNIPER_IFLE_PPP                17
252190207Srpaulo#define JUNIPER_IFLE_CISCOHDLC          18
253190207Srpaulo#define JUNIPER_IFLE_PPP_CCC            19
254190207Srpaulo#define JUNIPER_IFLE_IPIP_NULL          20
255190207Srpaulo#define JUNIPER_IFLE_PIM_NULL           21
256190207Srpaulo#define JUNIPER_IFLE_GRE_NULL           22
257190207Srpaulo#define JUNIPER_IFLE_GRE_PPP            23
258190207Srpaulo#define JUNIPER_IFLE_PIMD_DECAPS        24
259190207Srpaulo#define JUNIPER_IFLE_CISCOHDLC_CCC      25
260190207Srpaulo#define JUNIPER_IFLE_ATM_CISCO_NLPID    26
261190207Srpaulo#define JUNIPER_IFLE_VLAN_CCC           27
262190207Srpaulo#define JUNIPER_IFLE_MLPPP              28
263190207Srpaulo#define JUNIPER_IFLE_MLFR               29
264190207Srpaulo#define JUNIPER_IFLE_LSI_NULL           30
265190207Srpaulo#define JUNIPER_IFLE_AGGREGATE_UNUSED   31
266190207Srpaulo#define JUNIPER_IFLE_ATM_CELLRELAY_CCC  32
267190207Srpaulo#define JUNIPER_IFLE_CRYPTO             33
268190207Srpaulo#define JUNIPER_IFLE_GGSN               34
269190207Srpaulo#define JUNIPER_IFLE_ATM_TCC            35
270190207Srpaulo#define JUNIPER_IFLE_FR_TCC             36
271190207Srpaulo#define JUNIPER_IFLE_PPP_TCC            37
272190207Srpaulo#define JUNIPER_IFLE_CISCOHDLC_TCC      38
273190207Srpaulo#define JUNIPER_IFLE_ETHERNET_CCC       39
274190207Srpaulo#define JUNIPER_IFLE_VT                 40
275190207Srpaulo#define JUNIPER_IFLE_ATM_EOA_LLC        41
276190207Srpaulo#define JUNIPER_IFLE_EXTENDED_VLAN_CCC          42
277190207Srpaulo#define JUNIPER_IFLE_ATM_SNAP_TCC       43
278190207Srpaulo#define JUNIPER_IFLE_MONITOR            44
279190207Srpaulo#define JUNIPER_IFLE_ETHERNET_TCC       45
280190207Srpaulo#define JUNIPER_IFLE_VLAN_TCC           46
281190207Srpaulo#define JUNIPER_IFLE_EXTENDED_VLAN_TCC  47
282190207Srpaulo#define JUNIPER_IFLE_MFR                48
283190207Srpaulo#define JUNIPER_IFLE_ETHERNET_VPLS      49
284190207Srpaulo#define JUNIPER_IFLE_ETHERNET_VLAN_VPLS 50
285190207Srpaulo#define JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS 51
286190207Srpaulo#define JUNIPER_IFLE_SERVICES           52
287190207Srpaulo#define JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC                53
288190207Srpaulo#define JUNIPER_IFLE_FR_PORT_CCC        54
289190207Srpaulo#define JUNIPER_IFLE_ATM_MLPPP_LLC      55
290190207Srpaulo#define JUNIPER_IFLE_ATM_EOA_CCC        56
291190207Srpaulo#define JUNIPER_IFLE_LT_VLAN            57
292190207Srpaulo#define JUNIPER_IFLE_COLLECTOR          58
293190207Srpaulo#define JUNIPER_IFLE_AGGREGATOR         59
294190207Srpaulo#define JUNIPER_IFLE_LAPD               60
295190207Srpaulo#define JUNIPER_IFLE_ATM_PPPOE_LLC          61
296190207Srpaulo#define JUNIPER_IFLE_ETHERNET_PPPOE         62
297190207Srpaulo#define JUNIPER_IFLE_PPPOE                  63
298190207Srpaulo#define JUNIPER_IFLE_PPP_SUBORDINATE        64
299190207Srpaulo#define JUNIPER_IFLE_CISCOHDLC_SUBORDINATE  65
300190207Srpaulo#define JUNIPER_IFLE_DFC                    66
301190207Srpaulo#define JUNIPER_IFLE_PICPEER                67
302190207Srpaulo
303190207Srpaulostruct tok juniper_ifle_values[] = {
304190207Srpaulo    { JUNIPER_IFLE_AGGREGATOR, "Aggregator" },
305190207Srpaulo    { JUNIPER_IFLE_ATM_CCC, "CCC over ATM" },
306190207Srpaulo    { JUNIPER_IFLE_ATM_CELLRELAY_CCC, "ATM CCC Cell Relay" },
307190207Srpaulo    { JUNIPER_IFLE_ATM_CISCO_NLPID, "CISCO compatible NLPID" },
308190207Srpaulo    { JUNIPER_IFLE_ATM_EOA_CCC, "Ethernet over ATM CCC" },
309190207Srpaulo    { JUNIPER_IFLE_ATM_EOA_LLC, "Ethernet over ATM LLC" },
310190207Srpaulo    { JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC, "Ethernet VPLS over ATM LLC" },
311190207Srpaulo    { JUNIPER_IFLE_ATM_LLC, "ATM LLC" },
312190207Srpaulo    { JUNIPER_IFLE_ATM_MLPPP_LLC, "MLPPP over ATM LLC" },
313190207Srpaulo    { JUNIPER_IFLE_ATM_NLPID, "ATM NLPID" },
314190207Srpaulo    { JUNIPER_IFLE_ATM_PPPOE_LLC, "PPPoE over ATM LLC" },
315190207Srpaulo    { JUNIPER_IFLE_ATM_PPP_FUNI, "PPP over FUNI" },
316190207Srpaulo    { JUNIPER_IFLE_ATM_PPP_LLC, "PPP over ATM LLC" },
317190207Srpaulo    { JUNIPER_IFLE_ATM_PPP_VCMUX, "PPP over ATM VCMUX" },
318190207Srpaulo    { JUNIPER_IFLE_ATM_SNAP, "ATM SNAP" },
319190207Srpaulo    { JUNIPER_IFLE_ATM_SNAP_TCC, "ATM SNAP TCC" },
320190207Srpaulo    { JUNIPER_IFLE_ATM_TCC, "ATM VCMUX TCC" },
321190207Srpaulo    { JUNIPER_IFLE_ATM_VCMUX, "ATM VCMUX" },
322190207Srpaulo    { JUNIPER_IFLE_CISCOHDLC, "C-HDLC" },
323190207Srpaulo    { JUNIPER_IFLE_CISCOHDLC_CCC, "C-HDLC CCC" },
324190207Srpaulo    { JUNIPER_IFLE_CISCOHDLC_SUBORDINATE, "C-HDLC via dialer" },
325190207Srpaulo    { JUNIPER_IFLE_CISCOHDLC_TCC, "C-HDLC TCC" },
326190207Srpaulo    { JUNIPER_IFLE_COLLECTOR, "Collector" },
327190207Srpaulo    { JUNIPER_IFLE_CRYPTO, "Crypto" },
328190207Srpaulo    { JUNIPER_IFLE_ENET2, "Ethernet" },
329190207Srpaulo    { JUNIPER_IFLE_ETHERNET_CCC, "Ethernet CCC" },
330190207Srpaulo    { JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS, "Extended VLAN VPLS" },
331190207Srpaulo    { JUNIPER_IFLE_ETHERNET_PPPOE, "PPPoE over Ethernet" },
332190207Srpaulo    { JUNIPER_IFLE_ETHERNET_TCC, "Ethernet TCC" },
333190207Srpaulo    { JUNIPER_IFLE_ETHERNET_VLAN_VPLS, "VLAN VPLS" },
334190207Srpaulo    { JUNIPER_IFLE_ETHERNET_VPLS, "VPLS" },
335190207Srpaulo    { JUNIPER_IFLE_EXTENDED_VLAN_CCC, "Extended VLAN CCC" },
336190207Srpaulo    { JUNIPER_IFLE_EXTENDED_VLAN_TCC, "Extended VLAN TCC" },
337190207Srpaulo    { JUNIPER_IFLE_FR_CCC, "FR CCC" },
338190207Srpaulo    { JUNIPER_IFLE_FR_NLPID, "FR NLPID" },
339190207Srpaulo    { JUNIPER_IFLE_FR_PORT_CCC, "FR CCC" },
340190207Srpaulo    { JUNIPER_IFLE_FR_PPP, "FR PPP" },
341190207Srpaulo    { JUNIPER_IFLE_FR_SNAP, "FR SNAP" },
342190207Srpaulo    { JUNIPER_IFLE_FR_TCC, "FR TCC" },
343190207Srpaulo    { JUNIPER_IFLE_GGSN, "GGSN" },
344190207Srpaulo    { JUNIPER_IFLE_GRE_NULL, "GRE NULL" },
345190207Srpaulo    { JUNIPER_IFLE_GRE_PPP, "PPP over GRE" },
346190207Srpaulo    { JUNIPER_IFLE_IPIP_NULL, "IPIP" },
347190207Srpaulo    { JUNIPER_IFLE_LAPD, "LAPD" },
348190207Srpaulo    { JUNIPER_IFLE_LSI_NULL, "LSI Null" },
349190207Srpaulo    { JUNIPER_IFLE_LT_VLAN, "LT VLAN" },
350190207Srpaulo    { JUNIPER_IFLE_MFR, "MFR" },
351190207Srpaulo    { JUNIPER_IFLE_MLFR, "MLFR" },
352190207Srpaulo    { JUNIPER_IFLE_MLPPP, "MLPPP" },
353190207Srpaulo    { JUNIPER_IFLE_MONITOR, "Monitor" },
354190207Srpaulo    { JUNIPER_IFLE_PIMD_DECAPS, "PIMd" },
355190207Srpaulo    { JUNIPER_IFLE_PIM_NULL, "PIM Null" },
356190207Srpaulo    { JUNIPER_IFLE_PPP, "PPP" },
357190207Srpaulo    { JUNIPER_IFLE_PPPOE, "PPPoE" },
358190207Srpaulo    { JUNIPER_IFLE_PPP_CCC, "PPP CCC" },
359190207Srpaulo    { JUNIPER_IFLE_PPP_SUBORDINATE, "" },
360190207Srpaulo    { JUNIPER_IFLE_PPP_TCC, "PPP TCC" },
361190207Srpaulo    { JUNIPER_IFLE_SERVICES, "General Services" },
362190207Srpaulo    { JUNIPER_IFLE_VLAN_CCC, "VLAN CCC" },
363190207Srpaulo    { JUNIPER_IFLE_VLAN_TCC, "VLAN TCC" },
364190207Srpaulo    { JUNIPER_IFLE_VT, "VT" },
365190207Srpaulo    {0,                    NULL}
366190207Srpaulo};
367190207Srpaulo
368147899Ssamstruct juniper_cookie_table_t {
369147899Ssam    u_int32_t pictype;		/* pic type */
370147899Ssam    u_int8_t  cookie_len;       /* cookie len */
371147899Ssam    const char *s;		/* pic name */
372147899Ssam};
373147899Ssam
374147899Ssamstatic struct juniper_cookie_table_t juniper_cookie_table[] = {
375147899Ssam#ifdef DLT_JUNIPER_ATM1
376147899Ssam    { DLT_JUNIPER_ATM1,  4, "ATM1"},
377147899Ssam#endif
378147899Ssam#ifdef DLT_JUNIPER_ATM2
379147899Ssam    { DLT_JUNIPER_ATM2,  8, "ATM2"},
380147899Ssam#endif
381147899Ssam#ifdef DLT_JUNIPER_MLPPP
382147899Ssam    { DLT_JUNIPER_MLPPP, 2, "MLPPP"},
383147899Ssam#endif
384147899Ssam#ifdef DLT_JUNIPER_MLFR
385147899Ssam    { DLT_JUNIPER_MLFR,  2, "MLFR"},
386147899Ssam#endif
387147899Ssam#ifdef DLT_JUNIPER_MFR
388147899Ssam    { DLT_JUNIPER_MFR,   4, "MFR"},
389147899Ssam#endif
390147899Ssam#ifdef DLT_JUNIPER_PPPOE
391147899Ssam    { DLT_JUNIPER_PPPOE, 0, "PPPoE"},
392147899Ssam#endif
393147899Ssam#ifdef DLT_JUNIPER_PPPOE_ATM
394147899Ssam    { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"},
395147899Ssam#endif
396147899Ssam#ifdef DLT_JUNIPER_GGSN
397147899Ssam    { DLT_JUNIPER_GGSN, 8, "GGSN"},
398147899Ssam#endif
399147899Ssam#ifdef DLT_JUNIPER_MONITOR
400147899Ssam    { DLT_JUNIPER_MONITOR, 8, "MONITOR"},
401147899Ssam#endif
402147899Ssam#ifdef DLT_JUNIPER_SERVICES
403147899Ssam    { DLT_JUNIPER_SERVICES, 8, "AS"},
404147899Ssam#endif
405147899Ssam#ifdef DLT_JUNIPER_ES
406147899Ssam    { DLT_JUNIPER_ES, 0, "ES"},
407147899Ssam#endif
408147899Ssam    { 0, 0, NULL }
409147899Ssam};
410147899Ssam
411147899Ssamstruct juniper_l2info_t {
412147899Ssam    u_int32_t length;
413147899Ssam    u_int32_t caplen;
414147899Ssam    u_int32_t pictype;
415147899Ssam    u_int8_t direction;
416147899Ssam    u_int8_t header_len;
417147899Ssam    u_int8_t cookie_len;
418147899Ssam    u_int8_t cookie_type;
419147899Ssam    u_int8_t cookie[8];
420147899Ssam    u_int8_t bundle;
421147899Ssam    u_int16_t proto;
422190207Srpaulo    u_int8_t flags;
423147899Ssam};
424147899Ssam
425146773Ssam#define LS_COOKIE_ID            0x54
426147899Ssam#define AS_COOKIE_ID            0x47
427147899Ssam#define LS_MLFR_COOKIE_LEN	4
428147899Ssam#define ML_MLFR_COOKIE_LEN	2
429147899Ssam#define LS_MFR_COOKIE_LEN	6
430147899Ssam#define ATM1_COOKIE_LEN         4
431147899Ssam#define ATM2_COOKIE_LEN         8
432146773Ssam
433146773Ssam#define ATM2_PKT_TYPE_MASK  0x70
434146773Ssam#define ATM2_GAP_COUNT_MASK 0x3F
435146773Ssam
436147899Ssam#define JUNIPER_PROTO_NULL          1
437147899Ssam#define JUNIPER_PROTO_IPV4          2
438147899Ssam#define JUNIPER_PROTO_IPV6          6
439147899Ssam
440162017Ssam#define MFR_BE_MASK 0xc0
441162017Ssam
442147899Ssamstatic struct tok juniper_protocol_values[] = {
443147899Ssam    { JUNIPER_PROTO_NULL, "Null" },
444147899Ssam    { JUNIPER_PROTO_IPV4, "IPv4" },
445147899Ssam    { JUNIPER_PROTO_IPV6, "IPv6" },
446147899Ssam    { 0, NULL}
447147899Ssam};
448147899Ssam
449146773Ssamint ip_heuristic_guess(register const u_char *, u_int);
450146773Ssamint juniper_ppp_heuristic_guess(register const u_char *, u_int);
451190207Srpauloint juniper_read_tlv_value(const u_char *, u_int, u_int);
452147899Ssamstatic int juniper_parse_header (const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *);
453146773Ssam
454147899Ssam#ifdef DLT_JUNIPER_GGSN
455146773Ssamu_int
456147899Ssamjuniper_ggsn_print(const struct pcap_pkthdr *h, register const u_char *p)
457146773Ssam{
458147899Ssam        struct juniper_l2info_t l2info;
459147899Ssam        struct juniper_ggsn_header {
460147899Ssam            u_int8_t svc_id;
461147899Ssam            u_int8_t flags_len;
462147899Ssam            u_int8_t proto;
463147899Ssam            u_int8_t flags;
464147899Ssam            u_int8_t vlan_id[2];
465147899Ssam            u_int8_t res[2];
466147899Ssam        };
467147899Ssam        const struct juniper_ggsn_header *gh;
468146773Ssam
469147899Ssam        l2info.pictype = DLT_JUNIPER_GGSN;
470147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
471147899Ssam            return l2info.header_len;
472146773Ssam
473147899Ssam        p+=l2info.header_len;
474190207Srpaulo        gh = (struct juniper_ggsn_header *)&l2info.cookie;
475147899Ssam
476190207Srpaulo        if (eflag) {
477147899Ssam            printf("proto %s (%u), vlan %u: ",
478147899Ssam                   tok2str(juniper_protocol_values,"Unknown",gh->proto),
479147899Ssam                   gh->proto,
480147899Ssam                   EXTRACT_16BITS(&gh->vlan_id[0]));
481190207Srpaulo        }
482147899Ssam
483147899Ssam        switch (gh->proto) {
484147899Ssam        case JUNIPER_PROTO_IPV4:
485147899Ssam            ip_print(gndo, p, l2info.length);
486147899Ssam            break;
487147899Ssam#ifdef INET6
488147899Ssam        case JUNIPER_PROTO_IPV6:
489235530Sdelphij            ip6_print(gndo, p, l2info.length);
490147899Ssam            break;
491147899Ssam#endif /* INET6 */
492147899Ssam        default:
493147899Ssam            if (!eflag)
494147899Ssam                printf("unknown GGSN proto (%u)", gh->proto);
495146773Ssam        }
496146773Ssam
497147899Ssam        return l2info.header_len;
498147899Ssam}
499147899Ssam#endif
500146773Ssam
501147899Ssam#ifdef DLT_JUNIPER_ES
502147899Ssamu_int
503147899Ssamjuniper_es_print(const struct pcap_pkthdr *h, register const u_char *p)
504147899Ssam{
505147899Ssam        struct juniper_l2info_t l2info;
506147899Ssam        struct juniper_ipsec_header {
507147899Ssam            u_int8_t sa_index[2];
508147899Ssam            u_int8_t ttl;
509147899Ssam            u_int8_t type;
510147899Ssam            u_int8_t spi[4];
511147899Ssam            u_int8_t src_ip[4];
512147899Ssam            u_int8_t dst_ip[4];
513147899Ssam        };
514147899Ssam        u_int rewrite_len,es_type_bundle;
515147899Ssam        const struct juniper_ipsec_header *ih;
516147899Ssam
517147899Ssam        l2info.pictype = DLT_JUNIPER_ES;
518147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
519147899Ssam            return l2info.header_len;
520147899Ssam
521147899Ssam        p+=l2info.header_len;
522147899Ssam        ih = (struct juniper_ipsec_header *)p;
523147899Ssam
524147899Ssam        switch (ih->type) {
525147899Ssam        case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
526147899Ssam        case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
527147899Ssam            rewrite_len = 0;
528147899Ssam            es_type_bundle = 1;
529147899Ssam            break;
530147899Ssam        case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE:
531147899Ssam        case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE:
532147899Ssam        case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE:
533147899Ssam            rewrite_len = 16;
534147899Ssam            es_type_bundle = 0;
535147899Ssam        default:
536147899Ssam            printf("ES Invalid type %u, length %u",
537147899Ssam                   ih->type,
538147899Ssam                   l2info.length);
539147899Ssam            return l2info.header_len;
540147899Ssam        }
541147899Ssam
542147899Ssam        l2info.length-=rewrite_len;
543147899Ssam        p+=rewrite_len;
544147899Ssam
545147899Ssam        if (eflag) {
546147899Ssam            if (!es_type_bundle) {
547147899Ssam                printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
548147899Ssam                       EXTRACT_16BITS(&ih->sa_index),
549147899Ssam                       ih->ttl,
550147899Ssam                       tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
551147899Ssam                       ih->type,
552147899Ssam                       EXTRACT_32BITS(&ih->spi),
553190207Srpaulo                       ipaddr_string(&ih->src_ip),
554190207Srpaulo                       ipaddr_string(&ih->dst_ip),
555147899Ssam                       l2info.length);
556147899Ssam            } else {
557147899Ssam                printf("ES SA, index %u, ttl %u type %s (%u), length %u\n",
558147899Ssam                       EXTRACT_16BITS(&ih->sa_index),
559147899Ssam                       ih->ttl,
560147899Ssam                       tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
561147899Ssam                       ih->type,
562147899Ssam                       l2info.length);
563147899Ssam            }
564147899Ssam        }
565147899Ssam
566147899Ssam        ip_print(gndo, p, l2info.length);
567147899Ssam        return l2info.header_len;
568147899Ssam}
569147899Ssam#endif
570147899Ssam
571147899Ssam#ifdef DLT_JUNIPER_MONITOR
572147899Ssamu_int
573147899Ssamjuniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p)
574147899Ssam{
575147899Ssam        struct juniper_l2info_t l2info;
576147899Ssam        struct juniper_monitor_header {
577147899Ssam            u_int8_t pkt_type;
578147899Ssam            u_int8_t padding;
579147899Ssam            u_int8_t iif[2];
580147899Ssam            u_int8_t service_id[4];
581147899Ssam        };
582147899Ssam        const struct juniper_monitor_header *mh;
583147899Ssam
584147899Ssam        l2info.pictype = DLT_JUNIPER_MONITOR;
585147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
586147899Ssam            return l2info.header_len;
587147899Ssam
588147899Ssam        p+=l2info.header_len;
589147899Ssam        mh = (struct juniper_monitor_header *)p;
590147899Ssam
591147899Ssam        if (eflag)
592147899Ssam            printf("service-id %u, iif %u, pkt-type %u: ",
593147899Ssam                   EXTRACT_32BITS(&mh->service_id),
594147899Ssam                   EXTRACT_16BITS(&mh->iif),
595147899Ssam                   mh->pkt_type);
596147899Ssam
597147899Ssam        /* no proto field - lets guess by first byte of IP header*/
598147899Ssam        ip_heuristic_guess(p, l2info.length);
599147899Ssam
600147899Ssam        return l2info.header_len;
601147899Ssam}
602147899Ssam#endif
603147899Ssam
604147899Ssam#ifdef DLT_JUNIPER_SERVICES
605147899Ssamu_int
606147899Ssamjuniper_services_print(const struct pcap_pkthdr *h, register const u_char *p)
607147899Ssam{
608147899Ssam        struct juniper_l2info_t l2info;
609147899Ssam        struct juniper_services_header {
610147899Ssam            u_int8_t svc_id;
611147899Ssam            u_int8_t flags_len;
612147899Ssam            u_int8_t svc_set_id[2];
613147899Ssam            u_int8_t dir_iif[4];
614147899Ssam        };
615147899Ssam        const struct juniper_services_header *sh;
616147899Ssam
617147899Ssam        l2info.pictype = DLT_JUNIPER_SERVICES;
618147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
619147899Ssam            return l2info.header_len;
620147899Ssam
621147899Ssam        p+=l2info.header_len;
622147899Ssam        sh = (struct juniper_services_header *)p;
623147899Ssam
624147899Ssam        if (eflag)
625147899Ssam            printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
626147899Ssam                   sh->svc_id,
627147899Ssam                   sh->flags_len,
628147899Ssam                   EXTRACT_16BITS(&sh->svc_set_id),
629147899Ssam                   EXTRACT_24BITS(&sh->dir_iif[1]));
630147899Ssam
631147899Ssam        /* no proto field - lets guess by first byte of IP header*/
632147899Ssam        ip_heuristic_guess(p, l2info.length);
633147899Ssam
634147899Ssam        return l2info.header_len;
635147899Ssam}
636147899Ssam#endif
637147899Ssam
638147899Ssam#ifdef DLT_JUNIPER_PPPOE
639147899Ssamu_int
640147899Ssamjuniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p)
641147899Ssam{
642147899Ssam        struct juniper_l2info_t l2info;
643147899Ssam
644147899Ssam        l2info.pictype = DLT_JUNIPER_PPPOE;
645147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
646147899Ssam            return l2info.header_len;
647147899Ssam
648147899Ssam        p+=l2info.header_len;
649147899Ssam        /* this DLT contains nothing but raw ethernet frames */
650235530Sdelphij        ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL);
651147899Ssam        return l2info.header_len;
652147899Ssam}
653147899Ssam#endif
654147899Ssam
655162017Ssam#ifdef DLT_JUNIPER_ETHER
656162017Ssamu_int
657162017Ssamjuniper_ether_print(const struct pcap_pkthdr *h, register const u_char *p)
658162017Ssam{
659162017Ssam        struct juniper_l2info_t l2info;
660162017Ssam
661162017Ssam        l2info.pictype = DLT_JUNIPER_ETHER;
662162017Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
663162017Ssam            return l2info.header_len;
664162017Ssam
665162017Ssam        p+=l2info.header_len;
666162017Ssam        /* this DLT contains nothing but raw Ethernet frames */
667235530Sdelphij        ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL);
668162017Ssam        return l2info.header_len;
669162017Ssam}
670162017Ssam#endif
671162017Ssam
672162017Ssam#ifdef DLT_JUNIPER_PPP
673162017Ssamu_int
674162017Ssamjuniper_ppp_print(const struct pcap_pkthdr *h, register const u_char *p)
675162017Ssam{
676162017Ssam        struct juniper_l2info_t l2info;
677162017Ssam
678162017Ssam        l2info.pictype = DLT_JUNIPER_PPP;
679162017Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
680162017Ssam            return l2info.header_len;
681162017Ssam
682162017Ssam        p+=l2info.header_len;
683162017Ssam        /* this DLT contains nothing but raw ppp frames */
684162017Ssam        ppp_print(p, l2info.length);
685162017Ssam        return l2info.header_len;
686162017Ssam}
687162017Ssam#endif
688162017Ssam
689162017Ssam#ifdef DLT_JUNIPER_FRELAY
690162017Ssamu_int
691162017Ssamjuniper_frelay_print(const struct pcap_pkthdr *h, register const u_char *p)
692162017Ssam{
693162017Ssam        struct juniper_l2info_t l2info;
694162017Ssam
695162017Ssam        l2info.pictype = DLT_JUNIPER_FRELAY;
696162017Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
697162017Ssam            return l2info.header_len;
698162017Ssam
699162017Ssam        p+=l2info.header_len;
700162017Ssam        /* this DLT contains nothing but raw frame-relay frames */
701162017Ssam        fr_print(p, l2info.length);
702162017Ssam        return l2info.header_len;
703162017Ssam}
704162017Ssam#endif
705162017Ssam
706162017Ssam#ifdef DLT_JUNIPER_CHDLC
707162017Ssamu_int
708162017Ssamjuniper_chdlc_print(const struct pcap_pkthdr *h, register const u_char *p)
709162017Ssam{
710162017Ssam        struct juniper_l2info_t l2info;
711162017Ssam
712162017Ssam        l2info.pictype = DLT_JUNIPER_CHDLC;
713162017Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
714162017Ssam            return l2info.header_len;
715162017Ssam
716162017Ssam        p+=l2info.header_len;
717162017Ssam        /* this DLT contains nothing but raw c-hdlc frames */
718162017Ssam        chdlc_print(p, l2info.length);
719162017Ssam        return l2info.header_len;
720162017Ssam}
721162017Ssam#endif
722162017Ssam
723147899Ssam#ifdef DLT_JUNIPER_PPPOE_ATM
724147899Ssamu_int
725147899Ssamjuniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p)
726147899Ssam{
727147899Ssam        struct juniper_l2info_t l2info;
728147899Ssam	u_int16_t extracted_ethertype;
729147899Ssam
730147899Ssam        l2info.pictype = DLT_JUNIPER_PPPOE_ATM;
731147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
732147899Ssam            return l2info.header_len;
733147899Ssam
734147899Ssam        p+=l2info.header_len;
735147899Ssam
736147899Ssam        extracted_ethertype = EXTRACT_16BITS(p);
737147899Ssam        /* this DLT contains nothing but raw PPPoE frames,
738147899Ssam         * prepended with a type field*/
739235530Sdelphij        if (ethertype_print(gndo, extracted_ethertype,
740147899Ssam                              p+ETHERTYPE_LEN,
741147899Ssam                              l2info.length-ETHERTYPE_LEN,
742214478Srpaulo                              l2info.caplen-ETHERTYPE_LEN) == 0)
743147899Ssam            /* ether_type not known, probably it wasn't one */
744147899Ssam            printf("unknown ethertype 0x%04x", extracted_ethertype);
745147899Ssam
746147899Ssam        return l2info.header_len;
747147899Ssam}
748147899Ssam#endif
749147899Ssam
750147899Ssam#ifdef DLT_JUNIPER_MLPPP
751147899Ssamu_int
752147899Ssamjuniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p)
753147899Ssam{
754147899Ssam        struct juniper_l2info_t l2info;
755147899Ssam
756147899Ssam        l2info.pictype = DLT_JUNIPER_MLPPP;
757147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
758147899Ssam            return l2info.header_len;
759147899Ssam
760146773Ssam        /* suppress Bundle-ID if frame was captured on a child-link
761147899Ssam         * best indicator if the cookie looks like a proto */
762146773Ssam        if (eflag &&
763147899Ssam            EXTRACT_16BITS(&l2info.cookie) != PPP_OSI &&
764147899Ssam            EXTRACT_16BITS(&l2info.cookie) !=  (PPP_ADDRESS << 8 | PPP_CONTROL))
765147899Ssam            printf("Bundle-ID %u: ",l2info.bundle);
766146773Ssam
767147899Ssam        p+=l2info.header_len;
768147899Ssam
769147899Ssam        /* first try the LSQ protos */
770147899Ssam        switch(l2info.proto) {
771147899Ssam        case JUNIPER_LSQ_L3_PROTO_IPV4:
772162017Ssam            /* IP traffic going to the RE would not have a cookie
773162017Ssam             * -> this must be incoming IS-IS over PPP
774162017Ssam             */
775162017Ssam            if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR))
776162017Ssam                ppp_print(p, l2info.length);
777162017Ssam            else
778162017Ssam                ip_print(gndo, p, l2info.length);
779147899Ssam            return l2info.header_len;
780147899Ssam#ifdef INET6
781147899Ssam        case JUNIPER_LSQ_L3_PROTO_IPV6:
782235530Sdelphij            ip6_print(gndo, p,l2info.length);
783147899Ssam            return l2info.header_len;
784147899Ssam#endif
785147899Ssam        case JUNIPER_LSQ_L3_PROTO_MPLS:
786147899Ssam            mpls_print(p,l2info.length);
787147899Ssam            return l2info.header_len;
788147899Ssam        case JUNIPER_LSQ_L3_PROTO_ISO:
789147899Ssam            isoclns_print(p,l2info.length,l2info.caplen);
790147899Ssam            return l2info.header_len;
791147899Ssam        default:
792147899Ssam            break;
793147899Ssam        }
794147899Ssam
795147899Ssam        /* zero length cookie ? */
796147899Ssam        switch (EXTRACT_16BITS(&l2info.cookie)) {
797146773Ssam        case PPP_OSI:
798147899Ssam            ppp_print(p-2,l2info.length+2);
799146773Ssam            break;
800146773Ssam        case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */
801146773Ssam        default:
802147899Ssam            ppp_print(p,l2info.length);
803146773Ssam            break;
804146773Ssam        }
805146773Ssam
806147899Ssam        return l2info.header_len;
807146773Ssam}
808147899Ssam#endif
809146773Ssam
810146773Ssam
811147899Ssam#ifdef DLT_JUNIPER_MFR
812146773Ssamu_int
813147899Ssamjuniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p)
814146773Ssam{
815147899Ssam        struct juniper_l2info_t l2info;
816147899Ssam
817147899Ssam        l2info.pictype = DLT_JUNIPER_MFR;
818147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
819147899Ssam            return l2info.header_len;
820146773Ssam
821147899Ssam        p+=l2info.header_len;
822162017Ssam
823162017Ssam        /* child-link ? */
824162017Ssam        if (l2info.cookie_len == 0) {
825162017Ssam            mfr_print(p,l2info.length);
826162017Ssam            return l2info.header_len;
827162017Ssam        }
828162017Ssam
829162017Ssam        /* first try the LSQ protos */
830162017Ssam        if (l2info.cookie_len == AS_PIC_COOKIE_LEN) {
831162017Ssam            switch(l2info.proto) {
832162017Ssam            case JUNIPER_LSQ_L3_PROTO_IPV4:
833162017Ssam                ip_print(gndo, p, l2info.length);
834162017Ssam                return l2info.header_len;
835162017Ssam#ifdef INET6
836162017Ssam            case JUNIPER_LSQ_L3_PROTO_IPV6:
837235530Sdelphij                ip6_print(gndo, p,l2info.length);
838162017Ssam                return l2info.header_len;
839162017Ssam#endif
840162017Ssam            case JUNIPER_LSQ_L3_PROTO_MPLS:
841162017Ssam                mpls_print(p,l2info.length);
842162017Ssam                return l2info.header_len;
843162017Ssam            case JUNIPER_LSQ_L3_PROTO_ISO:
844162017Ssam                isoclns_print(p,l2info.length,l2info.caplen);
845162017Ssam                return l2info.header_len;
846162017Ssam            default:
847162017Ssam                break;
848162017Ssam            }
849162017Ssam            return l2info.header_len;
850162017Ssam        }
851162017Ssam
852147899Ssam        /* suppress Bundle-ID if frame was captured on a child-link */
853147899Ssam        if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle);
854147899Ssam        switch (l2info.proto) {
855147899Ssam        case (LLCSAP_ISONS<<8 | LLCSAP_ISONS):
856147899Ssam            isoclns_print(p+1, l2info.length-1, l2info.caplen-1);
857147899Ssam            break;
858147899Ssam        case (LLC_UI<<8 | NLPID_Q933):
859147899Ssam        case (LLC_UI<<8 | NLPID_IP):
860147899Ssam        case (LLC_UI<<8 | NLPID_IP6):
861147899Ssam            /* pass IP{4,6} to the OSI layer for proper link-layer printing */
862147899Ssam            isoclns_print(p-1, l2info.length+1, l2info.caplen+1);
863147899Ssam            break;
864147899Ssam        default:
865147899Ssam            printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length);
866147899Ssam        }
867146773Ssam
868147899Ssam        return l2info.header_len;
869147899Ssam}
870147899Ssam#endif
871146773Ssam
872147899Ssam#ifdef DLT_JUNIPER_MLFR
873147899Ssamu_int
874147899Ssamjuniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p)
875147899Ssam{
876147899Ssam        struct juniper_l2info_t l2info;
877146773Ssam
878147899Ssam        l2info.pictype = DLT_JUNIPER_MLFR;
879147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
880147899Ssam            return l2info.header_len;
881146773Ssam
882147899Ssam        p+=l2info.header_len;
883147899Ssam
884146773Ssam        /* suppress Bundle-ID if frame was captured on a child-link */
885147899Ssam        if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle);
886147899Ssam        switch (l2info.proto) {
887146773Ssam        case (LLC_UI):
888146773Ssam        case (LLC_UI<<8):
889147899Ssam            isoclns_print(p, l2info.length, l2info.caplen);
890146773Ssam            break;
891146773Ssam        case (LLC_UI<<8 | NLPID_Q933):
892146773Ssam        case (LLC_UI<<8 | NLPID_IP):
893146773Ssam        case (LLC_UI<<8 | NLPID_IP6):
894147899Ssam            /* pass IP{4,6} to the OSI layer for proper link-layer printing */
895147899Ssam            isoclns_print(p-1, l2info.length+1, l2info.caplen+1);
896146773Ssam            break;
897146773Ssam        default:
898147899Ssam            printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length);
899146773Ssam        }
900146773Ssam
901147899Ssam        return l2info.header_len;
902146773Ssam}
903147899Ssam#endif
904146773Ssam
905146773Ssam/*
906146773Ssam *     ATM1 PIC cookie format
907146773Ssam *
908146773Ssam *     +-----+-------------------------+-------------------------------+
909146773Ssam *     |fmtid|     vc index            |  channel  ID                  |
910146773Ssam *     +-----+-------------------------+-------------------------------+
911146773Ssam */
912146773Ssam
913147899Ssam#ifdef DLT_JUNIPER_ATM1
914146773Ssamu_int
915146773Ssamjuniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p)
916146773Ssam{
917146773Ssam        u_int16_t extracted_ethertype;
918146773Ssam
919147899Ssam        struct juniper_l2info_t l2info;
920146773Ssam
921147899Ssam        l2info.pictype = DLT_JUNIPER_ATM1;
922147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
923147899Ssam            return l2info.header_len;
924146773Ssam
925147899Ssam        p+=l2info.header_len;
926146773Ssam
927147899Ssam        if (l2info.cookie[0] == 0x80) { /* OAM cell ? */
928147899Ssam            oam_print(p,l2info.length,ATM_OAM_NOHEC);
929147899Ssam            return l2info.header_len;
930146773Ssam        }
931146773Ssam
932146773Ssam        if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
933146773Ssam            EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
934146773Ssam
935147899Ssam            if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL,
936146773Ssam                          &extracted_ethertype) != 0)
937147899Ssam                return l2info.header_len;
938146773Ssam        }
939146773Ssam
940146773Ssam        if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
941147899Ssam            isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1);
942146773Ssam            /* FIXME check if frame was recognized */
943147899Ssam            return l2info.header_len;
944146773Ssam        }
945146773Ssam
946147899Ssam        if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */
947147899Ssam            return l2info.header_len;
948146773Ssam
949147899Ssam	return l2info.header_len;
950146773Ssam}
951147899Ssam#endif
952146773Ssam
953146773Ssam/*
954146773Ssam *     ATM2 PIC cookie format
955146773Ssam *
956146773Ssam *     +-------------------------------+---------+---+-----+-----------+
957146773Ssam *     |     channel ID                |  reserv |AAL| CCRQ| gap cnt   |
958146773Ssam *     +-------------------------------+---------+---+-----+-----------+
959146773Ssam */
960146773Ssam
961147899Ssam#ifdef DLT_JUNIPER_ATM2
962146773Ssamu_int
963146773Ssamjuniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p)
964146773Ssam{
965146773Ssam        u_int16_t extracted_ethertype;
966146773Ssam
967147899Ssam        struct juniper_l2info_t l2info;
968146773Ssam
969147899Ssam        l2info.pictype = DLT_JUNIPER_ATM2;
970147899Ssam        if(juniper_parse_header(p, h, &l2info) == 0)
971147899Ssam            return l2info.header_len;
972146773Ssam
973147899Ssam        p+=l2info.header_len;
974146773Ssam
975147899Ssam        if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */
976147899Ssam            oam_print(p,l2info.length,ATM_OAM_NOHEC);
977147899Ssam            return l2info.header_len;
978146773Ssam        }
979146773Ssam
980146773Ssam        if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
981146773Ssam            EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
982146773Ssam
983147899Ssam            if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL,
984146773Ssam                          &extracted_ethertype) != 0)
985147899Ssam                return l2info.header_len;
986146773Ssam        }
987146773Ssam
988147899Ssam        if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */
989147899Ssam            (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) {
990235530Sdelphij            ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL);
991147899Ssam            return l2info.header_len;
992146773Ssam        }
993146773Ssam
994146773Ssam        if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
995147899Ssam            isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1);
996146773Ssam            /* FIXME check if frame was recognized */
997147899Ssam            return l2info.header_len;
998146773Ssam        }
999146773Ssam
1000147899Ssam        if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) /* PPPoA vcmux encaps ? */
1001147899Ssam            return l2info.header_len;
1002146773Ssam
1003147899Ssam        if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */
1004147899Ssam            return l2info.header_len;
1005146773Ssam
1006147899Ssam	return l2info.header_len;
1007146773Ssam}
1008147899Ssam#endif
1009146773Ssam
1010146773Ssam
1011146773Ssam/* try to guess, based on all PPP protos that are supported in
1012146773Ssam * a juniper router if the payload data is encapsulated using PPP */
1013146773Ssamint
1014146773Ssamjuniper_ppp_heuristic_guess(register const u_char *p, u_int length) {
1015146773Ssam
1016146773Ssam    switch(EXTRACT_16BITS(p)) {
1017146773Ssam    case PPP_IP :
1018146773Ssam    case PPP_OSI :
1019146773Ssam    case PPP_MPLS_UCAST :
1020146773Ssam    case PPP_MPLS_MCAST :
1021146773Ssam    case PPP_IPCP :
1022146773Ssam    case PPP_OSICP :
1023146773Ssam    case PPP_MPLSCP :
1024146773Ssam    case PPP_LCP :
1025146773Ssam    case PPP_PAP :
1026146773Ssam    case PPP_CHAP :
1027146773Ssam    case PPP_ML :
1028146773Ssam#ifdef INET6
1029146773Ssam    case PPP_IPV6 :
1030146773Ssam    case PPP_IPV6CP :
1031146773Ssam#endif
1032146773Ssam        ppp_print(p, length);
1033146773Ssam        break;
1034146773Ssam
1035146773Ssam    default:
1036146773Ssam        return 0; /* did not find a ppp header */
1037146773Ssam        break;
1038146773Ssam    }
1039146773Ssam    return 1; /* we printed a ppp packet */
1040146773Ssam}
1041146773Ssam
1042146773Ssamint
1043146773Ssamip_heuristic_guess(register const u_char *p, u_int length) {
1044146773Ssam
1045146773Ssam    switch(p[0]) {
1046146773Ssam    case 0x45:
1047146773Ssam    case 0x46:
1048146773Ssam    case 0x47:
1049146773Ssam    case 0x48:
1050146773Ssam    case 0x49:
1051146773Ssam    case 0x4a:
1052146773Ssam    case 0x4b:
1053146773Ssam    case 0x4c:
1054146773Ssam    case 0x4d:
1055146773Ssam    case 0x4e:
1056146773Ssam    case 0x4f:
1057146773Ssam	    ip_print(gndo, p, length);
1058146773Ssam	    break;
1059146773Ssam#ifdef INET6
1060146773Ssam    case 0x60:
1061146773Ssam    case 0x61:
1062146773Ssam    case 0x62:
1063146773Ssam    case 0x63:
1064146773Ssam    case 0x64:
1065146773Ssam    case 0x65:
1066146773Ssam    case 0x66:
1067146773Ssam    case 0x67:
1068146773Ssam    case 0x68:
1069146773Ssam    case 0x69:
1070146773Ssam    case 0x6a:
1071146773Ssam    case 0x6b:
1072146773Ssam    case 0x6c:
1073146773Ssam    case 0x6d:
1074146773Ssam    case 0x6e:
1075146773Ssam    case 0x6f:
1076235530Sdelphij        ip6_print(gndo, p, length);
1077146773Ssam        break;
1078146773Ssam#endif
1079146773Ssam    default:
1080146773Ssam        return 0; /* did not find a ip header */
1081146773Ssam        break;
1082146773Ssam    }
1083146773Ssam    return 1; /* we printed an v4/v6 packet */
1084146773Ssam}
1085146773Ssam
1086190207Srpauloint
1087190207Srpaulojuniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len) {
1088190207Srpaulo
1089190207Srpaulo   int tlv_value;
1090190207Srpaulo
1091190207Srpaulo   /* TLVs < 128 are little endian encoded */
1092190207Srpaulo   if (tlv_type < 128) {
1093190207Srpaulo       switch (tlv_len) {
1094190207Srpaulo       case 1:
1095190207Srpaulo           tlv_value = *p;
1096190207Srpaulo           break;
1097190207Srpaulo       case 2:
1098190207Srpaulo           tlv_value = EXTRACT_LE_16BITS(p);
1099190207Srpaulo           break;
1100190207Srpaulo       case 3:
1101190207Srpaulo           tlv_value = EXTRACT_LE_24BITS(p);
1102190207Srpaulo           break;
1103190207Srpaulo       case 4:
1104190207Srpaulo           tlv_value = EXTRACT_LE_32BITS(p);
1105190207Srpaulo           break;
1106190207Srpaulo       default:
1107190207Srpaulo           tlv_value = -1;
1108190207Srpaulo           break;
1109190207Srpaulo       }
1110190207Srpaulo   } else {
1111190207Srpaulo       /* TLVs >= 128 are big endian encoded */
1112190207Srpaulo       switch (tlv_len) {
1113190207Srpaulo       case 1:
1114190207Srpaulo           tlv_value = *p;
1115190207Srpaulo           break;
1116190207Srpaulo       case 2:
1117190207Srpaulo           tlv_value = EXTRACT_16BITS(p);
1118190207Srpaulo           break;
1119190207Srpaulo       case 3:
1120190207Srpaulo           tlv_value = EXTRACT_24BITS(p);
1121190207Srpaulo           break;
1122190207Srpaulo       case 4:
1123190207Srpaulo           tlv_value = EXTRACT_32BITS(p);
1124190207Srpaulo           break;
1125190207Srpaulo       default:
1126190207Srpaulo           tlv_value = -1;
1127190207Srpaulo           break;
1128190207Srpaulo       }
1129190207Srpaulo   }
1130190207Srpaulo   return tlv_value;
1131190207Srpaulo}
1132190207Srpaulo
1133146773Ssamstatic int
1134147899Ssamjuniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) {
1135146773Ssam
1136147899Ssam    struct juniper_cookie_table_t *lp = juniper_cookie_table;
1137190207Srpaulo    u_int idx, jnx_ext_len, jnx_header_len = 0;
1138190207Srpaulo    u_int8_t tlv_type,tlv_len;
1139172683Smlaier    u_int32_t control_word;
1140190207Srpaulo    int tlv_value;
1141190207Srpaulo    const u_char *tptr;
1142147899Ssam
1143190207Srpaulo
1144147899Ssam    l2info->header_len = 0;
1145147899Ssam    l2info->cookie_len = 0;
1146147899Ssam    l2info->proto = 0;
1147147899Ssam
1148147899Ssam
1149147899Ssam    l2info->length = h->len;
1150147899Ssam    l2info->caplen = h->caplen;
1151190207Srpaulo    TCHECK2(p[0],4);
1152190207Srpaulo    l2info->flags = p[3];
1153147899Ssam    l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
1154146773Ssam
1155162017Ssam    if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
1156162017Ssam        printf("no magic-number found!");
1157147899Ssam        return 0;
1158162017Ssam    }
1159146773Ssam
1160147899Ssam    if (eflag) /* print direction */
1161147899Ssam        printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction));
1162147899Ssam
1163190207Srpaulo    /* magic number + flags */
1164190207Srpaulo    jnx_header_len = 4;
1165190207Srpaulo
1166190207Srpaulo    if (vflag>1)
1167190207Srpaulo        printf("\n\tJuniper PCAP Flags [%s]",
1168190207Srpaulo               bittok2str(jnx_flag_values, "none", l2info->flags));
1169190207Srpaulo
1170162017Ssam    /* extensions present ?  - calculate how much bytes to skip */
1171190207Srpaulo    if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {
1172162017Ssam
1173190207Srpaulo        tptr = p+jnx_header_len;
1174190207Srpaulo
1175190207Srpaulo        /* ok to read extension length ? */
1176190207Srpaulo        TCHECK2(tptr[0], 2);
1177190207Srpaulo        jnx_ext_len = EXTRACT_16BITS(tptr);
1178190207Srpaulo        jnx_header_len += 2;
1179190207Srpaulo        tptr +=2;
1180190207Srpaulo
1181190207Srpaulo        /* nail up the total length -
1182190207Srpaulo         * just in case something goes wrong
1183190207Srpaulo         * with TLV parsing */
1184190207Srpaulo        jnx_header_len += jnx_ext_len;
1185190207Srpaulo
1186190207Srpaulo        if (vflag>1)
1187190207Srpaulo            printf(", PCAP Extension(s) total length %u",
1188190207Srpaulo                   jnx_ext_len);
1189190207Srpaulo
1190190207Srpaulo        TCHECK2(tptr[0], jnx_ext_len);
1191190207Srpaulo        while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) {
1192190207Srpaulo            tlv_type = *(tptr++);
1193190207Srpaulo            tlv_len = *(tptr++);
1194190207Srpaulo            tlv_value = 0;
1195190207Srpaulo
1196190207Srpaulo            /* sanity check */
1197190207Srpaulo            if (tlv_type == 0 || tlv_len == 0)
1198190207Srpaulo                break;
1199190207Srpaulo
1200190207Srpaulo            if (vflag>1)
1201190207Srpaulo                printf("\n\t  %s Extension TLV #%u, length %u, value ",
1202190207Srpaulo                       tok2str(jnx_ext_tlv_values,"Unknown",tlv_type),
1203190207Srpaulo                       tlv_type,
1204190207Srpaulo                       tlv_len);
1205190207Srpaulo
1206190207Srpaulo            tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len);
1207190207Srpaulo            switch (tlv_type) {
1208190207Srpaulo            case JUNIPER_EXT_TLV_IFD_NAME:
1209190207Srpaulo                /* FIXME */
1210190207Srpaulo                break;
1211190207Srpaulo            case JUNIPER_EXT_TLV_IFD_MEDIATYPE:
1212190207Srpaulo            case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE:
1213190207Srpaulo                if (tlv_value != -1) {
1214190207Srpaulo                    if (vflag>1)
1215190207Srpaulo                        printf("%s (%u)",
1216190207Srpaulo                               tok2str(juniper_ifmt_values, "Unknown", tlv_value),
1217190207Srpaulo                               tlv_value);
1218190207Srpaulo                }
1219190207Srpaulo                break;
1220190207Srpaulo            case JUNIPER_EXT_TLV_IFL_ENCAPS:
1221190207Srpaulo            case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS:
1222190207Srpaulo                if (tlv_value != -1) {
1223190207Srpaulo                    if (vflag>1)
1224190207Srpaulo                        printf("%s (%u)",
1225190207Srpaulo                               tok2str(juniper_ifle_values, "Unknown", tlv_value),
1226190207Srpaulo                               tlv_value);
1227190207Srpaulo                }
1228190207Srpaulo                break;
1229190207Srpaulo            case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */
1230190207Srpaulo            case JUNIPER_EXT_TLV_IFL_UNIT:
1231190207Srpaulo            case JUNIPER_EXT_TLV_IFD_IDX:
1232190207Srpaulo            default:
1233190207Srpaulo                if (tlv_value != -1) {
1234190207Srpaulo                    if (vflag>1)
1235190207Srpaulo                        printf("%u",tlv_value);
1236190207Srpaulo                }
1237190207Srpaulo                break;
1238190207Srpaulo            }
1239190207Srpaulo
1240190207Srpaulo            tptr+=tlv_len;
1241190207Srpaulo            jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD;
1242190207Srpaulo        }
1243190207Srpaulo
1244190207Srpaulo        if (vflag>1)
1245190207Srpaulo            printf("\n\t-----original packet-----\n\t");
1246190207Srpaulo    }
1247190207Srpaulo
1248190207Srpaulo    if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {
1249146773Ssam        if (eflag)
1250146773Ssam            printf("no-L2-hdr, ");
1251146773Ssam
1252146773Ssam        /* there is no link-layer present -
1253146773Ssam         * perform the v4/v6 heuristics
1254146773Ssam         * to figure out what it is
1255146773Ssam         */
1256190207Srpaulo        TCHECK2(p[jnx_header_len+4],1);
1257190207Srpaulo        if(ip_heuristic_guess(p+jnx_header_len+4,l2info->length-(jnx_header_len+4)) == 0)
1258146773Ssam            printf("no IP-hdr found!");
1259146773Ssam
1260190207Srpaulo        l2info->header_len=jnx_header_len+4;
1261146773Ssam        return 0; /* stop parsing the output further */
1262146773Ssam
1263146773Ssam    }
1264190207Srpaulo    l2info->header_len = jnx_header_len;
1265147899Ssam    p+=l2info->header_len;
1266147899Ssam    l2info->length -= l2info->header_len;
1267147899Ssam    l2info->caplen -= l2info->header_len;
1268147899Ssam
1269147899Ssam    /* search through the cookie table and copy values matching for our PIC type */
1270147899Ssam    while (lp->s != NULL) {
1271147899Ssam        if (lp->pictype == l2info->pictype) {
1272147899Ssam
1273162017Ssam            l2info->cookie_len += lp->cookie_len;
1274147899Ssam
1275147899Ssam            switch (p[0]) {
1276147899Ssam            case LS_COOKIE_ID:
1277147899Ssam                l2info->cookie_type = LS_COOKIE_ID;
1278147899Ssam                l2info->cookie_len += 2;
1279147899Ssam                break;
1280147899Ssam            case AS_COOKIE_ID:
1281147899Ssam                l2info->cookie_type = AS_COOKIE_ID;
1282162017Ssam                l2info->cookie_len = 8;
1283147899Ssam                break;
1284147899Ssam
1285147899Ssam            default:
1286147899Ssam                l2info->bundle = l2info->cookie[0];
1287147899Ssam                break;
1288147899Ssam            }
1289147899Ssam
1290162017Ssam
1291162017Ssam#ifdef DLT_JUNIPER_MFR
1292162017Ssam            /* MFR child links don't carry cookies */
1293162017Ssam            if (l2info->pictype == DLT_JUNIPER_MFR &&
1294162017Ssam                (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
1295162017Ssam                l2info->cookie_len = 0;
1296162017Ssam            }
1297162017Ssam#endif
1298162017Ssam
1299162017Ssam            l2info->header_len += l2info->cookie_len;
1300162017Ssam            l2info->length -= l2info->cookie_len;
1301162017Ssam            l2info->caplen -= l2info->cookie_len;
1302162017Ssam
1303147899Ssam            if (eflag)
1304147899Ssam                printf("%s-PIC, cookie-len %u",
1305147899Ssam                       lp->s,
1306147899Ssam                       l2info->cookie_len);
1307147899Ssam
1308147899Ssam            if (l2info->cookie_len > 0) {
1309147899Ssam                TCHECK2(p[0],l2info->cookie_len);
1310147899Ssam                if (eflag)
1311147899Ssam                    printf(", cookie 0x");
1312147899Ssam                for (idx = 0; idx < l2info->cookie_len; idx++) {
1313147899Ssam                    l2info->cookie[idx] = p[idx]; /* copy cookie data */
1314147899Ssam                    if (eflag) printf("%02x",p[idx]);
1315147899Ssam                }
1316147899Ssam            }
1317147899Ssam
1318147899Ssam            if (eflag) printf(": "); /* print demarc b/w L2/L3*/
1319147899Ssam
1320147899Ssam
1321147899Ssam            l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len);
1322147899Ssam            break;
1323147899Ssam        }
1324147899Ssam        ++lp;
1325147899Ssam    }
1326147899Ssam    p+=l2info->cookie_len;
1327147899Ssam
1328147899Ssam    /* DLT_ specific parsing */
1329147899Ssam    switch(l2info->pictype) {
1330162017Ssam#ifdef DLT_JUNIPER_MLPPP
1331147899Ssam    case DLT_JUNIPER_MLPPP:
1332147899Ssam        switch (l2info->cookie_type) {
1333147899Ssam        case LS_COOKIE_ID:
1334147899Ssam            l2info->bundle = l2info->cookie[1];
1335147899Ssam            break;
1336147899Ssam        case AS_COOKIE_ID:
1337147899Ssam            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
1338147899Ssam            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
1339147899Ssam            break;
1340147899Ssam        default:
1341147899Ssam            l2info->bundle = l2info->cookie[0];
1342147899Ssam            break;
1343147899Ssam        }
1344147899Ssam        break;
1345162017Ssam#endif
1346162017Ssam#ifdef DLT_JUNIPER_MLFR
1347162017Ssam    case DLT_JUNIPER_MLFR:
1348162017Ssam        switch (l2info->cookie_type) {
1349162017Ssam        case LS_COOKIE_ID:
1350162017Ssam            l2info->bundle = l2info->cookie[1];
1351162017Ssam            l2info->proto = EXTRACT_16BITS(p);
1352162017Ssam            l2info->header_len += 2;
1353162017Ssam            l2info->length -= 2;
1354162017Ssam            l2info->caplen -= 2;
1355162017Ssam            break;
1356162017Ssam        case AS_COOKIE_ID:
1357162017Ssam            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
1358162017Ssam            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
1359162017Ssam            break;
1360162017Ssam        default:
1361162017Ssam            l2info->bundle = l2info->cookie[0];
1362162017Ssam            l2info->header_len += 2;
1363162017Ssam            l2info->length -= 2;
1364162017Ssam            l2info->caplen -= 2;
1365162017Ssam            break;
1366162017Ssam        }
1367162017Ssam        break;
1368162017Ssam#endif
1369162017Ssam#ifdef DLT_JUNIPER_MFR
1370147899Ssam    case DLT_JUNIPER_MFR:
1371147899Ssam        switch (l2info->cookie_type) {
1372147899Ssam        case LS_COOKIE_ID:
1373147899Ssam            l2info->bundle = l2info->cookie[1];
1374162017Ssam            l2info->proto = EXTRACT_16BITS(p);
1375162017Ssam            l2info->header_len += 2;
1376162017Ssam            l2info->length -= 2;
1377162017Ssam            l2info->caplen -= 2;
1378147899Ssam            break;
1379147899Ssam        case AS_COOKIE_ID:
1380147899Ssam            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
1381162017Ssam            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
1382147899Ssam            break;
1383147899Ssam        default:
1384147899Ssam            l2info->bundle = l2info->cookie[0];
1385147899Ssam            break;
1386147899Ssam        }
1387147899Ssam        break;
1388162017Ssam#endif
1389162017Ssam#ifdef DLT_JUNIPER_ATM2
1390147899Ssam    case DLT_JUNIPER_ATM2:
1391147899Ssam        TCHECK2(p[0],4);
1392147899Ssam        /* ATM cell relay control word present ? */
1393172683Smlaier        if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
1394172683Smlaier            control_word = EXTRACT_32BITS(p);
1395172683Smlaier            /* some control word heuristics */
1396172683Smlaier            switch(control_word) {
1397172683Smlaier            case 0: /* zero control word */
1398172683Smlaier            case 0x08000000: /* < JUNOS 7.4 control-word */
1399172683Smlaier            case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
1400172683Smlaier                l2info->header_len += 4;
1401172683Smlaier                break;
1402172683Smlaier            default:
1403172683Smlaier                break;
1404172683Smlaier            }
1405172683Smlaier
1406147899Ssam            if (eflag)
1407172683Smlaier                printf("control-word 0x%08x ", control_word);
1408147899Ssam        }
1409147899Ssam        break;
1410162017Ssam#endif
1411190207Srpaulo#ifdef DLT_JUNIPER_GGSN
1412190207Srpaulo    case DLT_JUNIPER_GGSN:
1413190207Srpaulo        break;
1414190207Srpaulo#endif
1415162017Ssam#ifdef DLT_JUNIPER_ATM1
1416147899Ssam    case DLT_JUNIPER_ATM1:
1417162017Ssam        break;
1418162017Ssam#endif
1419172683Smlaier#ifdef DLT_JUNIPER_PPP
1420172683Smlaier    case DLT_JUNIPER_PPP:
1421172683Smlaier        break;
1422172683Smlaier#endif
1423172683Smlaier#ifdef DLT_JUNIPER_CHDLC
1424172683Smlaier    case DLT_JUNIPER_CHDLC:
1425172683Smlaier        break;
1426172683Smlaier#endif
1427172683Smlaier#ifdef DLT_JUNIPER_ETHER
1428172683Smlaier    case DLT_JUNIPER_ETHER:
1429172683Smlaier        break;
1430172683Smlaier#endif
1431172683Smlaier#ifdef DLT_JUNIPER_FRELAY
1432172683Smlaier    case DLT_JUNIPER_FRELAY:
1433172683Smlaier        break;
1434172683Smlaier#endif
1435172683Smlaier
1436147899Ssam    default:
1437162017Ssam        printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
1438147899Ssam        break;
1439147899Ssam    }
1440147899Ssam
1441147899Ssam    if (eflag > 1)
1442147899Ssam        printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);
1443147899Ssam
1444146773Ssam    return 1; /* everything went ok so far. continue parsing */
1445147899Ssam trunc:
1446147899Ssam    printf("[|juniper_hdr], length %u",h->len);
1447147899Ssam    return 0;
1448146773Ssam}
1449146773Ssam
1450146773Ssam
1451146773Ssam/*
1452146773Ssam * Local Variables:
1453146773Ssam * c-style: whitesmith
1454147899Ssam * c-basic-offset: 4
1455146773Ssam * End:
1456146773Ssam */
1457