Hi,
thank you very much. Works like a charm now.
I had to set udp_packet.len as well in order to get the correct length everywhere. I also set the ipv4_packet.protocol and ethernet_packet.type to the corresponding values.

As already pointed out: Try to use a string as payload for the packet and you will most probably get an exception that array.array could not be found.
Thank you very much for your help!

Best regards
Bernd

On 26.01.2012 22:09, Sabnis, Saurabh S wrote:
Thanks. Let me try your code and let me also try using a different branch. But I think you are not 
getting this error because you are sending a packet as an argument to the set_payload method and 
hence the code "elif type(payload) == array.array:" never gets called because "if 
isinstance(payload, packet_base):" will always be true for such cases. (Please see below)

from packet_base.py
===================

  def set_payload(self, payload):
         '''Set the packet payload.  Expects a string, array to packet of type 
packet_base'''
         if isinstance(payload, packet_base):
             self.next    = payload
             payload.prev = self
         elif type(payload) == type(''):
             self.next = payload
         elif type(payload) == array.array:
             self.next = payload.tostring()
         else:
             self.msg('warning, payload must be string, array or type 
packet_base')

--Saurabh

----- Original Message -----
From: Aaron Rosen<aro...@clemson.edu>
To: Saurabh S Sabnis<ssabn...@gatech.edu>
Cc: nox-dev<nox-dev@noxrepo.org>, Bernd Wittefeld<s9bew...@stud.uni-saarland.de>
Sent: Thu, 26 Jan 2012 15:33:45 -0500 (EST)
Subject: Re: [nox-dev] Creating and sending udp packet from controller through 
switch

Here's an example of sending a UDP packet. If you want to send an ICMP
packet just change l4=icmp() (and fill in the  icmp fields) and the
l3.protocol type to icmp.

Aaron

P.S: I'm using the latest nox destiny and I didn't need to change any
internal nox code.

def send_udp(mac, dstip, srcip, srcport, dstport, payload):
     l4 = udp()
     l4.srcport = srcport
     l4.dstport  = dstport
     l4.len = udp.MIN_LEN + len(payload)
     l4.set_payload(payload)
     l4.arr = l4.tostring()
     l3 = ipv4()
     l3.iplen = ipv4.MIN_LEN + l4.len
     l3.protocol = ipv4.UDP_PROTOCOL
     l3.dstip = dstip
     l3.srcip = srcip
     l3.set_payload(l4)
     l2 = ethernet()
     l2.set_payload(l3)
     l2.dst = mac
     l2.src = octstr_to_array(CONTROLLER_MAC)
     l2.type = ethernet.IP_TYPE
     l4.csum = l4.checksum()
     return l2

then:

send_openflow_packet(dpid, send_udp(mac, dstip, srcip, srcport,
dstport, payload).tostring(), inport)


On Thu, Jan 26, 2012 at 2:43 PM, Sabnis, Saurabh S<ssabn...@gatech.edu>  wrote:
Hi,

I have similar doubt. I was trying to send ICMP unreachable packets back to host but when 
I tried to set the payload of unreach() packet to "packet.next.arr[0:packet.next.hl 
* 4 + 8]", I got an error due to missing 'import array' statement. After inserting 
it in the packet_base.py file I got the following error.

00074|pyrt|ERR:unable to invoke a Python event handler:
Traceback (most recent call last):
  File "./nox/lib/util.py", line 116, in f
    event.total_len, buffer_id, packet)
  File "./nox/coreapps/examples/printpacket.py", line 185, in packet_in_callback
    route_packet(self,dpid, inport, packet, packet.arr, bufid)
  File "./nox/coreapps/examples/printpacket.py", line 173, in route_packet
    learn_and_forward(self,dpid,inport,packet,buf,bufid)
  File "./nox/coreapps/examples/printpacket.py", line 132, in learn_and_forward
    send_dest_unreach(self,dpid,packet,inport)
  File "./nox/coreapps/examples/printpacket.py", line 89, in send_dest_unreach
    unreach_packet.set_payload(packet.next.arr[0:packet.next.hl * 4 + 8])
  File "./nox/lib/packet/packet_base.py", line 96, in set_payload
    elif type(payload) == array.array:
AttributeError: type object 'array.array' has no attribute 'array'

Then to work around, I did not set the payload of unreach() and created other 
wrapper packets and sent them to the host using sed_openflow_packet method. 
This method requires eth.tostring() method which calls hdr and checksum methods 
of ipv4.py. But then it again gets stuck there by giving following error:

  File "./nox/coreapps/examples/printpacket.py", line 185, in packet_in_callback
    route_packet(self,dpid, inport, packet, packet.arr, bufid)
  File "./nox/coreapps/examples/printpacket.py", line 173, in route_packet
    learn_and_forward(self,dpid,inport,packet,buf,bufid)
  File "./nox/coreapps/examples/printpacket.py", line 132, in learn_and_forward
    send_dest_unreach(self,dpid,packet,inport)
  File "./nox/coreapps/examples/printpacket.py", line 119, in send_dest_unreach
    self.send_openflow_packet(dpid, unreach_eth.tostring(), 
inport,openflow.OFPP_NONE)
  File "./nox/lib/packet/packet_base.py", line 117, in tostring
    return ''.join((buf, self.next.tostring()))
  File "./nox/lib/packet/packet_base.py", line 112, in tostring
    buf = self.hdr()
  File "./nox/lib/packet/ipv4.py", line 167, in hdr
    self.csum = self.checksum()
  File "./nox/lib/packet/ipv4.py", line 162, in checksum
    self.dstip)
