• POX Wiki

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
def parseICMP(packet):
	if eth_packet.type == ethernet.IP_type:
		ip_packet = eth_packet.next
		if ip_packet.protocol = ipv4.ICMP_PROTOCOL
			icmp_packet = ip_packet.next
...

This is probably not the best way to navigate a packet, but it illustrates the structure of packet headers in POX. At each level of encapsulation the packet header values can be obtained. For example, the source mac ip address of an ethernet frame the ip packet above and icmp sequence number can be retrieved obtained as followsshown:

Code Block
...
src_macip = ethip_packet.hw_srcsrcip
icmp_sequence = icmp_packet.seq

And similarly for other packet headers. Refer to the specific packet code for other headers.

ARP messages

 

Generating arbitrary messages 

This section briefly describes how to generate arbitrary packet which are defined within POX in pox/lib/packet.

TODO

...

Handling ARP packet as they arrive as packet ins can be a little confusing. Moreover you'll probably want the controller proxy the arp replies rather than flood them all over the network depending on whether you know the mac address of the machine the arp request is looking for. To handle arp packet in you should have an event listener set up to receive packet ins as shown:

Code Block
def _handle_PacketIn (self, event):
	packet = event.parsed
	if packet.type == packet.ARP_TYPE:
		if packet.next.opcode == arp.REQUEST:
			arp_reply = arp()
            		arp_reply.hwsrc = <requested mac address>
            		arp_reply.hwdst = packet.src
            		arp_reply.hwtype = packet.next.hwtype
            		arp_reply.prototype = packet.next.prototype
            		arp_reply.opcode = arp.REPLY #No shit!
            		arp_reply.protosrc = <IP of requested mac-associated machine>
            		arp_reply.protodst = packet.next.protosrc
            		ether = ethernet()
            		ether.type = ethernet.ARP_TYPE
            		ether.dst = packet.src
            		ether.src = <requested mac address>
            		ether.set_payload(arp_reply)
			#send this packet to the switch
			#see section below on this topic
		elif packet.next.opcode == arp.REPLY:
			print "It's a reply do something cool"
		else:
			print "Some other ARP opcode, probably do something smart here"

Sending a message to a datapath

There are several methods to send messages to the datapath. We will cover FlowMods and PacketOuts in this document. 

When a datapath connects to the controller an event will be generated provided you are listening to connection up events. Below is the basic code to handle switch connections:

Code Block
def _handle_ConnectionUp (self, event):
	connection = event.connection

The connection parameter is essentially the connection to the datapath and can be used to send messages down to the datapath. This variable should be stored.

Sending a FlowMod

To send a flow mod you must define a match structure (discussed above) and set some flow mod specific parameters as shown here:

Code Block
    msg = ofp_flow_mod()
    msg.match = match
    msg.idle_timeout = idle_timeout
    msg.hard_timeout = hard_timeout
    msg.actions.append(of.ofp_action_output(port = port))
    msg.buffer_id = <some buffer id, if any>
    connection.send(msg)

Using the connection variable obtained when the datapath joined, we can send the flowmod to the switch.

Sending a PacketOut

In a similar manner to a flow mod, one must first define a packet out as shown here:

Code Block
    msg = of.ofp_packet_out(in_port=of.OFPP_NONE)
    msg.actions.append(of.ofp_action_output(port = outport))
    msg.buffer_id = <some buffer id, if any>
    connection.send(msg)

The inport is set to OFPP_NONE because the packet was generated at the controller and did not originate as a packet in at the datapath.