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