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

📄 mpsend.c

📁 这是全套的PPP协议的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* mpsend.c - MP Send related functions *//* Copyright 1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01n,23jan03,ijm fix for SPR#85876, netStackDataPoolShow displays increasing                count for HEADER mblocks and negative count for DATA mblocks,                removed redundant packet frees in mp_send_ppp_packet, free                packet if ENOBUFS in  mp_fragment_ppp_packet_and_send,                changed logMsg to printf01m,06aug02,jr  fixed build warnings 01l,05may02,vk  modifications to use m_prepend() to attach MP header and                 fragment data01k,28apr02,vk  modification as part of ARM fixes01j,23feb02,ak  removing the state lock and release in mp_send_ppp_packet()01i,04jan02,vk  Modifications to avoid copying the input to a local buffer                 before fragmentation01h,11dec01,ak  Made incrementing buffer pointer conditional                 in mp_fragment_ppp_packet_and_send01g,08oct01,ak  Maximum fragment length supported on a link is PPP MAC header                length subtracted from the MTU supported from the link01f,19sep01,ak  Modification to fragment the packet based on MRU contribution                of individual links01e,19sep01,ak	Removed the check incoming packet size > remote MRRU in                 mp_send_ppp_packet()01d,19sep01,ak 	Setting the MBLK header after netTupleGet in                 mp_fragment_ppp_packet_and_send()01c,19sep01,ak  Support for rotating the links for non-fragmented packets01b,30may01,ijm fixed memory leak problem in mp_fragment_ppp_packet_and_send()01a,20feb01,as  created from routerware source base*//*DESCRIPTIONThis module implements the MP send related functions and is partof the MP_FRAMING_LAYER functionality.The PPP packet to be sent is fragmented and encapsulated with the MP headersbased on the SHORT sequence or the LONG sequence header format. The fragmentlength is decided based on the bandwidth of the individual links of the bundle,through which the fragments are sent.The constructed fragments are finally sent to the MP_INTERFACE_LAYER componentof the MEMBER stack, through the queue if it is enabled. If the queue is notenabled, the fragments are sent using the pfwSend function.INCLUDE FILES : mpFramingLayerP.h*//* defines */#define SIZE_OF_PPP_CONTROL_AND_ADDRESS_FIELDS				2#define HALF_SIZE_OF_PPP_PROTOCOL_FIELD					1#define BUNDLE_CLOSED							0/* includes */#include "stdio.h"#include "private/ppp/mpFramingLayerP.h"#include "logLib.h"/* externs */IMPORT STATUS mp_send_ppp_packet (PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState,					M_BLK_ID  pMblkId,	PFW_PACKET_TYPE	packet_type);IMPORT STATUS mpSendQueueAdd (PFW_OBJ *pfwObj, FUNCPTR jobHandlerFunc,							  void *data, int);/* locals and forwards */LOCAL void mp_compress_ppp_header 	(	M_BLK_ID pMblkId	);LOCAL STATUS mp_fragment_ppp_packet_and_send 	(	PFW_PLUGIN_OBJ_STATE 	*pMpFramingLayerState, 	M_BLK_ID 				packet, 	PFW_PACKET_TYPE 		packet_type	);LOCAL STATUS mp_encapsulate_ppp_fragment_and_send 	(	PFW_PLUGIN_OBJ_STATE 	*pMpFramingLayerState, 	enum FRAGMENT_FLAG 		fragment_flag,	M_BLK_ID 				packet, 	USHORT 					link_number, 	USHORT 					ppp_fragment_length, 	PFW_PACKET_TYPE 		packet_type	);LOCAL STATUS encapsulate_ppp_fragment 	(	PFW_PLUGIN_OBJ_STATE 	*pMpFramingLayerState, 	enum FRAGMENT_FLAG 		fragment_flag,	M_BLK_ID 				packet, 	M_BLK_ID	 			pppp_encapsulated_mp_packet, 	USHORT 					ppp_fragment_length/*	UINT 					packet_offset    */	);LOCAL STATUS mp_populate_ppp_fragment_header_with_short_sequence_number	(	MP_PACKET_WITH_SHORT_SEQUENCE_NUMBER 	*sptr_mp_packet,	USHORT									short_sequence_number, 	enum FRAGMENT_FLAG	 					fragment_flag	);LOCAL void install_short_sequence_number_into_header 	(	SHORT_SEQUENCE_NUMBER_MP_HEADER 	*sptr_short_sequence_number_mp_header, 	USHORT 								short_sequence_number	);LOCAL void convert_short_sequence_number_header_into_network_order 	(	SHORT_SEQUENCE_NUMBER_MP_HEADER 	*sptr_short_sequence_number_mp_header	);STATUS mp_populate_ppp_fragment_header_with_long_sequence_number	(	MP_PACKET_WITH_LONG_SEQUENCE_NUMBER		*sptr_mp_packet,	ULONG 									long_sequence_number,	enum FRAGMENT_FLAG	 					fragment_flag	);LOCAL void install_long_sequence_number_into_header 	(	LONG_SEQUENCE_NUMBER_MP_HEADER 		*sptr_long_sequence_number_mp_header, 	ULONG 								long_sequence_number	);LOCAL void convert_long_sequence_number_header_into_network_order	(	LONG_SEQUENCE_NUMBER_MP_HEADER 		*sptr_long_sequence_number_mp_header	);void _mpSend 	(	void *data	);/******************************************************************************** mp_send_ppp_packet - fragments the PPP packet and sends the fragments ** This function fragments the given PPP packet and encapsulates the fragments * with MP procedure and sends them.** RETURNS OK/ERROR*/STATUS mp_send_ppp_packet 	(	PFW_PLUGIN_OBJ_STATE 	*pMpFramingLayerState,	/* plugin object state */	M_BLK_ID  		 		pMblkId,				/* packet to send */	PFW_PACKET_TYPE		 	packet_type				/* packet type */	)	{	USHORT 		pppPacketLength = 0;	M_BLK_ID 	mblkPacket = NULL;	MP_FRAMING_LAYER_STACK_DATA *pStackData = 				(MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData;    if ((mblkPacket = pMblkId) == NULL)		{#ifdef PPP_DEBUG		printf ("Null packet for MP Send \n");#endif /* PPP_DEBUG */		return ERROR;		}    if ((mblkPacket->mBlkHdr.mFlags & M_PKTHDR)  && 										(mblkPacket->mBlkHdr.mNext != NULL))		{		pppPacketLength = mblkPacket->mBlkPktHdr.len;		}    else		{		pppPacketLength = mblkPacket->mBlkHdr.mLen;		}	if (pStackData->bundle.sending_end.no_of_links == 0 || 							pStackData->bundle_state == MP_BUNDLE_CLOSED_STATE)		{#ifdef PPP_DEBUG		printf ("mp_send_ppp_packet: No Link present or bundle is in closed state \n");#endif /* PPP_DEBUG */		netMblkClChainFree (mblkPacket);		return ERROR;		}	mp_compress_ppp_header (mblkPacket);	if (mp_fragment_ppp_packet_and_send (pMpFramingLayerState, 						mblkPacket, packet_type) == OK)		{		return OK;		}	return ERROR;	}/******************************************************************************** mp_compress_ppp_header - *					compresses the Protocol Field in PPP encapsulated packet** This function compresses the protocol field in the given PPP encapsulated * packet* * RETURNS N/A*/LOCAL void mp_compress_ppp_header 	(	M_BLK_ID packet			/* packet to compress */	)	{    PPP_PACKET 	*pppPacket = NULL;    pppPacket = mtod (packet, PPP_PACKET *);#if (_BYTE_ORDER == _BIG_ENDIAN) /* big endian support */	if ((pppPacket->header.protocol_type & 0xff00) == 0x0000)#else	if ((pppPacket->header.protocol_type & 0x00ff) == 0x0000)#endif		{		packet->mBlkHdr.mData = packet->mBlkHdr.mData 								+ HALF_SIZE_OF_PPP_PROTOCOL_FIELD;		if (packet->mBlkHdr.mNext != NULL)			{			packet->mBlkPktHdr.len = packet->mBlkPktHdr.len 								- HALF_SIZE_OF_PPP_PROTOCOL_FIELD;			packet->mBlkHdr.mLen  = packet->mBlkHdr.mLen 								- HALF_SIZE_OF_PPP_PROTOCOL_FIELD;			}		else			packet->mBlkHdr.mLen  = packet->mBlkHdr.mLen 								- HALF_SIZE_OF_PPP_PROTOCOL_FIELD;		}	}/******************************************************************************** mp_fragment_ppp_packet_and_send - fragment the Protocol Field Compressied * 		PPP packet. Also encapsulates the fragments and send them.** This function fragments the given PFC applied PPP packet, encapsulates the * fragments with MP procedure and sends them. It does not fragment a packet if * its size is smaller than a value configured in the profile of the * MP_FRAMING_LAYER component. While fragmenting, it balances the load across * the links in the bundle with the bandwidth share information available on the * sending end of the bundle class.** RETURNS OK/ERROR*/LOCAL STATUS mp_fragment_ppp_packet_and_send 	(	PFW_PLUGIN_OBJ_STATE 	*pMpFramingLayerState, 	M_BLK_ID 				packet, 	PFW_PACKET_TYPE 		packet_type	)	{	USHORT				link_number = 0;	UINT 				pppPacketLength = 0;	UINT 				sentPacketLength = 0;	UINT 				fragment_length = 0;	enum FRAGMENT_FLAG  fragment_flag;	PFW_OBJ 			*pfwObj = NULL;			int 				remainingLen = 0;	BOOL				bFirstFragment = 0;	UINT				majorFragmentLength = 0;	UINT 				packet_offset = 0;	M_BLK_ID			fragMblk;	MP_FRAMING_LAYER_STACK_DATA *pStackData = 				(MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData;	if (packet == NULL)		return ERROR;	if ((packet->mBlkHdr.mFlags & M_PKTHDR)  && (packet->mBlkHdr.mNext != NULL))		{		pppPacketLength = packet->mBlkPktHdr.len;		}    	else		{		pppPacketLength = packet->mBlkHdr.mLen;		}    	pfwObj = pMpFramingLayerState->pluginObj->pfwObj;	/* do not fragment the packet, only encapsulate with MP procedure and send */	if (pppPacketLength < pStackData->bundle.sending_end.small_packet_length)		{		if (pStackData->bundle.sending_end.linkForNonFragmentedPacket >= 			pStackData->bundle.sending_end.no_of_links)				pStackData->bundle.sending_end.linkForNonFragmentedPacket = 0;		link_number = 			pStackData->bundle.sending_end.linkForNonFragmentedPacket++;		fragment_length	= pppPacketLength;			fragment_flag 	= ONLY_FRAGMENT;#ifdef PPP_DEBUG    	printf ("MP Tx: Packet sent through the single link %d in the bundle\n",				(int) link_number);#endif /* PPP_DEBUG */		fragMblk = netMblkChainDup(pStackData->netPoolId,packet,					0,M_COPYALL,M_DONTWAIT);		if (fragMblk == NULL)			{#ifdef PPP_DEBUG			printf ("ENOBUFS while getting mBlk for single MP fragment\n");#endif /* PPP_DEBUG */            netMblkClChainFree (packet);			return ERROR;			}		if (mp_encapsulate_ppp_fragment_and_send (pMpFramingLayerState, 					fragment_flag, fragMblk, link_number, 					fragment_length, packet_type) == OK)			{			netMblkClChainFree (packet); 			return OK;				}		else			{			netMblkClChainFree (packet);			return ERROR;			}		}	else		/* fragment the packet, encapsulate with MP procedure and send */		{		remainingLen = pppPacketLength;		bFirstFragment = TRUE;		while (remainingLen > 0)			{			sentPacketLength = 0;			if (remainingLen <= (pStackData->bundle.sending_end.aggregateMru - 								 (PPP_WITH_MAC_HEADER_LENGTH * 								 pStackData->bundle.sending_end.no_of_links)))				majorFragmentLength = remainingLen;			else				majorFragmentLength = 					(pStackData->bundle.sending_end.aggregateMru - 					(PPP_WITH_MAC_HEADER_LENGTH *					 pStackData->bundle.sending_end.no_of_links));			for (link_number = 0x0000; 			 link_number < pStackData->bundle.sending_end.no_of_links; 			 ++link_number)				{#if defined (INCLUDE_FLOATING_POINT)				fragment_length	= 				pStackData->bundle.sending_end.mru_share[link_number] 				* majorFragmentLength;#else				fragment_length	= (majorFragmentLength 				* pStackData->bundle.sending_end.mru_share[link_number]) 				/ 100;#endif					/* If the link is not the last link */				if (link_number != (pStackData->bundle.sending_end.no_of_links - 1))					{					sentPacketLength = sentPacketLength + fragment_length;					}					/* the last link */				else					{					/* In the last link send the remaining whole packet */					fragment_length	= majorFragmentLength - sentPacketLength;					}#ifdef PPP_DEBUG             printf ("MP: Fragmenting packet of length 0x%x for link 0x%x\n",				(int) fragment_length,(int)link_number);#endif /* PPP_DEBUG */			/* Assign the fragment flag information */				if (bFirstFragment)					{					bFirstFragment = FALSE;					if ((remainingLen - fragment_length) <= 0)						{						fragment_flag = ONLY_FRAGMENT;										}					else						{						fragment_flag = FIRST_FRAGMENT;										}					}				else if ((remainingLen - fragment_length) <= 0)					{					fragment_flag = LAST_FRAGMENT;					}				else					{					fragment_flag = NOT_END_FRAGMENT;					} 				if (fragment_length == 0x0000)					{					continue;					}				fragMblk = netMblkChainDup(pStackData->netPoolId,packet,					packet_offset,fragment_length,M_DONTWAIT);				if (fragMblk == NULL)					{#ifdef PPP_DEBUG					printf ("No pool memory for offset %d, fragment length %d\n",						packet_offset, fragment_length);#endif /* PPP_DEBUG */                    netMblkClChainFree (packet); 					return ERROR;					}				if (mp_encapsulate_ppp_fragment_and_send (pMpFramingLayerState, 					fragment_flag, fragMblk, link_number, 					fragment_length, packet_type) == ERROR)					{#ifdef PPP_DEBUG					printf ("Error while encapsulating the PPP packet for MP\n");#endif /* PPP_DEBUG */					return ERROR;					}				packet_offset += fragment_length; 								remainingLen -= fragment_length;				} /* end of for */			} /* end of while */   	     netMblkClChainFree (packet); 		} /* end of else */	return OK;				}/******************************************************************************** mp_encapsulate_ppp_fragment_and_send - *					Encapsulates a PPP fragment with MP procedure and sends it** This function allocates memory to store the PPP fragment with MP and PPP * encapsulation. It encapsulates the PPP fragment with MP procedure and sends it.* 		* RETURNS OK/ERROR*/LOCAL STATUS mp_encapsulate_ppp_fragment_and_send 	(	PFW_PLUGIN_OBJ_STATE	*pMpFramingLayerState,	enum FRAGMENT_FLAG		fragment_flag,	M_BLK_ID				packet,							USHORT					link_number,	USHORT					ppp_fragment_length, 	PFW_PACKET_TYPE			packet_type	)	{	USHORT 				mp_packet_length = 0;	USHORT 				ppp_encapsulated_mp_packet_length = 0;

⌨️ 快捷键说明

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