📄 mpreassemble.c
字号:
mp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&(pStackData->bundle.receiving_end.buffer.ppp_fragments)); while (mp_fragment->indexInList != index_of_first_ending_fragment) { mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) mp_fragment); } /* handling first and non end fragment loss */ if (M > mp_fragment->sequence_number) { does_M_bear_beginning_bit = does_fragment_bear_beginning_bit (mp_fragment_M); discard_fragments_up_to_index (pMpFramingLayerState, index_of_M, TRUE); if (does_M_bear_beginning_bit == FALSE) { discard_fragments_up_to_index (pMpFramingLayerState, pStackData->bundle.receiving_end.buffer. number_of_ppp_fragments_buffered, TRUE); pStackData->bundle.receiving_end.buffer. receiver_is_resynchronizing = TRUE; #ifdef PPP_DEBUG printf ("MP: lost fragment. Discard up to 0x%x bundle 0x%x\n", (int) M, (int) pMpFramingLayerState->stackObj);#endif /* PPP_DEBUG */ } else { mp_reassemble_ppp_packet (pMpFramingLayerState, current_fragment_index); #ifdef PPP_DEBUG printf ("MP: lost fragment. Discard up to 0x%x bundle 0x%x\n", (int) M, (int) pMpFramingLayerState->stackObj);#endif /* PPP_DEBUG */ } } }/********************************************************************************* discard_fragment_range - discrad the fragments buffered, in a particular range** RETURNS: N/A*/LOCAL void discard_fragment_range ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, ULONG first, ULONG last, BOOL free_the_packet ) { MP_FRAGMENT_CLASS *first_mp_fragment = NULL; MP_FRAGMENT_CLASS *last_mp_fragment = NULL; MP_FRAGMENT_CLASS *next_mp_fragment = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if (pMpFramingLayerState == NULL) return; /* get the first node in the list */ first_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&(pStackData->bundle.receiving_end.buffer.ppp_fragments)); /* get the first node in the list */ last_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&(pStackData->bundle.receiving_end.buffer.ppp_fragments)); /* traverse upto the index (first) in the list and get its pointer */ while (first_mp_fragment->indexInList != (USHORT) first) { first_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) first_mp_fragment); } /* traverse upto the index (last) in the list and get its pointer */ while (last_mp_fragment->indexInList != (USHORT) last) { last_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) last_mp_fragment); } /* traverse from first to last and discard the fragment everytime */ while (first_mp_fragment != last_mp_fragment) { next_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT((SL_NODE *) first_mp_fragment); discard_a_ppp_fragment (pMpFramingLayerState, first_mp_fragment, free_the_packet); first_mp_fragment = next_mp_fragment; } /* we have not cleared the last one, clear it here */ discard_a_ppp_fragment (pMpFramingLayerState, last_mp_fragment, free_the_packet); /* update the number of fragments buffered */ pStackData->bundle.receiving_end.buffer.number_of_ppp_fragments_buffered -= (USHORT) (last - first + 1); }/********************************************************************************* discard_fragments_up_to_index - discard the fragments in the buffer upto the* the given index.** RETURNS: N/A*/LOCAL void discard_fragments_up_to_index ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, USHORT to_index, BOOL free_the_packet ) { MP_FRAGMENT_CLASS *temp_fragment = NULL; MP_FRAGMENT_CLASS *temporary_fragment = NULL; MP_FRAGMENT_CLASS *next_fragment = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; MP_FRAGMENT_CLASS *mp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&pStackData->bundle.receiving_end.buffer.ppp_fragments); if (pMpFramingLayerState == NULL) return; if (to_index >= pStackData->bundle.receiving_end.buffer. number_of_ppp_fragments_buffered) { while (mp_fragment != NULL) { /* from 0 to number of fragments buffered */ next_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT((SL_NODE *) mp_fragment); discard_a_ppp_fragment (pMpFramingLayerState, mp_fragment, free_the_packet); mp_fragment = next_fragment; } } else { temp_fragment = mp_fragment; while (mp_fragment->indexInList != to_index) mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) mp_fragment); while (temp_fragment != mp_fragment) { temporary_fragment = temp_fragment; temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); discard_a_ppp_fragment (pMpFramingLayerState, temporary_fragment, free_the_packet); } } pStackData->bundle.receiving_end.buffer.number_of_ppp_fragments_buffered = (USHORT) (pStackData->bundle.receiving_end.buffer. number_of_ppp_fragments_buffered - to_index); }/********************************************************************************* discard_a_ppp_fragment - discrad a particular PPP fragement from the buffer** RETURNS: N/A*/LOCAL void discard_a_ppp_fragment ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, MP_FRAGMENT_CLASS *mp_fragment, BOOL free_the_packet ) { MP_FRAGMENT_CLASS *temp_fragment = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; MP_FRAGMENT_CLASS *prev_fragment = (MP_FRAGMENT_CLASS *) sllPrevious (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), (SL_NODE *) mp_fragment); if (mp_fragment == NULL) return; /* check for a fragment bearing a BEGIN Bit or ONLY_FRAGMENT(B & E) */ if (does_fragment_bear_beginning_bit (mp_fragment) == TRUE) { --pStackData->bundle.receiving_end.buffer. number_of_beginning_fragments_buffered; } /* check for a fragment bearing an END Bit or ONLY_FRAGMENT(B & E) */ if (does_fragment_bear_ending_bit (mp_fragment) == TRUE) { --pStackData->bundle.receiving_end.buffer. number_of_ending_fragments_buffered; } /* update the index numbers maintained in the structure */ temp_fragment = mp_fragment; while (temp_fragment != NULL) { temp_fragment->indexInList = temp_fragment->indexInList - 1; temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); } /* check and free the MBLKs */ if (free_the_packet == TRUE) { netMblkClChainFree (mp_fragment->mblk_fragment); } /* remove the node from the list */ sllRemove (&(pStackData->bundle.receiving_end.buffer.ppp_fragments), (SL_NODE *) mp_fragment, (SL_NODE *) prev_fragment); /* free the fragment */ pfwFree ((void *) mp_fragment); mp_fragment = NULL; }/********************************************************************************* mp_get_M - find the current minimum of the most recently received sequence* number over all the member links in the bundle.** RETURNS: M*/ULONG mp_get_M ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState ) { ULONG M = 0; /* current minimum of the most recently received sequence number * over all the member links in the bundle. RFC 1717,p.10. */ USHORT current_link = 0; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; M = 0xFFFFFFFF; for (current_link = 0x0000; current_link < pStackData->bundle.receiving_end.no_of_links; ++current_link) { if (pStackData->bundle.receiving_end. links [current_link].most_recently_received_sequence_number < M) { M = pStackData->bundle.receiving_end. links [current_link].most_recently_received_sequence_number; } } return (M); }/******************************************************************************* search_for_duplicate_entries - search for duplicate sequence number** This function searches the buffer of fragments for duplicate sequence number.* If there is a duplicate entry found, it discards the fragment and frees the* mblk associated with it.*/LOCAL USHORT search_for_duplicate_entries ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, ULONG *begin_fragment_index, ULONG *end_fragment_index ) { MP_FRAGMENT_CLASS *temp_fragment = NULL; MP_FRAGMENT_CLASS *next_fragment = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; USHORT no_of_dup_entries = 0; if (*begin_fragment_index < *end_fragment_index) /* B...C...E */ { temp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&pStackData->bundle.receiving_end.buffer.ppp_fragments); /* move upto the begin fragment index */ while (temp_fragment->indexInList != *begin_fragment_index) { temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); } /* search from begin fragment to end fragment index */ while (temp_fragment->indexInList != *end_fragment_index) { next_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); if (next_fragment == NULL) break; if (next_fragment->sequence_number == temp_fragment->sequence_number) { discard_a_ppp_fragment (pMpFramingLayerState, next_fragment, TRUE); /* update the end fragment index */ (*end_fragment_index)--; no_of_dup_entries++; pStackData->bundle.receiving_end.buffer.number_of_ppp_fragments_buffered--; } temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); } } else /* E....C....B */ { /* search from begin fragment to the last (no. of fragments buffered) */ temp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&pStackData->bundle.receiving_end.buffer.ppp_fragments); while (temp_fragment->indexInList != *begin_fragment_index) { temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); } while (temp_fragment != NULL) { next_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); if (next_fragment == NULL) break; if (next_fragment->sequence_number == temp_fragment->sequence_number) { discard_a_ppp_fragment (pMpFramingLayerState, next_fragment, TRUE); no_of_dup_entries++; pStackData->bundle.receiving_end.buffer.number_of_ppp_fragments_buffered--; } temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); } /* search from first (0) upto the end fragment index */ temp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&pStackData->bundle.receiving_end.buffer.ppp_fragments); while (temp_fragment->indexInList != *end_fragment_index) { next_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); if (next_fragment == NULL) break; if (next_fragment->sequence_number == temp_fragment->sequence_number) { discard_a_ppp_fragment (pMpFramingLayerState, next_fragment, TRUE); /* update both "end" and "begin" fragment indices */ (*end_fragment_index)--; (*begin_fragment_index)--; no_of_dup_entries++; pStackData->bundle.receiving_end.buffer.number_of_ppp_fragments_buffered--; } temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) temp_fragment); } } return no_of_dup_entries;} #if 0/******************************************************************************** ppp_buffer_print - prints the buffer in the bundle.** used for testing only...!*/LOCAL void ppp_buffer_print (PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState) { MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; MP_FRAGMENT_CLASS *temp_fragment; M_BLK_ID pMblk = NULL; temp_fragment = (MP_FRAGMENT_CLASS *) SLL_FIRST (&pStackData->bundle.receiving_end.buffer.ppp_fragments); while (temp_fragment != NULL) { printf ("The fragment details are\n"); printf ("SQ NO is => 0x%x::indexInList is => 0x%x::Fragment Flag is => 0x%x\n", temp_fragment->sequence_number, temp_fragment->indexInList, temp_fragment->fragment_flag); pMblk = temp_fragment->mblk_fragment; printf("Fragment Data:\n "); if (pMblk->mBlkHdr.mLen < 50) mp_dump_data ((BYTE *)pMblk->mBlkHdr.mData, pMblk->mBlkHdr.mLen); temp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *)temp_fragment); } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -