📄 mprx.c
字号:
( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, PPP_PACKET *ptr_ppp_packet, USHORT ppp_packet_length, UNION_MP_PACKET **ptr_uptr_mp_packet, USHORT *uptr_mp_packet_length, ULONG *ulptr_sequence_number, enum FRAGMENT_FLAG *eptr_fragment_flag ) { UNION_MP_PACKET *uptr_mp_packet = NULL; if ((pMpFramingLayerState == NULL) || (ptr_ppp_packet == NULL) || (ptr_uptr_mp_packet == NULL) || (uptr_mp_packet_length == NULL) || (ulptr_sequence_number == NULL) || (eptr_fragment_flag == NULL)) return; /* get MP_HEADER_FORMAT information from the PPP Packet */ uptr_mp_packet = get_handle_of_mp_packet (pMpFramingLayerState, ptr_ppp_packet, ppp_packet_length, uptr_mp_packet_length); *ptr_uptr_mp_packet = uptr_mp_packet; /* get sequence number */ *ulptr_sequence_number = get_mp_sequence_number (pMpFramingLayerState, uptr_mp_packet); /* get fragment flag(B or E or B & E) */ *eptr_fragment_flag = get_mp_fragment_flag (pMpFramingLayerState, uptr_mp_packet); }/********************************************************************************* verify_reassembled_ppp_packet - verify the reassembled ppp packet.* * This function verifies the size of the PPP packet that is being reassembled* and checks if it is greater than the local MRRU. If also checks the PROTOCOL* type and if it is a LCP protocol, then it silently discards the packet.** RETURNS: PASS or FAIL*/LOCAL TEST verify_reassembled_ppp_packet ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, PPP_PACKET *ptr_ppp_packet, USHORT ppp_packet_length ) { MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if (ptr_ppp_packet == NULL) { pfwPrintError (__FILE__, "verify_reassembled_ppp_packet", __LINE__, NULL, pMpFramingLayerState->stackObj, "Invalid Argument: Null pointer"); return (FAIL); } /* * if Packet-Protocol-Type is of the following * then silently discard the packet */ if (ptr_ppp_packet->header.protocol_type == htons (LCP_PROTOCOL)) { switch (((LCP_PACKET *) ptr_ppp_packet)->lcp_header.code) { /* ..., and implementation receiving them MUST silently * discard them. RFC 1717 p.5. */ case CONFIGURE_REQUEST: case CONFIGURE_REJECT: case CONFIGURE_ACK: case CONFIGURE_NAK: case TERMINATION_REQUEST: case TERMINATION_ACK: pfwPrintError (__FILE__, "verify_reassembled_ppp_packet", __LINE__, NULL, pMpFramingLayerState->stackObj, "LCP packet received on the bundle"); netMblkClChainFree (pStackData->bundle.receiving_end.pMblkId); pStackData->bundle.receiving_end.pMblkId = NULL; return (FAIL); } } return (PASS); }/********************************************************************************* update_buffer_information - update the buffer information.* * This function updates the buffer information, checks if the fragment is the * ONLY_FRAGMENT or FIRST_FRAGMENT, in which case it sets * the receiver_is_resynchronizing FLAG to FALSE if it was true before. If it is* NOT_END_FRAGMENT, then the receiver is still waiting for the fragments from * the current packet.** RETURNS: N/A*/LOCAL void update_buffer_information ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, enum FRAGMENT_FLAG fragment_flag ) { MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; switch (fragment_flag) { case ONLY_FRAGMENT: if (pStackData->bundle.receiving_end.buffer. receiver_is_resynchronizing == TRUE) { pStackData->bundle.receiving_end.buffer. receiver_is_resynchronizing = FALSE; } ++pStackData->bundle.receiving_end.buffer. number_of_beginning_fragments_buffered; ++pStackData->bundle.receiving_end.buffer. number_of_ending_fragments_buffered; break; case FIRST_FRAGMENT: if (pStackData->bundle.receiving_end.buffer. receiver_is_resynchronizing == TRUE) { pStackData->bundle.receiving_end.buffer. receiver_is_resynchronizing = FALSE; } ++pStackData->bundle.receiving_end.buffer. number_of_beginning_fragments_buffered; break; case NOT_END_FRAGMENT: break; case LAST_FRAGMENT: ++pStackData->bundle.receiving_end.buffer. number_of_ending_fragments_buffered; break; default: /* control reaching here is impossible, just in case */ pfwPrintError (__FILE__, "update_buffer_information", __LINE__, NULL, pMpFramingLayerState->stackObj, "packet with unknown fragment flag received in bundle"); } }/********************************************************************************* get_mp_sequence_number - get the sequence number of the fragment from the* packet.** This function gets the sequence number from the MP packet, either from the* short seqence number header or the long sequence number header.** RETURNS: sequence number*/LOCAL ULONG get_mp_sequence_number ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, UNION_MP_PACKET *uptr_mp_packet ) { MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; ULONG temp = 0; if (pStackData->bundle.receiving_end. use_short_sequence_number == FALSE) { bcopyBytes ((char *)uptr_mp_packet, (char *)&temp, sizeof (ULONG)); temp = temp & 0x00FFFFFF; return temp; } else { return (uptr_mp_packet->mp_packet_with_short_sequence_number. header.sequence_number); } }/********************************************************************************* get_mp_fragment_flag - get the fragment flag of the fragment from the packet.** This function gets the fragment flag from the MP packet, either from the* short seqence number header or the long sequence number header. The fragment* flag can be - ONLY_FRAGMENT, FIRST_FRAGMENT, LAST_FRAGMENT or NOT_END_FRAGMENT** RETURNS: FRAGMENT_FLAG*/LOCAL enum FRAGMENT_FLAG get_mp_fragment_flag ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, UNION_MP_PACKET *uptr_mp_packet ) { MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; /* check if short sequence / long sequence number is used */ if (pStackData->bundle.receiving_end. use_short_sequence_number == FALSE) { if ((uptr_mp_packet->mp_packet_with_long_sequence_number.header. first_fragment_flag == MP_ON) && (uptr_mp_packet->mp_packet_with_long_sequence_number.header. last_fragment_flag == MP_ON)) { return (ONLY_FRAGMENT); } if ((uptr_mp_packet->mp_packet_with_long_sequence_number.header. first_fragment_flag == MP_ON) && (uptr_mp_packet->mp_packet_with_long_sequence_number.header. last_fragment_flag == MP_OFF)) { return (FIRST_FRAGMENT); } if ((uptr_mp_packet->mp_packet_with_long_sequence_number.header. first_fragment_flag == MP_OFF) && (uptr_mp_packet->mp_packet_with_long_sequence_number.header. last_fragment_flag == MP_ON)) { return (LAST_FRAGMENT); } return (NOT_END_FRAGMENT); } else { if ((uptr_mp_packet->mp_packet_with_short_sequence_number.header. first_fragment_flag == MP_ON) && (uptr_mp_packet->mp_packet_with_short_sequence_number.header. last_fragment_flag == MP_ON)) { return (ONLY_FRAGMENT); } if ((uptr_mp_packet->mp_packet_with_short_sequence_number.header. first_fragment_flag == MP_ON) && (uptr_mp_packet->mp_packet_with_short_sequence_number.header. last_fragment_flag == MP_OFF)) { return (FIRST_FRAGMENT); } if ((uptr_mp_packet->mp_packet_with_short_sequence_number.header. first_fragment_flag == MP_OFF) && (uptr_mp_packet->mp_packet_with_short_sequence_number.header. last_fragment_flag == MP_ON)) { return (LAST_FRAGMENT); } return (NOT_END_FRAGMENT); } }/********************************************************************************* get_handle_of_mp_packet - get the handle of the MP packet from the PPP * encapsulated MP packet.* * This function gets the MP packet from the PPP encapsulated MP packet and * converts if from the network byte order to host byte order.** RETURNS: UNION_MP_PACKET * or NULL*/LOCAL UNION_MP_PACKET *get_handle_of_mp_packet ( PFW_PLUGIN_OBJ_STATE *pMpFramingLayerState, PPP_PACKET *sptr_ppp_encapsulated_mp_packet, USHORT ppp_packet_length, USHORT *usptr_mp_packet_length ) { UNION_MP_PACKET *uptr_mp_packet = NULL; MP_FRAMING_LAYER_STACK_DATA *pStackData = (MP_FRAMING_LAYER_STACK_DATA *) pMpFramingLayerState->stackData; if ((pMpFramingLayerState == NULL) || (sptr_ppp_encapsulated_mp_packet == NULL) || (usptr_mp_packet_length == NULL)) return NULL; uptr_mp_packet = (UNION_MP_PACKET *) ((BYTE *) sptr_ppp_encapsulated_mp_packet + sizeof (PPP_HEADER)); if (pStackData->bundle.receiving_end.use_short_sequence_number == FALSE) { convert_long_sequence_number_mp_packet_to_host_order (uptr_mp_packet); } else { convert_short_sequence_number_mp_packet_to_host_order (uptr_mp_packet); } *usptr_mp_packet_length = (USHORT) (ppp_packet_length - sizeof (PPP_HEADER)); return uptr_mp_packet; }/********************************************************************************* convert_long_sequence_number_mp_packet_to_host_order - * * This function is used to convert a long sequence number header MP packet to* host byte order.** RETURNS: N/A*/LOCAL void convert_long_sequence_number_mp_packet_to_host_order ( UNION_MP_PACKET *uptr_mp_packet ) { ULONG long_sequence_number_mp_header_in_ulong = 0; ULONG mp_header_in_host_long = 0; if (uptr_mp_packet == NULL) return; bcopyBytes ((char *) uptr_mp_packet, (char *) &long_sequence_number_mp_header_in_ulong, sizeof (ULONG)); mp_header_in_host_long = ntohl (long_sequence_number_mp_header_in_ulong); bcopyBytes ((char *) &mp_header_in_host_long, (char *) uptr_mp_packet, sizeof (ULONG)); } /********************************************************************************* convert_short_sequence_number_mp_packet_to_host_order - * * This function is used to convert a short sequence number header MP packet to* host byte order.** RETURNS: N/A*/LOCAL void convert_short_sequence_number_mp_packet_to_host_order ( UNION_MP_PACKET *uptr_mp_packet ) { SHORT_SEQUENCE_NUMBER_MP_HEADER *sptr_short_sequence_number_mp_header = NULL; USHORT *usptr_short_sequence_number_mp_header = NULL; USHORT short_sequence_number_mp_header_in_ushort; USHORT mp_header_in_host_short; sptr_short_sequence_number_mp_header = &uptr_mp_packet->mp_packet_with_short_sequence_number.header; 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; mp_header_in_host_short = ntohs (short_sequence_number_mp_header_in_ushort); memcpy ((void *) uptr_mp_packet, (void *) &mp_header_in_host_short, sizeof (USHORT)); }#ifdef PPP_DEBUG/********************************************************************************* mp_fragment_flag_enum_to_string - Convert enum to equivalent string* * This function is used to get the string equivalent of the FRAGMENT_FLAG * enumerated data type. Used for printing the fragment information.** RETURNS: String*/LOCAL char *mp_fragment_flag_enum_to_string ( enum FRAGMENT_FLAG fragment_flag ) { switch (fragment_flag) { case FIRST_FRAGMENT : return ("first fragment"); case LAST_FRAGMENT : return ("last fragment"); case NOT_END_FRAGMENT : return ("non-end fragment"); case ONLY_FRAGMENT : return ("only fragment"); default: return ("unknown fragment"); } }#endif /* PPP_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -