12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Code by Gert Doering, SpaceNet GmbH, gert@space.net
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Reference documentation:
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifndef lint
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic const char rcsid[] _U_ =
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.25 2004/10/07 14:53:11 hannes Exp $";
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "addrtoname.h"
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h"			/* must come after interface.h */
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "nlpid.h"
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define CDP_HEADER_LEN  4
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok cdp_tlv_values[] = {
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x01,             "Device-ID"},
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x02,             "Address"},
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x03,             "Port-ID"},
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x04,             "Capability"},
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x05,             "Version String"},
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x06,             "Platform"},
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x07,             "Prefixes"},
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x08,             "Protocol-Hello option"},
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x09,             "VTP Management Domain"},
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x0a,             "Native VLAN ID"},
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x0b,             "Duplex"},
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x0e,             "ATA-186 VoIP VLAN request"},
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x0f,             "ATA-186 VoIP VLAN assignment"},
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x10,             "power consumption"},
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x11,             "MTU"},
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x12,             "AVVID trust bitmap"},
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x13,             "AVVID untrusted ports CoS"},
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x14,             "System Name"},
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x15,             "System Object ID (not decoded)"},
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x16,             "Management Addresses"},
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x17,             "Physical Location"},
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL}
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic struct tok cdp_capability_values[] = {
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x01,             "Router" },
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x02,             "Transparent Bridge" },
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x04,             "Source Route Bridge" },
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x08,             "L2 Switch" },
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x10,             "L3 capable" },
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x20,             "IGMP snooping" },
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0x40,             "L1 capable" },
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int cdp_print_addr(const u_char *, int);
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int cdp_print_prefixes(const u_char *, int);
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic unsigned long cdp_get_number(const u_char *, int);
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcdp_print(const u_char *pptr, u_int length, u_int caplen)
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int type, len, i, j;
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        const u_char *tptr;
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (caplen < CDP_HEADER_LEN) {
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		(void)printf("[|cdp]");
962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        tptr = pptr; /* temporary pointer */
1002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (!TTEST2(*tptr, CDP_HEADER_LEN))
1022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                goto trunc;
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("CDPv%u, ttl: %us", *tptr, *(tptr+1));
1042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (vflag)
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                printf(", checksum: %u (unverified), length %u", EXTRACT_16BITS(tptr), length);
1062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	tptr += CDP_HEADER_LEN;
1072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (tptr < (pptr+length)) {
1092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (!TTEST2(*tptr, 4)) /* read out Type and Length */
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    goto trunc;
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		type = EXTRACT_16BITS(tptr);
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		len  = EXTRACT_16BITS(tptr+2); /* object length includes the 4 bytes header length */
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                tptr += 4;
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                len -= 4;
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (!TTEST2(*tptr, len))
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (vflag || type == 1) { /* in non-verbose mode just print Device-ID */
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    if (vflag)
1232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf("\n\t%s (0x%02x), length: %u byte%s: ",
1242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               tok2str(cdp_tlv_values,"unknown field type", type),
1252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               type,
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               len,
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               len>1 ? "s" : ""); /* plural */
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    switch (type) {
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x01: /* Device-ID */
1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (!vflag)
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            printf(", Device-ID '%.*s'", len, tptr);
1342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        else
1352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            printf("'%.*s'", len, tptr);
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x02: /* Address */
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        if (cdp_print_addr(tptr, len) < 0)
1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x03: /* Port-ID */
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("'%.*s'", len, tptr);
1432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x04: /* Capabilities */
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("(0x%08x): %s",
1462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               EXTRACT_32BITS(tptr),
1472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               bittok2str(cdp_capability_values, "none",EXTRACT_32BITS(tptr)));
1482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x05: /* Version */
1502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        printf("\n\t  ");
1512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        for (i=0;i<len;i++) {
1522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            j = *(tptr+i);
1532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            putchar(j);
1542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            if (j == 0x0a) /* lets rework the version string to get a nice identation */
1552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                printf("\t  ");
1562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        }
1572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x06: /* Platform */
1592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("'%.*s'", len, tptr);
1602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x07: /* Prefixes */
1622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cdp_print_prefixes(tptr, len) < 0)
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                            goto trunc;
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x08: /* Protocol Hello Option - not documented */
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x09: /* VTP Mgmt Domain  - not documented */
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("'%.*s'", len,tptr);
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x0a: /* Native VLAN ID - not documented */
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%d",EXTRACT_16BITS(tptr));
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x0b: /* Duplex - not documented */
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%s", *(tptr) ? "full": "half");
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    /* http://www.cisco.com/univercd/cc/td/doc/product/voice/ata/atarn/186rn21m.htm
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                     * plus more details from other sources
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                     */
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x0e: /* ATA-186 VoIP VLAN request - incomplete doc. */
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("app %d, vlan %d",
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               *(tptr), EXTRACT_16BITS(tptr+1));
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x10: /* ATA-186 VoIP VLAN assignment - incomplete doc. */
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%1.2fW",
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               cdp_get_number(tptr, len)/1000.0 );
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x11: /* MTU - not documented */
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("%u bytes", EXTRACT_32BITS(tptr));
1902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x12: /* AVVID trust bitmap - not documented */
1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("0x%02x", *(tptr) );
1932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x13: /* AVVID untrusted port CoS - not documented */
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("0x%02x", *(tptr));
1962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x14: /* System Name - not documented */
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("'%.*s'", len, tptr);
1992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x16: /* System Object ID - not documented */
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (cdp_print_addr(tptr, len) < 0)
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    case 0x17: /* Physical Location - not documented */
2052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("0x%02x/%.*s", *(tptr), len - 1, tptr + 1 );
2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
2072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    default:
2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        print_unknown_data(tptr,"\n\t  ",len);
2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    }
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		/* avoid infinite loop */
2132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (len == 0)
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			break;
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		tptr = tptr+len;
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (vflag < 1)
2182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            printf(", length %u",caplen);
2192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return;
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf("[|cdp]");
2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
2242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
2262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Protocol type values.
2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * PT_NLPID means that the protocol type field contains an OSI NLPID.
2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * PT_IEEE_802_2 means that the protocol type field contains an IEEE 802.2
2312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * LLC header that specifies that the payload is for that protocol.
2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define PT_NLPID		1	/* OSI NLPID */
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define PT_IEEE_802_2		2	/* IEEE 802.2 LLC header */
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
2372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcdp_print_addr(const u_char * p, int l)
2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
2392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int pt, pl, al, num;
2402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *endp = p + l;
2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	static u_char prot_ipv6[] = {
2432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd
2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	};
2452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	TCHECK2(*p, 2);
2482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	num = EXTRACT_32BITS(p);
2492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p += 4;
2502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (p < endp && num >= 0) {
2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK2(*p, 2);
2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (p + 2 > endp)
2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
2552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		pt = p[0];		/* type of "protocol" field */
2562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		pl = p[1];		/* length of "protocol" field */
2572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p += 2;
2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		TCHECK2(p[pl], 2);
2602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (p + pl + 2 > endp)
2612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			goto trunc;
2622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		al = EXTRACT_16BITS(&p[pl]);	/* address length */
2632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (pt == PT_NLPID && pl == 1 && *p == NLPID_IP && al == 4) {
2652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*
2662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * IPv4: protocol type = NLPID, protocol length = 1
2672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4),
2682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * address length = 4
2692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 */
2702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p += 3;
2712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK2(*p, 4);
2732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (p + 4 > endp)
2742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
2752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("IPv4 (%u) %s",
2762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               num,
2772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               ipaddr_string(p));
2782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p += 4;
2792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
2802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef INET6
2812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else if (pt == PT_IEEE_802_2 && pl == 8 &&
2822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		    memcmp(p, prot_ipv6, 8) == 0 && al == 16) {
2832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*
2842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * IPv6: protocol type = IEEE 802.2 header,
2852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * protocol length = 8 (size of LLC+SNAP header),
2862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * protocol = LLC+SNAP header with the IPv6
2872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * Ethertype, address length = 16
2882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 */
2892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p += 10;
2902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK2(*p, al);
2912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (p + al > endp)
2922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
2932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("IPv6 (%u) %s",
2952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               num,
2962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                               ip6addr_string(p));
2972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p += al;
2982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
2992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
3002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		else {
3012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/*
3022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 * Generic case: just print raw data
3032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			 */
3042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK2(*p, pl);
3052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (p + pl > endp)
3062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
3072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf("pt=0x%02x, pl=%d, pb=", *(p - 2), pl);
3082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			while (pl-- > 0)
3092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" %02x", *p++);
3102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK2(*p, 2);
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (p + 2 > endp)
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
3132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			al = (*p << 8) + *(p + 1);
3142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(", al=%d, a=", al);
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			p += 2;
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			TCHECK2(*p, al);
3172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			if (p + al > endp)
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				goto trunc;
3192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			while (al-- > 0)
3202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				printf(" %02x", *p++);
3212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		num--;
3232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (num)
3242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			printf(" ");
3252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 0;
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
3302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -1;
3312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectcdp_print_prefixes(const u_char * p, int l)
3362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (l % 5)
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		goto trunc;
3392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	printf(" IPv4 Prefixes (%d):", l / 5);
3412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	while (l > 0) {
3432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		printf(" %u.%u.%u.%u/%u", p[0], p[1], p[2], p[3], p[4]);
3442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		l -= 5;
3452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p += 5;
3462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return 0;
3492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projecttrunc:
3512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return -1;
3522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* read in a <n>-byte number, MSB first
3552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * (of course this can handle max sizeof(long))
3562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
3572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic unsigned long cdp_get_number(const u_char * p, int l)
3582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    unsigned long res=0;
3602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    while( l>0 )
3612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    {
3622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	res = (res<<8) + *p;
3632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p++; l--;
3642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
3652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return res;
3662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
367