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