OSPF协议解析及相关技术探索(C/C++代码实现)

OSPF(开放最短路径优先)是一种用于自治系统(AS)内部的路由协议,它是基于链路状态算法的。OSPF的设计目的是为了提供一种可扩展、快速收敛和高效的路由解决方案。

OSPF概念和特点

  • 概念
c 复制代码
自治系统(AS):一个AS是由一组通过统一路由策略或协议互相交换路由信息的路由器组成的网络。
 
链路状态:OSPF通过链路状态数据库(LSDB)来维护网络的拓扑结构。每个路由器会记录它与网络中其他路由器的连接状态,包括接口、成本和其他参数。
 
路由器ID(Router ID):每个OSPF路由器需要有一个唯一的32位标识符,用于在LSDB中表示自己。路由器ID通常配置为路由器的某个接口的IP地址。

OSPF区域:为了提高可扩展性和减少LSDB的大小,OSPF将网络划分为多个区域。每个区域有一个唯一的区域ID,并且只包含该区域内的链路状态信息。
 
链路状态通告(LSA):路由器通过发送LSA来通知其他路由器它所知道的链路状态变化。

洪泛(Flooding):OSPF使用洪泛机制来确保LSA能够被传递给网络中的所有路由器。

数据库描述(DBD):路由器之间通过DBD包来交换LSDB的概要信息。

选举:在OSPF网络中,会选举出区域内的主路由器(DR)和备份路由器(BDR),以及每个接口的指定路由器(DR)和备份指定路由器(BDR)。
  • 特点
c 复制代码
无环路设计:OSPF通过SPF算法确保没有环路发生,从而避免路由循环。

快速收敛:OSPF在网络拓扑发生变化时能够快速地重新计算路由,收敛速度比距离矢量协议快。

支持CIDR:OSPF支持无类域内路由(CIDR),能够处理大量子网和聚合路由。

支持VLSM:OSPF支持可变长子网掩码(VLSM),允许在同一网络中使用不同长度的子网掩码。

组播通信:OSPF使用组播地址224.0.0.5(所有OSPF路由器)和224.0.0.6(OSPF DR和BDR)来进行路由器之间的通信。

安全性:OSPF提供了一系列安全特性,如接口认证和Hello包的序列号验证,以防止未授权的访问和路由信息的伪造。

灵活的网络结构:OSPF能够适应多种网络结构,包括点到点、广播、非广播和点到多点网络。

扩展性:OSPF通过区域的概念来提高可扩展性,使得大型网络能够更加高效地运行。

OSPF的这些概念和特点使其成为互联网和私有网络中广泛使用的一种内部网关协议。

OSPF工作过程的简要概述

OSPF(开放最短路径优先)协议的工作过程是一个复杂的过程,涉及多个步骤和机制。以下是OSPF工作过程的简要概述:
1.启动和配置:

  • 路由器启动并配置OSPF协议。
  • 每个路由器分配一个唯一的32位路由器ID。
  • 路由器根据其接口的IP地址和子网掩码确定其OSPF区域。

2.邻居发现和建立:

  • 路由器通过发送Hello包来发现其他OSPF路由器。
  • Hello包中包含路由器ID、接口IP地址、子网掩码、区域ID等信息。
  • 路由器根据收到的Hello包中的信息,与对端路由器建立邻居关系。

3.建立邻接关系:

  • 邻居关系建立后,路由器之间会建立邻接关系。
  • 邻接路由器之间交换DBD(数据库描述)包,以了解对方LSDB(链路状态数据库)的概要信息。

4.交换链路状态信息:

  • 路由器通过发送LSR(链路状态请求)包来请求特定的LSA(链路状态通告)信息。
  • 收到LSR包的邻居路由器会回应LSU(链路状态更新)包,携带请求的LSA信息。
  • 路由器接收到LSU包后,会更新自己的LSDB。

5.维护LSDB:

  • 路由器定期发送Hello包来维护邻居关系。
  • Hello包中包含LSA的序列号,用于检测LSA是否发生变化。
  • 如果检测到LSA发生变化,路由器会请求更新的LSA。

