def make_packet(pkt_size, outer_vlan=0, inner_vlan=0, vni=0, eth_src=None, eth_dst=None, udp_src_port=None, udp_dst_port=None, eth_type=None, ip_src=None, ip_dst=None, ip_proto=None): ip_src = IP_SRC if ip_src is None else ip_src ip_dst = IP_DST if ip_dst is None else ip_dst ip_proto = IP_PROTO if ip_proto is None else ip_proto eth_src = DL_SRC if eth_src is None else eth_src eth_dst = DL_SRC if eth_dst is None else eth_dst eth_type = ether.ETH_TYPE_IP if eth_type is None else eth_type udp_src_port = UDP_SRC_PORT if udp_src_port is None else udp_src_port udp_dst_port = UDP_DST_PORT if udp_dst_port is None else udp_dst_port if outer_vlan or inner_vlan: eth_type = ether.ETH_TYPE_8021Q e = ethernet.ethernet(eth_dst, eth_src, eth_type) i = ipv4.ipv4(total_length=0, src=ip_src, dst=ip_dst, proto=ip_proto, ttl=1) if vni: udp_dst_port = 4789 u = udp.udp(src_port=udp_src_port, dst_port=udp_dst_port) outer_len = 0 outer_tag = None if outer_vlan: outer_tag = vlan.vlan(vid=outer_vlan, ethertype=ether.ETH_TYPE_8021Q, cfi=1) outer_len = len(outer_tag) inner_len = 0 inner_tag = None if inner_vlan: inner_tag = vlan.vlan(vid=inner_vlan, ethertype=ether.ETH_TYPE_8021Q, cfi=1) inner_len = len(inner_tag) vxlan_len = 0 vxlan_tag = None if vni: vxlan_tag = vxlan.vxlan(vni) vxlan_len = len(vxlan_tag) payload_size = pkt_size - (len(e) + len(i) + len(u) + inner_len + outer_len + vxlan_len) payload = bytearray(payload_size if payload_size > 0 else 0) p = packet.Packet() p.add_protocol(e) if outer_tag: p.add_protocol(outer_tag) if inner_tag: p.add_protocol(inner_tag) p.add_protocol(i) p.add_protocol(u) if vxlan_tag: p.add_protocol(vxlan_tag) p.add_protocol(payload) return p
def breakdown_trunk_ports(self,src,dpid,pkt,eth,dst): if src in self.mac_to_port[dpid]: vlan_tag = 0 pkt.add_protocol(vlan.vlan(vid=vlan_tag, ethertype=ether.ETH_TYPE_8021Q)) eth = pkt.get_protocols(ethernet.ethernet)[0] dst = eth.dst src = eth.src elif src in self.src_vid: vlan_tag = self.src_vid[src] print 'src_vid:',vlan_tag pkt.add_protocol(vlan.vlan(vid=vlan_tag, ethertype=ether.ETH_TYPE_8021Q)) eth = pkt.get_protocols(ethernet.ethernet)[0] dst = eth.dst src = eth.src
def createPacket(self, src, dst, srcip, dstip): # create send packet # ether - vlan - ipv6 - icmpv6 ( - mldv2 ) sendpkt = packet.Packet() sendpkt.add_protocol(ethernet.ethernet( ethertype=ether.ETH_TYPE_8021Q, dst=dst, src=src)) sendpkt.add_protocol(vlan.vlan( pcp=0, cfi=0, vid=100, ethertype=ether.ETH_TYPE_IPV6)) sendpkt.add_protocol(ipv6.ipv6( src=srcip, dst=dstip, nxt=inet.IPPROTO_ICMPV6)) sendpkt.add_protocol(icmpv6.icmpv6( type_=icmpv6.ICMPV6_MEMBERSHIP_QUERY, data=icmpv6.mldv2_query(address='::'))) ''' sendpkt.add_protocol(icmpv6.icmpv6( type_=icmpv6.MLDV2_LISTENER_REPORT, data=icmpv6.mldv2_report( record_num=2, records=[ icmpv6.mldv2_report_group(type_=1, address='::'), icmpv6.mldv2_report_group(type_=2, address='::')]))) ''' sendpkt.serialize() return sendpkt
def _respond_arp(self, datapath, port, arptbl, pkt_ethernet, pkt_vlan, pkt_arp): if pkt_arp.opcode != arp.ARP_REQUEST: LOG.debug("unknown arp op %s", pkt_arp.opcode) return False ip_addr = pkt_arp.dst_ip hw_addr = arptbl.get(ip_addr) if hw_addr is None: LOG.debug("unknown arp request %s", ip_addr) return False LOG.debug("responding arp request %(ip_addr)s -> %(hw_addr)s", {'ip_addr': ip_addr, 'hw_addr': hw_addr}) pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=hw_addr)) if pkt_vlan: pkt.add_protocol(vlan.vlan(cfi=pkt_vlan.cfi, ethertype=pkt_vlan.ethertype, pcp=pkt_vlan.pcp, vid=pkt_vlan.vid)) pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=hw_addr, src_ip=ip_addr, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_arp_reply(datapath, port, pkt) return True
def _respond_arp(self, datapath, port, arptbl, pkt_ethernet, pkt_vlan, pkt_arp): if pkt_arp.opcode != arp.ARP_REQUEST: LOG.debug("unknown arp op %s", pkt_arp.opcode) return False ip_addr = pkt_arp.dst_ip hw_addr = arptbl.get(ip_addr) if hw_addr is None: LOG.debug("unknown arp request %s", ip_addr) return False LOG.debug("responding arp request %(ip_addr)s -> %(hw_addr)s", { 'ip_addr': ip_addr, 'hw_addr': hw_addr }) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=hw_addr)) pkt.add_protocol( vlan.vlan(cfi=pkt_vlan.cfi, ethertype=pkt_vlan.ethertype, pcp=pkt_vlan.pcp, vid=pkt_vlan.vid)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=hw_addr, src_ip=ip_addr, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_arp_reply(datapath, port, pkt) return True
def build_pkt(pkt): layers = [] if 'arp_target_ip' in pkt: ethertype = 0x806 layers.append(arp.arp(dst_ip=pkt['arp_target_ip'])) elif 'ipv6_src' in pkt: ethertype = 0x86DD layers.append(ipv6.ipv6(src=pkt['ipv6_src'], dst=pkt['ipv6_src'])) else: ethertype = 0x800 if 'ipv4_src' in pkt: net = ipv4.ipv4(src=pkt['ipv4_src'], dst=pkt['ipv4_dst']) else: net = ipv4.ipv4() layers.append(net) if 'vid' in pkt: tpid = 0x8100 layers.append(vlan.vlan(vid=pkt['vid'], ethertype=ethertype)) else: tpid = ethertype eth = ethernet.ethernet( dst=pkt['eth_dst'], src=pkt['eth_src'], ethertype=tpid) layers.append(eth) result = packet.Packet() for layer in layers: result.add_protocol(layer) return result
def add_vlan_tag_to_vlan_port(self,dpid,in_port,pkt,src): vlan_tag=vlanid[dpid-1][in_port-1] pkt.add_protocol(vlan.vlan(vid=vlan_tag, ethertype=ether.ETH_TYPE_8021Q)) print" added vlan id" self.vlan_to_port[dpid][vlan_tag][src] = in_port print 'vlan_to_port:',self.vlan_to_port
def build_pkt(pkt): layers = [] if 'arp_target_ip' in pkt: ethertype = 0x806 layers.append(arp.arp(dst_ip=pkt['arp_target_ip'])) elif 'ipv6_src' in pkt: ethertype = 0x86DD layers.append(ipv6.ipv6(src=pkt['ipv6_src'], dst=pkt['ipv6_src'])) else: ethertype = 0x800 if 'ipv4_src' in pkt: net = ipv4.ipv4(src=pkt['ipv4_src'], dst=pkt['ipv4_dst']) else: net = ipv4.ipv4() layers.append(net) if 'vid' in pkt: tpid = 0x8100 layers.append(vlan.vlan(vid=pkt['vid'], ethertype=ethertype)) else: tpid = ethertype eth = ethernet.ethernet(dst=pkt['eth_dst'], src=pkt['eth_src'], ethertype=tpid) layers.append(eth) result = packet.Packet() for layer in layers: result.add_protocol(layer) return result
def assemble_tcp(self, content, vlanid, dst_ip, dst_mac, src_ip, src_mac, dport, sport=61300): offset = ethernet.ethernet._MIN_LEN if vlanid != 0: ether_proto = ether.ETH_TYPE_8021Q vlan_ether = ether.ETH_TYPE_IP v = vlan.vlan(0, 0, vlanid, vlan_ether) offset += vlan.vlan._MIN_LEN else: ether_proto = ether.ETH_TYPE_IP pkt = packet.Packet() if vlanid != 0: pkt.add_protocol(v) # Add ethernet protocol with ether type IP protocol and mac addresses pkt.add_protocol(ethernet.ethernet(ethertype=ether_proto, dst=dst_mac, src=src_mac)) # Add ipv4 protocol with IP addresses and TCP protocol which is 6 pkt.add_protocol(ipv4.ipv4(dst=dst_ip, src=src_ip, proto=6)) # Add tcp protocol with port numbers and sequence number pkt.add_protocol(tcp.tcp(src_port=sport, dst_port=dport)) pkt.add_protocol(bytearray(content)) return pkt
def send_arp(self, arp_opcode, vlan_id, src_mac, dst_mac, src_ip, dst_ip, arp_target_mac, in_port, output): # Generate ARP packet if vlan_id != VLANID_NONE: ether_proto = ether.ETH_TYPE_8021Q pcp = 0 cfi = 0 vlan_ether = ether.ETH_TYPE_ARP v = vlan.vlan(pcp, cfi, vlan_id, vlan_ether) else: ether_proto = ether.ETH_TYPE_ARP hwtype = 1 arp_proto = ether.ETH_TYPE_IP hlen = 6 plen = 4 pkt = packet.Packet() e = ethernet.ethernet(dst_mac, src_mac, ether_proto) a = arp.arp(hwtype, arp_proto, hlen, plen, arp_opcode, src_mac, src_ip, arp_target_mac, dst_ip) pkt.add_protocol(e) if vlan_id != VLANID_NONE: pkt.add_protocol(v) pkt.add_protocol(a) pkt.serialize() # Send packet out self.send_packet_out(in_port, output, pkt.data, data_str=str(pkt))
def generate_trace_pkt(entries, color, r_id): ''' Receives the REST/PUT to generate a PacketOut data needs to be serialized template_trace.json is an example ''' trace = {} switch = {} eth = {} ip = {} tp = {} # TODO Validate for dl_vlan. If empty, return error. dpid, in_port = 0, 65532 dl_src, dl_dst = "ca:fe:ca:fe:00:00", "ca:fe:ca:fe:ca:fe" dl_vlan, dl_type = 100, 2048 nw_src, nw_dst, nw_tos = '127.0.0.1', '127.0.0.1', 0 tp_src, tp_dst = 1, 1 try: trace = entries['trace'] switch = trace['switch'] eth = trace['eth'] ip = trace['ip'] tp = trace['tp'] except: pass if len(switch) > 0: dpid, in_port = prepare_switch(switch, dpid, in_port) if len(eth) > 0: dl_src, dl_dst, dl_vlan, dl_type = prepare_ethernet(eth, dl_src, dl_dst, dl_vlan, dl_type) if len(ip) > 0: nw_src, nw_dst, nw_tos = prepare_ip(ip, nw_src, nw_dst, nw_tos) if len(tp) > 0: tp_src, tp_dst = prepare_tp(tp, tp_src, tp_dst) pkt = packet.Packet() eth_pkt = ethernet.ethernet(dst=dl_dst, src=dl_src, ethertype=33024) vlan_pkt = vlan.vlan(vid=dl_vlan, ethertype=dl_type, pcp=int(color, 2)) pkt.add_protocol(eth_pkt) pkt.add_protocol(vlan_pkt) if dl_type == 2048: ip_pkt = ipv4.ipv4(dst=str(nw_dst), src=str(nw_src), tos=nw_tos, proto=6) pkt.add_protocol(ip_pkt) tp_pkt = tcp.tcp(dst_port=tp_dst, src_port=tp_src) pkt.add_protocol(tp_pkt) data = str(r_id) # this will be the ID pkt.add_protocol(data) pkt.serialize() return in_port, pkt
def match_to_packet(self, match): pkt = packet.Packet() l2 = ethernet.ethernet( dst=match.setdefault('eth_dst', "00:00:00:00:00:02"), src=match.setdefault('eth_src', "00:00:00:00:00:01"), ethertype=match.setdefault('eth_type', 0x800) ) pkt.add_protocol(l2) if 'vlan_vid' in match: pkt.get_protocol(ethernet.ethernet).ethertype=0x8100 vl = vlan.vlan( pcp=0, cfi=0, vid=match['vlan_vid'], ethertype=match['eth_type'] ) pkt.add_protocol(vl) l3 = ipv4.ipv4( src=match.setdefault('ipv4_src', "192.168.1.1"), dst=match.setdefault('ipv4_dst', "192.168.1.2") ) pkt.add_protocol(l3) l4 = tcp.tcp( src_port=match.setdefault('tcp_src', 12345), dst_port=match.setdefault('tcp_dst', 80) ) pkt.add_protocol(l4) pkt.serialize() return pkt
def _build_itag(self): b_src_mac = '00:07:0d:af:f4:54' b_dst_mac = '00:00:00:00:00:00' b_ethertype = ether.ETH_TYPE_8021AD e1 = ethernet.ethernet(b_dst_mac, b_src_mac, b_ethertype) b_pcp = 0 b_cfi = 0 b_vid = 32 b_ethertype = ether.ETH_TYPE_8021Q bt = vlan.svlan(b_pcp, b_cfi, b_vid, b_ethertype) c_src_mac = '11:11:11:11:11:11' c_dst_mac = 'aa:aa:aa:aa:aa:aa' c_ethertype = ether.ETH_TYPE_8021AD e2 = ethernet.ethernet(c_dst_mac, c_src_mac, c_ethertype) s_pcp = 0 s_cfi = 0 s_vid = 32 s_ethertype = ether.ETH_TYPE_8021Q st = vlan.svlan(s_pcp, s_cfi, s_vid, s_ethertype) c_pcp = 0 c_cfi = 0 c_vid = 32 c_ethertype = ether.ETH_TYPE_IP ct = vlan.vlan(c_pcp, c_cfi, c_vid, c_ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = '131.151.32.21' dst = '131.151.32.129' option = 'TEST' ip = ipv4.ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = packet.Packet() p.add_protocol(e1) p.add_protocol(bt) p.add_protocol(self.it) p.add_protocol(e2) p.add_protocol(st) p.add_protocol(ct) p.add_protocol(ip) p.serialize() return p
def create_packet(self, vid, mld): self.logger.debug("") # VLAN vln = vlan.vlan(vid=vid, ethertype=ether.ETH_TYPE_IPV6) # Hop-By-Hop ext_headers = [ipv6.hop_opts(nxt=inet.IPPROTO_ICMPV6, data=[ ipv6.option(type_=5, len_=2, data="\x00\x00"), ipv6.option(type_=1, len_=0)])] # MLDV2_Query if type(mld) == icmpv6.mldv2_query: eth_dst = self.QUERY_DST ip_dst = self.QUERY_DST_IP if mld.address != "::": ip_str = netaddr.ip.IPAddress(mld.address).\ format(netaddr.ipv6_verbose()) eth_dst = "33:33:" + ip_str[30:32] + ":" + \ ip_str[32:34] + ":" + ip_str[35:37] + ":" + ip_str[37:39] ip_dst = mld.address # ETHER eth = ethernet.ethernet( ethertype=ether.ETH_TYPE_8021Q, src=self.ifinfo[self.IF_KEY_MAC], dst=eth_dst) # IPV6 with ExtensionHeader ip6 = ipv6.ipv6( src=self.ifinfo[self.IF_KEY_IP6], dst=ip_dst, hop_limit=1, nxt=inet.IPPROTO_HOPOPTS, ext_hdrs=ext_headers) # MLD Query icmp6 = icmpv6_extend( type_=icmpv6.MLD_LISTENER_QUERY, data=mld) # MLDV2_Report elif type(mld) == icmpv6.mldv2_report: # ETHER eth = ethernet.ethernet( ethertype=ether.ETH_TYPE_8021Q, src=self.ifinfo[self.IF_KEY_MAC], dst=self.REPORT_DST) # IPV6 with ExtensionHeader ip6 = ipv6.ipv6( src=self.ifinfo[self.IF_KEY_IP6], dst=self.REPORT_DST_IP, hop_limit=1, nxt=inet.IPPROTO_HOPOPTS, ext_hdrs=ext_headers) # MLD Report icmp6 = icmpv6_extend( type_=icmpv6.MLDV2_LISTENER_REPORT, data=mld) # ether - vlan - ipv6 - icmpv6 ( - mldv2 ) sendpkt = eth / vln / ip6 / icmp6 sendpkt.serialize() self.logger.debug("created packet(ryu) : %s", str(sendpkt)) return sendpkt
def SetVlanTag(self, ev, datapath, in_port): dpid = datapath.id vlan_tag = port_vlan[dpid - 1][in_port - 1] msg = ev.msg pkt = packet.Packet(msg.data) pkt.add_protocol( vlan.vlan(vid=vlan_tag, ethertype=ether.ETH_TYPE_8021Q)) print "add vlan tag" return pkt
def createPacket(self, src, dst, srcip, dstip): # create send packet sendpkt = packet.Packet() sendpkt.add_protocol(ethernet.ethernet(ethertype=ether.ETH_TYPE_8021Q, dst=dst, src=src)) sendpkt.add_protocol(vlan.vlan(pcp=0, cfi=0, vid=100, ethertype=ether.ETH_TYPE_IPV6)) sendpkt.add_protocol(ipv6.ipv6(src=srcip, dst=dstip, nxt=inet.IPPROTO_ICMPV6)) sendpkt.add_protocol(icmpv6.icmpv6(type_=icmpv6.ICMPV6_MEMBERSHIP_QUERY, data=icmpv6.mldv2_query(address='ff38::1'))) sendpkt.serialize() return sendpkt
def _handle_arp(self, datapath, in_port, vlan_id, eth_pkt, vlan_pkt, arp_pkt): # check if it is an arp request if arp_pkt.opcode != arp.ARP_REQUEST: return # variable population arp_dst_ip = arp_pkt.dst_ip arp_src_mac = arp_pkt.src_mac arp_src_ip = arp_pkt.src_ip vlan_exist = False print(in_port, vlan_id, arp_src_ip, arp_dst_ip, arp_src_mac) # save SRC IP and MAC for later use for i in range(len(self.vlan_src_ip_mac)): if vlan_id == self.vlan_src_ip_mac[i]['vlan']: vlan_exist = True break if vlan_exist == False: self.vlan_src_ip_mac.append({ "vlan": vlan_id, "MAC": arp_src_mac, "IP": arp_src_ip }) self.logger.info( "SRC_MAC_IP_VLAN table has been updated! = {0}".format( self.vlan_src_ip_mac)) # create ARP Response if arp_dst_ip == HOST_IP: # create ethernet pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=ether.ETH_TYPE_8021Q, dst=arp_src_mac, src=HOST_MAC)) # add vlan tag pkt.add_protocol( vlan.vlan(vid=vlan_id, ethertype=ether.ETH_TYPE_ARP)) #add arp header pkt.add_protocol( arp.arp(proto=0x0800, opcode=arp.ARP_REPLY, src_ip=arp_dst_ip, dst_ip=arp_src_ip, src_mac=HOST_MAC, dst_mac=arp_src_mac)) self._send_packet(datapath, in_port, pkt) else: return
def test_pkt_in_filter_pass(self): datapath = ProtocolDesc(version=ofproto_v1_3.OFP_VERSION) e = ethernet.ethernet(mac.BROADCAST_STR, mac.BROADCAST_STR, ether.ETH_TYPE_8021Q) v = vlan.vlan() i = ipv4.ipv4() pkt = (e / v / i) pkt.serialize() pkt_in = ofproto_v1_3_parser.OFPPacketIn(datapath, data=buffer(pkt.data)) ev = ofp_event.EventOFPPacketIn(pkt_in) ok_(self.app.packet_in_handler(ev))
def build_pkt(pkt): """Build and return a packet and eth type from a dict.""" layers = [] assert 'eth_dst' in pkt and 'eth_src' in pkt ethertype = None if 'arp_source_ip' in pkt and 'arp_target_ip' in pkt: ethertype = ether.ETH_TYPE_ARP layers.append( arp.arp(src_ip=pkt['arp_source_ip'], dst_ip=pkt['arp_target_ip'])) elif 'ipv6_src' in pkt and 'ipv6_dst' in pkt: ethertype = ether.ETH_TYPE_IPV6 if 'neighbor_solicit_ip' in pkt: layers.append( icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor( dst=pkt['neighbor_solicit_ip'], option=icmpv6.nd_option_sla(hw_src=pkt['eth_src'])))) elif 'echo_request_data' in pkt: layers.append( icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REQUEST, data=icmpv6.echo(id_=1, seq=1, data=pkt['echo_request_data']))) layers.append( ipv6.ipv6(src=pkt['ipv6_src'], dst=pkt['ipv6_dst'], nxt=inet.IPPROTO_ICMPV6)) elif 'ipv4_src' in pkt and 'ipv4_dst' in pkt: ethertype = ether.ETH_TYPE_IP proto = inet.IPPROTO_IP if 'echo_request_data' in pkt: echo = icmp.echo(id_=1, seq=1, data=pkt['echo_request_data']) layers.append(icmp.icmp(type_=icmp.ICMP_ECHO_REQUEST, data=echo)) proto = inet.IPPROTO_ICMP net = ipv4.ipv4(src=pkt['ipv4_src'], dst=pkt['ipv4_dst'], proto=proto) layers.append(net) assert ethertype is not None, pkt if 'vid' in pkt: tpid = ether.ETH_TYPE_8021Q layers.append(vlan.vlan(vid=pkt['vid'], ethertype=ethertype)) else: tpid = ethertype eth = ethernet.ethernet(dst=pkt['eth_dst'], src=pkt['eth_src'], ethertype=tpid) layers.append(eth) layers = [layer for layer in reversed(layers)] result = packet.Packet() for layer in layers: result.add_protocol(layer) result.serialize() return (result, ethertype)
def test_pkt_in_filter_pass(self): datapath = ProtocolDesc(version=ofproto_v1_3.OFP_VERSION) e = ethernet.ethernet(mac.BROADCAST_STR, mac.BROADCAST_STR, ether.ETH_TYPE_8021Q) v = vlan.vlan() i = ipv4.ipv4() pkt = (e / v / i) pkt.serialize() pkt_in = ofproto_v1_3_parser.OFPPacketIn(datapath, data=six.binary_type(pkt.data)) ev = ofp_event.EventOFPPacketIn(pkt_in) ok_(self.app.packet_in_handler(ev))
def test_pkt_in_filter_pass(self): datapath = _Datapath() e = ethernet.ethernet(mac.BROADCAST_STR, mac.BROADCAST_STR, ether.ETH_TYPE_8021Q) v = vlan.vlan() i = ipv4.ipv4() pkt = (e / v / i) pkt.serialize() pkt_in = ofproto_v1_3_parser.OFPPacketIn(datapath, data=buffer(pkt.data)) ev = ofp_event.EventOFPPacketIn(pkt_in) ok_(self.app.packet_in_handler(ev))
def build_ethernet_pkt(self, eth_dst, in_port, vlan, ethertype): pkt = packet.Packet() if vlan.port_is_tagged(in_port): eth_pkt = ethernet.ethernet( eth_dst, self.FAUCET_MAC, ether.ETH_TYPE_8021Q) vlan_pkt = packet_vlan.vlan( vid=vlan.vid, ethertype=ethertype) pkt.add_protocol(eth_pkt) pkt.add_protocol(vlan_pkt) else: eth_pkt = ethernet.ethernet( eth_dst, self.FAUCET_MAC, ethertype) pkt.add_protocol(eth_pkt) return pkt
def create_packet(self, primary_ip_address, vlan_id=None): """Prepare a VRRP packet. Returns a newly created ryu.lib.packet.packet.Packet object with appropriate protocol header objects added by add_protocol(). It's caller's responsibility to serialize(). The serialized packet would looks like the ones described in the following sections. * RFC 3768 5.1. VRRP Packet Format * RFC 5798 5.1. VRRP Packet Format ================== ==================== Argument Description ================== ==================== primary_ip_address Source IP address vlan_id VLAN ID. None for no VLAN. ================== ==================== """ if self.is_ipv6: traffic_class = 0xc0 # set tos to internetwork control flow_label = 0 payload_length = ipv6.ipv6._MIN_LEN + len(self) # XXX _MIN_LEN e = ethernet.ethernet(VRRP_IPV6_DST_MAC_ADDRESS, vrrp_ipv6_src_mac_address(self.vrid), ether.ETH_TYPE_IPV6) ip = ipv6.ipv6(6, traffic_class, flow_label, payload_length, inet.IPPROTO_VRRP, VRRP_IPV6_HOP_LIMIT, primary_ip_address, VRRP_IPV6_DST_ADDRESS) else: header_length = ipv4.ipv4._MIN_LEN / 4 # XXX _MIN_LEN total_length = 0 tos = 0xc0 # set tos to internetwork control identification = self.get_identification() e = ethernet.ethernet(VRRP_IPV4_DST_MAC_ADDRESS, vrrp_ipv4_src_mac_address(self.vrid), ether.ETH_TYPE_IP) ip = ipv4.ipv4(4, header_length, tos, total_length, identification, 0, 0, VRRP_IPV4_TTL, inet.IPPROTO_VRRP, 0, primary_ip_address, VRRP_IPV4_DST_ADDRESS) p = packet.Packet() p.add_protocol(e) if vlan_id is not None: vlan_ = vlan.vlan(0, 0, vlan_id, e.ethertype) e.ethertype = ether.ETH_TYPE_8021Q p.add_protocol(vlan_) p.add_protocol(ip) p.add_protocol(self) return p
def encapsulate_dot1q(self, pkt, tag): eth = pkt.get_protocol(ethernet.ethernet) if not eth: return e = pkt.protocols.pop(0) assert (eth == e) eth_rep = ethernet.ethernet(ethertype=ether_types.ETH_TYPE_8021Q, dst=eth.dst, src=eth.src) vlan_rep = vlan.vlan(vid=tag, ethertype=eth.ethertype) pkt.protocols.insert(0, eth_rep) pkt.protocols.insert(1, vlan_rep) pkt.serialize() return pkt
def _handle_arp(self, datapath, port, pkt_ethernet, pkt_arp, pkt_vlan): if pkt_arp.opcode != arp.ARP_REQUEST: return # check for dst_ip's matching MAC # dst_mac = pkt_ethernet.dst #unknown value src_mac = pkt_ethernet.src dst_ip = pkt_arp.dst_ip src_ip = pkt_arp.src_ip dpid = datapath.id self.ip_to_mac.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src_mac, dst_mac, port) # learn mac address to avoid DROP. self.ip_to_mac[dpid][src_ip] = src_mac if dst_ip in self.ip_to_mac[dpid]: dst_mac = self.ip_to_mac[dpid][dst_ip] else: # Requested MAC address is unknown. # There is nothing we can do without flood. return # build arp reply # pkt = packet.Packet() e = ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=src_mac, src=dst_mac) v = vlan.vlan(pcp=pkt_vlan.pcp, cfi=pkt_vlan.cfi, vid=pkt_vlan.vid, ethertype=pkt_vlan.ethertype) a = arp.arp(opcode=arp.ARP_REPLY, src_mac=dst_mac, src_ip=dst_ip, dst_mac=src_mac, dst_ip=src_ip) pkt.add_protocol(e) pkt.add_protocol(v) pkt.add_protocol(a) self._send_packet(datapath, port, pkt)
def _build_arp(self, vlan_enabled): if vlan_enabled is True: ethertype = ether.ETH_TYPE_8021Q v = vlan(1, 1, 3, ether.ETH_TYPE_ARP) else: ethertype = ether.ETH_TYPE_ARP e = ethernet(self.dst_mac, self.src_mac, ethertype) p = Packet() p.add_protocol(e) if vlan_enabled is True: p.add_protocol(v) p.add_protocol(self.a) p.serialize() return p
def may_add_vlan(packet, vlan_id): """ :type packet: ryu.lib.packet.packet.Packet :param packet: :type vlan_id: int (0 <= vlan_id <= 4095) or None (= No VLAN) :param vlan_id: """ if vlan_id is None: return e = packet.protocols[0] assert isinstance(e, ethernet.ethernet) v = vlan.vlan(0, 0, vlan_id, e.ethertype) e.ethertype = ether.ETH_TYPE_8021Q packet.add_protocol(v)
def Set_Trunk_Vlan(self, ev, datapath, in_port, src): dpid = datapath.id msg = ev.msg pkt = packet.Packet(msg.data) for i in range(0, len(trunk_ports)): if i == dpid - 1: continue else: # search the vlan tag for j in port_vlan[i]: # for the naive vlan print(" the vlan to port is", self.vlan_to_port) print(" the mac to port is", self.mac_to_port) if j != 0: if src in self.vlan_to_port[i + 1][j]: check_port = self.vlan_to_port[i + 1][j][src] vlan_tag = port_vlan[i][check_port - 1] pkt.add_protocol( vlan.vlan(vid=vlan_tag, ethertype=ether.ETH_TYPE_8021Q)) print "add the trunk vlan tag" # dpid = i + 1 # src_vlan = j record_ij[0] = i + 1 record_ij[1] = j return pkt # for the normal else: if src in self.mac_to_port[i + 1]: check_port = self.mac_to_port[i + 1][src] vlan_tag = 0 pkt.add_protocol( vlan.vlan(vid=vlan_tag, ethertype=ether.ETH_TYPE_8021Q)) print "add the trunk normal tag" return pkt
def send_arp(self, arp_opcode, vlan_id, dst_mac, sender_mac, sender_ip, target_ip, target_mac, src_port, output_port): """ Generate an ARP packet and send it Arguments: arp_opcode -- Opcode for message vlan_id -- VLAN identifier, or VLANID_NONE dst_mac -- Destination to send the packet (not an ARP field) sender_mac -- Sender hardware address sender_ip -- Sender protocol address target_mac -- Target hardware address target_ip -- Target protocol address src_port -- Source port number for sending message (can be OFPP_CONTROLLER) output_port -- Outgoing port number to send message """ if vlan_id != VLANID_NONE: ether_proto = ether.ETH_TYPE_8021Q pcp = 0 cfi = 0 vlan_ether = ether.ETH_TYPE_ARP v = vlan.vlan(pcp, cfi, vlan_id, vlan_ether) else: ether_proto = ether.ETH_TYPE_ARP hwtype = 1 arp_proto = ether.ETH_TYPE_IP hlen = 6 plen = 4 pkt = packet.Packet() e = ethernet.ethernet(dst_mac, sender_mac, ether_proto) a = arp.arp(hwtype, arp_proto, hlen, plen, arp_opcode, sender_mac, sender_ip, target_mac, target_ip) pkt.add_protocol(e) if vlan_id != VLANID_NONE: pkt.add_protocol(v) pkt.add_protocol(a) pkt.serialize() print(sender_mac) print(sender_ip) print(target_mac) print(target_ip) # Send packet out self.send_packet_out(src_port, output_port, pkt.data, data_str=str(pkt))
def send_tcp_pke(self, datapath, port, vlan_id, dst_ip, src_ip, src_mac, dst_mac, dport, sport=61300): seq = 0 ack = 0 offset = 6 window_size = 8192 urgent = 0 option = [tcp.TCPOptionWindowScale(shift_cnt=9), tcp.TCPOptionSACKPermitted(length=2), tcp.TCPOptionTimestamps(ts_val=287454020, ts_ecr=1432778632)] if vlan_id != 0: ether_proto = ether.ETH_TYPE_8021Q vlan_ether = ether.ETH_TYPE_IP v = vlan.vlan(0, 0, vlan_id, vlan_ether) offset += vlan.vlan._MIN_LEN else: ether_proto = ether.ETH_TYPE_IP pkt = packet.Packet() # Add ethernet protocol with ether type IP protocol and mac addresses pkt.add_protocol(ethernet.ethernet(ethertype=ether_proto, dst=dst_mac, src=src_mac)) # Add ipv4 protocol with IP addresses and TCP protocol which is 6 ipv4_pkt = ipv4.ipv4(dst=dst_ip, src=src_ip, proto=6, flags=2) pkt.add_protocol(ipv4_pkt) # Add tcp protocol with port numbers and sequence number tcp_pkt = tcp.tcp(src_port=sport, dst_port=dport, seq=seq, ack=ack, offset=offset, bits=tcp.TCP_SYN, window_size=window_size, urgent=urgent, option=option) tcp_pkt.has_flags(tcp.TCP_SYN) pkt.add_protocol(tcp_pkt) if vlan_id != 0: pkt.add_protocol(v) self._send_packet(datapath, pkt, port)
def assemble_arp(self, opcode, src_mac, src_ip, dst_ip, vlan_id=0): pkt = packet.Packet() offset = ethernet.ethernet._MIN_LEN if int(vlan_id) != 0: ether_proto = ether.ETH_TYPE_8021Q vlan_ether = ether.ETH_TYPE_ARP v = vlan.vlan(0, 0, int(vlan_id), vlan_ether) offset += vlan.vlan._MIN_LEN else: ether_proto = ether.ETH_TYPE_ARP e = ethernet.ethernet('ff:ff:ff:ff:ff:ff', src_mac, ether_proto) a = arp.arp(1, 0x0800, 6, 4, opcode, src_mac, src_ip, '00:00:00:00:00:00', dst_ip) if int(vlan_id) != 0: pkt.add_protocol(v) pkt.add_protocol(e) pkt.add_protocol(a) return pkt
def packet_in_handler(self, event): if event.msg.match['in_port'] != FAKEPORT: return pkt = packet.Packet(event.msg.data) eth_protocol = pkt.get_protocol(ethernet.ethernet) vlan_protocol = pkt.get_protocol(vlan.vlan) ipv6_protocol = pkt.get_protocol(ipv6.ipv6) icmpv6_protocol = pkt.get_protocol(icmpv6.icmpv6) if not (eth_protocol and vlan_protocol and ipv6_protocol and icmpv6_protocol): return if icmpv6_protocol.type_ != icmpv6.ND_NEIGHBOR_SOLICIT: return if int(ipaddress.ip_address(ipv6_protocol.src)) == 0: return src_ip = ipaddress.ip_address(icmpv6_protocol.data.dst) if src_ip.is_reserved: return eth_dst = eth_protocol.src dst_ip = ipv6_protocol.src eth_src = FAKECLIENTMAC vid = vlan_protocol.vid reply = packet.Packet() for protocol in (ethernet.ethernet(eth_dst, eth_src, ether.ETH_TYPE_8021Q), vlan.vlan(vid=vid, ethertype=ether.ETH_TYPE_IPV6), ipv6.ipv6(src=src_ip, dst=dst_ip, nxt=socket.IPPROTO_ICMPV6, hop_limit=255), icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor( dst=src_ip, option=icmpv6.nd_option_tla(hw_src=eth_src), res=7))): reply.add_protocol(protocol) reply.serialize() out = parser.OFPPacketOut(datapath=event.msg.datapath, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=[parser.OFPActionOutput(FAKEPORT)], data=reply.data) self.send_mods(event.msg.datapath, [out])
def prepare_lldp_packet(node, port, vlan_id): """ Prepare the LLDP frame to be used by PacketOut Args: node: destination node port: destination port vlan_id: vlan tag to be added to pkt Returns: an Ethernet+LLDP frame (data field of PacketOut) """ pkt = packet.Packet() # Generate Ethernet frame dst = lldp.LLDP_MAC_NEAREST_BRIDGE src = 'ca:fe:ca:fe:ca:fe' vlan_pkt = None if vlan_id > 1: ethertype = ether.ETH_TYPE_8021Q vlan_pkt = vlan.vlan(vid=vlan_id, ethertype=ether.ETH_TYPE_LLDP) else: ethertype = ether.ETH_TYPE_LLDP eth_pkt = ethernet.ethernet(dst, src, ethertype) pkt.add_protocol(eth_pkt) if vlan_id > 1: pkt.add_protocol(vlan_pkt) # Generate LLDP packet dp = '%016x' % node.dpid chassis_subtype = lldp.ChassisID.SUB_LOCALLY_ASSIGNED tlv_chassis_id = lldp.ChassisID(subtype=chassis_subtype, chassis_id=dp) tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_PORT_COMPONENT, port_id=(b'%s' % port)) tlv_ttl = lldp.TTL(ttl=120) tlv_end = lldp.End() tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end) lldp_pkt = lldp.lldp(tlvs) pkt.add_protocol(lldp_pkt) pkt.serialize() return pkt
def build_udp(self): #dst = '1' * 6 dst = '00:00:00:00:00:01' src = '00:00:00:00:00:02' ethertype = ether.ETH_TYPE_8021Q e = ethernet.ethernet(dst, src, ethertype) v = vlan.vlan(1, 1, 3, ether.ETH_TYPE_IP) ip = ipv4.ipv4(4, 5, 0, 0, 0, 0, 0, 255, 17, 33, '192.168.1.1', '192.168.1.11') u = udp.udp(12, 34, 0) p = packet.Packet() p.add_protocol(e) p.add_protocol(v) p.add_protocol(ip) p.add_protocol(u) #data content p.add_protocol("123456789") p.serialize() return p
def lldp_packet(dpid, port_no, dl_addr, ttl, vlan_vid): # by jesse : add vlan if vlan_vid != VLANID_NONE: ether_proto = ETH_TYPE_8021Q pcp = 0 cfi = 0 vlan_ether = ETH_TYPE_LLDP v = vlan.vlan(pcp, cfi, vlan_vid, vlan_ether) dst = lldp.LLDP_MAC_NEAREST_BRIDGE src = dl_addr pkt = packet.Packet() e = ethernet.ethernet(dst, src, ether_proto) pkt.add_protocol(e) pkt.add_protocol(v) else: pkt = packet.Packet() dst = lldp.LLDP_MAC_NEAREST_BRIDGE src = dl_addr ethertype = ETH_TYPE_LLDP eth_pkt = ethernet.ethernet(dst, src, ethertype) pkt.add_protocol(eth_pkt) tlv_chassis_id = lldp.ChassisID( subtype=lldp.ChassisID.SUB_LOCALLY_ASSIGNED, chassis_id=LLDPPacket.CHASSIS_ID_FMT % dpid_to_str(dpid)) tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_PORT_COMPONENT, port_id=struct.pack( LLDPPacket.PORT_ID_STR, port_no)) tlv_ttl = lldp.TTL(ttl=ttl) tlv_end = lldp.End() tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end) lldp_pkt = lldp.lldp(tlvs) pkt.add_protocol(lldp_pkt) pkt.serialize() return pkt.data
def build_pkt_header(vid, eth_src, eth_dst, dl_type): """Return an Ethernet packet header. Args: vid (int or None): VLAN VID to use (or None). eth_src (str): source Ethernet MAC address. eth_dst (str): destination Ethernet MAC address. dl_type (int): EtherType. Returns: ryu.lib.packet.ethernet: Ethernet packet with header. """ pkt_header = packet.Packet() if vid is None: eth_header = ethernet.ethernet(eth_dst, eth_src, dl_type) pkt_header.add_protocol(eth_header) else: eth_header = ethernet.ethernet(eth_dst, eth_src, ether.ETH_TYPE_8021Q) pkt_header.add_protocol(eth_header) vlan_header = vlan.vlan(vid=vid, ethertype=dl_type) pkt_header.add_protocol(vlan_header) return pkt_header
def test_smoke_packet_in(self): nd_solicit = packet.Packet() eth_src = '01:02:03:04:05:06' eth_dst = 'ff:ff:ff:ff:ff:ff' src_ip = 'fc00::1' dst_ip = 'fc00::2' vid = 2 for protocol in ( ethernet.ethernet(eth_dst, eth_src, ether.ETH_TYPE_8021Q), vlan.vlan(vid=vid, ethertype=ether.ETH_TYPE_IPV6), ipv6.ipv6(src=src_ip, dst=dst_ip, nxt=socket.IPPROTO_ICMPV6, hop_limit=255), icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor(dst=src_ip, option=icmpv6.nd_option_tla(hw_src=eth_src), res=7))): nd_solicit.add_protocol(protocol) nd_solicit.serialize() fake_dp = FakeDP() fake_pipette = Pipette(dpset={}) class FakeMsg: def __init__(self): self.datapath = fake_dp self.match = {'in_port': FAKEPORT} self.data = nd_solicit.data class FakePiEv: def __init__(self): self.msg = FakeMsg() fake_pipette = Pipette(dpset={}) fake_pipette.packet_in_handler(FakePiEv()) assert fake_dp.msgs
def _build_svlan(self): src_mac = '00:07:0d:af:f4:54' dst_mac = '00:00:00:00:00:00' ethertype = ether.ETH_TYPE_8021AD e = ethernet(dst_mac, src_mac, ethertype) pcp = 0 cfi = 0 vid = 32 tci = pcp << 15 | cfi << 12 | vid ethertype = ether.ETH_TYPE_IP v = vlan(pcp, cfi, vid, ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = '131.151.32.21' dst = '131.151.32.129' option = 'TEST' ip = ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = Packet() p.add_protocol(e) p.add_protocol(self.sv) p.add_protocol(v) p.add_protocol(ip) p.serialize() return p
def _build_svlan(self): src_mac = '00:07:0d:af:f4:54' dst_mac = '00:00:00:00:00:00' ethertype = ether.ETH_TYPE_8021AD e = ethernet(dst_mac, src_mac, ethertype) pcp = 0 cfi = 0 vid = 32 tci = pcp << 15 | cfi << 12 | vid ethertype = ether.ETH_TYPE_IP v = vlan(pcp, cfi, vid, ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = '131.151.32.21' dst = '131.151.32.129' option = b'TEST' ip = ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = Packet() p.add_protocol(e) p.add_protocol(self.sv) p.add_protocol(v) p.add_protocol(ip) p.serialize() return p
def assemble_icmp(self, vlanid, dst_ip, dst_mac, src_ip, src_mac, csum, identification): offset = ethernet.ethernet._MIN_LEN if vlanid != 0: ether_proto = ether.ETH_TYPE_8021Q vlan_ether = ether.ETH_TYPE_IP v = vlan.vlan(0, 0, vlanid, vlan_ether) offset += vlan.vlan._MIN_LEN else: ether_proto = ether.ETH_TYPE_IP pkt = packet.Packet() if vlanid != 0: pkt.add_protocol(v) pkt.add_protocol(ethernet.ethernet(ethertype=ether_proto, dst=dst_mac, src=src_mac)) pkt.add_protocol(ipv4.ipv4(dst=dst_ip, src=src_ip, csum=csum, identification=identification, total_length=60, ttl=127, proto=1)) return pkt
def encode_in_place(self, pyr, pkt): if (not 'vlan_id' in pyr and not 'vlan_pcp' in pyr and vlan.vlan in pkt): for idx, proto in enumerate(pkt.protocols): if isinstance(proto, vlan.vlan): pkt.protocols.pop(idx) return pyr if not 'vlan_id' in pyr: return pyr if not vlan.vlan in pkt: pkt.protocols.insert( 1, vlan.vlan(ethertype=pkt.protocols[0].ethertype)) gen = (protocol for protocol in pkt.protocols if protocol.__class__ == vlan.vlan) vl = gen.next() vl.vid = pyr['vlan_id'] pkt.protocols[0].ethertype = VLAN return pyr
def build_pkt_header(eth_src, eth_dst, vid, dl_type): """Return an Ethernet packet header. Args: eth_src (str): source Ethernet MAC address. eth_dst (str): destination Ethernet MAC address. vid (int or None): VLAN VID to use (or None) dl_type (int): EtherType. Returns: ryu.lib.packet.ethernet: Ethernet packet with header. """ pkt_header = packet.Packet() if vid is None: eth_header = ethernet.ethernet( eth_dst, eth_src, dl_type) pkt_header.add_protocol(eth_header) else: eth_header = ethernet.ethernet( eth_dst, eth_src, ether.ETH_TYPE_8021Q) pkt_header.add_protocol(eth_header) vlan_header = vlan.vlan(vid=vid, ethertype=dl_type) pkt_header.add_protocol(vlan_header) return pkt_header
def _respond_dhcp(self, datapath, port, pool, pkt_ethernet, pkt_vlan, pkt_ip, pkt_udp, pkt_dhcp): # DHCP message type code options = dict() for option in pkt_dhcp.options.option_list: options[option.tag] = option.value src = pkt_dhcp.chaddr # RESPONSE MSG pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src='00:00:00:00:00:00')) if pkt_vlan: pkt.add_protocol(vlan.vlan(cfi=pkt_vlan.cfi, ethertype=pkt_vlan.ethertype, pcp=pkt_vlan.pcp, vid=pkt_vlan.vid)) pkt.add_protocol(ipv4.ipv4(src=pkt_ip.dst, dst=pkt_ip.src, proto=in_proto.IPPROTO_UDP)) pkt.add_protocol(udp.udp(src_port=pkt_udp.dst_port, dst_port=pkt_udp.src_port)) # DISCOVER MSG dhcp_msg_type = ord(options[dhcp.DHCP_MESSAGE_TYPE_OPT]) if dhcp_msg_type == dhcp.DHCP_DISCOVER: msg_type = dhcp.DHCP_OFFER if src in self.leases: offer = self.leases[src] del self.leases[src] self.offers[src] = offer else: offer = self.offers.get(src) if offer is None: if len(pool) == 0: LOG.error("Out of IP addresses") msg_type = dhcp.DHCP_NAK offer = pool[0] if dhcp.DHCP_REQUESTED_IP_ADDR_OPT in options: wanted_ip = IPAddr(addrconv.ipv4.bin_to_text(options[dhcp.DHCP_REQUESTED_IP_ADDR_OPT].value)) if wanted_ip in pool: offer = wanted_ip pool.remove(offer) self.offers[src] = offer wanted_opts = list() if dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT in options: fmt = "s" * len(options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT]) wanted_opt_set = struct.unpack(fmt, options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT]) for i in wanted_opt_set: wanted_opts.append(ord(i)) option_list = list() option_list.append(dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, chr(msg_type), length=1)) if msg_type is not dhcp.DHCP_NAK: if dhcp.DHCP_SUBNET_MASK_OPT in wanted_opts: option_list.append(dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, addrconv.ipv4.text_to_bin(self.subnet.toStr()), length=4)) if dhcp.DHCP_GATEWAY_ADDR_OPT in wanted_opts and self.router_addr is not None: option_list.append(dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, addrconv.ipv4.text_to_bin(self.router_addr.toStr()), length=4)) if dhcp.DHCP_DNS_SERVER_ADDR_OPT in wanted_opts and self.dns_addr is not None: option_list.append(dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, addrconv.ipv4.text_to_bin(self.dns_addr.toStr()), length=4)) option_list.append(dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT, chr(self.lease_time), length=4)) option_list.append(dhcp.option(dhcp.DHCP_RENEWAL_TIME_OPT, chr(self.lease_time / 2), length=4)) option_list.append(dhcp.option(dhcp.DHCP_REBINDING_TIME_OPT, chr(self.lease_time * 7 / 8), length=4)) resp_options = dhcp.options(option_list=option_list) pkt.add_protocol(dhcp.dhcp(op=self._MSG_TYPE_BOOT_REPLY, chaddr=pkt_dhcp.chaddr, options=resp_options, xid=pkt_dhcp.xid, ciaddr=pkt_dhcp.ciaddr, yiaddr=offer.toStr(), siaddr=self.ip_addr.toStr(), giaddr='0.0.0.0', sname='', boot_file='')) # REQUEST MSG if dhcp_msg_type == dhcp.DHCP_REQUEST: msg_type = dhcp.DHCP_ACK if dhcp.DHCP_REQUESTED_IP_ADDR_OPT not in options: return wanted_ip = IPAddr(addrconv.ipv4.bin_to_text(options[dhcp.DHCP_REQUESTED_IP_ADDR_OPT])) got_ip = None if src in self.leases: if wanted_ip != self.leases[src]: pool.append(self.leases[src]) del self.leases[src] else: got_ip = self.leases[src] if got_ip is None: if src in self.offers: if wanted_ip != self.offers[src]: pool.append(self.offers[src]) del self.offers[src] else: got_ip = self.offers[src] if got_ip is None: if wanted_ip in pool: pool.remove(wanted_ip) got_ip = wanted_ip if got_ip is None: LOG.warn("%s asked for un-offered %s", src, wanted_ip.toStr()) msg_type = dhcp.DHCP_NAK wanted_opts = list() if dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT in options: fmt = "s" * len(options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT]) wanted_opt_set = struct.unpack(fmt, options[dhcp.DHCP_PARAMETER_REQUEST_LIST_OPT]) for i in wanted_opt_set: wanted_opts.append(ord(i)) # DHCP options tag code option_list = list() option_list.append(dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, chr(msg_type), length=1)) if msg_type is not dhcp.DHCP_NAK: if dhcp.DHCP_SUBNET_MASK_OPT in wanted_opts: option_list.append(dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, addrconv.ipv4.text_to_bin(self.subnet.toStr()), length=4)) if dhcp.DHCP_GATEWAY_ADDR_OPT in wanted_opts and self.router_addr is not None: option_list.append(dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, addrconv.ipv4.text_to_bin(self.router_addr.toStr()), length=4)) if dhcp.DHCP_DNS_SERVER_ADDR_OPT in wanted_opts and self.dns_addr is not None: option_list.append(dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, addrconv.ipv4.text_to_bin(self.dns_addr.toStr()), length=4)) option_list.append(dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT, chr(self.lease_time), length=4)) option_list.append(dhcp.option(dhcp.DHCP_RENEWAL_TIME_OPT, chr(self.lease_time / 2), length=4)) option_list.append(dhcp.option(dhcp.DHCP_REBINDING_TIME_OPT, chr(self.lease_time * 7 / 8), length=4)) resp_options = dhcp.options(option_list=option_list) pkt.add_protocol(dhcp.dhcp(op=self._MSG_TYPE_BOOT_REPLY, chaddr=pkt_dhcp.chaddr, options=resp_options, xid=pkt_dhcp.xid, ciaddr=pkt_dhcp.ciaddr, yiaddr=wanted_ip.toStr(), siaddr=self.ip_addr.toStr(), giaddr='0.0.0.0', sname='', boot_file='')) # RELEASE MSG if dhcp_msg_type == dhcp.DHCP_RELEASE: if self.leases.get(src).toStr() != pkt_dhcp.ciaddr: LOG.warn("%s tried to release unleased %s" % (src, pkt_dhcp.ciaddr)) return del self.leases[src] pool.append(pkt_dhcp.ciaddr) LOG.info("%s released %s" % (src, pkt_dhcp.ciaddr)) self._send_dhcp_reply(datapath, port, pkt) return True
def _packet_in_handler(self, ev): self.packet_in_cnt += 1 self.packet_in_cnt_s += 1 msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) # get_protocols(ethernet) pkt_eth = pkt.get_protocols(ethernet.ethernet)[0] self.logger.debug('ethernet= %s ', str(pkt_eth)) dst = pkt_eth.dst src = pkt_eth.src pkt_ipv6 = None pkt_icmpv6 = None if 'ipv6' in self.PROTPCOL: # get_protocols(pkt_ipv6) pkt_ipv6 = pkt.get_protocols(ipv6.ipv6) if 0 < len(pkt_ipv6): self.logger.debug('ipv6= %s', str(pkt_ipv6)) # get_protocols(pkt_icmpv6) pkt_icmpv6 = pkt.get_protocols(icmpv6.icmpv6) if 0 < len(pkt_icmpv6): self.logger.debug('icmpv6= %s icmpv6.ND_NEIGHBOR_SOLICIT = %s' , str(pkt_icmpv6), icmpv6.ND_NEIGHBOR_SOLICIT) if not pkt_icmpv6[0].type_ in [icmpv6.MLDV2_LISTENER_REPORT, icmpv6.ICMPV6_MEMBERSHIP_QUERY]: print "icmpv6.type is " + pkt_icmpv6[0].type return dpid = datapath self.mac_to_port.setdefault(dpid, {}) self.logger.debug('packet in %s %s %s %s %s', dpid, src, dst, in_port, str(self.packet_in_cnt)) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time self.logger.debug('in_port = %s, out_port = %s, OFPP_FLOOD = %s', str(in_port), str(out_port), str(ofproto.OFPP_FLOOD)) if out_port != ofproto.OFPP_FLOOD: if 'eth' in self.PROTPCOL: # match match = parser.OFPMatch(in_port=in_port, eth_dst=dst ) #miss match match = parser.OFPMatch(in_port=in_port, eth_type=0, eth_dst=dst ) elif 'ipv6' in self.PROTPCOL: match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IPV6, ip_proto=inet.IPPROTO_ICMPV6, ipv6_dst=dst) self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data # create send packet sendpkt = packet.Packet() sendpkt.add_protocol(ethernet.ethernet(ethertype=ether.ETH_TYPE_8021Q, dst=dst, src=src)) sendpkt.add_protocol(vlan.vlan(pcp=0, cfi=0, vid=100, ethertype=ether.ETH_TYPE_IPV6)) sendpkt.add_protocol(ipv6.ipv6(src=pkt_ipv6[0].src, dst=pkt_ipv6[0].dst, nxt=inet.IPPROTO_ICMPV6)) sendpkt.add_protocol(icmpv6.icmpv6(type_=icmpv6.ICMPV6_MEMBERSHIP_QUERY, data=icmpv6.mldv2_query(address='::'))) sendpkt.serialize() self.logger.debug("******** create packet :\n %s" % (sendpkt,)) print "\n" data = sendpkt.data #out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) out = parser.OFPPacketOut(datapath=datapath, buffer_id=0xffffffff, in_port=in_port, actions=actions, data=data) self.logger.debug("******** send :\n datapath : %s,\n in_port : %s,\n" \ % (str(datapath), str(in_port))) datapath.send_msg(out) """
def _packet_in_handler(self, ev): self.packet_in_cnt += 1 self.packet_in_cnt_s += 1 msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) # get_protocols(ethernet) pkt_eth = pkt.get_protocols(ethernet.ethernet)[0] self.logger.debug('ethernet= %s ', str(pkt_eth)) dst = pkt_eth.dst src = pkt_eth.src pkt_ipv6 = None pkt_icmpv6 = None if 'ipv6' in self.PROTPCOL: # get_protocols(pkt_ipv6) pkt_ipv6 = pkt.get_protocols(ipv6.ipv6) if 0 < len(pkt_ipv6): self.logger.debug('ipv6= %s', str(pkt_ipv6)) # get_protocols(pkt_icmpv6) pkt_icmpv6 = pkt.get_protocols(icmpv6.icmpv6) if 0 < len(pkt_icmpv6): self.logger.debug('icmpv6= %s icmpv6.ND_NEIGHBOR_SOLICIT = %s' , str(pkt_icmpv6), icmpv6.ND_NEIGHBOR_SOLICIT) # if not pkt_icmpv6[0].type_ in [icmpv6.MLDV2_LISTENER_REPORT, icmpv6.ICMPV6_MEMBERSHIP_QUERY]: # print "icmpv6.type is " + str(pkt_icmpv6[0].type_) # return dpid = datapath self.mac_to_port.setdefault(dpid, {}) self.logger.debug('packet in %s %s %s %s %s', dpid, src, dst, in_port, str(self.packet_in_cnt)) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time self.logger.debug('in_port = %s, out_port = %s, OFPP_FLOOD = %s', str(in_port), str(out_port), str(ofproto.OFPP_FLOOD)) if out_port != ofproto.OFPP_FLOOD: if 'eth' in self.PROTPCOL: # match match = parser.OFPMatch(in_port=in_port, eth_dst=dst ) #miss match match = parser.OFPMatch(in_port=in_port, eth_type=0, eth_dst=dst ) elif 'ipv6' in self.PROTPCOL: match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IPV6, ip_proto=inet.IPPROTO_ICMPV6, ipv6_dst=dst) self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data # create send packet sendpkt = packet.Packet() sendpkt.add_protocol(ethernet.ethernet(ethertype=ether.ETH_TYPE_8021Q, dst=dst, src=src)) sendpkt.add_protocol(vlan.vlan(pcp=0, cfi=0, vid=100, ethertype=ether.ETH_TYPE_IPV6)) sendpkt.add_protocol(ipv6.ipv6(src=srcip, dst=dstip, nxt=inet.IPPROTO_ICMPV6)) sendpkt.add_protocol(icmpv6.icmpv6(type_=icmpv6.ICMPV6_MEMBERSHIP_QUERY, data=icmpv6.mldv2_query(address='::'))) sendpkt.serialize() self.logger.debug("packet-out %s" % (sendpkt,)) print "\n" data = sendpkt.data IPPROTO_ICMP = socket.getprotobyname('icmp') sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, IPPROTO_ICMP) while sendpkt.data: sent_bytes = sock.sendto(sendpkt.data, ('ff38::1', 0)) sendpkt.data = sendpkt.data[sent_bytes:] """ # out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) #out = parser.OFPPacketOut(datapath=datapath, buffer_id=0xffffffff, in_port=in_port, actions=actions, data=data) self.logger.debug("out %s %s %s %s" % (datapath, self.buffer_id, in_port, actions)) sendmsg = ofproto_v1_3_parser._set_msg_type(ofproto_v1_3.OFPT_PACKET_OUT); sendmsg.__init__(datapath) sendmsg.datapath = datapath sendmsg.buffer_id = 0xffffffff sendmsg.in_port = in_port sendmsg.actions_len = 0 sendmsg.actions = actions self.logger.debug("sendmsg %s %s %s %s" % (sendmsg.datapath, sendmsg.buffer_id, sendmsg.in_port, sendmsg.actions)) actions_len = 0 offset = ofproto_v1_3.OFP_PACKET_OUT_SIZE for a in actions: a.serialize(self.buf, offset) offset += a.len actions_len += a.len if sendpkt.data is not None: assert sendmsg.buffer_id == ofproto_v1_3.OFP_NO_BUFFER self.buf += sendpkt.data self.logger.debug("self.buf %s " % (self.buf)) sendout = msg_pack_into(ofproto_v1_3.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto_v1_3.OFP_HEADER_SIZE, sendmsg.buffer_id, in_port, a.len) self.logger.debug("self.buf %s " % (self.buf)) IPPROTO_ICMP = socket.getprotobyname('icmp') sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, IPPROTO_ICMP) # sock.send(sendout) # while self.buf: # sent_bytes = sock.sendto(self.buf, ('ff38::1', 0)) # self.buf = self.buf[sent_bytes:] while self.buf: sent_bytes = sock.sendto(self.buf, ('ff38::1', 0)) self.buf = self.buf[sent_bytes:] # create_connection # sock.send() #datapath.send_packet_out(self, sendmsg.buffer_id, sendmsg.in_port, sendmsg.actions) """ #datapath.send_packet_out(buffer_id=0xffffffff, in_port=in_port, actions=actions, data=data) # datapath.send_msg(sendout) # datapath.send_msg(out) """ # create send packet sendpkt = packet.Packet() sendpkt.add_protocol(ethernet.ethernet(ethertype=ether.ETH_TYPE_8021Q, dst=dst, src=src)) sendpkt.add_protocol(vlan.vlan(pcp=0, cfi=0, vid=100, ethertype=ether.ETH_TYPE_IPV6)) sendpkt.add_protocol(ipv6.ipv6(src=pkt_ipv6[0].src, dst=pkt_ipv6[0].dst, nxt=inet.IPPROTO_ICMPV6)) sendpkt.add_protocol(icmpv6.icmpv6(type_=icmpv6.ICMPV6_MEMBERSHIP_QUERY, data=icmpv6.mldv2_query(address='::'))) sendpkt.serialize() newmsg = ofproto_v1_3_parser._set_msg_type(ofproto.OFPT_PACKET_OUT); self.logger.debug("newmsg %s " % (newmsg)) newmsg.__init__(datapath) newmsg.buffer_id = msg.buffer_id newmsg.in_port = in_port newmsg.actions_len = 0 newmsg.actions = actions self.buf print "\n" actions_len = 0 offset = ofproto.OFP_PACKET_OUT_SIZE for a in actions: a.serialize(self.buf, offset) offset += a.len actions_len += a.len self.logger.debug("DATA %s " % (sendpkt.data)) if sendpkt.data is not None: # assert msg.buffer_id == 0xffffffff self.buf += sendpkt.data msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) if data is not None: newmsg.buf += sendpkt.data self.logger.debug("self.buf %s " % (newmsg.buf)) self.logger.debug("ofproto.OFP_PACKET_OUT_PACK_STR %s " % (ofproto.OFP_PACKET_OUT_PACK_STR)) self.logger.debug("ofproto.OFP_HEADER_SIZE %s " % (ofproto.OFP_HEADER_SIZE)) self.logger.debug("msg.buffer_id %s " % (newmsg.buffer_id)) self.logger.debug("in_port %s " % (in_port)) self.logger.debug("a.len %s " % (a.len)) out = msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, newmsg.buf, ofproto.OFP_HEADER_SIZE, newmsg.buffer_id, in_port, a.len) self.logger.debug("out %s " % (out)) # data = sendpkt.data # assert isinstance(msg, parser.MsgBase) IPPROTO_ICMP = socket.getprotobyname('icmp') sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, IPPROTO_ICMP) # msg.buffer_id == 0xffffffff # out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, # in_port=in_port, actions=actions, data=data) # msg(datapath, version, msg_type, msg_len, xid, buf): # parser.OFPMatch # out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, # in_port=in_port, actions=actions, data=data) # out.serialize() sock.send(out) # if sendpkt.xid is None: # parser.set # self.set_xid(sendpkt) # sendpkt.serialize() # LOG.debug('send_msg %s', msg) # self.send(msg.buf) # if self.data is not None: # assert self.buffer_id == 0xffffffff # self.buf += data """ # sock.sendto(sendpkt,dst) # datapath.send_msg(parserdata) """ self.buffer_id = ofproto.OFP_NO_BUFFER self.in_port = in_port self.actions = actions self.actions_len = 16 self.data = data print('self.buffer_id=' + str(self.buffer_id) + ' self.in_port=' + str(self.in_port) + ' self.actions=' + str(self.actions) + ' self.actions_len=' + str(self.actions_len) + ' self.data=' + str(self.data)) offset = ofproto.OFP_PACKET_OUT_SIZE print('offset=' + str(offset)) if self.data is not None: assert self.buffer_id == 0xffffffff self.buf += data print ("send %s " % data) parserdata = parser.msg_pack_into(ofproto_v1_3.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) print ("send %s " % self.buf) print ("send %s " % parserdata) datapath.send_msg(parserdata) """ # sock.send(sendpkt) """ print('New switch is joined: %s' % datapath.id) flow = { 'match': { 'dl_type': ether.ETH_TYPE_IPV6, 'nw_proto': inet.IPPROTO_ICMPV6, }, 'actions': [ { 'type': 'OUTPUT', 'port': ofproto_v1_3.OFPP_NORMAL, }, ] } print('New flow: %s' % flow) self.actions_len = 0 offset = ofproto.OFP_PACKET_OUT_SIZE for a in self.actions: a.serialize(self.buf, offset) offset += a.len self.actions_len += a.len if self.data is not None: assert self.buffer_id == 0xffffffff self.buf += self.data msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) # parser # parser(cls, datapath, version, msg_type, msg_len, xid, buf): parser.OFPPacketOut #out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) # out = parser.OFPPacketOut(datapath=datapath, buffer_id=0xffffffff, in_port=in_port, actions=actions, data=data) # MsgBase.set_headers() # buf = 'version: %s msg_type %s xid %s ' % ('0x1', '0x6', '0xd35262b') # buf = 'version: 0x%x msg_type 0x%x xid 0x%x ' % (self.OFP_VERSIONS, 0x6, 8) # print (str(buf)) aaa = parser.set_headers(self, '0x1', '0x6', '0xd35262b') # MsgBase(self, datapath) print aaa # datapath.ofproto_parser # ofproto_parser # MsgBase.set_buf(buf) # MsgBase.set_buf() # def parser(cls, datapath, version, msg_type, msg_len, xid, buf): # msg_ = cls(datapath) # msg_.set_headers(version, msg_type, msg_len, xid) # msg_.set_buf(buf) # return msg_ """ """ self.socket = socket self.socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) self.address = address self.is_active = True # The limit is arbitrary. We need to limit queue size to # prevent it from eating memory up self.send_q = hub.Queue(16) self.xid = random.randint(0, self.ofproto.MAX_XID) self.id = None # datapath_id is unknown yet self.ports = None self.flow_format = ofproto_v1_0.NXFF_OPENFLOW10 self.ofp_brick = ryu.base.app_manager.lookup_service_brick('ofp_event') self.set_state(handler.HANDSHAKE_DISPATCHER) """ #datapath.send_msg(out) """
''' $ sudo ip link add veth0 type veth peer name veth1 $ sudo ip netns add ns0 $ sudo ip link set dev veth0 netns ns0 $ sudo ip netns exec ns0 bash # python send.py ''' import socket from ryu.lib.packet import packet, ethernet, vlan, ipv6, icmpv6 from ryu.ofproto import ether, inet sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW) sock.bind(('veth0', 0)) pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=ether.ETH_TYPE_8021Q)) pkt.add_protocol(vlan.vlan(vid=10, ethertype=ether.ETH_TYPE_IPV6)) pkt.add_protocol(ipv6.ipv6(nxt=inet.IPPROTO_ICMPV6)) pkt.add_protocol(icmpv6.icmpv6( type_=icmpv6.MLD_LISTENER_QUERY, data=icmpv6.mldv2_query())) pkt.serialize() sock.send(pkt.data)
def send_icmp(self, in_port, protocol_list, vlan_id, icmp_type, icmp_code, icmp_data=None, msg_data=None, src_ip=None): # Generate ICMP reply packet csum = 0 offset = ethernet.ethernet._MIN_LEN if vlan_id != VLANID_NONE: ether_proto = ether.ETH_TYPE_8021Q pcp = 0 cfi = 0 vlan_ether = ether.ETH_TYPE_IP v = vlan.vlan(pcp, cfi, vlan_id, vlan_ether) offset += vlan.vlan._MIN_LEN else: ether_proto = ether.ETH_TYPE_IP eth = protocol_list[ETHERNET] e = ethernet.ethernet(eth.src, eth.dst, ether_proto) ip = protocol_list[IPV4] if icmp_data is None and msg_data is not None: # RFC 4884 says that we should send "at least 128 octets" # if we are using the ICMP Extension Structure. # We're not using the extension structure, but let's send # up to 128 bytes of the original msg_data. # # RFC 4884 also states that the length field is interpreted in # 32 bit units, so the length calculated in bytes needs to first # be divided by 4, then increased by 1 if the modulus is non-zero. # # Finally, RFC 4884 says, if we're specifying the length, we MUST # zero pad to the next 32 bit boundary. end_of_data = offset + len(ip) + 128 ip_datagram = bytearray() ip_datagram += msg_data[offset:end_of_data] data_len = int(len(ip_datagram) / 4) length_modulus = int(len(ip_datagram) % 4) if length_modulus: data_len += 1 ip_datagram += bytearray([0] * (4 - length_modulus)) if icmp_type == icmp.ICMP_DEST_UNREACH: icmp_data = icmp.dest_unreach(data_len=data_len, data=ip_datagram) elif icmp_type == icmp.ICMP_TIME_EXCEEDED: icmp_data = icmp.TimeExceeded(data_len=data_len, data=ip_datagram) ic = icmp.icmp(icmp_type, icmp_code, csum, data=icmp_data) if src_ip is None: src_ip = ip.dst ip_total_length = ip.header_length * 4 + ic._MIN_LEN if ic.data is not None: ip_total_length += ic.data._MIN_LEN if ic.data.data is not None: ip_total_length += +len(ic.data.data) i = ipv4.ipv4(ip.version, ip.header_length, ip.tos, ip_total_length, ip.identification, ip.flags, ip.offset, DEFAULT_TTL, inet.IPPROTO_ICMP, csum, src_ip, ip.src) pkt = packet.Packet() pkt.add_protocol(e) if vlan_id != VLANID_NONE: pkt.add_protocol(v) pkt.add_protocol(i) pkt.add_protocol(ic) pkt.serialize() # Send packet out self.send_packet_out(in_port, self.dp.ofproto.OFPP_IN_PORT, pkt.data, data_str=str(pkt))