source: rtems-libbsd/freebsd/contrib/tcpdump/print-juniper.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

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