1 /* $OpenBSD: print-cdp.c,v 1.7 2019/04/05 00:57:59 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * Code by Gert Doering, SpaceNet GmbH, gert@space.net 24 * 25 * Reference documentation: 26 * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm 27 */ 28 29 #include <sys/time.h> 30 31 #include <netinet/in.h> 32 33 #include <ctype.h> 34 #include <netdb.h> 35 #include <stdio.h> 36 #include <string.h> 37 38 #include "interface.h" 39 #include "addrtoname.h" 40 #include "extract.h" /* must come after interface.h */ 41 42 int cdp_print_addr(const u_char * p, int l); 43 void cdp_print_prefixes(const u_char * p, int l); 44 45 /* 46 * Returns non-zero IFF it succeeds in printing the header 47 */ 48 void 49 cdp_print(const u_char *p, u_int length, u_int caplen, int i) 50 { 51 int type, len; 52 53 /* Cisco Discovery Protocol */ 54 55 if (caplen < i + 4) { 56 printf("[|cdp]"); 57 return; 58 } 59 60 printf("CDP v%d, ttl=%ds", p[i], p[i+1]); 61 i+=4; /* skip version, TTL and chksum */ 62 63 while (i < length) { 64 if (i + 4 > caplen) { 65 printf("[|cdp]"); 66 return; 67 } 68 69 type = (p[i]<<8) + p[i+1]; 70 len = (p[i+2]<<8) + p[i+3]; 71 72 if (vflag) 73 printf(" %02x/%02x", type, len); 74 75 if (len < 4) 76 goto error; 77 78 if (i+len > caplen) { 79 printf("[|cdp]"); 80 return; 81 } 82 83 switch(type) { 84 case 0x01: 85 printf(" DevID '%.*s'", len - 4, p + i + 4); 86 break; 87 case 0x02: 88 printf(" Addr"); 89 if (cdp_print_addr(p + i + 4, len - 4)) 90 goto error; 91 break; 92 case 0x03: 93 printf(" PortID '%.*s'", len - 4, p + i + 4); 94 break; 95 case 0x04: 96 if (len < 8) 97 goto error; 98 printf(" CAP 0x%02x", (unsigned) p[i+7]); 99 break; 100 case 0x05: 101 if (vflag) 102 printf(" Version %.*s", len-4, p+i+4 ); 103 else 104 printf(" Version (suppressed)" ); 105 break; 106 case 0x06: 107 printf(" Platform '%.*s'", len-4, p+i+4 ); 108 break; 109 case 0x07: 110 cdp_print_prefixes(p+i+4, len-4); 111 break; 112 case 0x09: /* guess - not documented */ 113 printf(" VTP-Management-Domain '%.*s'", len-4, p+i+4 ); 114 break; 115 case 0x0a: /* guess - not documented */ 116 if (len < 6) 117 goto error; 118 printf(" Native-VLAN-ID %d", (p[i+4]<<8) + p[i+4+1] - 1 ); 119 break; 120 case 0x0b: /* guess - not documented */ 121 if (len < 5) 122 goto error; 123 printf(" Duplex %s", p[i+4] ? "full": "half" ); 124 break; 125 default: 126 printf(" unknown-type %02x len %d", type, len ); 127 } 128 129 /* avoid infinite loop */ 130 if (len == 0) 131 break; 132 i += len; 133 } 134 error: 135 printf("[!cdp]"); 136 } 137 138 #define CDP_CHECK_ACCESS(p, s) if ((endp - (p)) < (s)) return 1 139 140 int 141 cdp_print_addr(const u_char * p, int l) 142 { 143 int pl, pt, al, num; 144 const u_char * endp = p+l; 145 146 CDP_CHECK_ACCESS(p, 4); 147 num = (p[0] << 24) + (p[1]<<16) + (p[2]<<8)+ p[3]; 148 p+=4; 149 150 printf(" (%d): ", num); 151 152 while(p < endp && num >= 0) { 153 CDP_CHECK_ACCESS(p, 2); 154 pt=*p; 155 pl=*(p+1); 156 p+=2; 157 158 CDP_CHECK_ACCESS(p, 3); 159 /* special case: IPv4, protocol type=0xcc, addr. length=4 */ 160 if (pl == 1 && *p == 0xcc && p[1] == 0 && p[2] == 4) { 161 p+=3; 162 163 CDP_CHECK_ACCESS(p, 4); 164 printf("IPv4 %d.%d.%d.%d ", p[0], p[1], p[2], p[3]); 165 p+=4; 166 } else { /* generic case: just print raw data */ 167 printf("pt=0x%02x, pl=%d, pb=", pt, pl); 168 169 CDP_CHECK_ACCESS(p, pl); 170 while(pl-- > 0) 171 printf(" %02x", *p++); 172 173 CDP_CHECK_ACCESS(p, 2); 174 al=(*p << 8) + *(p+1); 175 printf(", al=%d, a=", al); 176 p+=2; 177 178 CDP_CHECK_ACCESS(p, al); 179 while(al-- > 0) 180 printf(" %02x", *p++); 181 } 182 printf(" "); 183 num--; 184 } 185 186 return 0; 187 } 188 189 190 void 191 cdp_print_prefixes(const u_char * p, int l) 192 { 193 printf(" IPv4 Prefixes (%d):", l/5); 194 195 while (l > 0) { 196 if (l >= 5) 197 printf(" %d.%d.%d.%d/%d", p[0], p[1], p[2], p[3], p[4] ); 198 l-=5; p+=5; 199 } 200 } 201