Knowledge base: Knowledge Base > ByteBlower > Automation > Tcl
Tutorial: Hello (ByteBlower) World application
Posted by Wouter Debie, Last modified by Pieter Vandercammen on 29 October 2020 06:11 PM

Introduction

When learning a new progamming language, you always start with a Hello-world project. Mostly it is a simple exercise to learn the basics of a language. Let's do the same to start knowing the basic of the ByteBlower API in TCL. Lets make a Hello-world project - aka a simple back 2 back flow between 2 port. For this to work we need

The API documentation can be read online at http://api.byteblower.com . This tutorial is also published in the API docs at https://api.byteblower.com/tcl/bbexamples_tut.html .

Hello ( TCL ) world

The tclsh is a simple command-line interactive interpreter. You can either start it with a script on the command line, in which case it runs the script to completion and then exits, or you can start it without any arguments, in which case you will be presented with an interactive prompt, usually using a % symbol to prompt for input. In interactive mode, you can type in commands, which Tcl will then execute and display the result, or any error messages that result. To exit the interpreter, type exit and press Return. Playing around with the interactive interpreter is a great way to learn how to use Tcl. Most Tcl commands will produce a helpful error message explaining how they are used if you just type in the command with no arguments.

If you have never worked with TCL then on this page ( http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html ) you will find a complete tutorial covering everything you need or want to know about programming in TCL.

To continue this tutorial you only need to know the first 8 short lessons.

Hello ( ByteBlower ) world

Now that we covert the basics of TCL we can start on writing our first TCL script to send traffic between 2 ByteBlower ports. What we need are 2 ports on the Trunking interface connected back-to-back. This is a simple setup for our simple Hello-world script.

We start by starting an editor that you prefer to work with. You can use Notepad++ on windows, vim of geany on Linux or Textwrangle on Mac. We will write our lines of code in a file that we afterwards can execute. You could also type these lines directly in a Tcl-console and see the output directly on the screen.

Loading the ByteBlower API

Before we can start we need to load the ByteBlower API. This can be done simply by following lines of code.

package require ByteBlower
package require ByteBlowerHL
package require excentis_basic

The first line Package require ByteBlower will load the Lower Layer API of ByteBlower. Since this is a simple hello-world, we will load also the Higher Layer API which will help us with common tasks. More info can be found in ( background: The ByteBlower TCL API and its components )

Connect to ByteBlower

Now the API's are loaded so let's continue with our next step: connecting to the ByteBlower server. To do this, we create a ByteBlower Server Object. Once this object is created, we have a connection to our server. The parameter after "Server.Add" can be the fqdn of your ByteBlower server or even its IP-address. 

set bbServer [ ByteBlower Server.Add byteblower.lab.company.com ]

The variable $bbServer now holds our ByteBlowerServerObject. If you want, you can print out the description of this serverObject with following command.

puts [ $bbServer Description.Get ]

Every ByteBlower-object has a method Description.Get. This method will print out all information known about this object. This information will be printed in a hirachical way. So if you ask the description of a server, you will get the description of every port, which will print out the description of every flow on that port... and so on.

Create our src-port and dst-port

Now that we have a server, we will create a source port and a destination port. Step by step we will do this for the source port. For the destination port we will us the same methods. First we create our port on the server. The physical location of this port is het first port on our first trunk switch. So the name for this port is trunk-1-1 ( trunk-1 port 1 ).

set srcPort [ $bbServer Port.Create "trunk-1-1" ]

Our port is created and stored in variable srcPort. Let's move on to Layer2

set srcL2 [ $srcPort Layer2.Set ethII ]
$srcL2 Mac.Set "00ff1c000001"

Now that we have configured our Layer2 on our ByteBlowerPort we can create a Layer3. There are 2 types of Layer3 supported by ByteBlower: IPv4 and IPv6. In this example we use IPv4 But you could easly use IPv6 as well. We start by creating the Layer3 Object and then configure it with the apropriate values. 

set srcL3 [ $srcPort Layer3.Set ipv4 ]
$srcL3 Ip.Set "192.168.1.2"
$srcL3 Netmask.Set "255.255.255.0"
$srcL3 Gateway.Set "192.168.1.1"

Lets do the same for our destination port.

set dstPort [ $bbServer Port.Create "trunk-1-2" ]
set dstL2 [ $dstPort Layer2.Set ethII ]
$dstL2 Mac.Set "00ff1c000002"
set dstL3 [ $dstPort Layer3.Set ipv4 ]
$dstL3 Ip.Set "192.168.1.3"
$dstL3 Netmask.Set "255.255.255.0"
$dstL3 Gateway.Set "192.168.1.1"

So this is done. Now we have an active source-port and an active destination port. Lets create a frame we want to send and put is on this flow.

Create a Frame.

To easly create a frame, we use a procedure which is available in our excentis_basic package. This procedure will generate the bytes of our package that we can set on our flow. First we need to resolve our destination mac address. Following snippet will send an ARP request from our source port to resolve the mac-address.

#
# --- Get the destination MAC addresses for our UDP frame to reach the other port ---
#
#- Sending an Arp for the destination IP of our UDP frame.
set dmacBackToBackDestination [ $srcL3 Protocol.Arp [ $dstL3 Ip.Get ] ]

Protocol.Arp will have as effect the transmission of an ARP packet to resolve the destination. It will return the resolved mac-address ( depending on the setup: the mac-address of our destination-port or the mac-address of our gateway). If it fails, it will throw an exception. Now that we have our destination mac-address, we can generate the bytes of our frame. We will create an UDP frame of length 64 ( incl FCS ) between udp-port 2001 and 2002.

set dstUdpPort 2002
set srcUdpPort 2001
# length exclude FCS
set udpLength 60
set srcFrameContent [ Frame.Udp.Set $dmacBackToBackDestination [ $srcL2 Mac.Get ] [ $dstL3 Ip.Get ] [ $srcL3 Ip.Get ] $dstUdpPort $srcUdpPort [ list -Length $udpLength ] ]

This line of code will return the string representation of the bytes of our frame. If you want to provide UDP content you could create your frame this way

set dstUdpPort 2002
set srcUdpPort 2001
set srcFrameContent [ ::excentis::basic::Frame.Udp.Set $dmacBackToBackSource [ $srcL2 Mac.Get ] [ $dmacBackToBackSource Ip.Get ] [ $srcL3 Ip.Get ] $dstUdpPort $srcUdpPort { 0xAA 0xBB 0xCC 0xDD }

Create a Flow

Since we will use the Higher Layer API, we don't need to create all the flow-object. The HL-API will do this for us. We simple need to describe the flow, provide its characteristics. In this example we will send a 1000 frames with an interframe gap of 1ms. At the receiving side, we will count the packets that meet our filter.

set numberOfFrames 1000
set interFrameGap 1000000

set srcFlow [ list -tx [ list -port $srcPort \
    -frame $srcFrameContent \
    -numberofframes $numberOfFrames \
    -interframegap $interFrameGap \
] \
    -rx [ list -port $dstPort \
    -trigger [ list -type basic -filterFormat bpf -filter "( ip src [ $srcL3 Ip.Get ] ) and ( ip dst [ $dstL3 Ip.Get ] ) and ( udp src port $srcUdpPort ) and ( udp dst port $dstUdpPort )" ] \
] \
]

the scenario

To run our scenario we call the Higher Layer method ExecuteScenario and provide as argument our flow configuration. If we give it a list of flow configuration than all these flows will be executed.

# Sending the packet
set result [ ::excentis::ByteBlower::ExecuteScenario [ list $srcFlow ] ]
puts "Result of this back-to-back scenario:" puts "${result}"

Destroy our object

As a pragmatic programmer we must release our resources. If not, we could create a leak. To destroy all our object we just need to destroy our parent object meaning our serverObject. Every child-Object will be destroyed as well.

# Destructing our objects
$bbServer Destructor

Run the final script

Now the script is finished, we can run it. Just open a terminal and start wish84. On Windows just start wish.exe ( normally located in the start menu ).

debie@laptop:~$ wish

Now the wish is loaded, lets source our script aka hello-byteblower-world.tcl

source hello-byteblower-world.tcl

Voila your script is running, you first automated test with the ByteBlower API is created. If all is connected well you sould get some output like this

Result of this back-to-back scenario
{-tx {NrOfFramesSent 1000 ByteBlowerObject_1381496571_10 1000} -rx {NrOfFrames 1000}}
(0 vote(s))
Helpful
Not helpful

Comments (0)

We to help you!