1 /* $OpenBSD: print-cdp.c,v 1.3 2007/10/07 16:41:05 deraadt 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 #ifndef lint 30 static const char rcsid[] = 31 "@(#) $Id: print-cdp.c,v 1.3 2007/10/07 16:41:05 deraadt Exp $"; 32 #endif 33 34 #include <sys/param.h> 35 #include <sys/time.h> 36 37 #include <netinet/in.h> 38 39 #include <ctype.h> 40 #include <netdb.h> 41 #include <stdio.h> 42 #include <string.h> 43 44 #include "interface.h" 45 #include "addrtoname.h" 46 #include "extract.h" /* must come after interface.h */ 47 48 void cdp_print_addr(const u_char * p, int l); 49 void cdp_print_prefixes(const u_char * p, int l); 50 51 /* 52 * Returns non-zero IFF it succeeds in printing the header 53 */ 54 void 55 cdp_print(const u_char *p, u_int length, u_int caplen, 56 const u_char *esrc, const u_char *edst) 57 { 58 int i; 59 int type, len; 60 61 /* Cisco Discovery Protocol */ 62 63 if (caplen < 12) { 64 printf("[|cdp]"); 65 return; 66 } 67 68 i=8; /* CDP data starts at offset 8 */ 69 printf("CDP v%d, ttl=%ds", p[i], p[i+1]); 70 i+=4; /* skip version, TTL and chksum */ 71 72 while (i < length) { 73 if (i + 4 > caplen) { 74 printf("[!cdp]"); 75 return; 76 } 77 78 type = (p[i]<<8) + p[i+1]; 79 len = (p[i+2]<<8) + p[i+3]; 80 81 if (vflag) 82 printf(" %02x/%02x", type, len); 83 84 if (i+len > caplen) { 85 printf("[!cdp]"); 86 return; 87 } 88 89 switch(type) { 90 case 0x01: 91 printf(" DevID '%.*s'", len - 4, p + i + 4); 92 break; 93 case 0x02: 94 printf(" Addr"); 95 cdp_print_addr(p + i + 4, len - 4); 96 break; 97 case 0x03: 98 printf(" PortID '%.*s'", len - 4, p + i + 4); 99 break; 100 case 0x04: 101 printf(" CAP 0x%02x", (unsigned) p[i+7]); 102 break; 103 case 0x05: 104 if (vflag) 105 printf(" Version %.*s", len-4, p+i+4 ); 106 else 107 printf(" Version (suppressed)" ); 108 break; 109 case 0x06: 110 printf(" Platform '%.*s'", len-4, p+i+4 ); 111 break; 112 case 0x07: 113 cdp_print_prefixes(p+i+4, len-4); 114 break; 115 case 0x09: /* guess - not documented */ 116 printf(" VTP-Management-Domain '%.*s'", len-4, p+i+4 ); 117 break; 118 case 0x0a: /* guess - not documented */ 119 printf(" Native-VLAN-ID %d", (p[i+4]<<8) + p[i+4+1] - 1 ); 120 break; 121 case 0x0b: /* guess - not documented */ 122 printf(" Duplex %s", p[i+4] ? "full": "half" ); 123 break; 124 default: 125 printf(" unknown-type %02x len %d", type, len ); 126 } 127 128 /* avoid infinite loop */ 129 if (len == 0) 130 break; 131 i += len; 132 } 133 } 134 135 void 136 cdp_print_addr(const u_char * p, int l) 137 { 138 int pl, al, num; 139 const u_char * endp = p+l; 140 141 num = (p[0] << 24) + (p[1]<<16) + (p[2]<<8)+ p[3]; 142 p+=4; 143 144 printf(" (%d): ", num); 145 146 while(p < endp && num >= 0) { 147 pl=*(p+1); 148 p+=2; 149 150 /* special case: IPv4, protocol type=0xcc, addr. length=4 */ 151 if (pl == 1 && *p == 0xcc && p[1] == 0 && p[2] == 4) { 152 p+=3; 153 154 printf("IPv4 %d.%d.%d.%d ", p[0], p[1], p[2], p[3]); 155 p+=4; 156 } else { /* generic case: just print raw data */ 157 printf("pt=0x%02x, pl=%d, pb=", *(p-2), pl); 158 while(pl-- > 0) 159 printf(" %02x", *p++); 160 al=(*p << 8) + *(p+1); 161 printf(", al=%d, a=", al); 162 p+=2; 163 while(al-- > 0) 164 printf(" %02x", *p++); 165 } 166 printf(" "); 167 num--; 168 } 169 } 170 171 172 void 173 cdp_print_prefixes(const u_char * p, int l) 174 { 175 printf(" IPv4 Prefixes (%d):", l/5); 176 177 while (l > 0) { 178 printf(" %d.%d.%d.%d/%d", p[0], p[1], p[2], p[3], p[4] ); 179 l-=5; p+=5; 180 } 181 } 182