mpsend.c

来自「这是全套的PPP协议的源码」· C语言 代码 · 共 962 行 · 第 1/2 页

C
962
字号
	USHORT				ppp_mp_header_length = 0;	USHORT				mp_header_length = 0;	M_BLK_ID 			ppp_encapsulated_mp_packet = NULL;	MP_SEND_INTERFACE	mpSendInterfaceData;	PFW_OBJ				*pfwObj = NULL;	MP_FRAMING_LAYER_STACK_DATA *pStackData = 			(MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData;	if (packet == NULL)		return ERROR;	pfwObj = pfwStackObjPfwGet (pMpFramingLayerState->stackObj);	if (pfwObj == NULL)		{		pfwPrintError (__FILE__, "mp_encapsulate_ppp_fragment_and_send",					 __LINE__, NULL, NULL, "Null framework reference");		}	/*	 * find the total PPP encapsulated MP packet length and get the 	 * mBlk-clBlk-cluster for the calculated length 	 */	if (pStackData->bundle.sending_end.use_short_sequence_number == TRUE)		{		mp_packet_length = sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER) 							+ ppp_fragment_length ;		mp_header_length = sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); 		}	else		{		mp_packet_length = sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER) 							+ ppp_fragment_length ;		mp_header_length = sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER);		}	ppp_encapsulated_mp_packet_length = mp_packet_length 							+ sizeof (PPP_MP_PACKET)							- VARIABLE_NUMBER_OF_BYTES;	ppp_mp_header_length = mp_header_length + sizeof (PPP_MP_PACKET)						   - VARIABLE_NUMBER_OF_BYTES;	ppp_encapsulated_mp_packet = m_prepend(packet, ppp_mp_header_length, M_DONTWAIT);	if (ppp_encapsulated_mp_packet == NULL)		{#ifdef PPP_DEBUG		printf ("Error while prepending MP header for MP encapsulation\n");#endif /* PPP_DEBUG */		return ERROR;		}	if (encapsulate_ppp_fragment (pMpFramingLayerState, fragment_flag, packet, 								  ppp_encapsulated_mp_packet, 								  ppp_fragment_length) == ERROR) 		{#ifdef PPP_DEBUG		printf ("MP encapsulation Error \n");#endif /* PPP_DEBUG */		netMblkClChainFree (ppp_encapsulated_mp_packet);				return ERROR;		}	ppp_encapsulated_mp_packet->mBlkHdr.mFlags |= M_PKTHDR;	ppp_encapsulated_mp_packet->mBlkPktHdr.len = 						ppp_encapsulated_mp_packet_length;	ppp_encapsulated_mp_packet->mBlkHdr.mLen = ppp_mp_header_length;	switch (packet_type)		{		case CONTROL_PACKET:				mpSendInterfaceData.state = pStackData->bundle.sending_end.							   links[link_number].pMpControlLayerState;								mpSendInterfaceData.packet = ppp_encapsulated_mp_packet;				/* Add the packet to the mpSend queue */				if (mpSendQueueAdd (pfwObj, (FUNCPTR) _mpSend,								(void *)&mpSendInterfaceData, 								sizeof (MP_SEND_INTERFACE)) == ERROR)					{					netMblkClChainFree (ppp_encapsulated_mp_packet);							return ERROR;					}			break;		case DATA_PACKET:						mpSendInterfaceData.state = pStackData->bundle.sending_end.							   links[link_number].pMpInterfaceLayerState;								mpSendInterfaceData.packet = ppp_encapsulated_mp_packet;				/* Add the packet to the mpSend queue */				if (mpSendQueueAdd (pfwObj, (FUNCPTR) _mpSend,							(void *)&mpSendInterfaceData, 							sizeof (MP_SEND_INTERFACE)) == ERROR)					{					netMblkClChainFree (ppp_encapsulated_mp_packet);							return ERROR;					}			break;		default:			/* If error free the mBlk-clBlk-cluster */			netMblkClChainFree (ppp_encapsulated_mp_packet);					return ERROR;		}	return OK;	}/******************************************************************************** encapsulate_ppp_fragment - Encapsulates PPP fragment with MP procedure** This function encapsulates the PPP fragment with MP procedure. It checks the * MP header format configured for the sending end of the bundle. Accordingly, it * encapsulates the fragment either with long sequence header format or * short sequence header format. * 		* RETURNS OK/ERROR*/LOCAL STATUS encapsulate_ppp_fragment 	(	PFW_PLUGIN_OBJ_STATE	*pMpFramingLayerState,	enum FRAGMENT_FLAG		fragment_flag,	M_BLK_ID				packet,	M_BLK_ID 				ppp_encapsulated_mp_packet,	USHORT					ppp_fragment_length	)	{	char 			*ptr_mp_packet = NULL;	PPP_MP_PACKET	*sptr_ppp_packet_with_mac_header = NULL;	MP_FRAMING_LAYER_STACK_DATA *pStackData = 				(MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData;	if ((packet == NULL) || (ppp_encapsulated_mp_packet == NULL))		return ERROR;	sptr_ppp_packet_with_mac_header = mtod (ppp_encapsulated_mp_packet, 											PPP_MP_PACKET *);	sptr_ppp_packet_with_mac_header->header.protocol_type = 								htons (MULTILINK_PROTOCOL);	ptr_mp_packet = sptr_ppp_packet_with_mac_header->protocol_data; 	if (pStackData->bundle.sending_end.use_short_sequence_number == TRUE)		{				/* encapsulate with short sequence header */		mp_populate_ppp_fragment_header_with_short_sequence_number 			((MP_PACKET_WITH_SHORT_SEQUENCE_NUMBER *) ptr_mp_packet, 			pStackData->bundle.sending_end.master_short_sequence_number,			fragment_flag); 					pStackData->bundle.sending_end.master_short_sequence_number++;		}	else if (pStackData->bundle.sending_end.use_short_sequence_number == FALSE)		{		/* encapsulate with long sequence header */		mp_populate_ppp_fragment_header_with_long_sequence_number 			((MP_PACKET_WITH_LONG_SEQUENCE_NUMBER *)ptr_mp_packet, 			pStackData->bundle.sending_end.master_long_sequence_number,			fragment_flag);				pStackData->bundle.sending_end.master_long_sequence_number++;		}	else		return ERROR;	return OK;	}/******************************************************************************** mp_populate_ppp_fragment_header_with_short_sequence_number -  *		Populates the fragment header with short sequence number header format * 		* This function encapsulates a PPP fragment header with short sequence number * header format. It installs the sequence number and sets fragment flags * according to the fragment_flag passed.** RETURNS OK/ERROR*/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	)	{	if (sptr_mp_packet == NULL)				return ERROR;	/* Assigning short sequence number to MP header */	install_short_sequence_number_into_header 				(&sptr_mp_packet->header, short_sequence_number);	/* MUST be set to zero RFC 1717 p.8 */	sptr_mp_packet->header.reserved_field = 0; 	switch (fragment_flag)		{		case FIRST_FRAGMENT:			sptr_mp_packet->header.first_fragment_flag = MP_ON;			sptr_mp_packet->header.last_fragment_flag = MP_OFF;			break;		case LAST_FRAGMENT:					sptr_mp_packet->header.first_fragment_flag = MP_OFF;			sptr_mp_packet->header.last_fragment_flag = MP_ON;						break;		case ONLY_FRAGMENT:					sptr_mp_packet->header.first_fragment_flag = MP_ON;			sptr_mp_packet->header.last_fragment_flag = MP_ON;						break;		case NOT_END_FRAGMENT:					sptr_mp_packet->header.first_fragment_flag = MP_OFF;			sptr_mp_packet->header.last_fragment_flag = MP_OFF;						break;		default:						return ERROR;		}	/* Convert the short sequence number header to network order  */	convert_short_sequence_number_header_into_network_order 						(&(sptr_mp_packet->header));	return OK;	}/******************************************************************************** install_short_sequence_number_into_header - *			 		Installs short sequence number in MP header  ** This function copies the given short sequence number in the sequence number * field of the MP header.** RETURNS N/A*/LOCAL void install_short_sequence_number_into_header 	(	SHORT_SEQUENCE_NUMBER_MP_HEADER *sptr_short_sequence_number_mp_header, 	USHORT short_sequence_number	)	{	memcpy ((void *) sptr_short_sequence_number_mp_header, 			(void *) &short_sequence_number, 			sizeof (USHORT));	}/******************************************************************************** convert_short_sequence_number_header_into_network_order -  ** Convert the short sequence number header to network order   		** RETURNS N/A*/LOCAL void convert_short_sequence_number_header_into_network_order	(	SHORT_SEQUENCE_NUMBER_MP_HEADER *sptr_short_sequence_number_mp_header	)	{	USHORT short_sequence_number_mp_header_in_network_order = 0;	USHORT *usptr_short_sequence_number_mp_header = NULL;	USHORT short_sequence_number_mp_header_in_ushort = 0;	usptr_short_sequence_number_mp_header = 				(USHORT *) sptr_short_sequence_number_mp_header;	short_sequence_number_mp_header_in_ushort = 					*usptr_short_sequence_number_mp_header;	short_sequence_number_mp_header_in_network_order = 				htons (short_sequence_number_mp_header_in_ushort);	memcpy ((void *) sptr_short_sequence_number_mp_header, 			(void *) &short_sequence_number_mp_header_in_network_order,			sizeof (USHORT));	}/******************************************************************************** mp_populate_ppp_fragment_header_with_long_sequence_number -  *		Populates the fragment header with long sequence number header format * 		* This function encapsulates a PPP fragment header with long sequence number * header format. It installs the sequence number and sets fragment flags * according to the fragment_flag passed.** RETURNS OK/ERROR*/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	)	{		if (sptr_mp_packet == NULL)		return ERROR;	/* Assigning short sequence number to MP header */	install_long_sequence_number_into_header 					(&sptr_mp_packet->header, long_sequence_number);	/* MUST be set to zero RFC 1717 p.8 */	sptr_mp_packet->header.reserved_field = 0; 	switch (fragment_flag)		{		case FIRST_FRAGMENT:			sptr_mp_packet->header.first_fragment_flag = MP_ON;			sptr_mp_packet->header.last_fragment_flag = MP_OFF;			break;		case LAST_FRAGMENT:					sptr_mp_packet->header.first_fragment_flag = MP_OFF;			sptr_mp_packet->header.last_fragment_flag = MP_ON;						break;		case ONLY_FRAGMENT:					sptr_mp_packet->header.first_fragment_flag = MP_ON;			sptr_mp_packet->header.last_fragment_flag = MP_ON;						break;		case NOT_END_FRAGMENT:					sptr_mp_packet->header.first_fragment_flag = MP_OFF;			sptr_mp_packet->header.last_fragment_flag = MP_OFF;						break;		default:			return ERROR;		}	/* Convert the long sequence number header to network order  */	convert_long_sequence_number_header_into_network_order 						(&sptr_mp_packet->header);	return OK;	}/******************************************************************************** install_long_sequence_number_into_header - *			 		Installs long sequence number in MP header  ** This function copies the given long sequence number in the sequence number * field of the MP header.** RETURNS N/A*/LOCAL void install_long_sequence_number_into_header 	(	LONG_SEQUENCE_NUMBER_MP_HEADER *sptr_long_sequence_number_mp_header, 	ULONG long_sequence_number	)	{	if (sptr_long_sequence_number_mp_header == NULL)		return;	memcpy ((void *) sptr_long_sequence_number_mp_header, 			(void *) &long_sequence_number, 			sizeof (ULONG));	}/******************************************************************************** convert_long_sequence_number_header_into_network_order - * 							* Convert the long sequence number header to network order  * 		* RETURNS N/A*/LOCAL void convert_long_sequence_number_header_into_network_order 	(	LONG_SEQUENCE_NUMBER_MP_HEADER *sptr_long_sequence_number_mp_header	)	{	ULONG long_sequence_number_mp_header_in_network_order = 0;	ULONG long_sequence_number_mp_header_in_ulong = 0;	if (sptr_long_sequence_number_mp_header == NULL)		return;	memcpy ((void *) &long_sequence_number_mp_header_in_ulong, 			(void *) sptr_long_sequence_number_mp_header, 			sizeof (ULONG));	long_sequence_number_mp_header_in_network_order = 				htonl (long_sequence_number_mp_header_in_ulong);	memcpy ((void *) sptr_long_sequence_number_mp_header, 			(void *) &long_sequence_number_mp_header_in_network_order, 			sizeof (ULONG)); 	}/********************************************************************************* _mpSend - stub routine for supporting MP Send Queue operation** RETURNS : N/A**/void _mpSend    (    void *data    )    {    MP_SEND_INTERFACE  *pSendData = (MP_SEND_INTERFACE *)data;    if (pSendData == NULL)        {	pfwPrintError (__FILE__, "_mpSend", __LINE__, 		       NULL, NULL, "Null argument");	return;        }    pfwSend (pSendData->state, pSendData->packet);    }

⌨️ 快捷键说明

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