def test_default_args(self): ip = ipv6.ipv6() buf = ip.serialize(bytearray(), None) res = struct.unpack(ipv6.ipv6._PACK_STR, str(buf)) eq_(res[0], 6 << 28) eq_(res[1], 0) eq_(res[2], 6) eq_(res[3], 255) eq_(res[4], addrconv.ipv6.text_to_bin('::')) eq_(res[5], addrconv.ipv6.text_to_bin('::')) # with extension header ip = ipv6.ipv6( nxt=0, ext_hdrs=[ ipv6.hop_opts(58, 0, [ ipv6.option(5, 2, '\x00\x00'), ipv6.option(1, 0, None)])]) buf = ip.serialize(bytearray(), None) res = struct.unpack(ipv6.ipv6._PACK_STR + '8s', str(buf)) eq_(res[0], 6 << 28) eq_(res[1], 8) eq_(res[2], 0) eq_(res[3], 255) eq_(res[4], addrconv.ipv6.text_to_bin('::')) eq_(res[5], addrconv.ipv6.text_to_bin('::')) eq_(res[6], '\x3a\x00\x05\x02\x00\x00\x01\x00')
def test_default_args(self): ip = ipv6.ipv6() buf = ip.serialize(bytearray(), None) res = struct.unpack(ipv6.ipv6._PACK_STR, str(buf)) eq_(res[0], 6 << 28) eq_(res[1], 0) eq_(res[2], 6) eq_(res[3], 255) eq_(res[4], addrconv.ipv6.text_to_bin('::')) eq_(res[5], addrconv.ipv6.text_to_bin('::')) # with extension header ip = ipv6.ipv6( nxt=0, ext_hdrs=[ ipv6.hop_opts( 58, 0, [ipv6.option(5, 2, '\x00\x00'), ipv6.option(1, 0, None)]) ]) buf = ip.serialize(bytearray(), None) res = struct.unpack(ipv6.ipv6._PACK_STR + '8s', str(buf)) eq_(res[0], 6 << 28) eq_(res[1], 8) eq_(res[2], 0) eq_(res[3], 255) eq_(res[4], addrconv.ipv6.text_to_bin('::')) eq_(res[5], addrconv.ipv6.text_to_bin('::')) eq_(res[6], '\x3a\x00\x05\x02\x00\x00\x01\x00')
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 control_plane_icmpv6_handler(self, in_port, vlan, eth_src, ipv6_pkt, icmpv6_pkt): flowmods = [] pkt = self.build_ethernet_pkt( eth_src, in_port, vlan, ether.ETH_TYPE_IPV6) if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT: dst = icmpv6_pkt.data.dst ipv6_reply = ipv6.ipv6( src=dst, dst=ipv6_pkt.src, nxt=inet.IPPROTO_ICMPV6, hop_limit=ipv6_pkt.hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor( dst=dst, option=icmpv6.nd_option_tla(hw_src=self.FAUCET_MAC), res=7)) pkt.add_protocol(icmpv6_reply) pkt.serialize() flowmods.extend([self.valve_packetout(in_port, pkt.data)]) elif icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_ADVERT: resolved_ip_gw = ipaddr.IPv6Address(icmpv6_pkt.data.dst) self.logger.info('ND response %s for %s', eth_src, resolved_ip_gw) is_updated = None if resolved_ip_gw in vlan.nd_cache: cached_eth_dst = vlan.nd_cache[resolved_ip_gw].eth_src if cached_eth_dst != eth_src: is_updated = True else: is_updated = False for ip_dst, ip_gw in vlan.ipv6_routes.iteritems(): if ip_gw == resolved_ip_gw: flowmods.extend( self.add_resolved_route( ether.ETH_TYPE_IPV6, vlan, vlan.nd_cache, ip_gw, ip_dst, eth_src,is_updated)) elif icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST: dst = ipv6_pkt.dst ipv6_reply = ipv6.ipv6( src=dst, dst=ipv6_pkt.src, nxt=inet.IPPROTO_ICMPV6, hop_limit=ipv6_pkt.hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = icmpv6.icmpv6( type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo( id_=icmpv6_pkt.data.id, seq=icmpv6_pkt.data.seq, data=icmpv6_pkt.data.data)) pkt.add_protocol(icmpv6_reply) pkt.serialize() flowmods.extend([self.valve_packetout(in_port, pkt.data)]) return flowmods
def test_default_args(self): la = icmpv6.nd_option_sla() buf = la.serialize() res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, str(buf)) eq_(res[0], icmpv6.ND_OPTION_SLA) eq_(res[1], len(icmpv6.nd_option_sla()) / 8) eq_(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) # with nd_neighbor prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor( option=icmpv6.nd_option_tla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ND_NEIGHBOR_ADVERT) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_neighbor._PACK_STR, str(buf[4:24])) eq_(res[0], 0) eq_(res[1], addrconv.ipv6.text_to_bin('::')) res = struct.unpack(icmpv6.nd_option_tla._PACK_STR, str(buf[24:])) eq_(res[0], icmpv6.ND_OPTION_TLA) eq_(res[1], len(icmpv6.nd_option_tla()) / 8) eq_(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) # with nd_router_solicit prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_SOLICIT, data=icmpv6.nd_router_solicit( option=icmpv6.nd_option_sla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ND_ROUTER_SOLICIT) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_solicit._PACK_STR, str(buf[4:8])) eq_(res[0], 0) res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, str(buf[8:])) eq_(res[0], icmpv6.ND_OPTION_SLA) eq_(res[1], len(icmpv6.nd_option_sla()) / 8) eq_(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00'))
def test_default_args(self): la = icmpv6.nd_option_sla() buf = la.serialize() res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, str(buf)) eq_(res[0], icmpv6.ND_OPTION_SLA) eq_(res[1], len(icmpv6.nd_option_sla()) / 8) eq_(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) # with nd_neighbor prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor(option=icmpv6.nd_option_tla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ND_NEIGHBOR_ADVERT) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_neighbor._PACK_STR, str(buf[4:24])) eq_(res[0], 0) eq_(res[1], addrconv.ipv6.text_to_bin('::')) res = struct.unpack(icmpv6.nd_option_tla._PACK_STR, str(buf[24:])) eq_(res[0], icmpv6.ND_OPTION_TLA) eq_(res[1], len(icmpv6.nd_option_tla()) / 8) eq_(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) # with nd_router_solicit prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_SOLICIT, data=icmpv6.nd_router_solicit(option=icmpv6.nd_option_sla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ND_ROUTER_SOLICIT) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_solicit._PACK_STR, str(buf[4:8])) eq_(res[0], 0) res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, str(buf[8:])) eq_(res[0], icmpv6.ND_OPTION_SLA) eq_(res[1], len(icmpv6.nd_option_sla()) / 8) eq_(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00'))
def control_plane_icmpv6_handler(self, in_port, vlan, eth_src, ipv6_pkt, icmpv6_pkt): flowmods = [] pkt = self.build_ethernet_pkt( eth_src, in_port, vlan, ether.ETH_TYPE_IPV6) if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT: dst = icmpv6_pkt.data.dst ipv6_reply = ipv6.ipv6( src=dst, dst=ipv6_pkt.src, nxt=inet.IPPROTO_ICMPV6, hop_limit=ipv6_pkt.hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor( dst=dst, option=icmpv6.nd_option_tla(hw_src=self.FAUCET_MAC), res=7)) pkt.add_protocol(icmpv6_reply) pkt.serialize() flowmods.extend([self.valve_packetout(in_port, pkt.data)]) elif icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_ADVERT: resolved_ip_gw = ipaddr.IPv6Address(icmpv6_pkt.data.dst) for ip_dst, ip_gw in vlan.ipv6_routes.iteritems(): if ip_gw == resolved_ip_gw: self.logger.info('ND response %s for %s', eth_src, resolved_ip_gw) flowmods.extend( self.add_resolved_route( ether.ETH_TYPE_IPV6, vlan, vlan.nd_cache, ip_gw, ip_dst, eth_src)) elif icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST: dst = ipv6_pkt.dst ipv6_reply = ipv6.ipv6( src=dst, dst=ipv6_pkt.src, nxt=inet.IPPROTO_ICMPV6, hop_limit=ipv6_pkt.hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = icmpv6.icmpv6( type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo( id_=icmpv6_pkt.data.id, seq=icmpv6_pkt.data.seq, data=icmpv6_pkt.data.data)) pkt.add_protocol(icmpv6_reply) pkt.serialize() flowmods.extend([self.valve_packetout(in_port, pkt.data)]) return flowmods
def nd_advert(vid, eth_src, eth_dst, src_ip, dst_ip): """Return IPv6 neighbor avertisement packet. 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. src_ip (ipaddress.IPv6Address): source IPv6 address. dst_ip (ipaddress.IPv6Address): destination IPv6 address. Returns: ryu.lib.packet.ethernet: Serialized IPv6 neighbor discovery packet. """ pkt = build_pkt_header( vid, eth_src, eth_dst, valve_of.ether.ETH_TYPE_IPV6) ipv6_icmp6 = ipv6.ipv6( src=src_ip, dst=dst_ip, nxt=valve_of.inet.IPPROTO_ICMPV6, hop_limit=IPV6_MAX_HOP_LIM) pkt.add_protocol(ipv6_icmp6) icmpv6_nd_advert = 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)) pkt.add_protocol(icmpv6_nd_advert) pkt.serialize() return pkt
def icmpv6_echo_reply(vid, eth_src, eth_dst, src_ip, dst_ip, hop_limit, id_, seq, data): r"""Return IPv6 ICMP echo reply packet. 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. src_ip (ipaddress.IPv6Address): source IPv6 address. dst_ip (ipaddress.IPv6Address): destination IPv6 address. hop_limit (int): IPv6 hop limit. id_ (int): identifier for echo reply. seq (int): sequence number for echo reply. data (str): payload for echo reply. Returns: ryu.lib.packet.ethernet: Serialized IPv6 ICMP echo reply packet. """ pkt = build_pkt_header( vid, eth_src, eth_dst, valve_of.ether.ETH_TYPE_IPV6) ipv6_reply = ipv6.ipv6( src=src_ip, dst=dst_ip, nxt=valve_of.inet.IPPROTO_ICMPV6, hop_limit=hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = icmpv6.icmpv6( type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo(id_=id_, seq=seq, data=data)) pkt.add_protocol(icmpv6_reply) pkt.serialize() return pkt
def test_regist_multicast_info(self): """ self.logger.debug("") # TODO p-inしたReportの情報をメモリ上に保持する """ # TODO 実装待ち self.mld_proc.regist_multicast_info(ipv6.ipv6())
def setUp_with_dst_opts(self): self.opt1_type = 5 self.opt1_len = 2 self.opt1_data = '\x00\x00' self.opt2_type = 1 self.opt2_len = 0 self.opt2_data = None self.options = [ ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data), ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data), ] self.dst_opts_nxt = 6 self.dst_opts_size = 0 self.dst_opts = ipv6.dst_opts( self.dst_opts_nxt, self.dst_opts_size, self.options) self.ext_hdrs = [self.dst_opts] self.payload_length += len(self.dst_opts) self.nxt = ipv6.dst_opts.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.dst_opts.serialize()
def __init__(self, mac_src, mac_dst, ipv6_src, ipv6_dst, is_router): """ ================ ========================================================= Input Parameter Description ================ ========================================================= mac_src String instance mac_dst String instance ipv6_src String instance ipv6_dst String instance is_router Boolean instance. ================ ========================================================= ================ ========================================================= Attribute Description ================ ========================================================= pkt The Neighbor Advertisement generated packet ================ ========================================================= """ self.pkt = packet.Packet() e = ethernet.ethernet(mac_dst, mac_src, ether.ETH_TYPE_IPV6) i6 = ipv6.ipv6(src = ipv6_src, dst = ipv6_dst, nxt = inet.IPPROTO_ICMPV6) if is_router: res = 7 else: res = 3 ic = icmpv6.icmpv6(type_ = icmpv6.ND_NEIGHBOR_ADVERT, data = icmpv6.nd_neighbor(dst = ipv6_src, option = icmpv6.nd_option_tla(hw_src = mac_src), res = res)) self.pkt.add_protocol(e) self.pkt.add_protocol(i6) self.pkt.add_protocol(ic)
def __init__(self, mac_src, mac_dst, ipv6_src, ipv6_dst, ipv6_tgt): """ ================ ========================================================= Input Parameter Description ================ ========================================================= mac_src String instance mac_dst String instance ipv6_src String instance ipv6_dst String instance ipv6_tgt String instance ================ ========================================================= ================ ========================================================= Attribute Description ================ ========================================================= pkt The Neighbor Solicitation generated packet ================ ========================================================= """ self.pkt = packet.Packet() e = ethernet.ethernet(mac_dst, mac_src, ether.ETH_TYPE_IPV6) i6 = ipv6.ipv6(src = ipv6_src, dst = ipv6_dst, nxt = inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6(type_ = icmpv6.ND_NEIGHBOR_SOLICIT, data = icmpv6.nd_neighbor(dst = ipv6_tgt, option = icmpv6.nd_option_sla(hw_src = mac_src))) self.pkt.add_protocol(e) self.pkt.add_protocol(i6) self.pkt.add_protocol(ic)
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv, pkt_icmp): # if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST: pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, # dst=pkt_ethernet.src, # src=self.hw_addr)) dst=pkt_ethernet.dst, src=pkt_ethernet.src)) # pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, # src=self.ip_addr, # proto=pkt_ipv4.proto)) """ IPv6 update pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv.src, src=pkt_ethernet.src, proto=pkt_ipv.proto)) pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) """ pkt.add_protocol(ipv6.ipv6(dst=pkt_ipv.dst, src=pkt_ipv.src)) pkt.add_protocol(icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY, csum=0, data=pkt_icmp.data)) self._send_packet(datapath, port, pkt)
def nd_request(vid, eth_src, eth_dst, src_ip, dst_ip): """Return IPv6 neighbor discovery request packet. Args: vid (int or None): VLAN VID to use (or None). eth_src (str): source Ethernet MAC address. eth_dst (str): Ethernet destination address. src_ip (ipaddress.IPv6Address): source IPv6 address. dst_ip (ipaddress.IPv6Address): requested IPv6 address. Returns: ryu.lib.packet.ethernet: Serialized IPv6 neighbor discovery packet. """ if mac_addr_is_unicast(eth_dst): nd_mac = eth_dst nd_ip = dst_ip else: nd_mac = ipv6_link_eth_mcast(dst_ip) nd_ip = ipv6_solicited_node_from_ucast(dst_ip) pkt = build_pkt_header(vid, eth_src, nd_mac, valve_of.ether.ETH_TYPE_IPV6) ipv6_pkt = ipv6.ipv6( src=str(src_ip), dst=nd_ip, nxt=valve_of.inet.IPPROTO_ICMPV6) pkt.add_protocol(ipv6_pkt) icmpv6_pkt = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor( dst=dst_ip, option=icmpv6.nd_option_sla(hw_src=eth_src))) pkt.add_protocol(icmpv6_pkt) pkt.serialize() return pkt
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 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 setUp_with_routing_type3(self): self.routing_nxt = 6 self.routing_size = 6 self.routing_type = 3 self.routing_seg = 2 self.routing_cmpi = 0 self.routing_cmpe = 0 self.routing_adrs = [ "2001:db8:dead::1", "2001:db8:dead::2", "2001:db8:dead::3" ] self.routing = ipv6.routing_type3(self.routing_nxt, self.routing_size, self.routing_type, self.routing_seg, self.routing_cmpi, self.routing_cmpe, self.routing_adrs) self.ext_hdrs = [self.routing] self.payload_length += len(self.routing) self.nxt = ipv6.routing.TYPE self.ip = ipv6.ipv6(self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack(ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.routing.serialize()
def create_packet(self, src, dst, srcip, dstip, mld): self.logger.debug("") # ETHER eth = ethernet.ethernet( # ethertype=ether.ETH_TYPE_8021Q, dst=dst, src=src) ethertype=ether.ETH_TYPE_IPV6, dst=dst, src=src) # TODO """ # VLAN vln = vlan.vlan(vid=100, ethertype=ether.ETH_TYPE_IPV6) """ # IPV6 with 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)])] ip6 = ipv6.ipv6(src=srcip, dst=dstip, hop_limit=1, nxt=inet.IPPROTO_HOPOPTS, ext_hdrs=ext_headers) # MLDV2 if type(mld) == icmpv6.mldv2_query: icmp6 = icmpv6_extend( type_=icmpv6.MLD_LISTENER_QUERY, data=mld) elif type(mld) == icmpv6.mldv2_report: icmp6 = icmpv6_extend( type_=icmpv6.MLDV2_LISTENER_REPORT, data=mld) # ether - vlan - ipv6 - icmpv6 ( - mldv2 ) # sendpkt = eth / vln / ip6 / icmp6 sendpkt = eth / ip6 / icmp6 sendpkt.serialize() self.logger.debug("created packet(ryu) : %s", str(sendpkt)) return sendpkt
def setUp_with_dst_opts(self): self.opt1_type = 5 self.opt1_len = 2 self.opt1_data = '\x00\x00' self.opt2_type = 1 self.opt2_len = 0 self.opt2_data = None self.options = [ ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data), ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data), ] self.dst_opts_nxt = 6 self.dst_opts_size = 0 self.dst_opts = ipv6.dst_opts(self.dst_opts_nxt, self.dst_opts_size, self.options) self.ext_hdrs = [self.dst_opts] self.payload_length += len(self.dst_opts) self.nxt = ipv6.dst_opts.TYPE self.ip = ipv6.ipv6(self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack(ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.dst_opts.serialize()
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 __init__(self, mac_src, mac_dst, ipv6_src, ipv6_dst, ipv6_tgt): """ ================ ========================================================= Input Parameter Description ================ ========================================================= mac_src String instance mac_dst String instance ipv6_src String instance ipv6_dst String instance ipv6_tgt String instance ================ ========================================================= ================ ========================================================= Attribute Description ================ ========================================================= pkt The Neighbor Solicitation generated packet ================ ========================================================= """ self.pkt = packet.Packet() e = ethernet.ethernet(mac_dst, mac_src, ether.ETH_TYPE_IPV6) i6 = ipv6.ipv6(src=ipv6_src, dst=ipv6_dst, nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor(dst=ipv6_tgt, option=icmpv6.nd_option_sla(hw_src=mac_src)), ) self.pkt.add_protocol(e) self.pkt.add_protocol(i6) self.pkt.add_protocol(ic)
def nd_reply(eth_src, eth_dst, vid, src_ip, dst_ip, hop_limit): """Return IPv6 neighbor discovery reply packet. 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). src_ip (ipaddr.IPv6Address): source IPv6 address. dst_ip (ipaddr.IPv6Address): destination IPv6 address. hop_limit (int): IPv6 hop limit. Returns: ryu.lib.packet.ethernet: Serialized IPv6 neighbor discovery packet. """ pkt = build_pkt_header(eth_src, eth_dst, vid, ether.ETH_TYPE_IPV6) ipv6_reply = ipv6.ipv6(src=src_ip, dst=dst_ip, nxt=inet.IPPROTO_ICMPV6, hop_limit=hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = 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)) pkt.add_protocol(icmpv6_reply) pkt.serialize() return pkt
def icmpv6_echo_reply(eth_src, eth_dst, vid, src_ip, dst_ip, hop_limit, id_, seq, data): """Return IPv6 ICMP echo reply packet. 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). src_ip (ipaddr.IPv6Address): source IPv6 address. dst_ip (ipaddr.IPv6Address): destination IPv6 address. hop_limit (int): IPv6 hop limit. id_ (int): identifier for echo reply. seq (int): sequence number for echo reply. data (str): payload for echo reply. Returns: ryu.lib.packet.ethernet: Serialized IPv6 ICMP echo reply packet. """ pkt = build_pkt_header( eth_src, eth_dst, vid, ether.ETH_TYPE_IPV6) ipv6_reply = ipv6.ipv6( src=src_ip, dst=dst_ip, nxt=inet.IPPROTO_ICMPV6, hop_limit=hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = icmpv6.icmpv6( type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo(id_=id_, seq=seq, data=data)) pkt.add_protocol(icmpv6_reply) pkt.serialize() return pkt
def _send_icmp_NS(self, datapath, outport_no, dst_ip): src_mac_addr = \ str(self.dpid_to_switch[datapath.id].ports[outport_no].hw_addr) src_ip = \ str(self.dpid_to_switch[datapath.id].ports[outport_no].gateway.gw_ipv6) p = packet.Packet() dst_mac, dst_ip_multicast = self._generate_dst_for_NS(dst_ip) dst_mac = str(dst_mac) dst_ip_multicast = str(dst_ip_multicast) dst_ip = str(dst_ip) e = ethernet.ethernet(dst = dst_mac, src = src_mac_addr, ethertype = ether.ETH_TYPE_IPV6) ip6 = ipv6.ipv6(version = 6, traffic_class = 0, flow_label = 0, # 4byte ICMP header, 4byte reserved, 16byte target address, # 8byte "source link-layer address" option # next header value for ICMPv6 is 58 payload_length = 32, nxt = 58, hop_limit = 255, src = src_ip, dst = dst_ip_multicast) # source link-layer address sla_addr = icmpv6.nd_option_sla(hw_src = src_mac_addr) # ns for neighbor solicit; res for reserved, but actually is a flag, # see comments on "nd_option_tla" above ns = icmpv6.nd_neighbor(res = 4, dst = dst_ip, data = sla_addr) ic6 = icmpv6.icmpv6(type_ = icmpv6.ND_NEIGHBOR_SOLICIT, code = 0, # checksum = 0 then ryu calculate for you csum = 0, data = ns) p.add_protocol(e) p.add_protocol(ip6) p.add_protocol(ic6) p.serialize() datapath.send_packet_out(in_port = ofproto_v1_0.OFPP_NONE, actions = [datapath.ofproto_parser.OFPActionOutput(outport_no)], data = p.data)
def nd_request(eth_src, vid, src_ip, dst_ip): """Return IPv6 neighbor discovery request packet. Args: eth_src (str): source Ethernet MAC address. vid (int or None): VLAN VID to use (or None). src_ip (ipaddr.IPv6Address): source IPv6 address. dst_ip (ipaddr.IPv6Address): requested IPv6 address. Returns: ryu.lib.packet.ethernet: Serialized IPv6 neighbor discovery packet. """ nd_mac = ipv6_link_eth_mcast(dst_ip) ip_gw_mcast = ipv6_solicited_node_from_ucast(dst_ip) pkt = build_pkt_header(eth_src, nd_mac, vid, ether.ETH_TYPE_IPV6) ipv6_pkt = ipv6.ipv6( src=str(src_ip), dst=ip_gw_mcast, nxt=inet.IPPROTO_ICMPV6) pkt.add_protocol(ipv6_pkt) icmpv6_pkt = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor( dst=dst_ip, option=icmpv6.nd_option_sla(hw_src=eth_src))) pkt.add_protocol(icmpv6_pkt) pkt.serialize() return pkt
def nd_reply(eth_src, eth_dst, vid, src_ip, dst_ip, hop_limit): """Return IPv6 neighbor discovery reply packet. 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). src_ip (ipaddr.IPv6Address): source IPv6 address. dst_ip (ipaddr.IPv6Address): destination IPv6 address. hop_limit (int): IPv6 hop limit. Returns: ryu.lib.packet.ethernet: Serialized IPv6 neighbor discovery packet. """ pkt = build_pkt_header( eth_src, eth_dst, vid, ether.ETH_TYPE_IPV6) ipv6_reply = ipv6.ipv6( src=src_ip, dst=dst_ip, nxt=inet.IPPROTO_ICMPV6, hop_limit=hop_limit) pkt.add_protocol(ipv6_reply) icmpv6_reply = 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)) pkt.add_protocol(icmpv6_reply) pkt.serialize() return pkt
def setUp_with_routing_type3(self): self.routing_nxt = 6 self.routing_size = 6 self.routing_type = 3 self.routing_seg = 2 self.routing_cmpi = 0 self.routing_cmpe = 0 self.routing_adrs = ["2001:db8:dead::1", "2001:db8:dead::2", "2001:db8:dead::3"] self.routing = ipv6.routing_type3( self.routing_nxt, self.routing_size, self.routing_type, self.routing_seg, self.routing_cmpi, self.routing_cmpe, self.routing_adrs) self.ext_hdrs = [self.routing] self.payload_length += len(self.routing) self.nxt = ipv6.routing.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.routing.serialize()
def __init__(self, mac_src, mac_dst, ipv6_src, ipv6_dst, is_router): """ ================ ========================================================= Input Parameter Description ================ ========================================================= mac_src String instance mac_dst String instance ipv6_src String instance ipv6_dst String instance is_router Boolean instance. ================ ========================================================= ================ ========================================================= Attribute Description ================ ========================================================= pkt The Neighbor Advertisement generated packet ================ ========================================================= """ self.pkt = packet.Packet() e = ethernet.ethernet(mac_dst, mac_src, ether.ETH_TYPE_IPV6) i6 = ipv6.ipv6(src=ipv6_src, dst=ipv6_dst, nxt=inet.IPPROTO_ICMPV6) if is_router: res = 7 else: res = 3 ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor(dst=ipv6_src, option=icmpv6.nd_option_tla(hw_src=mac_src), res=res), ) self.pkt.add_protocol(e) self.pkt.add_protocol(i6) self.pkt.add_protocol(ic)
def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_la(self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, self.nd_type, self.nd_length, nd_opt) prev = ipv6(6, 0, 0, 32, 64, 255, self.src_ipv6, self.dst_ipv6) nd_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (res, dst) = struct.unpack_from(nd._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from('!BB6s', buf, icmp._MIN_LEN + nd._MIN_LEN) data = buf[(icmp._MIN_LEN + nd._MIN_LEN + 8):] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, nd_csum) eq_(res >> 29, self.res) eq_(dst, self.dst) eq_(nd_type, self.nd_type) eq_(nd_length, self.nd_length) eq_(nd_hw_src, self.nd_hw_src)
def setUp_with_multi_headers(self): self.opt1_type = 5 self.opt1_len = 2 self.opt1_data = '\x00\x00' self.opt2_type = 1 self.opt2_len = 0 self.opt2_data = None self.options = [ ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data), ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data), ] self.hop_opts_nxt = ipv6.auth.TYPE self.hop_opts_size = 0 self.hop_opts = ipv6.hop_opts(self.hop_opts_nxt, self.hop_opts_size, self.options) self.auth_nxt = 6 self.auth_size = 4 self.auth_spi = 256 self.auth_seq = 1 self.auth_data = '\xa0\xe7\xf8\xab\xf9\x69\x1a\x8b\xf3\x9f\x7c\xae' self.auth = ipv6.auth(self.auth_nxt, self.auth_size, self.auth_spi, self.auth_seq, self.auth_data) self.ext_hdrs = [self.hop_opts, self.auth] self.payload_length += len(self.hop_opts) + len(self.auth) self.nxt = ipv6.hop_opts.TYPE self.ip = ipv6.ipv6(self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack(ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.hop_opts.serialize() self.buf += self.auth.serialize()
def ipv6_packet_gen(): pkt = packet.Packet() pkt.protocols.append( ethernet.ethernet("ff:ff:ff:ff:ff:ff", "ff:ff:ff:ff:ff:ff", IPV6)) pkt.protocols.append( ipv6.ipv6(6, 0, 0, 0, 0, 0, '0:0:0:0:0:0:0:0', '0:0:0:0:0:0:0:0')) return pkt
def _send_neighbor_advertisement(self, target_ipv6: str, tun_id: int, tun_ipv4_dst: str, output_port, direction): """ Generates the Neighbor Advertisement response packet """ ofproto, parser = self._datapath.ofproto, self._datapath.ofproto_parser # Only check direction OUT because direction IN doesn't need tunn info if direction == Direction.OUT and (not tun_id or not tun_ipv4_dst): self.logger.error("Packet missing tunnel information, can't reply") return prefix = self.get_custom_prefix(target_ipv6) if not prefix: self.logger.debug("Can't reply to NS for UE ip %s", target_ipv6) return pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet( dst=self.MAC_MULTICAST, src=self.config.ll_addr, ethertype=ether_types.ETH_TYPE_IPV6, )) pkt.add_protocol( ipv6.ipv6( dst=self.DEVICE_MULTICAST, src=self.config.ipv6_src, nxt=in_proto.IPPROTO_ICMPV6, )) pkt.add_protocol( icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor( dst=target_ipv6, option=icmpv6.nd_option_tla(hw_src=self.config.ll_addr)), )) pkt.serialize() # For NS from SGI response doesn't need tunnel information actions_out = [] if direction == Direction.OUT: actions_out.extend([ parser.NXActionSetTunnel(tun_id=tun_id), parser.NXActionRegLoad2(dst='tun_ipv4_dst', value=tun_ipv4_dst), ]) actions_out.append(parser.OFPActionOutput(port=output_port)) out = parser.OFPPacketOut(datapath=self._datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions_out, data=pkt.data) ret = self._datapath.send_msg(out) if not ret: self.logger.error("Datapath disconnected, couldn't send NA")
def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6() prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf)) eq_(res[0], 0) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf))
def test_send_multicast_info(self): """ self.logger.debug("") self.regist_multicast_info(pkt) # TODO p-outの情報を設定したReportを生成する # sendpkt = self.create_mldreport(("", "")) # self.send_packet_to_ryu(sendpkt) """ # TODO 実装待ち self.mld_proc.send_multicast_info(ipv6.ipv6())
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 _send_router_advertisement(self, ipv6_src: str, tun_id: int, tun_ipv4_dst: str, output_port): """ Generates the Router Advertisement response packet """ ofproto, parser = self._datapath.ofproto, self._datapath.ofproto_parser if not tun_id or not tun_ipv4_dst: self.logger.error("Packet missing tunnel information, can't reply") return prefix = self.get_custom_prefix(ipv6_src) if not prefix: self.logger.debug("Can't reply to RS for UE ip %s", ipv6_src) return pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet( dst=self.MAC_MULTICAST, src=self.config.ll_addr, ethertype=ether_types.ETH_TYPE_IPV6, )) pkt.add_protocol( ipv6.ipv6( dst=self.DEVICE_MULTICAST, src=self.config.ipv6_src, nxt=in_proto.IPPROTO_ICMPV6, )) pkt.add_protocol( icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert(options=[ icmpv6.nd_option_sla(hw_src=self.config.ll_addr, ), icmpv6.nd_option_pi( pl=self.config.prefix_len, prefix=prefix, ) ]), )) pkt.serialize() actions_out = [ parser.NXActionSetTunnel(tun_id=tun_id), parser.NXActionRegLoad2(dst='tun_ipv4_dst', value=tun_ipv4_dst), parser.OFPActionOutput(port=output_port) ] out = parser.OFPPacketOut(datapath=self._datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions_out, data=pkt.data) ret = self._datapath.send_msg(out) if not ret: self.logger.error("Datapath disconnected, couldn't send RA")
def test_serialize(self): src_ipv6 = netaddr.IPAddress("fe80::200:ff:fe00:ef").packed dst_ipv6 = netaddr.IPAddress("fe80::200:ff:fe00:1").packed prev = ipv6(6, 0, 0, 4, 58, 255, src_ipv6, dst_ipv6) buf = self.icmp.serialize(bytearray(), prev) (type_, code, csum) = struct.unpack(self.icmp._PACK_STR, buffer(buf)) eq_(type_, self.type_) eq_(code, self.code) eq_(csum, self.csum)
def test_serialize(self): src_ipv6 = netaddr.IPAddress('fe80::200:ff:fe00:ef').packed dst_ipv6 = netaddr.IPAddress('fe80::200:ff:fe00:1').packed prev = ipv6(6, 0, 0, 4, 58, 255, src_ipv6, dst_ipv6) buf = self.icmp.serialize(bytearray(), prev) (type_, code, csum) = struct.unpack(self.icmp._PACK_STR, buffer(buf)) eq_(type_, self.type_) eq_(code, self.code) eq_(csum, self.csum)
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 generate_ra_pkt(self, datapath, in_port): nd_option_sla = icmpv6.nd_option_sla(hw_src=self.port_mac_dic[datapath.id][in_port]) nd_option_pi = icmpv6.nd_option_pi( pl=64, res1=6, val_l=2592000, pre_l=604800, prefix=setting.Prefix_dic[datapath.id][in_port]) ra_data = icmpv6.nd_router_advert(ch_l=64, res=0, rou_l=1800, rea_t=0, ret_t=0, options=[nd_option_sla, nd_option_pi]) ra_pkt = packet.Packet() ra_pkt.add_protocol(ethernet.ethernet(ethertype=0x86DD, dst='33:33:00:00:00:01', src=self.port_mac_dic[datapath.id][in_port])) ra_pkt.add_protocol(ipv6.ipv6(dst='ff02::1', src=setting.Port_link_dic[datapath.id][in_port], nxt=58)) ra_pkt.add_protocol(icmpv6.icmpv6(type_=134, code=0, data=ra_data)) return ra_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 ping_connected_hosts(self, datapath, wan_port): """ This function will send an ICMPv6 ECHO REQUEST message to all the nodes of protected network. That will in turn, trigger a Neighbor Solicitation message to be received and the IPv6 destination address, will be the randomly generated LLU address of Janus. :param datapath: The datapath (represents the device used as a traffic normaliser (Janus)) :param wan_port: The port to send a message from. Use this as the in_port, to exclude from multicast """ # Construct L2 header src_mac = generate_random_mac( ) # Generated randomly (can be seen that it is not factory default) dst_mac = '33:33:ff:ff:ff:ff' # This is a multicast L2 address self.temporary_mac_id = "33:33:ff" + src_mac[-9:] layer2 = ethernet.ethernet(dst=dst_mac, src=src_mac, ethertype=ether_types.ETH_TYPE_IPV6) # Construct L3 header ip6_dst = 'ff02::1' # well known multicast L3 address, as defined by IANA ip6_src = generate_llu_ipv6(src_mac) # IPv6 Link Local Unicast address layer3 = ipv6.ipv6(nxt=inet.IPPROTO_ICMPV6, src=ip6_src, dst=ip6_dst) # Construct l4 header icmpv6_type = icmpv6.ICMPV6_ECHO_REQUEST layer4 = icmpv6.icmpv6(type_=icmpv6_type, code=0, csum=0, data=icmpv6.echo()) # Create packet pkt = packet.Packet() # layer 1 is automatically generated when packet.serialize() is called pkt.add_protocol(layer2) pkt.add_protocol(layer3) pkt.add_protocol(layer4) # Send packet to multicast addresses in protected network ofproto = datapath.ofproto parser = datapath.ofproto_parser pkt.serialize() data = pkt.data actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, actions=actions, data=data, in_port=wan_port) datapath.send_msg(out)
def test_send_packet_to_ryu(self): logger.debug("test_send_packet_to_ryu") """ # send of zeromq self.send_sock.send(cPickle.dumps(ryu_packet, protocol=0)) """ eth = ethernet.ethernet() ip6 = ipv6.ipv6() icmp6 = icmpv6.icmpv6() packet = eth / ip6 / icmp6 packet.serialize() # TODO send_sock.send()のMock化 """
def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ICMPV6_ECHO_REPLY) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.echo._PACK_STR, str(buf[4:])) eq_(res[0], 0) eq_(res[1], 0)
def test_send_packet_to_sw(self): eth = ethernet.ethernet() ip6 = ipv6.ipv6() icmp6 = icmpv6.icmpv6() packet = eth / ip6 / icmp6 packet.serialize() # sendrecv.sendp()のMock化 sendpkt = scapy_packet.Packet(packet.data) self.mocker.StubOutWithMock(sendrecv, "sendp") sendrecv.sendp(sendpkt).AndReturn(0) self.mocker.ReplayAll() self.mld_proc.send_packet_to_sw(packet) self.mocker.UnsetStubs() self.mocker.VerifyAll()
def _build_rpl_pkt(self, src_ip, dst_ip, src_mac, dst_mac, rpl): pkt = packet.Packet() e = ethernet.ethernet(ethertype=ether.ETH_TYPE_IPV6, dst = dst_mac, src = src_mac) #TODO: hop_limit=1 i6 = ipv6.ipv6(dst=dst_ip,src=src_ip, nxt=inet.IPPROTO_ICMPV6) pkt.add_protocol(e) pkt.add_protocol(i6) pkt.add_protocol(rpl) return pkt
def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ICMPV6_ECHO_REPLY) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.echo._PACK_STR, str(buf[4:])) eq_(res[0], 0) eq_(res[1], 0)
def router_advert(vid, eth_src, eth_dst, src_ip, dst_ip, vips, hop_limit=255, pi_flags=0x6): """Return IPv6 ICMP echo reply packet. Args: vid (int or None): VLAN VID to use (or None). eth_src (str): source Ethernet MAC address. eth_dst (str): dest Ethernet MAC address. src_ip (ipaddress.IPv6Address): source IPv6 address. vips (list): prefixes (ipaddress.IPv6Address) to advertise. hop_limit (int): IPv6 hop limit. pi_flags (int): flags to set in prefix information field (default set A and L) Returns: ryu.lib.packet.ethernet: Serialized IPv6 ICMP RA packet. """ pkt = build_pkt_header(vid, eth_src, eth_dst, ether.ETH_TYPE_IPV6) ipv6_pkt = ipv6.ipv6(src=src_ip, dst=dst_ip, nxt=inet.IPPROTO_ICMPV6, hop_limit=hop_limit) pkt.add_protocol(ipv6_pkt) options = [] for vip in vips: options.append( icmpv6.nd_option_pi( prefix=vip.network.network_address, pl=vip.network.prefixlen, res1=pi_flags, val_l=86400, pre_l=14400, )) options.append(icmpv6.nd_option_sla(hw_src=eth_src)) # https://tools.ietf.org/html/rfc4861#section-4.6.2 icmpv6_ra_pkt = icmpv6.icmpv6(type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert( rou_l=1800, ch_l=hop_limit, options=options)) pkt.add_protocol(icmpv6_ra_pkt) pkt.serialize() return pkt
def _test_serialize(self, nd_data=None): nd_data = str(nd_data or "") buf = self.buf + nd_data src_ipv6 = netaddr.IPAddress("fe80::102d:a5ff:fe6d:bc0f").packed dst_ipv6 = netaddr.IPAddress("ff02::2").packed prev = ipv6(6, 0, 0, len(buf), 58, 255, src_ipv6, dst_ipv6) nd_csum = icmpv6_csum(prev, buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd_data) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) data = buf[icmp._MIN_LEN :] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, nd_csum) eq_(data, nd_data)
def test_serialize_without_data(self): rs = icmpv6.nd_router_solicit(self.res) prev = ipv6(6, 0, 0, 8, 64, 255, self.src_ipv6, self.dst_ipv6) rs_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, rs) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) res = struct.unpack_from(rs._PACK_STR, buf, icmp._MIN_LEN) data = buf[(icmp._MIN_LEN + rs._MIN_LEN):] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, rs_csum) eq_(res[0], self.res) eq_(data, '')
def _test_serialize(self, nd_data=None): nd_data = str(nd_data or '') buf = self.buf + nd_data src_ipv6 = netaddr.IPAddress('fe80::102d:a5ff:fe6d:bc0f').packed dst_ipv6 = netaddr.IPAddress('ff02::2').packed prev = ipv6(6, 0, 0, len(buf), 58, 255, src_ipv6, dst_ipv6) nd_csum = icmpv6_csum(prev, buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd_data) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) data = buf[icmp._MIN_LEN:] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, nd_csum) eq_(data, nd_data)
def test_default_args(self): pi = icmpv6.nd_option_pi() buf = pi.serialize() res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, str(buf)) eq_(res[0], icmpv6.ND_OPTION_PI) eq_(res[1], len(icmpv6.nd_option_pi()) / 8) eq_(res[2], 0) eq_(res[3], 0) eq_(res[4], 0) eq_(res[5], 0) eq_(res[6], 0) eq_(res[7], addrconv.ipv6.text_to_bin('::')) # with nd_router_advert prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert( options=[icmpv6.nd_option_pi()])) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ND_ROUTER_ADVERT) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_advert._PACK_STR, str(buf[4:16])) eq_(res[0], 0) eq_(res[1], 0) eq_(res[2], 0) eq_(res[3], 0) eq_(res[4], 0) res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, str(buf[16:])) eq_(res[0], icmpv6.ND_OPTION_PI) eq_(res[1], 4) eq_(res[2], 0) eq_(res[3], 0) eq_(res[4], 0) eq_(res[5], 0) eq_(res[6], 0) eq_(res[7], addrconv.ipv6.text_to_bin('::'))
def test_default_args(self): pi = icmpv6.nd_option_pi() buf = pi.serialize() res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, str(buf)) eq_(res[0], icmpv6.ND_OPTION_PI) eq_(res[1], len(icmpv6.nd_option_pi()) / 8) eq_(res[2], 0) eq_(res[3], 0) eq_(res[4], 0) eq_(res[5], 0) eq_(res[6], 0) eq_(res[7], addrconv.ipv6.text_to_bin('::')) # with nd_router_advert prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert(options=[icmpv6.nd_option_pi()])) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4])) eq_(res[0], icmpv6.ND_ROUTER_ADVERT) eq_(res[1], 0) eq_(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_advert._PACK_STR, str(buf[4:16])) eq_(res[0], 0) eq_(res[1], 0) eq_(res[2], 0) eq_(res[3], 0) eq_(res[4], 0) res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, str(buf[16:])) eq_(res[0], icmpv6.ND_OPTION_PI) eq_(res[1], 4) eq_(res[2], 0) eq_(res[3], 0) eq_(res[4], 0) eq_(res[5], 0) eq_(res[6], 0) eq_(res[7], addrconv.ipv6.text_to_bin('::'))
def test_serialize_without_data(self): nd = icmpv6.nd_neighbor(self.res, self.dst) prev = ipv6(6, 0, 0, 24, 64, 255, self.src_ipv6, self.dst_ipv6) nd_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (res, dst) = struct.unpack_from(nd._PACK_STR, buf, icmp._MIN_LEN) data = buf[(icmp._MIN_LEN + nd._MIN_LEN):] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, nd_csum) eq_(res >> 29, self.res) eq_(dst, self.dst) eq_(data, '')
def setUp_with_fragment(self): self.fragment_nxt = 6 self.fragment_offset = 50 self.fragment_more = 1 self.fragment_id = 123 self.fragment = ipv6.fragment(self.fragment_nxt, self.fragment_offset, self.fragment_more, self.fragment_id) self.ext_hdrs = [self.fragment] self.payload_length += len(self.fragment) self.nxt = ipv6.fragment.TYPE self.ip = ipv6.ipv6(self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack(ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.fragment.serialize()