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