아래와 같이 함수를 구현한다.
int muxSnarfInit(char *if_name, int if_unit) { END_OBJ *pEnd; void *pCookie; unsigned int flags = 0; char ifnameBuf[10]; pEnd = endFindByName(if_name, if_unit); if (NULL == pEnd) { printf("Cannot find END device %s%d\n", if_name, if_unit); printf("Usage: muxSnarfInit(char *if_name, int if_unit)\n"); return ERROR; } pCookie = muxBind(if_name, if_unit, snarfRecvFunc, 0, 0, 0, MUX_PROTO_SNARF, "VLAN", (void *) pEnd); //MUX_PROTO_SNARF if (NULL == pCookie) { printf("Error 0x%x occured in muxBind\n", errnoGet()); return ERROR; } sprintf(ifnameBuf, "%s%d", if_name, if_unit); flags |= IFF_PROMISC; ifFlagSet(ifnameBuf, flags); setCookie(pCookie); printf("muxSnarfInit started sussessfully!\n"); return OK; }
여기서
flags |= IFF_PROMISC;
ifFlagSet(ifnameBuf, flags);
을 빼면 자신의 맥과 다른 맥에 대해서 만 캡쳐되는데, 이것을 넣으면 맥에 관계 없이 모든 데이터를 캡쳐한다.
아래는 이함수를 호출하는 초기화 영역이다.
#ifndef WIN32 if (muxLibInit() != NO_ERR) printf("Failed to initialize mux subsystem\n"); else { if (muxSnarfInit(DUAL_NET_DEV_NAME, unitNum) != OK) printf("Failed to muxSnarfInit\n"); } #endif
수신되는 함수는 아래와 같으며, 받은 데이터는 메시지 Queue를 통하여 처리한다.
#ifndef WIN32 LOCAL BOOL snarfRecvFunc(void *pCookie, long type, M_BLK_ID pMblk, LL_HDR_INFO * pLlHdrInfo, void * pProtoCtrl) { /* please note that for performance issues, one might want to analyze the incoming packet information by looking at the pMblk->mBlkHdr.mData pointer; To simplify this example, the data is copied into a linear buffer with int netMblkToBufCopy ( M_BLK_ID pMblk, / * pointer to an mBlk * / char * pBuf, / * pointer to the buffer to copy * / FUNCPTR pCopyRtn / * function pointer for copy routine * / ) */ char buffer[2048]; /* should be far more than enouth for ethernet devices */ char ipAddr[16]; int len; /* amount of data received */ END_OBJ *pEnd; struct ip *pIp; static int k; PTNET_ETH_HDREX peth; PTNET_TANMP_HDR pthdr; int32 status; /* The end device the packet was received on was passed as the last parameter in muxBind below; Therefore, the protocol specific pointer corresponds to pEnd in this case */ /* The following call copies the received packet into a linear buffer */ len = netMblkToBufCopy(pMblk, buffer, NULL); pEnd = (END_OBJ *) pProtoCtrl; if (len < sizeof(TNET_HDR)) { /* 기본적인 데이터 구조가 들어오지 않았으므로 리턴 시킨다. */ return FALSE; /* returning FALSE means that this function has not consumed the packet, so it might be adressed for another protocol */ } peth = (PTNET_ETH_HDREX) buffer; pthdr = (PTNET_TANMP_HDR) (peth + 1); if (ntohs(peth->type) == LSIS_TANMP_PKT_TYPE) { if (gTrMsgQueId) { if ((status = messageQueueSend(gTrMsgQueId, (char *) &buffer, len, NOWAIT, MYMSG_PRI_NORMAL)) == NO_ERR) { } } netMblkClChainFree(pMblk); return TRUE; } else { netMblkClChainFree(pMblk); return FALSE; } /* If the packet NOT to be passed to any other protocol, it is necessary to 1) release the mBlk chain by calling netMblkClChainFree(pMblk); and 2) inform the MUX that we consumed the packet by returning TRUE otherwise (i.e. if this function didn't consume the packet, return FALSE */ netMblkClChainFree(pMblk); return FALSE; }
수신된 데이터의 처리는 타스크를 따로 두어 아래와 같이 처리한다.
void tNetRecvTask(int32 arg1,int32 arg2,int32 arg3,int32 arg4,int32 arg5,int32 arg6,int32 arg7,int32 arg8,int32 arg9,int32 arg10) { uint32 status = NO_ERR; static u_char recvBuf[1000]; /* 수신 큐 초기화 */ gTrMsgQueId = msgQCreate(256,sizeof(recvBuf),MSG_Q_FIFO); if(gTrMsgQueId) { printf("tNetRecvTask is created\n"); } int retLen = 0; while(1L){ status = messageQueueRecv( gTrMsgQueId, (int8 *)&recvBuf, sizeof(recvBuf), FOREVERWAIT, &retLen ); if(status == NO_ERR) { ProcessPacket((u_char*)recvBuf,retLen); //printf("\n"); //PrintData(recvBuf,retLen); } sysTaskDelay(systemClockRateGet()*SYSTEM_TICK / 100); } return; }
'프로그래밍 > vxWorks' 카테고리의 다른 글
workbench(vxWorks)에서 DKM(Downloadable Kernel Module) 다운로드시 Relocation offset too large 에러 발생하는 경우 (0) | 2014.07.01 |
---|