6.计算最短路径:

  • 路由器使用SPF(最短路径优先)算法,根据LSDB中的信息计算到达所有其他路由器的最短路径。
  • SPF算法会为每个目的地生成一个最短路径树。

7.更新路由表:

  • 根据SPF算法计算出的最短路径,路由器更新其路由表。
  • 路由表中包含目的地的IP地址、下一跳路由器的路由器ID和路径成本。

8.路由表维护和更新:

  • 路由器持续监控网络拓扑的变化。
  • 当网络拓扑发生变化时,路由器会重新计算最短路径,并更新路由表。

9.状态监控和故障处理:

  • 路由器通过发送Hello包来监控邻居状态。
  • 如果邻居路由器失效,路由器会进入Down状态,并重新建立邻居关系。

OSPF协议的工作过程确保了网络的路由信息能够及时更新,并快速响应网络拓扑的变化。这种协议的设计使得OSPF能够高效地支持大型和复杂的数据中心网络。

OSPF的网络类型有哪些

OSPF(开放最短路径优先)协议支持多种网络类型,以适应不同的网络环境和需求。以下是OSPF的主要网络类型:
1.点对点(Point-to-Point, P2P):

  • 点到点网络是指在一个链路上仅连接两台设备的网络。
  • 在点到点网络中,不需要进行DR(设计路由器)和BDR(备份设计路由器)的选举。
  • 点到点网络通常用于连接两个远程路由器,如通过PPP或HDLC连接的设备。

2.广播(Broadcast):

  • 广播网络是指支持广播功能的网络,如以太网。
  • 在广播网络中,需要进行DR和BDR的选举,以便控制路由器之间的链路状态信息的传播。
  • 广播网络中的所有路由器都会监听224.0.0.5这个组播地址,用于发送和接收OSPF报文。

3.非广播多路访问(Non-Broadcast, NBMA):

  • NBMA网络是指不支持广播的 多路访问网络,如帧中继、ATM等。

  • 在NBMA网络中,路由器无法通过发送Hello包来发现邻居,因此需要手动配置邻居关系。

  • NBMA网络中使用单播方式发送协议报文。

4.点到多点(Point-to-Multipoint, P2MP):

  • 点到多点网络是指一个接口通过点到多点的网络与多台路由器相连。

  • 点到多点网络没有专门的DR和BDR选举机制。

  • 这种网络类型通常用于连接多个客户端的路由器,如通过光纤通道或无线连接。

5.多路访问点到多点(Multipoint-to-Multipoint, MP2MP):

  • 多路访问点到多点网络是指多个路由器通过点到多点的连接相互连接。

  • 这种网络类型没有DR和BDR的选举,所有路由器都是平等的。

  • MP2MP网络通常用于大型网络,如通过卫星连接的多个分支机构。

6.环路back(Loopback):

  • 环路back网络是指路由器的一个环路接口,通常用于路由器的管理目的。
  • 环路back接口的网络类型默认就是环路back,且不能修改。

7.虚拟链路(Virtual Link):

  • 虚拟链路是一种特殊的网络类型,用于在非直接连接的OSPF区域之间建立逻辑连接。

  • 它允许跨区域的路由,使得不同区域之间的路由器仿佛直接相连。

8.点对多点非广播(Point-to-Multipoint Non-Broadcast, P2MP-NBMA):

  • P2MP-NBMA网络是一种特殊的点到多点网络,它在NBMA网络上实现了点到多点的功能。

  • 这种网络类型需要手动指定邻居,并使用单播方式发送协议报文。

每种网络类型都有其特定的应用场景和配置要求,OSPF通过这些网络类型的支持,能够适应各种不同的网络架构和需求。

OSPF报头格式

OSPF(开放最短路径优先)协议使用IP协议报文来传输其协议数据,这些数据被封装在不同的OSPF报文类型中。OSPF报文直接封装在IP协议数据包中,IP协议号为89。OSPF报文头部格式对所有报文类型都是相同的,但每种报文类型携带的数据内容不同。以下是OSPF报文头部的详细格式:

  • Version(版本):

占1个字节,指出所采用的OSPF协议版本号。目前最高版本为OSPF v4。

  • Type(类型):

占1个字节,标识对应报文的类型。OSPF有5种报文类型:Hello报文、DD(数据库描述)报文、LSR(链路状态请求)报文、LSU(链路状态更新)报文和LSAck(链路状态应答)报文。

  • Code(代码):

占1个字节,用于进一步区分报文类型。例如,在Hello报文中,Code字段用于指示Hello报文是用于邻居发现、确认邻居关系还是用于发送路由器ID。

  • Packet Length(包长度):

占2个字节。它是指整个报文(包括OSPF报头和后面各报文内容部分)的字节长度。

  • Router ID(路由器ID):

占4个字节,指定发送报文的源路由器ID。

  • Area ID(区域ID):

占4个字节,指定发送报文的路由器所对应的OSPF区域号。

  • Checksum(校验和):

占2个字节,是对整个报文(包括OSPF报头和各报文具体内容,但不包括认证字段)的校验和。用于确保报文在传输过程中的完整性。

  • AuType(验证类型):

占2个字节,表示OSPF验证类型。0表示不验证,1表示简单认证,2表示MD5认证。

  • Authentication(认证信息):

根据验证类型而定。验证类型为0时未定义,验证类型为1时该字段是密码信息,类型为2时该字段包括Key ID、MD5验证数据长度和序列号的信息。MD5验证数据添加在OSPF报文后面,不包含在Authentication字段中。

除了头部信息,不同类型的OSPF报文还包含特定的数据字段。例如,Hello报文包含用于邻居发现和维护邻居关系的信息,如Hello间隔、Dead间隔等;DD报文用于在邻居之间同步数据库摘要信息;LSR报文用于请求特定类型的LSA;LSU报文用于发送完整的LSA信息;LSAck报文用于对收到的LSA进行确认。

OSPF报文的详细格式和内容可以参考OSPF协议的官方文档或相关技术标准。

OSPF协议中常用的一些数据包类型

1.Hello包(Hello Packet):

  • 用于在路由器之间发现邻居并维护邻居关系。
  • 包含路由器ID、网络掩码、Hello间隔、Dead间隔等信息。
  • 通过周期性地发送Hello包,路由器可以检测邻居的状态。

2.数据库描述包(Database Description Packet,DBD):

  • 用于在邻居之间同步数据库的概要信息。

  • 包含本地OSPF数据库中LSA的类型、ID和序列号。

  • DBD包是初始同步过程的一部分,用于确定需要交换哪些具体的LSA。

3.链路状态请求包(Link State Request Packet,LSR):

  • 用于请求对端邻居的特定LSA。

  • 当一个路由器需要了解它尚未收到的LSA时,它会发送LSR包。

  • LSR包包含请求的LSA的ID和广告路由器的信息。

4.链路状态更新包(Link State Update Packet,LSU):

  • 用于携带完整的LSA信息。

  • 当路由器收到新的LSA或者当LSA的内容发生变化时,它会发送LSU包。

  • LSU包中包含LSA的具体信息,如链路成本、出口接口等。

5.链路状态确认包(Link State Acknowledgment Packet,LSACK):

  • 用于确认收到的LSU包。

  • LSACK包包含一个或多个LSA的序列号,表示确认这些LSA已经正确接收。

  • 这有助于确保LSA的可靠传输。

除了上述五种主要类型的包,OSPF还定义了其他一些数据包类型,例如:

  • Hello包的扩展(Hello Packet Extensions):

提供比基本Hello包更多的信息,如路由器的优先级、DR和BDR的选举状态等。

  • Link State Packet(LSP):

在某些情况下,LSU包可能被LSP替代,LSP包含一个或多个LSA的集合。

  • Graceful Restart Packets:

用于在路由器重启过程中维护网络的连通性。

OSPF中LSA的一些基本概念

在OSPF(开放最短路径优先)协议中,链路状态通告(Link State Advertisement,LSA)是核心概念之一。LSAs是OSPF路由器用来描述其连接链路状态的数据包,它们包含了路由器接口的详细信息,如接口类型、成本、邻居路由器等。LSAs是OSPF构建链路状态数据库(LSDB)的基础,从而使得OSPF能够计算出网络中的最短路径。

