📄 mpreassemble.c
字号:
/* skip the MP header - check SSNHF or LSNHF */ if (pStackData->bundle.receiving_end. use_short_sequence_number == TRUE) { firstMBlkId->mBlkHdr.mData += sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); firstMBlkId->mBlkHdr.mLen -= sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); firstMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } else { firstMBlkId->mBlkHdr.mData += sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); firstMBlkId->mBlkHdr.mLen -= sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); firstMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } /* F...................Max */ endMBlkId = firstMBlkId; /* * goto the next fragment, * coz, first fragment is already with the chain */ first_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) first_mp_fragment); while (first_mp_fragment != NULL) { if (first_mp_fragment->mblk_fragment != NULL) { tempMBlkId = first_mp_fragment->mblk_fragment; if (pStackData->bundle.receiving_end. use_short_sequence_number == TRUE) { tempMBlkId->mBlkHdr.mData += sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mLen -= sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } else { tempMBlkId->mBlkHdr.mData += sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mLen -= sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } while (endMBlkId->mBlkHdr.mNext != NULL) { endMBlkId = endMBlkId->mBlkHdr.mNext; } endMBlkId->mBlkHdr.mNext = first_mp_fragment->mblk_fragment; endMBlkId = tempMBlkId; } else { /* * discard from 0 to L and F to Max and pass TRUE so that * MBLK-CLBLK-Cluster chain also is freed */ discard_fragment_range (pMpFramingLayerState, first_fragment_index, pStackData->bundle.receiving_end. buffer.number_of_ppp_fragments_buffered - 1, TRUE); discard_fragment_range (pMpFramingLayerState, 0, last_fragment_index, TRUE); return (FAIL); } first_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) first_mp_fragment); } /* Now - 0......L */ /* 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 last_mp_fragment, to get its pointer */ while (last_mp_fragment->indexInList != last_fragment_index) { last_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) last_mp_fragment); } while (first_mp_fragment != last_mp_fragment) { /* check if the fragment is NULL */ if (first_mp_fragment->mblk_fragment != NULL) { tempMBlkId = first_mp_fragment->mblk_fragment; if (pStackData->bundle.receiving_end. use_short_sequence_number == TRUE) { tempMBlkId->mBlkHdr.mData += sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mLen -= sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } else { tempMBlkId->mBlkHdr.mData += sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mLen -= sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } while (endMBlkId->mBlkHdr.mNext != NULL) { endMBlkId = endMBlkId->mBlkHdr.mNext; } endMBlkId->mBlkHdr.mNext = first_mp_fragment->mblk_fragment; endMBlkId = tempMBlkId; } else { /* * discard from F....Max and 0....L, pass TRUE so that * MBLK-CLBLK-Cluster chain is also freed */ discard_fragment_range (pMpFramingLayerState, first_fragment_index, pStackData->bundle.receiving_end. buffer.number_of_ppp_fragments_buffered - 1, TRUE); discard_fragment_range (pMpFramingLayerState, 0, last_fragment_index, TRUE); return (FAIL); } first_mp_fragment = (MP_FRAGMENT_CLASS *) SLL_NEXT ((SL_NODE *) first_mp_fragment); } /* we have not added the last fragment, so explicitly do it here */ tempMBlkId = last_mp_fragment->mblk_fragment; if (pStackData->bundle.receiving_end. use_short_sequence_number == TRUE) { tempMBlkId->mBlkHdr.mData += sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mLen -= sizeof (SHORT_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } else { tempMBlkId->mBlkHdr.mData += sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mLen -= sizeof (LONG_SEQUENCE_NUMBER_MP_HEADER); tempMBlkId->mBlkHdr.mFlags &= (~M_PKTHDR); } while (endMBlkId->mBlkHdr.mNext != NULL) { endMBlkId = endMBlkId->mBlkHdr.mNext; } endMBlkId->mBlkHdr.mNext = tempMBlkId; endMBlkId = tempMBlkId; /* * discard from 0 to L and F to Max, but pass FLASE so that * MBLK-CLBLK-Cluster chain is not freed */ discard_fragment_range (pMpFramingLayerState, first_fragment_index, pStackData->bundle.receiving_end.buffer. number_of_ppp_fragments_buffered - 1, FALSE); discard_fragment_range (pMpFramingLayerState, 0, last_fragment_index, FALSE); } /* now firstMBlkId is the chain, to be passed UP in the stack */ *packet_to_be_passed_up = firstMBlkId; return (PASS); }/********************************************************************************* mp_reassemble_fragments_to_ppp_packet - reassemble the received fragments into* a PPP packet.* * This function reassembles fragments to ppp packet. It computes the length of the* PPP packet and allocates memory for the ppp packet. It checks for the reception * of a non RFC-compliant packet using the adjust_reassembled_ppp_packet function* and returns the pointer to the PPP packet.** RETURNS: PPP_PACKET * or NULL*/M_BLK_ID mp_reassemble_fragments_to_ppp_packet ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, ULONG first_fragment_index, ULONG last_fragment_index, USHORT *usptr_ppp_packet_length ) { BYTE *bptr_second_byte_of_ppp_protocol_type_field = NULL; M_BLK_ID packet_to_be_passed_up = NULL; char *pTemp = NULL; M_BLK_ID pTempMBlk = NULL; if ((pMpFramingLayerState == NULL) || (usptr_ppp_packet_length == NULL)) return NULL; /* get the length of all the fragments that are buffered */ *usptr_ppp_packet_length = (USHORT) mp_reassemble_fragments_length (pMpFramingLayerState, first_fragment_index, last_fragment_index); if (*usptr_ppp_packet_length == 0x0000) { return (NULL); } /* add the actual length with length of HALF_SIZE_OF_PPP_PROTOCOL_FIELD */ /* PFC should have been applied by the other end of the bundle */ /* assemble received fragment to packet in the range first to last */ if (mp_assemble_received_packet_from_fragments(pMpFramingLayerState, first_fragment_index, last_fragment_index, &packet_to_be_passed_up) == FAIL) { pfwPrintError (__FILE__, "mp_reassemble_fragments_to_ppp_packet", __LINE__, NULL, pMpFramingLayerState->stackObj, "PPP packet reassembly FAILED"); return (NULL); } if (packet_to_be_passed_up->mBlkHdr.mNext != NULL) { packet_to_be_passed_up->mBlkHdr.mFlags |= M_PKTHDR; pTempMBlk = packet_to_be_passed_up->mBlkHdr.mNext; while (pTempMBlk != NULL) { pTempMBlk->mBlkHdr.mFlags &= (~M_PKTHDR); pTempMBlk = pTempMBlk->mBlkHdr.mNext; } } /* make place for protocol field uncompress */ packet_to_be_passed_up->mBlkHdr.mData -= 1; pTemp = (char *)packet_to_be_passed_up->mBlkHdr.mData; pTemp [0] = 0; bptr_second_byte_of_ppp_protocol_type_field = (BYTE *) &pTemp[1]; adjust_reassembled_ppp_packet (pMpFramingLayerState, bptr_second_byte_of_ppp_protocol_type_field, usptr_ppp_packet_length, packet_to_be_passed_up); packet_to_be_passed_up->mBlkHdr.mLen += HALF_SIZE_OF_PPP_PROTOCOL_FIELD; *usptr_ppp_packet_length = (USHORT) (*usptr_ppp_packet_length + HALF_SIZE_OF_PPP_PROTOCOL_FIELD); /* assign the length here...*/ if ((packet_to_be_passed_up->mBlkHdr.mFlags & M_PKTHDR) && (packet_to_be_passed_up->mBlkHdr.mNext != NULL)) { packet_to_be_passed_up->mBlkPktHdr.len = *usptr_ppp_packet_length; } else { packet_to_be_passed_up->mBlkHdr.mLen = *usptr_ppp_packet_length; }#ifdef PPP_DEBUG printf ("MP: PPP packet of length %hu reassembled on bundle 0x%x\n", (int) *usptr_ppp_packet_length, (int) pMpFramingLayerState->stackObj);#endif /* PPP_DEBUG */ return packet_to_be_passed_up;}/********************************************************************************* adjust_reassembled_ppp_packet - adjust the reassembled PPP packet.* * This function checks if a non RFC-compliant packet is received. It it is* received, it adjust the PPP packet and also the size of the PPP packet.** RETURNS: N/A*/LOCAL void adjust_reassembled_ppp_packet ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, BYTE *bptr_second_byte_of_ppp_protocol_type_field, USHORT *usptr_ppp_packet_length, M_BLK_ID packet_to_be_passed_up ) { if ((pMpFramingLayerState == NULL) || (bptr_second_byte_of_ppp_protocol_type_field == NULL) || (usptr_ppp_packet_length == NULL) || (packet_to_be_passed_up == NULL)) return; if ((bptr_second_byte_of_ppp_protocol_type_field[0] == HDLC_ADDRESS) && (bptr_second_byte_of_ppp_protocol_type_field[1] == UNNUMBERED_INFORMATION)) { *usptr_ppp_packet_length -= SIZE_OF_PPP_CONTROL_AND_ADDRESS_FIELDS; packet_to_be_passed_up->mBlkHdr.mLen -= SIZE_OF_PPP_CONTROL_AND_ADDRESS_FIELDS; memmove ((void *) &bptr_second_byte_of_ppp_protocol_type_field[0], (void *) &bptr_second_byte_of_ppp_protocol_type_field[2], packet_to_be_passed_up->mBlkHdr.mLen); } if ((*bptr_second_byte_of_ppp_protocol_type_field & 0x01) == 0x00) { memmove ((void *) (bptr_second_byte_of_ppp_protocol_type_field - 0x0001), (void *) bptr_second_byte_of_ppp_protocol_type_field, packet_to_be_passed_up->mBlkHdr.mLen); --(*usptr_ppp_packet_length); packet_to_be_passed_up->mBlkHdr.mLen--; } }/********************************************************************************* mp_search_packet_with_all_fragments_received - check if all the fragments* between the BEGIN and END packet are received for the packet.** RETURNS: N/A*/TEST mp_search_packet_with_all_fragments_received ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, ULONG *begin_fragment_index, ULONG *end_fragment_index, ULONG current_fragment_index ) { ULONG end_fragment_sequence_number = 0; ULONG beginning_fragment_sequence_number = 0; ULONG number_of_fragments_expected = 0; ULONG number_of_fragments_received = 0; ULONG last_node_sequence_number = 0; MP_FRAGMENT_CLASS *last_fragment = NULL; USHORT no_of_dup_entries = 0; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if ((begin_fragment_index == NULL) || (end_fragment_index == NULL)) return FAIL; /* to see if all fragments are received between start and end fragment */ if (current_fragment_index == 0xFFFFFFFFL) { current_fragment_index = 0x00000000L; } if ((search_for_beginning_fragment (pMpFramingLayerState, current_fragment_index, begin_fragment_index, &beginning_fragment_sequence_number) == PASS) && (search_for_end_fragment (pMpFramingLayerState, current_fragment_index, end_fragment_index, &end_fragment_sequence_number) == PASS)) { if (*end_fragment_index >= *begin_fragment_index) /* ...B..C..E.... */ { number_of_fragments_expected = end_fragment_sequence_number - beginning_fragment_sequence_number + 1; /* checking for dup seq no. entries, if found discard them */ no_of_dup_entries = search_for_duplicate_entries (pMpFramingLayerState, begin_fragment_index, end_fragment_index); /* number_of_fragments_expected += no_of_dup_entries; */ number_of_fragments_received = *end_fragment_index - *begin_fragment_index + 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -