import unittest
import socket

from scapy.layers.inet import IP, ICMP, TCP
from scapy.layers.ipsec import SecurityAssociation
from scapy.layers.l2 import Ether, Raw
from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest

from framework import VppTestCase, VppTestRunner
from util import ppp
from vpp_papi import VppEnum


class IPsecIPv4Params(object):

    addr_type = socket.AF_INET
    addr_any = "0.0.0.0"
    addr_bcast = "255.255.255.255"
    addr_len = 32
    is_ipv6 = 0

    def __init__(self):
        self.remote_tun_if_host = '1.1.1.1'

        self.scapy_tun_sa_id = 10
        self.scapy_tun_spi = 1001
        self.vpp_tun_sa_id = 20
        self.vpp_tun_spi = 1000

        self.scapy_tra_sa_id = 30
        self.scapy_tra_spi = 2001
        self.vpp_tra_sa_id = 40
        self.vpp_tra_spi = 2000

        self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t.
                                 IPSEC_API_INTEG_ALG_SHA1_96)
        self.auth_algo = 'HMAC-SHA1-96'  # scapy name
        self.auth_key = 'C91KUR9GYMm5GfkEvNjX'

        self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_128)
        self.crypt_algo = 'AES-CBC'  # scapy name
        self.crypt_key = 'JPjyOWBeVEQiMe7h'


class IPsecIPv6Params(object):

    addr_type = socket.AF_INET6
    addr_any = "0::0"
    addr_bcast = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
    addr_len = 128
    is_ipv6 = 1

    def __init__(self):
        self.remote_tun_if_host = '1111:1111:1111:1111:1111:1111:1111:1111'

        self.scapy_tun_sa_id = 50
        self.scapy_tun_spi = 3001
        self.vpp_tun_sa_id = 60
        self.vpp_tun_spi = 3000

        self.scapy_tra_sa_id = 70
        self.scapy_tra_spi = 4001
        self.vpp_tra_sa_id = 80
        self.vpp_tra_spi = 4000

        self.auth_algo_vpp_id = (VppEnum.vl_api_ipsec_integ_alg_t.
                                 IPSEC_API_INTEG_ALG_SHA_256_128)
        self.auth_algo = 'SHA2-256-128'  # scapy name
        self.auth_key = 'C91KUR9GYMm5GfkEvNjX'

        self.crypt_algo_vpp_id = (VppEnum.vl_api_ipsec_crypto_alg_t.
                                  IPSEC_API_CRYPTO_ALG_AES_CBC_256)
        self.crypt_algo = 'AES-CBC'  # scapy name
        self.crypt_key = 'JPjyOWBeVEQiMe7hJPjyOWBeVEQiMe7h'


