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, /*从RFC1700或SAP中获得的协议类型*/
char * pProtoName, /*协议名*/
void * pSpare /*一个指向传递给MUX的多余信息的指针,这个信息的使用是可选的*/
)
这里我们要特别注意的是muxBind()中的long type(协议类型)。MUX使用此协议类型来区分协议的优先权。这个优先权决定哪个协议先获得接收数据包的处理权利。当驱动程序传送给MUX一个数据包 时,驱动程序包含一个指向END_OBJ结构的指针(END_OBJ结构如图3)。此结构还包含一个protocols成员、关注设备的协议清单 (NET_PROTOCL结构清单)首部。此清单中的协议顺序决定拉哪个协议优先处理数据包。MUX负责保存此清单。
协议类型VxWorks中有三个典型值,分别时MUX_PROTO_
SNARF、MUX_PROTO_PROMISC、MUX_PROTO_OUTPUT。
MUX_PROTO_SNARF:协议获得完整的接收数据包。
MUX_PROTO_PROMISC:协议优先处理接收数据包,被协议处理部分将被屏蔽。
MUX_PROTO_OUTPUT:协议获得输出数据包。
当协议在它的muxBind()中规定一种MUX_PROTO_SNARF类型,则MUX在END_OBJ.protocols清单首部添加一协议。注 意VxWorks在任何时候只允许MUX下有一MUX_PROTO_SNARF类型协议激活。当协议在它的muxBind()中规定一种 MUX_PROTO_PROMISC类型,则MUX在END_OBJ.protocols清单的尾部添加一协议。若协议在muxBind()中还规定了其 他类型,则MUX在清单中MUX_PROTO_SNARF协议后添加这些类型的协议(若无MUX_PROTO_SNARF协议则在清单首部添加)。这种协 议添加方式保证了在接收数据包之前,低优先级的协议无法盗用或破坏高优先级的协议的数据包。
StackRcvRtn()是协议里最重要的API,MUX通过它来传递数据包给协议。协议对数据包的处理也是由其完成的。它的原型如下:
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 评论:
发表评论