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 + -
显示快捷键?