📄 mpreassemble.c
字号:
/* mpReassemble.c - MP re-assemble related source file *//* Copyright 2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02k,14may03,ijm fixed diab build warnings02j,23jan03,ijm removed redundant settings of MT_DATA as part of SPR#85876, changed logMsg to printf02i,06aug02,jr fixed build warnings 01h,23feb02.as storing next pointer while deleting a ppp fragment in funtion discard_fragment_range storing next pointer while deleting a ppp fragment in funtion discard_fragments_up_to_index 01g,19feb02.ak input parameter validation in all the functions01f,08oct01,ak removed unwanted debug messages in adjust_reassembled_ppp_packet()01e,19sep01,ak bug fixing in setting mflags in the MBLKs in the re-assembled packet01d,21apr01,nts code clean-up01c,04apr01,nts changed fragments array to fragment list and made associated changes in all the related functions01b,02apr01,nts changed fragments from flat memory to MBLK-CLBLK-clusters01a,21feb01,nts created from routerware source base*//**$Log:: /Rtrware/devdrvrs/Mp/mpreassm $ * * 5 3/12/99 11:24a Nishit * Mofidication in reassembly * * 4 11/18/98 7:50a Nishit * -1 is now 0xffffffffL * * 3 4/30/98 3:02p Alex * Mp v4.2.0 check in * * 1 4/24/98 12:56a Release Engineer * code cleanup, code style changes, * linted, system level test * MP v4.2.0*//*DESCRIPTIONThis module implements the MP re-assemble related functions. When ever anMP fragment is received on a bundle, the fragments are buffered into a bufferwhich is maintined for each bundle in the MP system.This file contains functions which are used to buffer the fragments into thebuffer and then re-assemble the fragments into a PPP packet, using the methodproposed by the RFC 1717 and RFC 1990.INCLUDES : mpFramingLayerP.h vpppstr.h*//* includes */#include "vxWorks.h"#include "stdio.h"#include "stdlib.h"#include "private/ppp/mpFramingLayerP.h"#include "private/ppp/vpppstr.h"#include "netBufLib.h"#include "logLib.h"/* defines */#define HALF_SIZE_OF_PPP_PROTOCOL_FIELD 1#define SIZE_OF_PPP_CONTROL_AND_ADDRESS_FIELDS 2/* externs */IMPORT TEST mp_reassemble_ppp_packet (PFW_PLUGIN_OBJ_STATE *, ULONG);/* locals & forwards */TEST mp_buffer_ppp_fragment (PFW_PLUGIN_OBJ_STATE *, M_BLK_ID, USHORT, enum FRAGMENT_FLAG, ULONG, ULONG *);TEST mp_search_packet_with_all_fragments_received (PFW_PLUGIN_OBJ_STATE *, ULONG *, ULONG *, ULONG);ULONG mp_get_M (PFW_PLUGIN_OBJ_STATE *);void mp_check_and_handle_frame_lost (PFW_PLUGIN_OBJ_STATE *, ULONG);M_BLK_ID mp_reassemble_fragments_to_ppp_packet (PFW_PLUGIN_OBJ_STATE *, ULONG, ULONG, USHORT *);LOCAL TEST mp_assemble_received_packet_from_fragments (PFW_PLUGIN_OBJ_STATE *, ULONG, ULONG, M_BLK_ID *);LOCAL void adjust_reassembled_ppp_packet (PFW_PLUGIN_OBJ_STATE *, BYTE *, USHORT *, M_BLK_ID);#if 0 LOCAL BYTE *get_handle_of_mp_data (PFW_PLUGIN_OBJ_STATE *, UNION_MP_PACKET *, USHORT, USHORT *);#endifLOCAL MP_FRAGMENT_CLASS * fill_ppp_fragment_array (PFW_PLUGIN_OBJ_STATE *, M_BLK_ID, USHORT, enum FRAGMENT_FLAG, ULONG);LOCAL int mp_reassemble_fragments_length (PFW_PLUGIN_OBJ_STATE *, ULONG, ULONG);LOCAL TEST search_for_beginning_fragment (PFW_PLUGIN_OBJ_STATE *, ULONG, ULONG *, ULONG *);LOCAL TEST search_for_end_fragment (PFW_PLUGIN_OBJ_STATE *, ULONG, ULONG *, ULONG *);LOCAL USHORT get_index_of_M (PFW_PLUGIN_OBJ_STATE *, ULONG);LOCAL USHORT get_index_of_first_ending_fragment (PFW_PLUGIN_OBJ_STATE *);LOCAL BOOL does_fragment_bear_beginning_bit (MP_FRAGMENT_CLASS *);LOCAL BOOL does_fragment_bear_ending_bit (MP_FRAGMENT_CLASS *);LOCAL void discard_fragment_range (PFW_PLUGIN_OBJ_STATE *, ULONG, ULONG, BOOL);LOCAL void discard_fragments_up_to_index (PFW_PLUGIN_OBJ_STATE *, USHORT, BOOL);LOCAL void discard_a_ppp_fragment (PFW_PLUGIN_OBJ_STATE *, MP_FRAGMENT_CLASS *, BOOL);LOCAL USHORT search_for_duplicate_entries (PFW_PLUGIN_OBJ_STATE *, ULONG *, ULONG *);#if 0LOCAL void ppp_buffer_print (PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState);#endif/********************************************************************************* mp_buffer_ppp_fragment - Add the PPP fragment into the buffer.* * This function ppp fragment into the buffer, using the insertion sort algorithm** RETURNS: PASS or FAIL*/TEST mp_buffer_ppp_fragment ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, M_BLK_ID fragment, USHORT mp_packet_length, enum FRAGMENT_FLAG fragment_flag, ULONG sequence_number, ULONG *uptr_current_fragment_index ) { USHORT mp_data_length = 0; MP_FRAGMENT_CLASS *mp_fragment = NULL; MP_FRAGMENT_CLASS *temp_fragment = NULL; MP_FRAGMENT_CLASS *prev_fragment = NULL; MP_FRAGMENT_CLASS *temporary_fragment = NULL; BOOL last_in_list = FALSE; MP_PACKET_WITH_LONG_SEQUENCE_NUMBER *mpPacketWithLongSequenceNumber; MP_PACKET_WITH_SHORT_SEQUENCE_NUMBER *mpPacketWithShortSequenceNumber; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if ((pMpFramingLayerState == NULL) || (fragment == NULL) || (uptr_current_fragment_index == NULL)) return FAIL; if (pStackData->bundle.receiving_end.use_short_sequence_number == FALSE) { /* * support RFC 1990 section 3 page 9 - * discard the packets with Reserved Bits SET */ mpPacketWithLongSequenceNumber = mtod (fragment, MP_PACKET_WITH_LONG_SEQUENCE_NUMBER *); if (mpPacketWithLongSequenceNumber->header.reserved_field > 0) { pfwPrintError (__FILE__, "mp_buffer_ppp_fragment", __LINE__, NULL, pMpFramingLayerState->stackObj, "Invalid LSNHF Packet: Reserved Bits are SET"); return (FALSE); } /* decrement the length here */ mp_data_length = (USHORT) (mp_packet_length - sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER)); } else { /* * support RFC 1990 section 3 page 9 - * discard the packets with Reserved Bits SET */ mpPacketWithShortSequenceNumber = mtod (fragment, MP_PACKET_WITH_SHORT_SEQUENCE_NUMBER *); if (mpPacketWithShortSequenceNumber->header.reserved_field > 0) { pfwPrintError (__FILE__, "mp_buffer_ppp_fragment", __LINE__, NULL, pMpFramingLayerState->stackObj, "Invalid SSNHF Packet: Reserved Bits are SET"); return (FALSE); } /* decrement the length here */ mp_data_length = (USHORT) (mp_packet_length - sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER)); } /* * special case - no fragments buffered, so, use sllInit and put the new * node at the tail */ if (pStackData->bundle.receiving_end.buffer. number_of_ppp_fragments_buffered == 0x0000) /* special case */ { sllInit (&(pStackData->bundle.receiving_end.buffer.ppp_fragments)); mp_fragment = fill_ppp_fragment_array (pMpFramingLayerState, fragment, mp_data_length, fragment_flag, sequence_number); sllPutAtTail (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), (SL_NODE *) (mp_fragment)); mp_fragment->indexInList = 0; *uptr_current_fragment_index = 0; return (PASS); } temp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&(pStackData->bundle.receiving_end.buffer.ppp_fragments)); /* * check if there is only one node and to insert it * at the start node itself */ if (temp_fragment->next == NULL) { /* check the sequence number and insert */ if (sequence_number < (temp_fragment->sequence_number)) { mp_fragment = fill_ppp_fragment_array (pMpFramingLayerState, fragment, mp_data_length, fragment_flag, sequence_number); sllPutAtHead (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), (SL_NODE *) (mp_fragment)); *uptr_current_fragment_index = 0; mp_fragment->indexInList = 0; mp_fragment->next->indexInList = 1; } else { mp_fragment = fill_ppp_fragment_array (pMpFramingLayerState, fragment, mp_data_length, fragment_flag, sequence_number); sllPutAtTail (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), (SL_NODE *) (mp_fragment)); *uptr_current_fragment_index = 1; mp_fragment->indexInList = 1; } } else /* traverse the list and insert it according to the ascending order of sequence number */ { while (temp_fragment != NULL) { if (sequence_number < (temp_fragment->sequence_number)) { prev_fragment = (MP_FRAGMENT_CLASS *) sllPrevious (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), (SL_NODE *)temp_fragment); if (prev_fragment == NULL) { mp_fragment = fill_ppp_fragment_array (pMpFramingLayerState, fragment, mp_data_length, fragment_flag, sequence_number); mp_fragment->indexInList = 0; sllPutAtHead (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), (SL_NODE *) (mp_fragment)); *uptr_current_fragment_index = 0; /* * to update the index inforamtion of other * fragments after adding new fragment */ temporary_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&(pStackData->bundle.receiving_end.buffer.ppp_fragments)); temporary_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *)temporary_fragment); while (temporary_fragment != NULL) { last_in_list = TRUE; temporary_fragment->indexInList = (temporary_fragment->indexInList) + 1; temporary_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *)temporary_fragment); } break; } else { mp_fragment = fill_ppp_fragment_array (pMpFramingLayerState, fragment, mp_data_length, fragment_flag, sequence_number); prev_fragment->next = mp_fragment; mp_fragment->next = temp_fragment; *uptr_current_fragment_index = (prev_fragment->indexInList) + 1; mp_fragment->indexInList = (prev_fragment->indexInList) + 1; /* * to update the index inforamtion of other * fragments after adding new fragment */ while (temp_fragment != NULL) { last_in_list = TRUE; temp_fragment->indexInList = temp_fragment->indexInList + 1; temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *)temp_fragment); } break; } } temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *)temp_fragment); } if (last_in_list == FALSE) { mp_fragment = fill_ppp_fragment_array (pMpFramingLayerState, fragment, mp_data_length, fragment_flag, sequence_number); temp_fragment = (MP_FRAGMENT_CLASS *) SLL_LAST (&(pStackData->bundle.receiving_end.buffer.ppp_fragments)); mp_fragment->indexInList = temp_fragment->indexInList + 1; sllPutAtTail (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), ((SL_NODE *) mp_fragment)); *uptr_current_fragment_index = mp_fragment->indexInList; } } return (PASS); }/********************************************************************************* fill_ppp_fragment_array - Populate the PPP fragment array.* * This function populates the PPP fragment array element with the information* like the sequence number, fragment_flag, pointer to the ppp fragment and * increments the count, the number of fragments buffered.** RETURNS: N/A*/LOCAL MP_FRAGMENT_CLASS * fill_ppp_fragment_array ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, M_BLK_ID fragment, USHORT ppp_fragment_length, enum FRAGMENT_FLAG fragment_flag, ULONG sequence_number ) { MP_FRAGMENT_CLASS * mp_fragment = NULL; PFW_OBJ * pfwObj = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if (fragment == NULL) return NULL; /* get the framework obj, for usage with pfwMalloc */ pfwObj = pfwStackObjPfwGet (pMpFramingLayerState->stackObj); /* allocate memory for the fragment class, to be added the list */ mp_fragment = (MP_FRAGMENT_CLASS *) pfwMalloc (pfwObj, sizeof (MP_FRAGMENT_CLASS)); if (mp_fragment == NULL) { pfwPrintError (__FILE__, "fill_ppp_fragment_array", __LINE__, NULL, pMpFramingLayerState->stackObj, "Could not allocate memory for the incoming packet"); return NULL; } /* populate the fragment */ mp_fragment->sequence_number = sequence_number; mp_fragment->fragment_flag = fragment_flag; mp_fragment->mblk_fragment = fragment; mp_fragment->length = ppp_fragment_length; /* increment the number of fragments buffered */ ++pStackData->bundle.receiving_end.buffer.number_of_ppp_fragments_buffered; return (mp_fragment); }/********************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -