1 /* 2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 /* \summary: Broadcom LI Printer */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include "netdissect-stdinc.h" 29 30 #define ND_LONGJMP_FROM_TCHECK 31 #include "netdissect.h" 32 #include "addrtoname.h" 33 #include "extract.h" 34 35 #define BCM_LI_SHIM_LEN 4 36 37 static const struct tok bcm_li_direction_values[] = { 38 { 1, "unused" }, 39 { 2, "egress" }, 40 { 3, "ingress" }, 41 { 0, NULL} 42 }; 43 44 #define BCM_LI_PKT_TYPE_UNDECIDED 4 45 #define BCM_LI_PKT_TYPE_IPV4 5 46 #define BCM_LI_PKT_TYPE_IPV6 6 47 #define BCM_LI_PKT_TYPE_ETHERNET 7 48 49 static const struct tok bcm_li_pkt_type_values[] = { 50 { BCM_LI_PKT_TYPE_UNDECIDED, "undecided" }, 51 { BCM_LI_PKT_TYPE_IPV4, "ipv4" }, 52 { BCM_LI_PKT_TYPE_IPV6, "ipv6" }, 53 { BCM_LI_PKT_TYPE_ETHERNET, "ethernet" }, 54 { 0, NULL} 55 }; 56 57 static const struct tok bcm_li_pkt_subtype_values[] = { 58 { 1, "single VLAN tag" }, 59 { 2, "double VLAN tag" }, 60 { 3, "untagged" }, 61 { 0, NULL} 62 }; 63 64 void 65 bcm_li_print(netdissect_options *ndo, 66 const u_char *bp, u_int length) 67 { 68 u_int shim, direction, pkt_type, pkt_subtype, li_id; 69 70 ndo->ndo_protocol = "bcm_li"; 71 if (length < BCM_LI_SHIM_LEN) { 72 ND_PRINT(" (length %u < %u)", length, BCM_LI_SHIM_LEN); 73 goto invalid; 74 } 75 shim = GET_BE_U_4(bp); 76 77 direction = (shim >> 29) & 0x7; 78 pkt_type = (shim >> 25) & 0xf; 79 pkt_subtype = (shim >> 22) & 0x7; 80 li_id = shim & 0x3fffff; 81 82 length -= BCM_LI_SHIM_LEN; 83 bp += BCM_LI_SHIM_LEN; 84 85 ND_PRINT("%sBCM-LI-SHIM: direction %s, pkt-type %s, pkt-subtype %s, li-id %u%s", 86 ndo->ndo_vflag ? "\n " : "", 87 tok2str(bcm_li_direction_values, "unknown", direction), 88 tok2str(bcm_li_pkt_type_values, "unknown", pkt_type), 89 tok2str(bcm_li_pkt_subtype_values, "unknown", pkt_subtype), 90 li_id, 91 ndo->ndo_vflag ? "\n ": ""); 92 93 if (!ndo->ndo_vflag) { 94 ND_TCHECK_LEN(bp, length); 95 return; 96 } 97 98 switch (pkt_type) { 99 case BCM_LI_PKT_TYPE_ETHERNET: 100 ether_print(ndo, bp, length, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); 101 break; 102 case BCM_LI_PKT_TYPE_IPV4: 103 ip_print(ndo, bp, length); 104 break; 105 case BCM_LI_PKT_TYPE_IPV6: 106 ip6_print(ndo, bp, length); 107 break; 108 case BCM_LI_PKT_TYPE_UNDECIDED: 109 110 /* 111 * Guess IP version from first nibble. 112 */ 113 if ((GET_U_1(bp) >> 4) == 4) { 114 ip_print(ndo, bp, length); 115 } else if ((GET_U_1(bp) >> 4) == 6) { 116 ip6_print(ndo, bp, length); 117 } else { 118 ND_PRINT("unknown payload"); 119 } 120 break; 121 122 default: 123 goto invalid; 124 } 125 126 return; 127 invalid: 128 nd_print_invalid(ndo); 129 } 130 131