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