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 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 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 test_to_string(self): ec = icmpv6.echo(self.id_, self.seq, self.data) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, ec) echo_values = {'id': self.id_, 'seq': self.seq, 'data': self.data} _echo_str = ','.join([ '%s=%s' % (k, repr(echo_values[k])) for k, v in inspect.getmembers(ec) if k in echo_values ]) echo_str = '%s(%s)' % (icmpv6.echo.__name__, _echo_str) icmp_values = { 'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': echo_str } _ic_str = ','.join([ '%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values ]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
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 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(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 __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 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 _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 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 _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 test_to_string(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) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) nd_opt_values = {'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_la.__name__, _nd_opt_str) nd_values = {'res': repr(nd.res), 'dst': repr(self.dst), 'type_': repr(self.nd_type), 'length': repr(self.nd_length), 'data': nd_opt_str} _nd_str = ','.join(['%s=%s' % (k, nd_values[k]) for k, v in inspect.getmembers(nd) if k in nd_values]) nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': nd_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
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 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 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 __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_to_string(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, rs) nd_opt_values = {'length': self.nd_length, 'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_sla.__name__, _nd_opt_str) rs_values = {'res': repr(rs.res), 'option': nd_opt_str} _rs_str = ','.join(['%s=%s' % (k, rs_values[k]) for k, v in inspect.getmembers(rs) if k in rs_values]) rs_str = '%s(%s)' % (icmpv6.nd_router_solicit.__name__, _rs_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': rs_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
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 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 sendDIO(self, out_port=[], dst_ip=[], dst_mac =[], dodag_shutdown=False): """ Send a DIO message port: port number to send on dst_ip: destination ippv6 dst_mac: destination mac with the following Options: 1. Prefix Information 2. DODAG Configuration 3. DAO messages are sent after short interval if the sending node is not the root of this DODAG or it is not poisoned Called by: DIS message handler, if the DIS is unicast, posion, and setDIOtime """ # create RPL options rploption = [] # create Dodag Configuration Option dodag_conf = icmpv6_rpl.rpl_option_dodag_conf(length=0, # the rpl serialize method know what to do with len flags=0, a = self.authenticated, pcs = self.PCS, diointdouble = self.DIOIntDoublings, diointmin = self.DIOIntMin, dioredun = self.DIORedundancyConst, maxrankinc = self.MaxRankIncrease, minhoprankinc = self.MinHopRankIncrease, ocp = self.OCP, reserved=0, def_lifetime = self.DftLft, lifetime_unit = self.LftUnit) rploption.append(dodag_conf) # Create Prefix Information Option for every advertised prefix for prefix in self.advertised_prefixes: prefix_info = icmpv6_rpl.rpl_option_pi(length=0, pre_length=64, l=0, a=1,r=0, reserved1=0, valid_lifetime=RPL_PREFIX_TIME_INF, pref_lifetime=RPL_PREFIX_TIME_INF, reserved2=0, prefix=prefix) rploption.append(prefix_info) # Create RPL_DIO message diomsg = icmpv6_rpl.rpl_dio(rplinstanceid=self.instanceID, version=self.version.get_val(), rank=self.rank,g=self.G,o=0,mop=self.MOP, prf=self.Prf,dtsn=self.DTSN.get_val(), flags=0,reserved=0, dodagid=self.dodagID,option=rploption) # Create Dodag RPL Control message rplmsg = icmpv6_rpl.rpl_control(code=icmpv6_rpl.RPL_DIO, rplctrl=diomsg) # Create ICMPv6 protocol message rpl = icmpv6.icmpv6(type_= icmpv6_rpl.ICMPv6_RPL, code=icmpv6_rpl.RPL_DIO, csum=0, data= rplmsg) if len(out_port) and len(dst_ip) and len(dst_mac): self._send_rpl_pkt(out_port, dst_ip, dst_mac, rpl) else: self._broadcast_rpl_pkt(rpl) # DAO message are sent after a short interval when DIO messages are # sent if not self.is_dodagRoot and not dodag_shutdown: self.setDAOtimer() del DIO_message
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 _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 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 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 _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")
class Test_icmpv6_header(unittest.TestCase): type_ = 255 code = 0 csum = 207 buf = '\xff\x00\x00\xcf' icmp = icmpv6.icmpv6(type_, code, 0) def setUp(self): pass def tearDown(self): pass def test_init(self): eq_(self.type_, self.icmp.type_) eq_(self.code, self.icmp.code) eq_(0, self.icmp.csum) def test_parser(self): msg, n, _ = self.icmp.parser(self.buf) eq_(msg.type_, self.type_) eq_(msg.code, self.code) eq_(msg.csum, self.csum) eq_(msg.data, None) eq_(n, None) def test_serialize(self): src_ipv6 = 'fe80::200:ff:fe00:ef' dst_ipv6 = 'fe80::200:ff:fe00:1' 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) @raises(Exception) def test_malformed_icmpv6(self): m_short_buf = self.buf[1:self.icmp._MIN_LEN] self.icmp.parser(m_short_buf) 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 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 test_to_string(self): ic = icmpv6.icmpv6(self.type_, self.code, self.csum, self.data) icmp_values = {'type_': self.type_, 'code': self.code, 'csum': self.csum, 'data': self.data} _ic_str = ','.join(['%s=%s' % (k, repr(icmp_values[k])) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
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_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_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_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 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_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(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_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_to_string(self): ic = icmpv6.icmpv6(self.type_, self.code, self.csum, self.data) icmp_values = { 'type_': self.type_, 'code': self.code, 'csum': self.csum, 'data': self.data } _ic_str = ','.join([ '%s=%s' % (k, repr(icmp_values[k])) for k, v in inspect.getmembers(ic) if k in icmp_values ]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
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 _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv6, pkt_icmpv6): print('_handle_icmp STR') if pkt_icmpv6.type_ !=icmpv6.ICMPV6_ECHO_REQUEST: return pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.dst, src=pkt_ethernet.src)) pkt.add_protocol(ipv6.ipv6(dst=pkt_ipv6.dst, src=pkt_ipv6.src)) # proto=pkt_ipv6.proto)) pkt.add_protocol(icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY, # code=icmpv6.ICMPV6_ECHO_REPLY_CODE, csum=0, data=pkt_icmpv6.data)) print('_handle_icmp CALL') self._send_packet(datapath, port, pkt)
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 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 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 _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)
class Test_icmpv6_header(unittest.TestCase): type_ = 255 code = 0 csum = 207 buf = '\xff\x00\x00\xcf' icmp = icmpv6.icmpv6(type_, code, 0) def setUp(self): pass def tearDown(self): pass def test_init(self): eq_(self.type_, self.icmp.type_) eq_(self.code, self.icmp.code) eq_(0, self.icmp.csum) def test_parser(self): msg, n, _ = self.icmp.parser(self.buf) eq_(msg.type_, self.type_) eq_(msg.code, self.code) eq_(msg.csum, self.csum) eq_(msg.data, None) eq_(n, None) 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) @raises(Exception) def test_malformed_icmpv6(self): m_short_buf = self.buf[1:self.icmp._MIN_LEN] self.icmp.parser(m_short_buf)
def router_advert(vid, eth_src, eth_dst, src_ip, dst_ip, vips, pi_flags=0x6): """Return IPv6 ICMP Router Advert. 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. 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, valve_of.ether.ETH_TYPE_IPV6) ipv6_pkt = ipv6.ipv6( src=src_ip, dst=dst_ip, nxt=valve_of.inet.IPPROTO_ICMPV6, hop_limit=IPV6_MAX_HOP_LIM) 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=IPV6_RA_HOP_LIM, options=options)) pkt.add_protocol(icmpv6_ra_pkt) pkt.serialize() return pkt
def test_to_string(self): nd_opt = icmpv6.nd_option_tla(self.nd_length, self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) nd_opt_values = { 'length': self.nd_length, 'hw_src': self.nd_hw_src, 'data': None } _nd_opt_str = ','.join([ '%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values ]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_tla.__name__, _nd_opt_str) nd_values = { 'res': repr(nd.res), 'dst': repr(self.dst), 'option': nd_opt_str } _nd_str = ','.join([ '%s=%s' % (k, nd_values[k]) for k, v in inspect.getmembers(nd) if k in nd_values ]) nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str) icmp_values = { 'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': nd_str } _ic_str = ','.join([ '%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values ]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) eq_(str(ic), ic_str) eq_(repr(ic), ic_str)
def nd_solicit_ip_gw(self, ip_gw, controller_ip, vlan, ports): flowmods = [] if ports: self.logger.info('Resolving %s', ip_gw) nd_mac = self.ipv6_link_eth_mcast(ip_gw) ip_gw_mcast = self.ipv6_link_mcast_from_ucast(ip_gw) port_num = ports[0].number pkt = self.build_ethernet_pkt( nd_mac, port_num, vlan, ether.ETH_TYPE_IPV6) ipv6_pkt = ipv6.ipv6( src=controller_ip.ip, dst=ip_gw_mcast, nxt=inet.IPPROTO_ICMPV6) icmpv6_pkt = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor( dst=ip_gw, option=icmpv6.nd_option_sla(hw_src=self.FAUCET_MAC))) pkt.add_protocol(ipv6_pkt) pkt.add_protocol(icmpv6_pkt) pkt.serialize() for port in ports: flowmods.append(self.valve_packetout(port.number, pkt.data)) return flowmods
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 _test_serialize(self, echo_data=None): buf = self.buf + str(echo_data or "") src_ipv6 = netaddr.IPAddress("3ffe:507:0:1:200:86ff:fe05:80da").packed dst_ipv6 = netaddr.IPAddress("3ffe:501:0:1001::2").packed prev = ipv6(6, 0, 0, len(buf), 64, 255, src_ipv6, dst_ipv6) echo_csum = icmpv6_csum(prev, buf) echo = icmpv6.echo(self.id_, self.seq, echo_data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, echo) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (id_, seq) = struct.unpack_from(echo._PACK_STR, buf, icmp._MIN_LEN) data = buf[(icmp._MIN_LEN + echo._MIN_LEN) :] data = data if len(data) != 0 else None eq_(type_, self.type_) eq_(code, self.code) eq_(csum, echo_csum) eq_(id_, self.id_) eq_(seq, self.seq) eq_(data, echo_data)
def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, nd_opt) prev = ipv6(6, 0, 0, 16, 64, 255, self.src_ipv6, self.dst_ipv6) rs_csum = icmpv6_csum(prev, self.buf + self.data) 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) (nd_type, nd_length, nd_hw_src) = struct.unpack_from( nd_opt._PACK_STR, buf, icmp._MIN_LEN + rs._MIN_LEN) data = buf[(icmp._MIN_LEN + rs._MIN_LEN + 8):] eq_(type_, self.type_) eq_(code, self.code) eq_(csum, rs_csum) eq_(res[0], self.res) eq_(nd_type, self.nd_type) eq_(nd_length, self.nd_length) eq_(nd_hw_src, addrconv.mac.text_to_bin(self.nd_hw_src))
def _test_serialize(self, echo_data=None): buf = self.buf + str(echo_data or '') src_ipv6 = netaddr.IPAddress('3ffe:507:0:1:200:86ff:fe05:80da').packed dst_ipv6 = netaddr.IPAddress('3ffe:501:0:1001::2').packed prev = ipv6(6, 0, 0, len(buf), 64, 255, src_ipv6, dst_ipv6) echo_csum = icmpv6_csum(prev, buf) echo = icmpv6.echo(self.id_, self.seq, echo_data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, echo) buf = buffer(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (id_, seq) = struct.unpack_from(echo._PACK_STR, buf, icmp._MIN_LEN) data = buf[(icmp._MIN_LEN + echo._MIN_LEN):] data = data if len(data) != 0 else None eq_(type_, self.type_) eq_(code, self.code) eq_(csum, echo_csum) eq_(id_, self.id_) eq_(seq, self.seq) eq_(data, echo_data)
def nd_solicit_ip_gw(self, ip_gw, controller_ip, vlan, ports): flowmods = [] if ports: self.logger.info('Resolving %s', ip_gw) nd_mac = self.ipv6_link_eth_mcast(ip_gw) ip_gw_mcast = self.ipv6_link_mcast_from_ucast(ip_gw) port_num = ports[0].number pkt = self.build_ethernet_pkt( nd_mac, port_num, vlan, ether.ETH_TYPE_IPV6) ipv6_pkt = ipv6.ipv6( src=controller_ip.ip, dst=ip_gw_mcast, nxt=inet.IPPROTO_ICMPV6) icmpv6_pkt = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor( dst=ip_gw, option=icmpv6.nd_option_sla(hw_src=self.FAUCET_MAC))) pkt.add_protocol(ipv6_pkt) pkt.add_protocol(icmpv6_pkt) pkt.serialize() for port in ports: flowmods.append(self.valve_packetout(port.number, pkt.data)) return flowmods