LANforge-CLI API Cookbook

The LANforge-CLI API Cookbook provides a series of detailed examples of how to craft testing scripts for unattended/automated operation. Each example intends to give the reader a runnable test script and a better understanding of how to use the LANforge-CLI API.

Places to Run CLI Commands

You do not need to operate scripts directly from the LANforge server, and this allows you to code scripts in your preferred text editing environment. Likewise, you do not need to run a copy of LANforge Server on your desktop. Scripts will create a plain-text connection to the LANforger server you specify.

Windows Desktop
You can install a copy of the LANforge Server on your windows desktop (without a license) so that you have access to the Perl scripting libraries. Edit scripts and run them from your C:\Program Files\LANforge-Server\scripts directory.
Linux Desktop
You can copy the LANforge scripts folder directly from your LANforge server to your Documents directory with scp.
SSH or VNC connection to LANforge Server
Using vncviewer, rdesktop or ssh are all fine options to connect to the LANforge server to write and operate scripts. The LANforge server comes with a basic Linux desktop and you can use emacs, vim, pluma, or gedit text editors installed by default. When editing scripts on the LANforge server itself, be careful to back up your work before you upgrade LANforge. The LANforge install process will over-write scripts of the same name in the scripts directory.

Requirements for Scripts

Your desktop (or other computer) running CLI scripts needs to have a reliable (wired) connection to the management port of your LANforge server. If you are engaging in long running tests, you might consider running the scripts from the LANforge manager itself if your desktop machine needs to be powered off.

Script Libraries
CLI scripts are written using Perl. They require the libraries in /home/lanforge/scripts/LANforge Users may write scripts in other programming languages, such as python, but in that case, they will not be able to take direct avantage of the Perl scripts included in LANforge.
On Windows
LANforge is more fully featured on Linux, but basic support exists on Windows as well.

You can run CLI scripts from any Windows desktop as long as you have Perl installed. You can use ActiveState Perl or Perl from the Cygwin project. We also highly suggest installing PuTTY ssh client to access your LANforge server.

On Linux/OS X
Most Linux distributions come with and ssh client and Perl already installed.
LANforge Server Requirements
The following examples will create test scenarios that work on LANforge Linux systems running the LANforge software with the LANforge kernel and a sufficient license. If you are running LANforge server using another Linux kernel, you may not be able to operate some of the examples. (Features like Armageddon, operation of WiFi-AC radios, and WanLinks all require drivers included only in Candela provided kernels.)
Please contact us at support@candelatech.com if you have any questions.

Before Starting LANforge-CLI Traffic Generation

Before attempting the examples below, ensure that you have successfully followed these software installation guides:

It is also recommended that you back up your current running LANforge Server database so that you may safely return to your current operating state.
For instance:

     su - root
     cd /home/lanforge
     tar -cvzf my_db_backup.tar.gz DB
     

LANforge-CLI Detailed Cookbook Examples

  1. CLI: Introduction
  2. Monitor and Reset Ports with the portmod Script
  3. Cross Connects and Endpoints Tutorial
  4. Creating Connections with the FIREmod Script
  5. Operating Endpoint Hunt Scripts with the CLI
  6. Generating WiFi Traffic with the Associate Script
  7. Changing Station WiFi SSID with the CLI API
  8. Changing Station POST_IFUP Script with the CLI API
  9. Scripting Attenuation with CSV data
  10. LANforge Entity IDs
  11. Querying the LANforge GUI for JSON Data
  12. Station CLI Operations

Introduction to CLI Scripts

Goal: You will be able to execute LANforge testing scripts from the command line from Windows, Linux, remote desktop or ssh connection.

Traffic emulation may be run unattended and automated using Perl scripts provided with the LANforge Server. These scripts can be run from within the LANforge server or outside the LANforge Server (on a Windows or other desktop). The output of the scripts should be redirected into a text file for you to process the results.

Where Do I Find Scripts?

On Windows

On most versions of windows, the LANforge Server installs scripts in

C:\Program Files (x86)\LANforge-Server\scripts

On Linux

In the home directory for user LANforge:

/home/lanforge/scripts

How to Run Scripts

Starting a script on Windows:
  1. Make sure that perl is in your PATH. (See Inspecting DOS PATH)
  2. Open a CMD window (or a PowerShell window)
  3. and change directory to C:\Program Files (x86)\LANforge-Server\scripts
  4. Type perl .\script_name.plENTER to run the script.
Generally, the script will tell you that it needs more switches.
Finding Help
Most scripts have a -h or --help switch that explain what switches they expect.
Script Conventions
In general, scripts will expect you to tell them a few things, regardless of the script:
  • The manager IP address to connect to:--mgr 127.0.0.1 or --manager 192.168.100.1. This often defaults to 127.0.0.1, but when connecting from outside the machine, please use the IP of the LANforge management port (often eth0).
  • The manager port to connect to:--port 4001 or --mgr_port 4001. This often defaults to 4001.
  • Which resource to direct the command to. The manager is always resource 1. Resource 2 would be your second LANforge server. --resource 2. Some scripts use the older term card: --card
  • If you need debugging output, turn off quiet mode: -q no or --quiet no. Some older scripts want you to turn quiet on explicitly: --quiet 1
  • To capture the output, use the > operator to redirect the text output into a text file.
  • Scripts are often executed from within a shell script (or batch file). Often the formatting of the commands includes '\' characters which indicate 'continue this command on the next line of input.' Here is an example of formatting a single script command on multipl lines:
     $ ./lf_portmod.pl \
       --manager 192.168.100.1 \
       --card 3 \
       --show_port
  • Comments begin with '#'. They are lines ignored by the shell, and they are also comments in perl.
Running on local LANforge manager
You can use ssh, VNC or Rdesktop to connect from your desktop to your LANforge manager server. (When using VNC, assume display :1). From there, in a terminal, you will execute your script from the /home/lanforge/scripts directory as shown in the example below:
 $ cd /home/lanforge/scripts
 $  ./lf_portmod.pl --help
#...help appears...
 $ ./lf_portmod.pl --manager 192.168.100.1 --card 1 --show_port
# ... displays port info
         
Running on local LANforge resource
If you connect to a LANforge resource and want to run a script, you must direct the script at the LANforge manager server and specify the resource you are interested in. For example, you might be on resource 2 (192.168.100.2) and desire to run tests on resource 3 (192.168.100.3):
 $ cd /home/lanforge/scripts
 $  ./lf_portmod.pl --manager 192.168.100.1 --card 3 --show_port
# ... displays port info
Running on a Linux Desktop to a Remote LANforge
A more detailed set of steps follows. When running LANforge CLI scripts on a Linux desktop, you normally want to download and un-zip a copy of the LANforge-Server install file found on the Candela Technologies downloads page. Use a link similar to: http://www.candelatech.com/private/downloads/r5.3.2/LANforgeServer-5.3.2_Linux-F21-x64.tar.gz. For best results, use the scripts packaged with the version of LANforge to which your scripts will be connecting.
  1. Open a terminal on your desktop, cd to your Downloads folder
  2. use wget or curl to download the tar file:
     wget "http://guest:guest@www.candelatech.com/private/downloads/r5.3.2/LANforgeServer-5.3.2_Linux-F21-x64.tar.gz"
  3. Create a scripts directory in your Documents folder:
     $ cd ~/Documents/scripts
  4. Expand the tar file in your Downloads directory:
     $ tar xf LANforgeServer*tar.gz
  5. Copy the scripts file into your Documents folder:
     $ cp -r LANforgeServer-5.3.2/scripts/. ~/Documents/scripts/

To use your scripts, in your terminal, change directories to ~/Documents/scripts and they will operate similar to the above examples.

 $ cd ~/Documents/scripts
 $ ./lf_portmod.pl --manager 192.168.100.1 --card 3 --show_port

Running on a Windows Desktop to a Remote LANforge
The process for running CLI scripts on a Windows desktop is roughly similar, but involves running the Windows LANforge Server installer. This process does not require a Windows license as we will not be running the windows LANforge server. Perl is required to run Windows scripts. Start by installing that. You can use the perl that comes with the Cygwin project or if you just want perl, install the ActiveState ActivePerl package. ActivePerl should install update your environment %PATH% variable. If it does not immediately, you might need to log out and log back in.
  1. Download the Windows version of the LANforge Server installer using your browser: http://www.candelatech.com/private/downloads/r5.3.2/LANforge-Server-5.3.2-Installer.exe. Use username guest, password guest.
  2. In your Downloads folder, double click and install the LANforge-Server-Installer.exe. Do not configure it, do not run LANforgeServer. You will not need to be running the LANforge GUI to do this install.
  3. The installation scripts folder will be system-protected, so you want to copy the folder over to your desktop Documents directory.
  4. Open a DOS terminal, either using Run→cmdEnter or Run→powershellEnter
  5. Change to the new copy of the scripts directory, and then you can run scripts by giving them to perl:
     C:> cd C:\Users\bob\Documents\scripts
     C:> perl .\lf_portmod.pl --manager 192.168.100.1 --card 3 --show_port --port_name eth1 --quiet 1
  6. To capture output from a script, use the shell redirect operator: >. This example shows redirecting and browsing the results with Notepad:
     C:> perl .\lf_portmod.pl --manager 192.168.100.1 --card 3 --show_port --port_name eth1 --quiet 1 > results.txt
     C:> notepad.exe results.txt

Inspecting Ports (Network Interfaces) using lf_portmod

Goal: You will be able to report and reset ports on your LANforge server.

Port statistics can be programatically monitored using the script lf_portmod.pl. This script can also reset ports, alter WiFi station settings, and pass arbitrary LANforge CLI commands directly to the LANforge manager.

Ports of all kinds can be viewed with the lf_portmod.pl perl script. You can also do some limited manipulation of ports as well.

Listing Ports
You can show statistic on a port with the --show_port argument:
 C:\> perl .\lf_portmod.pl --quiet 1 --manager jedtest --card 1 --port_name eth1 --show_port
You can right-click to paste these commands into your DOS window
Produces:
Listing Port Attributes
Individual port attributes can also be shown, which often makes automating reporting easier.
perl .\lf_portmod.pl --manager jedtest --card 1 --quiet 1 --port_name eth1 --show_port "RxDrop,Rxp,IP"
Produces: Consider that is a lot of text to type. If we want, we can reformat that command.
Long DOS commands and be continued on the next line with the ^ character.
perl .\lf_portmod.pl --manager jedtest ^
 --card 1 --quiet 1 --port_name eth1 ^
 --show_port "RxDrop,Rxp,IP"
Produces the same output:
Loading a test scenario
Saved test scenarios are often referred to as 'databases'
lf_portmod.pl --load day_238
This matches the same database name seen in the Status tab database dropdown.
Admin-down a port
lf_portmod.pl --manager 192.168.1.101 --card 1 --port_name eth2 --set_ifstate down
Resetting a Port
Resetting a port forces a port to unload and reload its configuration.
lf_portmod.pl --manager 192.168.1.101 --card 1 --port_name eth2 --cmd reset
Sending a specific CLI command to the LANforge manager:
It is possible to directly pass a command to the LANforge manager:
lf_portmod.pl --manager 192.168.1.101 --cli_cmd "scan 1 1 sta0"

Cross Connects and Endpoints Tutorial

Goal: Gain a better understanding on how you will use Cross connects, Connections and Endpoints to use the LANforge CLI scripts knowlegably.

Creating connections in the LANforgeGUI implies creating endpoints. These endpoint entities are created with predictable names and are usually created in pairs. Understanding these naming conventions and how they are created is fundamental to your proficiency with creating connections with LANforge CLI scripts.

Most examples in our cookbooks assume a dual-ended connection, also known as a cross-connect or abbreviated as CX.

Building Endpoints and Connections

Let's follow the creation of a Connection:

Using a terminal on the LANforge machine, we look at the /home/lanforge/DB/DFLT/endps.db file and inspect the commands issued that create that connection:

That's a lot of commands. We will point out what is particularly necessary when using our Perl scripts.

Endpoints and Connections Naming Convention

The connection we created above is named tutorial-cx. Two endpoints also have names, tutorial-cx-A and tutorial-cx-B. The A-side of a connection is always managed. A B-side endpoint may be unmanaged. When you write CLI scripts that create connections, name your endpoints using a similar convention.

Endpoints are Created First

We can use the lf_firemod.pl script to create endpoints and a cross connect in this order:

$ ./lf_firemod.pl --action create_endp --endp_name tutorial2-cx-A \
      --speed 256000 --endp_type lf_tcp --port_name sta301

$ ./lf_firemod.pl --action create_endp --endp_name tutorial2-cx-B \
      --speed 256000 --endp_type lf_tcp --port_name eth1

$ ./lf_firemod.pl --action create_cx --cx_name tutorial2-cx \
      --cx_endps tutorial2-cx-A,tutorial2-cx-B

We can see the results of those script commands in our Layer-3 and L3 Endps tabs:

Multiple Windows can be displayed using the Tear Offs menu.
Clicking on the Layer-3 connection automatically highlights the two endpoints.

Starting and Stopping: Connections have State

When a connection is first created, it is STOPPED. When you start it, it becomes RUNNING. When you set a connection to STOPPED, both endpoints immediately stop sending and recieving. That can have a consequence of leaving unacknowledged packets in flight. The safest way is to QUIECE the connection, which first stops the endpoints transmitting, waits a short time, and then stops the endpoints from recieving.

When there is just one Endpoint

Normally, if you see one endpoint, it should only be a multicast endpoint. A single endpoint can be seen in these situations:

  • You have paused between creating the first and second endpoint for a connection. Continue working.
  • Created by a script mistakenly, through a typo or other misconfiguration
  • Left over from an interrupted script that deleted the cross-connect and one of two endpoints

A single endpoint is not an illegal entity, but lonely endpoints can add confusion. If you find endpoints that do not match any existing connections, we suggest deleting them.

A Cross-Connect can be one-sided, that is, have one unmanaged endpoint. The A side endpoint is a LANforge managed port transmitting to another device that's not a LANforge machine. Some connection types create this style of endpoint pairs, like File-endpoints and Layer-4 connections.

Multicast

Multicast endpoints are created differently both in the GUI and in the CLI scripting environment. This tutorial does not focus on multicast, but see the section Creating Endpoints section of Creating Connections with FIREMod Script and the chapter on WiFi Multicast Download.

Creating Connections with the FIREmod Script

Goal: Create, destroy, start and stop connections and endpoints without needing to use the LANforge GUI.

Traffic emulation can be run unattended and using automated tools without use of the LANforgeGUI using Perl scripts provided with the LANforge Server. These scripts can be run from within the LANforge server or outside the LANforge Server (on a Windows desktop). The output of the scripts needs to be redirected into a text file for you to process the results.

Script Capabilities

The lf_firemod.pl script has a lot of options because endpoints have a lot of features. Basic actions:

  • Creating and Deleting Endpoints and Cross Connects: create_endp, delte_endp, create_cx, delete_cx
  • Modifying an Endpoints TX Speed: set_endp
  • Listing and Monitoring Ports, Endpoints and Cross Connects: list_ports, show_endp, list_cx, show_cx
  • Reporting on Ports, Endpoints and Cross Connects: show_port, show_endp, show_cx
  • Controlling Traffic: do_cli, start_endp, stop_endp. To start bi-directional traffic, start both endpoints.
  • Pass direct CLI commands: do_cmd. Use this to help configure aspects of your testing scenario that are options presented in this script. Like secondary IPs on a port.

Creating a basic cross connect requires two endpoints, and each endpoint requires a port (network interface). Script options often begin by stating the manager, resource and action:

C:\> perl .\lf_firemod.pl --mgr 192.168.100.1 --resource 2 --action create_endp ...more options...

Script Actions, arguments to --action

Creating Endoints: create_endp

We use these parameters when creating and endpoint:

--endp_name
name this endpoint
--port_name
name of the port this endpoint uses
--speed
speed of the endpoint transmission in bps
--tos
type of service
--max_speed
Maximum port speed if different than minimum speed of port, in bps
--endp_type
Endpoint Types: tcp, udp, tcp6, udp6. To create multicast endpoint types, use mc_udp and mc_udp6.
--min_pkt_sz/--max_pkt_sz
Minimum and maximum packet sizes
--use_csums
Enable checksums
--ttl
packet Time To Live
--report_timer
the update interval for the endpoint

Example of creating a tcp connection endpoint with debugging:

 lf_firemod.pl   --action create_endp \
   --mgr 192.168.45.34        --mgr_port 4002 \
   --endp_name web_1          --speed 154000 \
   --endp_type tcp            --port_name eth1 \
   --quiet no

Creating a multicast udp connection:

 lf_firemod.pl   --action create_endp \
   --mgr 192.168.45.34        --mgr_port 4002 \
   --endp_name mcast_xmit_1   --speed 154000 \
   --endp_type mc_udp         --mcast_addr 224.9.9.8 --mcast_port 9998 \
   --rcv_mcast NO             --port_name eth1 \
   --min_pkt_sz 1072          --max_pkt_sz 1472 \
   --use_csums NO             --ttl 32 \
   --quiet no                 --report_timer 1000 

Create a connection with specific test-manager

 lf_firemod.pl  --action create_endp \
   --mgr 192.168.45.34     --mgr_port 4002 \
   --endp_name web_1       --speed 154000 \
   --endp_type tcp         --port_name eth1 \
   --quiet no              --test_manager web_tm

Show Endpoint Stats: show_endp

By default, using the show_endp action shows all endpoints. It might be useful to place output like this right into a file or to immediate use grep to find the rows you want.

 $ ./lf_firemod.pl --action show_endp --mgr cholla-f19

 RSLT: 0  Cmd: 'nc_show_endp'


FileEndp [e2#0-nfs-100] (NOT_RUNNING, WRITING, WRITE_RATE_BURSTY, CHECK_MOUNT, AUTO_MOUNT, UN_MOUNT, O_TRUNC)
     Shelf: 1, Card: 1  Port: 10  Endpoint: 1  Type: FILE_NFS  Pattern: INCREASING
     MinWriteRate: 1544000bps  MaxWriteRate: 0bps  MinRead/WriteSz: 4096B  MaxRead/WriteSz: 32768B
     MinReadRate:  1544000bps  MaxReadRate:  1544000bps  QuiesceAfterFiles: -1
     NumFiles: 2  MinFileSize: 26214400B  MaxFileSize: 26214400B
     Directory: AUTO  Prefix: AUTO  Volume:
     Server-Mount: 10.41.0.1:/tank/tmp  Mount-Dir: AUTO  Mount-Options:
     RptTimer: 1000ms  RunningFor: 0s  StopIn: 0s  Quiesce: 3
     LastRpt: 0.000 secs ago     RealWriteRate: 0bps   RealReadRate: 0bps
     RetryTimer: 1000ms  InFailedIO: 0ms
       Buffers Read:     Total: 0           Time: 0s    Cur: 0         0/s
       Bytes Read:       Total: 0           Time: 0s    Cur: 0         0/s
       Files Read:       Total: 0           Time: 0s    Cur: 0         0/s
       Bytes Written:    Total: 0           Time: 0s    Cur: 0         0/s
       Buffers Written:  Total: 0           Time: 0s    Cur: 0         0/s
       Files Written:    Total: 0           Time: 0s    Cur: 0         0/s
       Read CRC Failed:  Total: 0           Time: 0s    Cur: 0         0/s

FileEndp [e2#0-nfs-101] (NOT_RUNNING, WRITING, WRITE_RATE_BURSTY, CHECK_MOUNT, AUTO_MOUNT, UN_MOUNT, O_TRUNC)
     Shelf: 1, Card: 1  Port: 12  Endpoint: 2  Type: FILE_NFS  Pattern: INCREASING
     MinWriteRate: 1544000bps  MaxWriteRate: 0bps  MinRead/WriteSz: 4096B  MaxRead/WriteSz: 32768B
     MinReadRate:  1544000bps  MaxReadRate:  1544000bps  QuiesceAfterFiles: -1
     NumFiles: 2  MinFileSize: 26214400B  MaxFileSize: 26214400B
     Directory: AUTO  Prefix: AUTO  Volume:
     Server-Mount: 10.41.0.1:/tank/tmp  Mount-Dir: AUTO  Mount-Options:
     RptTimer: 1000ms  RunningFor: 0s  StopIn: 0s  Quiesce: 3
     LastRpt: 0.000 secs ago     RealWriteRate: 0bps   RealReadRate: 0bps
     RetryTimer: 1000ms  InFailedIO: 0ms
       Buffers Read:     Total: 0           Time: 0s    Cur: 0         0/s
       Bytes Read:       Total: 0           Time: 0s    Cur: 0         0/s
       Files Read:       Total: 0           Time: 0s    Cur: 0         0/s
       Bytes Written:    Total: 0           Time: 0s    Cur: 0         0/s
       Buffers Written:  Total: 0           Time: 0s    Cur: 0         0/s
       Files Written:    Total: 0           Time: 0s    Cur: 0         0/s
       Read CRC Failed:  Total: 0           Time: 0s    Cur: 0         0/s

You can redirect all output into a file:

 $ ./lf_firemod.pl --action show_endp --mgr cholla-f19 > /var/tmp/endp-stats.txt 

It is possible to print out one-word attributes, such as MaxWriteRate tx_bps or rx_bps:

./lf_firemod.pl --mgr 127.0.0.1 --quiet 1 --action show_endp --endp_name cx_0-B --endp_vals tx_bps,rx_bps
Rx Bytes: 99938104
Tx Bytes: 99993112

Configure Endpoint: set_endp

This is for changing the attributes of an endpoint, such as endpoint TX rate.

 $ ./lf_firemod.pl --mgr cholla-f19 --action set_endp --endp_name cx_0-A --speed 2000000

Show Port Stats: show_port

This is pretty useful for getting transmit rate on ports during a connection while not having to use the lf_portmod script. If you do not specify --port_name, all ports will be listed.

 $ ./lf_firemod.pl --action show_port --mgr cholla-f19 --port_name eth2#0

Shelf: 1, Card: 1, Port: 10  Type: MacVLAN  Alias:
  Win32-Name:   Win32-Desc:   Parent/Peer: eth2  Rpt-Timer: 8000  CPU-Mask: 0
   Current:	UP LINK-UP TSO UFO GSO GRO PROBE_ERROR
   Supported:	UP SEND_TO_SELF
   Partner:	UP
   Advertising:	10bt-HD 10bt-FD 100bt-HD 100bt-FD 1000-FD TSO-ENABLED UFO-ENABLED GSO-ENABLED GRO-ENABLED
   IP: 10.41.0.10  MASK: 255.255.255.0  GW: 0.0.0.0  VID: 0  ResetState: COMPLETE
   DNS Servers:
   IPv6-Global: DELETED
   IPv6-Link: fe80::a00:27ff:fe09:183d/64
   IPv6-Gateway: DELETED
   MAC: 08:00:27:09:18:3d  DEV: eth2#0  MTU: 1500  TX Queue Len: 0
   LastDHCP: 0ms  Driver: macvlan Tx-Rate: 1000000Kbps
   Bus-Speed: 0/0  Bus-Width: 0/0
   Bridge-Port-Cost: Ignore  Prio: Ignore  Aging: 0
   DHCP-Client-ID: NONE  DHCP-Vendor-ID: NONE
     pps_tx: 0  pps_rx: 0  bps_tx: 0  bps_rx: 0
     Rxp: 5652  Txp: 21  Rxb: 1932984  Txb: 1826  RxERR: 0  TxERR: 0
     RxDrop: 0  TxDrop: 0  Multi: 5652  Coll: 0  RxLenERR: 0  RxOverFlow: 0
     RxCRC: 0  RxFrame: 0  RxFifo: 0  RxMissed: 0  TxAbort: 0  TxCarrier: 0
     TxFifo: 0  TxHeartBeat: 0  TxWindow: 0  RxBytesLL: 2068632  TxBytesLL: 2330

      

List Ports, action: list_ports

This is the same as --show_port without the port_name option.

Direct LANforge Command: do_cmd

In case you wanted to pass a CLI command directly in. Below is an example of setting the TOS flag for an endpoint:

C:\> perl .\lf_firemod.pl --mgr 192.168.100.1 --action do_cmd \
   --cmd "set_endp_tos cx_01-A LOWDELAY 10"

See the LANforge CLI User Guide for more info.

Remove endpoint: delete_endp

Remember to remove the cross connect before removing the endpoint.

 $ ./lf_firemod.pl --action delete_endp  --mgr cholla-f19 --endp_name cx-0-A

Create Cross-connect: create_cx

First you want to create two endpoints. You will add those endpoints to your cross connect. This example below shows all three steps:

 $ ./lf_firemod.pl --action create_endp --mgr cholla-f19 --port_name eth2#0 \
      --endp_name cx_0-A --speed 1000000 --endp_type tcp --min_pkt_sz 1462 --report_timer 1000

 $ ./lf_firemod.pl --action create_endp --mgr cholla-f19 --port_name eth2#1 \
      --endp_name cx_0-B --speed 1000000 --endp_type tcp --min_pkt_sz 1462 --report_timer 1000

 $ ./lf_firemod.pl --action create_cx --mgr cholla-f19 --cx_name  cx_0 \
      --cx_endps cx_0-A,cx_0-B --report_timer 1000

Below we see the endpoints created: and the CX details screen:

Show Cross Connects: list_cx

This shows the cross connects and their enpoints:

 $ ./lf_firemod.pl --action list_cx --mgr cholla-f19
CX cx_0, endpoint cx_0-A, endpoint cx_0-B

Show Cross Connect Stats: show_cx

The output of this command begins with the basic stats for the CX and includes the statistics of each endpoint.

$ ./lf_firemod.pl --action delete_endp  --mgr cholla-f19 --endp_name cx_0-A
 LANFORGE_TCP CX:  cx_0  id: 12  type: LANFORGE_TCP  DesiredState: UN_INITIALIZED RealState: STOPPED
   tx_endpoint: cx_0-A  rx_endpoint: cx_0-B report_timer: 1.000000s  TestMgr: default_tm

Endpoint [cx_0-A] (NOT_RUNNING, FIXED_PLD_SIZE, RATE_BURSTY, IP_PORT_AUTO)
     Shelf: 1, Card: 1  Port: 10  Endpoint: 11 Type: LANFORGE_TCP  Pattern: INCREASING
     MinTxRate: 1000000bps  MaxTxRate: 1000000bps  MinPktSize: 1462B  MaxPktSize: 1462B
     DestMAC: 08:00:27:69:1a:3d  DestIpAddr: 10.41.0.11  DestIpPort: 0  Quiesce: 3
     SrcMAC:  08:00:27:09:18:3d  SrcIp:  0.0.0.0  IpPort:  0-0  IpTOS: DONT-SET  Priority: 0
     Role: CONNECT  RptTimer: 1000ms  RunningFor: 0s  StopIn: 0s  Avg-Jitter: 0ms
     Latency: 0 -:0:- 0  [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] (1)
     Pkt-Gaps: 0 -:0:- 0  [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] (1)
     Last-Rpt: 0.000 secs ago  RealTxRate: 0bps  RealRxRate: 0bps  TTL: 0  Conn-Timeout: 10000
     FileName:   SendBadCrc: 0  RcvBuf: 0  SndBuf: 0  CWND: 0 SND-MSS: 0
     RxDrop%-SEQ:  0.0000  RxDrop%-CX: 0.0000  Conn-Timer: -1-0ms  Conn-Pause: 0-0ms
     PktsToSend: 0
  Multi-Conn: 0  Active-Connections: 0  Files-Played: 0
     RunningInGroup: NONE  Script-steps-completed: 0  Steps-Failed: 0
     First-Rx: -1ms  Mcast-Source: 0.0.0.0:0
       Rx Pkts:            Total: 0           Time: 60s   Cur: 0         0/s
       Rx Pkts (On Wire):  Total: 0           Time: 60s   Cur: 0         0/s
       Rx Bytes:           Total: 0           Time: 60s   Cur: 0         0/s
       Rx Bytes (On Wire): Total: 0           Time: 60s   Cur: 0         0/s
       Rx OOO Pkts:        Total: 0           Time: 60s   Cur: 0         0/s
       RX Wrong Dev:       Total: 0           Time: 60s   Cur: 0         0/s
       RX CRC Failed:      Total: 0           Time: 60s   Cur: 0         0/s
       RX Bit Errors:      Total: 0           Time: 3s    Cur: 0         0/s
       Rx Dropped Pkts:    Total: 0           Time: 3s    Cur: 0         0/s
          Cx Detected:     0
       Rx Duplicate Pkts:  Total: 0           Time: 60s   Cur: 0         0/s
       Tx Pkts:            Total: 0           Time: 60s   Cur: 0         0/s
       Tx Pkts (On Wire):  Total: 0           Time: 60s   Cur: 0         0/s
       Tx Bytes:           Total: 0           Time: 60s   Cur: 0         0/s
       Tx Bytes (On Wire): Total: 0           Time: 3s    Cur: 0         0/s
       Tx Failed Pkts:     Total: 0           Time: 60s   Cur: 0         0/s
       Tx Failed Bytes:    Total: 0           Time: 60s   Cur: 0         0/s
       Conn Established:   Total: 0           Time: 30s   Cur: 0         0/s
       TCP Retransmits:    Total: 0           Time: 3s    Cur: 0         0/s
       Conn Timeouts:      Total: 0           Time: 30s   Cur: 0         0/s

Endpoint [cx_0-B] (NOT_RUNNING, FIXED_PLD_SIZE, RATE_BURSTY, IP_PORT_AUTO)
     Shelf: 1, Card: 1  Port: 12  Endpoint: 12 Type: LANFORGE_TCP  Pattern: INCREASING
     MinTxRate: 1000000bps  MaxTxRate: 1000000bps  MinPktSize: 1462B  MaxPktSize: 1462B
     DestMAC: 08:00:27:09:18:3d  DestIpAddr: 10.41.0.10  DestIpPort: 0  Quiesce: 3
     SrcMAC:  08:00:27:69:1a:3d  SrcIp:  0.0.0.0  IpPort:  0-0  IpTOS: DONT-SET  Priority: 0
     Role: ACCEPT  RptTimer: 1000ms  RunningFor: 0s  StopIn: 0s  Avg-Jitter: 0ms
     Latency: 0 -:0:- 0  [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] (1)
     Pkt-Gaps: 0 -:0:- 0  [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ] (1)
     Last-Rpt: 0.000 secs ago  RealTxRate: 0bps  RealRxRate: 0bps  TTL: 0  Conn-Timeout: 10000
     FileName:   SendBadCrc: 0  RcvBuf: 0  SndBuf: 0  CWND: 0 SND-MSS: 0
     RxDrop%-SEQ:  0.0000  RxDrop%-CX: 0.0000  Conn-Timer: -1-0ms  Conn-Pause: 0-0ms
     PktsToSend: 0
  Multi-Conn: 0  Active-Connections: 0  Files-Played: 0
     RunningInGroup: NONE  Script-steps-completed: 0  Steps-Failed: 0
     First-Rx: -1ms  Mcast-Source: 0.0.0.0:0
       Rx Pkts:            Total: 0           Time: 60s   Cur: 0         0/s
       Rx Pkts (On Wire):  Total: 0           Time: 60s   Cur: 0         0/s
       Rx Bytes:           Total: 0           Time: 60s   Cur: 0         0/s
       Rx Bytes (On Wire): Total: 0           Time: 60s   Cur: 0         0/s
       Rx OOO Pkts:        Total: 0           Time: 60s   Cur: 0         0/s
       RX Wrong Dev:       Total: 0           Time: 60s   Cur: 0         0/s
       RX CRC Failed:      Total: 0           Time: 60s   Cur: 0         0/s
       RX Bit Errors:      Total: 0           Time: 3s    Cur: 0         0/s
       Rx Dropped Pkts:    Total: 0           Time: 3s    Cur: 0         0/s
          Cx Detected:     0
       Rx Duplicate Pkts:  Total: 0           Time: 60s   Cur: 0         0/s
       Tx Pkts:            Total: 0           Time: 60s   Cur: 0         0/s
       Tx Pkts (On Wire):  Total: 0           Time: 60s   Cur: 0         0/s
       Tx Bytes:           Total: 0           Time: 60s   Cur: 0         0/s
       Tx Bytes (On Wire): Total: 0           Time: 3s    Cur: 0         0/s
       Tx Failed Pkts:     Total: 0           Time: 60s   Cur: 0         0/s
       Tx Failed Bytes:    Total: 0           Time: 60s   Cur: 0         0/s
       Conn Established:   Total: 0           Time: 30s   Cur: 0         0/s
       TCP Retransmits:    Total: 0           Time: 3s    Cur: 0         0/s
       Conn Timeouts:      Total: 0           Time: 30s   Cur: 0         0/s

Remove Cross Connect: delete_cx

Remember to delete a cross connect before you delete its endpoints.

 $ ./lf_firemod.pl --action delete_cx  --mgr cholla-f19 --cx_name cx_0

Controlling Traffic

You need to use do_cmd to control Unicast traffic.

By default, cross connects are created in the default_tm test manager. To control them, you want to specify default_tm in your set_cx_state CLI command.

 ./lf_firemod.pl --mgr 127.0.0.1 --quiet 0 --action do_cmd --cmd "set_cx_state default_tm cx_0 RUNNING"

The format of the command is specified in the CLI User Guide: set_cx_state. Possible CX states include:

  • RUNNING
  • SWITCH
  • QUIECE
  • STOPPED
  • DELETED

For Multicast traffic, use start_endp/stop_endp

 $ ./lf_firemod.pl --mgr cholla-f19 --action stop_endp --endp_name cx_0-A

Multicast Endpoints

There are different options for creating multicast endpoints.

 $ ./lf_firemod.pl --action create_endp --endp_name mcast_xmit_1 \
   --endp_type mc_udp      --speed 154000 \
   --mcast_addr 224.9.9.8  --mcast_port 9998 \
   --rcv_mcast NO          --port_name eth1 \
   --min_pkt_sz 1072       --max_pkt_sz 1472 \
   --use_csums NO          --ttl 32 

Add secondary IPs to a Port

This is not a default script option, so we use the do_cmd action:

 C:\> perl .\lf_firemod.pl --mgr 192.168.100.1
   --action do_cmd "set_sec_ip 1 1 eth1 10.26.0.20-250/24"

See the LANforge CLI User Guide for more info.

Present Options

This is the output of lf_firemod.pl --help:

./lf_firemod.pl  --action { create_endp | show_endp | set_endp | show_port | list_ports
                            | do_cmd | start_endp | stop_endp | delete_endp
                            | create_cx | list_cx | show_cx | delete_cx } ]
  [--endp_vals {key,key,key,key}]
      # show_endp output can be narrowed with key-value arguments
      # Examples:
      #  --action show_endp --endp_vals MinTxRate,DestMAC,Avg-Jitter
      # Not available: Latency,Pkt-Gaps, or rows below steps-failed.
      # Special Keys:
      #  --endp_vals tx_bps         (Tx Bytes)
      #  --endp_vals rx_bps         (Rx Bytes)
  [--mgr       {host-name | IP}]
  [--mgr_port  {ip port}]
  [--cmd       {lf-cli-command text}]
  [--endp_name {name}]
  [--port_name {name}]
  [--resource  {number}]
  [--speed     {speed in bps}]
  [--tos       { DONT-SET | LOWDELAY | THROUGHPUT | RELIABILITY | LOWCOST },{priority}]
  [--max_speed {speed in bps}]
  [--quiet     { yes | no }]
  [--endp_type { lf_udp | lf_udp6 | lf_tcp | lf_tcp6 | mc_udp | mc_udp6 }]
  [--mcast_addr {multicast address, for example: 224.4.5.6}]
  [--mcast_port {multicast port number}]
  [--min_pkt_sz {minimum payload size in bytes}]
  [--max_pkt_sz {maximum payload size in bytes}]
  [--rcv_mcast { yes (receiver) | no (transmitter) }]
  [--use_csums { yes | no, should we checksum the payload }]
  [--ttl       {time-to-live}]
  [--report_timer {miliseconds}]
  [--cx_name   {connection name}]
  [--cx_endps  {endp1},{endp2}]
  [--test_mgr  {default_tm|all|other-tm-name}]

Example:
 ./lf_firemod.pl --action set_endp --endp_name udp1-A --speed 154000

 ./lf_firemod.pl --action create_endp --endp_name mcast_xmit_1 --speed 154000 \
   --endp_type mc_udp   --mcast_addr 224.9.9.8 --mcast_port 9998 \
   --rcv_mcast NO       --port_name eth1 \
   --min_pkt_sz 1072    --max_pkt_sz 1472 \
   --use_csums NO       --ttl 32 \
   --quiet no --report_timer 1000

 ./lf_firemod.pl --action create_endp --endp_name bc1 --speed 256000 \
   --endp_type lf_tcp   --tos THROUGHPUT,100 --port_name rd0#1

 ./lf_firemod.pl --action list_cx --test_mgr all --cx_name all

 ./lf_firemod.pl --action create_cx --cx_name L301 \
   --cx_endps ep_rd0a,ep_rd1a --report_timer 1000

Creating Endpoint Hunt Scripts with CLI API

Goal: Use the the CLI to operate the Endpoint Scripting features of the Layer-3 Endpoints you create.

Layer-3 endpoints can manipulate their own transmission parameters using a variety of internal scripts, known as Endpoint Scripts. Using the lf_endp_script.pl CLI script, you can operate those internal endpoints behaviours.
This cookbook talks about Endpoint Scripts and CLI scripts at the same time. In this chapter, if the term script is used, assume Endpoint Script. Additionally, the terms operating and running can also be confusing. To keep the activities distinct, a LANforge user will operate a CLI script from a terminal. The LANforge server will run the Endpoint Script. A CLI script is a user-space perl script that issues CLI commands to a LANforge server. A CLI command is an instruction obeyed by the LANforge server.

The Forces at Play

There are a number of subsystems running while we operate an automated Endpoint Script, so let's review them:

  • There will be Layer-3 connect constructed using lf_firemod.pl. (Don't forget: create the endpoints before creating the cross connect.)
  • A managed endpoint of that connection will be configured with an Endpoint Script.
  • The attending engineer will operate a CLI script that changes state the Layer-3 connection to Running
  • The Layer-3 connection starts both endpoints transmitting, one of them starts running it's Endpoint Script that sets it's transmit parameters.
  • Remember: Endpoint Scripts run inside the LANforge server process. CLI scripts run from the client side.

Let's Walk Thru Putting One Together

We recommend starting your first script off by the LANforge GUI to save an endpoint with an Endpoint Script. Next, inspect the LANforge database on the server for the script parameters. Take those parameters and adapt them to the operator's CLI script.

  1. From the Layer-3 tab, open a connection tutorial-cx, and navigate to box 2. Click on the Script button.
  2. Name your script
  3. Select your Script type, here we choose ScriptHunt
  4. We immediately see the parameters for the script:
  5. Let's modify the parameters to match our CLI command example below:
  6. In a LANforge terminal, let's look at at /home/lanforge/DB/DFLT/endps.db We will search for bunny-script and we'll inspect the resulting CLI command.
  7. set_script tutorial-cx-A bunny-script 37120 ScriptHunt
       '5000 5000 100000,20000,100000,20,56000,30000,1,100000, 60,128,256,512,1024,1280,1460,1472,1514 1472 0,100,300,500,550,600,650,700,750,850,900,950 NONE' ALL 20
  8. Now we can craft this command into a CLI script. In a CMD window, we can write the formatted CLI script arguments:
  9. C:\> .\lf_endp_script.pl --mgr jedtest --resource 1 ^
     --action set_script --script_type Hunt --script_name bunny-script ^
     --endp_name tutorial-CX-A -loops 1 --flags 37120 ^
     --private "5000 5000 100000,20000,100000,20,56000,30000,1,100000, 60,128,256,512,1024,1280,1460,1472,1514 1472 0,100,300,500,550,600,650,700,750,850,900,950 NONE"
    In the CMD window, use double-quotes " for quoted script arguments. Using single-quotes will break your command.

    In a Linux terminal, we can use double " or single ' quotes:

    $ ./lf_endp_script.pl --mgr jedtest --resource 1 \
     --action set_script --script_type Hunt --script_name bunny-script \
     --endp_name tutorial-CX-A -loops 1 --flags 37120 \
     --private '5000 5000 100000,20000,100000,20,56000,30000,1,100000, 60,128,256,512,1024,1280,1460,1472,1514 1472 0,100,300,500,550,600,650,700,750,850,900,950 NONE'
  10. We can start the connection and the Endpoint Script will immediately begin running:
  11. lf_endp_script --mgr jedtest --resource 1 --action start_cx --cx_name tutorial-CX
  12. If the number of loops is fixed, it will eventually quiesce and stop itself. If we need to stop it and let in-flight packets come to rest, we can quiesce it:
  13. lf_endp_script --mgr jedtest --resource 1 --action quiesce_cx --cx_name tutorial-CX

    We could also use action stop_cx to immediately stop the connection.

  14. If you have a LANforge GUI running, the Endpoint Script report will automatically display in a GUI window as soon as the connection starts. To display it to the terminal, you need to enable debug output:
  15. lf_endp_script.pl --action show_report --endp_name tutorial-CX-A --quiet no

    Or to save it to a text file:

    lf_endp_script.pl --action show_report --endp_name tutorial-CX-A --quiet no > /home/lanforge/Documents/report.txt
  16. To remove the script:
  17. lf_endp_script.pl --action remove_script --endp_name tutorial-CX-A

At the CLI Command Level

Review of the set_script CLI command

We have covered creating endpoints in earlier cookbooks. The perl script lf_endp_script.pl was created to modify endpoints and operate their Endpoint Scripts. That script is using the set_script CLI command (documented here). A call to it looks like:

set_script tutorial-cx-A bunny-script 37120 ScriptHunt '...' ALL 20

Endpoint Scripting Uses Large Parameters

That vague '...' section is the private parameter which is a parameter list each script type requires. The private parameter combines a series of constraints (sub-parameters). For the ScriptHunt, we might use:

run_duration pause_duration constraints payload_sizes_a payload_sizes_b attenuations attenuator
 5000          |             |               |                  |              |          |
             5000            |               |                  |              |          |
100000,20000,100000,20,56000,30000,1,100000  |                  |              |          |
                  | 60,128,256,512,1024,1280,1460,1472,1514     |              |          |
                  |                                            1472            |          |
                  |                    0,100,300,500,550,600,650,700,750,850,900,950      |
                  v                                                                    1.1.14
      drops,jitter_us,latency_us,max_steps,start_rate,accuracy,is_bps,max_tx_slowdown

Accuracy is also Threshold, max_tx_slowdown is also Underrun. The result is a very long line that has to be surrounded the the CLI level by one pair of single quotes:

'5000 5000 100000,20000,100000,20,56000,30000,1,100000, 60,128,256,512,1024,1280,1460,1472,1514 1472 0,100,300,500,550,600,650,700,750,850,900,950 NONE'
Write these parameters very carefully! Your first mistake is likely going to involve misplaced apostrophes.

Associating stations with the lf_associate_ap script.

Goal: Create, destroy, start and stop virtual stations without needing to use the LANforge GUI.

Automated wireless traffic is possible using the lf_associate_ap.pl script. This script can be run within the LANforge server or outside the LANforge Server (on a windows desktop). The output of the script should be redirected to a text file if you want to review the resuts. Use this file in conjunction with the lf_firemod.pl script to create traffic. Requires a LANforge CT520 (or better) system and an access point.

Script Capabilities

The lf_assocatiate_ap.pl script has many options, but here are the basic actions:

  • Create stations and cross connects with them, running traffic for a specified amount of time (action: step1)
  • Generate stress on the AP by repeatedly bringing up stations and taking them down (action: step2).

Before you begin

  1. We assume you have a separate WiFi access point in routed mode. These examples can be used on a CT523 (or better) system with more than one radio if you want to practice the techniques. You would dedicate a radio to be a virtual AP (see cookbook).
  2. For these examples, our AP will be open with no username or password, and the SSID will be jedtest
  3. If you want to run scripts from your Windows desktop, you have ActivePerl installed.

Creating a virtual station with traffic

Using lf_associate_ap on Windows

  1. In the LANforge GUI, we will inspect our wiphy0 radio. And the radio should be set to channel -1 AUTO
  2. CMD window shortcut: R cmd
    LANforge Scripts are at C:\Program Files\LANforge-Server\scripts
  3. cd C:\Program Files\LANforge-Server\scripts
  4. perl .\lf_associate_ap.pl --help Will show you the script options.
  5. We can create a virtual station with this command:
  6. perl .\lf_associate_ap.pl --resource 1  --resource 1 --mgr jedtest ^
       --action step1       --radio wiphy0    --ssid jedtest ^
       --first_sta sta100   --num_stations 1  --duration 20 ^
       --first_ip DHCP      --upstream eth1 --security wpa2 --passphrase jedtest1
    Long DOS commands and be continued on the next line with the ^ character.
  7. We can see the port appear in the LANforge GUI: and we can inspect it.

Using lf_associate_ap on Linux

  1. Double click on your PuTTY icon and open a connection to your LANforge machine.
  2. The lf_associate_ap.pl script is in the scripts sub directory.
  3. Our command is basically the same.
  4. Long shell commands and be continued on the next line with the \ character.
    ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 1  --duration 20 \
       --first_ip DHCP      --upstream eth1   --security wpa2 --passphrase jedtest1
          
  5. We will see similar output:

More Traffic Examples

  1. Creating Multiple stations that transm
  2. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100 --num_stations 10 --duration 20 \
       --first_ip DHCP      --upstream eth1   --security wpa2 --passphrase jedtest1
  3. Creating TCP/IP bursty traffic from 30Mbps to 450 Mbps
  4. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1   --security wpa2 --passphrase jedtest1 \
       --cxtype tcp --bps-min 30Mpbs \
       --bps-max 450Mbps
  5. Capturing that report with redirection
  6. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1   --security wpa2 --passphrase jedtest1 \
       --cxtype tcp --bps-min 30Mpbs --bps-max 450Mbps &> report.txt
    Both DOS and Linux command output can be saved to a file with the &> operator.
    Both DOS and Linux files can be viewed with the more command.
  7. Creating steady UDP traffic to at 450Mbps
  8. $ ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1   --security wpa2 --passphrase jedtest1 \
       --cxtype udp --bps-min 450Mpbs \
       --bps-max SAME &> report.txt
    $  more report.txt
  9. Associating to an open AP
  10. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1   --security open
  11. Connecting a station at 802.11/abg speeds
  12. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1 --security open \
       --wifi_mode abg
  13. Initializing your test secenario by pre-loading a database. The database is the same name as the dropdown in the GUI Status tab.
  14. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1 --security open \
       --db_preload day_236
  15. Saving your test state after completing a traffic run
  16. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1 --security open \
       --db_preload day_236 --db_save station_results
  17. Cleaning out your scenario settings after completing a traffic run. We can do this by loading the EMPTY database with the db_postload switch.
  18. ./lf_associate_ap.pl --resource 1 --mgr localhost \
       --action step1       --radio wiphy0    --ssid jedtest \
       --first_sta sta100   --num_stations 10 --duration 120 \
       --first_ip DHCP      --upstream eth1 --security open \
       --db_preload day_236 --db_save station_results --db_postload EMPTY

Using lf_associate_ap to stress test an AP

We can have a series of stations associate and unassociate over and over. This can be quite a bit of exercise for an AP. Below is a command that tests five clients connecting.

./lf_associate_ap.pl --mgr jedtest --action step2 \
 --ssid jedtest --first_sta sta100 --first_ip DHCP \
 --num_stations 10 --security wpa2 --passphrase jedtest1
      
This will create set of ten stations bring them up and then take them down.

Script Options

These might have been update since publication, please check --help output for your version of the script.

./lf_associate_ap.pl   [--mgr {host-name | IP}]
      [--mgr_port {ip port}]     # use if on non-default management port
      [--resource {resource}]    # use if multiple lanforge systems; defaults to 1
      [--quiet { yes | no }]     # debug output; -q

      ##       AP selection
      [--radio {name}]           # e.g. wiphy2
      [--ssid {ssid}]            # e.g. jedtest
      [--security {open|wep|wpa|wpa2}] # station authentication type
      [--passphrase {...}]       # implies wpa2 if --security not set
      [--wifi_mode {a|abg|abgn|abgnAC|an|anAC|b|bg|bgn|g}]

      ##       station configuration
      [--num_stations {10}]
      [--first_sta {sta100}]
      [--first_ip {DHCP |ip address}]
      [--netmask {255.255.0.0}]

      ##       connection configuration
      [--cxtype {tcp/tcp6/udp/udp6}]   # use a tcp/udp connection, default tcp
      [--upstream {name|eth1}]
         # could be AP or could be port on LANforge
         # connected to WAN side of AP
      [--bps-min {10000000}]         # minimum tx bps
      [--bps-max {SAME|bps-value}]  # maximum tx bps, use SAME or omit for SAME
      [--duration {30}]      # connection duration, seconds, default 60
      [--poll-time {5}]    # nap time between connection displays
      [--action {step1,step2}]
         # step1: creates [num_stations] stations and L3 connections
         # step2: does bringup test

      [--traffic_type {separate|concurrent}]
         # for step1: separate does download then upload
         # concurrent does upload and download at same time

      [--db_preload {scenario name}]
         # load this database before creating stations
         # option intended as a cleanup step

      [--db_save {name}]
         # save the state of this test scenario after running the
         # connections, before --db_postload

      [--db_postload {scenario name}]
         # load this database after running connections,
         # option intended as a cleanup step

Changing Station WiFi SSID with the CLI API

Goal: Programmatically change a stations SSID

Programatically creating LANforge virtual stations requires using the add_sta command. If you already have a station and need to change the SSID, you still use the add_sta command.

The general sequence of commands is:

  1. if port is up, set port down with:
  2. cur_flags=0x1 interest_flags=0x800002
  3. issue add_port with changed SSID
  4. issue set_port to bring it up with:
  5. cur_flags=0x0 interest_flags=0x800002

We can create a station using this script command:

./lf_associate_ap.pl --action step2 --mgr jedtest \
   --resource 1 --radio wiphy0 \
   --ssid jedtest --first_sta sta100 \
   --num_stations 1 --first_ip=DHCP \
   --wifi_mode abgn --security wpa2 \
   --passphrase jedtest1 --quiet=0
   

The format of the add_sta command is listed in the CLI User's Guide. When we watch the debug output of the lf_associate_ap script, we see this add_sta command executed:

'add_sta' '1' '1' 'wiphy0' 'sta100' '1024' 'jedtest'
   'NA' 'jedtest1' 'AUTO' 'NA' '00:E3:F7:91:4A:1A' '5' 'NA'
   'NA' 'NA' 'NA' 'NA' '1024' 'NA' 'NA' 'NA' 'NA'
   

Looking at an example in the lf_associate_ap.pl script we see it being formatted here:

   my $sta1_cmd   = fmt_vsta_cmd($::resource, $::sta_wiphy, $sta_name,
                                 "$flags", "$::ssid", "$::passphrase",
                                 $mac_addr, "$flagsmask", $wifi_m);
   doCmd($sta1_cmd);
   

We format the parameters:

      return fmt_cmd("add_sta", 1, $resource, $sta_wiphy, $sta_name, "$flags",
                  "$ssid", "NA", "$key", $ap, $cfg_file, $mac,
                  $mode, $rate, $amsdu, $ampdu_factor, $ampdu_density,
                  $sta_br_id, "$flags_mask" );
   

Changing Station POST_IFUP field with the CLI API

Goal: Programmatically change a station's POST_IFUP field.

Creating a series of scripts using the lf_associate_ap.pl script is not adequate for negotiating a captive-portal environment, that script does not set the POST_IFUP parameter for the station. However, stations can be modified to gain that field.

Creating a station that negotiates a Captive Portal environment requires the POST_IFUP field to name a script. (Usually a portal-bot.pl script.) We can assign that port parameter with the set_wifi_extra2 command. At the time of this writing, there are no perl scripts using this CLI command, but I will show an example here:

set_port,
   1,       # resource number
   sta100,  # port name
   0,       # flush-to-kernel
   NA,      # ignore probe
   NA,      # ignore auth
   NA,      # ignore assoc
   NA,      # ignore_reassoc
   NA,      # corrupt_gtk_rekey_mic
   NA,      # radius_ip
   NA,      # radius_port
   NA,      # freq_24
   NA,      # freq_5

   # post_ifup_script
   './portal-bot.pl --bot bp.pm --user "username" --pass "secret" --start_url "http://www.google.com/"  --ap_url "http://localhost/" --login_form "login.php" --login_action "login.php" --logout_form  "logout.php"',
   NA       # ocsp
   

The above command would never actually be formatted in in the way it appears above. It would all appear on one line without commentds.

In a perl script, the command could be formatted like:

my $cmd = fmt_cmd("set_port", 1,
         "sta100",  # port name
         0,         # flush-to-kernel
         "NA",      # ignore probe
         "NA",      # ignore auth
         "NA",      # ignore assoc
         "NA",      # ignore_reassoc
         "NA",      # corrupt_gtk_rekey_mic
         "NA",      # radius_ip
         "NA",      # radius_port
         "NA",      # freq_24
         "NA",      # freq_5
   qq(./portal-bot.pl --bot bp.pm ) # post_ifup_script
   .qq(--user "username" --pass "secret" )
   .qq(--start_url "http://www.google.com/" )
   .qq(--ap_url "http://localhost/" )
   .qq(--login_form "login.php" )
   .qq(--login_action "login.php" )
   .qq(--logout_form "logout.php"),
         "NA"       # ocsp );
   

Important Notes

  1. the LANforge server treats single-quotes (apostrophes, ') as command delimiters. Use only double-quotes (") to quote the arguments to the script.
  2. Do not use newlines (\n or carriage-returns (\r\n). That will truncate the command and LANforge will process it immedately.
  3. These parameters will be provided by the server:
    • --mgt The management FIFO
    • --ip4 The IP address of the port
    • --ip6 The IPv6 address of the port
    • --dnsv A comma-separated list of DNS addresses
    • --logout Signals logout

Generating a series of attenuations using data in a CSV file.

Goal: Using the script and a specially formatted csv file, you will be able to re-play an arbitrary series of attenuations.

Playing back a series of WiFi attenuation levels using the attenuator_series.pl and a CSV file of attenuations make it possible to emulate the motion of a station (or stations) moving among a series APs. Or it could emulate interference in a crowd of moving people. Requires a LANforge CT703 (or better) and a LANforge CT520 (or better) system, and an access point.

Testing 1x1 with one attenuator

Our LANforge manager (resource 1.1) has an attenuator serial number 3 (resource 1.1.3) connected to the Device Under Test. The attenuator will be 1.1.1.3. There will be station sta100 on LANforge resource 1 and AP vap0 on LANforge resource 2. Cables connect the radios to the the attenator. The radios are configured in 1x1 mode. The corresponding channel on the attenuator is 1.1.3.0

[See LANforge Entity IDs for more on numbering.]

Let's script it with a simple data file: /home/lanforge/atten_test1.csv

channels,1.1.3.0
delay,5000
attenuate,250
attenuate,320
attenuate,450
attenuate,520
attenuate,820

We run the script in our terminal:

$ cd /home/lanforge/scripts
$ ./attenuate_series.pl -f ../atten_test1.csv

Watching a Layer-3 connection in the Dynamic Display, we will see a dip, rise and dip at 10 second intervals.

Testing 2x2 with One Attenuator

Next we cable up the second channel (1.1.3.1). We can update the csv test file, by adding a new column for the channel.

channels,1.1.3.0,1.1.3.1
delay,5000
attenuate,250,250
attenuate,320,250
attenuate,450,250
attenuate,520,520
attenuate,820,820

We can run the same command and watch the dynamic reports window to see a similar graph.

A 2x2 Example with Two Attenuators

The first radio on each LANforge is connected in 2x2 mode to both attenuators. This example is drawn to illustrate how you design the connection of your channels independently of their radios. Obviously, you don't need two attenuators for this scenario. However, if you had a CT523 with three radios and want to perform 2x2 testing with three client radios, it is possible to do so with only two CT703 attenuators.

We change the data file to specify the first channel on attenuator 14 (1.1.14.0): /home/lanforge/atten_test3.csv

channels,1.1.3.0,1.1.14.0
delay,5000
attenuate,250,250
attenuate,320,320
attenuate,450,450
attenuate,520,520
attenuate,820,820

We can run the script once in our terminal:

$ cd /home/lanforge/scripts
$ ./attenuate_series.pl -f ../atten_test3.csv

Watching the port signal in the dynamic display we will see a rise and dip at 10 second intervals.

Connecting up Multiple Radios

There is no different in attenuator control whether you have one radio in 3x3 or three radios in 1x1 to control. If you are testing multiple radios, you will be monitoring their RX Signal in the dynamic report.

File Format

Editing the test data file with a basic spreadsheet program than can save to CSV format is possible. You will want to save with comma format, without double-quoting the cells. These directives are converted to lower-case, so you can type them in UPPER-CASE or Mixed-Case if necessary.

The format of the CSV file allows you to specify many options that might also be specified on the command line.

Directives

# comments
Rows that begin with a comment sign (#, ;, !) will be entirely ignored. Cells in column B or beyond will be ignored.
channels
Each cell following this directive specifies an attenuator channel to control.
sleep, nap
The following cell specifies a one-time wait time in milliseconds
delay, naptime
The following cell specifies a standard wait time in milliseconds between each attenuate command
attenuate, _, ,
The following cells specify an attenuation value for channels specified by the last channels command.
minimum, min
Sets the minimum attenuation permitted. Values below this will be set to the minimum directed.
maximum, max
Sets the maximum attenuation permitted. Values above this will be set to the maximum directed.

Attenuation Values

  • Inherently Positive Values, like 200 are absolute attenuation values, in deci-decibels. 200 means 20.0dB. The smallest unit of resolution is 0.5dB, so all your values will end in zero or five. E.G. (0, 5, 105, 200, 955). Values range between zero and 955.
  • Explicitly Positive Values, that begin with @+, ++, + are increments with respect to the last value set on the channel.
    attenuate,250
    attenuate,@+50
    Results in the channel at 30.0dB. Spreadsheets often omit signed values when saving, so @+ will force a text type cell.
  • Explicitly Negative Values, that begin with @-, --, - are decrements with respect to the last value set on the channel.
    attenuate,300
    attenuate,@-50
    Results in the channel at 25.0dB. Spreadsheets often omit signed values when saving, so @- will force a text type cell.
  • Basic Cell Math can be performed, but only against absolute cell values.
    attenuate,500,400
    attenuate,=B1+50,=C1-50,   # results in 550, 350
    attenuate,=B2+5,=C2-5,     # fails: B2 and C2 were formulas.
    This feature is unlikely to be as useful as it sounds, because pasting a column of forumae will be pretty useless, since a spreadsheet processes them recursively. Also, most spreadsheets saved to CSV typically don't save formulae by default, you probably will get the computed values in your CSV file.
  • Shortcuts include _, NA, and ,,. You can skip a computation on a cell by leaving a blank cell, underscore, or 'NA'. Careful: the value +0 will likely be truncated to 0, and set the channel to 0.0dB attenuation.

Script Options

The attenuate_series.pl script uses these arguments. They support long and short argument switch names:

   -m
   --mgr             LANforge manager host, like localhost or 192.168.101.1
   
   -f
   --file            CSV file with attenuation data
   
   -d
   --delay           Override of DELAY variable, milliseconds between applying rows
   
   -l
   --loop            Repeat indefinitely
   
   -c
   --channel         Override of channels variable, eg: 1.2.3.1,2.3.4.3
   
   -i
   --min
   --minimum         Set minimum attenuation value (not lower than zero)
   
   -x
   --max
   --maximum         Set maximum attenuation value (not higher than 955)
   
   -n
   --dry
   --dryrun
   --dry_run         Do not apply attenuation, just parse file, ignore nap times

Example CSV File

This CSV shows a working example that gives warnings.

  1. # example csv
  2. channels, 1.1.14.0, 1.1.14.1, 1.1.14.2, 1.1.3.0, 1.1.3.1, 1.1.3.2,
  3. DELAY,2000,,,,,,
  4. ATTENUATE,950,850,750,950,850,750,
  5. attenuate,940,-10,-10,-10,-10,-10,
  6. attenuate,930,-10,NA,-10,-10,,
  7. attenuate,=B4-10,=C4+10,NA,-15,-15,,
  8. attenuate,-15,_,-15,,NA,-15,
  9. sleep,1000,,,,,,
  10. attenuate,110,115,215,315,415,515,
  11. _,=B10-20,=C10+20,=D10+20,=E10+20,=F10+20,=G10-20,
  12. _,@+10,@+10,@-10,10,10,10,
  13. # eof

Attenuators Tab

Here's the Attenuators tab used for the examples:

Opening and Saving CSV

Here are options used for the open dialog in LibreOffice Calc:

Here are the options used for the save dialog in LibreOffice Calc:

LANforge Entity IDs

Goal: Gain a better understanding of LANforge Entitiy IDs (EIDs)

Every port, radio, virtual port, endpoint and connection in LANforge has an ID known as an EID. These are an internal notation that expresses the heirarchy of the physical and virtual objects managed by LANforge realm.

Ports, Endpoints and Connections are Entities

Entity IDs (EIDs) are a dotted-decimal phrase. It expresses the Shelf, Resource Number, Port or Connection number, and if it is an endpoint, it gains an fourth decimal. An Example:

1.2.8.4  : EID
1        : shelf
  2      : resource
    8    : port
      4  : endpoint

You can assume the shelf number will always be 1 for now. The Resource number will refer to the LANforge machine ID as reported on the Status tab. The port id is only unique within a LANforge machine. The port ID also refers to hardware in a machine: radios get a third decimal. The fourth decimal refers to either endpoints or connections.

Only Some LANforge Entities Generate Connection Data

While some items with port numbers, notably radios and ports, do not generate traffic. Endpoints generate traffic, and typically endpoints are transmitting to an opposite endpoint. The exception to this are multicast endpoints.

EIDs Express Heirarchy

From the dotted-decimal perspective:

  • Physical or virtual ports reside below a resource, except:
  • ...for VLANs: A virtual port does not reside below it's physical port
  • ...for bridge ports:: A port of a bridge has to exist before the bridge is created
  • An endpoint resides below a physical or virtual port.

The formatting of the decimals might or might not be zero-padded. The picture below should convey how a connection (Layer 3) relates to two endpoints, and two ports:

The exception is connections. Connections are numbered outside of this heirarchy.

Do I use EIDs in Scripts?

Usually not, for these reasons:

  1. EIDs are generated at LANforge manager start time, and might depend on the detection order of ports when the PCI bus on the host is enumerated at boot time.
  2. New EIDs can be created by appending one database to another on non-conflicting devices
  3. New devices can be hot-added to a LANforge resource, like a programmable attenuator or a USB-Ethernet adapter, generating new Port IDs.

In scripts, it is legal to reference port numbers, but not advised to store them between sessions. If you reference an EID, it should be from within your present LANforge session. If your resources tend to disappear off the network and return (you had a machine reboot) those EIDs are not guaranteed to return.

For ports, only the first two decimals (shelf and resource id) are actually stable across machine reboots.

If you look into the saved scenarios (in /home/lanforge/DB/DFLT) you will notice that ports, endpoints, and connections are refered to by name. Event though in the CLI Users's guide, where it states port number, use names in your scripts:

CMD
|        SHELF
|        |  RESOURCE
|        |  |  PORT
|        |  |  |
set_port 1  1  eth1 10.26.1.2 255.255.255.0 10.26.1.1 ....

Querying the LANforge GUI for JSON Data

Goal: Learn how to configure and query the LANforge GUI for JSON formatted data.

The LANforge GUI (as of release 5.3.6) can be configured to start a lightweight web service listener that can provide data about ports and layer-3 connections. This service can be queried with with any browser or AJAX connection. This feature promises to provide a number of benefits:

  • More rapid polling: using CLI scripts to poll ports on the LANforge manager can add stress and contention to the LANforge manager; polling the GUI will not tax your test scenario.
  • Expanded array of data: the views found in the GUI, like Port Mgr, and Layer-3 tabs, can be represented in JSON format.
  • GUI client synthesized data: many columns in the GUI tabs are synthesized during traffic generation and are not available through the CLI scripting API.
  • Reduced effort when integrating with third party test libraries: many other testing libraries expect JSON formatted input.

Present and potential drawbacks of the GUI JSON data feature:

  • Introductory state: the JSON views/schema of the objects is at a demonstation state. It is likely to change with the next release of LANforge, for example, the JSON objects in 5.3.7 probaby won't match 5.3.6.
  • JSON Features are compiled into the LANforge GUI from Java sources. Adding or extending JSON features is not as simple as adding another Groovy script. We're concerned that Groovy plugins will not perform as well. If you are interested in Groovy plugins that provide JSON data, please discuss your needs with us.
  • Initially limited data views: in 5.3.6, we are providing this as a proof of concept and have chosen to display only data from the Port Manager, Layer-3 Connections, and Layer-3 Endpoints tabs. As requirements develop, we'll develop more data views.

GUI Settings

The LANforge GUI is started using a script (lfclient.bash or lfclient.bat). From a terminal, we call that script with the -httpd switch. By default the GUI will listen on port 8080:

 $ cd /home/lanforge
 $  ./lfclient.bash -httpd

You can specify the port to listen on:

 $ cd /home/lanforge
 $  ./lfclient.bash -httpd 3210

There is not a graphical gui preference to set for the feature at this time.

Example Query

Status

From the terminal we can query the port to find a basic message from the GUI:

 $ curl -sqv http://localhost:8080/
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Tue, 2 May 2017 21:22:57 GMT
< Connection: keep-alive
< Content-Length: 461
<
* Connection #0 to host localhost left intact
"text":"These urls are presently available",
"mappings":{"":"(This page) Provides status and configuration.","/Port/Index":"List of ports in the PortManager tab.","/PortTab":"List of ports in the PortManager tab.","/Layer3/Calc":"Show Layer3 Endpoint calculations","/Port/Calc":"Show port calculations.","/Layer3/Index":"List of ports in the Layer3 tab","/":"(This page) Provides status and configuration."}[{"handler":"candela.lanforge.HttpStatus"},{"uri":""}]

Parsing Results

JSON formatted text is pretty difficult to read, so you might like to know two different utilities that can help you look at it: jq and jsonlint.

Installing and using jq

On Fedora, install jq:

 $ sudo dnf install -y jq

On Ubuntu, install jq:

 $ sudo apt install -y jq

Now we can perform a query:

 $ curl -sq http://localhost:8080/ | jq
[
  {
    "handler": "candela.lanforge.HttpStatus"
  },
  {
    "uri": ""
  },
  {
    "text": "These urls are presently available"
  },
  {
    "mappings": {
      "": "(This page) Provides status and configuration.",
      "/Port/Index": "List of ports in the PortManager tab.",
      "/PortTab": "List of ports in the PortManager tab.",
      "/Layer3/Calc": "Show Layer3 Endpoint calculations",
      "/Port/Calc": "Show port calculations.",
      "/Layer3/Index": "List of ports in the Layer3 tab",
      "/": "(This page) Provides status and configuration."
    }
  }
]

Validating with jsonlint

On Fedora, install php-jsonlint:

 $ sudo dnf install -y php-jsonlint

On Ubuntu, install jsonlint:

 $ sudo apt install -y jsonlint

Running jsonlint-php is not nearly as exciting:

 $ curl -sq http://localhost:8080/ | jsonlint-php
Valid JSON

Data Views

Ports

/Port/Index
Provides a digest of ports and their state:
 $ curl -sq http://localhost:8080/Port/Index
[{"handler":"candela.lanforge.HttpPortIndex"},{"uri":"Port/Index"},
{"header":["eid","name","phantom","down"]},
{"data":[
          ["1.0.0","eth0","false","false"],
          ["1.1.0","eth0","false","false"],
          ["1.2.0","eth0","false","false"],
          ["1.1.1","eth1","false","false"],
          ["1.2.1","eth1","false","false"],
          ["1.1.2","wiphy0","false","false"],
          ["1.2.2","wiphy0","false","false"],
          ["1.1.3","wiphy1","false","false"],
          ["1.2.3","wiphy1","false","false"],
          ["1.1.4","wiphy2","false","false"],
          ["1.2.4","wiphy2","false","false"],
          ["1.1.5","wlan0","false","true"],
          ["1.2.5","wlan0","false","false"],
          ["1.1.6","wlan1","false","true"],
          ["1.2.6","wlan1","false","false"],
          ["1.1.7","wlan2","false","true"],
          ["1.2.7","wlan2","false","false"],
          ["1.1.8","vap100","false","false"],
          ["1.1.9","vap110","false","false"],
          ["1.1.10","vap120","false","false"],
          ["1.1.11","b100","false","false"],
          ["1.1.12","r100a","false","false"],
          ["1.1.13","r100b","false","false"],
          ["1.1.14","r101a","false","false"],
          ["1.1.15","r101b","false","false"]
]}]
/PortTab

PortTab provides data found in Port Mgr tab. The configuration of the Port Mgr tab (Add-Remove Table Columns) will show in this response.

 $ curl -sq "http://localhost:8080/PortTab"
[{"handler":"candela.lanforge.HttpPortTab"},
{"uri":"PortTab"},
{"header":["Port","Phantom","Down","Parent Dev","Device","IP","RX Bytes","AP","Connections","SSID","Gateway IP","MAC","bps RX","bps TX"]},
{"data":[["1.1.00","false","false","","eth0","192.168.100.26","4,097,857,554","","0","","192.168.100.1","00:90:0b:29:06:f8","109,695","340,974"],
  ["1.1.01","false","false","","eth1","10.26.1.1","1,651,636,119,416","","0","","0.0.0.0","00:90:0b:29:06:f9","0","0"],
  ["1.1.02","false","false","","wiphy0","0.0.0.0","3,217,297,499","","0","","0.0.0.0","00:0e:8e:4e:5a:56","2,794","106"],
  ["1.1.03","false","false","","wiphy1","0.0.0.0","4,462,247,651","","0","","0.0.0.0","00:0e:8e:4e:57:91","20,632","230"],
  ["1.1.04","false","false","","wiphy2","0.0.0.0","4,294,994,299","","0","","0.0.0.0","00:0e:8e:3e:27:5b","21,066","268"],
  ["1.1.05","false","true","wiphy0","wlan0","0.0.0.0","0","Not-Associated","0","","0.0.0.0","00:0e:8e:4e:5a:56","0","0"],
  ["1.1.06","false","true","wiphy1","wlan1","0.0.0.0","0","Not-Associated","0","","0.0.0.0","00:0e:8e:4e:57:91","0","0"],
  ["1.1.11","false","false","","b100","10.26.4.1","9,128,638,764","","0","","0.0.0.0","00:0e:8e:c9:6f:5b","0","0"],
  ["1.1.12","false","false","r100b","r100a","0.0.0.0","850,541,375,484","","0","","0.0.0.0","a6:95:6a:90:14:1e","0","131"],
  ["1.1.13","false","false","r100a","r100b","10.26.4.13","845,854,312,922","","0","","10.26.4.1","6a:c4:3f:13:13:dc","125","0"],
  ["1.1.14","false","false","r101b","r101a","0.0.0.0","845,854,004,368","","0","","0.0.0.0","62:e7:56:85:97:1b","0","190"],
  ["1.1.15","false","false","r101a","r101b","10.26.4.14","850,541,680,988","","0","","10.26.4.1","e2:31:8e:2e:b9:86","194","0"],
  ["1.2.0","false","false","","eth0","192.168.100.42","1,285,507,529","","0","","192.168.100.1","00:90:0b:40:64:c6","5,331","85,739"],
  ["1.2.1","false","false","","eth1","10.26.1.2","11,741,736,214","","0","","10.26.1.1","00:90:0b:40:64:c7","0","0"],
  ["1.2.2","false","false","","wiphy0","0.0.0.0","656,227,422,653","","0","","0.0.0.0","00:0e:8e:43:36:e9","6,276","6"],
  ["1.2.3","false","false","","wiphy1","0.0.0.0","591,417,884,328","","0","","0.0.0.0","00:0e:8e:43:3a:62","7,391","6"],
  ["1.2.4","false","false","","wiphy2","0.0.0.0","564,127,688,199","","0","","0.0.0.0","00:0e:8e:43:37:63","7,002","6"],
  ["1.1.07","false","true","wiphy2","wlan2","0.0.0.0","0","Not-Associated","0","","0.0.0.0","00:0e:8e:3e:27:5b","0","0"],
  ["1.1.08","false","false","wiphy0","vap100","0.0.0.0","3,071,654,503","","0","jedtest-40","0.0.0.0","00:0e:8e:ef:49:56","0","0"],
  ["1.1.09","false","false","wiphy1","vap110","0.0.0.0","3,071,656,850","","0","jedtest-36","0.0.0.0","00:0e:8e:d1:b1:91","0","0"],
  ["1.1.10","false","false","wiphy2","vap120","0.0.0.0","3,071,657,075","","0","jedtest-44","0.0.0.0","00:0e:8e:c9:6f:5b","0","0"],
  ["1.2.5","false","false","wiphy0","wlan0","10.26.4.12","548,247,399,423","00:0E:8E:EF:49:56","9","jedtest-40","10.26.4.1","00:0e:8e:43:36:e9","0","0"],
  ["1.2.6","false","false","wiphy1","wlan1","10.26.4.11","548,246,490,732","00:0E:8E:D1:B1:91","12","jedtest-36","10.26.4.1","00:0e:8e:43:3a:62","0","0"],
  ["1.2.7","false","false","wiphy2","wlan2","10.26.4.10","548,245,803,601","00:0E:8E:C9:6F:5B","9","jedtest-44","10.26.4.1","00:0e:8e:43:37:63","0","0"]
]}]
/Port/Calc

The path provides port calculations similar to the Port Calculations window. It requires one or more EID parameters. You can specify the eids as a comma separated list: ?eid=1.2.3,1.2.4 or a series of query parameters: ?eid=1.2.3&eid=1.2.4

curl -sq "http://localhost:8080/Port/Calc?eid=1.1.15"
[{"handler":"candela.lanforge.HttpPortTabSsData"},
{"uri":"Port/Calc"},
{"1.1.15":
  {"TimeStamp":"1493767726537",
  "Name":"r101b",
  "EID":"1.1.15",
  "Resource":"jedtest",
  "tx_pkts":"48631077",
  "rx_pkts":"48697662",
  "tx_bytes":"845854005290",
  "rx_bytes":"850541798136",
  "tx_errors":"0",
  "rx_errors":"0",
  "tx_dropped":"0",
  "rx_dropped_pkts":"0",
  "rx_multicast":"0",
  "rx_collisions":"0",
  "rx_length":"0",
  "rx_overrun":"0",
  "rx_crc":"0",
  "rx_frame":"0",
  "rx_fifo":"0",
  "rx_missed":"0",
  "tx_aborted":"0",
  "tx_carrier":"0",
  "tx_fifo":"0",
  "tx_heartbeat":"0",
  "tx_window":"0",
  "rx_signal":"0",
  "link_speed":"10000000000",
  "rx_link_speed":"10000000000",
  "frequency":"0",
  "portal_login_ok":"0",
  "portal_login_fail":"0",
  "portal_logout_ok":"0",
  "portal_logout_fail":"0",
  "dhcp_neg_ms":"1699",
  "conn_count":"0",
  "last_conn_ms":"0",
  "connect_duration_us":"0",
  "disconn_duration_us":"0",
  "anqp_duration_us":"0",
  "4way_duration_us":"01493767729321"}
}]
        

Connections

Layer-3 information is organized in a similar way.

/Layer3/Index
This path provides a digest of layer 3 connections and their status.
 $ curl -sq 'http://localhost:8080/Layer3/Index'
[{"handler":"candela.lanforge.HttpLayer3Index"},
{"uri":"Layer3/Index"},
{"header":["Eid","Name","State","EidA","EidB"]},
{"data":[
  ["2.1","u-e1-w0","Stopped","1.2.5.2","1.2.1.1"],
  ["3.1","u-e1-w1","Stopped","1.2.6.4","1.2.1.3"],
  ["4.1","u-e1-w2","Stopped","1.2.7.6","1.2.1.5"],
  ["7.1","test-rr-10G","Stopped","1.1.15.12","1.1.13.11"]
]}]
/Layer3/Calc

This path provides data similar to the Layer-3 Calculations window. Notice that the pattern of the EID for connections is ordered as [CX_INDEX].[TYPE], unlike ports that are identified like [SHELF].[RESOURCE].[PORT_INDEX] This [TYPE] identifier should correspond to the end of the EID for endpoints, which are [SHELF].[RESOURCE].[PORT_INDEX].[ENDPOINT_INDEX].[TYPE]. The following example queries endpoint data for two connections, 2.1 and 4.1:

$ curl -sq "http://localhost:8080/Layer3/Calc?eid=2.1,4.1"
[{"handler":"candela.lanforge.HttpLayer3TabSsData"},
{"uri":"Layer3/Calc"},
{"header":[
  "TimeStamp","Name","EID","CX-Name","IS_RUNNING","tx_rate","bps_tx_rate_3s","rx_rate","bps_rx_rate_3s","rx_drop%x1000","tx_pkts","rx_pkts","tx_bytes","rx_bytes","rx_dropped_pkts","rx_dup_pkts","rx_ooo_pkts","rx_wrong_dev","rx_crc_failed","rx_bit_errors","TCP-RTX","conn_timeouts","conn_established","conn_active","tcp_CWND","min_conn_duration_ms","max_conn_duration_ms","min_reconn_pause_ms","max_reconn_pause_ms","pattern","min_pkt_size","max_pkt_size","min_tx_rate","max_tx_rate","running_for","last_report","destination_addr","source_addr","min_latency","avg_latency","max_latency","box_width","lat_0","lat_1","lat_2","lat_3","lat_4","lat_5","lat_6","lat_7","lat_8","lat_9","lat_10","lat_11","lat_12","lat_13","lat_14","lat_15","min_rt_latency","avg_rt_latency","max_rt_latency","rt_box_width","rt_lat_0","rt_lat_1","rt_lat_2","rt_lat_3","rt_lat_4","rt_lat_5","rt_lat_6","rt_lat_7","rt_lat_8","rt_lat_9","rt_lat_10","rt_lat_11","rt_lat_12","rt_lat_13","rt_lat_14","rt_lat_15","min_drop_amt","avg_drop_amt","max_drop_amt","drop_box_width","drop_amt_0","drop_amt_1","drop_amt_2","drop_amt_3","drop_amt_4","drop_amt_5","drop_amt_6","drop_amt_7","drop_amt_8","drop_amt_9","drop_amt_10","drop_amt_11","drop_amt_12","drop_amt_13","drop_amt_14","drop_amt_15","RptTimer","files_replayed","Avg-Jitter","rx_pkts_ll","tx_pkts_ll","rx_bytes_ll","tx_bytes_ll","cx_dropped_pkts","Rx-First-Pkt-ms","min_gap","avg_gap","max_gap","gap_box_width","gap_0","gap_1","gap_2","gap_3","gap_4","gap_5","gap_6","gap_7","gap_8","gap_9","gap_10","gap_11","gap_12","gap_13","gap_14","gap_15"
]},
{
  "2.1":{
    "tx_data":[
      "1493770429164","u-e1-w0-A","1.2.1.1.1","u-e1-w0","false","9990794","10010814","52973","53077","0","1886","10","2776192","14720","0","0","0","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","10000000","10000000","2","0","10.26.4.12:33008","10.26.1.2:33007","0","0.9","1","1","10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","1.9","2","1","10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0.0","0","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1000","0","0","10","1886","15140","2855404","0","211","206","2150346.9","21501576","1","4","0","3","3","0","0","0","0","0","0","0","0","0","0","0","0"
    ],
    "rx_data":[
      "1493770429164","u-e1-w0-B","1.2.5.2.1","u-e1-w0","false","52973","53077","9985497","10005506","53","10","1885","14720","2774720","0","0","0","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","56000","56000","2","0","10.26.1.2:33007","10.26.4.12:33008","0","1.148","4","1","1583","293","9","0","0","0","0","0","0","0","0","0","0","0","0","0","0","2.148","5","1","794","773","139","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0.0","0","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1000","0","0","1885","10","2853890","15140","1","2","0","1.181","21501351","1","1389","388","106","1","1","0","0","0","0","0","0","0","0","0","0","0"
    ]
  },
  {
    "4.1":{
      "tx_data":[
        "1493748925591","u-e1-w2-A","1.2.1.5.1","u-e1-w2","false","9999315","10008210","55994","59453","10","362118446","2027796","533038352512","2984915712","231","0","3","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","10000000","10000000","426459","0","10.26.4.10:33006","10.26.1.2:33005","0","0.642","6","1","2017386","5956","2618","1251","313","118","70","52","23","4","1","2","2","0","0","0","0","1.647","7","1","780042","1224907","18988","2557","902","183","92","75","38","7","1","2","2","0","0","0","0","2.783","0","1","46","12","16","8","1","0","0","0","0","0","0","0","0","0","0","0","1000","0","0","2027796","362118446","3070083144","548247327244","206","212","205","210.29","216","1","247795","320437","447206","439229","405276","72556","32087","36076","27046","43","29","16","0","0","0","0"
      ],
      "rx_data":[
        "1493748925591","u-e1-w2-B","1.2.7.6.1","u-e1-w2","false","55999","59453","9999263","10012176","0","2028002","362116541","2985218944","533035548352","70202","0","812","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","56000","56000","426459","0","10.26.1.2:33005","10.26.4.10:33006","0","1.085","16","1","339286622","21098161","1179805","356224","91200","39017","28599","19845","12984","3469","611","4","0","0","0","0","0","1.938","16","1","134861468","211216818","14792147","870910","218717","67800","39273","28252","15267","4075","819","816","0","0","0","0","0","66.701","0","1","41","10","22","41","88","145","223","167","93","26","19","0","0","0","0","0","1000","0","0","362116541","2028002","548244443074","3070395028","1905","2","0","1.171","16","1","274233813","75937349","11696502","219321","25431","2541","1040","327","173","42","1","0","0","0","0","0"
      ]
    }}]

Learn CLI commands used to operate WiFi stations.

Goal: Compare and learn script and CLI commands used when creating and operating stations.

The LANforge perl scripts have always been able to print out the CLI commands used to communicate with the LANforger manager. These examples show recent modifications that allow you to collect the CLI commands more easily using the --log_cli switch. (Not all scripts have this feature yet). The --log_cli switch prints CLI commands to your console. You can collect those commands in a file using the switch with an argument of the file name:
 $ ./lf_vue_mod.sh --log_cli /tmp/clilog.txt 

It is possible to repeat these commands using the lf_firemod.pl script:

 $ ./lf_firemod.pl --mgr localhost --action do_cmd \
--cmd "set_port 1 2 sta200 NA NA NA NA 0 NA NA NA NA 8388610"

Requires a LANforge CT520 (or better) system and an access point.

Examples of CLI commands

  1. Creating Stations
  2. Using Open Authentication
  3. Using WPA2 Authentication
  4. Static IP Addresses
  5. Station DHCP IP Address
  6. Creating a Station with a MAC Address Pattern
  7. Admin Down
  8. Admin Up
  9. Deleting a Station
  10. Creating Connections and Running Traffic
  11. Starting and Stopping Traffic
  12. Create a Layer 3 TCP Connection
  13. Create a Layer 3 UDP Connection
  14. Create a Layer 4 Web Connection

Setting for Examples

This was done in a two-machine LANforge cluster, the manager named jedtest and the second resource named kedtest. The CLI output of these CLI commands has been discarded as well as any show_port commands.

The show_port commands are useful for inspecting the results of previous commands. Often there is useful wait before issuing the show_port command to allow processing time on the manager. Please inspect the scripts in the /home/lanforge/scripts directory for how and when they tend to sleep.

These commands are also found in the /home/lanforge/DB/DFLT directory files. You cannot run those DB files directly, because they are executed in certain order. However, you can grep for connection- and station-names in those files to find results of GUI commands.

Creating Stations

Using Open Authentication

This station is created with DHCP enabled. That is controlled via flags that are descibed in the add_sta command.

Shell script:
./lf_vue_mod.sh --mgr jedtest --resource 2 --create_sta --name sta100 --radio wiphy0 --security open --ssid jedtest
Perl script:
./lf_associate_ap.pl --mgr jedtest --resource 2 --quiet yes --action add --radio wiphy0 --security open --ssid jedtest --passphrase --first_sta sta100 --first_ip DHCP --num_stations 1
CLI command:
set_wifi_radio 1 2 wiphy0 NA -1 NA NA NA NA NA NA NA NA 0x1 NA
add_sta 1 2 wiphy0 sta100 0 jedtest NA [BLANK] AUTO NA 00:0e:8e:8d:8d:e9 8 NA NA NA NA NA 0
set_port 1 2 sta100 0.0.0.0 255.255.0.0 0.0.0.0 NA 2147483648 00:0e:8e:8d:8d:e9 NA NA NA 8405038 1000 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NONE

Using WPA2 Authentication

This station is created with DHCP enabled. That is controlled via flags that are descibed in the add_sta command.

Shell script:
 $ ./lf_vue_mod.sh --mgr jedtest --resource 2 --create_sta --name sta200 \
  --radio wiphy1 --security wpa2 --ssid jedtest --passphrase jedtest1 \
  --log_cli /tmp/clilog.txt
Perl script:
./lf_associate_ap.pl --mgr jedtest --resource 2 \
  --action add --radio wiphy1 --security wpa2 --ssid jedtest \
  --passphrase jedtest1 --first_sta sta200 --first_ip DHCP --num_stations 1
CLI command:
set_wifi_radio 1 2 wiphy1 NA -1 NA NA NA NA NA NA NA NA 0x1 NA
add_sta 1 2 wiphy1 sta200 1024 jedtest NA jedtest1 AUTO NA 00:0e:8e:6f:01:62 8 NA NA NA NA NA 1024
set_port 1 2 sta200 0.0.0.0 255.255.0.0 0.0.0.0 NA 2147483648 00:0e:8e:6f:01:62 NA NA NA 8405038 1000 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NONE

Static IP Addresses

Here is an example of creating a virtual station with a static address: 10.26.2.14/255.255.254.0

Shell Script:
--
Perl Script:
./lf_associate_ap.pl --mgr jedtest --resource 2 --action add --radio wiphy1 --first_sta sta203 --first_ip 10.26.2.4 --netmask 255.255.254.0 --ssid jedtest --security wpa2 --passphrase jedtest1 --num_stations 1 --wifi_mode abgnAC --log_cli /tmp/clilog.txt
CLI Command:
set_wifi_radio 1 2 wiphy1 NA -1 NA NA NA NA NA NA NA NA 0x1 NA
show_port 1 2 wiphy1
add_sta 1 2 wiphy1 sta203 1024 jedtest NA jedtest1 AUTO NA 00:0e:8e:63:50:62 8 NA NA NA NA NA 1024
set_port 1 2 sta100 10.26.2.4 255.255.254.0 0.0.0.0 NA 0 00:0e:8e:63:50:62 NA NA NA 8388654 1000 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NONE

Station DHCP IP Address

For the station to gain a DHCP IP address, you have to admin-up the station.

Creating a Station with a MAC Address Pattern

The lf_associate_ap script contains logic that parses a MAC address pattern and produces new MAC addresses. This is not a feature of the LANforge Manager. Your CLI calls to the LANforge manager will not parse the mask.

The pattern nomenclature of the LANforge GUI can also be used when specifying a MAC address for stations:

xx
keep parent radio octet
*
randomize this octet
00 - ff
assign this value to the octet
Shell script:
--
Perl script:
./lf_associate_ap.pl --mgr jedtest --resource 2 --action add --radio wiphy1 --first_sta sta205 --first_ip 10.26.2.4 --netmask 255.255.254.0 --ssid jedtest --security wpa2 --passphrase jedtest1 --num_stations 1 --mac-pattern '4e:xx:xx:xx:*:01' --log_cli /tmp/clilog.txt
CLI command:
set_wifi_radio 1 2 wiphy1 NA -1 NA NA NA NA NA NA NA NA 0x1 NA
show_port 1 2 wiphy1
add_sta 1 2 wiphy1 sta205 1024 jedtest NA jedtest1 AUTO NA 4e:0e:8e:43:f1:01 8 NA NA NA NA NA 1024
set_port 1 2 sta205 10.26.2.4 255.255.254.0 0.0.0.0 NA 0 4e:0e:8e:43:f1:01 NA NA NA 8388654 1000 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NONE

Admin Down

Shell script:
./lf_vue_mod.sh --mgr jedtest --resource 2 --down --name sta200 --log_cli /tmp/clilog.txt --quiet 1
Perl script:
./lf_portmod.pl --manager jedtest --card 2 --port_name sta200 --set_ifstate down
CLI command:
set_port 1 2 sta200 NA NA NA NA 1 NA NA NA NA 8388610

Admin Up

Shell script:
./lf_vue_mod.sh --mgr jedtest --resource 2 --up --name sta200 --log_cli /tmp/clilog.txt --quiet 1
Perl script:
./lf_portmod.pl --manager jedtest --card 2 --port_name sta200 --set_ifstate up
CLI command:
set_port 1 2 sta200 NA NA NA NA 0 NA NA NA NA 8388610

Delete Station

Shell script:
./lf_vue_mod.sh --mgr jedtest --resource 2 --delete_sta --name sta200 --log_cli /tmp/clilog.txt --quiet 1
Perl script:
./lf_associate_ap.pl --mgr jedtest --resource 2 --action del --port_del sta200
CLI command:
rm_vlan 1 2 sta100

Creating Connections and Running Traffic

LANforge can create Layer-3 and Layer-4 connections using the lf_vue_mod.sh script. When connections are created, they exist in a stopped state. Connections can then have their state changed to RUNNING to start traffic.

Starting and Stopping Traffic

Layer-3 and Layer-4 connections both subject to the states STOPPED, RUNNING, and QUIECSE.

Shell script:
./lf_vue_mod.sh --mgr jedtest --start_cx --name tcp200 --log_cli /tmp/clilog.txt --quiet 1
./lf_vue_mod.sh --mgr jedtest --stop_cx --name tcp200 --log_cli /tmp/clilog.txt --quiet 1
Perl script:
./lf_firemod.pl --mgr jedtest --action do_cmd --cmd "set_cx_state default_tm tcp200 RUNNING"
./lf_firemod.pl --mgr jedtest --action do_cmd --cmd "set_cx_state default_tm tcp200 STOPPED"
CLI commands:
set_cx_state default_tm tcp200 RUNNING
set_cx_state default_tm tcp200 STOPPED

Create a Layer 3 TCP Connection

Shell script:
./lf_vue_mod.sh --mgr jedtest --resource 2 --create_cx --name tcp200 --tcp --sta sta200 --port eth1 --bps 1000000 --log_cli /tmp/clilog.txt --quiet 1
Perl script:
./lf_firemod.pl --mgr jedtest --resource 2 --action create_endp --endp_name tcp200-A --speed 1000000 --endp_type lf_tcp --port_name sta200
./lf_firemod.pl --mgr jedtest --resource 2 --action create_endp --endp_name tcp200-B --speed 1000000 --endp_type lf_tcp --port_name eth1
./lf_firemod.pl --mgr jedtest --resource 2 --action create_cx --cx_name tcp200 --cx_endps tcp200-A,tcp200-B
CLI commands:
add_endp tcp200-A 1 2 sta200 lf_tcp -1 NA 1000000 1000000 NA -1 -1 increasing NO NA 0 0
set_endp_report_timer tcp200-A 5000
add_endp tcp200-B 1 2 eth1 lf_tcp -1 NA 1000000 1000000 NA -1 -1 increasing NO NA 0 0
set_endp_report_timer tcp200-B 5000
add_cx tcp200 default_tm tcp200-A tcp200-B
set_cx_report_timer default_tm tcp200 5000 NA 

Create a Layer 3 UDP Connection

Shell script:
./lf_vue_mod.sh --mgr jedtest --resource 2 --create_cx --name upd200 --udp --sta sta200 --port eth1 --bps 2000000 --log_cli /tmp/clilog.txt --quiet 1
Perl script:
./lf_firemod.pl --mgr jedtest --resource 2 --log_cli /tmp/clilog.txt --quiet 1 --action create_endp --endp_name udp200-A --speed 2000000 --endp_type lf_udp --port_name sta200
./lf_firemod.pl --mgr jedtest --resource 2 --log_cli /tmp/clilog.txt --quiet 1 --action create_endp --endp_name udp200-B --speed 2000000 --endp_type lf_udp --port_name eth1
./lf_firemod.pl --mgr jedtest --resource 2 --log_cli /tmp/clilog.txt --quiet 1 --action create_cx --cx_name udp200 --cx_endps udp200-A,udp200-B
CLI commands:
add_endp udp200-A 1 2 sta200 lf_udp -1 NA 2000000 2000000 NA -1 -1 increasing NO NA 0 0
set_endp_report_timer udp200-A 5000
add_endp udp200-B 1 2 eth1 lf_udp -1 NA 2000000 2000000 NA -1 -1 increasing NO NA 0 0
set_endp_report_timer udp200-B 5000
add_cx udp200 default_tm udp200-A udp200-B
set_cx_report_timer default_tm udp200 5000 NA

Create a Layer 4 Web Connection

Layer-4 connections are created with a one-sided technique, the curl command always operates on the A-side and the B-side is unmanaged. The endpoint and connection naming does not follow the Layer-3 convention.

Shell script:
./lf_vue_mod.sh --mgr jedtest --resource 2 --create_l4 --name yh200 --sta sta200 --url http://www.yahoo.com/ --utm 2400 --log_cli /tmp/clilog.txt --quiet 1
Perl script:
Commands are set using lf_firemod.pl --action do_cmd --cmd ...
CLI commands:
add_l4_endp yh200 1 2 sta200 l4_generic 0 10000 2400 'dl http://www.yahoo.com/ /dev/null' NA NA ca-bundle.crt NA 0 0 60 0 512   0.0.0.0
set_endp_tos yh200 DONT-SET 0
set_endp_flag yh200 L4Enable404 0
set_endp_report_timer yh200 5000
set_endp_flag yh200 ClearPortOnStart 0
set_endp_quiesce yh200 3
add_cx CX_yh200 default_tm yh200

Candela  Technologies, 2417 Main Street, Suite 201, Ferndale, WA 98248, USA
www.candelatech.com | sales@candelatech.com | +1.360.380.1618
Google+ | Facebook | LinkedIn | Blog