class TemplateIpsec(VppTestCase):
    """
    TRANSPORT MODE:

     ------   encrypt   ---
    |tra_if| <-------> |VPP|
     ------   decrypt   ---

    TUNNEL MODE:

     ------   encrypt   ---   plain   ---
    |tun_if| <-------  |VPP| <------ |pg1|
     ------             ---           ---

     ------   decrypt   ---   plain   ---
    |tun_if| ------->  |VPP| ------> |pg1|
     ------             ---           ---
    """

    def ipsec_select_backend(self):
        """ empty method to be overloaded when necessary """
        pass

    def setUp(self):
        super(TemplateIpsec, self).setUp()

        self.ipv4_params = IPsecIPv4Params()
        self.ipv6_params = IPsecIPv6Params()
        self.params = {self.ipv4_params.addr_type: self.ipv4_params,
                       self.ipv6_params.addr_type: self.ipv6_params}

        self.payload = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"\
                       "XXXXXXXXXXXXXXXXXXXXX"

        self.tun_spd_id = 1
        self.tra_spd_id = 2

        self.vpp_esp_protocol = (VppEnum.vl_api_ipsec_proto_t.
                                 IPSEC_API_PROTO_ESP)
        self.vpp_ah_protocol = (VppEnum.vl_api_ipsec_proto_t.
                                IPSEC_API_PROTO_AH)

        self.create_pg_interfaces(range(3))
        self.interfaces = list(self.pg_interfaces)
        for i in self.interfaces:
            i.admin_up()
            i.config_ip4()
            i.resolve_arp()
            i.config_ip6()
            i.resolve_ndp()
        self.ipsec_select_backend()

    def tearDown(self):
        super(TemplateIpsec, self).tearDown()

        for i in self.interfaces:
            i.admin_down()
            i.unconfig_ip4()
            i.unconfig_ip6()

        if not self.vpp_dead:
            self.vapi.cli("show hardware")

    def gen_encrypt_pkts(self, sa, sw_intf, src, dst, count=1):
        return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
                sa.encrypt(IP(src=src, dst=dst) / ICMP() / self.payload)
                for i in range(count)]

    def gen_encrypt_pkts6(self, sa, sw_intf, src, dst, count=1):
        return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
                sa.encrypt(IPv6(src=src, dst=dst) /
                           ICMPv6EchoRequest(id=0, seq=1, data=self.payload))
                for i in range(count)]

    def gen_pkts(self, sw_intf, src, dst, count=1):
        return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
                IP(src=src, dst=dst) / ICMP() / self.payload
                for i in range(count)]

    def gen_pkts6(self, sw_intf, src, dst, count=1):
        return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
                IPv6(src=src, dst=dst) /
                ICMPv6EchoRequest(id=0, seq=1, data=self.payload)
                for i in range(count)]

    def configure_sa_tun(self, params):
        ip_class_by_addr_type = {socket.AF_INET: IP, socket.AF_INET6: IPv6}
        scapy_tun_sa = SecurityAssociation(
            self.encryption_type, spi=params.vpp_tun_spi,
            crypt_algo=params.crypt_algo, crypt_key=params.crypt_key,
            auth_algo=params.auth_algo, auth_key=params.auth_key,
            tunnel_header=ip_class_by_addr_type[params.addr_type](
                src=self.tun_if.remote_addr[params.addr_type],
                dst=self.tun_if.local_addr[params.addr_type]))
        vpp_tun_sa = SecurityAssociation(
            self.encryption_type, spi=params.scapy_tun_spi,
            crypt_algo=params.crypt_algo, crypt_key=params.crypt_key,
            auth_algo=params.auth_algo, auth_key=params.auth_key,
            tunnel_header=ip_class_by_addr_type[params.addr_type](
                dst=self.tun_if.remote_addr[params.addr_type],
                src=self.tun_if.local_addr[params.addr_type]))
        return vpp_tun_sa, scapy_tun_sa

    def configure_sa_tra(self, params):
        params.scapy_tra_sa = SecurityAssociation(self.encryption_type,
                                                  spi=params.vpp_tra_spi,
                                                  crypt_algo=params.crypt_algo,
                                                  crypt_key=params.crypt_key,
                                                  auth_algo=params.auth_algo,
                                                  auth_key=params.auth_key)
        params.vpp_tra_sa = SecurityAssociation(self.encryption_type,
                                                spi=params.scapy_tra_spi,
                                                crypt_algo=params.crypt_algo,
                                                crypt_key=params.crypt_key,
                                                auth_algo=params.auth_algo,
                                                auth_key=params.auth_key)


class IpsecTcpTests(object):
    def test_tcp_checksum(self):
        """ verify checksum correctness for vpp generated packets """
        self.vapi.cli("test http server")
        p = self.params[socket.AF_INET]
        vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun(p)
        send = (Ether(src=self.tun_if.remote_mac, dst=self.tun_if.local_mac) /
                scapy_tun_sa.encrypt(IP(src=p.remote_tun_if_host,
                                        dst=self.tun_if.local_ip4) /
                                     TCP(flags='S', dport=80)))
        self.logger.debug(ppp("Sending packet:", send))
        recv = self.send_and_expect(self.tun_if, [send], self.tun_if)
        recv = recv[0]
        decrypted = vpp_tun_sa.decrypt(recv[IP])
        self.assert_packet_checksums_valid(decrypted)


