Manipulating streams¶
We suppose that drone is running on the local host.
Configuration¶
At this point, the stream is created on the drone instance, but it has not
configuration. To configure it, we simply set the desired attributes on the
stream object, and then call save()
to update the stream configuration on
the drone instance.
# we give a name to the stream, although it's optional
stream.name = 'a_stream'
# we want to send packets, not bursts of packets
stream.unit = 'PACKETS'
# we want the stream to finish after it sent a fixed amount of packets
stream.mode = 'FIXED'
# after this stream, we want to stop transmitting, even if there is another
# stream enabled on this port
stream.next = 'STOP'
# we want to send 100 packets
stream.num_packets = 100
# at a rate of 50 packets per seconds
stream.packets_per_sec = 50
# finally, we enable the stream, otherwise, it won't send anything.
stream.is_enabled = True
The stream object holds the configuration. To apply it we call save()
:
stream.save()
Protocols configuration¶
We will send a simple IP packet with fixed fields. We add the different layers
(or protocols) to the stream. Note that the order matters: adding an IPv4 layer
before a MAC layer will result in an invalid frame. Each layer correspond to a
class in simple_ostinato.protocols
:
from simple_ostinato.protocols import Mac, Ethernet, IPv4, Payload
mac = Mac()
mac.source = '00:00:11:11:22:22'
mac.destination = 'FF:FF:FF:FF:FF:FF'
stream.layers.append(mac)
eth = Ethernet()
eth.ether_type = 0x800
stream.layers.append(eth)
ip = IPv4()
ip.source = '10.0.0.1'
ip.destination = '10.0.0.2'
stream.layers.append(ip)
payload = Payload()
stream.layers.append(payload)
# finally, save the stream
stream.save()
Since simple_ostinato.stream.Stream.layers
is a simple list, we could
have writtend directly stream.layers = [mac, eth, ip, payload]
.
Also, all the attributes of the layers can be passed to the class constructor, so the above could be just written:
from simple_ostinato.protocols import Mac, Ethernet, IPv4, Payload
stream.layers = [
Mac(source='00:00:11:11:22:22', destination='FF:FF:FF:FF:FF:FF'),
Ethernet(ether_type=0x800),
IPv4(source='10.0.0.1', destination='10.0.0.2'),
Payload()]
To remove a layer, remove it from the
simple_ostinato.stream.Stream.layers
list, and save the stream. For
instance, to delete the Payload
and IPv4
layers:
del stream.layers[-1]
del stream.layers[-1]
Variable fields¶
Apart from a small number of exceptions, every field can be variable, i.e. being increment/decremented/randomized. To control this, each attribute has three other attributes associated:
<attribute_name>_mode
: can beFIXED
(the default),INCREMENT
,DECREMENT
, orRANDOMIZED
<attribute_name>_step
: is an integer that specify by how much the field should be incremented or decremented<attribute_name>_count
: is an integer that specify after how many packets, the field should be reset to its inital value
Some fields also have a <attribute_name>_override
attribute. This field
must be set to True
in order to set a custom value. Otherwise, Ostinato
computes a value automatically.
Complete example¶
from simple_ostinato import Drone
from simple_ostinato.protocols import Mac, Ethernet, IPv4, Payload
drone = Drone('localhost')
drone.fetch_ports()
lo = drone.get_port('lo')
# create a stream
stream = lo.add_stream()
# configure the stream
stream.name = 'a_stream'
stream.unit = 'PACKETS'
stream.mode = 'FIXED'
stream.next = 'STOP'
stream.num_packets = 100
stream.packets_per_sec = 50
stream.is_enabled = True
# IMPORTANT: apply the configuration
stream.save()
# Add layers
stream.layers = [
Mac(source='00:00:11:11:22:22', destination='FF:FF:FF:FF:FF:FF'),
Ethernet(ether_type=0x800),
IPv4(source='10.0.0.1', destination='10.0.0.2'),
Payload()]
# Delete the ip and payload layers
stream.layers = stream.layers[:-2]
# Delete stream
lo.del_stream(stream.stream_id)