Git Product home page Git Product logo

simple-ostinato's Introduction

simple-ostinato

Build Status Coverage Status

A wrapper for the ostinato python client.

Documentation (work in progress): http://simple-ostinato.readthedocs.org/en/latest/

simple_ostinato is a python package that makes it easy to use the ostinato python agent python-ostinato. It is basically a wrapper around python-ostinato that hides the RPC engineering.

Example

We assume that drone is already running on the localhost, and that we created a veth pair of interfaces with:

ip link add veth0 type veth peer name veth1
ip link set veth0 up
ip link set veth1 up

The following script sends traffic on veth0 and captures in on veth1:

from simple_ostinato import Drone
from simple_ostinato.protocols import Mac, Ethernet, IPv4, Payload

# connect to the drone instance that runs on localhost
drone = Drone('localhost')

# fetch port information
drone.fetch_ports()

# store the two ports we are going to use in dedicated variables
port_tx = drone.get_port_by_name('veth0')[0]
port_rx = drone.get_port_by_name('veth1')[0]

# Create a new stream
stream = port_tx.add_stream(
    Mac(source='00:11:22:aa:bb:cc', destination='00:01:02:03:04:05'),
    Ethernet(),
    IPv4(source='10.0.0.1', destination='10.0.0.2'),
    Payload())

# Configure the stream
stream.name = 'simple_mac_stream'
stream.packets_per_sec = 1000
stream.num_packets = 100
stream.enable()
stream.save()

# Clear the stats on the transmitting and receiving port
port_tx.clear_stats()
port_rx.clear_stats()

# Send and capture
port_rx.start_capture()
port_tx.start_send()
time.sleep(1)
port_tx.stop_send()
port_rx.stop_capture()

# Get the stats and print them
tx_stats = port_tx.get_stats()
rx_stats = port_rx.get_stats()
print str(tx_stats)
print str(rx_stats)

# We can also store the capture:
capture = port_rx.save_capture(port_rx.get_capture(), 'capture.pcap')

simple-ostinato's People

Contributors

little-dude avatar trainman419 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple-ostinato's Issues

Fresh install of 'simple_ostinato' fails with newer version of 'protobuf'

I installed 'simple_ostinato' on a new Ubuntu 16.04 VM and tried to import the library into the python interpreter and received the following error:

$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import simple_ostinato
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/simple_ostinato/__init__.py", line 1, in <module>
    from .stream import Stream
  File "/usr/local/lib/python2.7/dist-packages/simple_ostinato/stream.py", line 8, in <module>
    from . import protocols
  File "/usr/local/lib/python2.7/dist-packages/simple_ostinato/protocols/__init__.py", line 2, in <module>
    from .overrides import MacAddress, Mac, Ethernet, IPv4Address, IPv4, Payload, \
  File "/usr/local/lib/python2.7/dist-packages/simple_ostinato/protocols/overrides.py", line 3, in <module>
    from . import autogenerates
  File "/usr/local/lib/python2.7/dist-packages/simple_ostinato/protocols/autogenerates.py", line 1, in <module>
    from ostinato.protocols import arp_pb2, gmp_pb2, ip4over6_pb2, mld_pb2, \
  File "/usr/local/lib/python2.7/dist-packages/ostinato/protocols/dot2llc_pb2.py", line 13, in <module>
    serialized_pb='\n\rdot2llc.proto\x12\x08OstProto\x1a\x0eprotocol.proto\x1a\ndot3.proto\x1a\tllc.proto\"\t\n\x07\x44ot2Llc:7\n\x07\x64ot2Llc\x12\x12.OstProto.Protocol\x18\xce\x01 \x01(\x0b\x32\x11.OstProto.Dot2Llc')
  File "/usr/local/lib/python2.7/dist-packages/google/protobuf/descriptor.py", line 824, in __new__
    return _message.default_pool.AddSerializedFile(serialized_pb)
TypeError: Couldn't build proto file into descriptor pool!
Invalid proto descriptor for file "dot2llc.proto":
  dot2llc.proto: Import "dot3.proto" has not been loaded.
  dot2llc.proto: Import "llc.proto" has not been loaded.

I'm not exactly what the issue is, however, I'm thinking it may have to do with an update that was done to protobuf.

add the remaining protocols

ostinato supports many protocols, but we currently only support Ethernet, IPv4, UDP and TCP. The other needs to be implemented.

Part of the code can be generated. Here is how I processed for IPv4.

Create a new item in the protocol list in the generator module:

{
  'class_name':   'IPv4',   # name of the class to generate
  'doc':          'Represent the IPv4 layer.',  # docstring of the class
  'protocol_id':  constants._Protocols.IP4,  # protocol ID, see https://github.com/little-dude/simple-ostinato/blob/master/simple_ostinato/constants.py#L29
  'extension':    'ip4_pb2.ip4',
  'attributes': {
      # TODO
  }
},

The extension is the protocol buffer class that correspond to IPv4 in the native ostinato library:

>>> from ostinato.protocols import ip4_pb2
>>> type(ip4_pb2.Ip4)
google.protobuf.reflection.GeneratedProtocolMessageType

