create_dissector_handle -> new_create_dissector_handle
[metze/wireshark/wip.git] / epan / dissectors / packet-juniper.c
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  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "config.h"
25
26 #include <epan/packet.h>
27 #include <epan/expert.h>
28 #include <epan/addr_resolv.h>
29 #include <epan/ppptypes.h>
30 #include "packet-ppp.h"
31 #include "packet-juniper.h"
32 #include <epan/nlpid.h>
33
34 void proto_register_juniper(void);
35 void proto_reg_handoff_juniper(void);
36
37 #define JUNIPER_FLAG_PKT_OUT        0x00     /* Outgoing packet */
38 #define JUNIPER_FLAG_PKT_IN         0x01     /* Incoming packet */
39 #define JUNIPER_FLAG_NO_L2          0x02     /* L2 header stripped */
40 #define JUNIPER_FLAG_EXT            0x80     /* extensions present */
41 #define EXT_TLV_HEADER_SIZE 2
42 #define JUNIPER_ATM2_PKT_TYPE_MASK  0x70
43 #define JUNIPER_ATM2_GAP_COUNT_MASK 0x3F
44 #define JUNIPER_PCAP_MAGIC          0x4d4743
45
46 #define JUNIPER_PIC_ATM1   1
47 #define JUNIPER_PIC_ATM2   2
48 #define JUNIPER_PIC_MLPPP  3
49 #define JUNIPER_PIC_MLFR   4
50
51 #define JUNIPER_HDR_SNAP   0xaaaa03
52 #define JUNIPER_HDR_NLPID  0xfefe03
53 #define JUNIPER_HDR_LLC_UI 0x03
54 #define JUNIPER_HDR_PPP    0xff03
55
56 #define ML_PIC_COOKIE_LEN 2
57 #define LS_PIC_COOKIE_LEN 4
58 #define AS_PIC_COOKIE_LEN 8
59
60 #define GSP_SVC_REQ_APOLLO 0x40
61 #define GSP_SVC_REQ_LSQ    0x47
62
63 #define LSQ_COOKIE_RE         0x2
64 #define LSQ_COOKIE_DIR        0x1
65 #define LSQ_L3_PROTO_SHIFT     4
66 #define LSQ_L3_PROTO_MASK     0xf0
67 #define LSQ_L3_PROTO_IPV4     (0 << LSQ_L3_PROTO_SHIFT)
68 #define LSQ_L3_PROTO_IPV6     (1 << LSQ_L3_PROTO_SHIFT)
69 #define LSQ_L3_PROTO_MPLS     (2 << LSQ_L3_PROTO_SHIFT)
70 #define LSQ_L3_PROTO_ISO      (3 << LSQ_L3_PROTO_SHIFT)
71
72 #define EXT_TLV_IFD_IDX           1
73 #define EXT_TLV_IFD_NAME          2
74 #define EXT_TLV_IFD_MEDIATYPE     3
75 #define EXT_TLV_IFL_IDX           4
76 #define EXT_TLV_IFL_UNIT          5
77 #define EXT_TLV_IFL_ENCAPS        6
78 #define EXT_TLV_TTP_IFD_MEDIATYPE 7
79 #define EXT_TLV_TTP_IFL_ENCAPS    8
80
81 static const value_string ext_tlv_vals[] = {
82   { EXT_TLV_IFD_IDX,           "Device Interface Index" },
83   { EXT_TLV_IFD_NAME,          "Device Interface Name" },
84   { EXT_TLV_IFD_MEDIATYPE,     "Device Media Type" },
85   { EXT_TLV_IFL_IDX,           "Logical Interface Index" },
86   { EXT_TLV_IFL_UNIT,          "Logical Unit Number" },
87   { EXT_TLV_IFL_ENCAPS,        "Logical Interface Encapsulation" },
88   { EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" },
89   { EXT_TLV_TTP_IFL_ENCAPS,    "TTP derived Logical Interface Encapsulation" },
90   { 0,             NULL }
91 };
92
93 static const value_string juniper_direction_vals[] = {
94   {JUNIPER_FLAG_PKT_OUT, "Out"},
95   {JUNIPER_FLAG_PKT_IN,  "In"},
96   {0,                    NULL}
97 };
98
99 static const value_string juniper_l2hdr_presence_vals[] = {
100   { 0, "Present"},
101   { 2, "none"},
102   {0,                    NULL}
103 };
104
105 #define JUNIPER_IFML_ETHER              1
106 #define JUNIPER_IFML_FDDI               2
107 #define JUNIPER_IFML_TOKENRING          3
108 #define JUNIPER_IFML_PPP                4
109 #define JUNIPER_IFML_FRAMERELAY         5
110 #define JUNIPER_IFML_CISCOHDLC          6
111 #define JUNIPER_IFML_SMDSDXI            7
112 #define JUNIPER_IFML_ATMPVC             8
113 #define JUNIPER_IFML_PPP_CCC            9
114 #define JUNIPER_IFML_FRAMERELAY_CCC     10
115 #define JUNIPER_IFML_IPIP               11
116 #define JUNIPER_IFML_GRE                12
117 #define JUNIPER_IFML_PIM                13
118 #define JUNIPER_IFML_PIMD               14
119 #define JUNIPER_IFML_CISCOHDLC_CCC      15
120 #define JUNIPER_IFML_VLAN_CCC           16
121 #define JUNIPER_IFML_MLPPP              17
122 #define JUNIPER_IFML_MLFR               18
123 #define JUNIPER_IFML_ML                 19
124 #define JUNIPER_IFML_LSI                20
125 #define JUNIPER_IFML_DFE                21
126 #define JUNIPER_IFML_ATM_CELLRELAY_CCC  22
127 #define JUNIPER_IFML_CRYPTO             23
128 #define JUNIPER_IFML_GGSN               24
129 #define JUNIPER_IFML_LSI_PPP            25
130 #define JUNIPER_IFML_LSI_CISCOHDLC      26
131 #define JUNIPER_IFML_PPP_TCC            27
132 #define JUNIPER_IFML_FRAMERELAY_TCC     28
133 #define JUNIPER_IFML_CISCOHDLC_TCC      29
134 #define JUNIPER_IFML_ETHERNET_CCC       30
135 #define JUNIPER_IFML_VT                 31
136 #define JUNIPER_IFML_EXTENDED_VLAN_CCC  32
137 #define JUNIPER_IFML_ETHER_OVER_ATM     33
138 #define JUNIPER_IFML_MONITOR            34
139 #define JUNIPER_IFML_ETHERNET_TCC       35
140 #define JUNIPER_IFML_VLAN_TCC           36
141 #define JUNIPER_IFML_EXTENDED_VLAN_TCC  37
142 #define JUNIPER_IFML_CONTROLLER         38
143 #define JUNIPER_IFML_MFR                39
144 #define JUNIPER_IFML_LS                 40
145 #define JUNIPER_IFML_ETHERNET_VPLS      41
146 #define JUNIPER_IFML_ETHERNET_VLAN_VPLS 42
147 #define JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS 43
148 #define JUNIPER_IFML_LT                 44
149 #define JUNIPER_IFML_SERVICES           45
150 #define JUNIPER_IFML_ETHER_VPLS_OVER_ATM 46
151 #define JUNIPER_IFML_FR_PORT_CCC        47
152 #define JUNIPER_IFML_FRAMERELAY_EXT_CCC 48
153 #define JUNIPER_IFML_FRAMERELAY_EXT_TCC 49
154 #define JUNIPER_IFML_FRAMERELAY_FLEX    50
155 #define JUNIPER_IFML_GGSNI              51
156 #define JUNIPER_IFML_ETHERNET_FLEX      52
157 #define JUNIPER_IFML_COLLECTOR          53
158 #define JUNIPER_IFML_AGGREGATOR         54
159 #define JUNIPER_IFML_LAPD               55
160 #define JUNIPER_IFML_PPPOE              56
161 #define JUNIPER_IFML_PPP_SUBORDINATE    57
162 #define JUNIPER_IFML_CISCOHDLC_SUBORDINATE  58
163 #define JUNIPER_IFML_DFC                59
164 #define JUNIPER_IFML_PICPEER            60
165
166 static const value_string juniper_ifmt_vals[] = {
167   { JUNIPER_IFML_ETHER, "Ethernet" },
168   { JUNIPER_IFML_FDDI, "FDDI" },
169   { JUNIPER_IFML_TOKENRING, "Token-Ring" },
170   { JUNIPER_IFML_PPP, "PPP" },
171   { JUNIPER_IFML_PPP_SUBORDINATE, "PPP-Subordinate" },
172   { JUNIPER_IFML_FRAMERELAY, "Frame-Relay" },
173   { JUNIPER_IFML_CISCOHDLC, "Cisco-HDLC" },
174   { JUNIPER_IFML_SMDSDXI, "SMDS-DXI" },
175   { JUNIPER_IFML_ATMPVC, "ATM-PVC" },
176   { JUNIPER_IFML_PPP_CCC, "PPP-CCC" },
177   { JUNIPER_IFML_FRAMERELAY_CCC, "Frame-Relay-CCC" },
178   { JUNIPER_IFML_FRAMERELAY_EXT_CCC, "Extended FR-CCC" },
179   { JUNIPER_IFML_IPIP, "IP-over-IP" },
180   { JUNIPER_IFML_GRE, "GRE" },
181   { JUNIPER_IFML_PIM, "PIM-Encapsulator" },
182   { JUNIPER_IFML_PIMD, "PIM-Decapsulator" },
183   { JUNIPER_IFML_CISCOHDLC_CCC, "Cisco-HDLC-CCC" },
184   { JUNIPER_IFML_VLAN_CCC, "VLAN-CCC" },
185   { JUNIPER_IFML_EXTENDED_VLAN_CCC, "Extended-VLAN-CCC" },
186   { JUNIPER_IFML_MLPPP, "Multilink-PPP" },
187   { JUNIPER_IFML_MLFR, "Multilink-FR" },
188   { JUNIPER_IFML_MFR, "Multilink-FR-UNI-NNI" },
189   { JUNIPER_IFML_ML, "Multilink" },
190   { JUNIPER_IFML_LS, "LinkService" },
191   { JUNIPER_IFML_LSI, "LSI" },
192   { JUNIPER_IFML_ATM_CELLRELAY_CCC, "ATM-CCC-Cell-Relay" },
193   { JUNIPER_IFML_CRYPTO, "IPSEC-over-IP" },
194   { JUNIPER_IFML_GGSN, "GGSN" },
195   { JUNIPER_IFML_PPP_TCC, "PPP-TCC" },
196   { JUNIPER_IFML_FRAMERELAY_TCC, "Frame-Relay-TCC" },
197   { JUNIPER_IFML_FRAMERELAY_EXT_TCC, "Extended FR-TCC" },
198   { JUNIPER_IFML_CISCOHDLC_TCC, "Cisco-HDLC-TCC" },
199   { JUNIPER_IFML_ETHERNET_CCC, "Ethernet-CCC" },
200   { JUNIPER_IFML_VT, "VPN-Loopback-tunnel" },
201   { JUNIPER_IFML_ETHER_OVER_ATM, "Ethernet-over-ATM" },
202   { JUNIPER_IFML_ETHER_VPLS_OVER_ATM, "Ethernet-VPLS-over-ATM" },
203   { JUNIPER_IFML_MONITOR, "Monitor" },
204   { JUNIPER_IFML_ETHERNET_TCC, "Ethernet-TCC" },
205   { JUNIPER_IFML_VLAN_TCC, "VLAN-TCC" },
206   { JUNIPER_IFML_EXTENDED_VLAN_TCC, "Extended-VLAN-TCC" },
207   { JUNIPER_IFML_CONTROLLER, "Controller" },
208   { JUNIPER_IFML_ETHERNET_VPLS, "VPLS" },
209   { JUNIPER_IFML_ETHERNET_VLAN_VPLS, "VLAN-VPLS" },
210   { JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS, "Extended-VLAN-VPLS" },
211   { JUNIPER_IFML_LT, "Logical-tunnel" },
212   { JUNIPER_IFML_SERVICES, "General-Services" },
213   { JUNIPER_IFML_PPPOE, "PPPoE" },
214   { JUNIPER_IFML_ETHERNET_FLEX, "Flexible-Ethernet-Services" },
215   { JUNIPER_IFML_FRAMERELAY_FLEX, "Flexible-FrameRelay" },
216   { JUNIPER_IFML_COLLECTOR, "Flow-collection" },
217   { JUNIPER_IFML_PICPEER, "PIC Peer" },
218   { JUNIPER_IFML_DFC, "Dynamic-Flow-Capture" },
219   {0,                    NULL}
220 };
221
222 #define JUNIPER_IFLE_ATM_SNAP           2
223 #define JUNIPER_IFLE_ATM_NLPID          3
224 #define JUNIPER_IFLE_ATM_VCMUX          4
225 #define JUNIPER_IFLE_ATM_LLC            5
226 #define JUNIPER_IFLE_ATM_PPP_VCMUX      6
227 #define JUNIPER_IFLE_ATM_PPP_LLC        7
228 #define JUNIPER_IFLE_ATM_PPP_FUNI       8
229 #define JUNIPER_IFLE_ATM_CCC            9
230 #define JUNIPER_IFLE_FR_NLPID           10
231 #define JUNIPER_IFLE_FR_SNAP            11
232 #define JUNIPER_IFLE_FR_PPP             12
233 #define JUNIPER_IFLE_FR_CCC             13
234 #define JUNIPER_IFLE_ENET2              14
235 #define JUNIPER_IFLE_IEEE8023_SNAP      15
236 #define JUNIPER_IFLE_IEEE8023_LLC       16
237 #define JUNIPER_IFLE_PPP                17
238 #define JUNIPER_IFLE_CISCOHDLC          18
239 #define JUNIPER_IFLE_PPP_CCC            19
240 #define JUNIPER_IFLE_IPIP_NULL          20
241 #define JUNIPER_IFLE_PIM_NULL           21
242 #define JUNIPER_IFLE_GRE_NULL           22
243 #define JUNIPER_IFLE_GRE_PPP            23
244 #define JUNIPER_IFLE_PIMD_DECAPS        24
245 #define JUNIPER_IFLE_CISCOHDLC_CCC      25
246 #define JUNIPER_IFLE_ATM_CISCO_NLPID    26
247 #define JUNIPER_IFLE_VLAN_CCC           27
248 #define JUNIPER_IFLE_MLPPP              28
249 #define JUNIPER_IFLE_MLFR               29
250 #define JUNIPER_IFLE_LSI_NULL           30
251 #define JUNIPER_IFLE_AGGREGATE_UNUSED   31
252 #define JUNIPER_IFLE_ATM_CELLRELAY_CCC  32
253 #define JUNIPER_IFLE_CRYPTO             33
254 #define JUNIPER_IFLE_GGSN               34
255 #define JUNIPER_IFLE_ATM_TCC            35
256 #define JUNIPER_IFLE_FR_TCC             36
257 #define JUNIPER_IFLE_PPP_TCC            37
258 #define JUNIPER_IFLE_CISCOHDLC_TCC      38
259 #define JUNIPER_IFLE_ETHERNET_CCC       39
260 #define JUNIPER_IFLE_VT                 40
261 #define JUNIPER_IFLE_ATM_EOA_LLC        41
262 #define JUNIPER_IFLE_EXTENDED_VLAN_CCC          42
263 #define JUNIPER_IFLE_ATM_SNAP_TCC       43
264 #define JUNIPER_IFLE_MONITOR            44
265 #define JUNIPER_IFLE_ETHERNET_TCC       45
266 #define JUNIPER_IFLE_VLAN_TCC           46
267 #define JUNIPER_IFLE_EXTENDED_VLAN_TCC  47
268 #define JUNIPER_IFLE_MFR                48
269 #define JUNIPER_IFLE_ETHERNET_VPLS      49
270 #define JUNIPER_IFLE_ETHERNET_VLAN_VPLS 50
271 #define JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS 51
272 #define JUNIPER_IFLE_SERVICES           52
273 #define JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC                53
274 #define JUNIPER_IFLE_FR_PORT_CCC        54
275 #define JUNIPER_IFLE_ATM_MLPPP_LLC      55
276 #define JUNIPER_IFLE_ATM_EOA_CCC        56
277 #define JUNIPER_IFLE_LT_VLAN            57
278 #define JUNIPER_IFLE_COLLECTOR          58
279 #define JUNIPER_IFLE_AGGREGATOR         59
280 #define JUNIPER_IFLE_LAPD               60
281 #define JUNIPER_IFLE_ATM_PPPOE_LLC          61
282 #define JUNIPER_IFLE_ETHERNET_PPPOE         62
283 #define JUNIPER_IFLE_PPPOE                  63
284 #define JUNIPER_IFLE_PPP_SUBORDINATE        64
285 #define JUNIPER_IFLE_CISCOHDLC_SUBORDINATE  65
286 #define JUNIPER_IFLE_DFC                    66
287 #define JUNIPER_IFLE_PICPEER                67
288
289 static const value_string juniper_ifle_vals[] = {
290   { JUNIPER_IFLE_AGGREGATOR, "Aggregator" },
291   { JUNIPER_IFLE_ATM_CCC, "CCC over ATM" },
292   { JUNIPER_IFLE_ATM_CELLRELAY_CCC, "ATM CCC Cell Relay" },
293   { JUNIPER_IFLE_ATM_CISCO_NLPID, "CISCO compatible NLPID" },
294   { JUNIPER_IFLE_ATM_EOA_CCC, "Ethernet over ATM CCC" },
295   { JUNIPER_IFLE_ATM_EOA_LLC, "Ethernet over ATM LLC" },
296   { JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC, "Ethernet VPLS over ATM LLC" },
297   { JUNIPER_IFLE_ATM_LLC, "ATM LLC" },
298   { JUNIPER_IFLE_ATM_MLPPP_LLC, "MLPPP over ATM LLC" },
299   { JUNIPER_IFLE_ATM_NLPID, "ATM NLPID" },
300   { JUNIPER_IFLE_ATM_PPPOE_LLC, "PPPoE over ATM LLC" },
301   { JUNIPER_IFLE_ATM_PPP_FUNI, "PPP over FUNI" },
302   { JUNIPER_IFLE_ATM_PPP_LLC, "PPP over ATM LLC" },
303   { JUNIPER_IFLE_ATM_PPP_VCMUX, "PPP over ATM VCMUX" },
304   { JUNIPER_IFLE_ATM_SNAP, "ATM SNAP" },
305   { JUNIPER_IFLE_ATM_SNAP_TCC, "ATM SNAP TCC" },
306   { JUNIPER_IFLE_ATM_TCC, "ATM VCMUX TCC" },
307   { JUNIPER_IFLE_ATM_VCMUX, "ATM VCMUX" },
308   { JUNIPER_IFLE_CISCOHDLC, "C-HDLC" },
309   { JUNIPER_IFLE_CISCOHDLC_CCC, "C-HDLC CCC" },
310   { JUNIPER_IFLE_CISCOHDLC_SUBORDINATE, "C-HDLC via dialer" },
311   { JUNIPER_IFLE_CISCOHDLC_TCC, "C-HDLC TCC" },
312   { JUNIPER_IFLE_COLLECTOR, "Collector" },
313   { JUNIPER_IFLE_CRYPTO, "Crypto" },
314   { JUNIPER_IFLE_ENET2, "Ethernet" },
315   { JUNIPER_IFLE_ETHERNET_CCC, "Ethernet CCC" },
316   { JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS, "Extended VLAN VPLS" },
317   { JUNIPER_IFLE_ETHERNET_PPPOE, "PPPoE over Ethernet" },
318   { JUNIPER_IFLE_ETHERNET_TCC, "Ethernet TCC" },
319   { JUNIPER_IFLE_ETHERNET_VLAN_VPLS, "VLAN VPLS" },
320   { JUNIPER_IFLE_ETHERNET_VPLS, "VPLS" },
321   { JUNIPER_IFLE_EXTENDED_VLAN_CCC, "Extended VLAN CCC" },
322   { JUNIPER_IFLE_EXTENDED_VLAN_TCC, "Extended VLAN TCC" },
323   { JUNIPER_IFLE_FR_CCC, "FR CCC" },
324   { JUNIPER_IFLE_FR_NLPID, "FR NLPID" },
325   { JUNIPER_IFLE_FR_PORT_CCC, "FR CCC" },
326   { JUNIPER_IFLE_FR_PPP, "FR PPP" },
327   { JUNIPER_IFLE_FR_SNAP, "FR SNAP" },
328   { JUNIPER_IFLE_FR_TCC, "FR TCC" },
329   { JUNIPER_IFLE_GGSN, "GGSN" },
330   { JUNIPER_IFLE_GRE_NULL, "GRE NULL" },
331   { JUNIPER_IFLE_GRE_PPP, "PPP over GRE" },
332   { JUNIPER_IFLE_IPIP_NULL, "IPIP" },
333   { JUNIPER_IFLE_LAPD, "LAPD" },
334   { JUNIPER_IFLE_LSI_NULL, "LSI Null" },
335   { JUNIPER_IFLE_LT_VLAN, "LT VLAN" },
336   { JUNIPER_IFLE_MFR, "MFR" },
337   { JUNIPER_IFLE_MLFR, "MLFR" },
338   { JUNIPER_IFLE_MLPPP, "MLPPP" },
339   { JUNIPER_IFLE_MONITOR, "Monitor" },
340   { JUNIPER_IFLE_PIMD_DECAPS, "PIMd" },
341   { JUNIPER_IFLE_PIM_NULL, "PIM Null" },
342   { JUNIPER_IFLE_PPP, "PPP" },
343   { JUNIPER_IFLE_PPPOE, "PPPoE" },
344   { JUNIPER_IFLE_PPP_CCC, "PPP CCC" },
345   { JUNIPER_IFLE_PPP_SUBORDINATE, "" },
346   { JUNIPER_IFLE_PPP_TCC, "PPP TCC" },
347   { JUNIPER_IFLE_SERVICES, "General Services" },
348   { JUNIPER_IFLE_VLAN_CCC, "VLAN CCC" },
349   { JUNIPER_IFLE_VLAN_TCC, "VLAN TCC" },
350   { JUNIPER_IFLE_VT, "VT" },
351   {0,                    NULL}
352 };
353
354
355 static int proto_juniper = -1;
356
357 static int hf_juniper_magic = -1;
358 static int hf_juniper_direction = -1;
359 static int hf_juniper_l2hdr_presence = -1;
360 static int hf_juniper_ext_total_len = -1;
361 static int hf_juniper_cookie_len = -1;
362 static int hf_juniper_atm1_cookie = -1;
363 static int hf_juniper_atm2_cookie = -1;
364 static int hf_juniper_mlpic_cookie = -1;
365 static int hf_juniper_lspic_cookie = -1;
366 static int hf_juniper_aspic_cookie = -1;
367 static int hf_juniper_vlan = -1;
368 static int hf_juniper_proto = -1;
369 static int hf_juniper_payload_type = -1;
370 static int hf_juniper_encap_type = -1;
371 static int hf_juniper_ext_ifd = -1;
372 static int hf_juniper_ext_ifl = -1;
373 static int hf_juniper_ext_unit = -1;
374 static int hf_juniper_ext_ifmt = -1;
375 static int hf_juniper_ext_ifle = -1;
376 static int hf_juniper_ext_ttp_ifmt = -1;
377 static int hf_juniper_ext_ttp_ifle = -1;
378 static int hf_juniper_unknown_data = -1;
379
380 static expert_field ei_juniper_no_magic = EI_INIT;
381
382 static gint ett_juniper = -1;
383
384 static dissector_handle_t ipv4_handle;
385 static dissector_handle_t data_handle;
386
387 static dissector_table_t payload_table;
388
389 static int dissect_juniper_payload_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *juniper_subtree, guint proto, guint offset);
390 static void dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 atm_pictype);
391 static gboolean ppp_heuristic_guess(guint16 proto);
392 static guint ip_heuristic_guess(guint8 ip_header_byte);
393 static guint juniper_svc_cookie_len (guint64 cookie);
394 static guint juniper_svc_cookie_proto (guint64 cookie, guint16 pictype, guint8 flags);
395
396 static const value_string juniper_proto_vals[] = {
397   {JUNIPER_PROTO_IP, "IPv4"},
398   {JUNIPER_PROTO_MPLS_IP, "MPLS->IPv4"},
399   {JUNIPER_PROTO_IP_MPLS, "IPv4->MPLS"},
400   {JUNIPER_PROTO_IP6, "IPv6"},
401   {JUNIPER_PROTO_MPLS_IP6, "MPLS->IPv6"},
402   {JUNIPER_PROTO_IP6_MPLS, "IPv6->MPLS"},
403   {JUNIPER_PROTO_PPP, "PPP"},
404   {JUNIPER_PROTO_CLNP, "CLNP"},
405   {JUNIPER_PROTO_MPLS_CLNP, "MPLS->CLNP"},
406   {JUNIPER_PROTO_CLNP_MPLS, "CLNP->MPLS"},
407   {JUNIPER_PROTO_ISO, "OSI"},
408   {JUNIPER_PROTO_MPLS, "MPLS"},
409   {JUNIPER_PROTO_LLC, "LLC"},
410   {JUNIPER_PROTO_LLC_SNAP, "LLC/SNAP"},
411   {JUNIPER_PROTO_ETHER, "Ethernet"},
412   {JUNIPER_PROTO_OAM, "ATM OAM Cell"},
413   {JUNIPER_PROTO_Q933, "Q.933"},
414   {JUNIPER_PROTO_FRELAY, "Frame-Relay"},
415   {JUNIPER_PROTO_CHDLC, "C-HDLC"},
416   {0,                    NULL}
417 };
418
419 /* return a TLV value based on TLV length and TLV type (host/network order) */
420 static int
421 juniper_ext_get_tlv_value(tvbuff_t *tvb, guint tlv_type, guint tlv_len, guint offset) {
422
423   int tlv_value;
424
425   if (tlv_type < 128) {
426     /* TLVs < 128 are little-endian / host order encoded */
427     switch (tlv_len) {
428     case 1:
429       tlv_value = tvb_get_guint8(tvb, offset);
430       break;
431     case 2:
432       tlv_value = tvb_get_letohs(tvb, offset);
433       break;
434     case 3:
435       tlv_value = tvb_get_letoh24(tvb, offset);
436       break;
437     case 4:
438       tlv_value = tvb_get_letohl(tvb, offset);
439       break;
440     default:
441       tlv_value = -1;
442       break;
443     }
444   } else {
445     /* TLVs >= 128 are big-endian / network order encoded */
446     switch (tlv_len) {
447     case 1:
448       tlv_value = tvb_get_guint8(tvb, offset);
449       break;
450     case 2:
451       tlv_value = tvb_get_ntohs(tvb, offset);
452       break;
453     case 3:
454       tlv_value = tvb_get_ntoh24(tvb, offset);
455       break;
456     case 4:
457       tlv_value = tvb_get_ntohl(tvb, offset);
458       break;
459     default:
460       tlv_value = -1;
461       break;
462     }
463   }
464   return tlv_value;
465 }
466
467 /* generic juniper header dissector  */
468 static int
469 dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *juniper_subtree, guint8 *flags)
470 {
471   proto_item *tisub, *magic_item;
472   guint8     l2hdr_presence,proto,ext_type,ext_len;
473   guint16    ext_total_len,ext_offset=6,hdr_len;
474   guint32    magic_number,ext_val;
475
476   proto_tree *juniper_ext_subtree = NULL, *juniper_ext_subtree_item = NULL;
477
478   magic_number = tvb_get_ntoh24(tvb, 0);
479   *flags = tvb_get_guint8(tvb, 3);
480   l2hdr_presence = *flags & JUNIPER_FLAG_NO_L2;
481
482   magic_item = proto_tree_add_item(juniper_subtree, hf_juniper_magic, tvb, 0, 3, ENC_BIG_ENDIAN);
483
484   /* be liberal with magic-number detection -
485    * some older JUNOS releases (e.g. 6.4),
486    * which are still in the field do not generate magic-numbers */
487   if (magic_number != JUNIPER_PCAP_MAGIC) {
488     expert_add_info(pinfo, magic_item, &ei_juniper_no_magic);
489     return 0;
490   }
491
492   proto_tree_add_item(juniper_subtree, hf_juniper_direction, tvb, 3, 1, ENC_NA);
493
494   proto_tree_add_uint(juniper_subtree, hf_juniper_l2hdr_presence, tvb, 3, 1, l2hdr_presence);
495
496   /* calculate hdr_len before cookie, payload */
497
498   /* meta-info extensions (JUNOS >= 7.5) ? */
499   if ((*flags & JUNIPER_FLAG_EXT) == JUNIPER_FLAG_EXT) {
500     ext_total_len = tvb_get_ntohs(tvb,4);
501     hdr_len = 6 + ext_total_len; /* MGC,flags,ext_total_len */
502
503     tisub = proto_tree_add_uint (juniper_subtree, hf_juniper_ext_total_len, tvb, 4, 2, ext_total_len);
504     juniper_ext_subtree = proto_item_add_subtree(tisub, ett_juniper);
505
506     while (ext_total_len > EXT_TLV_HEADER_SIZE) {
507       ext_type = tvb_get_guint8(tvb, ext_offset);
508       ext_len = tvb_get_guint8(tvb, ext_offset+1);
509
510       if (ext_len == 0 || ext_len > (ext_total_len - EXT_TLV_HEADER_SIZE)) /* a few sanity checks */
511         break;
512
513       juniper_ext_subtree_item = proto_tree_add_subtree_format(juniper_ext_subtree, tvb, ext_offset, EXT_TLV_HEADER_SIZE + ext_len,
514                                    ett_juniper, &tisub, "%s Extension TLV #%u, length: %u",
515                                    val_to_str_const(ext_type, ext_tlv_vals, "Unknown"),
516                                    ext_type,
517                                    ext_len);
518
519       ext_val = juniper_ext_get_tlv_value(tvb, ext_type, ext_len, ext_offset+EXT_TLV_HEADER_SIZE);
520
521       switch (ext_type) {
522       case EXT_TLV_IFD_MEDIATYPE:
523         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifmt,
524                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
525         break;
526       case EXT_TLV_TTP_IFD_MEDIATYPE:
527         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifmt,
528                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
529         break;
530       case EXT_TLV_IFL_ENCAPS:
531         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifle,
532                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
533         break;
534       case EXT_TLV_TTP_IFL_ENCAPS:
535         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifle,
536                                     tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
537         break;
538
539       case EXT_TLV_IFL_IDX:
540         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifl,
541                             tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
542         break;
543
544       case EXT_TLV_IFL_UNIT:
545         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_unit,
546                             tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
547         break;
548       case EXT_TLV_IFD_IDX:
549         proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifd,
550                             tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val);
551         break;
552       case EXT_TLV_IFD_NAME: /* FIXME print ifname string - lets fall-through for now */
553       default:
554         proto_item_append_text(tisub, "Unknown");
555         break;
556       }
557
558       ext_offset += EXT_TLV_HEADER_SIZE + ext_len;
559       ext_total_len -= EXT_TLV_HEADER_SIZE + ext_len;
560     }
561
562   } else
563     hdr_len = 4; /* MGC,flags */
564
565   if ((*flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
566     proto = tvb_get_letohl(tvb,hdr_len); /* proto is stored in host-order */
567     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, hdr_len + 4);
568     return -1;
569   }
570
571   return hdr_len; /* bytes parsed */
572
573 }
574
575 /* print the payload protocol  */
576 static int
577 dissect_juniper_payload_proto(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
578                               proto_tree *juniper_subtree, guint proto, guint offset)
579 {
580   proto_item *ti;
581   tvbuff_t   *next_tvb;
582
583   ti = proto_tree_add_uint(juniper_subtree, hf_juniper_payload_type, tvb, offset, 0, proto);
584   PROTO_ITEM_SET_GENERATED(ti);
585
586   if (proto == 0xa248)
587   {
588     proto_tree_add_item(juniper_subtree, hf_juniper_unknown_data, tvb, offset, 4, ENC_NA);
589     next_tvb = tvb_new_subset_remaining(tvb, offset+4);
590     call_dissector(ipv4_handle, next_tvb, pinfo, tree);
591   }
592   else
593   {
594     next_tvb = tvb_new_subset_remaining(tvb, offset);
595
596     if (!dissector_try_uint(payload_table, proto, next_tvb, pinfo, tree))
597     {
598       /* XXX - left in for posterity, dissection was never done */
599       /* case JUNIPER_PROTO_OAM: FIXME call OAM disector without leading HEC byte */
600
601       call_dissector(data_handle, next_tvb, pinfo, tree);
602     }
603   }
604
605   return 0;
606 }
607
608 /* MLFR dissector */
609 static void
610 dissect_juniper_mlfr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
611 {
612   proto_item *ti;
613   proto_tree* juniper_subtree;
614   guint      offset;
615   int        bytes_processed;
616   guint8     flags;
617   guint64    aspic_cookie;
618   guint32    lspic_cookie;
619   guint16    mlpic_cookie;
620   guint      proto,cookie_len;
621
622   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper MLFR");
623   col_clear(pinfo->cinfo, COL_INFO);
624
625   offset = 0;
626
627   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Multi-Link Frame-Relay (FRF.15)");
628
629   /* parse header, match mgc, extract flags and build first tree */
630   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
631
632   if(bytes_processed == -1)
633     return;
634   else
635     offset+=bytes_processed;
636
637   aspic_cookie = tvb_get_ntoh64(tvb,offset);
638   proto = juniper_svc_cookie_proto(aspic_cookie, JUNIPER_PIC_MLFR, flags);
639   cookie_len = juniper_svc_cookie_len(aspic_cookie);
640
641   if (cookie_len == AS_PIC_COOKIE_LEN)
642     proto_tree_add_uint64(juniper_subtree, hf_juniper_aspic_cookie,
643                           tvb, offset, AS_PIC_COOKIE_LEN, aspic_cookie);
644   if (cookie_len == LS_PIC_COOKIE_LEN) {
645     lspic_cookie = tvb_get_ntohl(tvb,offset);
646     proto_tree_add_uint(juniper_subtree, hf_juniper_lspic_cookie,
647                         tvb, offset, LS_PIC_COOKIE_LEN, lspic_cookie);
648   }
649
650   offset += cookie_len;
651
652   mlpic_cookie = tvb_get_ntohs(tvb, offset);
653
654   /* AS-PIC IS-IS */
655   if (cookie_len == AS_PIC_COOKIE_LEN &&
656       proto == JUNIPER_PROTO_UNKNOWN &&
657       tvb_get_guint8(tvb,offset) == JUNIPER_HDR_LLC_UI) {
658     offset += 1;
659     proto = JUNIPER_PROTO_ISO;
660   }
661
662   /* LS-PIC IS-IS */
663   if (cookie_len == LS_PIC_COOKIE_LEN) {
664     if ( tvb_get_ntohs(tvb,offset) == JUNIPER_HDR_LLC_UI ||
665          tvb_get_ntohs(tvb,offset) == (JUNIPER_HDR_LLC_UI<<8)) {
666       offset += 2;
667     }
668   }
669
670   /* LS-PIC ? */
671   if (cookie_len == LS_PIC_COOKIE_LEN && tvb_get_guint8(tvb,offset) == JUNIPER_HDR_LLC_UI) {
672     offset += 1;
673   }
674
675   /* child link of an LS-PIC bundle ? */
676   if (cookie_len == 0 && tvb_get_ntohs(tvb,offset+ML_PIC_COOKIE_LEN) ==
677       (JUNIPER_HDR_LLC_UI<<8 | NLPID_Q_933)) {
678     cookie_len = ML_PIC_COOKIE_LEN;
679     proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
680                         tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
681     offset += 3;
682     proto = JUNIPER_PROTO_Q933;
683   }
684
685   /* child link of an ML-, LS-, AS-PIC bundle / ML-PIC bundle ? */
686   if (cookie_len == 0) {
687     if (tvb_get_ntohs(tvb,offset+ML_PIC_COOKIE_LEN) == JUNIPER_HDR_LLC_UI ||
688         tvb_get_ntohs(tvb,offset+ML_PIC_COOKIE_LEN) == (JUNIPER_HDR_LLC_UI<<8)) {
689       cookie_len = ML_PIC_COOKIE_LEN;
690       proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
691                           tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
692       offset += 4;
693       proto = JUNIPER_PROTO_ISO;
694     }
695   }
696
697   /* ML-PIC bundle ? */
698   if (cookie_len == 0 && tvb_get_guint8(tvb,offset+ML_PIC_COOKIE_LEN) == JUNIPER_HDR_LLC_UI) {
699     cookie_len = ML_PIC_COOKIE_LEN;
700     proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
701                         tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
702     offset += 3;
703     proto = JUNIPER_PROTO_ISO;
704   }
705
706   ti = proto_tree_add_uint(juniper_subtree, hf_juniper_cookie_len, tvb, offset, 0, cookie_len);
707   PROTO_ITEM_SET_GENERATED(ti);
708
709   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, offset);
710
711 }
712
713
714
715 /* MLPPP dissector */
716 static void
717 dissect_juniper_mlppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
718 {
719   proto_item *ti;
720   proto_tree* juniper_subtree;
721   guint      offset;
722   int        bytes_processed;
723   guint8     flags;
724   guint64    aspic_cookie;
725   guint32    lspic_cookie;
726   guint16    mlpic_cookie;
727   guint      proto,cookie_len;
728
729   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper MLPPP");
730   col_clear(pinfo->cinfo, COL_INFO);
731
732   offset = 0;
733
734   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper MLPPP");
735
736   /* parse header, match mgc, extract flags and build first tree */
737   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
738
739   if(bytes_processed == -1)
740     return;
741   else
742     offset+=bytes_processed;
743
744   aspic_cookie = tvb_get_ntoh64(tvb,offset);
745   proto = juniper_svc_cookie_proto(aspic_cookie, JUNIPER_PIC_MLPPP, flags);
746   cookie_len = juniper_svc_cookie_len(aspic_cookie);
747
748   if (cookie_len == AS_PIC_COOKIE_LEN)
749     proto_tree_add_uint64(juniper_subtree, hf_juniper_aspic_cookie,
750                           tvb, offset, AS_PIC_COOKIE_LEN, aspic_cookie);
751   if (cookie_len == LS_PIC_COOKIE_LEN) {
752     lspic_cookie = tvb_get_ntohl(tvb,offset);
753     proto_tree_add_uint(juniper_subtree, hf_juniper_lspic_cookie,
754                         tvb, offset, LS_PIC_COOKIE_LEN, lspic_cookie);
755   }
756
757   /* no cookie pattern identified - lets guess from now on */
758
759   /* child link of an LS-PIC bundle ? */
760   if (cookie_len == 0 && tvb_get_ntohs(tvb, offset) == JUNIPER_HDR_PPP) {
761     proto = JUNIPER_PROTO_PPP;
762     offset += 2;
763   }
764
765   /* ML-PIC ? */
766   if (cookie_len == 0 && ppp_heuristic_guess(tvb_get_ntohs(tvb, offset+2))) {
767     proto = JUNIPER_PROTO_PPP;
768     cookie_len = 2;
769     mlpic_cookie = tvb_get_ntohs(tvb, offset);
770     proto_tree_add_uint(juniper_subtree, hf_juniper_mlpic_cookie,
771                         tvb, offset, ML_PIC_COOKIE_LEN, mlpic_cookie);
772   }
773
774   /* child link of an ML-PIC bundle ? */
775   if (cookie_len == 0 && ppp_heuristic_guess(tvb_get_ntohs(tvb, offset))) {
776     proto = JUNIPER_PROTO_PPP;
777   }
778
779   ti = proto_tree_add_uint(juniper_subtree, hf_juniper_cookie_len, tvb, offset, 0, cookie_len);
780   PROTO_ITEM_SET_GENERATED(ti);
781   offset += cookie_len;
782
783   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, offset);
784
785 }
786
787
788 /* PPPoE dissector */
789 static void
790 dissect_juniper_pppoe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
791 {
792   proto_tree* juniper_subtree;
793   guint      offset;
794   int        bytes_processed;
795   guint8     flags;
796
797   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper PPPoE");
798   col_clear(pinfo->cinfo, COL_INFO);
799
800   offset = 0;
801
802   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper PPPoE PIC");
803
804   /* parse header, match mgc, extract flags and build first tree */
805   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
806
807   if(bytes_processed == -1)
808     return;
809   else
810     offset+=bytes_processed;
811
812   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ETHER, offset);
813
814 }
815
816 /* Ethernet dissector */
817 static void
818 dissect_juniper_ether(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
819 {
820   proto_tree* juniper_subtree;
821   guint      offset;
822   int        bytes_processed;
823   guint8     flags;
824
825   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Ethernet");
826   col_clear(pinfo->cinfo, COL_INFO);
827
828   offset = 0;
829
830   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Ethernet");
831
832   /* parse header, match mgc, extract flags and build first tree */
833   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
834
835   if(bytes_processed == -1)
836     return;
837   else
838     offset+=bytes_processed;
839
840   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ETHER, offset);
841
842 }
843
844 /* PPP dissector */
845 static void
846 dissect_juniper_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
847 {
848   proto_tree* juniper_subtree;
849   guint      offset;
850   int        bytes_processed;
851   guint8     flags;
852
853   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper PPP");
854   col_clear(pinfo->cinfo, COL_INFO);
855
856   offset = 0;
857
858   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper PPP");
859
860   /* parse header, match mgc, extract flags and build first tree */
861   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
862
863   if(bytes_processed == -1)
864     return;
865   else
866     offset+=bytes_processed;
867
868   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_PPP, offset+2);
869
870 }
871
872 /* Frame-Relay dissector */
873 static void
874 dissect_juniper_frelay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
875 {
876   proto_tree* juniper_subtree;
877   guint      offset;
878   int        bytes_processed;
879   guint8     flags;
880
881   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Frame-Relay");
882   col_clear(pinfo->cinfo, COL_INFO);
883
884   offset = 0;
885
886   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Frame-Relay");
887
888   /* parse header, match mgc, extract flags and build first tree */
889   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
890
891   if(bytes_processed == -1)
892     return;
893   else
894     offset+=bytes_processed;
895
896   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_FRELAY, offset);
897
898 }
899
900 /* C-HDLC dissector */
901 static void
902 dissect_juniper_chdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
903 {
904   proto_tree* juniper_subtree;
905   guint      offset = 0;
906   int        bytes_processed;
907   guint8     flags;
908
909   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper C-HDLC");
910   col_clear(pinfo->cinfo, COL_INFO);
911
912   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper C-HDLC");
913
914   /* parse header, match mgc, extract flags and build first tree */
915   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
916
917   if(bytes_processed == -1)
918     return;
919   else
920     offset+=bytes_processed;
921
922   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_CHDLC, offset);
923
924 }
925
926
927
928 /* wrapper for passing the PIC type to the generic ATM dissector */
929 static int
930 dissect_juniper_atm1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
931 {
932   dissect_juniper_atm(tvb,pinfo,tree, JUNIPER_PIC_ATM1);
933   return tvb_captured_length(tvb);
934 }
935
936 /* wrapper for passing the PIC type to the generic ATM dissector */
937 static int
938 dissect_juniper_atm2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
939 {
940   dissect_juniper_atm(tvb,pinfo,tree, JUNIPER_PIC_ATM2);
941   return tvb_captured_length(tvb);
942 }
943
944 /* generic ATM dissector */
945 static void
946 dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 atm_pictype)
947 {
948   proto_item *ti;
949   proto_tree* juniper_subtree;
950   guint8     next_proto = JUNIPER_PROTO_UNKNOWN,atm1_header_len,atm2_header_len,flags;
951   guint32    cookie1, proto;
952   guint64    cookie2;
953   guint      offset = 0;
954   int        bytes_processed;
955   tvbuff_t   *next_tvb;
956
957   col_clear(pinfo->cinfo, COL_INFO);
958
959   switch (atm_pictype) {
960   case JUNIPER_PIC_ATM1:
961     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper ATM1");
962     juniper_subtree = proto_tree_add_subtree(tree, tvb, 0, 0 , ett_juniper, NULL, "Juniper ATM1 PIC");
963     break;
964   case JUNIPER_PIC_ATM2:
965     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper ATM2");
966     juniper_subtree = proto_tree_add_subtree(tree, tvb, 0, 0 , ett_juniper, NULL, "Juniper ATM2 PIC");
967     break;
968   default: /* should not happen */
969     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper ATM unknown");
970     proto_tree_add_subtree(tree, tvb, 0, 0 , ett_juniper, NULL, "Juniper unknown ATM PIC");
971     return;
972   }
973
974   /* parse header, match mgc, extract flags and build first tree */
975   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
976   if(bytes_processed == -1)
977     return;
978   else
979     offset+=bytes_processed;
980
981   if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
982     atm1_header_len = 4;
983     atm2_header_len = 4;
984   }
985   else {
986     atm1_header_len = 4;
987     atm2_header_len = 8;
988   }
989
990   cookie1 = tvb_get_ntohl(tvb, offset);
991   cookie2 = tvb_get_ntoh64(tvb, offset);
992
993   if (atm_pictype == JUNIPER_PIC_ATM1) {
994     proto_tree_add_uint(juniper_subtree, hf_juniper_atm1_cookie, tvb, offset, 4, cookie1);
995     offset += atm1_header_len;
996     if ((cookie1 >> 24) == 0x80) /* OAM cell ? */
997       next_proto = JUNIPER_PROTO_OAM;
998   }
999   else { /* JUNIPER_PIC_ATM2 */
1000     proto_tree_add_uint64(juniper_subtree, hf_juniper_atm2_cookie, tvb, offset, 8, cookie2);
1001     offset += atm2_header_len;
1002     if (cookie2 & 0x70) /* OAM cell ? */
1003       next_proto = JUNIPER_PROTO_OAM;
1004   }
1005
1006   next_tvb = tvb_new_subset_remaining(tvb, offset);
1007
1008   if (next_proto == JUNIPER_PROTO_OAM) {
1009     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_OAM, offset);
1010     return;
1011   }
1012
1013   proto = tvb_get_ntoh24(tvb, offset); /* first try: 24-Bit guess */
1014
1015   if (proto == JUNIPER_HDR_NLPID) {
1016     /*
1017      * This begins with something that appears to be an LLC header for
1018      * OSI; is this LLC-multiplexed traffic?
1019      */
1020     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_LLC, offset);
1021     return;
1022   }
1023
1024   if (proto == JUNIPER_HDR_SNAP) {
1025     /*
1026      * This begins with something that appears to be an LLC header for
1027      * SNAP; is this LLC-multiplexed traffic?
1028      */
1029     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_LLC_SNAP, offset);
1030     return;
1031   }
1032
1033   if ((flags & JUNIPER_FLAG_PKT_IN) != JUNIPER_FLAG_PKT_IN && /* ether-over-1483 encaps ? */
1034       (cookie1 & JUNIPER_ATM2_GAP_COUNT_MASK) &&
1035       atm_pictype != JUNIPER_PIC_ATM1) {
1036     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ETHER, offset);
1037     return;
1038   }
1039
1040   proto = tvb_get_ntohs(tvb, offset); /* second try: 16-Bit guess */
1041
1042   if ( ppp_heuristic_guess( (guint16) proto) &&
1043        atm_pictype != JUNIPER_PIC_ATM1) {
1044     /*
1045      * This begins with something that appears to be a PPP protocol
1046      * type; is this VC-multiplexed PPPoA?
1047      * That's not supported on ATM1 PICs.
1048      */
1049     proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_encap_type, tvb, offset, 0, 0, "VC-MUX");
1050     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_PPP, offset);
1051     return;
1052   }
1053
1054   proto = tvb_get_guint8(tvb, offset); /* third try: 8-Bit guess */
1055
1056   if ( proto == JUNIPER_HDR_LLC_UI ) {
1057     /*
1058      * Cisco style NLPID encaps?
1059      * Is the 0x03 an LLC UI control field?
1060      */
1061     proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_encap_type, tvb, offset, 1, 1, "Cisco NLPID");
1062     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_ISO, offset+1);
1063     return;
1064   }
1065
1066   next_proto = ip_heuristic_guess( (guint8) proto);
1067   if (next_proto != JUNIPER_PROTO_UNKNOWN) { /* last resort: VC-MUX encaps ? */
1068     /*
1069      * This begins with something that might be the first byte of
1070      * an IPv4 or IPv6 packet; is this VC-multiplexed IP?
1071      */
1072     proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_encap_type, tvb, offset, 0, 2, "VC-MUX");
1073     dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, next_proto, offset);
1074     return;
1075   }
1076
1077   /* could not figure what it is */
1078   ti = proto_tree_add_uint_format_value(juniper_subtree, hf_juniper_payload_type, tvb, offset, 0, 0xFFFF, "Unknown");
1079   proto_item_set_len(ti, tvb_reported_length_remaining(tvb, offset));
1080   call_dissector(data_handle, next_tvb, pinfo, tree);
1081 }
1082
1083
1084 static void dissect_juniper_ggsn(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
1085
1086   proto_tree* juniper_subtree;
1087   guint      offset = 0;
1088   int        bytes_processed;
1089   guint8     flags;
1090   guint16    proto;
1091
1092   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper GGSN");
1093   col_clear(pinfo->cinfo, COL_INFO);
1094
1095   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper GGSN");
1096
1097   /* parse header, match mgc, extract flags and build first tree */
1098   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1099
1100   if(bytes_processed == -1)
1101     return;
1102   else
1103     offset+=bytes_processed;
1104
1105   proto = tvb_get_letohs(tvb, offset); /* fetch protocol */
1106
1107   proto_tree_add_uint(juniper_subtree, hf_juniper_proto, tvb, offset, 2, proto);
1108   proto_tree_add_item(juniper_subtree, hf_juniper_vlan, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1109   offset += 4;
1110
1111   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, proto, offset);
1112
1113 }
1114
1115 static void dissect_juniper_vp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
1116
1117   proto_tree* juniper_subtree;
1118   guint      offset = 0;
1119   int        bytes_processed;
1120   guint8     flags;
1121
1122   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Voice PIC");
1123   col_clear(pinfo->cinfo, COL_INFO);
1124
1125   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Voice PIC");
1126
1127   /* parse header, match mgc, extract flags and build first tree */
1128   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1129
1130   if(bytes_processed == -1)
1131     return;
1132   else
1133     offset+=bytes_processed;
1134
1135   /*
1136    * Right know IPv4 is the only protocol we may encounter.
1137    * For the future there should be sufficient space in the 18-byte
1138    * empty header before payload starts.
1139    */
1140   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_IP, offset+18);
1141 }
1142
1143 /* Wrapper for Juniper service PIC coookie dissector */
1144 static void
1145 dissect_juniper_svcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1146 {
1147   proto_tree* juniper_subtree;
1148   guint      offset = 0;
1149   int bytes_processed = 0;
1150   guint8     flags;
1151
1152   col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper Services");
1153   col_clear(pinfo->cinfo, COL_INFO);
1154
1155   juniper_subtree = proto_tree_add_subtree(tree, tvb, offset, 4, ett_juniper, NULL, "Juniper Services cookie");
1156
1157   /* parse header, match mgc, extract flags and build first tree */
1158   bytes_processed = dissect_juniper_header(tvb, pinfo, tree, juniper_subtree, &flags);
1159
1160   if (bytes_processed == -1)
1161       return;
1162   else
1163       offset+=bytes_processed;
1164
1165   if (flags & JUNIPER_FLAG_PKT_IN) {
1166       proto_tree_add_uint(juniper_subtree, hf_juniper_proto, tvb, offset, 2, JUNIPER_PROTO_IP);
1167       offset += 16;
1168   } else {
1169       offset += 12;
1170   }
1171
1172   dissect_juniper_payload_proto(tvb, pinfo, tree, juniper_subtree, JUNIPER_PROTO_IP, offset);
1173 }
1174
1175 /* list of Juniper supported PPP proto IDs */
1176 static gboolean
1177 ppp_heuristic_guess(guint16 proto) {
1178
1179   switch(proto) {
1180   case PPP_IP :
1181   case PPP_OSI :
1182   case PPP_MPLS_UNI :
1183   case PPP_MPLS_MULTI :
1184   case PPP_IPCP :
1185   case PPP_OSINLCP :
1186   case PPP_MPLSCP :
1187   case PPP_LCP :
1188   case PPP_PAP :
1189   case PPP_CHAP :
1190   case PPP_MP :
1191   case PPP_IPV6 :
1192   case PPP_IPV6CP :
1193     return TRUE;
1194
1195   default:
1196     return FALSE; /* did not find a ppp header */
1197   }
1198 }
1199
1200 /*
1201  * return the IP version number based on the first byte of the IP header
1202  * returns 0 if it does not match a valid first IPv4/IPv6 header byte
1203  */
1204 static guint
1205 ip_heuristic_guess(guint8 ip_header_byte) {
1206
1207   switch(ip_header_byte) {
1208   case 0x45:
1209   case 0x46:
1210   case 0x47:
1211   case 0x48:
1212   case 0x49:
1213   case 0x4a:
1214   case 0x4b:
1215   case 0x4c:
1216   case 0x4d:
1217   case 0x4e:
1218   case 0x4f:
1219     return JUNIPER_PROTO_IP;
1220   case 0x60:
1221   case 0x61:
1222   case 0x62:
1223   case 0x63:
1224   case 0x64:
1225   case 0x65:
1226   case 0x66:
1227   case 0x67:
1228   case 0x68:
1229   case 0x69:
1230   case 0x6a:
1231   case 0x6b:
1232   case 0x6c:
1233   case 0x6d:
1234   case 0x6e:
1235   case 0x6f:
1236     return JUNIPER_PROTO_IP6;
1237   default:
1238     return JUNIPER_PROTO_UNKNOWN; /* did not find a ip header */
1239   }
1240 }
1241
1242 /* return cookie length dep. on cookie SVC id */
1243 static
1244 guint juniper_svc_cookie_len (guint64 cookie) {
1245
1246   guint8 svc_cookie_id;
1247   svc_cookie_id = (guint8)(cookie >> 56) & 0xff;
1248
1249   switch(svc_cookie_id) {
1250   case 0x54:
1251     return LS_PIC_COOKIE_LEN;
1252   case GSP_SVC_REQ_APOLLO:
1253   case GSP_SVC_REQ_LSQ:
1254     return AS_PIC_COOKIE_LEN;
1255   default:
1256     return 0;
1257   }
1258 }
1259
1260 /* return the next-level protocol based on cookie input */
1261 static guint
1262 juniper_svc_cookie_proto (guint64 cookie, guint16 pictype, guint8 flags) {
1263
1264   guint8 svc_cookie_id;
1265   guint16 lsq_proto;
1266   guint8 lsq_dir;
1267
1268   svc_cookie_id = (guint8)(cookie >> 56) & 0xff;
1269   lsq_proto = (guint16)((cookie >> 16) & LSQ_L3_PROTO_MASK);
1270   lsq_dir = (guint8)(cookie >> 24) & 0x3;
1271
1272
1273   switch (svc_cookie_id) {
1274   case 0x54:
1275     switch (pictype) {
1276     case JUNIPER_PIC_MLPPP:
1277       return JUNIPER_PROTO_PPP;
1278     case JUNIPER_PIC_MLFR:
1279       return JUNIPER_PROTO_ISO;
1280     default:
1281       return JUNIPER_PROTO_UNKNOWN;
1282     }
1283   case GSP_SVC_REQ_APOLLO:
1284   case GSP_SVC_REQ_LSQ:
1285     switch(lsq_proto) {
1286     case LSQ_L3_PROTO_IPV4:
1287       switch(pictype) {
1288       case JUNIPER_PIC_MLPPP:
1289         /* incoming traffic would have the direction bits set
1290          * -> this must be IS-IS over PPP
1291          */
1292         if ((flags & JUNIPER_FLAG_PKT_IN) == JUNIPER_FLAG_PKT_IN &&
1293             lsq_dir != (LSQ_COOKIE_RE|LSQ_COOKIE_DIR))
1294           return JUNIPER_PROTO_PPP;
1295         else
1296           return JUNIPER_PROTO_IP;
1297       case JUNIPER_PIC_MLFR:
1298         if (lsq_dir == (LSQ_COOKIE_RE|LSQ_COOKIE_DIR))
1299           return JUNIPER_PROTO_UNKNOWN;
1300         else
1301           return JUNIPER_PROTO_IP;
1302       default:
1303         return JUNIPER_PROTO_UNKNOWN;
1304       }
1305     case LSQ_L3_PROTO_IPV6:
1306       return JUNIPER_PROTO_IP6;
1307     case LSQ_L3_PROTO_MPLS:
1308       return JUNIPER_PROTO_MPLS;
1309     case LSQ_L3_PROTO_ISO:
1310       return JUNIPER_PROTO_ISO;
1311     default:
1312       return JUNIPER_PROTO_UNKNOWN;
1313     }
1314   default:
1315     return JUNIPER_PROTO_UNKNOWN;
1316   }
1317 }
1318
1319
1320 void
1321 proto_register_juniper(void)
1322 {
1323   static hf_register_info hf[] = {
1324     { &hf_juniper_magic,
1325       { "Magic Number", "juniper.magic-number", FT_UINT24, BASE_HEX,
1326         NULL, 0x0, NULL, HFILL }},
1327     { &hf_juniper_direction,
1328       { "Direction", "juniper.direction", FT_UINT8, BASE_HEX,
1329         VALS(juniper_direction_vals), 0x0, NULL, HFILL }},
1330     { &hf_juniper_l2hdr_presence,
1331       { "L2 header presence", "juniper.l2hdr", FT_UINT8, BASE_HEX,
1332         VALS(juniper_l2hdr_presence_vals), 0x0, NULL, HFILL }},
1333     { &hf_juniper_ext_total_len,
1334       { "Extension(s) Total length", "juniper.ext_total_len", FT_UINT16, BASE_DEC,
1335         NULL, 0x0, NULL, HFILL }},
1336     { &hf_juniper_cookie_len,
1337       { "Cookie length", "juniper.cookie_len", FT_UINT32, BASE_DEC,
1338         NULL, 0x0, NULL, HFILL }},
1339     { &hf_juniper_atm2_cookie,
1340       { "Cookie", "juniper.atm2.cookie", FT_UINT64, BASE_HEX,
1341         NULL, 0x0, NULL, HFILL }},
1342     { &hf_juniper_atm1_cookie,
1343       { "Cookie", "juniper.atm1.cookie", FT_UINT32, BASE_HEX,
1344         NULL, 0x0, NULL, HFILL }},
1345     { &hf_juniper_mlpic_cookie,
1346       { "Cookie", "juniper.mlpic.cookie", FT_UINT16, BASE_HEX,
1347         NULL, 0x0, NULL, HFILL }},
1348     { &hf_juniper_lspic_cookie,
1349       { "Cookie", "juniper.lspic.cookie", FT_UINT32, BASE_HEX,
1350         NULL, 0x0, NULL, HFILL }},
1351     { &hf_juniper_aspic_cookie,
1352       { "Cookie", "juniper.aspic.cookie", FT_UINT64, BASE_HEX,
1353         NULL, 0x0, NULL, HFILL }},
1354     { &hf_juniper_vlan,
1355       { "VLan ID", "juniper.vlan", FT_UINT16, BASE_DEC,
1356         NULL, 0x0, NULL, HFILL }},
1357     { &hf_juniper_proto,
1358       { "Protocol", "juniper.proto", FT_UINT16, BASE_DEC,
1359         VALS(juniper_proto_vals), 0x0, NULL, HFILL }},
1360     { &hf_juniper_payload_type,
1361       { "Payload Type", "juniper.payload_type", FT_UINT16, BASE_DEC,
1362         VALS(juniper_proto_vals), 0x0, NULL, HFILL }},
1363     { &hf_juniper_encap_type,
1364       { "Encapsulation Type", "juniper.encap_type", FT_UINT8, BASE_DEC,
1365         NULL, 0x0, NULL, HFILL }},
1366     { &hf_juniper_ext_ifd,
1367       /* Juniper PCAP extensions */
1368       { "Device Interface Index", "juniper.ext.ifd", FT_UINT32, BASE_DEC,
1369         NULL, 0x0, NULL, HFILL }},
1370     { &hf_juniper_ext_ifl,
1371       { "Logical Interface Index", "juniper.ext.ifl", FT_UINT32, BASE_DEC,
1372         NULL, 0x0, NULL, HFILL }},
1373     { &hf_juniper_ext_unit,
1374       { "Logical Unit Number", "juniper.ext.unit", FT_UINT32, BASE_DEC,
1375         NULL, 0x0, NULL, HFILL }},
1376     { &hf_juniper_ext_ifmt,
1377       { "Device Media Type", "juniper.ext.ifmt", FT_UINT16, BASE_DEC,
1378         VALS(juniper_ifmt_vals), 0x0, NULL, HFILL }},
1379     { &hf_juniper_ext_ifle,
1380       { "Logical Interface Encapsulation", "juniper.ext.ifle", FT_UINT16, BASE_DEC,
1381         VALS(juniper_ifle_vals), 0x0, NULL, HFILL }},
1382     { &hf_juniper_ext_ttp_ifmt,
1383       { "TTP derived Device Media Type", "juniper.ext.ttp_ifmt", FT_UINT16, BASE_DEC,
1384         VALS(juniper_ifmt_vals), 0x0, NULL, HFILL }},
1385     { &hf_juniper_ext_ttp_ifle,
1386       { "TTP derived Logical Interface Encapsulation", "juniper.ext.ttp_ifle", FT_UINT16, BASE_DEC,
1387         VALS(juniper_ifle_vals), 0x0, NULL, HFILL }},
1388     { &hf_juniper_unknown_data,
1389       { "Unknown data", "juniper.unknown_data", FT_BYTES, BASE_NONE,
1390         NULL, 0x0, NULL, HFILL }},
1391   };
1392
1393   static gint *ett[] = {
1394     &ett_juniper,
1395   };
1396
1397   static ei_register_info ei[] = {
1398     { &ei_juniper_no_magic, { "juniper.magic-number.none", PI_PROTOCOL, PI_WARN, "No Magic-Number found!", EXPFILL }},
1399   };
1400
1401   expert_module_t* expert_juniper;
1402
1403   proto_juniper = proto_register_protocol("Juniper", "Juniper", "juniper");
1404   proto_register_field_array(proto_juniper, hf, array_length(hf));
1405   proto_register_subtree_array(ett, array_length(ett));
1406   expert_juniper = expert_register_protocol(proto_juniper);
1407   expert_register_field_array(expert_juniper, ei, array_length(ei));
1408
1409   payload_table = register_dissector_table("juniper.proto", "Juniper payload dissectors", FT_UINT32, BASE_HEX, DISSECTOR_TABLE_NOT_ALLOW_DUPLICATE);
1410
1411 }
1412
1413 void
1414 proto_reg_handoff_juniper(void)
1415 {
1416   dissector_handle_t juniper_atm1_handle;
1417   dissector_handle_t juniper_atm2_handle;
1418   dissector_handle_t juniper_pppoe_handle;
1419   dissector_handle_t juniper_mlppp_handle;
1420   dissector_handle_t juniper_mlfr_handle;
1421   dissector_handle_t juniper_ether_handle;
1422   dissector_handle_t juniper_ppp_handle;
1423   dissector_handle_t juniper_frelay_handle;
1424   dissector_handle_t juniper_chdlc_handle;
1425   dissector_handle_t juniper_ggsn_handle;
1426   dissector_handle_t juniper_vp_handle;
1427   dissector_handle_t juniper_svcs_handle;
1428
1429   ipv4_handle   = find_dissector("ip");
1430   data_handle   = find_dissector("data");
1431
1432   juniper_atm2_handle   = new_create_dissector_handle(dissect_juniper_atm2,   proto_juniper);
1433   juniper_atm1_handle   = new_create_dissector_handle(dissect_juniper_atm1,   proto_juniper);
1434   juniper_pppoe_handle  = create_dissector_handle(dissect_juniper_pppoe,  proto_juniper);
1435   juniper_mlppp_handle  = create_dissector_handle(dissect_juniper_mlppp,  proto_juniper);
1436   juniper_mlfr_handle   = create_dissector_handle(dissect_juniper_mlfr,   proto_juniper);
1437   juniper_ether_handle  = create_dissector_handle(dissect_juniper_ether,  proto_juniper);
1438   juniper_ppp_handle    = create_dissector_handle(dissect_juniper_ppp,    proto_juniper);
1439   juniper_frelay_handle = create_dissector_handle(dissect_juniper_frelay, proto_juniper);
1440   juniper_chdlc_handle  = create_dissector_handle(dissect_juniper_chdlc,  proto_juniper);
1441   juniper_ggsn_handle   = create_dissector_handle(dissect_juniper_ggsn,   proto_juniper);
1442   juniper_vp_handle     = create_dissector_handle(dissect_juniper_vp,     proto_juniper);
1443   juniper_svcs_handle   = create_dissector_handle(dissect_juniper_svcs,   proto_juniper);
1444
1445   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_ATM2,   juniper_atm2_handle);
1446   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_ATM1,   juniper_atm1_handle);
1447   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_PPPOE,  juniper_pppoe_handle);
1448   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_MLPPP,  juniper_mlppp_handle);
1449   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_MLFR,   juniper_mlfr_handle);
1450   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_ETHER,  juniper_ether_handle);
1451   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_PPP,    juniper_ppp_handle);
1452   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_FRELAY, juniper_frelay_handle);
1453   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_CHDLC,  juniper_chdlc_handle);
1454   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_GGSN,   juniper_ggsn_handle);
1455   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_VP,     juniper_vp_handle);
1456   dissector_add_uint("wtap_encap", WTAP_ENCAP_JUNIPER_SVCS,   juniper_svcs_handle);
1457
1458 }
1459
1460
1461 /*
1462  * Editor modelines
1463  *
1464  * Local Variables:
1465  * c-basic-offset: 2
1466  * tab-width: 8
1467  * indent-tabs-mode: nil
1468  * End:
1469  *
1470  * ex: set shiftwidth=2 tabstop=8 expandtab:
1471  * :indentSize=2:tabSize=8:noTabs=true:
1472  */