
"""icmp.py

Created by Thomas Mangin on 2010-01-15.
Copyright (c) 2009-2017 Exa Networks. All rights reserved.
License: 3-clause BSD. (See the COPYRIGHT file)
"""

from __future__ import annotations

from exabgp.protocol.resource import Resource


# ============================================================== ICMP Code Field
# https://www.iana.org/assignments/icmp-parameters


class ICMPType(Resource):
    NAME = 'icmp type'

    ECHO_REPLY = 0x00
    UNREACHABLE = 0x03
    REDIRECT = 0x05
    ECHO_REQUEST = 0x08
    ROUTER_ADVERTISEMENT = 0x09
    ROUTER_SOLICIT = 0x0A
    TIME_EXCEEDED = 0x0B
    PARAMETER_PROBLEM = 0x0C
    TIMESTAMP = 0x0D
    TIMESTAMP_REPLY = 0x0E
    PHOTURIS = 0x28
    EXPERIMENTAL_MOBILITY = 0x29
    EXTENDED_ECHO_REQUEST = 0x2A
    EXTENDED_ECHO_REPLY = 0x2B
    EXPERIMENTAL_ONE = 0xFD
    EXPERIMENTAL_TWO = 0xFE

    codes = dict(
        (k.lower().replace('_', '-'), v)
        for (k, v) in {
            'ECHO_REPLY': ECHO_REPLY,
            'UNREACHABLE': UNREACHABLE,
            'REDIRECT': REDIRECT,
            'ECHO_REQUEST': ECHO_REQUEST,
            'ROUTER_ADVERTISEMENT': ROUTER_ADVERTISEMENT,
            'ROUTER_SOLICIT': ROUTER_SOLICIT,
            'TIME_EXCEEDED': TIME_EXCEEDED,
            'PARAMETER_PROBLEM': PARAMETER_PROBLEM,
            'TIMESTAMP': TIMESTAMP,
            'TIMESTAMP_REPLY': TIMESTAMP_REPLY,
            'PHOTURIS': PHOTURIS,
            'EXPERIMENTAL_MOBILITY': EXPERIMENTAL_MOBILITY,
            'EXTENDED_ECHO_REQUEST': EXTENDED_ECHO_REQUEST,
            'EXTENDED_ECHO_REPLY': EXTENDED_ECHO_REPLY,
            'EXPERIMENTAL_ONE': EXPERIMENTAL_ONE,
            'EXPERIMENTAL_TWO': EXPERIMENTAL_TWO,
        }.items()
    )

    names = dict([(value, name) for (name, value) in codes.items()])


# https://www.iana.org/assignments/icmp-parameters
class ICMPCode(Resource):
    NAME = 'icmp code'

    # Destination Unreacheable (type 3)
    NETWORK_UNREACHABLE = 0x0
    HOST_UNREACHABLE = 0x1
    PROTOCOL_UNREACHABLE = 0x2
    PORT_UNREACHABLE = 0x3
    FRAGMENTATION_NEEDED = 0x4
    SOURCE_ROUTE_FAILED = 0x5
    DESTINATION_NETWORK_UNKNOWN = 0x6
    DESTINATION_HOST_UNKNOWN = 0x7
    SOURCE_HOST_ISOLATED = 0x8
    DESTINATION_NETWORK_PROHIBITED = 0x9
    DESTINATION_HOST_PROHIBITED = 0xA
    NETWORK_UNREACHABLE_FOR_TOS = 0xB
    HOST_UNREACHABLE_FOR_TOS = 0xC
    COMMUNICATION_PROHIBITED_BY_FILTERING = 0xD
    HOST_PRECEDENCE_VIOLATION = 0xE
    PRECEDENCE_CUTOFF_IN_EFFECT = 0xF

    # Redirect (Type 5)
    REDIRECT_FOR_NETWORK = 0x0
    REDIRECT_FOR_HOST = 0x1
    REDIRECT_FOR_TOS_AND_NET = 0x2
    REDIRECT_FOR_TOS_AND_HOST = 0x3

    # Time Exceeded (Type 11)
    TTL_EQ_ZERO_DURING_TRANSIT = 0x0
    TTL_EQ_ZERO_DURING_REASSEMBLY = 0x1

    # parameter Problem (Type 12)
    REQUIRED_OPTION_MISSING = 0x1
    IP_HEADER_BAD = 0x2

    codes = dict(
        (k.lower().replace('_', '-'), v)
        for (k, v) in {
            'NETWORK_UNREACHABLE': NETWORK_UNREACHABLE,
            'HOST_UNREACHABLE': HOST_UNREACHABLE,
            'PROTOCOL_UNREACHABLE': PROTOCOL_UNREACHABLE,
            'PORT_UNREACHABLE': PORT_UNREACHABLE,
            'FRAGMENTATION_NEEDED': FRAGMENTATION_NEEDED,
            'SOURCE_ROUTE_FAILED': SOURCE_ROUTE_FAILED,
            'DESTINATION_NETWORK_UNKNOWN': DESTINATION_NETWORK_UNKNOWN,
            'DESTINATION_HOST_UNKNOWN': DESTINATION_HOST_UNKNOWN,
            'SOURCE_HOST_ISOLATED': SOURCE_HOST_ISOLATED,
            'DESTINATION_NETWORK_PROHIBITED': DESTINATION_NETWORK_PROHIBITED,
            'DESTINATION_HOST_PROHIBITED': DESTINATION_HOST_PROHIBITED,
            'NETWORK_UNREACHABLE_FOR_TOS': NETWORK_UNREACHABLE_FOR_TOS,
            'HOST_UNREACHABLE_FOR_TOS': HOST_UNREACHABLE_FOR_TOS,
            'COMMUNICATION_PROHIBITED_BY_FILTERING': COMMUNICATION_PROHIBITED_BY_FILTERING,
            'HOST_PRECEDENCE_VIOLATION': HOST_PRECEDENCE_VIOLATION,
            'PRECEDENCE_CUTOFF_IN_EFFECT': PRECEDENCE_CUTOFF_IN_EFFECT,
            'REDIRECT_FOR_NETWORK': REDIRECT_FOR_NETWORK,
            'REDIRECT_FOR_HOST': REDIRECT_FOR_HOST,
            'REDIRECT_FOR_TOS_AND_NET': REDIRECT_FOR_TOS_AND_NET,
            'REDIRECT_FOR_TOS_AND_HOST': REDIRECT_FOR_TOS_AND_HOST,
            'TTL_EQ_ZERO_DURING_TRANSIT': TTL_EQ_ZERO_DURING_TRANSIT,
            'TTL_EQ_ZERO_DURING_REASSEMBLY': TTL_EQ_ZERO_DURING_REASSEMBLY,
            'REQUIRED_OPTION_MISSING': REQUIRED_OPTION_MISSING,
            'IP_HEADER_BAD': IP_HEADER_BAD,
        }.items()
    )

    # names would have non-unique keys

    def __str__(self):
        return '%d' % int(self)
