diff options
Diffstat (limited to 'vnet/vnet/map/examples')
-rwxr-xr-x | vnet/vnet/map/examples/gen-rules.py | 213 | ||||
-rwxr-xr-x | vnet/vnet/map/examples/map-test.py | 214 | ||||
-rw-r--r-- | vnet/vnet/map/examples/mapalgs.py | 327 | ||||
-rw-r--r-- | vnet/vnet/map/examples/mt-test.py | 80 |
4 files changed, 834 insertions, 0 deletions
diff --git a/vnet/vnet/map/examples/gen-rules.py b/vnet/vnet/map/examples/gen-rules.py new file mode 100755 index 00000000..d6746f79 --- /dev/null +++ b/vnet/vnet/map/examples/gen-rules.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3.4 + +# Copyright (c) 2015 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import ipaddress +import argparse +import sys + +# map add domain ip4-pfx <pfx> ip6-pfx ::/0 ip6-src <ip6-src> ea-bits-len 0 psid-offset 6 psid-len 6 +# map add rule index <0> psid <psid> ip6-dst <ip6-dst> + +parser = argparse.ArgumentParser(description='MAP VPP configuration generator') +parser.add_argument('-t', action="store", dest="mapmode") +args = parser.parse_args() + +# +# 1:1 Shared IPv4 address, shared BR, Terastream +# +def terastream(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/22') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 6 + ip6_src = ipaddress.ip_address('cccc:bbbb::') + for i in range(ip4_pfx.num_addresses): + if not i % 64: + ip6_src = ip6_src + 1 + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src " + str(ip6_src) + + " ea-bits-len 0 psid-offset 0 psid-len", psid_len) + for psid in range(0x1 << psid_len): + print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid]) + +# +# 1:1 Shared IPv4 address, shared BR, OTE +# +def oteshared11(): + ip4_pfx = ipaddress.ip_network('2.84.63.0/24') + dst = list(ipaddress.ip_network('2a02:580:8c00::/40').subnets(new_prefix=56)) + psid_len = 6 + ip6_src = ipaddress.ip_address('2a02::') + for i in range(ip4_pfx.num_addresses): + if not i % 64: + ip6_src = ip6_src + 1 + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src " + str(ip6_src) + + " ea-bits-len 0 psid-offset 6 psid-len", psid_len) + for psid in range(0x1 << psid_len): + enduserprefix = list(dst.pop(0).subnets(new_prefix=64))[255-1] + print("map add rule index", i, "psid", psid, "ip6-dst", enduserprefix[(i * (0x1<<psid_len)) + psid]) + + +# +# 1:1 Shared IPv4 address, shared BR, Terastream +# +def confdterastream(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/22') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 6 + ip6_src = ipaddress.ip_address('cccc:bbbb::') + for i in range(ip4_pfx.num_addresses): + if not i % 64: + ip6_src = ip6_src + 1 + print("vpp softwire softwire-instances softwire-instance", i, "br-ipv6 " + str(ip6_src) + " ipv6-prefix ::/0" + " ipv4-prefix " + str(ip4_pfx[i]) + + "/32 ea-len 0 psid-offset 6 psid-len", psid_len) +# print("vpp softwire softwire-instances softwire-instance", i, "ipv4-pfx " + str(ip4_pfx[i]) + "/32 ipv6-pfx ::/0 br-ipv6 " + str(ip6_src) + +# " ea-len 0 psid-offset 6 psid-len", psid_len) + for psid in range(0x1 << psid_len): + print("binding", psid, "ipv6-addr", ip6_dst[(i * (0x1<<psid_len)) + psid]) + +def shared11br_yang(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/16') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 6 + for i in range(ip4_pfx.num_addresses): + print("vpp softwire softwire-instances softwire-instance " + str(i) + " ipv4-prefix " + str(ip4_pfx[i]) + "/32 " + + "ipv6-prefix ::/0 ea-len 0 psid-offset 6 tunnel-mtu 1234 psid-len", psid_len) + #print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-shared-src cccc:bbbb::1", + # "ea-bits-len 0 psid-offset 6 psid-len", psid_len) + for psid in range(0x1 << psid_len): + # print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid]) + print("binding", psid, "ipv6-addr", ip6_dst[(i * (0x1<<psid_len)) + psid]) + +def shared11br_xml(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/32') + ip6_dst = ipaddress.ip_network('bbbb::/32') + ip6_src = ipaddress.ip_address('cccc:bbbb::') + psid_len = 6 + print('<vpp xmlns="http://www.cisco.com/yang/cisco-vpp"><softwire><softwire-instances>'); + count = 1024; + for i in range(ip4_pfx.num_addresses): + if not i % 64: + ip6_src = ip6_src + 1 + if count == 0: + break; + count = count - 1; + print('<softwire-instance>') + print(' <id>'+ str(i)+ '</id>') + print(' <ipv4-prefix>'+ str(ip4_pfx[i])+ '/32</ipv4-prefix>') + print(' <ipv6-prefix>::/0</ipv6-prefix>') + print(' <ea-len>0</ea-len>') + print(' <psid-offset>0</psid-offset>') + print(' <psid-len>'+ str(psid_len) + '</psid-len>') + for psid in range(0x1 << psid_len): + print(' <binding>') + print(' <psid>', psid, '</psid>') + print(' <ipv6-addr>'+ str(ip6_dst[(i * (0x1<<psid_len)) + psid]) + '</ipv6-addr>') + print(' </binding>') + print('</softwire-instance>') + print('</softwire-instances></softwire>') + print('</vpp>') + +# +# 1:1 Shared IPv4 address, shared BR +# +def shared11br(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/16') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 6 + for i in range(ip4_pfx.num_addresses): + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-shared-src cccc:bbbb::1", + "ea-bits-len 0 psid-offset 6 psid-len", psid_len) + for psid in range(0x1 << psid_len): + print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid]) + +# +# 1:1 Shared IPv4 address, shared BR +# +def shared11br(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/16') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 6 + for i in range(ip4_pfx.num_addresses): + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-shared-src cccc:bbbb::1", + "ea-bits-len 0 psid-offset 6 psid-len", psid_len) + for psid in range(0x1 << psid_len): + print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid]) + + +# +# 1:1 Shared IPv4 address +# +def shared11(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/16') + ip6_src = ipaddress.ip_network('cccc:bbbb::/64') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 6 + for i in range(ip4_pfx.num_addresses): + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src", ip6_src[i], + "ea-bits-len 0 psid-offset 6 psid-len", psid_len) + for psid in range(0x1 << psid_len): + print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid]) + +# +# 1:1 Shared IPv4 address small +# +def smallshared11(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/24') + ip6_src = ipaddress.ip_network('cccc:bbbb::/64') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 6 + for i in range(ip4_pfx.num_addresses): + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src", ip6_src[i], + "ea-bits-len 0 psid-offset 6 psid-len", psid_len) + for psid in range(0x1 << psid_len): + print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid]) + +# +# 1:1 Full IPv4 address +# +def full11(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/16') + ip6_src = ipaddress.ip_network('cccc:bbbb::/64') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 0 + for i in range(ip4_pfx.num_addresses): + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx " + str(ip6_dst[i]) + "/128 ip6-src", ip6_src[i], + "ea-bits-len 0 psid-offset 0 psid-len 0") +def full11br(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/16') + ip6_dst = ipaddress.ip_network('bbbb::/32') + psid_len = 0 + for i in range(ip4_pfx.num_addresses): + print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx " + str(ip6_dst[i]) + "/128 ip6-shared-src cccc:bbbb::1", + "ea-bits-len 0 psid-offset 0 psid-len 0") + +# +# Algorithmic mapping Shared IPv4 address +# +def algo(): + print("map add domain ip4-pfx 20.0.0.0/24 ip6-pfx bbbb::/32 ip6-src cccc:bbbb::1 ea-bits-len 16 psid-offset 6 psid-len 8") + print("map add domain ip4-pfx 20.0.1.0/24 ip6-pfx bbbb:1::/32 ip6-src cccc:bbbb::2 ea-bits-len 8 psid-offset 0 psid-len 0") + +# +# IP4 forwarding +# +def ip4(): + ip4_pfx = ipaddress.ip_network('20.0.0.0/16') + for i in range(ip4_pfx.num_addresses): + print("ip route add " + str(ip4_pfx[i]) + "/32 via 172.16.0.2") + + +globals()[args.mapmode]() + + diff --git a/vnet/vnet/map/examples/map-test.py b/vnet/vnet/map/examples/map-test.py new file mode 100755 index 00000000..01f377fb --- /dev/null +++ b/vnet/vnet/map/examples/map-test.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# Copyright (c) 2015 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys, time +from scapy.all import * + +import mapalgs + + +ifname = "vpp-tap" + +loc_v4_mac = "aa:aa:aa:aa:aa:a4" +loc_v6_mac = "aa:aa:aa:aa:aa:a6" +vpp_mac = "aa:aa:aa:aa:00:00" + +map_t = 1 + +fragsize = 0 +map_mtu = 200 + +def mac_to_vppmac(mac): + mac = mac.replace(':', '') + return mac[0:4]+"."+mac[4:8]+"."+mac[8:12] + + +map = mapalgs.MapCalc( rulev6 = 'bbbb::/32', + rulev4 = '20.0.0.0/24', + ratio = 256); + +dmr = mapalgs.DmrCalc('cccc:bbbb::/96') + + +ICMP_TYPES_CODES = { + 0: 0, + 3: 15, + 4: 0, + 5: 3, + 6: 0, + 8: 0, + 9: 0, + 10: 0, + 11: 1, + 12: 2, + 13: 0, + 14: 0, + 15: 0, + 16: 0, + 17: 0, + 18: 0 +} + +ICMP6_TYPES_CODES = { + 1: 7, + 2: 0, + 3: 1, + 4: 3, +} + +def net_conf(): + c = "" + c += "tap connect "+ifname+" hwaddr "+mac_to_vppmac(vpp_mac)+" \n" + c += "set int state tap-0 up \n" + c += "set ip6 neighbor tap-0 2001:f00d::1 "+mac_to_vppmac(loc_v6_mac)+" \n" + c += "set ip arp tap-0 10.0.0.1 "+mac_to_vppmac(loc_v4_mac)+" \n" + c += "ip route add ::/0 via 2001:f00d::1 tap-0 \n" + c += "ip route add 0.0.0.0/0 via 10.0.0.1 tap-0 \n" + return c + +def conf(): + c = net_conf() + c += "map add domain ip4-pfx 20.0.0.0/24 ip6-pfx bbbb::/32 ea-bits-len 16 psid-offset 6 psid-len 8" + if map_mtu != 0: + c += " mtu "+str(map_mtu) + if map_t: + c += " ip6-src cccc:bbbb::/96 map-t" + else: + c += " ip6-src cccc:bbbb::ffff" + + c += "\n" + return c + +def send_packet(ip_header, ip_content): + print("Send packet") + if fragsize != 0: + if ip_header.version == 4: + frags = fragment(ip_header/ip_content, fragsize=fragsize) + for f in frags: + print("Fragmented IPv4 packet") + sendp(Ether(dst=vpp_mac, src=loc_v4_mac)/f, iface=ifname) + elif ip_header.version == 6: + frags = fragment6(ip_header/IPv6ExtHdrFragment()/ip_content, fragsize) + for f in frags: + print("Fragmented IPv6 packet") + sendp(Ether(dst=vpp_mac, src=loc_v6_mac)/f, iface=ifname) + else: + sendp(Ether(dst=vpp_mac)/ip_header/ip_content, iface=ifname) + +def send_packet_frag_inner(packet, inner_header, inner_content): + print("Send packet with inner ICMP packet") + if fragsize != 0: + if packet.version == 4: + frags = fragment(inner_header/inner_content, fragsize=fragsize) + for f in frags: + print("Fragmented IPv4 inner packet") + sendp(Ether(dst=vpp_mac, src=loc_v4_mac)/packet/f, iface=ifname) + elif packet.version == 6: + frags = fragment6(inner_header/IPv6ExtHdrFragment()/inner_content, fragsize) + for f in frags: + print("Fragmented IPv6 inner packet") + sendp(Ether(dst=vpp_mac, src=loc_v6_mac)/packet/f, iface=ifname) + else: + sendp(Ether(dst=vpp_mac)/packet/inner_header/inner_content, iface=ifname) + + +def sendv6udp(src, dst, port): + psid = map.gen_psid(port) + ceaddr = str(map.get_mapce_addr(src, psid)) + dst = str(dmr.embed_6052addr(dst)) + send_packet(IPv6(dst=dst, src=ceaddr), UDP(sport=port)/('X'*900)) + +def sendv6tcp(src, dst, port): + psid = map.gen_psid(port) + ceaddr = str(map.get_mapce_addr(src, psid)) + dst = str(dmr.embed_6052addr(dst)) + send_packet(IPv6(dst=dst, src=ceaddr), TCP(sport=port)/('X'*900)) + +def sendv4udp(src, dst, port): + send_packet(IP(dst=dst, src=src), UDP(dport=port)/('X'*900)) + +def sendv4tcp(src, dst, port): + send_packet(IP(dst=dst, src=src), TCP(dport=port)/('X'*900)) + +def sendv6ping(src, dst, id): + psid = map.gen_psid(id) + ceaddr = str(map.get_mapce_addr(src, psid)) + dst = str(dmr.embed_6052addr(dst)) + send_packet(IPv6(dst=dst, src=ceaddr), ICMPv6EchoRequest(id=id, data='A'*500)) + send_packet(IPv6(dst=dst, src=ceaddr), ICMPv6EchoReply(id=id, data='A'*500)) + +def sendv4ping(src, dst, id): + send_packet(IP(dst=dst, src=src), ICMP(id=id, type=0)/('X'*500)) + send_packet(IP(dst=dst, src=src), ICMP(id=id, type=8)/('X'*500)) + +def sendv4icmperr(src, dst, type, code, port, inner_src, inner_dst, payload_length): + inner = IP(dst=inner_dst, src=inner_src)/TCP(sport=port, dport=8888)/('X'*payload_length) + send_packet_frag_inner(IP(dst=dst, src=src)/ICMP(type=type, code=code), IP(dst=inner_dst, src=inner_src), TCP(sport=port, dport=8888)/('X'*payload_length)) + #send_packet(IP(dst=dst, src=src)/ICMP(type=type, code=code)/inner) + +def sendv6icmperr(src, dst, type, code, port, payload_length): + psid = map.gen_psid(port) + src = str(map.get_mapce_addr(src, psid)) + dst = str(dmr.embed_6052addr(dst)) + inner_header = IPv6(dst=src, src=dst) + inner_content = TCP(sport=8888, dport=port)/('X'*payload_length) + send_packet_frag_inner(IPv6(dst=dst, src=src)/ICMPv6DestUnreach(type=type, code=code), inner_header, inner_content) + #send_packet(IPv6(dst=dst, src=src)/ICMPv6DestUnreach(type=type, code=code)/inner) + +def sendv4icmp_errors(src, dst, port, inner_src, inner_dst, payload_length): + for type in ICMP_TYPES_CODES: + for code in range(0, ICMP_TYPES_CODES[type] + 1): + sendv4icmperr(src, dst, type, code, port, inner_src, inner_dst, payload_length) + #sendv4icmperr(src, dst, type, ICMP_TYPES_CODES[type] + 2, port, inner_src, inner_dst, payload_length) + #sendv4icmperr(src, dst, type, 255, port, inner_src, inner_dst, payload_length) + #sendv4icmperr(src, dst, 1, 0, port, inner_src, inner_dst, payload_length) + #sendv4icmperr(src, dst, 2, 10, port, inner_src, inner_dst, payload_length) + #sendv4icmperr(src, dst, 255, 255, port, inner_src, inner_dst, payload_length) + + #TODO: Check wrong paramater with different pointer values + +def sendv6icmp_errors(src, dst, port, payload_length): + for type in ICMP6_TYPES_CODES: + for code in range(0, ICMP6_TYPES_CODES[type] + 1): + sendv6icmperr(src, dst, type, code, port, payload_length) + #sendv6icmperr(src, dst, type, ICMP6_TYPES_CODES[type] + 2, port, payload_length) + #sendv6icmperr(src, dst, type, 255, port, payload_length) + + +def traffic(): + delay = 2.0 + while 1: + #sendp(Ether(dst="bb:bb:bb:bb:bb:b4")/IP(dst="20.0.0.1")/UDP(chksum=0)/('X'*900), iface="vpp-tapv4") + #sendp(Ether(dst="bb:bb:bb:bb:bb:b6")/IPv6(dst="cccc:bbbb::a000:0001")/ICMPv6EchoRequest()/('X'*900), iface="vpp-tapv6") + #sendp(Ether(dst="bb:bb:bb:bb:bb:b6")/IPv6(dst="cccc:bbbb::a000:0001")/UDP()/('X'*900), iface="vpp-tapv6") + sendv6udp("20.0.0.1", "10.0.0.1", 12001) + sendv6tcp("20.0.0.1", "10.0.0.1", 12002) + sendv4udp("10.0.0.1", "20.0.0.1", 12003) + sendv4tcp("10.0.0.1", "20.0.0.1", 12004) + sendv6ping("20.0.0.1", "10.0.0.1", 12005) + sendv4ping("10.0.0.1", "20.0.0.1", 12006) + sendv4icmp_errors("10.0.0.1", "20.0.0.1", 12006, "20.0.0.1", "10.0.0.1", 500) + sendv4icmp_errors("10.0.0.1", "20.0.0.1", 12006, "20.0.0.1", "10.0.0.1", 1500) + sendv6icmp_errors("20.0.0.1", "10.0.0.1", 12006, 500) + time.sleep(delay) + delay *= 0.9 + +if len(sys.argv) <= 1: + print("Usage: conf|traffic") + exit(1) + +if sys.argv[1] == "conf": + print(conf()) +elif sys.argv[1] == "traffic": + traffic()
\ No newline at end of file diff --git a/vnet/vnet/map/examples/mapalgs.py b/vnet/vnet/map/examples/mapalgs.py new file mode 100644 index 00000000..50a0ed0a --- /dev/null +++ b/vnet/vnet/map/examples/mapalgs.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python3 + +# The MIT License (MIT) +# +# Copyright (c) 2015 +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# File included from https://github.com/ejordangottlieb/pyswmap +# Thanks to jordan ;) +# - Pierre +# + +# There is still a great deal of work required on this module. Please +# use with caution. +# -Jordan + +import sys +from ipaddress import ( + IPv6Address, + IPv6Network, + ip_network, + ip_address, + ) +from math import ( + log, + ) + +class MapCalc(object): + + def __init__(self,**bmr): + #rulev6,rulev4): + self.portranges = False + + # Validate and set BMR and BMR derived values + self._check_bmr_values(bmr) + + def _check_bmr_values(self,bmr): + # Assume these values have not been supplied. Validate later. + self.ealen = False + self.ratio = False + + # Validate that a proper PSID Offset has been set + if 'psidoffset' not in bmr: + # Set Default PSID Offset of 6 if it is not set + self.psidoffset = 6 + else: + self.psidoffset = self._psid_offset(bmr['psidoffset']) + + # Validate that a proper IPv4 rule prefix is defined + if 'rulev4' not in bmr: + print("The rule IPv4 prefix has not been set") + sys.exit(1) + else: + self.rulev4 = self._ipv4_rule(bmr['rulev4']) + + # Validate that a proper IPv6 rule prefix is defined + if 'rulev6' not in bmr: + print("The rule IPv6 prefix has not been set") + sys.exit(1) + else: + self.rulev6 = self._ipv6_rule(bmr['rulev6']) + + # Check if EA length was passed + if 'ealen' not in bmr: + self.ealen = False + else: + self.ealen = bmr['ealen'] + self.ratio = self._calc_ratio(bmr['ealen']) + + # Check if sharing ratio was passed or calculated by _calc_ratio + if 'ratio' not in bmr: + # Skip if we have already calculated ratio + if not (self.ratio): + self.ratio = False + else: + if (self.ealen): + # Check to see if supplied EA length contradicts supplied ratio + if ( bmr['ratio'] != self.ratio ): + eavalue = "EA value {}".format(self.ealen) + sharingratio = "sharing ratio {}".format(bmr['ratio']) + print("Supplied {} and {} are contradictory".format( + eavalue, + sharingratio) + ) + sys.exit(1) + else: + self.ratio = bmr['ratio'] + self.ealen = self._calc_ea(bmr['ratio']) + + # EA length or sharing ratio must be set + if not ( self.ealen or self.ratio): + print("The BMR must include an EA length or sharing ratio") + sys.exit(1) + + # Since we have not hit an exception we can calculate the port bits + self.portbits = self._calc_port_bits() + + def _ipv4_rule(self,rulev4): + try: + self.rulev4mask = ip_network( + rulev4, + strict=False + ).prefixlen + except ValueError: + print("Invalid IPv4 prefix {}".format(rulev4)) + sys.exit(1) + + self.rulev4object = ip_network(rulev4) + + return rulev4 + + def _ipv6_rule(self,rulev6): + try: + self.rulev6mask = IPv6Network( + rulev6, + strict=False + ).prefixlen + except ValueError: + print("Invalid IPv6 prefix {}".format(rulev6)) + sys.exit(1) + + return rulev6 + + def _psid_offset(self,psidoffset): + PSIDOFFSET_MAX = 6 + if psidoffset in range(0,PSIDOFFSET_MAX+1): + return psidoffset + else: + print("Invalid PSID Offset value: {}".format(psidoffset)) + sys.exit(1) + + def _psid_range(self,x): + rset = [] + for i in range(0,x+1): + rset.append(2**i) + return rset + + def _calc_port_bits(self): + portbits = 16 - self.psidoffset - self.psidbits + return portbits + + def _calc_ea(self,ratio): + if ratio not in ( self._psid_range(16) ): + print("Invalid ratio {}".format(ratio)) + print("Ratio between 2 to the power of 0 thru 16") + sys.exit(1) + + if ( 1 == ratio): + self.psidbits = 0 + else: + self.psidbits = int(log(ratio,2)) + ealen = self.psidbits + ( 32 - self.rulev4mask ) + return ealen + + def _calc_ratio(self,ealen): + maskbits = 32 - self.rulev4mask + if ( ealen < maskbits ): + print("EA of {} incompatible with rule IPv4 prefix {}".format( + ealen, + self.rulev4, + ) + ) + print("EA length must be at least {} bits".format( + maskbits, + ) + ) + sys.exit(1) + + self.psidbits = ealen - ( 32 - self.rulev4mask ) + if ( self.psidbits > 16): + print("EA length of {} is too large".format( + ealen, + ) + ) + print("EA should not exceed {} for rule IPv4 prefix {}".format( + maskbits + 16, + self.rulev4, + ) + ) + sys.exit(1) + ratio = 2**self.psidbits + return ratio + + def gen_psid(self,portnum): + if ( portnum < self.start_port() ): + print("port value is less than allowed by PSID Offset") + sys.exit(1) + psid = (portnum & ((2**self.psidbits - 1) << self.portbits)) + psid = psid >> self.portbits + return psid + + def port_ranges(self): + return 2**self.psidoffset - 1 + + def start_port(self): + if self.psidoffset == 0: return 0 + return 2**(16 - self.psidoffset) + + def port_list(self,psid): + startrange = psid * (2**self.portbits) + self.start_port() + increment = (2**self.psidbits) * (2**self.portbits) + portlist = [ ] + for port in range(startrange,startrange + 2**self.portbits): + if port >= 65536: continue + portlist.append(port) + for x in range(1,self.port_ranges()): + startrange += increment + for port in range(startrange,startrange + 2**self.portbits): + portlist.append(port) + return portlist + + def ipv4_index(self,ipv4addr): + if ip_address(ipv4addr) in ip_network(self.rulev4): + x = ip_address(ipv4addr) + y = ip_network(self.rulev4,strict=False).network_address + self.ipv4addr = x + return ( int(x) - int(y) ) + else: + print("Error: IPv4 address {} not in Rule IPv4 subnet {}".format( + ipv4add, + ip_network(self.rulev4,strict=False).network_address)) + sys.exit(1) + + def _calc_ipv6bit_pos(self): + addroffset = 128 - (self.rulev6mask + ( self.ealen - self.psidbits)) + psidshift = 128 - ( self.rulev6mask + self.ealen ) + return [addroffset,psidshift] + + def _append_map_eabits(self,ipv4index,addroffset,psidshift,psid): + rulev6base = IPv6Network(self.rulev6,strict=False).network_address + map_prefix = int(rulev6base) | ( ipv4index << addroffset ) + map_fullprefix = map_prefix | ( psid << psidshift) + return map_fullprefix + + + def get_mapce_addr(self,ipv4addr,psid): + ipv4index = self.ipv4_index(ipv4addr) + (addroffset,psidshift) = self._calc_ipv6bit_pos() + map_fullprefix = self._append_map_eabits(ipv4index, + addroffset, + psidshift, + psid) + mapv4iid = map_fullprefix | ( int(self.ipv4addr) << 16 ) + map_full_address = mapv4iid | psid + mapce_address = "{}".format(IPv6Address(map_full_address)) + return mapce_address + + def get_mapce_prefix(self,ipv4addr,psid): + ipv4index = self.ipv4_index(ipv4addr) + (addroffset,psidshift) = self._calc_ipv6bit_pos() + map_fullprefix = self._append_map_eabits(ipv4index, + addroffset, + psidshift, + psid) + mapce_prefix = "{}/{}".format( + IPv6Address(map_fullprefix), + self.rulev6mask + self.ealen + ) + return mapce_prefix + + def get_map_ipv4(self,mapce_address): + ipv4 = (int(IPv6Address(mapce_address)) & ( 0xffffffff << 16 )) >> 16 + return ip_address(ipv4) + + + +class DmrCalc(object): + + def __init__(self,dmr): + + # Validate and set BMR and BMR derived values + self.dmrprefix = self._check_dmr_prefix(dmr) + + def embed_6052addr(self,ipv4addr): + + try: + ipv4addrint = int(ip_address(ipv4addr)) + except ValueError: + print("Invalid IPv4 address {}".format(ipv4addr)) + sys.exit(1) + + if ( self.dmrprefix.prefixlen == 64 ): + ipv6int = ipv4addrint << 24 + ipv6int += int(self.dmrprefix.network_address) + return IPv6Address(ipv6int) + + if ( self.dmrprefix.prefixlen == 96 ): + ipv6int = ipv4addrint + ipv6int += int(self.dmrprefix.network_address) + return IPv6Address(ipv6int) + + def _check_dmr_prefix(self,dmrprefix): + try: + self.dmrmask = IPv6Network( + dmrprefix, + strict=False + ).prefixlen + except ValueError: + print("Invalid IPv6 prefix {}".format(prefix)) + sys.exit(1) + + if self.dmrmask not in (32,40,48,56,64,96): + print("Invalid prefix mask /{}".format(self.dmrmask)) + sys.exit(1) + + return IPv6Network(dmrprefix) + +if __name__ == "__main__": + m = DmrCalc('fd80::/48') + print(m.dmrprefix) diff --git a/vnet/vnet/map/examples/mt-test.py b/vnet/vnet/map/examples/mt-test.py new file mode 100644 index 00000000..62d269c7 --- /dev/null +++ b/vnet/vnet/map/examples/mt-test.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +# Copyright (c) 2009-2014 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import threading +import time +from scapy.all import * +from Queue import * + +iface = 'veth1' + +class SnifferThread(threading.Thread) : + def __init__(self,q,iface,flt,timeout) : + threading.Thread.__init__(self) + self.q = q + self.iface = iface + self.timeout = timeout + self.flt = flt + print("Sniffers reporting for service on ",self.iface) + + def run(self) : + conf.iface=self.iface + conf.iface6=self.iface + + r = sniff(filter=self.flt,iface=self.iface,timeout=self.timeout,prn=lambda x: x.summary()) + self.q.put(r) + + + +# New "SR" function +# Fire off thread with filter and expected answer packet(s). +# Fire off sniffer thread, main thread sends packet +# Returns true if found + +def sr2(answer, *args, **kwargs): + q = Queue() + print("Creating SnifferThreadWorkerThread") + flt='ip proto 41' + iface='veth1' + sniffer = SnifferThread(q,iface,flt,1) + sniffer.setDaemon(True) + sniffer.start() + + print "Sending packet:" + send(*args, **kwargs) + sniffer.join() + ps = q.get() + +# ps.summary() + print "Number of packets sniffed:", len(ps) + + for p in ps: + ip = p.getlayer(1) + print "Comparing", ip.summary(), "and", answer.summary() + if ip == answer: + print "We have a match!!" + return True + return False + +aip6 = IPv6(dst='2002:0a0a:0a0a::12')/ICMPv6EchoRequest() +answer= IP(src="10.0.0.100",dst="10.10.10.10",ttl=63)/aip6 +packet = IPv6(dst='2002:0a0a:0a0a::12')/ICMPv6EchoRequest() + +# From IPv6 +sr2(answer, packet,iface='veth1') + +#From IPv4 +packet = IP(src='10.10.10.10',dst='10.0.0.100')/IPv6(src='2002:0a0a:0a0a::12',dst='1::2')/ICMPv6EchoRequest() +sr2(answer, packet,iface='veth1') |