class IpsecTraTests(object):
    def test_tra_anti_replay(self, count=1):
        """ ipsec v4 transport anti-reply test """
        p = self.params[socket.AF_INET]

        # fire in a packet with seq number 1
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=1))
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # now move the window over to 235
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=235))
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # the window size is 64 packets
        # in window are still accepted
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=172))
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # out of window are dropped
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=17))
        self.send_and_assert_no_replies(self.tra_if, pkt * 17)

        self.assert_packet_counter_equal(
            '/err/%s/SA replayed packet' % self.tra4_decrypt_node_name, 17)

        # a packet that does not decrypt does not move the window forward
        bogus_sa = SecurityAssociation(self.encryption_type,
                                       p.vpp_tra_spi)
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                   dst=self.tra_if.local_ip4) /
                                ICMP(),
                                seq_num=350))
        self.send_and_assert_no_replies(self.tra_if, pkt * 17)

        self.assert_packet_counter_equal(
            '/err/%s/Integrity check failed' % self.tra4_decrypt_node_name, 17)

        # which we can determine since this packet is still in the window
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=234))
        self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # move the security-associations seq number on to the last we used
        p.scapy_tra_sa.seq_num = 351
        p.vpp_tra_sa.seq_num = 351

    def test_tra_basic(self, count=1):
        """ ipsec v4 transport basic test """
        self.vapi.cli("clear errors")
        try:
            p = self.params[socket.AF_INET]
            send_pkts = self.gen_encrypt_pkts(p.scapy_tra_sa, self.tra_if,
                                              src=self.tra_if.remote_ip4,
                                              dst=self.tra_if.local_ip4,
                                              count=count)
            recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
                                             self.tra_if)
            for rx in recv_pkts:
                try:
                    decrypted = p.vpp_tra_sa.decrypt(rx[IP])
                    self.assert_packet_checksums_valid(decrypted)
                except:
                    self.logger.debug(ppp("Unexpected packet:", rx))
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec"))

        self.assert_packet_counter_equal(self.tra4_encrypt_node_name, count)
        self.assert_packet_counter_equal(self.tra4_decrypt_node_name, count)

    def test_tra_burst(self):
        """ ipsec v4 transport burst test """
        self.test_tra_basic(count=257)

    def test_tra_basic6(self, count=1):
        """ ipsec v6 transport basic test """
        self.vapi.cli("clear errors")
        try:
            p = self.params[socket.AF_INET6]
            send_pkts = self.gen_encrypt_pkts6(p.scapy_tra_sa, self.tra_if,
                                               src=self.tra_if.remote_ip6,
                                               dst=self.tra_if.local_ip6,
                                               count=count)
            recv_pkts = self.send_and_expect(self.tra_if, send_pkts,
                                             self.tra_if)
            for rx in recv_pkts:
                try:
                    decrypted = p.vpp_tra_sa.decrypt(rx[IPv6])
                    self.assert_packet_checksums_valid(decrypted)
                except:
                    self.logger.debug(ppp("Unexpected packet:", rx))
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec"))

        self.assert_packet_counter_equal(self.tra6_encrypt_node_name, count)
        self.assert_packet_counter_equal(self.tra6_decrypt_node_name, count)

    def test_tra_burst6(self):
        """ ipsec v6 transport burst test """
        self.test_tra_basic6(count=257)


