2009年2月22日星期日

muxBind的参数可以决定数据包的优先级

MUX层的特点是:它可以完全屏蔽嵌入式系统的底层网络驱动和上层协议的关联,使网络驱动程序和协议之间没有内部交换数据,它们只能通过MUX间接相互作用。

任何要接收数据包的协议首先要将其比绑定到MUX上,通过MUX和设备连接起来。协议通过调用muxBind()来完成这个工作。下面为muxBind()的原型:

Void * muxBind

(

    char * pName,            /*设备名*/

    int       unit,              /*设备单元号*/

BOOL   (*stackRcvRtn)   /*接收函数*/

     (

     void * pEnd, long type, M_BLK_ID pNetBuff,LL_HDR_INFO

 * pLinkHdr,

     void * pCallbackId

       ),

       STATUS stackShutdownRtn( void * pCookie, void * pSpare),  /*关闭函数*/

       STATUS stackRestartRtn( void *pEND, void *Pspare),  /*复位函数*/

       Void stackErrorRtn(void * pEnd, END_ERR pError, void * pSpare), /*错误处理函数*/

long    type,      /*RFC1700SAP中获得的协议类型*/

char *  pProtoName, /*协议名*/

void *  pSpare      /*一个指向传递给MUX的多余信息的指针,这个信息的使用是可选的*/

       )

   这里我们要特别注意的是muxBind()中的long type(协议类型)。MUX使用此协议类型来区分协议的优先权。这个优先权决定哪个协议先获得接收数据包的处理权利。当驱动程序传送给MUX一个数据包 时,驱动程序包含一个指向END_OBJ结构的指针(END_OBJ结构如图3)。此结构还包含一个protocols成员、关注设备的协议清单 NET_PROTOCL结构清单)首部。此清单中的协议顺序决定拉哪个协议优先处理数据包。MUX负责保存此清单。

 

协议类型VxWorks中有三个典型值,分别时MUX_PROTO_

SNARFMUX_PROTO_PROMISCMUX_PROTO_OUTPUT

  MUX_PROTO_SNARF:协议获得完整的接收数据包。

  MUX_PROTO_PROMISC:协议优先处理接收数据包,被协议处理部分将被屏蔽。

  MUX_PROTO_OUTPUT:协议获得输出数据包。

   当协议在它的muxBind()中规定一种MUX_PROTO_SNARF类型,则MUXEND_OBJ.protocols清单首部添加一协议。注 VxWorks在任何时候只允许MUX下有一MUX_PROTO_SNARF类型协议激活。当协议在它的muxBind()中规定一种 MUX_PROTO_PROMISC类型,则MUXEND_OBJ.protocols清单的尾部添加一协议。若协议在muxBind()中还规定了其 他类型,则MUX在清单中MUX_PROTO_SNARF协议后添加这些类型的协议(若无MUX_PROTO_SNARF协议则在清单首部添加)。这种协 议添加方式保证了在接收数据包之前,低优先级的协议无法盗用或破坏高优先级的协议的数据包。

 

 

StackRcvRtn()是协议里最重要的APIMUX通过它来传递数据包给协议。协议对数据包的处理也是由其完成的。它的原型如下:

BOOL stackRcvRtn

       ( void *   pCookie,     /* 调用muxBind()后的返回指针,用来识别MUX将协议绑定到那个设备上* /

        long       type,         /* 协议类型*/

        M_BLK_ID       pNetBuff,  /*一个指向包含数据包和连接级信息的mBlk结构指针*/

        LL_HDR_INFO *  pLinkHdr,  /* 返回包含首部信息的一个LL_HDR_INFO结构,首部信息取决于END执行的特定数据连接层 */

         void *     pCallbackId   /*一个指向传递给MUX的多余信息的指针,这个信息的使用是可选的*/

          )

  在VxWorks中在一个设备上加入一个自有协议,当底层网络驱动完备时,我们只要将协议层的四个API函数写好并通过muxBind()绑定于设备上,协议即可生效。为了加深理解,下面以一个截获IP接收数据包的程序代码为例。

LOCAL BOOL monitorRecvProcess   /*接收数据监测*/

(

   void * pCookie,

    long  type,

    M_BLK_ID   pMblk,

    LL_HDR_INFO *    pLinkHdrInfo,

    void *  pSpare

 )

{

   int i;

  printf("DataMonitorByMux>Received data(len=%d):\n",pMblk->

  mBlkHdr.mLen);

  for(i=0;i<pMblk->mBlkHdr.mLen;i++)

      printf("%3x", *((unsigned char *)pMblk->mBlkHdr.mData+i));

  printf("\n");

return FALSE;

}

STATUS muxMonitorStart(char *ifname,int unit) /*程序启动*/

{

  monitorRecvBindCookie = muxBind (ifname, unit, (FUNCPTR)

  monitorRecvProcess,NULL, NULL, NULL,MUX_PROTO_SNARF, NULL, NULL);

  if(monitorRecvBindCookie==NULL)

{

  logMsg("monitorRecvBindCookie:Can't bind to %s%d!\n",ifname,unit);

  return(ERROR);

}

logMsg("DataMonitorByMux:%s%d Bind OK!!\n",ifname,unit);

return (OK);

}

STATUS muxMonitorStop(char *ifname,int unit) /*停止监测*/

{

if(muxUnbind(monitorRecvBindCookie,MUX_PROTO_SNARF,(FUNCPTR)monitorRecvProcess)!=OK)

{

logMsg("monitorRecvProcess unBind err!\n");

return ERROR;

}

return OK;

}

代码中monitorRecvProcess()即为协议中的StackRcvRtn(),它通过muxBind绑定于网络设备上,通过muxUnbind()从设备上卸载。monitorRecvProcess()可以截获网络设备上的所以IP接收数据包。

 

0 评论: