Source code for sts.traffic_generator

# Copyright 2011-2013 Colin Scott
# Copyright 2011-2013 Andreas Wundsam
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from pox.lib.packet.ethernet import *
from pox.lib.packet.ipv4 import *
from pox.lib.packet.icmp import *
from sts.dataplane_traces.trace import DataplaneEvent
import random
import itertools

[docs]class TrafficGenerator (object): """ Generate sensible randomly generated (openflow) events """
[docs] def __init__(self, random=random.Random()): self.random = random self.host2dests = {} self._packet_generators = { "icmp_ping" : self.icmp_ping }
[docs] def set_hosts(self, hosts): ''' Let us know how to set the destination addresses ''' for host in hosts: others = [ h for h in hosts if h != host ] self.host2dests[host] = itertools.cycle(others)
[docs] def generateAndInject(self, packet_type, host, self_pkt=False): if packet_type not in self._packet_generators: raise AttributeError("Unknown event type %s" % str(packet_type)) # Inject the packet through one of the hosts' interfaces if len(host.interfaces) < 1: raise RuntimeError("No interfaces to choose from on host %s!" % (str(host))) interface = self.random.choice(host.interfaces) destination_interface = None if self_pkt: # Send a packet to ourself to help the controller learn our location destination_interface = interface elif self.host2dests: destination = self.host2dests[host].next() destination_interface = self.random.choice(destination.interfaces) packet = self._packet_generators[packet_type](interface, destination_interface) host.send(interface, packet) return DataplaneEvent(interface, packet) # Generates an ICMP ping, and injects it through the interface
[docs] def icmp_ping(self, interface, destination_interface): # randomly choose an in_port. e = ethernet() e.src = interface.hw_addr if destination_interface is not None: e.dst = destination_interface.hw_addr else: # TODO(cs): need a better way to create random MAC addresses e.dst = EthAddr(struct.pack("Q",self.random.randint(1,0xFF))[:6]) e.type = ethernet.IP_TYPE ipp = ipv4() ipp.protocol = ipv4.ICMP_PROTOCOL if hasattr(interface, 'ips'): ipp.srcip = self.random.choice(interface.ips) else: ipp.srcip = IPAddr(self.random.randint(0,0xFFFFFFFF)) if destination_interface is not None and hasattr(destination_interface, 'ips'): ipp.dstip = self.random.choice(destination_interface.ips) else: ipp.dstip = IPAddr(self.random.randint(0,0xFFFFFFFF)) ping = icmp() ping.type = self.random.choice([TYPE_ECHO_REQUEST,TYPE_ECHO_REPLY]) ping.payload = "PingPing" * 6 ipp.payload = ping e.payload = ipp return e