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