Reply To: Bridging?

Home Forums Discussions Support Bridging? Reply To: Bridging?

#5670
Vadim Smirnov
Keymaster

    I have not code for WinpkFilter, but the routines below demonstrate how I did it in Ethernet Bridge. Doing this using WinpkFilter is very similar. Please note, that you should also set NDIS flags NDIS_FLAGS_SKIP_LOOPBACK | NDIS_FLAGS_DONT_LOOPBACK before sending the packet over the network in order to avoid it to indicated back (in the code below it is done inside UF_SendPacketToAdapter but I did not provided it).

    VOID FLT_FilterReceivedPacket (
    NDIS_HANDLE NdisBindingHandle,
    PINTERMEDIATE_BUFFER pBuffer
    )
    {
    // Processing relative declarations
    PUSHORT pEtherType;

    //Adapter and protocol relative structures

    PPROTOCOL_ENTRY pProto;
    PADAPTER_ENTRY pAdapter, pReceivedAdapter;

    DbgPrint ( "FLT_FilterReceivedPacket pBuffer->m_Lengh = %d...n", pBuffer->m_Length );

    // DbgPrint ( "FLT_FilterReceivedPacket entered...n" );

    // .... process packet here....

    // We dump packet content here
    //DbgPrint ("nRCV:n");
    //DbgPrint ("MACS: DEST %.2X%.2X%.2X%.2X%.2X%.2X SOURCE: %.2X%.2X%.2X%.2X%.2X%.2Xn",
    // pBuffer->m_IBuffer[0],
    // pBuffer->m_IBuffer[1],
    // pBuffer->m_IBuffer[2],
    // pBuffer->m_IBuffer[3],
    // pBuffer->m_IBuffer[4],
    // pBuffer->m_IBuffer[5],
    // pBuffer->m_IBuffer[6],
    // pBuffer->m_IBuffer[7],
    // pBuffer->m_IBuffer[8],
    // pBuffer->m_IBuffer[9],
    // pBuffer->m_IBuffer[10],
    // pBuffer->m_IBuffer[11]
    // );

    pEtherType = (PUSHORT) pBuffer->m_IBuffer;
    pEtherType += ETH_LENGTH_OF_ADDRESS;

    /* switch( htons( *pEtherType ) )
    {
    case ETHERTYPE_IP:
    DbgPrint ("IP packet: ");
    ipHdr = ( PIP_HEADER ) &pBuffer->m_IBuffer[MHdrSize];
    DbgPrint ( " %u.%u.%u.%u ---> %u.%u.%u.%un",
    (ipHdr->ip_src.S_un.S_un_b.s_b1),
    (ipHdr->ip_src.S_un.S_un_b.s_b2),
    (ipHdr->ip_src.S_un.S_un_b.s_b3),
    (ipHdr->ip_src.S_un.S_un_b.s_b4),
    (ipHdr->ip_dst.S_un.S_un_b.s_b1),
    (ipHdr->ip_dst.S_un.S_un_b.s_b2),
    (ipHdr->ip_dst.S_un.S_un_b.s_b3),
    (ipHdr->ip_dst.S_un.S_un_b.s_b4)
    );
    break;
    case ETHERTYPE_ARP:
    DbgPrint ("ARP packet:");
    arpPkt = ( PARP_PACKET ) pBuffer->m_IBuffer;
    DbgPrint ( " %u.%u.%u.%u ---> %u.%u.%u.%u ?n",
    (arpPkt->ea.arp_spa[0]),
    (arpPkt->ea.arp_spa[1]),
    (arpPkt->ea.arp_spa[2]),
    (arpPkt->ea.arp_spa[3]),
    (arpPkt->ea.arp_tpa[0]),
    (arpPkt->ea.arp_tpa[1]),
    (arpPkt->ea.arp_tpa[2]),
    (arpPkt->ea.arp_tpa[3])
    );
    break;
    case ETHERTYPE_REVARP:
    DbgPrint ("REVARP packet:n");
    break;
    default:
    DbgPrint ("Uknown type n");
    }*/
    // Simply indicate packet to protocol
    UF_SendPacketToProtocol (
    NdisBindingHandle,
    pBuffer->m_IBuffer,
    pBuffer->m_Length
    );

    // Send packet to all other network interfaces if bridging enabled

    if ( g_BridgingStatus )
    {
    // Locate adapter and protocol entryes associated with operation
    pReceivedAdapter = MF_FindAdapterByBindingHandle( NdisBindingHandle, &pProto);

    pAdapter = ( PADAPTER_ENTRY ) pProto -> m_AdaptersList.Flink;

    // Walk the list of binded adapters
    while ( pAdapter != ( PADAPTER_ENTRY ) &pProto -> m_AdaptersList )
    {
    if ( pAdapter != pReceivedAdapter)
    {
    // Packet was receved not from this adapter
    // Simply send packet onto this interface

    // DbgPrint ("Duplicating packet on the another interface...n");

    if (osMajorVersion == 5 && osMinorVersion > 0)
    UF_SendPacketToAdapter ( &pAdapter->m_XPOpenBlock, pBuffer );
    else
    UF_SendPacketToAdapter ( &pAdapter->m_W2kOpenBlock, pBuffer );


    // Also indicate packet to TCPIP from the name of this interface
    if (osMajorVersion == 5 && osMinorVersion > 0)
    UF_SendPacketToProtocol (
    &pAdapter->m_XPOpenBlock,
    pBuffer->m_IBuffer,
    pBuffer->m_Length
    );
    else
    UF_SendPacketToProtocol (
    &pAdapter->m_W2kOpenBlock,
    pBuffer->m_IBuffer,
    pBuffer->m_Length
    );

    }
    pAdapter = (PADAPTER_ENTRY) pAdapter->m_qLink.Flink;
    }
    }

    // Free intermediate buffer
    IB_FreeIntermediateBuffer ( pBuffer );
    }


    //***********************************************************************************
    // Name: FLT_FilterSendPacket
    //
    // Description: Routine for filtering outgoing packets, place packet processing code
    // here
    //
    // Return value: None
    //
    // Parameters:
    // NdisBindingHandle - network interface binding handle
    // pBuffer - pointer to intermediate buffer
    //
    // NOTE: None
    // **********************************************************************************

    VOID FLT_FilterSendPacket (
    NDIS_HANDLE NdisBindingHandle,
    PINTERMEDIATE_BUFFER pBuffer
    )
    {
    // Processing relative declarations
    PUSHORT pEtherType;

    //Adapter and protocol relative structures

    PPROTOCOL_ENTRY pProto;
    PADAPTER_ENTRY pAdapter, pSentAdapter;

    DbgPrint ( "FLT_FilterSendPacket pBuffer->m_Lengh = %d...n", pBuffer->m_Length );

    // DbgPrint ( "FLT_FilterSendPacket entered...n" );

    // .... process packet here....

    // We dump packet content here
    // DbgPrint ("nSEND:n");
    // DbgPrint ("MACS: DEST %.2X%.2X%.2X%.2X%.2X%.2X SOURCE: %.2X%.2X%.2X%.2X%.2X%.2Xn",
    // pBuffer->m_IBuffer[0],
    // pBuffer->m_IBuffer[1],
    // pBuffer->m_IBuffer[2],
    // pBuffer->m_IBuffer[3],
    // pBuffer->m_IBuffer[4],
    // pBuffer->m_IBuffer[5],
    // pBuffer->m_IBuffer[6],
    // pBuffer->m_IBuffer[7],
    // pBuffer->m_IBuffer[8],
    // pBuffer->m_IBuffer[9],
    // pBuffer->m_IBuffer[10],
    // pBuffer->m_IBuffer[11]
    // );

    pEtherType = (PUSHORT) pBuffer->m_IBuffer;
    pEtherType += ETH_LENGTH_OF_ADDRESS;

    /* switch( htons( *pEtherType ) )
    {
    case ETHERTYPE_IP:
    DbgPrint ("IP packet: ");
    ipHdr = ( PIP_HEADER ) &pBuffer->m_IBuffer[MHdrSize];
    DbgPrint ( " %u.%u.%u.%u ---> %u.%u.%u.%un",
    (ipHdr->ip_src.S_un.S_un_b.s_b1),
    (ipHdr->ip_src.S_un.S_un_b.s_b2),
    (ipHdr->ip_src.S_un.S_un_b.s_b3),
    (ipHdr->ip_src.S_un.S_un_b.s_b4),
    (ipHdr->ip_dst.S_un.S_un_b.s_b1),
    (ipHdr->ip_dst.S_un.S_un_b.s_b2),
    (ipHdr->ip_dst.S_un.S_un_b.s_b3),
    (ipHdr->ip_dst.S_un.S_un_b.s_b4)
    );
    break;
    case ETHERTYPE_ARP:
    DbgPrint ("ARP packet:");
    arpPkt = ( PARP_PACKET ) pBuffer->m_IBuffer;
    DbgPrint ( " %u.%u.%u.%u ---> %u.%u.%u.%u ?n",
    (arpPkt->ea.arp_spa[0]),
    (arpPkt->ea.arp_spa[1]),
    (arpPkt->ea.arp_spa[2]),
    (arpPkt->ea.arp_spa[3]),
    (arpPkt->ea.arp_tpa[0]),
    (arpPkt->ea.arp_tpa[1]),
    (arpPkt->ea.arp_tpa[2]),
    (arpPkt->ea.arp_tpa[3])
    );
    break;
    case ETHERTYPE_REVARP:
    DbgPrint ("REVARP packet:n");
    break;
    default:
    DbgPrint ("Uknown type n");
    }*/

    // Simply send packet onto network
    UF_SendPacketToAdapter (
    NdisBindingHandle,
    pBuffer
    );

    // Send packet to all other network interfaces if bridging enabled

    if ( g_BridgingStatus )
    {
    // Locate adapter and protocol entryes associated with operation
    pSentAdapter = MF_FindAdapterByBindingHandle( NdisBindingHandle, &pProto);

    pAdapter = ( PADAPTER_ENTRY ) pProto -> m_AdaptersList.Flink;

    // Walk the list of binded adapters
    while ( pAdapter != ( PADAPTER_ENTRY ) &pProto -> m_AdaptersList )
    {
    if ( pAdapter != pSentAdapter)
    {
    // Packet was sent not to this adapter
    // Simply send packet onto this interface

    // DbgPrint ("Duplicating packet on the another interface...n");

    if (osMajorVersion == 5 && osMinorVersion > 0)
    UF_SendPacketToAdapter (
    &pAdapter->m_XPOpenBlock,
    pBuffer
    );
    else
    UF_SendPacketToAdapter (
    &pAdapter->m_W2kOpenBlock,
    pBuffer
    );

    }
    pAdapter = (PADAPTER_ENTRY) pAdapter->m_qLink.Flink;
    }
    }


    // Free intermediate buffer
    IB_FreeIntermediateBuffer ( pBuffer );
    }