1 /* $OpenBSD: print-stp.c,v 1.1 2000/10/19 16:31:42 jason Exp $ */ 2 3 /* 4 * Copyright (c) 2000 Jason L. Wright (jason@thought.net) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Jason L. Wright 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Pretty print 802.1D Bridge Protocol Data Units 36 */ 37 38 #include <sys/param.h> 39 #include <sys/time.h> 40 #include <sys/socket.h> 41 #include <sys/file.h> 42 #include <sys/ioctl.h> 43 44 #ifdef __STDC__ 45 struct mbuf; 46 struct rtentry; 47 #endif 48 #include <net/if.h> 49 50 #include <netinet/in.h> 51 #include <netinet/in_systm.h> 52 #include <netinet/ip.h> 53 54 #include <netipx/ipx.h> 55 #include <netipx/ipx_if.h> 56 57 #include <ctype.h> 58 #include <netdb.h> 59 #include <pcap.h> 60 #include <signal.h> 61 #include <stdio.h> 62 63 #include <netinet/if_ether.h> 64 #include "ethertype.h" 65 66 #include <net/ppp_defs.h> 67 #include "interface.h" 68 #include "addrtoname.h" 69 #include "extract.h" 70 #include "llc.h" 71 72 #define STP_MSGTYPE_CBPDU 0x00 73 #define STP_MSGTYPE_TBPDU 0x80 74 75 #define STP_FLAGS_TC 0x01 /* Topology change */ 76 #define STP_FLAGS_TCA 0x80 /* Topology change ack */ 77 78 static void stp_print_cbpdu(const u_char *, u_int); 79 static void stp_print_tbpdu(const u_char *, u_int); 80 81 void 82 stp_print(p, len) 83 const u_char *p; 84 u_int len; 85 { 86 u_int16_t id; 87 88 if (len < 3) 89 goto truncated; 90 if (p[0] != LLCSAP_8021D || p[1] != LLCSAP_8021D || p[2] != LLC_UI) { 91 printf("invalid protocol"); 92 return; 93 } 94 printf("802.1d"); 95 p += 3; 96 len -= 3; 97 98 if (len < 3) 99 goto truncated; 100 id = EXTRACT_16BITS(p); 101 if (id != 0) { 102 printf(" unknown protocol id(0x%x)", id); 103 return; 104 } 105 if (p[2] != 0) { 106 printf(" unknown protocol ver(0x%x)", p[2]); 107 return; 108 } 109 p += 3; 110 len -= 3; 111 112 if (len < 1) 113 goto truncated; 114 switch (*p) { 115 case STP_MSGTYPE_CBPDU: 116 stp_print_cbpdu(p, len); 117 break; 118 case STP_MSGTYPE_TBPDU: 119 stp_print_tbpdu(p, len); 120 break; 121 default: 122 printf(" unknown message (0x%02x)", *p); 123 break; 124 } 125 126 return; 127 128 truncated: 129 printf("[|802.1d]"); 130 } 131 132 static void 133 stp_print_cbpdu(p, len) 134 const u_char *p; 135 u_int len; 136 { 137 u_int32_t cost; 138 u_int16_t t; 139 int x; 140 141 p += 1; 142 len -= 1; 143 144 printf(" config"); 145 146 if (len < 1) 147 goto truncated; 148 if (*p) { 149 x = 0; 150 151 printf(" flags=0x%x<", *p); 152 if ((*p) & STP_FLAGS_TC) 153 printf("%stc", (x++ != 0) ? "," : ""); 154 if ((*p) & STP_FLAGS_TCA) 155 printf("%stcack", (x++ != 0) ? "," : ""); 156 putchar('>'); 157 } 158 p += 1; 159 len -= 1; 160 161 if (len < 8) 162 goto truncated; 163 printf(" root="); 164 printf("%x.", EXTRACT_16BITS(p)); 165 p += 2; 166 len -= 2; 167 for (x = 0; x < 6; x++) { 168 printf("%s%x", (x != 0) ? ":" : "", *p); 169 p++; 170 len--; 171 } 172 173 if (len < 4) 174 goto truncated; 175 cost = EXTRACT_32BITS(p); 176 printf(" rootcost=0x%x", cost); 177 p += 4; 178 len -= 4; 179 180 if (len < 8) 181 goto truncated; 182 printf(" bridge="); 183 printf("%x.", EXTRACT_16BITS(p)); 184 p += 2; 185 len -= 2; 186 for (x = 0; x < 6; x++) { 187 printf("%s%x", (x != 0) ? ":" : "", *p); 188 p++; 189 len--; 190 } 191 192 if (len < 2) 193 goto truncated; 194 t = EXTRACT_16BITS(p); 195 printf(" port=0x%x", t); 196 p += 2; 197 len -= 2; 198 199 if (len < 2) 200 goto truncated; 201 printf(" age=%u/%u", p[0], p[1]); 202 p += 2; 203 len -= 2; 204 205 if (len < 2) 206 goto truncated; 207 printf(" max=%u/%u", p[0], p[1]); 208 p += 2; 209 len -= 2; 210 211 if (len < 2) 212 goto truncated; 213 printf(" hello=%u/%u", p[0], p[1]); 214 p += 2; 215 len -= 2; 216 217 if (len < 2) 218 goto truncated; 219 printf(" fwdelay=%u/%u", p[0], p[1]); 220 p += 2; 221 len -= 2; 222 223 return; 224 225 truncated: 226 printf("[|802.1d]"); 227 } 228 229 static void 230 stp_print_tbpdu(p, len) 231 const u_char *p; 232 u_int len; 233 { 234 printf(" tcn"); 235 } 236