1 /* packet-juniper.c
2  * Routines for Juniper Networks, Inc. packet disassembly
3  * Copyright 2005 Hannes Gredler <hannes@juniper.net>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include "config.h"
13 
14 #include <epan/packet.h>
15 #include <epan/expert.h>
16 #include <epan/addr_resolv.h>
17 #include <epan/ppptypes.h>
18 #include <epan/etypes.h>
19 #include <epan/ipproto.h>
20 #include "packet-ppp.h"
21 #include "packet-juniper.h"
22 #include <epan/nlpid.h>
23 
24 void proto_register_juniper(void);
25 void proto_reg_handoff_juniper(void);
26 
27 #define JUNIPER_FLAG_PKT_OUT        0x00     /* Outgoing packet */
28 #define JUNIPER_FLAG_PKT_IN         0x01     /* Incoming packet */
29 #define JUNIPER_FLAG_NO_L2          0x02     /* L2 header stripped */
30 #define JUNIPER_FLAG_EXT            0x80     /* extensions present */
31 #define EXT_TLV_HEADER_SIZE 2
32 #define JUNIPER_ATM2_PKT_TYPE_MASK  0x70
33 #define JUNIPER_ATM2_GAP_COUNT_MASK 0x3F
34 #define JUNIPER_PCAP_MAGIC          0x4d4743
35 
36 #define JUNIPER_PIC_ATM1   1
37 #define JUNIPER_PIC_ATM2   2
38 #define JUNIPER_PIC_MLPPP  3
39 #define JUNIPER_PIC_MLFR   4
40 
41 #define JUNIPER_HDR_SNAP   0xaaaa03
42 #define JUNIPER_HDR_NLPID  0xfefe03
43 #define JUNIPER_HDR_LLC_UI 0x03
44 #define JUNIPER_HDR_PPP    0xff03
45 
46 #define ML_PIC_COOKIE_LEN 2
47 #define LS_PIC_COOKIE_LEN 4
48 #define AS_PIC_COOKIE_LEN 8
49 
50 #define GSP_SVC_REQ_APOLLO 0x40
51 #define GSP_SVC_REQ_LSQ    0x47
52 
53 #define LSQ_COOKIE_RE         0x2
54 #define LSQ_COOKIE_DIR        0x1
55 #define LSQ_L3_PROTO_SHIFT     4
56 #define LSQ_L3_PROTO_MASK     0xf0
57 #define LSQ_L3_PROTO_IPV4     (0 << LSQ_L3_PROTO_SHIFT)
58 #define LSQ_L3_PROTO_IPV6     (1 << LSQ_L3_PROTO_SHIFT)
59 #define LSQ_L3_PROTO_MPLS     (2 << LSQ_L3_PROTO_SHIFT)
60 #define LSQ_L3_PROTO_ISO      (3 << LSQ_L3_PROTO_SHIFT)
61 
62 #define EXT_TLV_IFD_IDX           1
63 #define EXT_TLV_IFD_NAME          2
64 #define EXT_TLV_IFD_MEDIATYPE     3
65 #define EXT_TLV_IFL_IDX           4
66 #define EXT_TLV_IFL_UNIT          5
67 #define EXT_TLV_IFL_ENCAPS        6
68 #define EXT_TLV_TTP_IFD_MEDIATYPE 7
69 #define EXT_TLV_TTP_IFL_ENCAPS    8
70 
71 /* VN related defines */
72 #define VN_TLV_HDR_SIZE   2
73 #define VN_FLAG_ALERT     0x00000002
74 #define VN_FLAG_DROP      0x00000004
75 #define VN_FLAG_DENY      0x00000008
76 #define VN_FLAG_LOG       0x00000010
77 #define VN_FLAG_PASS      0x00000020
78 #define VN_FLAG_REJECT    0x00000040
79 #define VN_FLAG_MIRROR    0x00000080
80 #define VN_FLAG_DIRECTION 0x40000000
81 #define VN_FLAG_MASK      0xFFFFFFFF
82 enum {
83     VN_TLV_HOST_IP = 1,
84     VN_TLV_FLAGS   = 2,
85     VN_TLV_SRC_VN  = 3,
86     VN_TLV_DST_VN  = 4,
87     VN_TLV_LAST    = 255
88 };
89 
90 static const value_string ext_tlv_vals[] = {
91   { EXT_TLV_IFD_IDX,           "Device Interface Index" },
92   { EXT_TLV_IFD_NAME,          "Device Interface Name" },
93   { EXT_TLV_IFD_MEDIATYPE,     "Device Media Type" },
94   { EXT_TLV_IFL_IDX,           "Logical Interface Index" },
95   { EXT_TLV_IFL_UNIT,          "Logical Unit Number" },
96   { EXT_TLV_IFL_ENCAPS,        "Logical Interface Encapsulation" },
97   { EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" },
98   { EXT_TLV_TTP_IFL_ENCAPS,    "TTP derived Logical Interface Encapsulation" },
99   { 0,             NULL }
100 };
101 
102 static const value_string juniper_direction_vals[] = {
103   {JUNIPER_FLAG_PKT_OUT, "Out"},
104   {JUNIPER_FLAG_PKT_IN,  "In"},
105   {0,                    NULL}
106 };
107 
108 static const value_string juniper_l2hdr_presence_vals[] = {
109   { 0, "Present"},
110   { 2, "none"},
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 value_string juniper_ifmt_vals[] = {
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 value_string juniper_ifle_vals[] = {
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 
364 static int proto_juniper = -1;
365 
366 static int hf_juniper_magic = -1;
367 static int hf_juniper_direction = -1;
368 static int hf_juniper_l2hdr_presence = -1;
369 static int hf_juniper_ext_total_len = -1;
370 static int hf_juniper_cookie_len = -1;
371 static int hf_juniper_atm1_cookie = -1;
372 static int hf_juniper_atm2_cookie = -1;
373 static int hf_juniper_mlpic_cookie = -1;
374 static int hf_juniper_lspic_cookie = -1;
375 static int hf_juniper_aspic_cookie = -1;
376 static int hf_juniper_vlan = -1;
377 static int hf_juniper_proto = -1;
378 static int hf_juniper_payload_type = -1;
379 static int hf_juniper_encap_type = -1;
380 static int hf_juniper_ext_ifd = -1;
381 static int hf_juniper_ext_ifl = -1;
382 static int hf_juniper_ext_unit = -1;
383 static int hf_juniper_ext_ifmt = -1;
384 static int hf_juniper_ext_ifle = -1;
385 static int hf_juniper_ext_ttp_ifmt = -1;
386 static int hf_juniper_ext_ttp_ifle = -1;
387 static int hf_juniper_unknown_data = -1;
388 
389 static expert_field ei_juniper_no_magic = EI_INIT;
390 static expert_field ei_juniper_vn_incorrect_format = EI_INIT;
391 
392 static int hf_juniper_vn_host_ip = -1;
393 static int hf_juniper_vn_src = -1;
394 static int hf_juniper_vn_dst = -1;
395 static int hf_juniper_vn_flags = -1;
396 static int hf_juniper_vn_flag_alert = -1;
397 static int hf_juniper_vn_flag_drop = -1;
398 static int hf_juniper_vn_flag_deny = -1;
399 static int hf_juniper_vn_flag_log = -1;
400 static int hf_juniper_vn_flag_pass = -1;
401 static int hf_juniper_vn_flag_reject = -1;
402 static int hf_juniper_vn_flag_mirror = -1;
403 static int hf_juniper_vn_flag_direction = -1;
404 
405 static int hf_juniper_st_eth_dst = -1;
406 static int hf_juniper_st_eth_src = -1;
407 static int hf_juniper_st_eth_type = -1;
408 static int hf_juniper_st_ip_len = -1;
409 static int hf_juniper_st_ip_proto = -1;
410 static int hf_juniper_st_esp_spi = -1;
411 static int hf_juniper_st_esp_seq = -1;
412 
413 static gint ett_juniper = -1;
414 static gint ett_juniper_vn_flags = -1;
415 static gint ett_juniper_st_eth = -1;
416 static gint ett_juniper_st_ip = -1;
417 static gint ett_juniper_st_esp = -1;
418 static gint ett_juniper_st_unknown = -1;
419 
420 static dissector_table_t payload_table;
421 
422 static int dissect_juniper_payload_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *juniper_subtree, guint proto, guint offset);
423 static void dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 atm_pictype);
424 static gboolean ppp_heuristic_guess(guint16 proto);
425 static guint ip_heuristic_guess(guint8 ip_header_byte);
426 static guint juniper_svc_cookie_len (guint64 cookie);
427 static guint juniper_svc_cookie_proto (guint64 cookie, guint16 pictype, guint8 flags);
428 
429 static const value_string juniper_proto_vals[] = {
430   {JUNIPER_PROTO_IP, "IPv4"},
431   {JUNIPER_PROTO_MPLS_IP, "MPLS->IPv4"},
432   {JUNIPER_PROTO_IP_MPLS, "IPv4->MPLS"},
433   {JUNIPER_PROTO_IP6, "IPv6"},
434   {JUNIPER_PROTO_MPLS_IP6, "MPLS->IPv6"},
435   {JUNIPER_PROTO_IP6_MPLS, "IPv6->MPLS"},
436   {JUNIPER_PROTO_PPP, "PPP"},
437   {JUNIPER_PROTO_CLNP, "CLNP"},
438   {JUNIPER_PROTO_MPLS_CLNP, "MPLS->CLNP"},
439   {JUNIPER_PROTO_CLNP_MPLS, "CLNP->MPLS"},
440   {JUNIPER_PROTO_ISO, "OSI"},
441   {JUNIPER_PROTO_MPLS, "MPLS"},
442   {JUNIPER_PROTO_LLC, "LLC"},
443   {JUNIPER_PROTO_LLC_SNAP, "LLC/SNAP"},
444   {JUNIPER_PROTO_ETHER, "Ethernet"},
445   {JUNIPER_PROTO_OAM, "ATM OAM Cell"},
446   {JUNIPER_PROTO_Q933, "Q.933"},
447   {JUNIPER_PROTO_FRELAY, "Frame-Relay"},
448   {JUNIPER_PROTO_CHDLC, "C-HDLC"},
449   {0,                    NULL}
450 };
451 
452 static int * const vn_flags[] = {
453   &hf_juniper_vn_flag_direction,
454   &hf_juniper_vn_flag_mirror,
455   &hf_juniper_vn_flag_reject,
456   &hf_juniper_vn_flag_pass,
457   &hf_juniper_vn_flag_log,
458   &hf_juniper_vn_flag_deny,
459   &hf_juniper_vn_flag_drop,
460   &hf_juniper_vn_flag_alert,
461   NULL
462   };
463 
464 /* return a TLV value based on TLV length and TLV type (host/network order) */
465 static int
juniper_ext_get_tlv_value(tvbuff_t * tvb,guint tlv_type,guint tlv_len,guint offset)466 juniper_ext_get_tlv_value(tvbuff_t *tvb, guint tlv_type, guint tlv_len, guint offset) {
467 
468   int tlv_value;
469 
470   if (tlv_type < 128) {
471     /* TLVs < 128 are little-endian / host order encoded */
472     switch (tlv_len) {
473     case 1:
474       tlv_value = tvb_get_guint8(tvb, offset);
475       break;
476     case 2:
477       tlv_value = tvb_get_letohs(tvb, offset);
478       break;
479     case 3:
480       tlv_value = tvb_get_letoh24(tvb, offset);
481       break;
482     case 4:
483       tlv_value = tvb_get_letohl(tvb, offset);
484       break;
485     default:
486       tlv_value = -1;
487       break;
488     }
489   } else {
490     /* TLVs >= 128 are big-endian / network order encoded */
491     switch (tlv_len) {
492     case 1:
493       tlv_value = tvb_get_guint8(tvb, offset);
494       break;
495     case 2:
496       tlv_value = tvb_get_ntohs(tvb, offset);
497       break;
498     case 3:
499       tlv_value = tvb_get_ntoh24(tvb, offset);
500       break;
501     case 4:
502       tlv_value = tvb_get_ntohl(tvb, offset);
503       break;
504     default:
505       tlv_value = -1;
506       break;
507     }
508   }
509   return tlv_value;
510 }
511 
512 /* generic juniper header dissector  */
513 static int
dissect_juniper_header(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * juniper_subtree,guint8 * flags)514 dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *juniper_subtree, guint8 *flags)
515 {
516   proto_item *tisub, *magic_item;
517   guint8     proto,ext_type,ext_len;
518   guint16    ext_total_len,ext_offset=6,hdr_len;
519   guint32    magic_number,ext_val;
520 
521   proto_tree *juniper_ext_subtree = NULL, *juniper_ext_subtree_item = NULL;
522 
523   magic_number = tvb_get_ntoh24(tvb, 0);
524   *flags = tvb_get_guint8(tvb, 3);
525 
526   magic_item = proto_tree_add_item(juniper_subtree, hf_juniper_magic, tvb, 0, 3, ENC_BIG_ENDIAN);
527 
528   /* be liberal with magic-number detection -
529    * some older JUNOS releases (e.g. 6.4),
530    * which are still in the field do not generate magic-numbers */
531   if (magic_number != JUNIPER_PCAP_MAGIC) {
532     expert_add_info(pinfo, magic_item, &ei_juniper_no_magic);
533     return 0;
534   }
535 
536   proto_tree_add_item(juniper_subtree, hf_juniper_direction, tvb, 3, 1, ENC_NA);
537 
538   proto_tree_add_item(juniper_subtree, hf_juniper_l2hdr_presence, tvb, 3, 1, ENC_NA);
539 
540   /* calculate hdr_len before cookie, payload */
541 
542   /* meta-info extensions (JUNOS >= 7.5) ? */
543   if ((*flags & JUNIPER_FLAG_EXT) == JUNIPER_FLAG_EXT) {
544     ext_total_len = tvb_get_ntohs(tvb,4);
545     hdr_len = 6 + ext_total_len; /* MGC,flags,ext_total_len */
546 
547     tisub = proto_tree_add_uint (juniper_subtree, hf_juniper_ext_total_len, tvb, 4, 2, ext_total_len);
548     juniper_ext_subtree = proto_item_add_subtree(tisub, ett_juniper);
549 
550     while (ext_total_len > EXT_TLV_HEADER_SIZE) {
551       ext_type = tvb_get_guint8(tvb, ext_offset);
552       ext_len = tvb_get_guint8(tvb, ext_offset+1);
553 
554       if (ext_len == 0 || ext_len > (ext_total_len - EXT_TLV_HEADER_SIZE)) /* a few sanity checks */
555         break;
556 
557       juniper_ext_subtree_item = proto_tree_add_subtree_format(juniper_ext_subtree, tvb, ext_offset, EXT_TLV_HEADER_SIZE + ext_len,
558                                    ett_juniper, &tisub, "%s Extension TLV #%u, length: %u",
559                                    val_to_str_const(ext_type, ext_tlv_vals, "Unknown"),
560                                    ext_type,
561                                    ext_len);
562 
563       ext_val = juniper_ext_get_tlv_value(tvb, ext_type, ext_len, ext_offset+EXT_TLV_HEADER_SIZE);
564 
565       switch (ext_type) {
566       case EXT_TLV_IFD_MEDIATYPE:
567         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifmt,
568                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
569         break;
570       case EXT_TLV_TTP_IFD_MEDIATYPE:
571         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifmt,
572                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
573         break;
574       case EXT_TLV_IFL_ENCAPS:
575         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifle,
576                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
577         break;
578       case EXT_TLV_TTP_IFL_ENCAPS:
579         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifle,
580                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
581         break;
582 
583       case EXT_TLV_IFL_IDX:
584         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifl,
585                             tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
586         break;
587 
588       case EXT_TLV_IFL_UNIT:
589         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_unit,
590                             tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
591         break;
592       case EXT_TLV_IFD_IDX:
593         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifd,
594                             tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
595         break;
596       case EXT_TLV_IFD_NAME: /* FIXME print ifname string - lets fall-through for now */
597       default:
598         proto_item_append_text(tisub, "Unknown");
599         break;
600       }
601 
602       ext_offset += EXT_TLV_HEADER_SIZE + ext_len;
603       ext_total_len -= EXT_TLV_HEADER_SIZE + ext_len;
604     }
605 
606   } else
607     hdr_len = 4; /* MGC,flags */
608 
609   if ((*flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
610     proto = tvb_get_letohl(tvb,hdr_len); /* proto is stored in host-order */
611     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, hdr_len + 4);
612     return -1;
613   }
614 
615   return hdr_len; /* bytes parsed */
616 
617 }
618 
619 /* print the payload protocol  */
620 static int
dissect_juniper_payload_proto(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * juniper_subtree,guint proto,guint offset)621 dissect_juniper_payload_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
622                               proto_tree *juniper_subtree, guint proto, guint offset)
623 {
624   proto_item *ti;
625   tvbuff_t   *next_tvb;
626 
627   ti = proto_tree_add_uint(juniper_subtree, hf_juniper_payload_type, tvb, offset, 0, proto);
628   proto_item_set_generated(ti);
629 
630   switch (proto)
631   {
632     /* XXX - 0xa248 stands for ??? */
633     case 0xa248:
634       proto_tree_add_item(juniper_subtree, hf_juniper_unknown_data, tvb, offset, 4, ENC_NA);
635       offset += 4;
636       proto = JUNIPER_PROTO_IP;
637       break;
638 
639     default:
640       break;
641   }
642 
643   proto_item_set_len(juniper_subtree, offset);
644   next_tvb = tvb_new_subset_remaining(tvb, offset);
645 
646   if (!dissector_try_uint(payload_table, proto, next_tvb, pinfo, tree))
647   {
648     /* XXX - left in for posterity, dissection was never done */
649     /* case JUNIPER_PROTO_OAM: FIXME call OAM dissector without leading HEC byte */
650 
651     call_data_dissector(next_tvb, pinfo, tree);
652   }
653 
654   return 0;
655 }
656 
657 /* MLFR dissector */
658 static int
dissect_juniper_mlfr(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)659 dissect_juniper_mlfr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
660 {
661   proto_item *ti;
662   proto_tree* juniper_subtree;
663   guint      offset;
664   int        bytes_processed;
665   guint8     flags;
666   guint64    aspic_cookie;
667   guint32    lspic_cookie;
668   guint16    mlpic_cookie;
669   guint      proto,cookie_len;
670 
671   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper MLFR");
672   col_clear(pinfo->cinfo, COL_INFO);
673 
674   offset = 0;
675 
676   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Multi-Link Frame-Relay (FRF.15)");
677 
678   /* parse header, match mgc, extract flags and build first tree */
679   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
680 
681   if(bytes_processed == -1)
682     return 4;
683   else
684     offset+=bytes_processed;
685 
686   aspic_cookie = tvb_get_ntoh64(tvb,offset);
687   proto = juniper_svc_cookie_proto(aspic_cookie, JUNIPER_PIC_MLFR, flags);
688   cookie_len = juniper_svc_cookie_len(aspic_cookie);
689 
690   if (cookie_len == AS_PIC_COOKIE_LEN)
691     proto_tree_add_uint64(juniper_subtree, hf_juniper_aspic_cookie,
692                           tvb, offset, AS_PIC_COOKIE_LEN, aspic_cookie);
693   if (cookie_len == LS_PIC_COOKIE_LEN) {
694     lspic_cookie = tvb_get_ntohl(tvb,offset);
695     proto_tree_add_uint(juniper_subtree, hf_juniper_lspic_cookie,
696                         tvb, offset, LS_PIC_COOKIE_LEN, lspic_cookie);
697   }
698 
699   offset += cookie_len;
700 
701   mlpic_cookie = tvb_get_ntohs(tvb, offset);
702 
703   /* AS-PIC IS-IS */
704   if (cookie_len == AS_PIC_COOKIE_LEN &&
705       proto == JUNIPER_PROTO_UNKNOWN &&
706       tvb_get_guint8(tvb,offset) == JUNIPER_HDR_LLC_UI) {
707     offset += 1;
708     proto = JUNIPER_PROTO_ISO;
709   }
710 
711   /* LS-PIC IS-IS */
712   if (cookie_len == LS_PIC_COOKIE_LEN) {
713     if ( tvb_get_ntohs(tvb,offset) == JUNIPER_HDR_LLC_UI ||
714          tvb_get_ntohs(tvb,offset) == (JUNIPER_HDR_LLC_UI<<8)) {
715       offset += 2;
716     }
717   }
718 
719   /* LS-PIC ? */
720   if (cookie_len == LS_PIC_COOKIE_LEN && tvb_get_guint8(tvb,offset) == JUNIPER_HDR_LLC_UI) {
721     offset += 1;
722   }
723 
724   /* child link of an LS-PIC bundle ? */
725   if (cookie_len == 0 && tvb_get_ntohs(tvb,offset+ML_PIC_COOKIE_LEN) ==
726       (JUNIPER_HDR_LLC_UI<<8 | NLPID_Q_933)) {
727     cookie_len = ML_PIC_COOKIE_LEN;
728     proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
729                         tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
730     offset += 3;
731     proto = JUNIPER_PROTO_Q933;
732   }
733 
734   /* child link of an ML-, LS-, AS-PIC bundle / ML-PIC bundle ? */
735   if (cookie_len == 0) {
736     if (tvb_get_ntohs(tvb,offset+ML_PIC_COOKIE_LEN) == JUNIPER_HDR_LLC_UI ||
737         tvb_get_ntohs(tvb,offset+ML_PIC_COOKIE_LEN) == (JUNIPER_HDR_LLC_UI<<8)) {
738       cookie_len = ML_PIC_COOKIE_LEN;
739       proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
740                           tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
741       offset += 4;
742       proto = JUNIPER_PROTO_ISO;
743     }
744   }
745 
746   /* ML-PIC bundle ? */
747   if (cookie_len == 0 && tvb_get_guint8(tvb,offset+ML_PIC_COOKIE_LEN) == JUNIPER_HDR_LLC_UI) {
748     cookie_len = ML_PIC_COOKIE_LEN;
749     proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
750                         tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
751     offset += 3;
752     proto = JUNIPER_PROTO_ISO;
753   }
754 
755   ti = proto_tree_add_uint(juniper_subtree, hf_juniper_cookie_len, tvb, offset, 0, cookie_len);
756   proto_item_set_generated(ti);
757 
758   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, offset);
759 
760   return tvb_captured_length(tvb);
761 }
762 
763 
764 
765 /* MLPPP dissector */
766 static int
dissect_juniper_mlppp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)767 dissect_juniper_mlppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
768 {
769   proto_item *ti;
770   proto_tree* juniper_subtree;
771   guint      offset;
772   int        bytes_processed;
773   guint8     flags;
774   guint64    aspic_cookie;
775   guint32    lspic_cookie;
776   guint16    mlpic_cookie;
777   guint      proto,cookie_len;
778 
779   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper MLPPP");
780   col_clear(pinfo->cinfo, COL_INFO);
781 
782   offset = 0;
783 
784   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper MLPPP");
785 
786   /* parse header, match mgc, extract flags and build first tree */
787   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
788 
789   if(bytes_processed == -1)
790     return 4;
791   else
792     offset+=bytes_processed;
793 
794   aspic_cookie = tvb_get_ntoh64(tvb,offset);
795   proto = juniper_svc_cookie_proto(aspic_cookie, JUNIPER_PIC_MLPPP, flags);
796   cookie_len = juniper_svc_cookie_len(aspic_cookie);
797 
798   if (cookie_len == AS_PIC_COOKIE_LEN)
799     proto_tree_add_uint64(juniper_subtree, hf_juniper_aspic_cookie,
800                           tvb, offset, AS_PIC_COOKIE_LEN, aspic_cookie);
801   if (cookie_len == LS_PIC_COOKIE_LEN) {
802     lspic_cookie = tvb_get_ntohl(tvb,offset);
803     proto_tree_add_uint(juniper_subtree, hf_juniper_lspic_cookie,
804                         tvb, offset, LS_PIC_COOKIE_LEN, lspic_cookie);
805   }
806 
807   /* no cookie pattern identified - lets guess from now on */
808 
809   /* child link of an LS-PIC bundle ? */
810   if (cookie_len == 0 && tvb_get_ntohs(tvb, offset) == JUNIPER_HDR_PPP) {
811     proto = JUNIPER_PROTO_PPP;
812     offset += 2;
813   }
814 
815   /* ML-PIC ? */
816   if (cookie_len == 0 && ppp_heuristic_guess(tvb_get_ntohs(tvb, offset+2))) {
817     proto = JUNIPER_PROTO_PPP;
818     cookie_len = 2;
819     mlpic_cookie = tvb_get_ntohs(tvb, offset);
820     proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
821                         tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
822   }
823 
824   /* child link of an ML-PIC bundle ? */
825   if (cookie_len == 0 && ppp_heuristic_guess(tvb_get_ntohs(tvb, offset))) {
826     proto = JUNIPER_PROTO_PPP;
827   }
828 
829   ti = proto_tree_add_uint(juniper_subtree, hf_juniper_cookie_len, tvb, offset, 0, cookie_len);
830   proto_item_set_generated(ti);
831   offset += cookie_len;
832 
833   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, offset);
834 
835   return tvb_captured_length(tvb);
836 }
837 
838 
839 /* PPPoE dissector */
840 static int
dissect_juniper_pppoe(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)841 dissect_juniper_pppoe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
842 {
843   proto_tree* juniper_subtree;
844   guint      offset;
845   int        bytes_processed;
846   guint8     flags;
847 
848   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper PPPoE");
849   col_clear(pinfo->cinfo, COL_INFO);
850 
851   offset = 0;
852 
853   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper PPPoE PIC");
854 
855   /* parse header, match mgc, extract flags and build first tree */
856   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
857 
858   if(bytes_processed == -1)
859     return 4;
860   else
861     offset+=bytes_processed;
862 
863   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ETHER, offset);
864 
865   return tvb_captured_length(tvb);
866 }
867 
868 /* Ethernet dissector */
869 static int
dissect_juniper_ether(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)870 dissect_juniper_ether(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
871 {
872   proto_tree* juniper_subtree;
873   guint      offset;
874   int        bytes_processed;
875   guint8     flags;
876 
877   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Ethernet");
878   col_clear(pinfo->cinfo, COL_INFO);
879 
880   offset = 0;
881 
882   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Ethernet");
883 
884   /* parse header, match mgc, extract flags and build first tree */
885   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
886 
887   if(bytes_processed == -1)
888     return 4;
889   else
890     offset+=bytes_processed;
891 
892   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ETHER, offset);
893 
894   return tvb_captured_length(tvb);
895 }
896 
897 /* PPP dissector */
898 static int
dissect_juniper_ppp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)899 dissect_juniper_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
900 {
901   proto_tree* juniper_subtree;
902   guint      offset;
903   int        bytes_processed;
904   guint8     flags;
905 
906   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper PPP");
907   col_clear(pinfo->cinfo, COL_INFO);
908 
909   offset = 0;
910 
911   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper PPP");
912 
913   /* parse header, match mgc, extract flags and build first tree */
914   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
915 
916   if(bytes_processed == -1)
917     return 4;
918   else
919     offset+=bytes_processed;
920 
921   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_PPP, offset+2);
922 
923   return tvb_captured_length(tvb);
924 }
925 
926 /* Frame-Relay dissector */
927 static int
dissect_juniper_frelay(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)928 dissect_juniper_frelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
929 {
930   proto_tree* juniper_subtree;
931   guint      offset;
932   int        bytes_processed;
933   guint8     flags;
934 
935   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Frame-Relay");
936   col_clear(pinfo->cinfo, COL_INFO);
937 
938   offset = 0;
939 
940   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Frame-Relay");
941 
942   /* parse header, match mgc, extract flags and build first tree */
943   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
944 
945   if(bytes_processed == -1)
946     return 4;
947   else
948     offset+=bytes_processed;
949 
950   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_FRELAY, offset);
951 
952   return tvb_captured_length(tvb);
953 }
954 
955 /* C-HDLC dissector */
956 static int
dissect_juniper_chdlc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)957 dissect_juniper_chdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
958 {
959   proto_tree* juniper_subtree;
960   guint      offset = 0;
961   int        bytes_processed;
962   guint8     flags;
963 
964   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper C-HDLC");
965   col_clear(pinfo->cinfo, COL_INFO);
966 
967   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper C-HDLC");
968 
969   /* parse header, match mgc, extract flags and build first tree */
970   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
971 
972   if(bytes_processed == -1)
973     return 4;
974   else
975     offset+=bytes_processed;
976 
977   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_CHDLC, offset);
978 
979   return tvb_captured_length(tvb);
980 }
981 
982 
983 
984 /* wrapper for passing the PIC type to the generic ATM dissector */
985 static int
dissect_juniper_atm1(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)986 dissect_juniper_atm1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
987 {
988   dissect_juniper_atm(tvb,pinfo,tree, JUNIPER_PIC_ATM1);
989   return tvb_captured_length(tvb);
990 }
991 
992 /* wrapper for passing the PIC type to the generic ATM dissector */
993 static int
dissect_juniper_atm2(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)994 dissect_juniper_atm2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
995 {
996   dissect_juniper_atm(tvb,pinfo,tree, JUNIPER_PIC_ATM2);
997   return tvb_captured_length(tvb);
998 }
999 
1000 /* generic ATM dissector */
1001 static void
dissect_juniper_atm(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint16 atm_pictype)1002 dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 atm_pictype)
1003 {
1004   proto_item *ti;
1005   proto_tree* juniper_subtree;
1006   guint8     next_proto = JUNIPER_PROTO_UNKNOWN,atm1_header_len,atm2_header_len,flags;
1007   guint32    cookie1, proto;
1008   guint64    cookie2;
1009   guint      offset = 0;
1010   int        bytes_processed;
1011   tvbuff_t   *next_tvb;
1012 
1013   col_clear(pinfo->cinfo, COL_INFO);
1014 
1015   switch (atm_pictype) {
1016   case JUNIPER_PIC_ATM1:
1017     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper ATM1");
1018     juniper_subtree = proto_tree_add_subtree(tree, tvb, 0, 0 , ett_juniper, NULL, "Juniper ATM1 PIC");
1019     break;
1020   case JUNIPER_PIC_ATM2:
1021     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper ATM2");
1022     juniper_subtree = proto_tree_add_subtree(tree, tvb, 0, 0 , ett_juniper, NULL, "Juniper ATM2 PIC");
1023     break;
1024   default: /* should not happen */
1025     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper ATM unknown");
1026     proto_tree_add_subtree(tree, tvb, 0, 0 , ett_juniper, NULL, "Juniper unknown ATM PIC");
1027     return;
1028   }
1029 
1030   /* parse header, match mgc, extract flags and build first tree */
1031   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1032   if(bytes_processed == -1)
1033     return;
1034   else
1035     offset+=bytes_processed;
1036 
1037   if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
1038     atm1_header_len = 4;
1039     atm2_header_len = 4;
1040   }
1041   else {
1042     atm1_header_len = 4;
1043     atm2_header_len = 8;
1044   }
1045 
1046   cookie1 = tvb_get_ntohl(tvb, offset);
1047   cookie2 = tvb_get_ntoh64(tvb, offset);
1048 
1049   if (atm_pictype == JUNIPER_PIC_ATM1) {
1050     proto_tree_add_uint(juniper_subtree, hf_juniper_atm1_cookie, tvb, offset, 4, cookie1);
1051     offset += atm1_header_len;
1052     if ((cookie1 >> 24) == 0x80) /* OAM cell ? */
1053       next_proto = JUNIPER_PROTO_OAM;
1054   }
1055   else { /* JUNIPER_PIC_ATM2 */
1056     proto_tree_add_uint64(juniper_subtree, hf_juniper_atm2_cookie, tvb, offset, 8, cookie2);
1057     offset += atm2_header_len;
1058     if (cookie2 & 0x70) /* OAM cell ? */
1059       next_proto = JUNIPER_PROTO_OAM;
1060   }
1061 
1062   next_tvb = tvb_new_subset_remaining(tvb, offset);
1063 
1064   if (next_proto == JUNIPER_PROTO_OAM) {
1065     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_OAM, offset);
1066     return;
1067   }
1068 
1069   proto = tvb_get_ntoh24(tvb, offset); /* first try: 24-Bit guess */
1070 
1071   if (proto == JUNIPER_HDR_NLPID) {
1072     /*
1073      * This begins with something that appears to be an LLC header for
1074      * OSI; is this LLC-multiplexed traffic?
1075      */
1076     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_LLC, offset);
1077     return;
1078   }
1079 
1080   if (proto == JUNIPER_HDR_SNAP) {
1081     /*
1082      * This begins with something that appears to be an LLC header for
1083      * SNAP; is this LLC-multiplexed traffic?
1084      */
1085     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_LLC_SNAP, offset);
1086     return;
1087   }
1088 
1089   if ((flags & JUNIPER_FLAG_PKT_IN) != JUNIPER_FLAG_PKT_IN && /* ether-over-1483 encaps ? */
1090       (cookie1 & JUNIPER_ATM2_GAP_COUNT_MASK) &&
1091       atm_pictype != JUNIPER_PIC_ATM1) {
1092     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ETHER, offset);
1093     return;
1094   }
1095 
1096   proto = tvb_get_ntohs(tvb, offset); /* second try: 16-Bit guess */
1097 
1098   if ( ppp_heuristic_guess( (guint16) proto) &&
1099        atm_pictype != JUNIPER_PIC_ATM1) {
1100     /*
1101      * This begins with something that appears to be a PPP protocol
1102      * type; is this VC-multiplexed PPPoA?
1103      * That's not supported on ATM1 PICs.
1104      */
1105     proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_encap_type, tvb, offset, 0, 0, "VC-MUX");
1106     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_PPP, offset);
1107     return;
1108   }
1109 
1110   proto = tvb_get_guint8(tvb, offset); /* third try: 8-Bit guess */
1111 
1112   if ( proto == JUNIPER_HDR_LLC_UI ) {
1113     /*
1114      * Cisco style NLPID encaps?
1115      * Is the 0x03 an LLC UI control field?
1116      */
1117     proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_encap_type, tvb, offset, 1, 1, "Cisco NLPID");
1118     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ISO, offset+1);
1119     return;
1120   }
1121 
1122   next_proto = ip_heuristic_guess( (guint8) proto);
1123   if (next_proto != JUNIPER_PROTO_UNKNOWN) { /* last resort: VC-MUX encaps ? */
1124     /*
1125      * This begins with something that might be the first byte of
1126      * an IPv4 or IPv6 packet; is this VC-multiplexed IP?
1127      */
1128     proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_encap_type, tvb, offset, 0, 2, "VC-MUX");
1129     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, next_proto, offset);
1130     return;
1131   }
1132 
1133   /* could not figure what it is */
1134   ti = proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_payload_type, tvb, offset, 0, 0xFFFF, "Unknown");
1135   proto_item_set_len(ti, tvb_reported_length_remaining(tvb, offset));
1136   call_data_dissector(next_tvb, pinfo, tree);
1137 }
1138 
1139 
dissect_juniper_ggsn(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1140 static int dissect_juniper_ggsn(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) {
1141 
1142   proto_tree* juniper_subtree;
1143   guint      offset = 0;
1144   int        bytes_processed;
1145   guint8     flags;
1146   guint16    proto;
1147 
1148   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper GGSN");
1149   col_clear(pinfo->cinfo, COL_INFO);
1150 
1151   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper GGSN");
1152 
1153   /* parse header, match mgc, extract flags and build first tree */
1154   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1155 
1156   if(bytes_processed == -1)
1157     return 4;
1158   else
1159     offset+=bytes_processed;
1160 
1161   proto = tvb_get_letohs(tvb, offset); /* fetch protocol */
1162 
1163   proto_tree_add_uint(juniper_subtree, hf_juniper_proto, tvb, offset, 2, proto);
1164   proto_tree_add_item(juniper_subtree, hf_juniper_vlan, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1165   offset += 4;
1166 
1167   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, offset);
1168 
1169   return tvb_captured_length(tvb);
1170 }
1171 
dissect_juniper_vp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1172 static int dissect_juniper_vp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_) {
1173 
1174   proto_tree* juniper_subtree;
1175   guint      offset = 0;
1176   int        bytes_processed;
1177   guint8     flags;
1178 
1179   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Voice PIC");
1180   col_clear(pinfo->cinfo, COL_INFO);
1181 
1182   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Voice PIC");
1183 
1184   /* parse header, match mgc, extract flags and build first tree */
1185   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1186 
1187   if(bytes_processed == -1)
1188     return 4;
1189   else
1190     offset+=bytes_processed;
1191 
1192   /*
1193    * Right know IPv4 is the only protocol we may encounter.
1194    * For the future there should be sufficient space in the 18-byte
1195    * empty header before payload starts.
1196    */
1197   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_IP, offset+18);
1198   return tvb_captured_length(tvb);
1199 }
1200 
1201 /* Wrapper for Juniper service PIC coookie dissector */
1202 static int
dissect_juniper_svcs(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1203 dissect_juniper_svcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1204 {
1205   proto_tree* juniper_subtree;
1206   guint      offset = 0;
1207   int bytes_processed = 0;
1208   guint8     flags;
1209 
1210   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Services");
1211   col_clear(pinfo->cinfo, COL_INFO);
1212 
1213   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Services cookie");
1214 
1215   /* parse header, match mgc, extract flags and build first tree */
1216   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1217 
1218   if (bytes_processed == -1)
1219       return 4;
1220   else
1221       offset+=bytes_processed;
1222 
1223   if (flags & JUNIPER_FLAG_PKT_IN) {
1224       proto_tree_add_uint(juniper_subtree, hf_juniper_proto, tvb, offset, 2, JUNIPER_PROTO_IP);
1225       offset += 16;
1226   } else {
1227       offset += 12;
1228   }
1229 
1230   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_IP, offset);
1231   return tvb_captured_length(tvb);
1232 }
1233 
dissect_juniper_vn(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1234 static int dissect_juniper_vn(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
1235 {
1236   proto_tree* juniper_subtree;
1237   guint offset = 0;
1238   guint32 tlv_type, tlv_len;
1239 
1240   col_set_str(pinfo->cinfo, COL_PROTOCOL,
1241           "Juniper Virtual Network Information");
1242   col_clear(pinfo->cinfo, COL_INFO);
1243 
1244   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 20,
1245           ett_juniper, NULL, "Juniper Virtual Network Information");
1246 
1247   tlv_type = tvb_get_guint8(tvb, offset);
1248   tlv_len = tvb_get_guint8(tvb, (offset + 1));
1249   offset += VN_TLV_HDR_SIZE;
1250 
1251   while (tlv_type != 255) {
1252 
1253       switch (tlv_type) {
1254           case VN_TLV_HOST_IP:
1255               proto_tree_add_item(juniper_subtree, hf_juniper_vn_host_ip, tvb,
1256                       offset, 4, ENC_BIG_ENDIAN);
1257               break;
1258           case VN_TLV_FLAGS:
1259               proto_tree_add_bitmask(juniper_subtree, tvb, offset, hf_juniper_vn_flags, ett_juniper_vn_flags, vn_flags, ENC_BIG_ENDIAN);
1260               break;
1261           case VN_TLV_SRC_VN:
1262               proto_tree_add_item(juniper_subtree, hf_juniper_vn_src, tvb, offset, tlv_len, ENC_NA|ENC_ASCII);
1263               break;
1264           case VN_TLV_DST_VN:
1265               proto_tree_add_item(juniper_subtree, hf_juniper_vn_dst, tvb, offset, tlv_len, ENC_NA|ENC_ASCII);
1266               break;
1267           default:
1268               proto_tree_add_expert(juniper_subtree, pinfo, &ei_juniper_vn_incorrect_format, tvb, 0, 0);
1269               return offset;
1270       }
1271 
1272       offset += tlv_len;
1273       tlv_type = tvb_get_guint8(tvb, offset);
1274       tlv_len = tvb_get_guint8(tvb, (offset + 1));
1275       offset += VN_TLV_HDR_SIZE;
1276   }
1277 
1278   offset+=tlv_len;
1279   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ETHER, offset);
1280 
1281   return tvb_captured_length(tvb);
1282 }
dissect_juniper_st(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1283 static int dissect_juniper_st(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
1284 {
1285     proto_item *ti;
1286     proto_tree* juniper_subtree, *eth_tree, *ip_tree, *esp_tree;
1287     guint offset = 0;
1288     guint8     flags;
1289     guint32 type, len, ip_proto;
1290     int bytes_processed;
1291 
1292     col_set_str(pinfo->cinfo, COL_PROTOCOL,
1293         "Juniper Secure Tunnel Information");
1294     col_clear(pinfo->cinfo, COL_INFO);
1295 
1296     juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 70,
1297         ett_juniper, NULL, "Juniper Secure Tunnel Information");
1298 
1299      bytes_processed =  dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1300      if (bytes_processed < 1) {
1301          return tvb_captured_length(tvb);
1302      }
1303 
1304     offset += bytes_processed;
1305 
1306     /* Dissect lower layers */
1307     eth_tree = proto_tree_add_subtree(juniper_subtree, tvb, offset, 14, ett_juniper_st_eth, NULL, "Tunnel Ethernet Header");
1308     proto_tree_add_item(eth_tree, hf_juniper_st_eth_dst, tvb, offset, 6, ENC_NA);
1309     offset += 6;
1310     proto_tree_add_item(eth_tree, hf_juniper_st_eth_src, tvb, offset, 6, ENC_NA);
1311     offset += 6;
1312     proto_tree_add_item_ret_uint(eth_tree, hf_juniper_st_eth_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
1313     offset += 2;
1314     /* XXX can we have a VLAN header here ?*/
1315     switch (type) {
1316     case ETHERTYPE_IP:
1317         ip_tree = proto_tree_add_subtree(juniper_subtree, tvb, offset, -1, ett_juniper_st_ip, &ti, "Tunnel IP Header");
1318         proto_tree_add_item_ret_uint(ip_tree, hf_juniper_st_ip_len, tvb, offset, 1, ENC_BIG_ENDIAN, &len);
1319         len = len * 4;
1320         proto_item_set_len(ti, len);
1321         proto_tree_add_item_ret_uint(ip_tree, hf_juniper_st_ip_proto, tvb, offset+9, 1, ENC_BIG_ENDIAN, &ip_proto);
1322         offset += len;
1323         /* ESP is expected */
1324         if (ip_proto != IP_PROTO_ESP) {
1325             return tvb_captured_length(tvb);
1326         }
1327         esp_tree = proto_tree_add_subtree(juniper_subtree, tvb, offset, 8, ett_juniper_st_esp, NULL, "Tunnel ESP Header");
1328         proto_tree_add_item(esp_tree, hf_juniper_st_esp_spi, tvb, offset, 4, ENC_NA);
1329         offset += 4;
1330         proto_tree_add_item(esp_tree, hf_juniper_st_esp_seq, tvb, offset, 4, ENC_NA);
1331         offset += 4;
1332         /*  16 bytes unknown data remains in example trace */
1333         proto_tree_add_subtree(juniper_subtree, tvb, offset, 16, ett_juniper_st_unknown, NULL, "Tunnel Unknown Data");
1334         offset += 16;
1335         break;
1336     default:
1337         return tvb_captured_length(tvb);
1338     }
1339 
1340     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, ip_heuristic_guess(tvb_get_guint8(tvb,offset)), offset);
1341 
1342     return tvb_captured_length(tvb);
1343 
1344 }
1345 
1346 
1347 /* list of Juniper supported PPP proto IDs */
1348 static gboolean
ppp_heuristic_guess(guint16 proto)1349 ppp_heuristic_guess(guint16 proto) {
1350 
1351   switch(proto) {
1352   case PPP_IP :
1353   case PPP_OSI :
1354   case PPP_MPLS_UNI :
1355   case PPP_MPLS_MULTI :
1356   case PPP_IPCP :
1357   case PPP_OSINLCP :
1358   case PPP_MPLSCP :
1359   case PPP_LCP :
1360   case PPP_PAP :
1361   case PPP_CHAP :
1362   case PPP_MP :
1363   case PPP_IPV6 :
1364   case PPP_IPV6CP :
1365     return TRUE;
1366 
1367   default:
1368     return FALSE; /* did not find a ppp header */
1369   }
1370 }
1371 
1372 /*
1373  * return the IP version number based on the first byte of the IP header
1374  * returns 0 if it does not match a valid first IPv4/IPv6 header byte
1375  */
1376 static guint
ip_heuristic_guess(guint8 ip_header_byte)1377 ip_heuristic_guess(guint8 ip_header_byte) {
1378 
1379   switch(ip_header_byte) {
1380   case 0x45:
1381   case 0x46:
1382   case 0x47:
1383   case 0x48:
1384   case 0x49:
1385   case 0x4a:
1386   case 0x4b:
1387   case 0x4c:
1388   case 0x4d:
1389   case 0x4e:
1390   case 0x4f:
1391     return JUNIPER_PROTO_IP;
1392   case 0x60:
1393   case 0x61:
1394   case 0x62:
1395   case 0x63:
1396   case 0x64:
1397   case 0x65:
1398   case 0x66:
1399   case 0x67:
1400   case 0x68:
1401   case 0x69:
1402   case 0x6a:
1403   case 0x6b:
1404   case 0x6c:
1405   case 0x6d:
1406   case 0x6e:
1407   case 0x6f:
1408     return JUNIPER_PROTO_IP6;
1409   default:
1410     return JUNIPER_PROTO_UNKNOWN; /* did not find a ip header */
1411   }
1412 }
1413 
1414 /* return cookie length dep. on cookie SVC id */
1415 static
juniper_svc_cookie_len(guint64 cookie)1416 guint juniper_svc_cookie_len (guint64 cookie) {
1417 
1418   guint8 svc_cookie_id;
1419   svc_cookie_id = (guint8)(cookie >> 56) & 0xff;
1420 
1421   switch(svc_cookie_id) {
1422   case 0x54:
1423     return LS_PIC_COOKIE_LEN;
1424   case GSP_SVC_REQ_APOLLO:
1425   case GSP_SVC_REQ_LSQ:
1426     return AS_PIC_COOKIE_LEN;
1427   default:
1428     return 0;
1429   }
1430 }
1431 
1432 /* return the next-level protocol based on cookie input */
1433 static guint
juniper_svc_cookie_proto(guint64 cookie,guint16 pictype,guint8 flags)1434 juniper_svc_cookie_proto (guint64 cookie, guint16 pictype, guint8 flags) {
1435 
1436   guint8 svc_cookie_id;
1437   guint16 lsq_proto;
1438   guint8 lsq_dir;
1439 
1440   svc_cookie_id = (guint8)(cookie >> 56) & 0xff;
1441   lsq_proto = (guint16)((cookie >> 16) & LSQ_L3_PROTO_MASK);
1442   lsq_dir = (guint8)(cookie >> 24) & 0x3;
1443 
1444 
1445   switch (svc_cookie_id) {
1446   case 0x54:
1447     switch (pictype) {
1448     case JUNIPER_PIC_MLPPP:
1449       return JUNIPER_PROTO_PPP;
1450     case JUNIPER_PIC_MLFR:
1451       return JUNIPER_PROTO_ISO;
1452     default:
1453       return JUNIPER_PROTO_UNKNOWN;
1454     }
1455   case GSP_SVC_REQ_APOLLO:
1456   case GSP_SVC_REQ_LSQ:
1457     switch(lsq_proto) {
1458     case LSQ_L3_PROTO_IPV4:
1459       switch(pictype) {
1460       case JUNIPER_PIC_MLPPP:
1461         /* incoming traffic would have the direction bits set
1462          * -> this must be IS-IS over PPP
1463          */
1464         if ((flags & JUNIPER_FLAG_PKT_IN) == JUNIPER_FLAG_PKT_IN &&
1465             lsq_dir != (LSQ_COOKIE_RE|LSQ_COOKIE_DIR))
1466           return JUNIPER_PROTO_PPP;
1467         else
1468           return JUNIPER_PROTO_IP;
1469       case JUNIPER_PIC_MLFR:
1470         if (lsq_dir == (LSQ_COOKIE_RE|LSQ_COOKIE_DIR))
1471           return JUNIPER_PROTO_UNKNOWN;
1472         else
1473           return JUNIPER_PROTO_IP;
1474       default:
1475         return JUNIPER_PROTO_UNKNOWN;
1476       }
1477     case LSQ_L3_PROTO_IPV6:
1478       return JUNIPER_PROTO_IP6;
1479     case LSQ_L3_PROTO_MPLS:
1480       return JUNIPER_PROTO_MPLS;
1481     case LSQ_L3_PROTO_ISO:
1482       return JUNIPER_PROTO_ISO;
1483     default:
1484       return JUNIPER_PROTO_UNKNOWN;
1485     }
1486   default:
1487     return JUNIPER_PROTO_UNKNOWN;
1488   }
1489 }
1490 
1491 
1492 void
proto_register_juniper(void)1493 proto_register_juniper(void)
1494 {
1495   static hf_register_info hf[] = {
1496     { &hf_juniper_magic,
1497       { "Magic Number", "juniper.magic-number", FT_UINT24, BASE_HEX,
1498         NULL, 0x0, NULL, HFILL }},
1499     { &hf_juniper_direction,
1500       { "Direction", "juniper.direction", FT_UINT8, BASE_HEX,
1501         VALS(juniper_direction_vals), 0x01, NULL, HFILL }},
1502     { &hf_juniper_l2hdr_presence,
1503       { "L2 header presence", "juniper.l2hdr", FT_UINT8, BASE_HEX,
1504         VALS(juniper_l2hdr_presence_vals), 0x02, NULL, HFILL }},
1505     { &hf_juniper_ext_total_len,
1506       { "Extension(s) Total length", "juniper.ext_total_len", FT_UINT16, BASE_DEC,
1507         NULL, 0x0, NULL, HFILL }},
1508     { &hf_juniper_cookie_len,
1509       { "Cookie length", "juniper.cookie_len", FT_UINT32, BASE_DEC,
1510         NULL, 0x0, NULL, HFILL }},
1511     { &hf_juniper_atm2_cookie,
1512       { "Cookie", "juniper.atm2.cookie", FT_UINT64, BASE_HEX,
1513         NULL, 0x0, NULL, HFILL }},
1514     { &hf_juniper_atm1_cookie,
1515       { "Cookie", "juniper.atm1.cookie", FT_UINT32, BASE_HEX,
1516         NULL, 0x0, NULL, HFILL }},
1517     { &hf_juniper_mlpic_cookie,
1518       { "Cookie", "juniper.mlpic.cookie", FT_UINT16, BASE_HEX,
1519         NULL, 0x0, NULL, HFILL }},
1520     { &hf_juniper_lspic_cookie,
1521       { "Cookie", "juniper.lspic.cookie", FT_UINT32, BASE_HEX,
1522         NULL, 0x0, NULL, HFILL }},
1523     { &hf_juniper_aspic_cookie,
1524       { "Cookie", "juniper.aspic.cookie", FT_UINT64, BASE_HEX,
1525         NULL, 0x0, NULL, HFILL }},
1526     { &hf_juniper_vlan,
1527       { "VLan ID", "juniper.vlan", FT_UINT16, BASE_DEC,
1528         NULL, 0x0, NULL, HFILL }},
1529     { &hf_juniper_proto,
1530       { "Protocol", "juniper.proto", FT_UINT16, BASE_DEC,
1531         VALS(juniper_proto_vals), 0x0, NULL, HFILL }},
1532     { &hf_juniper_payload_type,
1533       { "Payload Type", "juniper.payload_type", FT_UINT16, BASE_DEC,
1534         VALS(juniper_proto_vals), 0x0, NULL, HFILL }},
1535     { &hf_juniper_encap_type,
1536       { "Encapsulation Type", "juniper.encap_type", FT_UINT8, BASE_DEC,
1537         NULL, 0x0, NULL, HFILL }},
1538     { &hf_juniper_ext_ifd,
1539       /* Juniper PCAP extensions */
1540       { "Device Interface Index", "juniper.ext.ifd", FT_UINT32, BASE_DEC,
1541         NULL, 0x0, NULL, HFILL }},
1542     { &hf_juniper_ext_ifl,
1543       { "Logical Interface Index", "juniper.ext.ifl", FT_UINT32, BASE_DEC,
1544         NULL, 0x0, NULL, HFILL }},
1545     { &hf_juniper_ext_unit,
1546       { "Logical Unit Number", "juniper.ext.unit", FT_UINT32, BASE_DEC,
1547         NULL, 0x0, NULL, HFILL }},
1548     { &hf_juniper_ext_ifmt,
1549       { "Device Media Type", "juniper.ext.ifmt", FT_UINT16, BASE_DEC,
1550         VALS(juniper_ifmt_vals), 0x0, NULL, HFILL }},
1551     { &hf_juniper_ext_ifle,
1552       { "Logical Interface Encapsulation", "juniper.ext.ifle", FT_UINT16, BASE_DEC,
1553         VALS(juniper_ifle_vals), 0x0, NULL, HFILL }},
1554     { &hf_juniper_ext_ttp_ifmt,
1555       { "TTP derived Device Media Type", "juniper.ext.ttp_ifmt", FT_UINT16, BASE_DEC,
1556         VALS(juniper_ifmt_vals), 0x0, NULL, HFILL }},
1557     { &hf_juniper_ext_ttp_ifle,
1558       { "TTP derived Logical Interface Encapsulation", "juniper.ext.ttp_ifle", FT_UINT16, BASE_DEC,
1559         VALS(juniper_ifle_vals), 0x0, NULL, HFILL }},
1560     { &hf_juniper_unknown_data,
1561       { "Unknown data", "juniper.unknown_data", FT_BYTES, BASE_NONE,
1562         NULL, 0x0, NULL, HFILL }},
1563     { &hf_juniper_vn_host_ip,
1564       { "Host IP", "juniper.vn.host_ip", FT_IPv4, BASE_NONE,
1565         NULL, 0x0, NULL, HFILL }},
1566     { &hf_juniper_vn_src,
1567       { "Src VN", "juniper.vn.src", FT_STRING, BASE_NONE,
1568         NULL, 0x0, NULL, HFILL }},
1569     { &hf_juniper_vn_dst,
1570       { "Dst VN", "juniper.vn.dst", FT_STRING, BASE_NONE,
1571         NULL, 0x0, NULL, HFILL }},
1572     { &hf_juniper_vn_flags,
1573       { "Flags", "juniper.vn.flags", FT_UINT32, BASE_HEX, NULL, VN_FLAG_MASK,
1574         NULL, HFILL }},
1575     { &hf_juniper_vn_flag_alert,
1576         { "Action Alert", "juniper.vn.flags.alert", FT_BOOLEAN, 32,
1577           TFS(&tfs_set_notset), VN_FLAG_ALERT, NULL, HFILL }},
1578     { &hf_juniper_vn_flag_drop,
1579         { "Action Drop", "juniper.vn.flags.drop", FT_BOOLEAN, 32,
1580           TFS(&tfs_set_notset), VN_FLAG_DROP, NULL, HFILL }},
1581     { &hf_juniper_vn_flag_deny,
1582         { "Action Deny", "juniper.vn.flags.deny", FT_BOOLEAN, 32,
1583           TFS(&tfs_set_notset), VN_FLAG_DENY, NULL, HFILL }},
1584     { &hf_juniper_vn_flag_log,
1585         { "Action Log", "juniper.vn.flags.log", FT_BOOLEAN, 32,
1586           TFS(&tfs_set_notset), VN_FLAG_LOG, NULL, HFILL }},
1587     { &hf_juniper_vn_flag_pass,
1588         { "Action Pass", "juniper.vn.flags.pass", FT_BOOLEAN, 32,
1589           TFS(&tfs_set_notset), VN_FLAG_PASS, NULL, HFILL }},
1590     { &hf_juniper_vn_flag_reject,
1591         { "Action Reject", "juniper.vn.flags.reject", FT_BOOLEAN, 32,
1592           TFS(&tfs_set_notset), VN_FLAG_REJECT, NULL, HFILL }},
1593     { &hf_juniper_vn_flag_mirror,
1594         { "Action Mirror", "juniper.vn.flags.mirror", FT_BOOLEAN, 32,
1595           TFS(&tfs_set_notset), VN_FLAG_MIRROR, NULL, HFILL }},
1596     { &hf_juniper_vn_flag_direction,
1597         { "Direction Ingress", "juniper.vn.flags.direction", FT_BOOLEAN, 32,
1598           TFS(&tfs_set_notset), VN_FLAG_DIRECTION, NULL, HFILL }},
1599     { &hf_juniper_st_eth_dst,
1600         { "Destination", "juniper.st.eth.dst", FT_ETHER, BASE_NONE,
1601           NULL, 0x0, NULL, HFILL }},
1602     { &hf_juniper_st_eth_src,
1603         { "Source", "juniper.st.eth.src", FT_ETHER, BASE_NONE,
1604           NULL, 0x0, NULL, HFILL }},
1605     { &hf_juniper_st_eth_type,
1606         { "Type", "juniper.st.eth.type", FT_UINT16, BASE_HEX,
1607             VALS(etype_vals), 0x0, NULL, HFILL }},
1608     { &hf_juniper_st_ip_len,
1609         { "Header Length", "juniper.st.ip.len", FT_UINT8, BASE_DEC,
1610             NULL, 0x0f, NULL, HFILL }},
1611     { &hf_juniper_st_ip_proto,
1612       { "Protocol", "juniper.st.ip.proto", FT_UINT8, BASE_DEC | BASE_EXT_STRING,
1613         &ipproto_val_ext, 0x0, NULL, HFILL }},
1614     { &hf_juniper_st_esp_spi,
1615         { "ESP SPI", "juniper.st.esp.spi", FT_UINT32, BASE_DEC,
1616             NULL, 0x0, NULL, HFILL }},
1617     { &hf_juniper_st_esp_seq,
1618         { "ESP Sequence", "juniper.st.esp.seq", FT_UINT32, BASE_DEC,
1619             NULL, 0x0, NULL, HFILL }},
1620 
1621   };
1622 
1623   static gint *ett[] = {
1624     &ett_juniper,
1625     &ett_juniper_vn_flags,
1626     &ett_juniper_st_eth,
1627     &ett_juniper_st_ip,
1628     &ett_juniper_st_esp,
1629     &ett_juniper_st_unknown,
1630   };
1631 
1632   static ei_register_info ei[] = {
1633     { &ei_juniper_no_magic, { "juniper.magic-number.none", PI_PROTOCOL, PI_WARN, "No Magic-Number found!", EXPFILL }},
1634     { &ei_juniper_vn_incorrect_format, { "juniper.vn.incorrect_format", PI_PROTOCOL, PI_WARN, "Incorrect format", EXPFILL }},
1635   };
1636 
1637   expert_module_t* expert_juniper;
1638 
1639   proto_juniper = proto_register_protocol("Juniper", "Juniper", "juniper");
1640   proto_register_field_array(proto_juniper, hf, array_length(hf));
1641   proto_register_subtree_array(ett, array_length(ett));
1642   expert_juniper = expert_register_protocol(proto_juniper);
1643   expert_register_field_array(expert_juniper, ei, array_length(ei));
1644 
1645   payload_table = register_dissector_table("juniper.proto", "Juniper payload dissectors", proto_juniper, FT_UINT32, BASE_HEX);
1646 
1647 }
1648 
1649 void
proto_reg_handoff_juniper(void)1650 proto_reg_handoff_juniper(void)
1651 {
1652   dissector_handle_t juniper_atm1_handle;
1653   dissector_handle_t juniper_atm2_handle;
1654   dissector_handle_t juniper_pppoe_handle;
1655   dissector_handle_t juniper_mlppp_handle;
1656   dissector_handle_t juniper_mlfr_handle;
1657   dissector_handle_t juniper_ether_handle;
1658   dissector_handle_t juniper_ppp_handle;
1659   dissector_handle_t juniper_frelay_handle;
1660   dissector_handle_t juniper_chdlc_handle;
1661   dissector_handle_t juniper_ggsn_handle;
1662   dissector_handle_t juniper_vp_handle;
1663   dissector_handle_t juniper_svcs_handle;
1664   dissector_handle_t juniper_vn_handle;
1665   dissector_handle_t juniper_st_handle;
1666 
1667   juniper_atm2_handle   = create_dissector_handle(dissect_juniper_atm2,   proto_juniper);
1668   juniper_atm1_handle   = create_dissector_handle(dissect_juniper_atm1,   proto_juniper);
1669   juniper_pppoe_handle  = create_dissector_handle(dissect_juniper_pppoe,  proto_juniper);
1670   juniper_mlppp_handle  = create_dissector_handle(dissect_juniper_mlppp,  proto_juniper);
1671   juniper_mlfr_handle   = create_dissector_handle(dissect_juniper_mlfr,   proto_juniper);
1672   juniper_ether_handle  = create_dissector_handle(dissect_juniper_ether,  proto_juniper);
1673   juniper_ppp_handle    = create_dissector_handle(dissect_juniper_ppp,    proto_juniper);
1674   juniper_frelay_handle = create_dissector_handle(dissect_juniper_frelay, proto_juniper);
1675   juniper_chdlc_handle  = create_dissector_handle(dissect_juniper_chdlc,  proto_juniper);
1676   juniper_ggsn_handle   = create_dissector_handle(dissect_juniper_ggsn,   proto_juniper);
1677   juniper_vp_handle     = create_dissector_handle(dissect_juniper_vp,     proto_juniper);
1678   juniper_svcs_handle   = create_dissector_handle(dissect_juniper_svcs,   proto_juniper);
1679   juniper_vn_handle     = create_dissector_handle(dissect_juniper_vn,     proto_juniper);
1680   juniper_st_handle     = create_dissector_handle(dissect_juniper_st,     proto_juniper);
1681 
1682   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_ATM2,   juniper_atm2_handle);
1683   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_ATM1,   juniper_atm1_handle);
1684   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_PPPOE,  juniper_pppoe_handle);
1685   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_MLPPP,  juniper_mlppp_handle);
1686   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_MLFR,   juniper_mlfr_handle);
1687   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_ETHER,  juniper_ether_handle);
1688   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_PPP,    juniper_ppp_handle);
1689   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_FRELAY, juniper_frelay_handle);
1690   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_CHDLC,  juniper_chdlc_handle);
1691   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_GGSN,   juniper_ggsn_handle);
1692   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_VP,     juniper_vp_handle);
1693   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_SVCS,   juniper_svcs_handle);
1694   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_VN,     juniper_vn_handle);
1695   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_ST,     juniper_st_handle);
1696   dissector_add_for_decode_as_with_preference("udp.port", juniper_vn_handle);
1697 }
1698 
1699 
1700 /*
1701  * Editor modelines
1702  *
1703  * Local Variables:
1704  * c-basic-offset: 2
1705  * tab-width: 8
1706  * indent-tabs-mode: nil
1707  * End:
1708  *
1709  * ex: set shiftwidth=2 tabstop=8 expandtab:
1710  * :indentSize=2:tabSize=8:noTabs=true:
1711  */
1712