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 #include <config.h> 25 26 #include "netdissect-stdinc.h" 27 28 #define ND_LONGJMP_FROM_TCHECK 29 #include "netdissect.h" 30 #include "addrtoname.h" 31 #include "extract.h" 32 33 #define BCM_LI_SHIM_LEN 4 34 35 static const struct tok bcm_li_direction_values[] = { 36 { 1, "unused" }, 37 { 2, "egress" }, 38 { 3, "ingress" }, 39 { 0, NULL} 40 }; 41 42 #define BCM_LI_PKT_TYPE_UNDECIDED 4 43 #define BCM_LI_PKT_TYPE_IPV4 5 44 #define BCM_LI_PKT_TYPE_IPV6 6 45 #define BCM_LI_PKT_TYPE_ETHERNET 7 46 47 static const struct tok bcm_li_pkt_type_values[] = { 48 { BCM_LI_PKT_TYPE_UNDECIDED, "undecided" }, 49 { BCM_LI_PKT_TYPE_IPV4, "ipv4" }, 50 { BCM_LI_PKT_TYPE_IPV6, "ipv6" }, 51 { BCM_LI_PKT_TYPE_ETHERNET, "ethernet" }, 52 { 0, NULL} 53 }; 54 55 static const struct tok bcm_li_pkt_subtype_values[] = { 56 { 1, "single VLAN tag" }, 57 { 2, "double VLAN tag" }, 58 { 3, "untagged" }, 59 { 0, NULL} 60 }; 61 62 void 63 bcm_li_print(netdissect_options *ndo, 64 const u_char *bp, u_int length) 65 { 66 u_int shim, direction, pkt_type, pkt_subtype, li_id; 67 68 ndo->ndo_protocol = "bcm_li"; 69 if (length < BCM_LI_SHIM_LEN) { 70 ND_PRINT(" (length %u < %u)", length, BCM_LI_SHIM_LEN); 71 goto invalid; 72 } 73 shim = GET_BE_U_4(bp); 74 75 direction = (shim >> 29) & 0x7; 76 pkt_type = (shim >> 25) & 0xf; 77 pkt_subtype = (shim >> 22) & 0x7; 78 li_id = shim & 0x3fffff; 79 80 length -= BCM_LI_SHIM_LEN; 81 bp += BCM_LI_SHIM_LEN; 82 83 ND_PRINT("%sBCM-LI-SHIM: direction %s, pkt-type %s, pkt-subtype %s, li-id %u%s", 84 ndo->ndo_vflag ? "\n " : "", 85 tok2str(bcm_li_direction_values, "unknown", direction), 86 tok2str(bcm_li_pkt_type_values, "unknown", pkt_type), 87 tok2str(bcm_li_pkt_subtype_values, "unknown", pkt_subtype), 88 li_id, 89 ndo->ndo_vflag ? "\n ": ""); 90 91 if (!ndo->ndo_vflag) { 92 ND_TCHECK_LEN(bp, length); 93 return; 94 } 95 96 switch (pkt_type) { 97 case BCM_LI_PKT_TYPE_ETHERNET: 98 ether_print(ndo, bp, length, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL); 99 break; 100 case BCM_LI_PKT_TYPE_IPV4: 101 ip_print(ndo, bp, length); 102 break; 103 case BCM_LI_PKT_TYPE_IPV6: 104 ip6_print(ndo, bp, length); 105 break; 106 case BCM_LI_PKT_TYPE_UNDECIDED: 107 108 /* 109 * Guess IP version from first nibble. 110 */ 111 if ((GET_U_1(bp) >> 4) == 4) { 112 ip_print(ndo, bp, length); 113 } else if ((GET_U_1(bp) >> 4) == 6) { 114 ip6_print(ndo, bp, length); 115 } else { 116 ND_PRINT("unknown payload"); 117 } 118 break; 119 120 default: 121 goto invalid; 122 } 123 124 return; 125 invalid: 126 nd_print_invalid(ndo); 127 } 128 129