2009年2月23日星期一

GOOSE报文在vxworks链路直接发送成功

#include "vxWorks.h"

#include "netinet/in.h"

#include "netinet/ip.h"

#include "netinet/if_ether.h"

#include "netinet/udp.h"

#include "private/muxlibP.h"

void *MuxCookie;

BOOL RxHandler

(

void * pCookie, /* returned by muxBind() */

long type, /* from RFC1700, or user-defined */

M_BLK_ID pNetBuff, /* packet with link-level info */

LL_HDR_INFO * pLinkHdr, /* link-level header info structure */

void * pSpare /* defined on a per-protocol basis */

)

{

return(FALSE);

}

int auto_init ()

{

if (muxLibInit() != OK)

{

printf( "Failed to initialize mux subsystem\n");

return -1;

}

/* Check if the interface exists */

if(muxDevExists("fei", 3 )) /*3=序号,使用网卡的序号为3*/

{

printf("muxDevExists\n");

/* MUX_PROTO_SNARF MUX_PROTO_PROMISC MUX_PROTO_OUTPUT */

if ((MuxCookie = muxBind("fei", 3, RxHandler, NULL, NULL, NULL,MUX_PROTO_SNARF, "VLAN", NULL)) == NULL)

{

printf("\nERROR: %x,bind failure (ERRNO=%x) ",errnoGet());

}

}

}

int auto_Send(char *pMsgBuf, long FrameLen)

{

M_BLK_ID pMblk = 0;

END_OBJ * pEnd = 0;

if ((pEnd = ((MUX_ID) MuxCookie) -> pEnd) == NULL)

{

printf( "Failed to get valid cookie end reference\n");

return -1;

}

if ((pMblk = netTupleGet (pEnd-> pNetPool, 1500, M_DONTWAIT,MT_DATA,FALSE)) == NULL)

{

perror ( "pMblk");

muxUnbind(MuxCookie,MUX_PROTO_SNARF,RxHandler);

return(ERROR);

}

pMblk->mBlkHdr.mFlags |= M_PKTHDR;

pMblk->mBlkHdr.mLen = 0;

pMblk->mBlkHdr.mData = pMblk->pClBlk->clNode.pClBuf;

pMblk->mBlkHdr.mLen = FrameLen;

memcpy(pMblk->mBlkHdr.mData, pMsgBuf, FrameLen);

if (muxSend(MuxCookie, pMblk) != OK)

{

printf( "Failed to send ethernet frame\n");

netMblkClChainFree(pMblk);

return -1;

}

printf("Sent an Frame\n");

}

void autofei_muxsend(void)

{

int i_Count= 0 ;

int i;

unsigned char packet[512];

memset(packet,0,sizeof(packet));

/* TODO: Add your control notification handler code here */

packet[0]=0x01;

packet[1]=0x0c;

packet[2]=0xcd;

packet[3]=0x04;

packet[4]=0x01;

packet[5]=0xff;

/* set mac source to 2:2:2:2:2:2 */

/* 00:10:16:00:89:d4 */

packet[6]=0x00;

packet[7]=0x10;

packet[8]=0x16;

packet[9]=0x00;

packet[10]=0x89;

packet[11]=0xd4;

packet[12]=0x88;

packet[13]=0xb8;

packet[14]=0x40;

packet[15]=0x00;

packet[16]=0x00;

packet[17]=0x7a;

/* Fill the rest of the packet */

strcpy((char*)&packet[18],"noodle and rice,very very nice,yummy yummy,very very nice;a big fat mouse,come to the house,ai yao,ai yao,pepper in the eyes!http://shenlan51.blogspot.com/");

while(1)

{

printf("prepare muxsend auto %d \n",i_Count++);

auto_Send(packet,256);

taskDelay(100);

}

}

void muxsend_auto (void)

{

sysClkRateSet(100);

if(chdir("/ata0a/")==ERROR)

{

printf("directory is not existed\r\n");

}

InitNetCard();

ftpInit();

auto_init();

taskSpawn("sig_main", 50, 0, 1024*20, (FUNCPTR)autofei_muxsend, 0,0,0,0,0,0,0,0,0,0);

}

From: http://shenlan51.blogspot.com/

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接收数据包。

 

与智者同行

总会遇到一些困惑于心的世事,会让我产生消极遁世的情绪,就着昏暗阴冷的冬天,躲进棉衣成一统,把自己和季节融为一体。像是要结个茧,殊不知,茧给我安全感的同时,也封住了生命的活力,小时候养蚕玩的时候,知道有的茧会破出蛾子,而有茧就从始至终只是个茧。于是渴望有人帮我挑开封口,让我尽早感知春天的气息。有时候一句温暖的话,可以是一股大西洋暖流,使心里的冰层融化。人生历程中的波折重重,需要与智者同行,以拨开云雾,走出困境。

几年前读《小窗幽记》,摘录了一句话,原句无法复述,大意却从未忘记:风狂雨骤时立得定,方见脚跟,花繁柳密时拨得开,方显眼力。虽记得不甚清楚,但这些年每当胸中风急浪大时,常常念及此义,就会站稳了,放眼望。即便没有大的进步,也不至于乱了方寸。处世的底线,就是良心的安宁。当老师的时候,我师从前辈精神,一心做到就是对得起自己的良心,无论境遇好坏,付出都多于回报,如果锱珠必较,不仅有违良心,也没有快乐。那些诗书,一边教一边学,滋味深长。见不到人与人的欺骗与虚伪,也没有学会狡诈圆滑,然而心灵宁静有如初春之晨。

年纪轻,会有宏心壮志,会有对前程一片光明的简单向往,总相信付出总有回报,努力就会成功,但挫折像一个智慧的同伴,与鸿鹄之志相生相克。真正了解我的人让我甘于做个庸人,因为甘于做平凡的自己,才会有平凡的快乐,才会有滋有味地品尝生活中真正实实在在的享受。在我尚未悟透的时候,我以为那是消沉。

当身边喜欢的人、不喜欢的人纷纷把真实的人生历程演示给我看时,我才明白,其实每个人的生活都是庸常的。努力也好,不争也罢,总归是将自己交与了时间,也展示在世间,时间给生命划出起始,世间便浅浅的将你定格成一幅黑白照片,那么色彩呢?缤纷的记忆或许可以留下来,但更多的都随风散了:风在树梢,月在云上,我在你的篱笆旁。

活着的时候,选择做个智者,如果做不到,至少要做个聪明的,选择与智者同行。