以下是OSPF中LSA的一些基本概念:
1.LSA类型:

  • 类型1 LSA(路由器LSA):由每个OSPF路由器生成,描述了路由器上的所有接口及其成本。
  • 类型2 LSA(网络LSA):由设计路由器(DR)生成,描述了多路访问网络(如以太网)的拓扑结构。
  • 类型3 LSA(汇总网络LSA):由区域边界路由器(ABR)生成,用于在多个区域之间汇总网络信息。
  • 类型4 LSA(ASBR汇总LSA):由ABR生成,描述了到达AS边界路由器(ASBR)的路径。
  • 类型5 LSA(外部LSA):由ASBR生成,描述了到达外部网络的路由信息。

2.LSA的传播:

  • LSA在生成后,首先被发送到本区域的所有邻居路由器。
  • 然后,通过OSPF的扩散算法(Explicit Data Distribution),LSA会在整个OSPF域内传播。

3.LSA的寿命:

  • 每个LSA都有一个寿命,随着时间的推移会不断增加。
  • 当LSA的寿命达到一定值时,它会被标记为不活动,并停止传播。
  • 路由器会根据收到的LSA的寿命来更新自己的LSDB。

4.LSA的同步:

  • 当路由器加入OSPF网络时,它会通过交换Hello包来发现邻居。
  • 随后,路由器会请求missing的LSA,并通过DBD和LSR包来同步LSDB。

5.LSA的可靠性:

  • OSPF通过LSA的校验和来确保数据的完整性。
  • 收到LSA的路由器会验证校验和,如果不符合,则丢弃该LSA。

6.LSA的更新:

  • 当网络拓扑发生变化时,相关路由器会生成新的LSA或更新现有LSA。
  • 这些更新会通过LSU包快速传播到整个网络。

LSA是OSPF协议能够高效计算路由的关键,因为它们提供了网络拓扑的详细信息,使得OSPF可以采用Dijkstra算法来计算最短路径树。每种类型的LSA都有其特定的用途和格式,确保了OSPF网络的可靠性和灵活性。

OSPF路径选择的基本过程

路径选择是基于路由器之间的链路状态信息来确定的。OSPF使用最短路径优先(SPF)算法,该算法由Dijkstra提出,用于在复杂的网络中选择数据包传输的最短路径。以下是OSPF路径选择的基本过程:
1.收集链路状态信息:

  • 每个OSPF路由器通过发送Hello包来发现邻居。
  • 路由器通过Hello包交换来确定邻居的状态和它们之间的链路成本。
  • 路由器还会通过数据库描述(DBD)包来同步邻居的链路状态数据库(LSDB)的概要信息。

2.构建链路状态通告(LSA):

  • 每个路由器根据其接口的状态生成LSAs。
  • LSA包含有关接口的详细信息,如接口类型、成本、邻居路由器等。
  • LSAs通过链路状态更新(LSU)包在OSPF域内传播。

3.交换链路状态信息:

  • 路由器通过交换LSU包来更新它们之间的链路状态信息。

  • 这确保了所有路由器都有一个最新的网络拓扑视图。

4.运行最短路径优先(SPF)算法:

  • 每个路由器使用SPF算法计算到达网络中每个目的地的最短路径。
  • SPF算法考虑了所有可用的路径,并选择成本最低的路径作为最佳路径。
  • 算法使用一个称为最短路径树(SPT)的数据结构来表示网络拓扑和最短路径。

5.维护和更新路径:

  • 当网络拓扑发生变化时(如链路故障、路由器故障等),相关路由器会重新生成或更新LSAs。
  • 这些更新通过LSU包传播,并触发OSPF路由器重新运行SPF算法,以计算新的最短路径。

6.路径选择依据:

  • 路径选择主要依据是路径的成本,这通常与接口的带宽和延迟相关。
  • 除了成本,OSPF还考虑了其他因素,如路径的可靠性、快速收敛等。

