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