//------------------------------------------------------------------------------ static tOplkError receiveFrameCb(tFrameInfo* pFrameInfo_p, tEdrvReleaseRxBuffer* pReleaseRxBuffer_p) { UINT nwrite; // replace the MAC address of the POWERLINK Ethernet interface with virtual // Ethernet MAC address before forwarding it into the virtual Ethernet interface if (OPLK_MEMCMP(pFrameInfo_p->frame.pBuffer->aDstMac, vethInstance_l.macAdrs, ETH_ALEN) == 0) { OPLK_MEMCPY(pFrameInfo_p->frame.pBuffer->aDstMac, vethInstance_l.tapMacAdrs, ETH_ALEN); } nwrite = write(vethInstance_l.fd, pFrameInfo_p->frame.pBuffer, pFrameInfo_p->frameSize); if (nwrite != pFrameInfo_p->frameSize) { DEBUG_LVL_VETH_TRACE("Error writing data to virtual Ethernet interface!\n"); } *pReleaseRxBuffer_p = kEdrvReleaseRxBufferImmediately; return kErrorOk; }
//------------------------------------------------------------------------------ static void packetHandler(u_char* pParam_p, const struct pcap_pkthdr* pHeader_p, const u_char* pPktData_p) { tEdrvInstance* pInstance = (tEdrvInstance*)pParam_p; tEdrvRxBuffer rxBuffer; if (OPLK_MEMCMP(pPktData_p + 6, pInstance->initParam.aMacAddr, 6) != 0) { // filter out self generated traffic rxBuffer.bufferInFrame = kEdrvBufferLastInFrame; rxBuffer.rxFrameSize = pHeader_p->caplen; rxBuffer.pBuffer = (UINT8*)pPktData_p; pInstance->initParam.pfnRxHandler(&rxBuffer); } else { // self generated traffic if (pInstance->pTransmittedTxBufferFirstEntry != NULL) { tEdrvTxBuffer* pTxBuffer = pInstance->pTransmittedTxBufferFirstEntry; //TRACE("%s: (%02X) first TxB=%p (%02X), last TxB=%p\n", __func__, // (UINT)pPktData_p[5], // pTxBuffer, // (UINT)pTxBuffer->pBuffer[5], // edrvInstance_l.pTransmittedTxBufferLastEntry); if (pTxBuffer->pBuffer != NULL) { if (OPLK_MEMCMP(pPktData_p, pTxBuffer->pBuffer, 6) == 0) { EnterCriticalSection(&pInstance->criticalSection); pInstance->pTransmittedTxBufferFirstEntry = (tEdrvTxBuffer*)pInstance->pTransmittedTxBufferFirstEntry->txBufferNumber.pArg; if (pInstance->pTransmittedTxBufferFirstEntry == NULL) { pInstance->pTransmittedTxBufferLastEntry = NULL; } LeaveCriticalSection(&pInstance->criticalSection); pTxBuffer->txBufferNumber.pArg = NULL; if (pTxBuffer->pfnTxHandler != NULL) { pTxBuffer->pfnTxHandler(pTxBuffer); } } else { TRACE("%s: no matching TxB: DstMAC=%02X%02X%02X%02X%02X%02X\n", __func__, (UINT)pPktData_p[0], (UINT)pPktData_p[1], (UINT)pPktData_p[2], (UINT)pPktData_p[3], (UINT)pPktData_p[4], (UINT)pPktData_p[5]); TRACE(" current TxB %p: DstMAC=%02X%02X%02X%02X%02X%02X\n", (void*)pTxBuffer, (UINT)pTxBuffer->pBuffer[0], (UINT)pTxBuffer->pBuffer[1], (UINT)pTxBuffer->pBuffer[2], (UINT)pTxBuffer->pBuffer[3], (UINT)pTxBuffer->pBuffer[4], (UINT)pTxBuffer->pBuffer[5]); } } } else { TRACE("%s: no TxB: DstMAC=%02X%02X%02X%02X%02X%02X\n", __func__, pPktData_p[0], pPktData_p[1], pPktData_p[2], pPktData_p[3], pPktData_p[4], pPktData_p[5]); } } }
//------------------------------------------------------------------------------ static void packetHandler(u_char* pParam_p, const struct pcap_pkthdr* pHeader_p, const u_char* pPktData_p) { tEdrvInstance* pInstance = (tEdrvInstance*)pParam_p; tEdrvRxBuffer rxBuffer; if (OPLK_MEMCMP(pPktData_p + 6, pInstance->initParam.aMacAddr, 6) != 0) { // filter out self generated traffic rxBuffer.bufferInFrame = kEdrvBufferLastInFrame; rxBuffer.rxFrameSize = pHeader_p->caplen; rxBuffer.pBuffer = (void*)pPktData_p; FTRACE_MARKER("%s RX", __func__); pInstance->initParam.pfnRxHandler(&rxBuffer); } else { // self generated traffic FTRACE_MARKER("%s TX-receive", __func__); if (pInstance->pTransmittedTxBufferFirstEntry != NULL) { tEdrvTxBuffer* pTxBuffer = pInstance->pTransmittedTxBufferFirstEntry; if (pTxBuffer->pBuffer != NULL) { if (OPLK_MEMCMP(pPktData_p, pTxBuffer->pBuffer, 6) == 0) { pthread_mutex_lock(&pInstance->mutex); pInstance->pTransmittedTxBufferFirstEntry = (tEdrvTxBuffer*)pInstance->pTransmittedTxBufferFirstEntry->txBufferNumber.pArg; if (pInstance->pTransmittedTxBufferFirstEntry == NULL) { pInstance->pTransmittedTxBufferLastEntry = NULL; } pthread_mutex_unlock(&pInstance->mutex); pTxBuffer->txBufferNumber.pArg = NULL; if (pTxBuffer->pfnTxHandler != NULL) { pTxBuffer->pfnTxHandler(pTxBuffer); } } else { TRACE("%s: no matching TxB: DstMAC=%02X%02X%02X%02X%02X%02X\n", __func__, (UINT)((UINT8*)pPktData_p)[0], (UINT)((UINT8*)pPktData_p)[1], (UINT)((UINT8*)pPktData_p)[2], (UINT)((UINT8*)pPktData_p)[3], (UINT)((UINT8*)pPktData_p)[4], (UINT)((UINT8*)pPktData_p)[5]); TRACE(" current TxB %p: DstMAC=%02X%02X%02X%02X%02X%02X\n", (void*)pTxBuffer, (UINT)((UINT8*)(pTxBuffer->pBuffer))[0], (UINT)((UINT8*)(pTxBuffer->pBuffer))[1], (UINT)((UINT8*)(pTxBuffer->pBuffer))[2], (UINT)((UINT8*)(pTxBuffer->pBuffer))[3], (UINT)((UINT8*)(pTxBuffer->pBuffer))[4], (UINT)((UINT8*)(pTxBuffer->pBuffer))[5]); } } } else { TRACE("%s: no TxB: DstMAC=%02X%02X%02X%02X%02X%02X\n", __func__, ((UINT8*)pPktData_p)[0], ((UINT8*)pPktData_p)[1], ((UINT8*)pPktData_p)[2], ((UINT8*)pPktData_p)[3], ((UINT8*)pPktData_p)[4], ((UINT8*)pPktData_p)[5]); } } }