xref: /netbsd-src/external/bsd/tcpdump/dist/print-juniper.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
10f74e101Schristos /*     NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp        */
20f74e101Schristos 
30f74e101Schristos /*
40f74e101Schristos  * Redistribution and use in source and binary forms, with or without
50f74e101Schristos  * modification, are permitted provided that: (1) source code
60f74e101Schristos  * distributions retain the above copyright notice and this paragraph
70f74e101Schristos  * in its entirety, and (2) distributions including binary code include
80f74e101Schristos  * the above copyright notice and this paragraph in its entirety in
90f74e101Schristos  * the documentation or other materials provided with the distribution.
100f74e101Schristos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
110f74e101Schristos  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
120f74e101Schristos  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
130f74e101Schristos  * FOR A PARTICULAR PURPOSE.
140f74e101Schristos  *
1572c96ff3Schristos  * Original code by Hannes Gredler (hannes@gredler.at)
160f74e101Schristos  */
170f74e101Schristos 
18dc860a36Sspz /* \summary: DLT_JUNIPER_* printers */
19dc860a36Sspz 
2011b3aaa1Schristos #include <sys/cdefs.h>
210f74e101Schristos #ifndef lint
22*26ba0b50Schristos __RCSID("$NetBSD: print-juniper.c,v 1.12 2024/09/02 16:15:31 christos Exp $");
230f74e101Schristos #endif
240f74e101Schristos 
25c74ad251Schristos #include <config.h>
260f74e101Schristos 
27c74ad251Schristos #include "netdissect-stdinc.h"
280f74e101Schristos 
29dc860a36Sspz #include <string.h>
30dc860a36Sspz 
31c74ad251Schristos #define ND_LONGJMP_FROM_TCHECK
32fdccd7e4Schristos #include "netdissect.h"
330f74e101Schristos #include "addrtoname.h"
340f74e101Schristos #include "extract.h"
350f74e101Schristos #include "ppp.h"
360f74e101Schristos #include "llc.h"
370f74e101Schristos #include "nlpid.h"
380f74e101Schristos #include "ethertype.h"
390f74e101Schristos #include "atm.h"
400f74e101Schristos 
41c74ad251Schristos /*
42c74ad251Schristos  * If none of the Juniper DLT_s are defined, there's nothing to do.
43c74ad251Schristos  */
44c74ad251Schristos #if defined(DLT_JUNIPER_GGSN) || defined(DLT_JUNIPER_ES) || \
45c74ad251Schristos     defined(DLT_JUNIPER_MONITOR) || defined(DLT_JUNIPER_SERVICES) || \
46c74ad251Schristos     defined(DLT_JUNIPER_PPPOE) || defined(DLT_JUNIPER_ETHER) || \
47c74ad251Schristos     defined(DLT_JUNIPER_PPP) || defined(DLT_JUNIPER_FRELAY) || \
48c74ad251Schristos     defined(DLT_JUNIPER_CHDLC) || defined(DLT_JUNIPER_PPPOE_ATM) || \
49c74ad251Schristos     defined(DLT_JUNIPER_MLPPP) || defined(DLT_JUNIPER_MFR) || \
50c74ad251Schristos     defined(DLT_JUNIPER_MLFR) || defined(DLT_JUNIPER_ATM1) || \
51c74ad251Schristos     defined(DLT_JUNIPER_ATM2)
520f74e101Schristos #define JUNIPER_BPF_OUT           0       /* Outgoing packet */
530f74e101Schristos #define JUNIPER_BPF_IN            1       /* Incoming packet */
540f74e101Schristos #define JUNIPER_BPF_PKT_IN        0x1     /* Incoming packet */
550f74e101Schristos #define JUNIPER_BPF_NO_L2         0x2     /* L2 header stripped */
560f74e101Schristos #define JUNIPER_BPF_IIF           0x4     /* IIF is valid */
570f74e101Schristos #define JUNIPER_BPF_FILTER        0x40    /* BPF filtering is supported */
580f74e101Schristos #define JUNIPER_BPF_EXT           0x80    /* extensions present */
590f74e101Schristos #define JUNIPER_MGC_NUMBER        0x4d4743 /* = "MGC" */
600f74e101Schristos 
610f74e101Schristos #define JUNIPER_LSQ_COOKIE_RE         (1 << 3)
620f74e101Schristos #define JUNIPER_LSQ_COOKIE_DIR        (1 << 2)
630f74e101Schristos #define JUNIPER_LSQ_L3_PROTO_SHIFT     4
640f74e101Schristos #define JUNIPER_LSQ_L3_PROTO_MASK     (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
650f74e101Schristos #define JUNIPER_LSQ_L3_PROTO_IPV4     (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
660f74e101Schristos #define JUNIPER_LSQ_L3_PROTO_IPV6     (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
670f74e101Schristos #define JUNIPER_LSQ_L3_PROTO_MPLS     (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
680f74e101Schristos #define JUNIPER_LSQ_L3_PROTO_ISO      (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
690f74e101Schristos #define AS_PIC_COOKIE_LEN 8
700f74e101Schristos 
710f74e101Schristos #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
720f74e101Schristos #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
730f74e101Schristos #define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
740f74e101Schristos #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
750f74e101Schristos #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
760f74e101Schristos 
77c74ad251Schristos #ifdef DLT_JUNIPER_ES
78870189d2Schristos static const struct tok juniper_ipsec_type_values[] = {
790f74e101Schristos     { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" },
800f74e101Schristos     { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" },
810f74e101Schristos     { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE, "ESP AUTH" },
820f74e101Schristos     { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE, "AH AUTH" },
830f74e101Schristos     { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" },
840f74e101Schristos     { 0, NULL}
850f74e101Schristos };
86c74ad251Schristos #endif
870f74e101Schristos 
88870189d2Schristos static const struct tok juniper_direction_values[] = {
890f74e101Schristos     { JUNIPER_BPF_IN,  "In"},
900f74e101Schristos     { JUNIPER_BPF_OUT, "Out"},
910f74e101Schristos     { 0, NULL}
920f74e101Schristos };
930f74e101Schristos 
940f74e101Schristos /* codepoints for encoding extensions to a .pcap file */
950f74e101Schristos enum {
960f74e101Schristos     JUNIPER_EXT_TLV_IFD_IDX = 1,
970f74e101Schristos     JUNIPER_EXT_TLV_IFD_NAME = 2,
980f74e101Schristos     JUNIPER_EXT_TLV_IFD_MEDIATYPE = 3,
990f74e101Schristos     JUNIPER_EXT_TLV_IFL_IDX = 4,
1000f74e101Schristos     JUNIPER_EXT_TLV_IFL_UNIT = 5,
1010f74e101Schristos     JUNIPER_EXT_TLV_IFL_ENCAPS = 6,
1020f74e101Schristos     JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE = 7,
1030f74e101Schristos     JUNIPER_EXT_TLV_TTP_IFL_ENCAPS = 8
1040f74e101Schristos };
1050f74e101Schristos 
1060f74e101Schristos /* 1 byte type and 1-byte length */
107dc860a36Sspz #define JUNIPER_EXT_TLV_OVERHEAD 2U
1080f74e101Schristos 
109870189d2Schristos static const struct tok jnx_ext_tlv_values[] = {
1100f74e101Schristos     { JUNIPER_EXT_TLV_IFD_IDX, "Device Interface Index" },
1110f74e101Schristos     { JUNIPER_EXT_TLV_IFD_NAME,"Device Interface Name" },
1120f74e101Schristos     { JUNIPER_EXT_TLV_IFD_MEDIATYPE, "Device Media Type" },
1130f74e101Schristos     { JUNIPER_EXT_TLV_IFL_IDX, "Logical Interface Index" },
1140f74e101Schristos     { JUNIPER_EXT_TLV_IFL_UNIT,"Logical Unit Number" },
1150f74e101Schristos     { JUNIPER_EXT_TLV_IFL_ENCAPS, "Logical Interface Encapsulation" },
1160f74e101Schristos     { JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" },
1170f74e101Schristos     { JUNIPER_EXT_TLV_TTP_IFL_ENCAPS, "TTP derived Logical Interface Encapsulation" },
1180f74e101Schristos     { 0, NULL }
1190f74e101Schristos };
1200f74e101Schristos 
121870189d2Schristos static const struct tok jnx_flag_values[] = {
1220f74e101Schristos     { JUNIPER_BPF_EXT, "Ext" },
1230f74e101Schristos     { JUNIPER_BPF_FILTER, "Filter" },
1240f74e101Schristos     { JUNIPER_BPF_IIF, "IIF" },
1250f74e101Schristos     { JUNIPER_BPF_NO_L2, "no-L2" },
1260f74e101Schristos     { JUNIPER_BPF_PKT_IN, "In" },
1270f74e101Schristos     { 0, NULL }
1280f74e101Schristos };
1290f74e101Schristos 
1300f74e101Schristos #define JUNIPER_IFML_ETHER              1
1310f74e101Schristos #define JUNIPER_IFML_FDDI               2
1320f74e101Schristos #define JUNIPER_IFML_TOKENRING          3
1330f74e101Schristos #define JUNIPER_IFML_PPP                4
1340f74e101Schristos #define JUNIPER_IFML_FRAMERELAY         5
1350f74e101Schristos #define JUNIPER_IFML_CISCOHDLC          6
1360f74e101Schristos #define JUNIPER_IFML_SMDSDXI            7
1370f74e101Schristos #define JUNIPER_IFML_ATMPVC             8
1380f74e101Schristos #define JUNIPER_IFML_PPP_CCC            9
1390f74e101Schristos #define JUNIPER_IFML_FRAMERELAY_CCC     10
1400f74e101Schristos #define JUNIPER_IFML_IPIP               11
1410f74e101Schristos #define JUNIPER_IFML_GRE                12
1420f74e101Schristos #define JUNIPER_IFML_PIM                13
1430f74e101Schristos #define JUNIPER_IFML_PIMD               14
1440f74e101Schristos #define JUNIPER_IFML_CISCOHDLC_CCC      15
1450f74e101Schristos #define JUNIPER_IFML_VLAN_CCC           16
1460f74e101Schristos #define JUNIPER_IFML_MLPPP              17
1470f74e101Schristos #define JUNIPER_IFML_MLFR               18
1480f74e101Schristos #define JUNIPER_IFML_ML                 19
1490f74e101Schristos #define JUNIPER_IFML_LSI                20
1500f74e101Schristos #define JUNIPER_IFML_DFE                21
1510f74e101Schristos #define JUNIPER_IFML_ATM_CELLRELAY_CCC  22
1520f74e101Schristos #define JUNIPER_IFML_CRYPTO             23
1530f74e101Schristos #define JUNIPER_IFML_GGSN               24
1540f74e101Schristos #define JUNIPER_IFML_LSI_PPP            25
1550f74e101Schristos #define JUNIPER_IFML_LSI_CISCOHDLC      26
1560f74e101Schristos #define JUNIPER_IFML_PPP_TCC            27
1570f74e101Schristos #define JUNIPER_IFML_FRAMERELAY_TCC     28
1580f74e101Schristos #define JUNIPER_IFML_CISCOHDLC_TCC      29
1590f74e101Schristos #define JUNIPER_IFML_ETHERNET_CCC       30
1600f74e101Schristos #define JUNIPER_IFML_VT                 31
1610f74e101Schristos #define JUNIPER_IFML_EXTENDED_VLAN_CCC  32
1620f74e101Schristos #define JUNIPER_IFML_ETHER_OVER_ATM     33
1630f74e101Schristos #define JUNIPER_IFML_MONITOR            34
1640f74e101Schristos #define JUNIPER_IFML_ETHERNET_TCC       35
1650f74e101Schristos #define JUNIPER_IFML_VLAN_TCC           36
1660f74e101Schristos #define JUNIPER_IFML_EXTENDED_VLAN_TCC  37
1670f74e101Schristos #define JUNIPER_IFML_CONTROLLER         38
1680f74e101Schristos #define JUNIPER_IFML_MFR                39
1690f74e101Schristos #define JUNIPER_IFML_LS                 40
1700f74e101Schristos #define JUNIPER_IFML_ETHERNET_VPLS      41
1710f74e101Schristos #define JUNIPER_IFML_ETHERNET_VLAN_VPLS 42
1720f74e101Schristos #define JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS 43
1730f74e101Schristos #define JUNIPER_IFML_LT                 44
1740f74e101Schristos #define JUNIPER_IFML_SERVICES           45
1750f74e101Schristos #define JUNIPER_IFML_ETHER_VPLS_OVER_ATM 46
1760f74e101Schristos #define JUNIPER_IFML_FR_PORT_CCC        47
1770f74e101Schristos #define JUNIPER_IFML_FRAMERELAY_EXT_CCC 48
1780f74e101Schristos #define JUNIPER_IFML_FRAMERELAY_EXT_TCC 49
1790f74e101Schristos #define JUNIPER_IFML_FRAMERELAY_FLEX    50
1800f74e101Schristos #define JUNIPER_IFML_GGSNI              51
1810f74e101Schristos #define JUNIPER_IFML_ETHERNET_FLEX      52
1820f74e101Schristos #define JUNIPER_IFML_COLLECTOR          53
1830f74e101Schristos #define JUNIPER_IFML_AGGREGATOR         54
1840f74e101Schristos #define JUNIPER_IFML_LAPD               55
1850f74e101Schristos #define JUNIPER_IFML_PPPOE              56
1860f74e101Schristos #define JUNIPER_IFML_PPP_SUBORDINATE    57
1870f74e101Schristos #define JUNIPER_IFML_CISCOHDLC_SUBORDINATE  58
1880f74e101Schristos #define JUNIPER_IFML_DFC                59
1890f74e101Schristos #define JUNIPER_IFML_PICPEER            60
1900f74e101Schristos 
191870189d2Schristos static const struct tok juniper_ifmt_values[] = {
1920f74e101Schristos     { JUNIPER_IFML_ETHER, "Ethernet" },
1930f74e101Schristos     { JUNIPER_IFML_FDDI, "FDDI" },
1940f74e101Schristos     { JUNIPER_IFML_TOKENRING, "Token-Ring" },
1950f74e101Schristos     { JUNIPER_IFML_PPP, "PPP" },
1960f74e101Schristos     { JUNIPER_IFML_PPP_SUBORDINATE, "PPP-Subordinate" },
1970f74e101Schristos     { JUNIPER_IFML_FRAMERELAY, "Frame-Relay" },
1980f74e101Schristos     { JUNIPER_IFML_CISCOHDLC, "Cisco-HDLC" },
1990f74e101Schristos     { JUNIPER_IFML_SMDSDXI, "SMDS-DXI" },
2000f74e101Schristos     { JUNIPER_IFML_ATMPVC, "ATM-PVC" },
2010f74e101Schristos     { JUNIPER_IFML_PPP_CCC, "PPP-CCC" },
2020f74e101Schristos     { JUNIPER_IFML_FRAMERELAY_CCC, "Frame-Relay-CCC" },
2030f74e101Schristos     { JUNIPER_IFML_FRAMERELAY_EXT_CCC, "Extended FR-CCC" },
2040f74e101Schristos     { JUNIPER_IFML_IPIP, "IP-over-IP" },
2050f74e101Schristos     { JUNIPER_IFML_GRE, "GRE" },
2060f74e101Schristos     { JUNIPER_IFML_PIM, "PIM-Encapsulator" },
2070f74e101Schristos     { JUNIPER_IFML_PIMD, "PIM-Decapsulator" },
2080f74e101Schristos     { JUNIPER_IFML_CISCOHDLC_CCC, "Cisco-HDLC-CCC" },
2090f74e101Schristos     { JUNIPER_IFML_VLAN_CCC, "VLAN-CCC" },
2100f74e101Schristos     { JUNIPER_IFML_EXTENDED_VLAN_CCC, "Extended-VLAN-CCC" },
2110f74e101Schristos     { JUNIPER_IFML_MLPPP, "Multilink-PPP" },
2120f74e101Schristos     { JUNIPER_IFML_MLFR, "Multilink-FR" },
2130f74e101Schristos     { JUNIPER_IFML_MFR, "Multilink-FR-UNI-NNI" },
2140f74e101Schristos     { JUNIPER_IFML_ML, "Multilink" },
2150f74e101Schristos     { JUNIPER_IFML_LS, "LinkService" },
2160f74e101Schristos     { JUNIPER_IFML_LSI, "LSI" },
2170f74e101Schristos     { JUNIPER_IFML_ATM_CELLRELAY_CCC, "ATM-CCC-Cell-Relay" },
2180f74e101Schristos     { JUNIPER_IFML_CRYPTO, "IPSEC-over-IP" },
2190f74e101Schristos     { JUNIPER_IFML_GGSN, "GGSN" },
2200f74e101Schristos     { JUNIPER_IFML_PPP_TCC, "PPP-TCC" },
2210f74e101Schristos     { JUNIPER_IFML_FRAMERELAY_TCC, "Frame-Relay-TCC" },
2220f74e101Schristos     { JUNIPER_IFML_FRAMERELAY_EXT_TCC, "Extended FR-TCC" },
2230f74e101Schristos     { JUNIPER_IFML_CISCOHDLC_TCC, "Cisco-HDLC-TCC" },
2240f74e101Schristos     { JUNIPER_IFML_ETHERNET_CCC, "Ethernet-CCC" },
2250f74e101Schristos     { JUNIPER_IFML_VT, "VPN-Loopback-tunnel" },
2260f74e101Schristos     { JUNIPER_IFML_ETHER_OVER_ATM, "Ethernet-over-ATM" },
2270f74e101Schristos     { JUNIPER_IFML_ETHER_VPLS_OVER_ATM, "Ethernet-VPLS-over-ATM" },
2280f74e101Schristos     { JUNIPER_IFML_MONITOR, "Monitor" },
2290f74e101Schristos     { JUNIPER_IFML_ETHERNET_TCC, "Ethernet-TCC" },
2300f74e101Schristos     { JUNIPER_IFML_VLAN_TCC, "VLAN-TCC" },
2310f74e101Schristos     { JUNIPER_IFML_EXTENDED_VLAN_TCC, "Extended-VLAN-TCC" },
2320f74e101Schristos     { JUNIPER_IFML_CONTROLLER, "Controller" },
2330f74e101Schristos     { JUNIPER_IFML_ETHERNET_VPLS, "VPLS" },
2340f74e101Schristos     { JUNIPER_IFML_ETHERNET_VLAN_VPLS, "VLAN-VPLS" },
2350f74e101Schristos     { JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS, "Extended-VLAN-VPLS" },
2360f74e101Schristos     { JUNIPER_IFML_LT, "Logical-tunnel" },
2370f74e101Schristos     { JUNIPER_IFML_SERVICES, "General-Services" },
2380f74e101Schristos     { JUNIPER_IFML_PPPOE, "PPPoE" },
2390f74e101Schristos     { JUNIPER_IFML_ETHERNET_FLEX, "Flexible-Ethernet-Services" },
2400f74e101Schristos     { JUNIPER_IFML_FRAMERELAY_FLEX, "Flexible-FrameRelay" },
2410f74e101Schristos     { JUNIPER_IFML_COLLECTOR, "Flow-collection" },
2420f74e101Schristos     { JUNIPER_IFML_PICPEER, "PIC Peer" },
2430f74e101Schristos     { JUNIPER_IFML_DFC, "Dynamic-Flow-Capture" },
2440f74e101Schristos     {0,                    NULL}
2450f74e101Schristos };
2460f74e101Schristos 
2470f74e101Schristos #define JUNIPER_IFLE_ATM_SNAP           2
2480f74e101Schristos #define JUNIPER_IFLE_ATM_NLPID          3
2490f74e101Schristos #define JUNIPER_IFLE_ATM_VCMUX          4
2500f74e101Schristos #define JUNIPER_IFLE_ATM_LLC            5
2510f74e101Schristos #define JUNIPER_IFLE_ATM_PPP_VCMUX      6
2520f74e101Schristos #define JUNIPER_IFLE_ATM_PPP_LLC        7
2530f74e101Schristos #define JUNIPER_IFLE_ATM_PPP_FUNI       8
2540f74e101Schristos #define JUNIPER_IFLE_ATM_CCC            9
2550f74e101Schristos #define JUNIPER_IFLE_FR_NLPID           10
2560f74e101Schristos #define JUNIPER_IFLE_FR_SNAP            11
2570f74e101Schristos #define JUNIPER_IFLE_FR_PPP             12
2580f74e101Schristos #define JUNIPER_IFLE_FR_CCC             13
2590f74e101Schristos #define JUNIPER_IFLE_ENET2              14
2600f74e101Schristos #define JUNIPER_IFLE_IEEE8023_SNAP      15
2610f74e101Schristos #define JUNIPER_IFLE_IEEE8023_LLC       16
2620f74e101Schristos #define JUNIPER_IFLE_PPP                17
2630f74e101Schristos #define JUNIPER_IFLE_CISCOHDLC          18
2640f74e101Schristos #define JUNIPER_IFLE_PPP_CCC            19
2650f74e101Schristos #define JUNIPER_IFLE_IPIP_NULL          20
2660f74e101Schristos #define JUNIPER_IFLE_PIM_NULL           21
2670f74e101Schristos #define JUNIPER_IFLE_GRE_NULL           22
2680f74e101Schristos #define JUNIPER_IFLE_GRE_PPP            23
2690f74e101Schristos #define JUNIPER_IFLE_PIMD_DECAPS        24
2700f74e101Schristos #define JUNIPER_IFLE_CISCOHDLC_CCC      25
2710f74e101Schristos #define JUNIPER_IFLE_ATM_CISCO_NLPID    26
2720f74e101Schristos #define JUNIPER_IFLE_VLAN_CCC           27
2730f74e101Schristos #define JUNIPER_IFLE_MLPPP              28
2740f74e101Schristos #define JUNIPER_IFLE_MLFR               29
2750f74e101Schristos #define JUNIPER_IFLE_LSI_NULL           30
2760f74e101Schristos #define JUNIPER_IFLE_AGGREGATE_UNUSED   31
2770f74e101Schristos #define JUNIPER_IFLE_ATM_CELLRELAY_CCC  32
2780f74e101Schristos #define JUNIPER_IFLE_CRYPTO             33
2790f74e101Schristos #define JUNIPER_IFLE_GGSN               34
2800f74e101Schristos #define JUNIPER_IFLE_ATM_TCC            35
2810f74e101Schristos #define JUNIPER_IFLE_FR_TCC             36
2820f74e101Schristos #define JUNIPER_IFLE_PPP_TCC            37
2830f74e101Schristos #define JUNIPER_IFLE_CISCOHDLC_TCC      38
2840f74e101Schristos #define JUNIPER_IFLE_ETHERNET_CCC       39
2850f74e101Schristos #define JUNIPER_IFLE_VT                 40
2860f74e101Schristos #define JUNIPER_IFLE_ATM_EOA_LLC        41
2870f74e101Schristos #define JUNIPER_IFLE_EXTENDED_VLAN_CCC          42
2880f74e101Schristos #define JUNIPER_IFLE_ATM_SNAP_TCC       43
2890f74e101Schristos #define JUNIPER_IFLE_MONITOR            44
2900f74e101Schristos #define JUNIPER_IFLE_ETHERNET_TCC       45
2910f74e101Schristos #define JUNIPER_IFLE_VLAN_TCC           46
2920f74e101Schristos #define JUNIPER_IFLE_EXTENDED_VLAN_TCC  47
2930f74e101Schristos #define JUNIPER_IFLE_MFR                48
2940f74e101Schristos #define JUNIPER_IFLE_ETHERNET_VPLS      49
2950f74e101Schristos #define JUNIPER_IFLE_ETHERNET_VLAN_VPLS 50
2960f74e101Schristos #define JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS 51
2970f74e101Schristos #define JUNIPER_IFLE_SERVICES           52
2980f74e101Schristos #define JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC                53
2990f74e101Schristos #define JUNIPER_IFLE_FR_PORT_CCC        54
3000f74e101Schristos #define JUNIPER_IFLE_ATM_MLPPP_LLC      55
3010f74e101Schristos #define JUNIPER_IFLE_ATM_EOA_CCC        56
3020f74e101Schristos #define JUNIPER_IFLE_LT_VLAN            57
3030f74e101Schristos #define JUNIPER_IFLE_COLLECTOR          58
3040f74e101Schristos #define JUNIPER_IFLE_AGGREGATOR         59
3050f74e101Schristos #define JUNIPER_IFLE_LAPD               60
3060f74e101Schristos #define JUNIPER_IFLE_ATM_PPPOE_LLC          61
3070f74e101Schristos #define JUNIPER_IFLE_ETHERNET_PPPOE         62
3080f74e101Schristos #define JUNIPER_IFLE_PPPOE                  63
3090f74e101Schristos #define JUNIPER_IFLE_PPP_SUBORDINATE        64
3100f74e101Schristos #define JUNIPER_IFLE_CISCOHDLC_SUBORDINATE  65
3110f74e101Schristos #define JUNIPER_IFLE_DFC                    66
3120f74e101Schristos #define JUNIPER_IFLE_PICPEER                67
3130f74e101Schristos 
314870189d2Schristos static const struct tok juniper_ifle_values[] = {
3150f74e101Schristos     { JUNIPER_IFLE_AGGREGATOR, "Aggregator" },
3160f74e101Schristos     { JUNIPER_IFLE_ATM_CCC, "CCC over ATM" },
3170f74e101Schristos     { JUNIPER_IFLE_ATM_CELLRELAY_CCC, "ATM CCC Cell Relay" },
3180f74e101Schristos     { JUNIPER_IFLE_ATM_CISCO_NLPID, "CISCO compatible NLPID" },
3190f74e101Schristos     { JUNIPER_IFLE_ATM_EOA_CCC, "Ethernet over ATM CCC" },
3200f74e101Schristos     { JUNIPER_IFLE_ATM_EOA_LLC, "Ethernet over ATM LLC" },
3210f74e101Schristos     { JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC, "Ethernet VPLS over ATM LLC" },
3220f74e101Schristos     { JUNIPER_IFLE_ATM_LLC, "ATM LLC" },
3230f74e101Schristos     { JUNIPER_IFLE_ATM_MLPPP_LLC, "MLPPP over ATM LLC" },
3240f74e101Schristos     { JUNIPER_IFLE_ATM_NLPID, "ATM NLPID" },
3250f74e101Schristos     { JUNIPER_IFLE_ATM_PPPOE_LLC, "PPPoE over ATM LLC" },
3260f74e101Schristos     { JUNIPER_IFLE_ATM_PPP_FUNI, "PPP over FUNI" },
3270f74e101Schristos     { JUNIPER_IFLE_ATM_PPP_LLC, "PPP over ATM LLC" },
3280f74e101Schristos     { JUNIPER_IFLE_ATM_PPP_VCMUX, "PPP over ATM VCMUX" },
3290f74e101Schristos     { JUNIPER_IFLE_ATM_SNAP, "ATM SNAP" },
3300f74e101Schristos     { JUNIPER_IFLE_ATM_SNAP_TCC, "ATM SNAP TCC" },
3310f74e101Schristos     { JUNIPER_IFLE_ATM_TCC, "ATM VCMUX TCC" },
3320f74e101Schristos     { JUNIPER_IFLE_ATM_VCMUX, "ATM VCMUX" },
3330f74e101Schristos     { JUNIPER_IFLE_CISCOHDLC, "C-HDLC" },
3340f74e101Schristos     { JUNIPER_IFLE_CISCOHDLC_CCC, "C-HDLC CCC" },
3350f74e101Schristos     { JUNIPER_IFLE_CISCOHDLC_SUBORDINATE, "C-HDLC via dialer" },
3360f74e101Schristos     { JUNIPER_IFLE_CISCOHDLC_TCC, "C-HDLC TCC" },
3370f74e101Schristos     { JUNIPER_IFLE_COLLECTOR, "Collector" },
3380f74e101Schristos     { JUNIPER_IFLE_CRYPTO, "Crypto" },
3390f74e101Schristos     { JUNIPER_IFLE_ENET2, "Ethernet" },
3400f74e101Schristos     { JUNIPER_IFLE_ETHERNET_CCC, "Ethernet CCC" },
3410f74e101Schristos     { JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS, "Extended VLAN VPLS" },
3420f74e101Schristos     { JUNIPER_IFLE_ETHERNET_PPPOE, "PPPoE over Ethernet" },
3430f74e101Schristos     { JUNIPER_IFLE_ETHERNET_TCC, "Ethernet TCC" },
3440f74e101Schristos     { JUNIPER_IFLE_ETHERNET_VLAN_VPLS, "VLAN VPLS" },
3450f74e101Schristos     { JUNIPER_IFLE_ETHERNET_VPLS, "VPLS" },
3460f74e101Schristos     { JUNIPER_IFLE_EXTENDED_VLAN_CCC, "Extended VLAN CCC" },
3470f74e101Schristos     { JUNIPER_IFLE_EXTENDED_VLAN_TCC, "Extended VLAN TCC" },
3480f74e101Schristos     { JUNIPER_IFLE_FR_CCC, "FR CCC" },
3490f74e101Schristos     { JUNIPER_IFLE_FR_NLPID, "FR NLPID" },
3500f74e101Schristos     { JUNIPER_IFLE_FR_PORT_CCC, "FR CCC" },
3510f74e101Schristos     { JUNIPER_IFLE_FR_PPP, "FR PPP" },
3520f74e101Schristos     { JUNIPER_IFLE_FR_SNAP, "FR SNAP" },
3530f74e101Schristos     { JUNIPER_IFLE_FR_TCC, "FR TCC" },
3540f74e101Schristos     { JUNIPER_IFLE_GGSN, "GGSN" },
3550f74e101Schristos     { JUNIPER_IFLE_GRE_NULL, "GRE NULL" },
3560f74e101Schristos     { JUNIPER_IFLE_GRE_PPP, "PPP over GRE" },
3570f74e101Schristos     { JUNIPER_IFLE_IPIP_NULL, "IPIP" },
3580f74e101Schristos     { JUNIPER_IFLE_LAPD, "LAPD" },
3590f74e101Schristos     { JUNIPER_IFLE_LSI_NULL, "LSI Null" },
3600f74e101Schristos     { JUNIPER_IFLE_LT_VLAN, "LT VLAN" },
3610f74e101Schristos     { JUNIPER_IFLE_MFR, "MFR" },
3620f74e101Schristos     { JUNIPER_IFLE_MLFR, "MLFR" },
3630f74e101Schristos     { JUNIPER_IFLE_MLPPP, "MLPPP" },
3640f74e101Schristos     { JUNIPER_IFLE_MONITOR, "Monitor" },
3650f74e101Schristos     { JUNIPER_IFLE_PIMD_DECAPS, "PIMd" },
3660f74e101Schristos     { JUNIPER_IFLE_PIM_NULL, "PIM Null" },
3670f74e101Schristos     { JUNIPER_IFLE_PPP, "PPP" },
3680f74e101Schristos     { JUNIPER_IFLE_PPPOE, "PPPoE" },
3690f74e101Schristos     { JUNIPER_IFLE_PPP_CCC, "PPP CCC" },
3700f74e101Schristos     { JUNIPER_IFLE_PPP_SUBORDINATE, "" },
3710f74e101Schristos     { JUNIPER_IFLE_PPP_TCC, "PPP TCC" },
3720f74e101Schristos     { JUNIPER_IFLE_SERVICES, "General Services" },
3730f74e101Schristos     { JUNIPER_IFLE_VLAN_CCC, "VLAN CCC" },
3740f74e101Schristos     { JUNIPER_IFLE_VLAN_TCC, "VLAN TCC" },
3750f74e101Schristos     { JUNIPER_IFLE_VT, "VT" },
3760f74e101Schristos     {0,                    NULL}
3770f74e101Schristos };
3780f74e101Schristos 
3790f74e101Schristos struct juniper_cookie_table_t {
380b3a00663Schristos     uint32_t pictype;		/* pic type */
381b3a00663Schristos     uint8_t  cookie_len;	/* cookie len */
3820f74e101Schristos     const char *s;		/* pic name */
3830f74e101Schristos };
3840f74e101Schristos 
385b3a00663Schristos static const struct juniper_cookie_table_t juniper_cookie_table[] = {
3860f74e101Schristos #ifdef DLT_JUNIPER_ATM1
3870f74e101Schristos     { DLT_JUNIPER_ATM1,  4, "ATM1"},
3880f74e101Schristos #endif
3890f74e101Schristos #ifdef DLT_JUNIPER_ATM2
3900f74e101Schristos     { DLT_JUNIPER_ATM2,  8, "ATM2"},
3910f74e101Schristos #endif
3920f74e101Schristos #ifdef DLT_JUNIPER_MLPPP
3930f74e101Schristos     { DLT_JUNIPER_MLPPP, 2, "MLPPP"},
3940f74e101Schristos #endif
3950f74e101Schristos #ifdef DLT_JUNIPER_MLFR
3960f74e101Schristos     { DLT_JUNIPER_MLFR,  2, "MLFR"},
3970f74e101Schristos #endif
3980f74e101Schristos #ifdef DLT_JUNIPER_MFR
3990f74e101Schristos     { DLT_JUNIPER_MFR,   4, "MFR"},
4000f74e101Schristos #endif
4010f74e101Schristos #ifdef DLT_JUNIPER_PPPOE
4020f74e101Schristos     { DLT_JUNIPER_PPPOE, 0, "PPPoE"},
4030f74e101Schristos #endif
4040f74e101Schristos #ifdef DLT_JUNIPER_PPPOE_ATM
4050f74e101Schristos     { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"},
4060f74e101Schristos #endif
4070f74e101Schristos #ifdef DLT_JUNIPER_GGSN
4080f74e101Schristos     { DLT_JUNIPER_GGSN, 8, "GGSN"},
4090f74e101Schristos #endif
4100f74e101Schristos #ifdef DLT_JUNIPER_MONITOR
4110f74e101Schristos     { DLT_JUNIPER_MONITOR, 8, "MONITOR"},
4120f74e101Schristos #endif
4130f74e101Schristos #ifdef DLT_JUNIPER_SERVICES
4140f74e101Schristos     { DLT_JUNIPER_SERVICES, 8, "AS"},
4150f74e101Schristos #endif
4160f74e101Schristos #ifdef DLT_JUNIPER_ES
4170f74e101Schristos     { DLT_JUNIPER_ES, 0, "ES"},
4180f74e101Schristos #endif
4190f74e101Schristos     { 0, 0, NULL }
4200f74e101Schristos };
4210f74e101Schristos 
4220f74e101Schristos struct juniper_l2info_t {
423b3a00663Schristos     uint32_t length;
424b3a00663Schristos     uint32_t caplen;
425b3a00663Schristos     uint32_t pictype;
426b3a00663Schristos     uint8_t direction;
427c74ad251Schristos     u_int header_len;
428b3a00663Schristos     uint8_t cookie_len;
429b3a00663Schristos     uint8_t cookie_type;
430b3a00663Schristos     uint8_t cookie[8];
431c74ad251Schristos     u_int bundle;
432b3a00663Schristos     uint16_t proto;
433b3a00663Schristos     uint8_t flags;
4340f74e101Schristos };
4350f74e101Schristos 
4360f74e101Schristos #define LS_COOKIE_ID            0x54
4370f74e101Schristos #define AS_COOKIE_ID            0x47
4380f74e101Schristos #define LS_MLFR_COOKIE_LEN	4
4390f74e101Schristos #define ML_MLFR_COOKIE_LEN	2
4400f74e101Schristos #define LS_MFR_COOKIE_LEN	6
4410f74e101Schristos #define ATM1_COOKIE_LEN         4
4420f74e101Schristos #define ATM2_COOKIE_LEN         8
4430f74e101Schristos 
4440f74e101Schristos #define ATM2_PKT_TYPE_MASK  0x70
4450f74e101Schristos #define ATM2_GAP_COUNT_MASK 0x3F
4460f74e101Schristos 
4470f74e101Schristos #define JUNIPER_PROTO_NULL          1
4480f74e101Schristos #define JUNIPER_PROTO_IPV4          2
4490f74e101Schristos #define JUNIPER_PROTO_IPV6          6
4500f74e101Schristos 
4510f74e101Schristos #define MFR_BE_MASK 0xc0
4520f74e101Schristos 
453c74ad251Schristos #ifdef DLT_JUNIPER_GGSN
454870189d2Schristos static const struct tok juniper_protocol_values[] = {
4550f74e101Schristos     { JUNIPER_PROTO_NULL, "Null" },
4560f74e101Schristos     { JUNIPER_PROTO_IPV4, "IPv4" },
4570f74e101Schristos     { JUNIPER_PROTO_IPV6, "IPv6" },
4580f74e101Schristos     { 0, NULL}
4590f74e101Schristos };
460c74ad251Schristos #endif
4610f74e101Schristos 
462c74ad251Schristos static int ip_heuristic_guess(netdissect_options *, const u_char *, u_int);
463c74ad251Schristos #ifdef DLT_JUNIPER_ATM2
464c74ad251Schristos static int juniper_ppp_heuristic_guess(netdissect_options *, const u_char *, u_int);
465c74ad251Schristos #endif
466b3a00663Schristos static int juniper_parse_header(netdissect_options *, const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *);
4670f74e101Schristos 
4680f74e101Schristos #ifdef DLT_JUNIPER_GGSN
469c74ad251Schristos void
470c74ad251Schristos juniper_ggsn_if_print(netdissect_options *ndo,
471c74ad251Schristos                       const struct pcap_pkthdr *h, const u_char *p)
4720f74e101Schristos {
4730f74e101Schristos         struct juniper_l2info_t l2info;
4740f74e101Schristos         struct juniper_ggsn_header {
475c74ad251Schristos             nd_uint8_t  svc_id;
476c74ad251Schristos             nd_uint8_t  flags_len;
477c74ad251Schristos             nd_uint8_t  proto;
478c74ad251Schristos             nd_uint8_t  flags;
479c74ad251Schristos             nd_uint16_t vlan_id;
480c74ad251Schristos             nd_byte     res[2];
4810f74e101Schristos         };
4820f74e101Schristos         const struct juniper_ggsn_header *gh;
483c74ad251Schristos         uint8_t proto;
4840f74e101Schristos 
485c74ad251Schristos         ndo->ndo_protocol = "juniper_ggsn";
486c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
4870f74e101Schristos         l2info.pictype = DLT_JUNIPER_GGSN;
488c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
489c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
490c74ad251Schristos             return;
491c74ad251Schristos         }
4920f74e101Schristos 
4930f74e101Schristos         p+=l2info.header_len;
4940f74e101Schristos         gh = (struct juniper_ggsn_header *)&l2info.cookie;
4950f74e101Schristos 
496c74ad251Schristos         /* use EXTRACT_, not GET_ (not packet buffer pointer) */
497c74ad251Schristos         proto = EXTRACT_U_1(gh->proto);
498b3a00663Schristos         if (ndo->ndo_eflag) {
499c74ad251Schristos             ND_PRINT("proto %s (%u), vlan %u: ",
500c74ad251Schristos                    tok2str(juniper_protocol_values,"Unknown",proto),
501c74ad251Schristos                    proto,
502c74ad251Schristos                    EXTRACT_BE_U_2(gh->vlan_id));
5030f74e101Schristos         }
5040f74e101Schristos 
505c74ad251Schristos         switch (proto) {
5060f74e101Schristos         case JUNIPER_PROTO_IPV4:
507b3a00663Schristos             ip_print(ndo, p, l2info.length);
5080f74e101Schristos             break;
5090f74e101Schristos         case JUNIPER_PROTO_IPV6:
510b3a00663Schristos             ip6_print(ndo, p, l2info.length);
5110f74e101Schristos             break;
5120f74e101Schristos         default:
513b3a00663Schristos             if (!ndo->ndo_eflag)
514c74ad251Schristos                 ND_PRINT("unknown GGSN proto (%u)", proto);
5150f74e101Schristos         }
5160f74e101Schristos 
517c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
5180f74e101Schristos }
5190f74e101Schristos #endif
5200f74e101Schristos 
5210f74e101Schristos #ifdef DLT_JUNIPER_ES
522c74ad251Schristos void
523c74ad251Schristos juniper_es_if_print(netdissect_options *ndo,
524c74ad251Schristos                     const struct pcap_pkthdr *h, const u_char *p)
5250f74e101Schristos {
5260f74e101Schristos         struct juniper_l2info_t l2info;
5270f74e101Schristos         struct juniper_ipsec_header {
528c74ad251Schristos             nd_uint16_t sa_index;
529c74ad251Schristos             nd_uint8_t  ttl;
530c74ad251Schristos             nd_uint8_t  type;
531c74ad251Schristos             nd_uint32_t spi;
532c74ad251Schristos             nd_ipv4     src_ip;
533c74ad251Schristos             nd_ipv4     dst_ip;
5340f74e101Schristos         };
5350f74e101Schristos         u_int rewrite_len,es_type_bundle;
5360f74e101Schristos         const struct juniper_ipsec_header *ih;
5370f74e101Schristos 
538c74ad251Schristos         ndo->ndo_protocol = "juniper_es";
539c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
5400f74e101Schristos         l2info.pictype = DLT_JUNIPER_ES;
541c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
542c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
543c74ad251Schristos             return;
544c74ad251Schristos         }
5450f74e101Schristos 
5460f74e101Schristos         p+=l2info.header_len;
547fdccd7e4Schristos         ih = (const struct juniper_ipsec_header *)p;
5480f74e101Schristos 
549c74ad251Schristos         ND_TCHECK_SIZE(ih);
550c74ad251Schristos         switch (GET_U_1(ih->type)) {
5510f74e101Schristos         case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
5520f74e101Schristos         case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
5530f74e101Schristos             rewrite_len = 0;
5540f74e101Schristos             es_type_bundle = 1;
5550f74e101Schristos             break;
5560f74e101Schristos         case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE:
5570f74e101Schristos         case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE:
5580f74e101Schristos         case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE:
5590f74e101Schristos             rewrite_len = 16;
5600f74e101Schristos             es_type_bundle = 0;
561b3a00663Schristos             break;
5620f74e101Schristos         default:
563c74ad251Schristos             ND_PRINT("ES Invalid type %u, length %u",
564c74ad251Schristos                    GET_U_1(ih->type),
565c74ad251Schristos                    l2info.length);
566c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
567c74ad251Schristos             return;
5680f74e101Schristos         }
5690f74e101Schristos 
5700f74e101Schristos         l2info.length-=rewrite_len;
5710f74e101Schristos         p+=rewrite_len;
5720f74e101Schristos 
573b3a00663Schristos         if (ndo->ndo_eflag) {
5740f74e101Schristos             if (!es_type_bundle) {
575c74ad251Schristos                 ND_PRINT("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
576c74ad251Schristos                        GET_BE_U_2(ih->sa_index),
577c74ad251Schristos                        GET_U_1(ih->ttl),
578c74ad251Schristos                        tok2str(juniper_ipsec_type_values,"Unknown",GET_U_1(ih->type)),
579c74ad251Schristos                        GET_U_1(ih->type),
580c74ad251Schristos                        GET_BE_U_4(ih->spi),
581c74ad251Schristos                        GET_IPADDR_STRING(ih->src_ip),
582c74ad251Schristos                        GET_IPADDR_STRING(ih->dst_ip),
583c74ad251Schristos                        l2info.length);
5840f74e101Schristos             } else {
585c74ad251Schristos                 ND_PRINT("ES SA, index %u, ttl %u type %s (%u), length %u\n",
586c74ad251Schristos                        GET_BE_U_2(ih->sa_index),
587c74ad251Schristos                        GET_U_1(ih->ttl),
588c74ad251Schristos                        tok2str(juniper_ipsec_type_values,"Unknown",GET_U_1(ih->type)),
589c74ad251Schristos                        GET_U_1(ih->type),
590c74ad251Schristos                        l2info.length);
5910f74e101Schristos             }
5920f74e101Schristos         }
5930f74e101Schristos 
594b3a00663Schristos         ip_print(ndo, p, l2info.length);
595c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
5960f74e101Schristos }
5970f74e101Schristos #endif
5980f74e101Schristos 
5990f74e101Schristos #ifdef DLT_JUNIPER_MONITOR
600c74ad251Schristos void
601c74ad251Schristos juniper_monitor_if_print(netdissect_options *ndo,
602c74ad251Schristos                          const struct pcap_pkthdr *h, const u_char *p)
6030f74e101Schristos {
6040f74e101Schristos         struct juniper_l2info_t l2info;
6050f74e101Schristos         struct juniper_monitor_header {
606c74ad251Schristos             nd_uint8_t  pkt_type;
607c74ad251Schristos             nd_byte     padding;
608c74ad251Schristos             nd_uint16_t iif;
609c74ad251Schristos             nd_uint32_t service_id;
6100f74e101Schristos         };
6110f74e101Schristos         const struct juniper_monitor_header *mh;
6120f74e101Schristos 
613c74ad251Schristos         ndo->ndo_protocol = "juniper_monitor";
614c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
6150f74e101Schristos         l2info.pictype = DLT_JUNIPER_MONITOR;
616c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
617c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
618c74ad251Schristos             return;
619c74ad251Schristos         }
6200f74e101Schristos 
6210f74e101Schristos         p+=l2info.header_len;
622fdccd7e4Schristos         mh = (const struct juniper_monitor_header *)p;
6230f74e101Schristos 
624c74ad251Schristos         ND_TCHECK_SIZE(mh);
625b3a00663Schristos         if (ndo->ndo_eflag)
626c74ad251Schristos             ND_PRINT("service-id %u, iif %u, pkt-type %u: ",
627c74ad251Schristos                    GET_BE_U_4(mh->service_id),
628c74ad251Schristos                    GET_BE_U_2(mh->iif),
629c74ad251Schristos                    GET_U_1(mh->pkt_type));
6300f74e101Schristos 
6310f74e101Schristos         /* no proto field - lets guess by first byte of IP header*/
632b3a00663Schristos         ip_heuristic_guess (ndo, p, l2info.length);
6330f74e101Schristos 
634c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
6350f74e101Schristos }
6360f74e101Schristos #endif
6370f74e101Schristos 
6380f74e101Schristos #ifdef DLT_JUNIPER_SERVICES
639c74ad251Schristos void
640c74ad251Schristos juniper_services_if_print(netdissect_options *ndo,
641c74ad251Schristos                           const struct pcap_pkthdr *h, const u_char *p)
6420f74e101Schristos {
6430f74e101Schristos         struct juniper_l2info_t l2info;
6440f74e101Schristos         struct juniper_services_header {
645c74ad251Schristos             nd_uint8_t  svc_id;
646c74ad251Schristos             nd_uint8_t  flags_len;
647c74ad251Schristos             nd_uint16_t svc_set_id;
648c74ad251Schristos             nd_byte     pad;
649c74ad251Schristos             nd_uint24_t dir_iif;
6500f74e101Schristos         };
6510f74e101Schristos         const struct juniper_services_header *sh;
6520f74e101Schristos 
653c74ad251Schristos         ndo->ndo_protocol = "juniper_services";
654c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
6550f74e101Schristos         l2info.pictype = DLT_JUNIPER_SERVICES;
656c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
657c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
658c74ad251Schristos             return;
659c74ad251Schristos         }
6600f74e101Schristos 
6610f74e101Schristos         p+=l2info.header_len;
662fdccd7e4Schristos         sh = (const struct juniper_services_header *)p;
6630f74e101Schristos 
664c74ad251Schristos         ND_TCHECK_SIZE(sh);
665b3a00663Schristos         if (ndo->ndo_eflag)
666c74ad251Schristos             ND_PRINT("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
667c74ad251Schristos                    GET_U_1(sh->svc_id),
668c74ad251Schristos                    GET_U_1(sh->flags_len),
669c74ad251Schristos                    GET_BE_U_2(sh->svc_set_id),
670c74ad251Schristos                    GET_BE_U_3(sh->dir_iif));
6710f74e101Schristos 
6720f74e101Schristos         /* no proto field - lets guess by first byte of IP header*/
673b3a00663Schristos         ip_heuristic_guess (ndo, p, l2info.length);
6740f74e101Schristos 
675c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
6760f74e101Schristos }
6770f74e101Schristos #endif
6780f74e101Schristos 
6790f74e101Schristos #ifdef DLT_JUNIPER_PPPOE
680c74ad251Schristos void
681c74ad251Schristos juniper_pppoe_if_print(netdissect_options *ndo,
682c74ad251Schristos                        const struct pcap_pkthdr *h, const u_char *p)
6830f74e101Schristos {
6840f74e101Schristos         struct juniper_l2info_t l2info;
6850f74e101Schristos 
686c74ad251Schristos         ndo->ndo_protocol = "juniper_pppoe";
687c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
6880f74e101Schristos         l2info.pictype = DLT_JUNIPER_PPPOE;
689c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
690c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
691c74ad251Schristos             return;
692c74ad251Schristos         }
6930f74e101Schristos 
6940f74e101Schristos         p+=l2info.header_len;
6950f74e101Schristos         /* this DLT contains nothing but raw ethernet frames */
696b3a00663Schristos         ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
697c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
6980f74e101Schristos }
6990f74e101Schristos #endif
7000f74e101Schristos 
7010f74e101Schristos #ifdef DLT_JUNIPER_ETHER
702c74ad251Schristos void
703c74ad251Schristos juniper_ether_if_print(netdissect_options *ndo,
704c74ad251Schristos                        const struct pcap_pkthdr *h, const u_char *p)
7050f74e101Schristos {
7060f74e101Schristos         struct juniper_l2info_t l2info;
7070f74e101Schristos 
708c74ad251Schristos         ndo->ndo_protocol = "juniper_ether";
709c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
7100f74e101Schristos         l2info.pictype = DLT_JUNIPER_ETHER;
711c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
712c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
713c74ad251Schristos             return;
714c74ad251Schristos         }
7150f74e101Schristos 
7160f74e101Schristos         p+=l2info.header_len;
7170f74e101Schristos         /* this DLT contains nothing but raw Ethernet frames */
718c74ad251Schristos         ndo->ndo_ll_hdr_len +=
719c74ad251Schristos 		l2info.header_len +
720b3a00663Schristos 		ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
7210f74e101Schristos }
7220f74e101Schristos #endif
7230f74e101Schristos 
7240f74e101Schristos #ifdef DLT_JUNIPER_PPP
725c74ad251Schristos void
726c74ad251Schristos juniper_ppp_if_print(netdissect_options *ndo,
727c74ad251Schristos                      const struct pcap_pkthdr *h, const u_char *p)
7280f74e101Schristos {
7290f74e101Schristos         struct juniper_l2info_t l2info;
7300f74e101Schristos 
731c74ad251Schristos         ndo->ndo_protocol = "juniper_ppp";
732c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
7330f74e101Schristos         l2info.pictype = DLT_JUNIPER_PPP;
734c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
735c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
736c74ad251Schristos             return;
737c74ad251Schristos         }
7380f74e101Schristos 
7390f74e101Schristos         p+=l2info.header_len;
7400f74e101Schristos         /* this DLT contains nothing but raw ppp frames */
741b3a00663Schristos         ppp_print(ndo, p, l2info.length);
742c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
7430f74e101Schristos }
7440f74e101Schristos #endif
7450f74e101Schristos 
7460f74e101Schristos #ifdef DLT_JUNIPER_FRELAY
747c74ad251Schristos void
748c74ad251Schristos juniper_frelay_if_print(netdissect_options *ndo,
749c74ad251Schristos                         const struct pcap_pkthdr *h, const u_char *p)
7500f74e101Schristos {
7510f74e101Schristos         struct juniper_l2info_t l2info;
7520f74e101Schristos 
753c74ad251Schristos         ndo->ndo_protocol = "juniper_frelay";
754c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
7550f74e101Schristos         l2info.pictype = DLT_JUNIPER_FRELAY;
756c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
757c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
758c74ad251Schristos             return;
759c74ad251Schristos         }
7600f74e101Schristos 
7610f74e101Schristos         p+=l2info.header_len;
7620f74e101Schristos         /* this DLT contains nothing but raw frame-relay frames */
763b3a00663Schristos         fr_print(ndo, p, l2info.length);
764c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
7650f74e101Schristos }
7660f74e101Schristos #endif
7670f74e101Schristos 
7680f74e101Schristos #ifdef DLT_JUNIPER_CHDLC
769c74ad251Schristos void
770c74ad251Schristos juniper_chdlc_if_print(netdissect_options *ndo,
771c74ad251Schristos                        const struct pcap_pkthdr *h, const u_char *p)
7720f74e101Schristos {
7730f74e101Schristos         struct juniper_l2info_t l2info;
7740f74e101Schristos 
775c74ad251Schristos         ndo->ndo_protocol = "juniper_chdlc";
776c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
7770f74e101Schristos         l2info.pictype = DLT_JUNIPER_CHDLC;
778c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
779c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
780c74ad251Schristos             return;
781c74ad251Schristos         }
7820f74e101Schristos 
7830f74e101Schristos         p+=l2info.header_len;
7840f74e101Schristos         /* this DLT contains nothing but raw c-hdlc frames */
785b3a00663Schristos         chdlc_print(ndo, p, l2info.length);
786c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
7870f74e101Schristos }
7880f74e101Schristos #endif
7890f74e101Schristos 
7900f74e101Schristos #ifdef DLT_JUNIPER_PPPOE_ATM
791c74ad251Schristos void
792c74ad251Schristos juniper_pppoe_atm_if_print(netdissect_options *ndo,
793c74ad251Schristos                            const struct pcap_pkthdr *h, const u_char *p)
7940f74e101Schristos {
7950f74e101Schristos         struct juniper_l2info_t l2info;
796b3a00663Schristos         uint16_t extracted_ethertype;
7970f74e101Schristos 
798c74ad251Schristos         ndo->ndo_protocol = "juniper_pppoe_atm";
799c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
8000f74e101Schristos         l2info.pictype = DLT_JUNIPER_PPPOE_ATM;
801c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
802c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
803c74ad251Schristos             return;
804c74ad251Schristos         }
8050f74e101Schristos 
8060f74e101Schristos         p+=l2info.header_len;
8070f74e101Schristos 
808c74ad251Schristos         extracted_ethertype = GET_BE_U_2(p);
8090f74e101Schristos         /* this DLT contains nothing but raw PPPoE frames,
8100f74e101Schristos          * prepended with a type field*/
811b3a00663Schristos         if (ethertype_print(ndo, extracted_ethertype,
8120f74e101Schristos                               p+ETHERTYPE_LEN,
8130f74e101Schristos                               l2info.length-ETHERTYPE_LEN,
814dc860a36Sspz                               l2info.caplen-ETHERTYPE_LEN,
815dc860a36Sspz                               NULL, NULL) == 0)
8160f74e101Schristos             /* ether_type not known, probably it wasn't one */
817c74ad251Schristos             ND_PRINT("unknown ethertype 0x%04x", extracted_ethertype);
8180f74e101Schristos 
819c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
8200f74e101Schristos }
8210f74e101Schristos #endif
8220f74e101Schristos 
8230f74e101Schristos #ifdef DLT_JUNIPER_MLPPP
824c74ad251Schristos void
825c74ad251Schristos juniper_mlppp_if_print(netdissect_options *ndo,
826c74ad251Schristos                        const struct pcap_pkthdr *h, const u_char *p)
8270f74e101Schristos {
8280f74e101Schristos         struct juniper_l2info_t l2info;
8290f74e101Schristos 
830c74ad251Schristos         ndo->ndo_protocol = "juniper_mlppp";
831c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
8320f74e101Schristos         l2info.pictype = DLT_JUNIPER_MLPPP;
833c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
834c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
835c74ad251Schristos             return;
836c74ad251Schristos         }
8370f74e101Schristos 
8380f74e101Schristos         /* suppress Bundle-ID if frame was captured on a child-link
8390f74e101Schristos          * best indicator if the cookie looks like a proto */
840b3a00663Schristos         if (ndo->ndo_eflag &&
841c74ad251Schristos             /* use EXTRACT_, not GET_ (not packet buffer pointer) */
842c74ad251Schristos             EXTRACT_BE_U_2(&l2info.cookie) != PPP_OSI &&
843c74ad251Schristos             /* use EXTRACT_, not GET_ (not packet buffer pointer) */
844c74ad251Schristos             EXTRACT_BE_U_2(&l2info.cookie) !=  (PPP_ADDRESS << 8 | PPP_CONTROL))
845c74ad251Schristos             ND_PRINT("Bundle-ID %u: ", l2info.bundle);
8460f74e101Schristos 
8470f74e101Schristos         p+=l2info.header_len;
8480f74e101Schristos 
8490f74e101Schristos         /* first try the LSQ protos */
8500f74e101Schristos         switch(l2info.proto) {
8510f74e101Schristos         case JUNIPER_LSQ_L3_PROTO_IPV4:
8520f74e101Schristos             /* IP traffic going to the RE would not have a cookie
8530f74e101Schristos              * -> this must be incoming IS-IS over PPP
8540f74e101Schristos              */
8550f74e101Schristos             if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR))
856b3a00663Schristos                 ppp_print(ndo, p, l2info.length);
8570f74e101Schristos             else
858b3a00663Schristos                 ip_print(ndo, p, l2info.length);
859c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
860c74ad251Schristos             return;
8610f74e101Schristos         case JUNIPER_LSQ_L3_PROTO_IPV6:
862b3a00663Schristos             ip6_print(ndo, p,l2info.length);
863c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
864c74ad251Schristos             return;
8650f74e101Schristos         case JUNIPER_LSQ_L3_PROTO_MPLS:
866b3a00663Schristos             mpls_print(ndo, p, l2info.length);
867c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
868c74ad251Schristos             return;
8690f74e101Schristos         case JUNIPER_LSQ_L3_PROTO_ISO:
87072c96ff3Schristos             isoclns_print(ndo, p, l2info.length);
871c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
872c74ad251Schristos             return;
8730f74e101Schristos         default:
8740f74e101Schristos             break;
8750f74e101Schristos         }
8760f74e101Schristos 
8770f74e101Schristos         /* zero length cookie ? */
878c74ad251Schristos         /* use EXTRACT_, not GET_ (not packet buffer pointer) */
879c74ad251Schristos         switch (EXTRACT_BE_U_2(&l2info.cookie)) {
8800f74e101Schristos         case PPP_OSI:
881b3a00663Schristos             ppp_print(ndo, p - 2, l2info.length + 2);
8820f74e101Schristos             break;
8830f74e101Schristos         case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */
8840f74e101Schristos         default:
885b3a00663Schristos             ppp_print(ndo, p, l2info.length);
8860f74e101Schristos             break;
8870f74e101Schristos         }
8880f74e101Schristos 
889c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
8900f74e101Schristos }
8910f74e101Schristos #endif
8920f74e101Schristos 
8930f74e101Schristos 
8940f74e101Schristos #ifdef DLT_JUNIPER_MFR
895c74ad251Schristos void
896c74ad251Schristos juniper_mfr_if_print(netdissect_options *ndo,
897c74ad251Schristos                      const struct pcap_pkthdr *h, const u_char *p)
8980f74e101Schristos {
8990f74e101Schristos         struct juniper_l2info_t l2info;
9000f74e101Schristos 
901c74ad251Schristos         ndo->ndo_protocol = "juniper_mfr";
902dc860a36Sspz         memset(&l2info, 0, sizeof(l2info));
9030f74e101Schristos         l2info.pictype = DLT_JUNIPER_MFR;
904c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
905c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
906c74ad251Schristos             return;
907c74ad251Schristos         }
9080f74e101Schristos 
9090f74e101Schristos         p+=l2info.header_len;
9100f74e101Schristos 
9110f74e101Schristos         /* child-link ? */
9120f74e101Schristos         if (l2info.cookie_len == 0) {
913b3a00663Schristos             mfr_print(ndo, p, l2info.length);
914c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
915c74ad251Schristos             return;
9160f74e101Schristos         }
9170f74e101Schristos 
9180f74e101Schristos         /* first try the LSQ protos */
9190f74e101Schristos         if (l2info.cookie_len == AS_PIC_COOKIE_LEN) {
9200f74e101Schristos             switch(l2info.proto) {
9210f74e101Schristos             case JUNIPER_LSQ_L3_PROTO_IPV4:
922b3a00663Schristos                 ip_print(ndo, p, l2info.length);
923c74ad251Schristos                 ndo->ndo_ll_hdr_len += l2info.header_len;
924c74ad251Schristos                 return;
9250f74e101Schristos             case JUNIPER_LSQ_L3_PROTO_IPV6:
926b3a00663Schristos                 ip6_print(ndo, p,l2info.length);
927c74ad251Schristos                 ndo->ndo_ll_hdr_len += l2info.header_len;
928c74ad251Schristos                 return;
9290f74e101Schristos             case JUNIPER_LSQ_L3_PROTO_MPLS:
930b3a00663Schristos                 mpls_print(ndo, p, l2info.length);
931c74ad251Schristos                 ndo->ndo_ll_hdr_len += l2info.header_len;
932c74ad251Schristos                 return;
9330f74e101Schristos             case JUNIPER_LSQ_L3_PROTO_ISO:
93472c96ff3Schristos                 isoclns_print(ndo, p, l2info.length);
935c74ad251Schristos                 ndo->ndo_ll_hdr_len += l2info.header_len;
936c74ad251Schristos                 return;
9370f74e101Schristos             default:
9380f74e101Schristos                 break;
9390f74e101Schristos             }
940c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
941c74ad251Schristos             return;
9420f74e101Schristos         }
9430f74e101Schristos 
9440f74e101Schristos         /* suppress Bundle-ID if frame was captured on a child-link */
945c74ad251Schristos         /* use EXTRACT_, not GET_ (not packet buffer pointer) */
946c74ad251Schristos         if (ndo->ndo_eflag && EXTRACT_BE_U_4(l2info.cookie) != 1)
947c74ad251Schristos             ND_PRINT("Bundle-ID %u, ", l2info.bundle);
9480f74e101Schristos         switch (l2info.proto) {
9490f74e101Schristos         case (LLCSAP_ISONS<<8 | LLCSAP_ISONS):
950c74ad251Schristos             /* At least one byte is required */
951c74ad251Schristos             ND_TCHECK_LEN(p, 1);
95272c96ff3Schristos             isoclns_print(ndo, p + 1, l2info.length - 1);
9530f74e101Schristos             break;
9540f74e101Schristos         case (LLC_UI<<8 | NLPID_Q933):
9550f74e101Schristos         case (LLC_UI<<8 | NLPID_IP):
9560f74e101Schristos         case (LLC_UI<<8 | NLPID_IP6):
9570f74e101Schristos             /* pass IP{4,6} to the OSI layer for proper link-layer printing */
95872c96ff3Schristos             isoclns_print(ndo, p - 1, l2info.length + 1);
9590f74e101Schristos             break;
9600f74e101Schristos         default:
961c74ad251Schristos             ND_PRINT("unknown protocol 0x%04x, length %u", l2info.proto, l2info.length);
9620f74e101Schristos         }
9630f74e101Schristos 
964c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
9650f74e101Schristos }
9660f74e101Schristos #endif
9670f74e101Schristos 
9680f74e101Schristos #ifdef DLT_JUNIPER_MLFR
969c74ad251Schristos void
970c74ad251Schristos juniper_mlfr_if_print(netdissect_options *ndo,
971c74ad251Schristos                       const struct pcap_pkthdr *h, const u_char *p)
9720f74e101Schristos {
9730f74e101Schristos         struct juniper_l2info_t l2info;
9740f74e101Schristos 
975c74ad251Schristos         ndo->ndo_protocol = "juniper_mlfr";
976c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
9770f74e101Schristos         l2info.pictype = DLT_JUNIPER_MLFR;
978c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
979c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
980c74ad251Schristos             return;
981c74ad251Schristos         }
9820f74e101Schristos 
9830f74e101Schristos         p+=l2info.header_len;
9840f74e101Schristos 
9850f74e101Schristos         /* suppress Bundle-ID if frame was captured on a child-link */
986c74ad251Schristos         /* use EXTRACT_, not GET_ (not packet buffer pointer) */
987c74ad251Schristos         if (ndo->ndo_eflag && EXTRACT_BE_U_4(l2info.cookie) != 1)
988c74ad251Schristos             ND_PRINT("Bundle-ID %u, ", l2info.bundle);
9890f74e101Schristos         switch (l2info.proto) {
9900f74e101Schristos         case (LLC_UI):
9910f74e101Schristos         case (LLC_UI<<8):
99272c96ff3Schristos             isoclns_print(ndo, p, l2info.length);
9930f74e101Schristos             break;
9940f74e101Schristos         case (LLC_UI<<8 | NLPID_Q933):
9950f74e101Schristos         case (LLC_UI<<8 | NLPID_IP):
9960f74e101Schristos         case (LLC_UI<<8 | NLPID_IP6):
9970f74e101Schristos             /* pass IP{4,6} to the OSI layer for proper link-layer printing */
99872c96ff3Schristos             isoclns_print(ndo, p - 1, l2info.length + 1);
9990f74e101Schristos             break;
10000f74e101Schristos         default:
1001c74ad251Schristos             ND_PRINT("unknown protocol 0x%04x, length %u", l2info.proto, l2info.length);
10020f74e101Schristos         }
10030f74e101Schristos 
1004c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
10050f74e101Schristos }
10060f74e101Schristos #endif
10070f74e101Schristos 
10080f74e101Schristos /*
10090f74e101Schristos  *     ATM1 PIC cookie format
10100f74e101Schristos  *
10110f74e101Schristos  *     +-----+-------------------------+-------------------------------+
10120f74e101Schristos  *     |fmtid|     vc index            |  channel  ID                  |
10130f74e101Schristos  *     +-----+-------------------------+-------------------------------+
10140f74e101Schristos  */
10150f74e101Schristos 
10160f74e101Schristos #ifdef DLT_JUNIPER_ATM1
1017c74ad251Schristos void
1018c74ad251Schristos juniper_atm1_if_print(netdissect_options *ndo,
1019c74ad251Schristos                       const struct pcap_pkthdr *h, const u_char *p)
10200f74e101Schristos {
1021fdccd7e4Schristos         int llc_hdrlen;
10220f74e101Schristos 
10230f74e101Schristos         struct juniper_l2info_t l2info;
10240f74e101Schristos 
1025c74ad251Schristos         ndo->ndo_protocol = "juniper_atm1";
1026c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
10270f74e101Schristos         l2info.pictype = DLT_JUNIPER_ATM1;
1028c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
1029c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1030c74ad251Schristos             return;
1031c74ad251Schristos         }
10320f74e101Schristos 
10330f74e101Schristos         p+=l2info.header_len;
10340f74e101Schristos 
10350f74e101Schristos         if (l2info.cookie[0] == 0x80) { /* OAM cell ? */
1036b3a00663Schristos             oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC);
1037c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1038c74ad251Schristos             return;
10390f74e101Schristos         }
10400f74e101Schristos 
1041c74ad251Schristos         if (GET_BE_U_3(p) == 0xfefe03 || /* NLPID encaps ? */
1042c74ad251Schristos             GET_BE_U_3(p) == 0xaaaa03) { /* SNAP encaps ? */
10430f74e101Schristos 
1044fdccd7e4Schristos             llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
1045c74ad251Schristos             if (llc_hdrlen > 0) {
1046c74ad251Schristos                 ndo->ndo_ll_hdr_len += l2info.header_len;
1047c74ad251Schristos                 return;
1048c74ad251Schristos             }
10490f74e101Schristos         }
10500f74e101Schristos 
1051c74ad251Schristos         if (GET_U_1(p) == 0x03) { /* Cisco style NLPID encaps ? */
1052c74ad251Schristos             /* At least one byte is required */
1053c74ad251Schristos             ND_TCHECK_LEN(p, 1);
105472c96ff3Schristos             isoclns_print(ndo, p + 1, l2info.length - 1);
10550f74e101Schristos             /* FIXME check if frame was recognized */
1056c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1057c74ad251Schristos             return;
10580f74e101Schristos         }
10590f74e101Schristos 
1060c74ad251Schristos         if (ip_heuristic_guess(ndo, p, l2info.length) != 0) { /* last try - vcmux encaps ? */
1061c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1062c74ad251Schristos             return;
1063c74ad251Schristos         }
10640f74e101Schristos 
1065c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
10660f74e101Schristos }
10670f74e101Schristos #endif
10680f74e101Schristos 
10690f74e101Schristos /*
10700f74e101Schristos  *     ATM2 PIC cookie format
10710f74e101Schristos  *
10720f74e101Schristos  *     +-------------------------------+---------+---+-----+-----------+
10730f74e101Schristos  *     |     channel ID                |  reserv |AAL| CCRQ| gap cnt   |
10740f74e101Schristos  *     +-------------------------------+---------+---+-----+-----------+
10750f74e101Schristos  */
10760f74e101Schristos 
10770f74e101Schristos #ifdef DLT_JUNIPER_ATM2
1078c74ad251Schristos void
1079c74ad251Schristos juniper_atm2_if_print(netdissect_options *ndo,
1080c74ad251Schristos                       const struct pcap_pkthdr *h, const u_char *p)
10810f74e101Schristos {
1082fdccd7e4Schristos         int llc_hdrlen;
10830f74e101Schristos 
10840f74e101Schristos         struct juniper_l2info_t l2info;
10850f74e101Schristos 
1086c74ad251Schristos         ndo->ndo_protocol = "juniper_atm2";
1087c74ad251Schristos         memset(&l2info, 0, sizeof(l2info));
10880f74e101Schristos         l2info.pictype = DLT_JUNIPER_ATM2;
1089c74ad251Schristos         if (juniper_parse_header(ndo, p, h, &l2info) == 0) {
1090c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1091c74ad251Schristos             return;
1092c74ad251Schristos         }
10930f74e101Schristos 
10940f74e101Schristos         p+=l2info.header_len;
10950f74e101Schristos 
10960f74e101Schristos         if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */
1097b3a00663Schristos             oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC);
1098c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1099c74ad251Schristos             return;
11000f74e101Schristos         }
11010f74e101Schristos 
1102c74ad251Schristos         if (GET_BE_U_3(p) == 0xfefe03 || /* NLPID encaps ? */
1103c74ad251Schristos             GET_BE_U_3(p) == 0xaaaa03) { /* SNAP encaps ? */
11040f74e101Schristos 
1105fdccd7e4Schristos             llc_hdrlen = llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
1106c74ad251Schristos             if (llc_hdrlen > 0) {
1107c74ad251Schristos                 ndo->ndo_ll_hdr_len += l2info.header_len;
1108c74ad251Schristos                 return;
1109c74ad251Schristos             }
11100f74e101Schristos         }
11110f74e101Schristos 
11120f74e101Schristos         if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */
1113c74ad251Schristos             /* use EXTRACT_, not GET_ (not packet buffer pointer) */
1114c74ad251Schristos             (EXTRACT_BE_U_4(l2info.cookie) & ATM2_GAP_COUNT_MASK)) {
1115b3a00663Schristos             ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
1116c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1117c74ad251Schristos             return;
11180f74e101Schristos         }
11190f74e101Schristos 
1120c74ad251Schristos         if (GET_U_1(p) == 0x03) { /* Cisco style NLPID encaps ? */
1121c74ad251Schristos             /* At least one byte is required */
1122c74ad251Schristos             ND_TCHECK_LEN(p, 1);
112372c96ff3Schristos             isoclns_print(ndo, p + 1, l2info.length - 1);
11240f74e101Schristos             /* FIXME check if frame was recognized */
1125c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1126c74ad251Schristos             return;
11270f74e101Schristos         }
11280f74e101Schristos 
1129c74ad251Schristos         if(juniper_ppp_heuristic_guess(ndo, p, l2info.length) != 0) { /* PPPoA vcmux encaps ? */
1130c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1131c74ad251Schristos             return;
11320f74e101Schristos         }
11330f74e101Schristos 
1134c74ad251Schristos         if (ip_heuristic_guess(ndo, p, l2info.length) != 0) { /* last try - vcmux encaps ? */
1135c74ad251Schristos             ndo->ndo_ll_hdr_len += l2info.header_len;
1136c74ad251Schristos             return;
1137c74ad251Schristos         }
1138c74ad251Schristos 
1139c74ad251Schristos         ndo->ndo_ll_hdr_len += l2info.header_len;
1140c74ad251Schristos }
11410f74e101Schristos 
11420f74e101Schristos /* try to guess, based on all PPP protos that are supported in
11430f74e101Schristos  * a juniper router if the payload data is encapsulated using PPP */
1144b3a00663Schristos static int
1145b3a00663Schristos juniper_ppp_heuristic_guess(netdissect_options *ndo,
1146c74ad251Schristos                             const u_char *p, u_int length)
1147ba2ff121Schristos {
1148c74ad251Schristos     switch(GET_BE_U_2(p)) {
11490f74e101Schristos     case PPP_IP :
11500f74e101Schristos     case PPP_OSI :
11510f74e101Schristos     case PPP_MPLS_UCAST :
11520f74e101Schristos     case PPP_MPLS_MCAST :
11530f74e101Schristos     case PPP_IPCP :
11540f74e101Schristos     case PPP_OSICP :
11550f74e101Schristos     case PPP_MPLSCP :
11560f74e101Schristos     case PPP_LCP :
11570f74e101Schristos     case PPP_PAP :
11580f74e101Schristos     case PPP_CHAP :
11590f74e101Schristos     case PPP_ML :
11600f74e101Schristos     case PPP_IPV6 :
11610f74e101Schristos     case PPP_IPV6CP :
1162b3a00663Schristos         ppp_print(ndo, p, length);
11630f74e101Schristos         break;
11640f74e101Schristos 
11650f74e101Schristos     default:
11660f74e101Schristos         return 0; /* did not find a ppp header */
11670f74e101Schristos         break;
11680f74e101Schristos     }
11690f74e101Schristos     return 1; /* we printed a ppp packet */
11700f74e101Schristos }
1171c74ad251Schristos #endif
11720f74e101Schristos 
1173b3a00663Schristos static int
1174b3a00663Schristos ip_heuristic_guess(netdissect_options *ndo,
1175c74ad251Schristos                    const u_char *p, u_int length)
1176ba2ff121Schristos {
1177c74ad251Schristos     switch(GET_U_1(p)) {
11780f74e101Schristos     case 0x45:
11790f74e101Schristos     case 0x46:
11800f74e101Schristos     case 0x47:
11810f74e101Schristos     case 0x48:
11820f74e101Schristos     case 0x49:
11830f74e101Schristos     case 0x4a:
11840f74e101Schristos     case 0x4b:
11850f74e101Schristos     case 0x4c:
11860f74e101Schristos     case 0x4d:
11870f74e101Schristos     case 0x4e:
11880f74e101Schristos     case 0x4f:
1189b3a00663Schristos         ip_print(ndo, p, length);
11900f74e101Schristos         break;
11910f74e101Schristos     case 0x60:
11920f74e101Schristos     case 0x61:
11930f74e101Schristos     case 0x62:
11940f74e101Schristos     case 0x63:
11950f74e101Schristos     case 0x64:
11960f74e101Schristos     case 0x65:
11970f74e101Schristos     case 0x66:
11980f74e101Schristos     case 0x67:
11990f74e101Schristos     case 0x68:
12000f74e101Schristos     case 0x69:
12010f74e101Schristos     case 0x6a:
12020f74e101Schristos     case 0x6b:
12030f74e101Schristos     case 0x6c:
12040f74e101Schristos     case 0x6d:
12050f74e101Schristos     case 0x6e:
12060f74e101Schristos     case 0x6f:
1207b3a00663Schristos         ip6_print(ndo, p, length);
12080f74e101Schristos         break;
12090f74e101Schristos     default:
12100f74e101Schristos         return 0; /* did not find a ip header */
12110f74e101Schristos         break;
12120f74e101Schristos     }
12130f74e101Schristos     return 1; /* we printed an v4/v6 packet */
12140f74e101Schristos }
12150f74e101Schristos 
1216b3a00663Schristos static int
1217c74ad251Schristos juniper_read_tlv_value(netdissect_options *ndo,
1218c74ad251Schristos 		       const u_char *p, u_int tlv_type, u_int tlv_len)
1219ba2ff121Schristos {
12200f74e101Schristos    int tlv_value;
12210f74e101Schristos 
12220f74e101Schristos    /* TLVs < 128 are little endian encoded */
12230f74e101Schristos    if (tlv_type < 128) {
12240f74e101Schristos        switch (tlv_len) {
12250f74e101Schristos        case 1:
1226c74ad251Schristos            tlv_value = GET_U_1(p);
12270f74e101Schristos            break;
12280f74e101Schristos        case 2:
1229c74ad251Schristos            tlv_value = GET_LE_U_2(p);
12300f74e101Schristos            break;
12310f74e101Schristos        case 3:
1232c74ad251Schristos            tlv_value = GET_LE_U_3(p);
12330f74e101Schristos            break;
12340f74e101Schristos        case 4:
1235c74ad251Schristos            tlv_value = GET_LE_U_4(p);
12360f74e101Schristos            break;
12370f74e101Schristos        default:
12380f74e101Schristos            tlv_value = -1;
12390f74e101Schristos            break;
12400f74e101Schristos        }
12410f74e101Schristos    } else {
12420f74e101Schristos        /* TLVs >= 128 are big endian encoded */
12430f74e101Schristos        switch (tlv_len) {
12440f74e101Schristos        case 1:
1245c74ad251Schristos            tlv_value = GET_U_1(p);
12460f74e101Schristos            break;
12470f74e101Schristos        case 2:
1248c74ad251Schristos            tlv_value = GET_BE_U_2(p);
12490f74e101Schristos            break;
12500f74e101Schristos        case 3:
1251c74ad251Schristos            tlv_value = GET_BE_U_3(p);
12520f74e101Schristos            break;
12530f74e101Schristos        case 4:
1254c74ad251Schristos            tlv_value = GET_BE_U_4(p);
12550f74e101Schristos            break;
12560f74e101Schristos        default:
12570f74e101Schristos            tlv_value = -1;
12580f74e101Schristos            break;
12590f74e101Schristos        }
12600f74e101Schristos    }
12610f74e101Schristos    return tlv_value;
12620f74e101Schristos }
12630f74e101Schristos 
12640f74e101Schristos static int
1265b3a00663Schristos juniper_parse_header(netdissect_options *ndo,
1266ba2ff121Schristos                      const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info)
1267ba2ff121Schristos {
1268c74ad251Schristos     const struct juniper_cookie_table_t *lp;
1269c74ad251Schristos     u_int idx, extension_length, jnx_header_len = 0;
1270b3a00663Schristos     uint8_t tlv_type,tlv_len;
1271c74ad251Schristos #ifdef DLT_JUNIPER_ATM2
1272b3a00663Schristos     uint32_t control_word;
1273c74ad251Schristos #endif
12740f74e101Schristos     int tlv_value;
12750f74e101Schristos     const u_char *tptr;
12760f74e101Schristos 
12770f74e101Schristos 
12780f74e101Schristos     l2info->header_len = 0;
12790f74e101Schristos     l2info->cookie_len = 0;
12800f74e101Schristos     l2info->proto = 0;
12810f74e101Schristos 
12820f74e101Schristos 
12830f74e101Schristos     l2info->length = h->len;
12840f74e101Schristos     l2info->caplen = h->caplen;
1285c74ad251Schristos     l2info->flags = GET_U_1(p + 3);
1286c74ad251Schristos     l2info->direction = GET_U_1(p + 3) & JUNIPER_BPF_PKT_IN;
12870f74e101Schristos 
1288c74ad251Schristos     if (GET_BE_U_3(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
1289c74ad251Schristos         ND_PRINT("no magic-number found!");
12900f74e101Schristos         return 0;
12910f74e101Schristos     }
12920f74e101Schristos 
1293b3a00663Schristos     if (ndo->ndo_eflag) /* print direction */
1294c74ad251Schristos         ND_PRINT("%3s ", tok2str(juniper_direction_values, "---", l2info->direction));
12950f74e101Schristos 
12960f74e101Schristos     /* magic number + flags */
12970f74e101Schristos     jnx_header_len = 4;
12980f74e101Schristos 
1299b3a00663Schristos     if (ndo->ndo_vflag > 1)
1300c74ad251Schristos         ND_PRINT("\n\tJuniper PCAP Flags [%s]",
1301c74ad251Schristos                bittok2str(jnx_flag_values, "none", l2info->flags));
13020f74e101Schristos 
13030f74e101Schristos     /* extensions present ?  - calculate how much bytes to skip */
13040f74e101Schristos     if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {
13050f74e101Schristos 
13060f74e101Schristos         tptr = p+jnx_header_len;
13070f74e101Schristos 
13080f74e101Schristos         /* ok to read extension length ? */
1309c74ad251Schristos         extension_length = GET_BE_U_2(tptr);
13100f74e101Schristos         jnx_header_len += 2;
13110f74e101Schristos         tptr +=2;
13120f74e101Schristos 
13130f74e101Schristos         /* nail up the total length -
13140f74e101Schristos          * just in case something goes wrong
13150f74e101Schristos          * with TLV parsing */
1316c74ad251Schristos         jnx_header_len += extension_length;
13170f74e101Schristos 
1318b3a00663Schristos         if (ndo->ndo_vflag > 1)
1319c74ad251Schristos             ND_PRINT(", PCAP Extension(s) total length %u", extension_length);
13200f74e101Schristos 
1321c74ad251Schristos         ND_TCHECK_LEN(tptr, extension_length);
1322c74ad251Schristos         while (extension_length > JUNIPER_EXT_TLV_OVERHEAD) {
1323c74ad251Schristos             tlv_type = GET_U_1(tptr);
1324c74ad251Schristos             tptr++;
1325c74ad251Schristos             tlv_len = GET_U_1(tptr);
1326c74ad251Schristos             tptr++;
13270f74e101Schristos             tlv_value = 0;
13280f74e101Schristos 
1329dc860a36Sspz             /* sanity checks */
13300f74e101Schristos             if (tlv_type == 0 || tlv_len == 0)
13310f74e101Schristos                 break;
1332*26ba0b50Schristos             ND_ICHECK_U(extension_length, <,
1333*26ba0b50Schristos                         tlv_len + JUNIPER_EXT_TLV_OVERHEAD);
13340f74e101Schristos 
1335b3a00663Schristos             if (ndo->ndo_vflag > 1)
1336c74ad251Schristos                 ND_PRINT("\n\t  %s Extension TLV #%u, length %u, value ",
13370f74e101Schristos                        tok2str(jnx_ext_tlv_values,"Unknown",tlv_type),
13380f74e101Schristos                        tlv_type,
1339c74ad251Schristos                        tlv_len);
13400f74e101Schristos 
1341c74ad251Schristos             tlv_value = juniper_read_tlv_value(ndo, tptr, tlv_type, tlv_len);
13420f74e101Schristos             switch (tlv_type) {
13430f74e101Schristos             case JUNIPER_EXT_TLV_IFD_NAME:
13440f74e101Schristos                 /* FIXME */
13450f74e101Schristos                 break;
13460f74e101Schristos             case JUNIPER_EXT_TLV_IFD_MEDIATYPE:
13470f74e101Schristos             case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE:
13480f74e101Schristos                 if (tlv_value != -1) {
1349b3a00663Schristos                     if (ndo->ndo_vflag > 1)
1350c74ad251Schristos                         ND_PRINT("%s (%u)",
13510f74e101Schristos                                tok2str(juniper_ifmt_values, "Unknown", tlv_value),
1352c74ad251Schristos                                tlv_value);
13530f74e101Schristos                 }
13540f74e101Schristos                 break;
13550f74e101Schristos             case JUNIPER_EXT_TLV_IFL_ENCAPS:
13560f74e101Schristos             case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS:
13570f74e101Schristos                 if (tlv_value != -1) {
1358b3a00663Schristos                     if (ndo->ndo_vflag > 1)
1359c74ad251Schristos                         ND_PRINT("%s (%u)",
13600f74e101Schristos                                tok2str(juniper_ifle_values, "Unknown", tlv_value),
1361c74ad251Schristos                                tlv_value);
13620f74e101Schristos                 }
13630f74e101Schristos                 break;
13640f74e101Schristos             case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */
13650f74e101Schristos             case JUNIPER_EXT_TLV_IFL_UNIT:
13660f74e101Schristos             case JUNIPER_EXT_TLV_IFD_IDX:
13670f74e101Schristos             default:
13680f74e101Schristos                 if (tlv_value != -1) {
1369b3a00663Schristos                     if (ndo->ndo_vflag > 1)
1370c74ad251Schristos                         ND_PRINT("%u", tlv_value);
13710f74e101Schristos                 }
13720f74e101Schristos                 break;
13730f74e101Schristos             }
13740f74e101Schristos 
13750f74e101Schristos             tptr+=tlv_len;
1376c74ad251Schristos             extension_length -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD;
13770f74e101Schristos         }
13780f74e101Schristos 
1379b3a00663Schristos         if (ndo->ndo_vflag > 1)
1380c74ad251Schristos             ND_PRINT("\n\t-----original packet-----\n\t");
13810f74e101Schristos     }
13820f74e101Schristos 
13830f74e101Schristos     if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {
1384b3a00663Schristos         if (ndo->ndo_eflag)
1385c74ad251Schristos             ND_PRINT("no-L2-hdr, ");
13860f74e101Schristos 
13870f74e101Schristos         /* there is no link-layer present -
13880f74e101Schristos          * perform the v4/v6 heuristics
13890f74e101Schristos          * to figure out what it is
13900f74e101Schristos          */
1391c74ad251Schristos         ND_TCHECK_1(p + (jnx_header_len + 4));
1392b3a00663Schristos         if (ip_heuristic_guess(ndo, p + jnx_header_len + 4,
1393b3a00663Schristos                                l2info->length - (jnx_header_len + 4)) == 0)
1394c74ad251Schristos             ND_PRINT("no IP-hdr found!");
13950f74e101Schristos 
13960f74e101Schristos         l2info->header_len=jnx_header_len+4;
13970f74e101Schristos         return 0; /* stop parsing the output further */
13980f74e101Schristos 
13990f74e101Schristos     }
14000f74e101Schristos     l2info->header_len = jnx_header_len;
14010f74e101Schristos     p+=l2info->header_len;
14020f74e101Schristos     l2info->length -= l2info->header_len;
14030f74e101Schristos     l2info->caplen -= l2info->header_len;
14040f74e101Schristos 
1405c74ad251Schristos     /* search through the cookie table for one matching our PIC type */
1406c74ad251Schristos     lp = NULL;
1407c74ad251Schristos     for (const struct juniper_cookie_table_t *table_lp = juniper_cookie_table;
1408c74ad251Schristos          table_lp->s != NULL; table_lp++) {
1409c74ad251Schristos         if (table_lp->pictype == l2info->pictype) {
1410c74ad251Schristos             lp = table_lp;
1411c74ad251Schristos             break;
1412c74ad251Schristos         }
1413c74ad251Schristos     }
14140f74e101Schristos 
1415c74ad251Schristos     /* If we found one matching our PIC type, copy its values */
1416c74ad251Schristos     if (lp != NULL) {
14170f74e101Schristos         l2info->cookie_len += lp->cookie_len;
14180f74e101Schristos 
1419c74ad251Schristos         switch (GET_U_1(p)) {
14200f74e101Schristos         case LS_COOKIE_ID:
14210f74e101Schristos             l2info->cookie_type = LS_COOKIE_ID;
14220f74e101Schristos             l2info->cookie_len += 2;
14230f74e101Schristos             break;
14240f74e101Schristos         case AS_COOKIE_ID:
14250f74e101Schristos             l2info->cookie_type = AS_COOKIE_ID;
14260f74e101Schristos             l2info->cookie_len = 8;
14270f74e101Schristos             break;
14280f74e101Schristos 
14290f74e101Schristos         default:
14300f74e101Schristos             l2info->bundle = l2info->cookie[0];
14310f74e101Schristos             break;
14320f74e101Schristos         }
14330f74e101Schristos 
14340f74e101Schristos 
14350f74e101Schristos #ifdef DLT_JUNIPER_MFR
14360f74e101Schristos         /* MFR child links don't carry cookies */
14370f74e101Schristos         if (l2info->pictype == DLT_JUNIPER_MFR &&
1438c74ad251Schristos             (GET_U_1(p) & MFR_BE_MASK) == MFR_BE_MASK) {
14390f74e101Schristos             l2info->cookie_len = 0;
14400f74e101Schristos         }
14410f74e101Schristos #endif
14420f74e101Schristos 
14430f74e101Schristos         l2info->header_len += l2info->cookie_len;
14440f74e101Schristos         l2info->length -= l2info->cookie_len;
14450f74e101Schristos         l2info->caplen -= l2info->cookie_len;
14460f74e101Schristos 
1447b3a00663Schristos         if (ndo->ndo_eflag)
1448c74ad251Schristos             ND_PRINT("%s-PIC, cookie-len %u",
14490f74e101Schristos                    lp->s,
1450c74ad251Schristos                    l2info->cookie_len);
14510f74e101Schristos 
1452817e9a7eSchristos         if (l2info->cookie_len > 8) {
1453c74ad251Schristos             nd_print_invalid(ndo);
1454817e9a7eSchristos             return 0;
1455817e9a7eSchristos         }
1456817e9a7eSchristos 
14570f74e101Schristos         if (l2info->cookie_len > 0) {
1458c74ad251Schristos             ND_TCHECK_LEN(p, l2info->cookie_len);
1459b3a00663Schristos             if (ndo->ndo_eflag)
1460c74ad251Schristos                 ND_PRINT(", cookie 0x");
14610f74e101Schristos             for (idx = 0; idx < l2info->cookie_len; idx++) {
1462c74ad251Schristos                 l2info->cookie[idx] = GET_U_1(p + idx); /* copy cookie data */
1463c74ad251Schristos                 if (ndo->ndo_eflag) ND_PRINT("%02x", GET_U_1(p + idx));
14640f74e101Schristos             }
14650f74e101Schristos         }
14660f74e101Schristos 
1467c74ad251Schristos         if (ndo->ndo_eflag) ND_PRINT(": "); /* print demarc b/w L2/L3*/
14680f74e101Schristos 
14690f74e101Schristos 
1470c74ad251Schristos         l2info->proto = GET_BE_U_2(p + l2info->cookie_len);
14710f74e101Schristos     }
14720f74e101Schristos     p+=l2info->cookie_len;
14730f74e101Schristos 
14740f74e101Schristos     /* DLT_ specific parsing */
14750f74e101Schristos     switch(l2info->pictype) {
14760f74e101Schristos #ifdef DLT_JUNIPER_MLPPP
14770f74e101Schristos     case DLT_JUNIPER_MLPPP:
14780f74e101Schristos         switch (l2info->cookie_type) {
14790f74e101Schristos         case LS_COOKIE_ID:
14800f74e101Schristos             l2info->bundle = l2info->cookie[1];
14810f74e101Schristos             break;
14820f74e101Schristos         case AS_COOKIE_ID:
1483c74ad251Schristos             /* use EXTRACT_, not GET_ (not packet buffer pointer) */
1484c74ad251Schristos             l2info->bundle = (EXTRACT_BE_U_2(&l2info->cookie[6])>>3)&0xfff;
14850f74e101Schristos             l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
14860f74e101Schristos             break;
14870f74e101Schristos         default:
14880f74e101Schristos             l2info->bundle = l2info->cookie[0];
14890f74e101Schristos             break;
14900f74e101Schristos         }
14910f74e101Schristos         break;
14920f74e101Schristos #endif
14930f74e101Schristos #ifdef DLT_JUNIPER_MLFR
14940f74e101Schristos     case DLT_JUNIPER_MLFR:
14950f74e101Schristos         switch (l2info->cookie_type) {
14960f74e101Schristos         case LS_COOKIE_ID:
14970f74e101Schristos             l2info->bundle = l2info->cookie[1];
1498c74ad251Schristos             l2info->proto = GET_BE_U_2(p);
14990f74e101Schristos             l2info->header_len += 2;
15000f74e101Schristos             l2info->length -= 2;
15010f74e101Schristos             l2info->caplen -= 2;
15020f74e101Schristos             break;
15030f74e101Schristos         case AS_COOKIE_ID:
1504c74ad251Schristos             /* use EXTRACT_, not GET_ (not packet buffer pointer) */
1505c74ad251Schristos             l2info->bundle = (EXTRACT_BE_U_2(&l2info->cookie[6])>>3)&0xfff;
15060f74e101Schristos             l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
15070f74e101Schristos             break;
15080f74e101Schristos         default:
15090f74e101Schristos             l2info->bundle = l2info->cookie[0];
15100f74e101Schristos             l2info->header_len += 2;
15110f74e101Schristos             l2info->length -= 2;
15120f74e101Schristos             l2info->caplen -= 2;
15130f74e101Schristos             break;
15140f74e101Schristos         }
15150f74e101Schristos         break;
15160f74e101Schristos #endif
15170f74e101Schristos #ifdef DLT_JUNIPER_MFR
15180f74e101Schristos     case DLT_JUNIPER_MFR:
15190f74e101Schristos         switch (l2info->cookie_type) {
15200f74e101Schristos         case LS_COOKIE_ID:
15210f74e101Schristos             l2info->bundle = l2info->cookie[1];
1522c74ad251Schristos             l2info->proto = GET_BE_U_2(p);
15230f74e101Schristos             l2info->header_len += 2;
15240f74e101Schristos             l2info->length -= 2;
15250f74e101Schristos             l2info->caplen -= 2;
15260f74e101Schristos             break;
15270f74e101Schristos         case AS_COOKIE_ID:
1528c74ad251Schristos             /* use EXTRACT_, not GET_ (not packet buffer pointer) */
1529c74ad251Schristos             l2info->bundle = (EXTRACT_BE_U_2(&l2info->cookie[6])>>3)&0xfff;
15300f74e101Schristos             l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
15310f74e101Schristos             break;
15320f74e101Schristos         default:
15330f74e101Schristos             l2info->bundle = l2info->cookie[0];
15340f74e101Schristos             break;
15350f74e101Schristos         }
15360f74e101Schristos         break;
15370f74e101Schristos #endif
15380f74e101Schristos #ifdef DLT_JUNIPER_ATM2
15390f74e101Schristos     case DLT_JUNIPER_ATM2:
1540c74ad251Schristos         ND_TCHECK_4(p);
15410f74e101Schristos         /* ATM cell relay control word present ? */
15420f74e101Schristos         if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
1543c74ad251Schristos             control_word = GET_BE_U_4(p);
15440f74e101Schristos             /* some control word heuristics */
15450f74e101Schristos             switch(control_word) {
15460f74e101Schristos             case 0: /* zero control word */
15470f74e101Schristos             case 0x08000000: /* < JUNOS 7.4 control-word */
15480f74e101Schristos             case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
15490f74e101Schristos                 l2info->header_len += 4;
15500f74e101Schristos                 break;
15510f74e101Schristos             default:
15520f74e101Schristos                 break;
15530f74e101Schristos             }
15540f74e101Schristos 
1555b3a00663Schristos             if (ndo->ndo_eflag)
1556c74ad251Schristos                 ND_PRINT("control-word 0x%08x ", control_word);
15570f74e101Schristos         }
15580f74e101Schristos         break;
15590f74e101Schristos #endif
1560c74ad251Schristos #ifdef DLT_JUNIPER_ES
1561c74ad251Schristos     case DLT_JUNIPER_ES:
1562c74ad251Schristos         break;
1563c74ad251Schristos #endif
15640f74e101Schristos #ifdef DLT_JUNIPER_GGSN
15650f74e101Schristos     case DLT_JUNIPER_GGSN:
15660f74e101Schristos         break;
15670f74e101Schristos #endif
1568c74ad251Schristos #ifdef DLT_JUNIPER_SERVICES
1569c74ad251Schristos     case DLT_JUNIPER_SERVICES:
1570c74ad251Schristos         break;
1571c74ad251Schristos #endif
15720f74e101Schristos #ifdef DLT_JUNIPER_ATM1
15730f74e101Schristos     case DLT_JUNIPER_ATM1:
15740f74e101Schristos         break;
15750f74e101Schristos #endif
15760f74e101Schristos #ifdef DLT_JUNIPER_PPP
15770f74e101Schristos     case DLT_JUNIPER_PPP:
15780f74e101Schristos         break;
15790f74e101Schristos #endif
15800f74e101Schristos #ifdef DLT_JUNIPER_CHDLC
15810f74e101Schristos     case DLT_JUNIPER_CHDLC:
15820f74e101Schristos         break;
15830f74e101Schristos #endif
15840f74e101Schristos #ifdef DLT_JUNIPER_ETHER
15850f74e101Schristos     case DLT_JUNIPER_ETHER:
15860f74e101Schristos         break;
15870f74e101Schristos #endif
15880f74e101Schristos #ifdef DLT_JUNIPER_FRELAY
15890f74e101Schristos     case DLT_JUNIPER_FRELAY:
15900f74e101Schristos         break;
15910f74e101Schristos #endif
1592c74ad251Schristos #ifdef DLT_JUNIPER_MONITOR
1593c74ad251Schristos     case DLT_JUNIPER_MONITOR:
1594c74ad251Schristos         break;
1595c74ad251Schristos #endif
1596c74ad251Schristos #ifdef DLT_JUNIPER_PPPOE
1597c74ad251Schristos     case DLT_JUNIPER_PPPOE:
1598c74ad251Schristos         break;
1599c74ad251Schristos #endif
1600c74ad251Schristos #ifdef DLT_JUNIPER_PPPOE_ATM
1601c74ad251Schristos     case DLT_JUNIPER_PPPOE_ATM:
1602c74ad251Schristos         break;
1603c74ad251Schristos #endif
16040f74e101Schristos 
16050f74e101Schristos     default:
1606c74ad251Schristos         ND_PRINT("Unknown Juniper DLT_ type %u: ", l2info->pictype);
16070f74e101Schristos         break;
16080f74e101Schristos     }
16090f74e101Schristos 
1610c74ad251Schristos     if (ndo->ndo_eflag)
1611c74ad251Schristos         ND_PRINT("hlen %u, proto 0x%04x, ", l2info->header_len, l2info->proto);
16120f74e101Schristos 
16130f74e101Schristos     return 1; /* everything went ok so far. continue parsing */
1614c74ad251Schristos invalid:
1615c74ad251Schristos     nd_print_invalid(ndo);
16160f74e101Schristos     return 0;
16170f74e101Schristos }
1618c74ad251Schristos #endif /* defined(DLT_JUNIPER_GGSN) || defined(DLT_JUNIPER_ES) || \
1619c74ad251Schristos           defined(DLT_JUNIPER_MONITOR) || defined(DLT_JUNIPER_SERVICES) || \
1620c74ad251Schristos           defined(DLT_JUNIPER_PPPOE) || defined(DLT_JUNIPER_ETHER) || \
1621c74ad251Schristos           defined(DLT_JUNIPER_PPP) || defined(DLT_JUNIPER_FRELAY) || \
1622c74ad251Schristos           defined(DLT_JUNIPER_CHDLC) || defined(DLT_JUNIPER_PPPOE_ATM) || \
1623c74ad251Schristos           defined(DLT_JUNIPER_MLPPP) || defined(DLT_JUNIPER_MFR) || \
1624c74ad251Schristos           defined(DLT_JUNIPER_MLFR) || defined(DLT_JUNIPER_ATM1) || \
1625c74ad251Schristos           defined(DLT_JUNIPER_ATM2) */
1626