通常,大多数网络都有几个路由器或交换机,为了便于网络管理,使用网络图或网络图来告诉网络中存在什么类型的设备,以及所有设备如何相互连接,使用的IP地址以及它们属于哪个VLAN的信息。
CDP是一种专有的第二层思科网络协议。它是一种网络发现工具,在cisco设备上运行,有助于发现连接到网络的cisco设备。CDP有助于有效地检查设备,而无需实际进行物理检查。CDP允许用户使用一些显示命令来查看连接设备的信息,例如有关本地端口、远程端口、主机名、设备平台等的信息。
默认情况下,从相邻的思科设备接收的CDP消息不会重定向到任何其他设备,即CDP只转发到直接连接的思科设备。所有支持CDP的设备都以表格格式存储从其相邻设备接收的所有消息,可以使用show CDP neighbors命令查看这些消息。
这些CDP消息在所有SNAP(子网络访问协议)报头兼容接口上每60秒传输一次。由于并非所有数据链路层介质类型都支持SNAP,因此支持的介质类型有令牌环、以太网、PPP(点对点协议)、FDDI(光纤分布式数据接口)、帧中继、ATM(异步传输模式)、HDLC(高级数据链路控制)。Cisco设备还将这些CDP消息发送到多播目标地址(01:00:0C:CC:CC:CC)。
CDP的工作原理
所有Cisco设备都会定期传输CDP数据包(默认时间间隔值为60秒,但可以调整)。这些数据包以秒为单位公布生存时间(TTL)值,该值指示在丢弃数据包之前必须保留的秒数(默认值为180秒)。
启用接口后,发送的CDP数据包的生存时间值为非零,并且在接口即将关闭之前,生存时间值为零。这提供了快速的状态发现。
所有Cisco设备都接收CDP数据包,对其进行处理并缓存数据包中的信息。Cisco设备从不转发CDP数据包。如果任何信息与上次接收到的数据包相比发生了变化,则会缓存新信息,并丢弃旧信息,即使其生存时间值尚未过期。
CDP版本
CDPV1:-初始版本,它只能收集连接到下一端的设备信息。
CDPV2:-是该协议的最新版本,提供了更智能的设备跟踪功能,如802.1Q中继上本地VLAN ID不匹配的实例,以及连接设备之间双工状态的不匹配。
- 各字段定义
Version :包含设备软件版本信息。
TTL:接收器应保留此数据包中包含的信息的时间量,以秒为单位。180秒后默认。
Address :包含接收和发送设备的网络地址。
Port-ID :标识发送Cisco发现协议数据包的端口。
Capabilities :标识设备类型,表示设备的功能能力。例如,一个开关。
Platform : 标识设备的硬件平台。例如,Cisco 4500。
Native :指示每个接口上未标记数据包的假定VLAN。Cisco发现协议学习接口的本机VLAN。该字段仅用于支持IEEE 802.1Q协议的接口。
VTP Management Domain: 播发配置的VLAN中继协议(VTP)-系统的管理域名。网络运营商使用此名称来验证相邻网络节点中的VTP域配置。
- CDP Version1和Vesion 2 的区别
CDP Version1 和 Version2的主要区别在于 Version2 支持更多 TLV,比如交换机之间的 VVTP Domain,Duplex,Native VLAN ID 等等。这样极大的扩充了 CDP的功能。
思科发现协议第2版提供了比第1版更智能的设备跟踪功能。可用的功能之一是增强的报告机制,用于更快速的错误跟踪,这有助于减少网络停机时间。报告的错误包括连接端口上的本机VLAN ID(IEEE 802.1Q)不匹配以及连接设备之间的端口双工状态不匹配。有关报告错误的消息可以发送到控制台或日志服务器。
CDP监控和维护命令
clear cdp counters #清除cdp计数器
clear cdp table #清除cdp表
show cdp #显示cdp
show cdp entry device-name [protocol | version] #显示cdp入口设备名称[协议|版本]
show cdp interface [type number] #显示cdp接口[类型号]
show cdp neighbors [type number] [detail] #显示cdp邻居[类型编号][详细信息]
show cdp traffic #显示cdp流量
什么是CDP欺骗
在CDP欺骗中,攻击者发送以多播mac地址(01:00:0c:cc:cc:cc)为目的地、以各种欺骗或伪造的mac地址为源的数据包。当Cisco设备接收到这些帧时,它开始在CDP表中添加信息,并且该表将开始变得更大,因为攻击者可能会向设备发送数千个CDP帧。如果设备无法处理此攻击,则设备可能会在一段时间后崩溃,这就是为什么建议在连接非思科设备、用户站的接口上禁用CDP。
CDP TLV的类型
#define TYPE_DEVICE_ID 0x0001
#define TYPE_ADDRESS 0x0002
#define TYPE_PORT_ID 0x0003
#define TYPE_CAPABILITIES 0x0004
#define TYPE_IOS_VERSION 0x0005
#define TYPE_PLATFORM 0x0006
#define TYPE_IP_PREFIX 0x0007
#define TYPE_PROTOCOL_HELLO 0x0008
#define TYPE_VTP_MGMT_DOMAIN 0x0009
#define TYPE_NATIVE_VLAN 0x000a
#define TYPE_DUPLEX 0x000b
/* 0x000c */
/* 0x000d */
#define TYPE_VOIP_VLAN_REPLY 0x000e
#define TYPE_VOIP_VLAN_QUERY 0x000f
#define TYPE_POWER 0x0010
#define TYPE_MTU 0x0011
#define TYPE_TRUST_BITMAP 0x0012
#define TYPE_UNTRUSTED_COS 0x0013
#define TYPE_SYSTEM_NAME 0x0014
#define TYPE_SYSTEM_OID 0x0015
#define TYPE_MANAGEMENT_ADDR 0x0016
#define TYPE_LOCATION 0x0017
#define TYPE_EXT_PORT_ID 0x0018
#define TYPE_POWER_REQUESTED 0x0019
#define TYPE_POWER_AVAILABLE 0x001a
#define TYPE_PORT_UNIDIR 0x001b
功能名称
char CAPABILITIES_NAMES[7][19] = {
"Router",
"Transparent bridge",
"Source Route Bridge",
"Switch",
"Host",
"IGMP",
"Repeater"
};
CDP思科发现协议解析及C/C++代码实现
int main( int argc, char *argv[] )
{
...
// 获取命令行参数
while( ( c = getopt( argc, argv, "i:dhw:r:" ) ) != -1 )
{
switch( c )
{
case 'i':
dev = optarg;
handle = pcap_open_live( dev, BUFSIZ, 1, 269000, errbuf );
if( handle == NULL )
{
fprintf( stderr, "Couldn't open device %s: %s\n", dev, errbuf );
return( 2 );
}
// 获取设备
if( pcap_lookupnet( dev, &net, &mask, errbuf ) == -1 )
{
fprintf( stderr, "Couldn't get netmask for device %s: %s\n",
dev, errbuf );
net = 0;
mask = 0;
}
break;
case 'd':
debug = 1;
break;
case 'r':
dumpfile = optarg;
handle = pcap_open_offline( dumpfile, errbuf );
if( !handle )
{
fprintf( stderr, "Couldn't open file %s: %s\n",
dumpfile, errbuf );
return( 2 );
}
net = 0;
mask = 0;
break;
case 'w':
dumper = pcap_dump_open( handle, optarg );
if( !dumper )
{
fprintf( stderr, "Couldn't write to file %s: %s\n",
optarg, errbuf );
}
break;
case '?':
if( optopt == 'd' || optopt == 'w' )
{
fprintf( stderr, "Option -%c requires an argument.\n",
optopt );
}
else if( isprint ( optopt ) )
{
fprintf( stderr, "Unknown option `-%c'.\n", optopt );
}
else
{
fprintf( stderr, "Unknown option character `\\x%x'.\n",
optopt );
}
return 1;
case 'h':
default:
print_help( argv );
return( 0 );
}
}
if( !dev && !dumpfile )
{
print_help( argv );
return( 0 );
}
...
printf( "Reading packets from %s.\n", ( dev ) ? dev : dumpfile );
printf( "Waiting for a CDP packet...\n\n" );
// 死循环
while( pcap_packet == 1 )
{
// 抓一包
pcap_packet =
pcap_next_ex( handle, &header, (const u_char **) &data );
// 一旦数据包到达,就将其写入转储文件
if( dumper )
{
pcap_dump( (u_char *)dumper, header, data );
pcap_dump_flush( dumper );
}
...
...
// 解析TLV树
tlv_parse( data, header->len );
...
}
...
}
运行结果:
CDP Version1 解析:
CDP Version2 解析:
If you need the complete source code, please add the WeChat number (c17865354792)
总结
Cisco发现协议是一种第2层、独立于媒体和网络的协议,网络应用程序使用该协议来了解附近的直接连接设备。默认情况下启用Cisco发现协议。为Cisco发现协议配置的每个设备至少播发一个地址,设备可以在该地址接收消息,并将定期播发(消息)发送到众所周知的多播地址01:00:0C:CC:CC:CC。设备通过监听该地址来发现彼此。当其他设备上的接口打开或关闭时,他们也会听消息来学习。