error: 'H' format requires 0<= number<= 65535

I printed the values of the attributes used in these functions and found out 
that the self.id attribute of ipv4 packet has value more than 65535. It is 
generated using int(time.time()) function. So I changed the statement to 
int(time.time()) % 65535 and went ahead.

Now I am able to send my packet to the host and I can see it in Wireshark but 
my host is not giving me destination unreachable error. There are several 
problems here. Can someone please help me regarding this. My code is as follows:

def send_dest_unreach(self,dpid,packet,inport):

        unreach_packet = unreach()
        unreach_packet.unused = 0
        unreach_packet.next_mtu = 0

        # unreachable messages include the IP header and the first 8 bytes of 
the
        # packet that couldn't reach its destination
        #print packet.next.arr[0:packet.next.hl * 4 + 8]
        unreach_packet.set_payload(packet.next.arr[0:packet.next.hl * 4 + 8])
        #unreach_packet.arr = packet.next.arr[0:packet.next.hl * 4 + 8]

        unreach_icmp = icmp()
        unreach_icmp.type = 3 # unreachable
        unreach_icmp.code = 0 # network unreachable
        unreach_icmp.set_payload(unreach_packet)

        # icmp (unlike ipv4) doesn't automatically calculate its checksum, so we
        # have to do it ourself
        unreach_icmp.csum = packet_utils.checksum(unreach_icmp.tostring(), 0)

        unreach_ip = ipv4()

        # length of the header plus the length of the payload
        unreach_ip.iplen = unreach_ip.hl * 4 + len(unreach_icmp.tostring())

        unreach_ip.protocol = ipv4.ICMP_PROTOCOL
        unreach_ip.srcip = packet.next.dstip # Hmm... ?
        unreach_ip.dstip = packet.next.srcip
        unreach_ip.set_payload(unreach_icmp)
        print_packet(unreach_ip,"ID")

        unreach_eth = ethernet()
        unreach_eth.src = packet.dst # I wonder what this should actually be... 
?
        unreach_eth.dst = packet.src
        unreach_eth.type = packet.type
        unreach_eth.set_payload(unreach_ip)

----- Original Message -----
From: Aaron Rosen<aro...@clemson.edu>
To: Bernd Wittefeld<s9bew...@stud.uni-saarland.de>
Cc: nox-dev<nox-dev@noxrepo.org>
Sent: Thu, 26 Jan 2012 14:03:38 -0500 (EST)
Subject: Re: [nox-dev] Creating and sending udp packet from controller  through 
switch

Hi,

You need to set the length field in the Ipv4 packet.

ipv4_packet.iplen = ipv4.MIN_LEN + udp_packet.len()

should do the trick.

Aaron

On Thu, Jan 26, 2012 at 1:42 PM, Bernd Wittefeld
<s9bew...@stud.uni-saarland.de>  wrote:
Hi,
I have a python component and want to create an udp packet in the controller
and send it out via "self.send_openflow_packet(dpid, packet.tostring(),
outport)"

First of all: a small bugfix is needed:
nox/src/nox/lib/packet/packet_base.py needs an "import array". Without that,
the set_payload function raises an exception as it does not find
array.array.

Now I create my packet the following way:

from nox.lib.packet.udp                import udp
from nox.lib.packet.ipv4               import ipv4
from nox.lib.packet.ethernet        import ethernet

udp_packet = udp()
udp_packet.srcport = 12345
udp_packet.dstport = 4711
rand = random.random()
udp_packet.set_payload(str(rand))
udp_packet.csum = udp_packet.checksum()

ipv4_packet = ipv4()
ipv4_packet.set_payload(udp_packet)
ipv4_packet.srcip = ipstr_to_int(CONTROLLER_IP)
ipv4_packet.dstip = ipstr_to_int(CONTROLLER_IP)
ipv4_packet.csum = ipv4_packet.checksum()

eth_packet = ethernet()
eth_packet.src = CONTROLLER_MAC
eth_packet.dst = CONTROLLER_MAC
eth_packet.set_payload(ipv4_packet)
eth_packet.type = ethernet.IP_TYPE

and send this then via self.send_openflow_packet

The packet goes out the link and is forwarded (via a flow on another switch)
back to the controller where I can see it in my packet_in handler.
The only problem is: the packet only consists of the link layer (ethernet
type) header and the ipv4 type header. The payload of the ipv4 packet (which
should be my udp header and the payload) is completely missing. From the
ipv4 class, the ipv4.next is None and I can also verify with wireshark that
the packet that is transmitted from the controller to the switch encapsuled
in an OpenFlow packet, consists only of the ethernet header and the ipv4
header.
Am I missing something? Where is this going wrong?
I tried to look at the send_openflow_packet function. It seems to somehow
call self.ctxt.send_openflow_packet_port in nox/src/nox/lib/core.py which I
could not find?!
I am not into Swig and all that stuff, so I am stuck here :(

Any help is greatly appreciated!


Best regards

Bernd

_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev


--
Aaron O. Rosen
Masters Student - Network Communication
306B Fluor Daniel
_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev




_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev

Reply via email to