populate the attributes, using the corresponding protobuf file in the ostinato repo.

Each attribute looks like this:

'attribute name': (offset, default value, full mask, mask, protobuf name, override name, docstring),
  • the offset is the offset of the field in the layer, in bytes
  • the default value is the default value of the protocol
  • the full mask is the mask in "entire" bytes. For example, in the IP protocol, the version field occupies 4 first bits, so we consider the full mask is 1 byte. It's somewhat confusing, and we could (should) probably get rid of the concept of "full mask" but it made it easier to generate the code at the beginning.
  • the mask is the actuall mask of the field. For the version, which occupied the 4 first bits of a byte, it is 0xf0.
  • the protobuf name is the name of the field in the protobuf message (see above the google.protobuf.reflection.GeneratedProtocolMessageType object)
  • the override name is generally None. It is used for fields that normally have default values (like checksums, which Ostinato computes automatically), but that can be overriden through an override attribute in the protobuf message. These override attributes are declared in the protobuf file.
    ` the doctring is the docstring of the attribute.

The source field of the IP protocol looks like this for example:

'source': (12, '127.0.0.1', 0xffffffff, 0xffffffff, 'src_ip' , None, 'Source IP address'),

Generate the code

python -m simple_ostinato.generator

This generates the code in simple_ostinato/autogenerates.py. For the IPv4 class, it generates an _IPv4 class.

Make you protocol available in the stream module

Add an override class

Declare your class in the simple_ostinato/protocols/overrides.py. This is where you can also customize you protocol if you want.

  1. Write tests :)

TCP Destination Port not working

I created a stream with a TCP destination port and the destination_override set to True.

stream.layers = [
... Mac(source='52:54:00:00:02:21', destination='52:54:00:00:02:20'),
... Ethernet(),
... IPv4(source='96.6.54.84', destination='141.193.37.5'),
... Tcp(destination_override=True, destination=443),
... Payload()]

The layer in the list looks to be correct.

print stream.layers[3]
Tcp(flag_ack=0,header_length=0,reserved=0,ack_num=0,flag_rst=0,window_size=0,destination=443,flag_psh=0,urgent_pointer=0,source=49152,flag_ece=0,flag_urg=0,sequence_num=0,checksum=0,flag_syn=0,flag_cwr=0,flag_fin=0,flag_ns=0,)

However, when I start the traffic and do a tcpdump of the packets, both the source and destination ports are set to 0.

13:46:49.671815 IP 96.6.54.84.0 > 141.193.37.5.0: Flags [none], seq 0:361, win 0, length 361
13:46:49.747704 IP 96.6.54.84.0 > 141.193.37.5.0: Flags [none], seq 0:1359, win 0, length 1359
13:46:49.819851 IP 96.6.54.84.0 > 141.193.37.5.0: Flags [none], seq 0:569, win 0, length 569
13:46:49.895964 IP 96.6.54.84.0 > 141.193.37.5.0: Flags [none], seq 0:762, win 0, length 762
13:46:49.975706 IP 96.6.54.84.0 > 141.193.37.5.0: Flags [none], seq 0:1423, win 0, length 1423

impossible to get rid of added layers in particular stream

Hi, pal.
Looks like it is impossible to get rid of some added layers using code like this

stream.layers.append(proto_layer)
stream.save()
del stream.layers[:]
stream.save()

Because looks like you're fetching layers while saving stream thus preventing them from being deleted. Am I missing something or there are actually issue persists?

Many errors returns during import. Any idea?

Hi,

Can you advise me what to do?

I tried to install using "python setup.py install" in virtualenv.

And try to run sample introduced, https://github.com/little-dude/simple-ostinato.
However, it returns many errors below;

Traceback (most recent call last):
File "d:\Programming\GTAC\test_automation\test\simple_ostinato_test.py", line 2, in
from simple_ostinato import Drone
File "D:\Programming\venv\venv27\lib\site-packages\simple_ostinato-0.0.4-py2.7.egg\simple_ostinato_init_.py", line 1, in
from .stream import Stream
File "D:\Programming\venv\venv27\lib\site-packages\simple_ostinato-0.0.4-py2.7.egg\simple_ostinato\stream.py", line 8, in
from . import protocols
File "D:\Programming\venv\venv27\lib\site-packages\simple_ostinato-0.0.4-py2.7.egg\simple_ostinato\protocols_init_.py", line 2, in
from .overrides import Mac, Ethernet, IPv4, Payload, Tcp, Udp
File "D:\Programming\venv\venv27\lib\site-packages\simple_ostinato-0.0.4-py2.7.egg\simple_ostinato\protocols\overrides.py", line 3, in
from . import autogenerates
File "D:\Programming\venv\venv27\lib\site-packages\simple_ostinato-0.0.4-py2.7.egg\simple_ostinato\protocols\autogenerates.py", line 2, in
from ostinato.protocols import arp_pb2, gmp_pb2, ip4over6_pb2, mld_pb2,
ImportError: cannot import name sample_pb2

Issue with the listed example

Listed example doesn't work as you are saving the stream before adding the protocol layers. This will result in malformed packet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.