7.类型1的外部路由和类型2的外部路由:

  • 类型1的外部路由包括到达外部网络的路由信息,以及到达该外部网络的OSPF域内的下一跳路由器。
  • 类型2的外部路由仅包括到达外部网络的路由信息,不包含OSPF域内的下一跳信息。

OSPF的路径选择过程确保了网络数据的传输遵循最短路径,从而优化了网络性能,降低了延迟。此外,OSPF的快速收敛特性使得网络在发生变化时能够迅速适应,保证网络的稳定性和可靠性

OSPF协议解析及相关技术探索(C/C++代码实现)

c 复制代码
...
typedef struct ospf2_header{

    u_int8_t  version;
    u_int8_t  type;
    u_int16_t length;
    u_int32_t router_id;
    u_int32_t area_id;
    u_int16_t checksum;
    u_int16_t auth_type;
    u_int8_t  auth_data[8];

} ospf2_header;

// type 1 - Hello
typedef struct ospf2_hello{

    u_int32_t   mask;
    u_int16_t   hello_interval;
    u_int8_t    opts;
    u_int8_t    rtr_priority;
    u_int32_t   rtr_dead_interval;
    u_int32_t   d_rtr;
    u_int32_t   bd_rtr;

} ospf2_hello;

// type 2 - Database Description
typedef struct ospf2_db_dscrp_hdr{

    u_int16_t   iface_mtu;
    u_int8_t    opts;
    u_int8_t    bits;
    u_int32_t   dd_seq_num;

} ospf2_db_dscrp_hdr;

// type 3 - LSA Request
typedef struct ospf2_ls_req_hdr{

    u_int32_t   type;
    u_int32_t   ls_id;
    u_int32_t   adv_rtr;

} ospf2_ls_req_hdr;

// type 4 - LSA Update
typedef struct ospf2_ls_upd_hdr {

    u_int32_t   num_lsa;

} ospf2_ls_upd_hdr;


// LSA Router
typedef struct ospf2_lsa_rtr {

	u_int8_t		flags;
	u_int8_t		dummy;
	u_int16_t		nlinks;

} ospf2_lsa_rtr;

// LSA Router Link
typedef struct ospf2_lsa_rtr_link {

	u_int32_t		id;
	u_int32_t		data;
	u_int8_t		type;
	u_int8_t		num_tos;
	u_int16_t		metric;

} ospf2_lsa_rtr_link;

// LSA Network Header
typedef struct ospf2_lsa_net {

	u_int32_t		mask;

} ospf2_lsa_net;

// LSA Network Attached
typedef struct ospf2_lsa_net_att {

    u_int32_t		att_rtr;

} ospf2_lsa_net_att;

// LSA Network Link
typedef struct ospf2_lsa_net_link {

	u_int32_t		att_rtr;

} ospf2_lsa_net_link;

// LSA Summary
typedef struct ospf2_lsa_sum {

	u_int32_t		mask;
	u_int32_t		metric;

} ospf2_lsa_sum;

// LSA AS-External
typedef struct ospf2_lsa_asext {

	u_int32_t		mask;
	u_int32_t		metric;
	u_int32_t		fw_addr;
	u_int32_t		ext_tag;

} ospf2_lsa_asext;

// LSA Header
typedef struct ospf2_lsa_hdr {

	u_int16_t		age;
	u_int8_t		opts;
	u_int8_t		type;
	u_int32_t		ls_id;
	u_int32_t		adv_rtr;
	u_int32_t		seq_num;
	u_int16_t		ls_chksum;
	u_int16_t		len;

} ospf2_lsa_hdr;

// LLS Data Block
typedef struct ospf2_lls_data_block {

    u_int16_t        checksum;
    u_int16_t        data_length;

} ospf2_lls_data_block;


typedef struct ospf2_lsa {

    struct ospf2_lsa_hdr    hdr;
    union {
        struct ospf2_lsa_rtr    rtr;
        struct ospf2_lsa_net    net;
        struct ospf2_lsa_sum    sum;
        struct ospf2_lsa_asext  asext;
    } data;

} ospf2_lsa;


//-------------

