Transmission sample

This small snippet of code shows how to populate a TC_PACKETS_BUFFER with packets to be transmitted in two possible ways:

void
FillPacketsBuffer(TC_PACKETS_BUFFER hPacketsBuffer)
{
    TC_PACKET_HEADER header;
    TC_STATUS status;
    static ULONG watermark;
    BYTE pData[PACKET_SIZE];

    ZeroMemory(&header, sizeof(header));
    header.Length = PACKET_SIZE;
    header.CapturedLength = PACKET_SIZE;

    //
    // MAC destination
    //
    pData[0] = 0xFF;
    pData[1] = 0xFF;
    pData[2] = 0xFF;
    pData[3] = 0xFF;
    pData[4] = 0xFF;
    pData[5] = 0xFF;

    //
    // MAC source
    //
    pData[6] = 0x00;
    pData[7] = 0x00;
    pData[8] = 0x00;
    pData[9] = 0x00;
    pData[10] = 0x00;
    pData[11] = 0x00;

    //
    // Ethertype is 0xCACE
    //
    pData[12] = 0xCA;
    pData[13] = 0xCE;

    do
    {

        //
        // let's put the watermark in the first 4 bytes of the packet L2 payload
        //
        *(PULONG)&pData[14] = watermark;

        //
        // This involves a copy of the packet
        //
        status = TcPacketsBufferCommitNextPacket(hPacketsBuffer, &header, pData);

        if (status != TC_SUCCESS) break; // the buffer is full
        
        watermark ++;

    }while(TRUE);
}
void
FillPacketsBufferLowLevel(TC_PACKETS_BUFFER hPacketsBuffer)
{
    PTC_PACKET_HEADER pHeader;
    TC_STATUS status;
    static ULONG watermark;
    PBYTE pData;
    PBYTE pBuffer;
    ULONG bufferLength;
    ULONG position = 0;

    pBuffer = (PBYTE)TcPacketsBufferGetBuffer(hPacketsBuffer);
    bufferLength = TcPacketsBufferGetLength(hPacketsBuffer);

    do
    {
        if (position + sizeof(TC_PACKET_HEADER) + TC_ALIGN_USHORT_TO_64BIT(PACKET_SIZE) > bufferLength) break;

        pHeader = (PTC_PACKET_HEADER)(pBuffer + position);
        
        position += sizeof(TC_PACKET_HEADER);
        
        pData = pBuffer + position;
    
        ZeroMemory(pHeader, sizeof(TC_PACKET_HEADER));
        pHeader->Length = PACKET_SIZE;
        pHeader->CapturedLength = PACKET_SIZE;

        //
        // MAC destination
        //
        pData[0] = 0xFF;
        pData[1] = 0xFF;
        pData[2] = 0xFF;
        pData[3] = 0xFF;
        pData[4] = 0xFF;
        pData[5] = 0xFF;

        //
        // MAC source
        //
        pData[6] = 0x00;
        pData[7] = 0x00;
        pData[8] = 0x00;
        pData[9] = 0x00;
        pData[10] = 0x00;
        pData[11] = 0x00;

        //
        // Ethertype is 0xCACE
        //
        pData[12] = 0xCA;
        pData[13] = 0xCE;

        //
        // let's put the watermark in the first 4 bytes of the packet L2 payload
        //
        *(PULONG)&pData[14] = watermark;
        
        watermark ++;
        
        position += TC_ALIGN_USHORT_TO_64BIT(PACKET_SIZE);

    }while(TRUE);

    status = TcPacketsBufferSetEffectiveLength(hPacketsBuffer, position);
    _ASSERT(status == TC_SUCCESS);
}
int main(int argc, char* argv[])
{
    TC_INSTANCE hInstance;
    TC_PACKETS_BUFFER hPacketsBuffer;
    TC_STATUS status;
    PCHAR portName;

    if (argc < 2)
    {
        printf("Please provide port name\n");
        return -1;
    }

    portName = argv[1];

    status = TcInstanceOpenByName(portName, &hInstance);

    if (status != TC_SUCCESS)
    {
        printf("Error, cannot open port, error %s (%08x)\n", TcStatusGetString(status), status);
        return -1;
    }

    //
    // Enable transmission
    //
    status = TcInstanceSetFeature(hInstance, TC_INST_FT_TX_STATUS, 1);
    if (status != TC_SUCCESS)
    {
        printf("Error, cannot enable transmission: %s (%08x)", TcStatusGetString(status), status);
        
        (VOID)TcInstanceClose(hInstance);
        return -1;
    }

    //
    // transmission code
    //
    do
    {
        status = TcPacketsBufferCreate(512 * 1024, &hPacketsBuffer);
        if (status != TC_SUCCESS)
        {
            break;
        }
        
        do
        {
            //
            // Please enable only one of the two buffer creation functions.
            //

            //
            // this is the first way to put packets in the buffer, API based
            //
            FillPacketsBuffer(hPacketsBuffer);

            //
            // This the second way to put packets in the buffer, raw buffers
            //
            FillPacketsBufferLowLevel(hPacketsBuffer);
        
            //
            // NOTE: what happens if only part of the buffer can be transmitted?
            //
            status = TcInstanceTransmitPackets(hInstance, hPacketsBuffer);
            
            if (status != TC_SUCCESS)   break;
            if (_kbhit()) break;
        }while(TRUE);

        TcPacketsBufferDestroy(hPacketsBuffer);

    }while(FALSE);
    
    if (status != TC_SUCCESS)
    {
        printf("Error in the transmission process: %s (%08x)\n", TcStatusGetString(status), status);
    }

    status = TcInstanceClose(hInstance);
    _ASSERT(status == TC_SUCCESS);
}

TurboCap API documentation. Copyright (c) 2007-2008 CACE Technologies. All rights reserved.