class IpsecTun4Tests(object):
    def test_tun_basic44(self, count=1):
        """ ipsec 4o4 tunnel basic test """
        self.vapi.cli("clear errors")
        try:
            p = self.params[socket.AF_INET]
            vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun(p)
            send_pkts = self.gen_encrypt_pkts(scapy_tun_sa, self.tun_if,
                                              src=p.remote_tun_if_host,
                                              dst=self.pg1.remote_ip4,
                                              count=count)
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
            for recv_pkt in recv_pkts:
                self.assert_equal(recv_pkt[IP].src, p.remote_tun_if_host)
                self.assert_equal(recv_pkt[IP].dst, self.pg1.remote_ip4)
                self.assert_packet_checksums_valid(recv_pkt)
            send_pkts = self.gen_pkts(self.pg1, src=self.pg1.remote_ip4,
                                      dst=p.remote_tun_if_host, count=count)
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
            for recv_pkt in recv_pkts:
                try:
                    decrypt_pkt = vpp_tun_sa.decrypt(recv_pkt[IP])
                    if not decrypt_pkt.haslayer(IP):
                        decrypt_pkt = IP(decrypt_pkt[Raw].load)
                    self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip4)
                    self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
                    self.assert_packet_checksums_valid(decrypt_pkt)
                except:
                    self.logger.debug(ppp("Unexpected packet:", recv_pkt))
                    try:
                        self.logger.debug(
                            ppp("Decrypted packet:", decrypt_pkt))
                    except:
                        pass
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec"))

        if (hasattr(p, "spd_policy_in_any")):
            pkts = p.spd_policy_in_any.get_stats()['packets']
            self.assertEqual(pkts, count,
                             "incorrect SPD any policy: expected %d != %d" %
                             (count, pkts))
        self.assert_packet_counter_equal(self.tun4_encrypt_node_name, count)
        self.assert_packet_counter_equal(self.tun4_decrypt_node_name, count)

    def test_tun_burst44(self):
        """ ipsec 4o4 tunnel burst test """
        self.test_tun_basic44(count=257)


class IpsecTun6Tests(object):
    def test_tun_basic66(self, count=1):
        """ ipsec 6o6 tunnel basic test """
        self.vapi.cli("clear errors")
        try:
            p = self.params[socket.AF_INET6]
            vpp_tun_sa, scapy_tun_sa = self.configure_sa_tun(p)
            send_pkts = self.gen_encrypt_pkts6(scapy_tun_sa, self.tun_if,
                                               src=p.remote_tun_if_host,
                                               dst=self.pg1.remote_ip6,
                                               count=count)
            recv_pkts = self.send_and_expect(self.tun_if, send_pkts, self.pg1)
            for recv_pkt in recv_pkts:
                self.assert_equal(recv_pkt[IPv6].src, p.remote_tun_if_host)
                self.assert_equal(recv_pkt[IPv6].dst, self.pg1.remote_ip6)
                self.assert_packet_checksums_valid(recv_pkt)
            send_pkts = self.gen_pkts6(self.pg1, src=self.pg1.remote_ip6,
                                       dst=p.remote_tun_if_host,
                                       count=count)
            recv_pkts = self.send_and_expect(self.pg1, send_pkts, self.tun_if)
            for recv_pkt in recv_pkts:
                try:
                    decrypt_pkt = vpp_tun_sa.decrypt(recv_pkt[IPv6])
                    if not decrypt_pkt.haslayer(IPv6):
                        decrypt_pkt = IPv6(decrypt_pkt[Raw].load)
                    self.assert_equal(decrypt_pkt.src, self.pg1.remote_ip6)
                    self.assert_equal(decrypt_pkt.dst, p.remote_tun_if_host)
                    self.assert_packet_checksums_valid(decrypt_pkt)
                except:
                    self.logger.debug(ppp("Unexpected packet:", recv_pkt))
                    try:
                        self.logger.debug(
                            ppp("Decrypted packet:", decrypt_pkt))
                    except:
                        pass
                    raise
        finally:
            self.logger.info(self.vapi.ppcli("show error"))
            self.logger.info(self.vapi.ppcli("show ipsec"))

        self.assert_packet_counter_equal(self.tun6_encrypt_node_name, count)
        self.assert_packet_counter_equal(self.tun6_decrypt_node_name, count)

    def test_tun_burst66(self):
        """ ipsec 6o6 tunnel burst test """
        self.test_tun_basic66(count=257)


class IpsecTunTests(IpsecTun4Tests, IpsecTun6Tests):
    pass


if __name__ == '__main__':
    unittest.main(testRunner=VppTestRunner)