typedef struct ospf3_header{

    u_int8_t  version;
    u_int8_t  type;
    u_int16_t length;
    u_int32_t router_id;
    u_int32_t area_id;
    u_int16_t checksum;
    u_int8_t instance_id;
    u_int8_t  dummy;

} ospf3_header;

typedef struct ospf3_hello{

    u_int32_t   interface_id;
    u_int32_t   opts;
    u_int16_t   hello_interval;
    u_int16_t   rtr_dead_interval;
    u_int32_t   d_rtr;
    u_int32_t   bd_rtr;
    u_int32_t   neighbor_id;

} ospf3_hello;

...

...
typedef struct ospf3_lsa_hdr {

	u_int16_t		age;
	u_int16_t       type;
	u_int32_t		ls_id;
	u_int32_t		adv_rtr;
	u_int32_t		seq_num;
	u_int16_t		ls_chksum;
	u_int16_t		len;

} ospf3_lsa_hdr;

// Router-LSA header
typedef struct ospf3_lsa_rtr_hdr {

    u_int32_t       opts;

} ospf3_lsa_rtr_hdr;

// Router-LSA
typedef struct ospf3_lsa_rtr {

    u_int8_t        type;
    u_int8_t        dummy;
    u_int16_t       metric;
    u_int32_t       if_id;
    u_int32_t       n_if_id;
    u_int32_t       n_rtr_id;

} ospf3_lsa_rtr;

// Network-LSA Header
typedef struct ospf3_lsa_net_hdr {

    u_int32_t       opts;

} ospf3_lsa_net_hdr;

// Network-LSA
typedef struct ospf3_lsa_net {

    u_int32_t       att_rtr;

} ospf3_lsa_net;

// Inter-Area-Prefix-LSA
typedef struct ospf3_lsa_inter_area_prefix_hdr {

    u_int32_t       metric;
    u_int8_t        p_len;
    u_int8_t        p_opts;
    u_int16_t       dummy;

} ospf3_inter_area_prefix_hdr;

// Inter-Area-Router-LSA
typedef struct ospf3_lsa_inter_area_rtr {

    u_int32_t       opts;
    u_int32_t       metric;
    u_int32_t       dst_rtr_id;

} ospf3_lsa_inter_area_rtr;

// AS-External-LSA
typedef struct ospf3_lsa_asext_hdr {

    u_int32_t       metric;
    u_int8_t        p_len;
    u_int8_t        p_opts;
    u_int16_t       ref_ls;

} ospf3_lsa_asext_hdr;

// Link-LSA Header
typedef struct ospf3_lsa_link_hdr {

    u_int32_t       opts;
    struct in6_addr addr;
    u_int32_t       num_pref;

} ospf3_lsa_link_hdr;

// Link-LSA
typedef struct ospf3_lsa_link {

    u_int8_t        p_len;
    u_int8_t        p_opts;
    u_int16_t       dummy;

} ospf3_lsa_link;


typedef struct ospf3_lsa_intra_area_prefix_hdr{

    u_int16_t       num_pref;
    u_int16_t       type;
    u_int32_t       ref_ls_id;
    u_int32_t       ref_adv_rtr;

} ospf3_lsa_intra_area_prefix_hdr;

// Intra-Area-Prefix LSA
typedef struct ospf3_lsa_intra_area_prefix {

    u_int8_t        p_len;
    u_int8_t        p_opts;
    u_int16_t       metric;


} ospf3_lsa_intra_area_prefix;

// OSPF3 LSA
typedef struct ospf3_lsa {

    struct ospf3_lsa_hdr        hdr;
    union{
        struct ospf3_lsa_rtr_hdr    rtr_hdr; // jak se to tam zobrazuje hdr+rtr?
        struct ospf3_lsa_net    net;
        struct ospf3_lsa_inter_area_prefix_hdr  ia_p_hdr;
        struct ospf3_lsa_inter_area_rtr         ia_rtr;
        struct ospf3_lsa_asext_hdr              asext_hdr;
        struct ospf3_lsa_link_hdr               link_hdr;
        struct ospf3_lsa_intra_area_prefix_hdr  intra_p_hdr;
    } data;

} ospf3_lsa;

//------

struct ospf3_db_item{

    struct ospf3_lsa* lsa;
    struct ospf3_db_item* next;

} ospf3_db_item;

struct ospf3_db_area{

    // area id
    u_int32_t area_id;

    struct ospf3_db_item* rtr_ls;

    struct ospf3_db_item* net_ls;

    struct ospf3_db_item* ia_p_ls;

    struct ospf3_db_item* ia_rtr_ls;

    struct ospf3_db_item* asext_ls;

    struct ospf3_db_item* link_ls;

    struct ospf3_db_item* intra_p_ls;

    struct ospf3_db_area* next;

} ospf3_db_area;

struct ospf3_db_instance{

    u_int32_t instance_id;

    struct ospf3_db_area* area_list;

    struct ospf3_db_instance* next;

} ospf3_db_instance;


struct ospf3_db {

    // id routeru
    u_int32_t router_id;
    // seznam instanci OSPFv3 na danem routeru
    struct ospf3_db_instance* instance_list;
    // ukazatel na dalsi databazi
    struct ospf3_db* next;

} ospf3_db;


int main(int argc, char *argv[])
{
...
    while((c = getopt(argc, argv, "hi:")) != -1){
        switch(c){
            case 'h':
                print_help();
                return(EXIT_SUCCESS);
                break;
            case 'i':
                dev = optarg;
                #ifdef DEBUG
                    printf("dev: %s", dev);
                #endif
                break;
            default:
                print_help();
                return(EXIT_FAILURE);
                break;
        }
    }


    if(pcap_lookupnet(dev, &net, &mask, errbuf) == -1){
        #ifdef DEBUG
            fprintf(ERROUT, "Can't get netmask for device %s, %s\n", dev, errbuf);
        #endif
        net = 0;
        mask = 0;
        //return ERRDEV;
    }


...
    handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
    if(handle == NULL){
        fprintf(ERROUT, "Couldn't open device %s: %s\n", dev, errbuf);
        return(EXIT_FAILURE);
    }


    if(pcap_datalink(handle) != DLT_EN10MB){
        fprintf(ERROUT, "%s is not an Ethernet interface\n", dev);
        exit(EXIT_FAILURE);
    }


    if(pcap_compile(handle, &fp, filter_exp, 0, net) == -1){
        fprintf(ERROUT, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(EXIT_FAILURE);
    }


    if(pcap_setfilter(handle, &fp) == -1){
        fprintf(ERROUT, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(EXIT_FAILURE);
    }


    pcap_loop(handle, NUMPACKETS, got_packet, NULL);


    pcap_freecode(&fp);
    pcap_close(handle);

    return(EXIT_SUCCESS);
}

If you need the complete source code, please add the WeChat number (c17865354792)

运行结果:

使用Wireshark可以捕获网络中传输的OSPF数据包,包括Hello包、数据库描述包(DBD)、链路状态请求包(LSR)、链路状态更新包(LSU)和链路状态确认包(LSAck)。

总结

OSPF协议作为互联网中重要的路由协议,其安全运行对整个互联网的稳定性至关重要。通过使用网络嗅探工具,如Wireshark,安全专家能够监控和分析OSPF协议的运行状态,及时发现并处理可能的安全威胁,保证网络的安全和稳定。

参考:RFC 2328、RFC 2740、、RFC 5340、RFC 826、RFC 1122、RFC 1191、RFC 4632

Welcome to follow WeChat official account【程序猿编码

相关推荐
时光の尘13 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
我们的五年18 分钟前
【Linux课程学习】:进程描述---PCB(Process Control Block)
linux·运维·c++
-一杯为品-23 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
程序猿阿伟34 分钟前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链
爱摸鱼的孔乙己1 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan1 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
烦躁的大鼻嘎2 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
IU宝2 小时前
C/C++内存管理
java·c语言·c++
fhvyxyci2 小时前
【C++之STL】摸清 string 的模拟实现(下)
开发语言·c++·string
qq_459730032 小时前
C 语言面向对象
c语言·开发语言