Coverage Report

Created: 2025-02-15 06:25

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