⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ospf_receive_packet.c

📁 vxworks下ospf协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ospf_receive_packet.c - OSPF receive packet *//* Copyright 2000-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02f,18aug03,agi Changed call to ospf_MD_string() to common code mdString()02e,30jul03,agi Changed call to MD_string() to ospf_MD_string()                updated copyright02d,26may03,agi Changed rwos_get_system_elapsed_time_second() to                ospf_get_system_elapsed_time_second()02a,03dec02,ram SPR 84312 - Change elapsed time to return seconds21,10April02,bt	modified PTMP to follow the same path of POINT-TO-POINT20,11january02,jkw			Fix TSR 72091, neighbors not being added.19,12november,jkw			Virtual link hello fix.18,21sep01,kc     			Obsolete ospf_router_receive_packet() routine.17,20jun01,jkw	  			Added unnumbered link support16,26september00,reshma	Added WindRiver CopyRight15,25september00,reshma	RFC-1587 implementation for OSPF NSSA Option, also tested against ANVL.14,07july00,reshma			Unix compatibility related changes.13,04april00,reshma		Added some MIB support (Read only).Passed all important ANVL OSPF tests.12,23december99,reshma		Compatibility with VxWorks-IP and VxWorks RTM-interface11,28december98,jack		Compiled and added some comments10,11november98,jack		Config changes, linted and big endian changes09,30october98,jack		Incorporate changes for compilation on Vxworks08,23august98,jack			ANVL tested OSPF with PATRICIA tree route table and no recursion07,10august98,jack			PATRICIA Route Table Based OSPF Code Base06,04june98,jack			Integration with RTM and BGP05,24april98,jack			RTM changes04,10july97,cindy			Pre-release v1.52b03,02october97,cindy		Release Version 1.5202,22october96,cindy		Release Version 1.5001,05june96,cindy			First Beta Release*//*DESCRIPTIONospf_receive_packet.c is used for processing received packets.  This file will validate the OSPFpacket header.  This file will find out the specific packet type and pass the packet to theappropriate file.This file is used whenever a new OSPF packet is received.*/#include "ospf.h"#if defined (__OSPF_VIRTUAL_STACK__)#include "ospf_vs_lib.h"#endif /* __OSPF_VIRTUAL_STACK__ */#include	<net/if.h>/*******************************************************************************************************************************//*opaque lsa added error condition for opaque lsa jkw*/static char *cptr_packet_state_string[] = {"Good","Bad Acknowledgement","Duplicate Acknowledgement",	"Bad State in Acknowledgement","Bad Type in Acknowledgement","Mismatched E_bit in Database Description",	"Bad Router ID in Database Description","Bad State in Database Description","Bad Type in Database Description",	"Mismatched E_bit in Hello","Bad ID in Hello","Bad Mask in Hello","Bad Router Dead Interval in Hello",	"Bad Timer in Hello","Bad Virtual in Hello","Bad Authentication Key","Bad Authentication Type",	"Interface is Down","Bad Packet Type","Request is Bogus","Request is Empty","Bad State in Update",    "Stop Processing the Packet","","","Opaque Option not Enabled","Interface Mismatch MTU"};/*#endif*/ /*__NSSA__*//*******************************************************************************************************************************/static enum TEST ospf_check_validity_of_interface (OSPF_INTERFACE *sptr_interface,ULONG source_address,ULONG destination_address);static enum TEST ospf_check_validity_of_multicast_interface (OSPF_INTERFACE *sptr_interface,ULONG destination_address);static enum TEST ospf_check_validity_of_unicast_packet (OSPF_INTERFACE *sptr_interface,ULONG destination_address);static enum TEST ospf_check_size_of_ospf_packet (USHORT total_length_of_packet,USHORT size_of_ospf_packet);static enum TEST ospf_verify_ospf_header_and_get_neighbor (USHORT packet_size,OSPF_HEADER *sptr_ospf_header,	OSPF_INTERFACE **ptr_to_sptr_interface, ULONG source_address,ULONG size_of_ospf_packet,OSPF_NEIGHBOR **ptr_to_sptr_neighbor,	ULONG *sptr_cryptographic_sequence_number);static enum TEST ospf_verify_checksum_field_in_ospf_packet_header (OSPF_HEADER *sptr_ospf_header,ULONG size_of_ospf_packet);static enum TEST ospf_verify_area_id_and_get_neighbor (OSPF_HEADER *sptr_ospf_header,OSPF_INTERFACE **ptr_to_sptr_interface, ULONG source_address,	OSPF_NEIGHBOR **ptr_to_sptr_neighbor);static enum TEST ospf_authenticate_packet (USHORT packet_size,OSPF_HEADER *sptr_ospf_header,OSPF_INTERFACE *sptr_interface,	OSPF_AUTHENTICATION *sptr_ospf_authentication,OSPF_NEIGHBOR *sptr_neighbor,ULONG *sptr_cryptographic_sequence_number);static enum TEST ospf_do_md5_authentication (USHORT packet_size,OSPF_HEADER *sptr_ospf_header,	OSPF_INTERFACE *sptr_interface,OSPF_NEIGHBOR *sptr_neighbor);static enum TEST ospf_find_matching_key_for_md5_authentication (OSPF_INTERFACE *sptr_interface, BYTE received_key,	OSPF_AUTHENTICATION_KEY **ptr_to_sptr_authentication_key);static enum OSPF_PACKET_STATE ospf_process_specific_packet_type (OSPF_HEADER *sptr_ospf_header,OSPF_INTERFACE *sptr_interface,	OSPF_NEIGHBOR *sptr_neighbor,ULONG source_address,ULONG destination_address,ULONG size_of_ospf_packet,ULONG cryptographic_sequence_number);static enum TEST ospf_verify_area_id_and_virtual_neighbor (ULONG router_id, ULONG area_id, OSPF_INTERFACE **ptr_to_sptr_interface, OSPF_NEIGHBOR **ptr_to_sptr_neighbor);/***************************************************************************************************************************** *  The IP stack must call the following routine to pass an OSPF protocol packet down to the OSPF level for processing. * *  According to section 8.2 of the OSPF specification (page 57), "In order for the packet to be accepted at the IP level, *  it must pass a number of tests, even before the packet is passed to OSPF for processing: *       1. The IP checksum must be correct. *       2. The packet's IP destination address must be the IP address of the receiving interface, *          or one of the IP multicast addresses AllSPFRouters or AllDRouters. *       3. The IP protocol specified must be OSPF (89). *       4. Locally originated packets should not be passed on to OSPF.  That is, the source IP *          address should be examined to make sure this is not a multicast packet that the router *          itself generated." * *  ospf_router_rx_packet () assumes the packet has already passed these tests. * ****************************************************************************//* section 8.2 of OSPF specification (page 56) */void ospf_router_rx_packet (OSPF_INTERFACE *sptr_interface, OSPF_PACKET *sptr_ospf_packet, USHORT packet_size,							ULONG source_ip_address, ULONG destination_ip_address){	OSPF_HEADER *sptr_ospf_header;	USHORT size_of_ospf_packet;	USHORT total_length_of_packet;	ULONG cryptographic_sequence_number;	OSPF_NEIGHBOR *sptr_neighbor;	enum TEST return_type;	enum OSPF_PACKET_STATE packet_processing_return_type;	ULONG source_address_in_host_order;	ULONG destination_address_in_host_order;	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_router_rx_packet\r\n");	sptr_ospf_header = &sptr_ospf_packet->header;	if (sptr_interface == NULL)		{		return;		}	source_address_in_host_order = source_ip_address;	source_address_in_host_order = net_to_host_long (source_address_in_host_order);	destination_address_in_host_order = destination_ip_address;	destination_address_in_host_order = net_to_host_long (destination_address_in_host_order);	return_type = ospf_check_validity_of_interface (sptr_interface, source_address_in_host_order,		destination_address_in_host_order);	if (return_type == FAIL)		{		OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Dropped incoming packet - Invalid Interface\r\n");		return;		}	size_of_ospf_packet = sptr_ospf_header->length;	size_of_ospf_packet = net_to_host_short (size_of_ospf_packet);    total_length_of_packet = (USHORT)sptr_ospf_packet->ip_header.ip_len;	total_length_of_packet = net_to_host_short (total_length_of_packet);	return_type = ospf_check_size_of_ospf_packet (total_length_of_packet, size_of_ospf_packet);	if (return_type == FAIL)		{		OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Dropped incoming packet - Invalid Size of Packet\r\n");		return;		}	return_type = ospf_verify_ospf_header_and_get_neighbor (packet_size, sptr_ospf_header,		&sptr_interface, source_address_in_host_order, (ULONG) size_of_ospf_packet, &sptr_neighbor, &cryptographic_sequence_number);	if (return_type == FAIL)		{		OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Dropped incoming packet - Invalid OSPF Header or unable to find associated Neighbor\r\n");		return;		}    ospf_display_packet (sptr_ospf_packet, TRUE);	packet_processing_return_type = ospf_process_specific_packet_type (sptr_ospf_header, sptr_interface, sptr_neighbor,		source_address_in_host_order, destination_address_in_host_order, (ULONG) size_of_ospf_packet, cryptographic_sequence_number);	if ((packet_processing_return_type != GOOD_RECEIVE) && (packet_processing_return_type != STOP_PROCESSING_PACKET))		{		OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Received Packet Dropped due to Error:  %s\r\n",			cptr_packet_state_string[packet_processing_return_type]);		}	return;}/******************************************************************************************************************************/static enum TEST ospf_check_validity_of_interface (OSPF_INTERFACE *sptr_interface,ULONG source_address,ULONG destination_address){	enum TEST return_type;	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_check_validity_of_interface\r\n");	if (sptr_interface->state == OSPF_INTERFACE_IS_DOWN)		/* something is wrong because the interface state is set to DOWN */		{		return (FAIL);		}	if (ospf.ip_multicast == TRUE)		{		return_type = ospf_check_validity_of_multicast_interface (sptr_interface, destination_address);		}	else		{		return_type = ospf_check_validity_of_unicast_packet (sptr_interface, destination_address);		}	if (return_type == FAIL)		{		return (FAIL);		}	if (source_address == sptr_interface->address)		{		return (FAIL);		}	else		{		return (PASS);		}}/******************************************************************************************************************************/static enum TEST ospf_check_validity_of_multicast_interface (OSPF_INTERFACE *sptr_interface,ULONG destination_address){	enum TEST return_type;	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_check_validity_of_multicast_interface\r\n");	if (destination_address == OSPF_ADDR_ALLSPF)		{		/* Multicast to All SPF routers */		if (sptr_interface == NULL)			{			return (FAIL);			}		switch (sptr_interface->type)			{			case OSPF_POINT_TO_POINT:			case OSPF_BROADCAST:				break;			default:				{				return (FAIL);				}			}		}	else if (destination_address == OSPF_ADDR_ALLDR)		{		/* Multicast to All Designated Router routers */		if ((sptr_interface == NULL) || ((destination_address & OSPF_IF_MULTICAST_ALLDR) != 0x00000000L))			{			return (FAIL);			}		switch (sptr_interface->state)			{			case OSPF_INTERFACE_DESIGNATED_ROUTER:					/* third bullet item under verifying the OSPF packet header (page 58) */			case OSPF_INTERFACE_BACKUP_DESIGNATED_ROUTER:				{				if ((sptr_interface->type == OSPF_BROADCAST) && (sptr_interface->priority > 0x0000))					{					return (PASS);					}				else					{					return (FAIL);					}				}			default:				{				return (FAIL);				}			}		}	else		{		return_type = ospf_check_validity_of_unicast_packet (sptr_interface, destination_address);		return (return_type);		}	return (PASS);}/******************************************************************************************************************************/static enum TEST ospf_check_validity_of_unicast_packet (OSPF_INTERFACE *sptr_interface,ULONG destination_address){	enum BOOLEAN I_am_an_area_border_router;	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_check_validity_of_unicast_packet\r\n");	I_am_an_area_border_router = ospf_check_if_area_border_router ();	/* Unicast packet */	if (sptr_interface != NULL)		{		/* Local source */		if ( (destination_address != sptr_interface->address) && (I_am_an_area_border_router == FALSE) )			{#if defined (__UNNUMBERED_LINK__)			if ((sptr_interface->address == 0x00000000L) && (sptr_interface->type == OSPF_POINT_TO_POINT))				{				return (PASS); /* unnumbered links excused */				}			else				{				return (FAIL);				}#else /* __UNNUMBERED_LINK__ */			return (FAIL);#endif /* __UNNUMBERED_LINK__ */			}		else if (destination_address == sptr_interface->address)			{			return (PASS);  /* NEW */			}		}	if (I_am_an_area_border_router == TRUE)		{		/* Non-local source, could be a virtual link */		return (PASS);		}	return (FAIL);}/******************************************************************************************************************************/static enum TEST ospf_check_size_of_ospf_packet (USHORT total_length_of_packet,USHORT size_of_ospf_packet){	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_check_size_of_ospf_packet\r\n");	if (size_of_ospf_packet < OSPF_PACKET_SIZE)		{		return (FAIL);		}	else if (size_of_ospf_packet > total_length_of_packet)		{		return (FAIL);		}	else		{		return (PASS);		}}/**************************************************************************//* section 8.2 of OSPF specification (page 57-58) */static enum TEST ospf_verify_ospf_header_and_get_neighbor (USHORT packet_size,OSPF_HEADER *sptr_ospf_header,	OSPF_INTERFACE **ptr_to_sptr_interface, ULONG source_address,ULONG size_of_ospf_packet,OSPF_NEIGHBOR **ptr_to_sptr_neighbor,	ULONG *sptr_cryptographic_sequence_number){	OSPF_AUTHENTICATION	*sptr_ospf_authentication;	USHORT swapped_auth_type;	enum TEST return_type;	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_verify_ospf_header_and_get_neighbor\r\n");	*ptr_to_sptr_neighbor = NULL;	if (sptr_ospf_header->version != OSPF_VERSION)	/* first bullet item under verifying the OSPF packet header (page 57) */		{		OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Version mismatch\r\n");		return (FAIL);		}	/* part of fifth bullet item under verifying the OSPF packet header (page 58) */	return_type = ospf_verify_checksum_field_in_ospf_packet_header (sptr_ospf_header, size_of_ospf_packet);	if (return_type == FAIL)		{		return (FAIL);		}	/* second bullet item under verifying the OSPF packet header (pages 57-58) */	return_type = ospf_verify_area_id_and_get_neighbor (sptr_ospf_header, ptr_to_sptr_interface, source_address, ptr_to_sptr_neighbor);	if (return_type == FAIL)		{		return (FAIL);		}	/* forth and fifth bullet items under verifying the OSPF packet header (page 58) */	swapped_auth_type = net_to_host_short (sptr_ospf_header->authentication_type);	if (swapped_auth_type == (*ptr_to_sptr_interface)->authentication.type)		{		sptr_ospf_authentication = &((*ptr_to_sptr_interface)->authentication);		}	else if (( (*ptr_to_sptr_interface)->flags._bit.secondary_authentication == TRUE) &&		(swapped_auth_type == (*ptr_to_sptr_interface)->authentication2.type))		{		sptr_ospf_authentication = &((*ptr_to_sptr_interface)->authentication2);		}	else		{		OSPF_PRINTF_ALARM (OSPF_ALARM_PRINTF, "OSPF: Received Authentication Type is not supported on this interface\r\n");		return (FAIL);		}	return_type = ospf_authenticate_packet (packet_size, sptr_ospf_header, *ptr_to_sptr_interface, sptr_ospf_authentication,		*ptr_to_sptr_neighbor, sptr_cryptographic_sequence_number);	return (return_type);}/******************************************************************************************************************************/static enum TEST ospf_verify_checksum_field_in_ospf_packet_header (OSPF_HEADER *sptr_ospf_header,ULONG size_of_ospf_packet){	UNION_OSPF_AUTHENTICATION_FIELD authentication_field;	USHORT swapped_auth_type;	enum TEST return_type;	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_verify_checksum_field_in_ospf_packet_header\r\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -