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

📄 ospf_receive_request.c

📁 vxworks下ospf协议栈
💻 C
字号:
/* ospf_receive_request.c *//* Copyright 1998-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02a,22apr03,ram     SPR#76812 Modifications for OSPF performance enhancements01s,10apr03,mwv     SPR 85906 - include IP header size for LSA fragmentation01r,16apr02,jkw     One copy of external and type 11 lsa01q,19jul01,aos     Fixes relating to TSR #24935801p,26sep00,reshma  Added WindRiver CopyRight01o,25sep00,reshma  RFC-1587 implementation for OSPF NSSA Option, also tested against ANVL.01n,07jul00,reshma  Unix compatibility related changes.01m,04apr00,reshma  Added some MIB support (Read only).Passed all important ANVL OSPF tests.01l,23dec99,reshma  Compatibility with VxWorks-IP and VxWorks RTM-interface01k,28dec98,jack    Compiled and added some comments01j,11nov98,jack    Config changes, linted and big endian changes01i,30oct98,jack    Incorporate changes for compilation on Vxworks01h,23aug98,jack    ANVL tested OSPF with PATRICIA tree route table and no recursion01g,10aug98,jack    PATRICIA Route Table Based OSPF Code Base01f,04jun98,jack    Integration with RTM and BGP01e,24apr98,jack    RTM changes01d,10jul97,cindy   Pre-release v1.52b01c,02oct97,cindy   Release Version 1.5201b,22oct96,cindy   Release Version 1.5001a,05jun96,cindy   First Beta Release*//*DESCRIPTIONospf_receive_request.c is used for processing received link state request packets.  This file will process therequest and build the appropriate link state update packet as a reply.This file is used whenever a new OSPF request packet is received.*/#include "ospf.h"#if defined (__OSPF_VIRTUAL_STACK__)#include "ospf_vs_lib.h"#endif /* __OSPF_VIRTUAL_STACK__ *//*******************************************************************************************************************************/static enum OSPF_PACKET_STATE ospf_gather_and_transmit_update_packets (OSPF_LS_REQUEST_HEADER *sptr_ls_request_header,OSPF_NEIGHBOR *sptr_neighbor,	OSPF_INTERFACE *sptr_interface,ULONG size_of_packet);/****************************************************************************//* section 10.7 of OSPF specification (page 93) */enum OSPF_PACKET_STATE ospf_ls_request_packet_received (OSPF_LS_REQUEST_HEADER *sptr_ls_request_header,OSPF_NEIGHBOR *sptr_neighbor,	OSPF_INTERFACE *sptr_interface,ULONG size_of_packet){	enum OSPF_PACKET_STATE return_type;	/* Link State Request Packets should be accepted when the neighbor is in states Exchange, Loading, or Full and ignored otherwise */	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_ls_request_packet_received\r\n");	if (sptr_neighbor->state < OSPF_NEIGHBOR_EXCHANGE)		{		return (OSPF_ERROR_ACKNOWLEDGEMENT_STATE);		}	size_of_packet -= OSPF_PACKET_SIZE;	if (size_of_packet == 0x00000000L)		{		return (OSPF_ERROR_REQUEST_EMPTY);		}	/*	 * Each link state advertisement specified in the Link State request packet should be located in the router's database and copied	 * into Link State Update packets for transmission to the neighbor.	 */	return_type = ospf_gather_and_transmit_update_packets (sptr_ls_request_header, sptr_neighbor, sptr_interface, size_of_packet);  	return (return_type);}/******************************************************************************************************************************/static enum OSPF_PACKET_STATE ospf_gather_and_transmit_update_packets (OSPF_LS_REQUEST_HEADER *sptr_ls_request_header,OSPF_NEIGHBOR *sptr_neighbor,	OSPF_INTERFACE *sptr_interface,ULONG size_of_packet){	OSPF_HEADER *sptr_update_packet;	OSPF_LS_DATABASE_ENTRY *sptr_database;	OSPF_LS_REQUESTED_ADVERTISEMENT *sptr_requested_advertisement;	UNION_OSPF_ADVERTISEMENT_HEADER *uptr_acknowledgement_header;	ULONG interface_mtu;	ULONG authentication_size;	ULONG update_packet_length;	ULONG link_state_id;	ULONG advertising_router;	USHORT length;	USHORT age;#if defined (__OPAQUE_LSA__)	OSPF_TYPE_9_LINK_ADVERTISEMENT_HEADER *sptr_type_9_advertisement_header = NULL;	OSPF_TYPE_10_LINK_ADVERTISEMENT_HEADER *sptr_type_10_advertisement_header = NULL;	OSPF_TYPE_11_LINK_ADVERTISEMENT_HEADER *sptr_type_11_advertisement_header = NULL;	OSPF_LS_OPAQUE_HEADER *opaque_lsa = NULL;	USHORT opaque_lsa_size = 0x0000;	USHORT opaque_ls_header_size = 0x0000;	USHORT data_size = 0x0000;#endif /* __OPAQUE_LSA__ */	OSPF_PRINTF_DEBUG (OSPF_DEBUG_PRINTF, "OSPF: Entering ospf_gather_and_transmit_update_packets\r\n");	sptr_update_packet = ospf_new_link_state_update (&uptr_acknowledgement_header, sptr_interface);	update_packet_length = OSPF_PACKET_SIZE + OSPF_LS_UPDATE_HEADER_SIZE;	if (sptr_update_packet == NULL)		{		return (GOOD_RECEIVE);		}	for (sptr_requested_advertisement = &sptr_ls_request_header->requested_advertisement; size_of_packet != 0x00000000L;		size_of_packet -= OSPF_LS_REQUESTED_ADVERTISEMENT_SIZE)		{		link_state_id = sptr_requested_advertisement->id;		link_state_id = net_to_host_long (link_state_id);		advertising_router = sptr_requested_advertisement->advertising_router;		advertising_router = net_to_host_long (advertising_router);		/* SPR#76812 */		sptr_database = ospf_find_LSA (sptr_interface->sptr_area, link_state_id, advertising_router, sptr_requested_advertisement->type);		if ((sptr_requested_advertisement->type < OSPF_LS_ROUTER) || (sptr_requested_advertisement->type > OSPF_LS_MAX) ||			(sptr_database == NULL))			{			ospf_execute_neighbor_state_machine (OSPF_BAD_LINK_STATE_REQUEST, sptr_neighbor->state, sptr_interface, sptr_neighbor);			ospf_free_an_ospf_send_packet (sptr_update_packet);			sptr_update_packet = NULL;			return (OSPF_ERROR_REQUEST_BOGUS);					/* didn't find the advertisement in the database, or the request type was invalid */			}		length = sptr_database->advertisement.sptr_router->ls_header.length;		length = net_to_host_short (length);		authentication_size = ospf_get_authentication_size (sptr_interface);		interface_mtu = ospf_get_interface_mtu (sptr_interface);        /* SPR 85906 */        if ((update_packet_length + length + authentication_size + OSPF_MAXIMUM_IP_HEADER_SIZE) > interface_mtu)			{			sptr_update_packet->rest_of_packet.ls_update.number_of_advertisements = host_to_net_long (				sptr_update_packet->rest_of_packet.ls_update.number_of_advertisements);			ospf_tx_packet (sptr_update_packet, sptr_interface, OSPF_LINK_STATE_UPDATE_PACKET, update_packet_length, sptr_neighbor->address, FALSE);			memset (sptr_update_packet, 0x0, update_packet_length);			uptr_acknowledgement_header = (UNION_OSPF_ADVERTISEMENT_HEADER *) &(sptr_update_packet->rest_of_packet.ls_update.advertisement_header); /* after txmitting the packet, reset the pointer so that sptr_update_packet can be reused */			update_packet_length = OSPF_PACKET_SIZE + OSPF_LS_UPDATE_HEADER_SIZE;			}		++sptr_update_packet->rest_of_packet.ls_update.number_of_advertisements;#if defined (__OPAQUE_LSA__)	if (sptr_database->advertisement.sptr_router->ls_header.type == OSPF_LS_TYPE_9)		{		opaque_ls_header_size = sizeof(OSPF_LS_OPAQUE_HEADER);		sptr_type_9_advertisement_header = sptr_database->advertisement.sptr_type_9;		data_size = sptr_type_9_advertisement_header->ls_header.length;		data_size = net_to_host_short(data_size);		data_size = (USHORT)(data_size - OSPF_LS_HEADER_SIZE);		opaque_lsa_size = (USHORT)(data_size + opaque_ls_header_size);		opaque_lsa = (OSPF_LS_OPAQUE_HEADER *) table_malloc(1, opaque_lsa_size);		if (opaque_lsa != NULL)			{			memset(opaque_lsa, 0x00, opaque_lsa_size);			memcpy(opaque_lsa, &(sptr_type_9_advertisement_header->ls_header), opaque_ls_header_size);			if ((sptr_type_9_advertisement_header->data != NULL) && (data_size > 0))				{				memcpy(((BYTE *)(opaque_lsa)+opaque_ls_header_size), sptr_type_9_advertisement_header->data, data_size);				}			memcpy ((void *) &(uptr_acknowledgement_header->router), (const void *)opaque_lsa, opaque_lsa_size);			table_free(opaque_lsa);			opaque_lsa = NULL;			uptr_acknowledgement_header->router.ls_header.checksum = 0x0000;			uptr_acknowledgement_header->router.ls_header.checksum = ospf_generate_LS_checksum ((void *) &(uptr_acknowledgement_header->router), (USHORT)opaque_lsa_size,				(BYTE *) &uptr_acknowledgement_header->router.ls_header.checksum);			}		}	else if (sptr_database->advertisement.sptr_router->ls_header.type == OSPF_LS_TYPE_10)		{		opaque_ls_header_size = sizeof(OSPF_LS_OPAQUE_HEADER);		sptr_type_10_advertisement_header = sptr_database->advertisement.sptr_type_10;		data_size = sptr_type_10_advertisement_header->ls_header.length;		data_size = net_to_host_short(data_size);		data_size = (USHORT)(data_size - OSPF_LS_HEADER_SIZE);		opaque_lsa_size = (USHORT)(data_size + opaque_ls_header_size);		opaque_lsa = (OSPF_LS_OPAQUE_HEADER *) table_malloc(1, opaque_lsa_size);		if (opaque_lsa != NULL)			{			memset(opaque_lsa, 0x00, opaque_lsa_size);			memcpy(opaque_lsa, &(sptr_type_10_advertisement_header->ls_header), opaque_ls_header_size);			if ((sptr_type_10_advertisement_header->data != NULL) && (data_size > 0))				{				memcpy(((BYTE *)(opaque_lsa)+opaque_ls_header_size), sptr_type_10_advertisement_header->data, data_size);				}			memcpy ((void *) &(uptr_acknowledgement_header->router), (const void *)opaque_lsa, opaque_lsa_size);			table_free(opaque_lsa);			opaque_lsa = NULL;			uptr_acknowledgement_header->router.ls_header.checksum = 0x0000;			uptr_acknowledgement_header->router.ls_header.checksum = ospf_generate_LS_checksum ((void *) &(uptr_acknowledgement_header->router), (USHORT)opaque_lsa_size,				(BYTE *) &uptr_acknowledgement_header->router.ls_header.checksum);			}		}	else if (sptr_database->advertisement.sptr_router->ls_header.type == OSPF_LS_TYPE_11)		{		opaque_ls_header_size = sizeof(OSPF_LS_OPAQUE_HEADER);		sptr_type_11_advertisement_header = sptr_database->advertisement.sptr_type_11;		data_size = sptr_type_11_advertisement_header->ls_header.length;		data_size = net_to_host_short(data_size);		data_size = (USHORT)(data_size - OSPF_LS_HEADER_SIZE);		opaque_lsa_size = (USHORT)(data_size + opaque_ls_header_size);		opaque_lsa = (OSPF_LS_OPAQUE_HEADER *) table_malloc(1, opaque_lsa_size);		if (opaque_lsa != NULL)			{			memset(opaque_lsa, 0x00, opaque_lsa_size);			memcpy(opaque_lsa, &(sptr_type_11_advertisement_header->ls_header), opaque_ls_header_size);			if ((sptr_type_11_advertisement_header->data != NULL) && (data_size > 0))				{				memcpy(((BYTE *)(opaque_lsa)+opaque_ls_header_size), sptr_type_11_advertisement_header->data, data_size);				}			memcpy ((void *) &(uptr_acknowledgement_header->router), (const void *)opaque_lsa, opaque_lsa_size);			table_free(opaque_lsa);			opaque_lsa = NULL;			uptr_acknowledgement_header->router.ls_header.checksum = 0x0000;			uptr_acknowledgement_header->router.ls_header.checksum = ospf_generate_LS_checksum ((void *) &(uptr_acknowledgement_header->router), (USHORT)opaque_lsa_size,				(BYTE *) &uptr_acknowledgement_header->router.ls_header.checksum);			}		}	else		{		memcpy ((void *) uptr_acknowledgement_header, (const void *) sptr_database->advertisement.sptr_router, (size_t) length);		}#else /* __OPAQUE_LSA__ */		memcpy ((void *) uptr_acknowledgement_header, (const void *) sptr_database->advertisement.sptr_router, (size_t) length);#endif /* __OPAQUE_LSA__ */		age = sptr_database->advertisement.sptr_router->ls_header.age;		age = net_to_host_short (age);		age = (USHORT) (age + sptr_interface->transmit_delay);		uptr_acknowledgement_header->router.ls_header.age = (USHORT) ospf_min (age, OSPF_MAXIMUM_AGE);		uptr_acknowledgement_header->router.ls_header.age = host_to_net_short (uptr_acknowledgement_header->router.ls_header.age);		uptr_acknowledgement_header = (UNION_OSPF_ADVERTISEMENT_HEADER *) ((ULONG) uptr_acknowledgement_header + length);		update_packet_length += length;		sptr_requested_advertisement = (OSPF_LS_REQUESTED_ADVERTISEMENT *) ((ULONG) sptr_requested_advertisement + OSPF_LS_REQUESTED_ADVERTISEMENT_SIZE);		}	if (sptr_update_packet->rest_of_packet.ls_update.number_of_advertisements != 0x00000000L)		{		sptr_update_packet->rest_of_packet.ls_update.number_of_advertisements = host_to_net_long (			sptr_update_packet->rest_of_packet.ls_update.number_of_advertisements);		ospf_tx_packet (sptr_update_packet, sptr_interface, OSPF_LINK_STATE_UPDATE_PACKET, update_packet_length, sptr_neighbor->address, /*TRUE*/FALSE);		ospf_free_an_ospf_send_packet (sptr_update_packet);		sptr_update_packet = NULL;		}	else        {		ospf_free_an_ospf_send_packet (sptr_update_packet);        sptr_update_packet = NULL;        }	return (GOOD_RECEIVE);}

⌨️ 快捷键说明

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