Writing a Transmit Script

In this tutorial, we will show you how to programmatically generate and transmit packets over the currently opened transport session.

Simple Packet

The entry point of your script is the main function. It takes no arguments, and doesn’t return any value.

void main()
{
    // TODO: generate & transmit packets
}

Since this code will be present in most user-defined scripts, we made it possible to auto-generate it with a few keystrokes. Start typing the function name (letter m), then press Ctrl + Space, and an auto-completion list will pop up. Select main (if you have an empty script, main will be the very first item on the list):

_images/script-main-auto-complete.png

Hit Enter – et voila! The skeleton for your transmission script is ready.

Now, let’s send our first programmatically generated packet. To do so, prepare a buffer, then pass it to the transmit function:

struct MyPacket
{
    int m_command;
    int m_param;
}

void main()
{
    MyPacket packet;
    packet.m_command = 10;
    packet.m_param = 20;
    transmit(&packet, sizeof(packet));
}

You can omit the size argument to the transmit function; in this case strlen will be used on the buffer, which makes it convenient to transmit strings:

void main()
{
    transmit("some-plain-text-command");
}

Connect & Disconnect

Before transmission, you must make sure the connection is established – otherwise, transmit will fail. Of course, you can simply click the Connect button before running your script. But it’s also possible to do programmatically, from within the script itself.

Observe:

void main()
{
    connect();
    transmit("command");
    sys.sleep(1000); // give the peer a chance to reply
    disconnect();
}

This script will ensure the connection is established before sending a command, then it will wait for a second (so that the peer has some time to respond), and then close the connection.

Looped Transmission

The examples above may have given you a taste of how the programmatically-driven transmission works, but those examples are still kind of boring – you can achieve the same even without in-app scripting, simply by using the Transmit Pane!

OK, let’s make it a bit more interesting. How about we send a unique packet for each address in the specific range? And let’s also pass the current timestamp as the parameter! This definitely cannot be done just with the Transmit Pane, without scripting! Alright, here we go:

alignment(1);

struct MyPacket
{
    uint32_t m_address;
    uint64_t m_timestamp;
}

void main()
{
    connect();

    for (uint32_t id = 10; id < 90; id++)
    {
        MyPacket packet;
        packet.m_address = id;
        packet.m_timestamp = sys.getTimestamp();
        transmit(&packet, sizeof(packet));
    }
}

You can even create an infinite loop – which will run forever! Or, more likely, until you press Stop.

void main()
{
    connect();

    for (int i = 0;; i++)
    {
        transmit($"command-id-%d"(i));
        sys.sleep(250);
    }
}