📄 pppvjc.c
字号:
/* pppVjc.c - Van Jacobson header compression module *//* Copyright 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01s,07aug03,rp updating include path for sl_compress.h01r,21oct02,qhu in setSlotNumbers, use MAX_STATES instead of 1601q,06aug02,adb specified component sequence number01p,30jul02,ijm include pppSlCompress.h01o,28may02,rvr fixed build warnings 01n,12feb02,ijm removed erroneous comment in vjcSend 01m,07feb02,mk corrected alignment problem, vjcReceive01l,23apr01,sj added NOMANUAL for printPktHdrs01k,18dec00,ijm corrected packet lengths in vjcReceive and vjcSend. corrected pppMPullup01j,29sep00,sj Merging in and reorganizing RFC2233 instrumentation01i,17mar00,cn corrected usage of compressing connection identifier, undone changes 01g.01h,15mar00,cn removed unnecessary logMsg.01g,14mar00,cn added vjc_ConnCompressEnable, vjcProfileDataConstruct () and vjcConnCompressHandle ().01f,13mar00,cn fixed vjcSend for non-TCP packets.01e,10mar00,sj added local version of m_pullup01d,23feb00,sj Pedantic ANSI fixes01c,02dec99,sgv Fixed bug in receive path01b,29nov99,sgv Added comments01a,09sep99,sgv Written*//*DESCRIPTIONThis component implements Van Jacobson Header Compression Protocolas specified in RFC 1144. This component resides in the network layerof the data plane.*/#include "vxWorks.h"#include "pfw/pfw.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "ctype.h"#include "intLib.h"#include "usrLib.h"#include "memLib.h"#include "inetLib.h"#include "hostLib.h"#include "ppp/kstart.h"#include "ppp/kppp.h"#include "hostLib.h"#include "pfw/pfwLayer.h"#include "pfw/pfwComponent.h"#include "pfw/pfwTimer.h"#include "pfw/pfwInterface.h"#include "pfw/pfwStack.h"#include "pfw/pfwProfile.h"#include "pfw/pfwMemory.h"#include "pfw/pfwInterface.h"#include "ppp/interfaces/pppVjcInterfaces.h"#include "ppp/interfaces/componentAcceptableProtocolsInterface.h"#include "ppp/interfaces/pppInterfacesGroupInterfaces.h"#include "ppp/pppVjcComponent.h"#include "private/ppp/vpppstr.h"#include "netinet/tcp.h"#include "logLib.h"#include "wrn/util/sl_compress.h"typedef struct vjcStackData { PFW_PLUGIN_OBJ_CALLBACKS * callbacks; BYTE numberOfSlots; BOOL connIdCompress; struct slcompress sc_comp; /* auxiliary variables aiding RFC 2233 counters's implementation */ int pfwAuxIfId; PFW_INTERFACE_STATE_PAIR pfwRFC2233CountPair; BOOL pfwRFC2233CountTest; } VJC_STACK_DATA;typedef struct pppVjcComponent { PFW_COMPONENT_OBJ component; PPP_VJC_INTERFACE pppVjcInterface; COMPONENT_ACCEPTABLE_PROTOCOLS_INTERFACE componentAcceptableProtocolsInterface; } PPP_VJC_COMPONENT;/* Defines */#define VJC_ALIGNMENT_FIX/* enable connection identifier compression */ #define VJC_CONN_COMPRESS_ENABLED TRUE#define M_DATASTART(m) (m)->m_extBuf#define M_DATASIZE(m) (m)->m_extSize#define COMPTYPE(proto) ((proto) == VAN_JACOBSON_COMPRESSED_PROTOCOL? \ TYPE_COMPRESSED_TCP: TYPE_UNCOMPRESSED_TCP)/* typedefs */LOCAL STATUS stackAdd (PFW_PLUGIN_OBJ_STATE *state, PFW_PLUGIN_OBJ_CALLBACKS * callbacks);LOCAL STATUS stackDelete (PFW_PLUGIN_OBJ_STATE *state);LOCAL STATUS vjcSend (PFW_PLUGIN_OBJ_STATE *state, M_BLK_ID * pkt);LOCAL STATUS vjcReceive (PFW_PLUGIN_OBJ_STATE *state, M_BLK_ID * pkt);LOCAL void vjcInit (PFW_PLUGIN_OBJ_STATE *state);LOCAL STATUS setConnIdCompress (PFW_PLUGIN_OBJ_STATE *state, BOOL connIdCompress);LOCAL STATUS setSlotNumbers (PFW_PLUGIN_OBJ_STATE *state, int numberOfSlots);LOCAL STATUS sendPathAcceptableProtocolsGet (PFW_PLUGIN_OBJ_STATE *state, ACCEPTABLE_PROTOCOLS_ARRAY **sendProtocols);LOCAL STATUS receivePathAcceptableProtocolsGet (PFW_PLUGIN_OBJ_STATE *state, ACCEPTABLE_PROTOCOLS_ARRAY **recvProtocols);LOCAL STATUS vjcInterfaceBind (PFW_PLUGIN_OBJ * pluginObj);LOCAL void ppp_sl_compress_init ( struct slcompress *comp, BYTE numberOfSlots); LOCAL M_BLK_ID pppMPullup ( M_BLK_ID inMblk, int len);LOCAL UINT vjcProtocolTypes[3] = {PPP_IP_PROTOCOL, VAN_JACOBSON_COMPRESSED_PROTOCOL, VAN_JACOBSON_UNCOMPRESSED_PROTOCOL};LOCAL ACCEPTABLE_PROTOCOLS_ARRAY recvAcceptableProtocols = {3, vjcProtocolTypes};LOCAL UINT ipProtocolType[1] = {PPP_IP_PROTOCOL};LOCAL ACCEPTABLE_PROTOCOLS_ARRAY sendAcceptableProtocols = {1, ipProtocolType};#ifdef VJC_DEBUGint vjcDebug = 0;int dumpHeaders = 0;void printPktHdrs(char *message, M_BLK_ID inMblk);#endif/******************************************************************************** pppVjcComponentCreate - initialize and add VJC component to framework** This routine creates the Van Jacobson Header compression component plug-in* object and adds it to the PPP framework.** RETURNS: OK or ERROR*/STATUS pppVjcComponentCreate ( PFW_OBJ *pfw ) { PPP_VJC_COMPONENT *pVjcComponent; PFW_PLUGIN_OBJ *pluginObj; pVjcComponent = (PPP_VJC_COMPONENT *) pfwMalloc (pfw, sizeof (PPP_VJC_COMPONENT)); if (pVjcComponent == NULL) { printf ("pppVjcInit Unable to allocate memory\n"); return (ERROR); } pluginObj = (PFW_PLUGIN_OBJ *)&(pVjcComponent->component); pVjcComponent->component.protocol = 0x002d; pVjcComponent->component.sequence = 0x0; pVjcComponent->component.layerObj = pfwLayerObjGet (pfw, "NETWORK_LAYER"); strcpy (pluginObj->name, "VJC"); pluginObj->pfwObj = pfw; pluginObj->profileDataSize = 0; pluginObj->stackDataSize = sizeof (VJC_STACK_DATA); pluginObj->profileDataConstruct = NULL; pluginObj->profileDataDestruct = NULL; pluginObj->profileDataCopy = NULL; pluginObj->stackDataConstruct = NULL; pluginObj->stackDataDestruct = NULL; pluginObj->stackDataShow = NULL; pluginObj->receive = vjcReceive; pluginObj->send = vjcSend; pluginObj->stackAdd = stackAdd; pluginObj->stackDelete = stackDelete; pluginObj->interfaceBind = vjcInterfaceBind; if (pfwComponentAdd (&pVjcComponent->component) == ERROR) { printf ("pppVjcInit VJC component could not be added"); return (ERROR); } return (OK); } /********************************************************************************* pppVjcComponentDelete - delete the VJC component from the framework** The VJC plug-in component object allocated by pppVjcComponentCreate() is* freed if there are no references to this object from a stack or* profile object in the framework.** RETURNS: OK or ERROR*/STATUS pppVjcComponentDelete ( PFW_OBJ *pfw ) { PFW_COMPONENT_OBJ *pComponent; pComponent = pfwComponentObjGetByName (pfw, "VJC"); if (pComponent == NULL) return ERROR; if (pfwComponentDelete (pComponent) == OK) { pfwFree (pComponent); return OK; } return (ERROR); }/******************************************************************************** vjcInterfaceBind -*/LOCAL STATUS vjcInterfaceBind ( PFW_PLUGIN_OBJ * pluginObj ) { PPP_VJC_COMPONENT * pComponent = (PPP_VJC_COMPONENT *)pluginObj; PPP_VJC_INTERFACE *pppVjcInterface; COMPONENT_ACCEPTABLE_PROTOCOLS_INTERFACE *componentAcceptableProtocolsInterface; PFW_OBJ * pfw = pluginObj->pfwObj; int i; if ((i = pfwInterfaceRegister(pfw,"PPP_VJC_INTERFACE")) > 0) { pppVjcInterface = &pComponent->pppVjcInterface; pppVjcInterface->interfaceObj.id = i; pppVjcInterface->interfaceObj.pluginObj = pluginObj; pppVjcInterface->setSlotNumbers = setSlotNumbers; pppVjcInterface->setConnIdCompress = setConnIdCompress; pfwInterfaceBind (&pppVjcInterface->interfaceObj); } if ((i = pfwInterfaceRegister(pfw, "COMPONENT_ACCEPTABLE_PROTOCOLS_INTERFACE")) > 0) { componentAcceptableProtocolsInterface = &pComponent->componentAcceptableProtocolsInterface; componentAcceptableProtocolsInterface->interfaceObj.id = i; componentAcceptableProtocolsInterface->interfaceObj.pluginObj = pluginObj; componentAcceptableProtocolsInterface->receivePathAcceptableProtocolsGet = receivePathAcceptableProtocolsGet; componentAcceptableProtocolsInterface->sendPathAcceptableProtocolsGet = sendPathAcceptableProtocolsGet; pfwInterfaceBind (&componentAcceptableProtocolsInterface->interfaceObj); } return (OK); }LOCAL STATUS stackAdd ( PFW_PLUGIN_OBJ_STATE *state, PFW_PLUGIN_OBJ_CALLBACKS * callbacks ) { VJC_STACK_DATA *pVjcStackData = (VJC_STACK_DATA *)state->stackData; pVjcStackData->callbacks = callbacks; /* Get pfwRFC2233CountPair and set pfwRFC2233CountTest */ RFC2233_COUNT_PAIR_GET(state, pVjcStackData->pfwAuxIfId, pVjcStackData->pfwRFC2233CountPair, pVjcStackData->pfwRFC2233CountTest); if (pVjcStackData->callbacks && pVjcStackData->callbacks->stackAddComplete) { (*pVjcStackData->callbacks->stackAddComplete) (pVjcStackData->callbacks, state); return (OK); } else return ERROR; }LOCAL STATUS stackDelete ( PFW_PLUGIN_OBJ_STATE *state ) { VJC_STACK_DATA *pStackData; pStackData = (VJC_STACK_DATA *)state->stackData; /* delete interface references */ if (pStackData->pfwRFC2233CountTest) pfwInterfaceReferenceDelete(pStackData->pfwRFC2233CountPair.interfaceObj); /* Inform the upper layers we are down */ if (pStackData->callbacks && pStackData->callbacks->stackDeleteComplete) { (*pStackData->callbacks->stackDeleteComplete) (pStackData->callbacks , state); return (OK); } else return ERROR; }LOCAL STATUS vjcReceive ( PFW_PLUGIN_OBJ_STATE *state, M_BLK_ID * packet ) { USHORT proto = 0; u_char *cp; M_BLK_ID mBlk; int newLen; struct slcompress *pSccomp; VJC_STACK_DATA *pVjcStackData; NET_POOL_ID netPoolId; M_BLK_ID newMblk; char * dst; int delta; pVjcStackData = (VJC_STACK_DATA *)state->stackData; pSccomp = &pVjcStackData->sc_comp; mBlk = *packet; cp = mtod(*packet, u_char *); proto = (cp[0] << 8) + cp[1];#ifdef VJC_DEBUG if (vjcDebug) printPktHdrs("RECEIVED", mBlk);#endif if (proto == VAN_JACOBSON_COMPRESSED_PROTOCOL || proto == VAN_JACOBSON_UNCOMPRESSED_PROTOCOL) { /* sl_uncompress_tcp assumes there are MAX_HDR (128 bytes) at the * beginning of the buffer to uncompress the header. 128 bytes are * needed to cover the maximum IP header (20 + 40 for options) and * the maximum TCP header (20 + options) + space to align IP packet * on 4 byte boundary if necessary. */ if (proto == VAN_JACOBSON_COMPRESSED_PROTOCOL && mBlk->mBlkHdr.mData - M_DATASTART(mBlk) < MAX_HDR) { netPoolId = pfwNetPoolIdGet (state->pluginObj->pfwObj); if ((newMblk = netTupleGet (netPoolId, MAX_HDR + mBlk->mBlkHdr.mLen, M_DONTWAIT,MT_DATA,TRUE)) == NULL) { netMblkClChainFree (*packet); RFC2233_COUNTER_UPDATE(pVjcStackData->pfwRFC2233CountTest, pVjcStackData->pfwRFC2233CountPair, M2_ctrId_ifInDiscards, 1); return (ERROR); } /* Point to IP packet */ mBlk->mBlkHdr.mLen -= sizeof(PPP_HEADER); mBlk->mBlkHdr.mData += sizeof(PPP_HEADER); dst = newMblk->mBlkHdr.mData + MAX_HDR + sizeof(PPP_HEADER); memcpy (dst, mBlk->mBlkHdr.mData, mBlk->mBlkHdr.mLen); newMblk->mBlkHdr.mLen = mBlk->mBlkHdr.mLen; newMblk->mBlkHdr.mData = dst; newMblk->mBlkHdr.mNext = mBlk->mBlkHdr.mNext; /* Copy packet header information */ if (mBlk->mBlkHdr.mFlags & M_PKTHDR) { newMblk->mBlkPktHdr = mBlk->mBlkPktHdr; newMblk->mBlkHdr.mFlags = mBlk->mBlkHdr.mFlags; } netMblkClFree(mBlk); mBlk = newMblk; } else { mBlk->mBlkHdr.mData += 2; /* Point to the IP Header */ mBlk->mBlkHdr.mLen -= 2;#ifdef VJC_ALIGNMENT_FIX /* The PPP packet with the TCP packet as the payload , is always unaligned.Assuming the mBlkHdr.mData is aligned , the first two bytes are occupied by the PPP header, hence the payload starts at an even but not word aligned boundary. The sl_uncompress_tcp , when it gets VAN_JACOBSON_UNCOMPRESSED_PROTOCOL tries to access the th_off bit field in the TCP header, since TCP header starts at an unaligned boundary. An exception is thrown. To correct this we create another packet similar to when proto==VAN_JACOBSON_UNCOMPRESSED_PROTOCOL, But we leave 4 bytes in front of the new packet so that, the PPP payload is word aligned. This causes the PPP_HEADER to be at word unaligned boundary.Also there are two additional bytes before the start of mBlkHdr.mData, this was done in order to make the PPP payload word aligned. */ netPoolId = pfwNetPoolIdGet (state->pluginObj->pfwObj); if ((newMblk = netTupleGet (netPoolId, mBlk->mBlkHdr.mLen + 4, M_DONTWAIT,MT_DATA,TRUE)) == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -