Home | History | Annotate | Download | only in contrib
      1 #!/usr/bin/env python
      2 
      3 # This file is part of Scapy
      4 # Scapy is free software: you can redistribute it and/or modify
      5 # it under the terms of the GNU General Public License as published by
      6 # the Free Software Foundation, either version 2 of the License, or
      7 # any later version.
      8 #
      9 # Scapy is distributed in the hope that it will be useful,
     10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12 # GNU General Public License for more details.
     13 #
     14 # You should have received a copy of the GNU General Public License
     15 # along with Scapy. If not, see <http://www.gnu.org/licenses/>.
     16 
     17 # scapy.contrib.description = IKEv2
     18 # scapy.contrib.status = loads
     19 
     20 import logging
     21 import struct
     22 
     23 
     24 ## Modified from the original ISAKMP code by Yaron Sheffer <yaronf.ietf (at] gmail.com>, June 2010.
     25 
     26 from scapy.packet import *
     27 from scapy.fields import *
     28 from scapy.layers.inet6 import *
     29 from scapy.layers.x509 import X509_Cert, X509_CRL
     30 from scapy.ansmachine import *
     31 from scapy.layers.inet import IP,UDP
     32 from scapy.layers.isakmp import ISAKMP
     33 from scapy.sendrecv import sr
     34 
     35 # see http://www.iana.org/assignments/ikev2-parameters for details
     36 IKEv2AttributeTypes= { "Encryption":    (1, { "DES-IV64"  : 1,
     37                                                 "DES" : 2,
     38                                                 "3DES" : 3,
     39                                                 "RC5" : 4,
     40                                                 "IDEA" : 5,
     41                                                 "CAST" : 6,
     42                                                 "Blowfish" : 7,
     43                                                 "3IDEA" : 8,
     44                                                 "DES-IV32" : 9,
     45                                                 "AES-CBC" : 12,
     46                                                 "AES-CTR" : 13,
     47                                                 "AES-CCM-8" : 14,
     48                                                 "AES-CCM-12" : 15,
     49                                                 "AES-CCM-16" : 16,
     50                                                 "AES-GCM-8ICV" : 18,
     51                                                 "AES-GCM-12ICV" : 19,
     52                                                 "AES-GCM-16ICV" : 20,
     53                                                 "Camellia-CBC" : 23,
     54                                                 "Camellia-CTR" : 24,
     55                                                 "Camellia-CCM-8ICV" : 25,
     56                                                 "Camellia-CCM-12ICV" : 26,
     57                                                 "Camellia-CCM-16ICV" : 27,
     58                                         }, 0),
     59                          "PRF":            (2, {"PRF_HMAC_MD5":1,
     60                                                 "PRF_HMAC_SHA1":2,
     61                                                 "PRF_HMAC_TIGER":3,
     62                                                 "PRF_AES128_XCBC":4,
     63                                                 "PRF_HMAC_SHA2_256":5,
     64                                                 "PRF_HMAC_SHA2_384":6,
     65                                                 "PRF_HMAC_SHA2_512":7,
     66                                                 "PRF_AES128_CMAC":8,
     67                                        }, 0),
     68                          "Integrity":    (3, { "HMAC-MD5-96": 1,
     69                                                 "HMAC-SHA1-96": 2,
     70                                                 "DES-MAC": 3,
     71                                                 "KPDK-MD5": 4,
     72                                                 "AES-XCBC-96": 5,
     73                                                 "HMAC-MD5-128": 6,
     74                                                 "HMAC-SHA1-160": 7,
     75                                                 "AES-CMAC-96": 8,
     76                                                 "AES-128-GMAC": 9,
     77                                                 "AES-192-GMAC": 10,
     78                                                 "AES-256-GMAC": 11,
     79                                                 "SHA2-256-128": 12,
     80                                                 "SHA2-384-192": 13,
     81                                                 "SHA2-512-256": 14,
     82                                         }, 0),
     83                          "GroupDesc":     (4, { "768MODPgr"  : 1,
     84                                                 "1024MODPgr" : 2,
     85                                                 "1536MODPgr" : 5,
     86                                                 "2048MODPgr" : 14,
     87                                                 "3072MODPgr" : 15,
     88                                                 "4096MODPgr" : 16,
     89                                                 "6144MODPgr" : 17,
     90                                                 "8192MODPgr" : 18,
     91                                                 "256randECPgr" : 19,
     92                                                 "384randECPgr" : 20,
     93                                                 "521randECPgr" : 21,
     94                                                 "1024MODP160POSgr"  : 22,
     95                                                 "2048MODP224POSgr"  : 23,
     96                                                 "2048MODP256POSgr"  : 24,
     97                                                 "192randECPgr" : 25,
     98                                                 "224randECPgr" : 26,
     99                                         }, 0),
    100                          "Extended Sequence Number":       (5, {"No ESN":     0,
    101                                                  "ESN":   1,  }, 0),
    102                          }
    103 
    104 IKEv2AuthenticationTypes = {
    105     0 : "Reserved",
    106     1 : "RSA Digital Signature",
    107     2 : "Shared Key Message Integrity Code",
    108     3 : "DSS Digital Signature",
    109     9 : "ECDSA with SHA-256 on the P-256 curve",
    110     10 : "ECDSA with SHA-384 on the P-384 curve",
    111     11 : "ECDSA with SHA-512 on the P-521 curve",
    112     12 : "Generic Secure Password Authentication Method",
    113     13 : "NULL Authentication",
    114     14 : "Digital Signature"
    115 }
    116 
    117 IKEv2NotifyMessageTypes = {
    118     1 : "UNSUPPORTED_CRITICAL_PAYLOAD",
    119     4 : "INVALID_IKE_SPI",
    120     5 : "INVALID_MAJOR_VERSION",
    121     7 : "INVALID_SYNTAX",
    122     9 : "INVALID_MESSAGE_ID",
    123     11 : "INVALID_SPI",
    124     14 : "NO_PROPOSAL_CHOSEN",
    125     17 : "INVALID_KE_PAYLOAD",
    126     24 : "AUTHENTICATION_FAILED",
    127     34 : "SINGLE_PAIR_REQUIRED",
    128     35 : "NO_ADDITIONAL_SAS",
    129     36 : "INTERNAL_ADDRESS_FAILURE",
    130     37 : "FAILED_CP_REQUIRED",
    131     38 : "TS_UNACCEPTABLE",
    132     39 : "INVALID_SELECTORS",
    133     40 : "UNACCEPTABLE_ADDRESSES",
    134     41 : "UNEXPECTED_NAT_DETECTED",
    135     42 : "USE_ASSIGNED_HoA",
    136     43 : "TEMPORARY_FAILURE",
    137     44 : "CHILD_SA_NOT_FOUND",
    138     45 : "INVALID_GROUP_ID",
    139     46 : "AUTHORIZATION_FAILED",
    140     16384 : "INITIAL_CONTACT",
    141     16385 : "SET_WINDOW_SIZE",
    142     16386 : "ADDITIONAL_TS_POSSIBLE",
    143     16387 : "IPCOMP_SUPPORTED",
    144     16388 : "NAT_DETECTION_SOURCE_IP",
    145     16389 : "NAT_DETECTION_DESTINATION_IP",
    146     16390 : "COOKIE",
    147     16391 : "USE_TRANSPORT_MODE",
    148     16392 : "HTTP_CERT_LOOKUP_SUPPORTED",
    149     16393 : "REKEY_SA",
    150     16394 : "ESP_TFC_PADDING_NOT_SUPPORTED",
    151     16395 : "NON_FIRST_FRAGMENTS_ALSO",
    152     16396 : "MOBIKE_SUPPORTED",
    153     16397 : "ADDITIONAL_IP4_ADDRESS",
    154     16398 : "ADDITIONAL_IP6_ADDRESS",
    155     16399 : "NO_ADDITIONAL_ADDRESSES",
    156     16400 : "UPDATE_SA_ADDRESSES",
    157     16401 : "COOKIE2",
    158     16402 : "NO_NATS_ALLOWED",
    159     16403 : "AUTH_LIFETIME",
    160     16404 : "MULTIPLE_AUTH_SUPPORTED",
    161     16405 : "ANOTHER_AUTH_FOLLOWS",
    162     16406 : "REDIRECT_SUPPORTED",
    163     16407 : "REDIRECT",
    164     16408 : "REDIRECTED_FROM",
    165     16409 : "TICKET_LT_OPAQUE",
    166     16410 : "TICKET_REQUEST",
    167     16411 : "TICKET_ACK",
    168     16412 : "TICKET_NACK",
    169     16413 : "TICKET_OPAQUE",
    170     16414 : "LINK_ID",
    171     16415 : "USE_WESP_MODE",
    172     16416 : "ROHC_SUPPORTED",
    173     16417 : "EAP_ONLY_AUTHENTICATION",
    174     16418 : "CHILDLESS_IKEV2_SUPPORTED",
    175     16419 : "QUICK_CRASH_DETECTION",
    176     16420 : "IKEV2_MESSAGE_ID_SYNC_SUPPORTED",
    177     16421 : "IPSEC_REPLAY_COUNTER_SYNC_SUPPORTED",
    178     16422 : "IKEV2_MESSAGE_ID_SYNC",
    179     16423 : "IPSEC_REPLAY_COUNTER_SYNC",
    180     16424 : "SECURE_PASSWORD_METHODS",
    181     16425 : "PSK_PERSIST",
    182     16426 : "PSK_CONFIRM",
    183     16427 : "ERX_SUPPORTED",
    184     16428 : "IFOM_CAPABILITY",
    185     16429 : "SENDER_REQUEST_ID",
    186     16430 : "IKEV2_FRAGMENTATION_SUPPORTED",
    187     16431 : "SIGNATURE_HASH_ALGORITHMS",
    188     16432 : "CLONE_IKE_SA_SUPPORTED",
    189     16433 : "CLONE_IKE_SA"
    190 }
    191 
    192 IKEv2CertificateEncodings = {
    193     1 : "PKCS #7 wrapped X.509 certificate",
    194     2 : "PGP Certificate",
    195     3 : "DNS Signed Key",
    196     4 : "X.509 Certificate - Signature",
    197     6 : "Kerberos Token",
    198     7 : "Certificate Revocation List (CRL)",
    199     8 : "Authority Revocation List (ARL)",
    200     9 : "SPKI Certificate",
    201     10 : "X.509 Certificate - Attribute",
    202     11 : "Raw RSA Key",
    203     12 : "Hash and URL of X.509 certificate",
    204     13 : "Hash and URL of X.509 bundle"
    205 }
    206 
    207 IKEv2TrafficSelectorTypes = {
    208     7 : "TS_IPV4_ADDR_RANGE",
    209     8 : "TS_IPV6_ADDR_RANGE",
    210     9 : "TS_FC_ADDR_RANGE"
    211 }
    212 
    213 IPProtocolIDs = {
    214     0 : "All protocols",
    215     1 : "Internet Control Message Protocol",
    216     2 : "Internet Group Management Protocol",
    217     3 : "Gateway-to-Gateway Protocol",
    218     4 : "IP in IP (encapsulation)",
    219     5 : "Internet Stream Protocol",
    220     6 : "Transmission Control Protocol",
    221     7 : "Core-based trees",
    222     8 : "Exterior Gateway Protocol",
    223     9 : "Interior Gateway Protocol (any private interior gateway (used by Cisco for their IGRP))",
    224     10 : "BBN RCC Monitoring",
    225     11 : "Network Voice Protocol",
    226     12 : "Xerox PUP",
    227     13 : "ARGUS",
    228     14 : "EMCON",
    229     15 : "Cross Net Debugger",
    230     16 : "Chaos",
    231     17 : "User Datagram Protocol",
    232     18 : "Multiplexing",
    233     19 : "DCN Measurement Subsystems",
    234     20 : "Host Monitoring Protocol",
    235     21 : "Packet Radio Measurement",
    236     22 : "XEROX NS IDP",
    237     23 : "Trunk-1",
    238     24 : "Trunk-2",
    239     25 : "Leaf-1",
    240     26 : "Leaf-2",
    241     27 : "Reliable Datagram Protocol",
    242     28 : "Internet Reliable Transaction Protocol",
    243     29 : "ISO Transport Protocol Class 4",
    244     30 : "Bulk Data Transfer Protocol",
    245     31 : "MFE Network Services Protocol",
    246     32 : "MERIT Internodal Protocol",
    247     33 : "Datagram Congestion Control Protocol",
    248     34 : "Third Party Connect Protocol",
    249     35 : "Inter-Domain Policy Routing Protocol",
    250     36 : "Xpress Transport Protocol",
    251     37 : "Datagram Delivery Protocol",
    252     38 : "IDPR Control Message Transport Protocol",
    253     39 : "TP++ Transport Protocol",
    254     40 : "IL Transport Protocol",
    255     41 : "IPv6 Encapsulation",
    256     42 : "Source Demand Routing Protocol",
    257     43 : "Routing Header for IPv6",
    258     44 : "Fragment Header for IPv6",
    259     45 : "Inter-Domain Routing Protocol",
    260     46 : "Resource Reservation Protocol",
    261     47 : "Generic Routing Encapsulation",
    262     48 : "Mobile Host Routing Protocol",
    263     49 : "BNA",
    264     50 : "Encapsulating Security Payload",
    265     51 : "Authentication Header",
    266     52 : "Integrated Net Layer Security Protocol",
    267     53 : "SwIPe",
    268     54 : "NBMA Address Resolution Protocol",
    269     55 : "IP Mobility (Min Encap)",
    270     56 : "Transport Layer Security Protocol (using Kryptonet key management)",
    271     57 : "Simple Key-Management for Internet Protocol",
    272     58 : "ICMP for IPv6",
    273     59 : "No Next Header for IPv6",
    274     60 : "Destination Options for IPv6",
    275     61 : "Any host internal protocol",
    276     62 : "CFTP",
    277     63 : "Any local network",
    278     64 : "SATNET and Backroom EXPAK",
    279     65 : "Kryptolan",
    280     66 : "MIT Remote Virtual Disk Protocol",
    281     67 : "Internet Pluribus Packet Core",
    282     68 : "Any distributed file system",
    283     69 : "SATNET Monitoring",
    284     70 : "VISA Protocol",
    285     71 : "Internet Packet Core Utility",
    286     72 : "Computer Protocol Network Executive",
    287     73 : "Computer Protocol Heart Beat",
    288     74 : "Wang Span Network",
    289     75 : "Packet Video Protocol",
    290     76 : "Backroom SATNET Monitoring",
    291     77 : "SUN ND PROTOCOL-Temporary",
    292     78 : "WIDEBAND Monitoring",
    293     79 : "WIDEBAND EXPAK",
    294     80 : "International Organization for Standardization Internet Protocol",
    295     81 : "Versatile Message Transaction Protocol",
    296     82 : "Secure Versatile Message Transaction Protocol",
    297     83 : "VINES",
    298     84 : "Internet Protocol Traffic Manager",
    299     85 : "NSFNET-IGP",
    300     86 : "Dissimilar Gateway Protocol",
    301     87 : "TCF",
    302     88 : "EIGRP",
    303     89 : "Open Shortest Path First",
    304     90 : "Sprite RPC Protocol",
    305     91 : "Locus Address Resolution Protocol",
    306     92 : "Multicast Transport Protocol",
    307     93 : "AX.25",
    308     94 : "IP-within-IP Encapsulation Protocol",
    309     95 : "Mobile Internetworking Control Protocol",
    310     96 : "Semaphore Communications Sec. Pro",
    311     97 : "Ethernet-within-IP Encapsulation",
    312     98 : "Encapsulation Header",
    313     99 : "Any private encryption scheme",
    314     100 : "GMTP",
    315     101 : "Ipsilon Flow Management Protocol",
    316     102 : "PNNI over IP",
    317     103 : "Protocol Independent Multicast",
    318     104 : "IBM's ARIS (Aggregate Route IP Switching) Protocol",
    319     105 : "SCPS (Space Communications Protocol Standards)",
    320     106 : "QNX",
    321     107 : "Active Networks",
    322     108 : "IP Payload Compression Protocol",
    323     109 : "Sitara Networks Protocol",
    324     110 : "Compaq Peer Protocol",
    325     111 : "IPX in IP",
    326     112 : "Virtual Router Redundancy Protocol, Common Address Redundancy Protocol (not IANA assigned)",
    327     113 : "PGM Reliable Transport Protocol",
    328     114 : "Any 0-hop protocol",
    329     115 : "Layer Two Tunneling Protocol Version 3",
    330     116 : "D-II Data Exchange (DDX)",
    331     117 : "Interactive Agent Transfer Protocol",
    332     118 : "Schedule Transfer Protocol",
    333     119 : "SpectraLink Radio Protocol",
    334     120 : "Universal Transport Interface Protocol",
    335     121 : "Simple Message Protocol",
    336     122 : "Simple Multicast Protocol",
    337     123 : "Performance Transparency Protocol",
    338     124 : "Intermediate System to Intermediate System (IS-IS) Protocol over IPv4",
    339     125 : "Flexible Intra-AS Routing Environment",
    340     126 : "Combat Radio Transport Protocol",
    341     127 : "Combat Radio User Datagram",
    342     128 : "Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment",
    343     129 : "IPLT",
    344     130 : "Secure Packet Shield",
    345     131 : "Private IP Encapsulation within IP",
    346     132 : "Stream Control Transmission Protocol",
    347     133 : "Fibre Channel",
    348     134 : "Reservation Protocol (RSVP) End-to-End Ignore",
    349     135 : "Mobility Extension Header for IPv6",
    350     136 : "Lightweight User Datagram Protocol",
    351     137 : "Multiprotocol Label Switching Encapsulated in IP",
    352     138 : "MANET Protocols",
    353     139 : "Host Identity Protocol",
    354     140 : "Site Multihoming by IPv6 Intermediation",
    355     141 : "Wrapped Encapsulating Security Payload",
    356     142 : "Robust Header Compression",
    357 }
    358 
    359 # the name 'IKEv2TransformTypes' is actually a misnomer (since the table 
    360 # holds info for all IKEv2 Attribute types, not just transforms, but we'll 
    361 # keep it for backwards compatibility... for now at least
    362 IKEv2TransformTypes = IKEv2AttributeTypes
    363 
    364 IKEv2TransformNum = {}
    365 for n in IKEv2TransformTypes:
    366     val = IKEv2TransformTypes[n]
    367     tmp = {}
    368     for e in val[1]:
    369         tmp[val[1][e]] = e
    370     IKEv2TransformNum[val[0]] = tmp
    371 
    372 IKEv2Transforms = {}
    373 for n in IKEv2TransformTypes:
    374     IKEv2Transforms[IKEv2TransformTypes[n][0]]=n
    375 
    376 del(n)
    377 del(e)
    378 del(tmp)
    379 del(val)
    380 
    381 # Note: Transform and Proposal can only be used inside the SA payload
    382 IKEv2_payload_type = ["None", "", "Proposal", "Transform"]
    383 
    384 IKEv2_payload_type.extend([""] * 29)
    385 IKEv2_payload_type.extend(["SA","KE","IDi","IDr", "CERT","CERTREQ","AUTH","Nonce","Notify","Delete",
    386                        "VendorID","TSi","TSr","Encrypted","CP","EAP", "", "", "", "", "Encrypted Fragment"])
    387 
    388 IKEv2_exchange_type = [""] * 34
    389 IKEv2_exchange_type.extend(["IKE_SA_INIT","IKE_AUTH","CREATE_CHILD_SA",
    390                         "INFORMATIONAL", "IKE_SESSION_RESUME"])
    391 
    392 
    393 class IKEv2_class(Packet):
    394     def guess_payload_class(self, payload):
    395         np = self.next_payload
    396         logging.debug("For IKEv2_class np=%d" % np)
    397         if np == 0:
    398             return conf.raw_layer
    399         elif np < len(IKEv2_payload_type):
    400             pt = IKEv2_payload_type[np]
    401             logging.debug(globals().get("IKEv2_payload_%s" % pt, IKEv2_payload))
    402             return globals().get("IKEv2_payload_%s" % pt, IKEv2_payload)
    403         else:
    404             return IKEv2_payload
    405 
    406 
    407 class IKEv2(IKEv2_class): # rfc4306
    408     name = "IKEv2"
    409     fields_desc = [
    410         StrFixedLenField("init_SPI","",8),
    411         StrFixedLenField("resp_SPI","",8),
    412         ByteEnumField("next_payload",0,IKEv2_payload_type),
    413         XByteField("version", 0x20),
    414         ByteEnumField("exch_type",0,IKEv2_exchange_type),
    415         FlagsField("flags",0, 8, ["res0","res1","res2","Initiator","Version","Response","res6","res7"]),
    416         IntField("id",0),
    417         IntField("length",None) # Length of total message: packets + all payloads
    418         ]
    419 
    420     def guess_payload_class(self, payload):
    421         if self.flags & 1:
    422             return conf.raw_layer
    423         return IKEv2_class.guess_payload_class(self, payload)
    424 
    425     def answers(self, other):
    426         if isinstance(other, IKEv2):
    427             if other.init_SPI == self.init_SPI:
    428                 return 1
    429         return 0
    430     def post_build(self, p, pay):
    431         p += pay
    432         if self.length is None:
    433             p = p[:24]+struct.pack("!I",len(p))+p[28:]
    434         return p
    435 
    436 
    437 class IKEv2_Key_Length_Attribute(IntField):
    438     # We only support the fixed-length Key Length attribute (the only one currently defined)
    439     def __init__(self, name):
    440         IntField.__init__(self, name, 0x800E0000)
    441 
    442     def i2h(self, pkt, x):
    443         return IntField.i2h(self, pkt, x & 0xFFFF)
    444 
    445     def h2i(self, pkt, x):
    446         return IntField.h2i(self, pkt, x if x !=None else 0 | 0x800E0000)
    447 
    448 class IKEv2_payload_Transform(IKEv2_class):
    449     name = "IKE Transform"
    450     fields_desc = [
    451         ByteEnumField("next_payload",None,{0:"last", 3:"Transform"}),
    452         ByteField("res",0),
    453         ShortField("length",8),
    454         ByteEnumField("transform_type",None,IKEv2Transforms),
    455         ByteField("res2",0),
    456         MultiEnumField("transform_id",None,IKEv2TransformNum,depends_on=lambda pkt:pkt.transform_type,fmt="H"),
    457         ConditionalField(IKEv2_Key_Length_Attribute("key_length"), lambda pkt: pkt.length > 8),
    458     ]
    459 
    460 class IKEv2_payload_Proposal(IKEv2_class):
    461     name = "IKEv2 Proposal"
    462     fields_desc = [
    463         ByteEnumField("next_payload",None,{0:"last", 2:"Proposal"}),
    464         ByteField("res",0),
    465         FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8+(pkt.SPIsize if pkt.SPIsize else 0)),
    466         ByteField("proposal",1),
    467         ByteEnumField("proto",1,{1:"IKEv2", 2:"AH", 3:"ESP"}),
    468         FieldLenField("SPIsize",None,"SPI","B"),
    469         ByteField("trans_nb",None),
    470         StrLenField("SPI","",length_from=lambda pkt:pkt.SPIsize),
    471         PacketLenField("trans",conf.raw_layer(),IKEv2_payload_Transform,length_from=lambda pkt:pkt.length-8-pkt.SPIsize),
    472         ]
    473 
    474 
    475 class IKEv2_payload(IKEv2_class):
    476     name = "IKEv2 Payload"
    477     fields_desc = [
    478         ByteEnumField("next_payload",None,IKEv2_payload_type),
    479         FlagsField("flags",0, 8, ["critical","res1","res2","res3","res4","res5","res6","res7"]),
    480         FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
    481         StrLenField("load","",length_from=lambda x:x.length-4),
    482         ]
    483 
    484 
    485 class IKEv2_payload_AUTH(IKEv2_class):
    486     name = "IKEv2 Authentication"
    487     overload_fields = { IKEv2: { "next_payload":39 }}
    488     fields_desc = [
    489         ByteEnumField("next_payload",None,IKEv2_payload_type),
    490         ByteField("res",0),
    491         FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+8),
    492         ByteEnumField("auth_type",None,IKEv2AuthenticationTypes),
    493         X3BytesField("res2",0),
    494         StrLenField("load","",length_from=lambda x:x.length-8),
    495         ]
    496 
    497 class IKEv2_payload_VendorID(IKEv2_class):
    498     name = "IKEv2 Vendor ID"
    499     overload_fields = { IKEv2: { "next_payload":43 }}
    500     fields_desc = [
    501         ByteEnumField("next_payload",None,IKEv2_payload_type),
    502         ByteField("res",0),
    503         FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
    504         StrLenField("vendorID","",length_from=lambda x:x.length-4),
    505         ]
    506 
    507 class TrafficSelector(Packet):
    508     @classmethod
    509     def dispatch_hook(cls, _pkt=None, *args, **kargs):
    510         if _pkt and len(_pkt) >= 16:
    511             ts_type = struct.unpack("!B", _pkt[0:1])[0]
    512             if ts_type == 7:
    513                 return IPv4TrafficSelector
    514             elif ts_type == 8:
    515                 return IPv6TrafficSelector
    516             elif ts_type == 9:
    517                 return EncryptedTrafficSelector
    518             else:
    519                 return RawTrafficSelector
    520         return IPv4TrafficSelector
    521 
    522 class IPv4TrafficSelector(TrafficSelector):
    523     name = "IKEv2 IPv4 Traffic Selector"
    524     fields_desc = [
    525         ByteEnumField("TS_type",7,IKEv2TrafficSelectorTypes),
    526         ByteEnumField("IP_protocol_ID",None,IPProtocolIDs),
    527         ShortField("length",16),
    528         ShortField("start_port",0),
    529         ShortField("end_port",65535),
    530         IPField("starting_address_v4","192.168.0.1"),
    531         IPField("ending_address_v4","192.168.0.255"),
    532         ]
    533 
    534 class IPv6TrafficSelector(TrafficSelector):
    535     name = "IKEv2 IPv6 Traffic Selector"
    536     fields_desc = [
    537         ByteEnumField("TS_type",8,IKEv2TrafficSelectorTypes),
    538         ByteEnumField("IP_protocol_ID",None,IPProtocolIDs),
    539         ShortField("length",20),
    540         ShortField("start_port",0),
    541         ShortField("end_port",65535),
    542         IP6Field("starting_address_v6","2001::"),
    543         IP6Field("ending_address_v6","2001::"),
    544         ]
    545 
    546 class EncryptedTrafficSelector(TrafficSelector):
    547     name = "IKEv2 Encrypted Traffic Selector"
    548     fields_desc = [
    549         ByteEnumField("TS_type",9,IKEv2TrafficSelectorTypes),
    550         ByteEnumField("IP_protocol_ID",None,IPProtocolIDs),
    551         ShortField("length",16),
    552         ByteField("res",0),
    553         X3BytesField("starting_address_FC",0),
    554         ByteField("res2",0),
    555         X3BytesField("ending_address_FC",0),
    556         ByteField("starting_R_CTL",0),
    557         ByteField("ending_R_CTL",0),
    558         ByteField("starting_type",0),
    559         ByteField("ending_type",0),
    560         ]
    561 
    562 class RawTrafficSelector(TrafficSelector):
    563     name = "IKEv2 Encrypted Traffic Selector"
    564     fields_desc = [
    565         ByteEnumField("TS_type",None,IKEv2TrafficSelectorTypes),
    566         ByteEnumField("IP_protocol_ID",None,IPProtocolIDs),
    567         FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
    568         PacketField("load", "", Raw)
    569         ]
    570 
    571 class IKEv2_payload_TSi(IKEv2_class):
    572     name = "IKEv2 Traffic Selector - Initiator"
    573     overload_fields = { IKEv2: { "next_payload":44 }}
    574     fields_desc = [
    575         ByteEnumField("next_payload",None,IKEv2_payload_type),
    576         ByteField("res",0),
    577         FieldLenField("length",None,"traffic_selector","H", adjust=lambda pkt,x:x+8),
    578         ByteField("number_of_TSs",0),
    579         X3BytesField("res2",0),
    580         PacketListField("traffic_selector",None,TrafficSelector,length_from=lambda x:x.length-8,count_from=lambda x:x.number_of_TSs),
    581         ]
    582 
    583 class IKEv2_payload_TSr(IKEv2_class):
    584     name = "IKEv2 Traffic Selector - Responder"
    585     overload_fields = { IKEv2: { "next_payload":45 }}
    586     fields_desc = [
    587         ByteEnumField("next_payload",None,IKEv2_payload_type),
    588         ByteField("res",0),
    589         FieldLenField("length",None,"traffic_selector","H", adjust=lambda pkt,x:x+8),
    590         ByteField("number_of_TSs",0),
    591         X3BytesField("res2",0),
    592         PacketListField("traffic_selector",None,TrafficSelector,length_from=lambda x:x.length-8,count_from=lambda x:x.number_of_TSs),
    593         ]
    594 
    595 class IKEv2_payload_Delete(IKEv2_class):
    596     name = "IKEv2 Vendor ID"
    597     overload_fields = { IKEv2: { "next_payload":42 }}
    598     fields_desc = [
    599         ByteEnumField("next_payload",None,IKEv2_payload_type),
    600         ByteField("res",0),
    601         FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
    602         StrLenField("vendorID","",length_from=lambda x:x.length-4),
    603         ]
    604 
    605 class IKEv2_payload_SA(IKEv2_class):
    606     name = "IKEv2 SA"
    607     overload_fields = { IKEv2: { "next_payload":33 }}
    608     fields_desc = [
    609         ByteEnumField("next_payload",None,IKEv2_payload_type),
    610         ByteField("res",0),
    611         FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+4),
    612         PacketLenField("prop",conf.raw_layer(),IKEv2_payload_Proposal,length_from=lambda x:x.length-4),
    613         ]
    614 
    615 class IKEv2_payload_Nonce(IKEv2_class):
    616     name = "IKEv2 Nonce"
    617     overload_fields = { IKEv2: { "next_payload":40 }}
    618     fields_desc = [
    619         ByteEnumField("next_payload",None,IKEv2_payload_type),
    620         ByteField("res",0),
    621         FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
    622         StrLenField("load","",length_from=lambda x:x.length-4),
    623         ]
    624 
    625 class IKEv2_payload_Notify(IKEv2_class):
    626     name = "IKEv2 Notify"
    627     overload_fields = { IKEv2: { "next_payload":41 }}
    628     fields_desc = [
    629         ByteEnumField("next_payload",None,IKEv2_payload_type),
    630         ByteField("res",0),
    631         FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+8),
    632         ByteEnumField("proto",None,{0:"Reserved",1:"IKE",2:"AH", 3:"ESP"}),
    633         FieldLenField("SPIsize",None,"SPI","B"),
    634         ShortEnumField("type",0,IKEv2NotifyMessageTypes),
    635         StrLenField("SPI","",length_from=lambda x:x.SPIsize),
    636         StrLenField("load","",length_from=lambda x:x.length-8),
    637         ]
    638 
    639 class IKEv2_payload_KE(IKEv2_class):
    640     name = "IKEv2 Key Exchange"
    641     overload_fields = { IKEv2: { "next_payload":34 }}
    642     fields_desc = [
    643         ByteEnumField("next_payload",None,IKEv2_payload_type),
    644         ByteField("res",0),
    645         FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+8),
    646         ShortEnumField("group", 0, IKEv2TransformTypes['GroupDesc'][1]),
    647         ShortField("res2", 0),
    648         StrLenField("load","",length_from=lambda x:x.length-8),
    649         ]
    650 
    651 class IKEv2_payload_IDi(IKEv2_class):
    652     name = "IKEv2 Identification - Initiator"
    653     overload_fields = { IKEv2: { "next_payload":35 }}
    654     fields_desc = [
    655         ByteEnumField("next_payload",None,IKEv2_payload_type),
    656         ByteField("res",0),
    657         FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
    658         ByteEnumField("IDtype",1,{1:"IPv4_addr", 2:"FQDN", 3:"Email_addr", 5:"IPv6_addr", 11:"Key"}),
    659         ByteEnumField("ProtoID",0,{0:"Unused"}),
    660         ShortEnumField("Port",0,{0:"Unused"}),
    661 #        IPField("IdentData","127.0.0.1"),
    662         StrLenField("load","",length_from=lambda x:x.length-8),
    663         ]
    664 
    665 class IKEv2_payload_IDr(IKEv2_class):
    666     name = "IKEv2 Identification - Responder"
    667     overload_fields = { IKEv2: { "next_payload":36 }}
    668     fields_desc = [
    669         ByteEnumField("next_payload",None,IKEv2_payload_type),
    670         ByteField("res",0),
    671         FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
    672         ByteEnumField("IDtype",1,{1:"IPv4_addr", 2:"FQDN", 3:"Email_addr", 5:"IPv6_addr", 11:"Key"}),
    673         ByteEnumField("ProtoID",0,{0:"Unused"}),
    674         ShortEnumField("Port",0,{0:"Unused"}),
    675 #        IPField("IdentData","127.0.0.1"),
    676         StrLenField("load","",length_from=lambda x:x.length-8),
    677         ]
    678 
    679 class IKEv2_payload_Encrypted(IKEv2_class):
    680     name = "IKEv2 Encrypted and Authenticated"
    681     overload_fields = { IKEv2: { "next_payload":46 }}
    682     fields_desc = [
    683         ByteEnumField("next_payload",None,IKEv2_payload_type),
    684         ByteField("res",0),
    685         FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
    686         StrLenField("load","",length_from=lambda x:x.length-4),
    687         ]
    688 
    689 class IKEv2_payload_Encrypted_Fragment(IKEv2_class):
    690     name = "IKEv2 Encrypted Fragment"
    691     overload_fields = {IKEv2: {"next_payload": 53}}
    692     fields_desc = [
    693         ByteEnumField("next_payload", None, IKEv2_payload_type),
    694         ByteField("res", 0),
    695         FieldLenField("length", None, "load", "H", adjust=lambda pkt, x: x+8),
    696         ShortField("frag_number", 1),
    697         ShortField("frag_total", 1),
    698         StrLenField("load", "", length_from=lambda x: x.length-8),
    699         ]
    700 
    701 class IKEv2_payload_CERTREQ(IKEv2_class):
    702     name = "IKEv2 Certificate Request"
    703     fields_desc = [
    704         ByteEnumField("next_payload",None,IKEv2_payload_type),
    705         ByteField("res",0),
    706         FieldLenField("length",None,"cert_data","H",adjust=lambda pkt,x:x+5),
    707         ByteEnumField("cert_type",0,IKEv2CertificateEncodings),
    708         StrLenField("cert_data","",length_from=lambda x:x.length-5),
    709         ]
    710 
    711 class IKEv2_payload_CERT(IKEv2_class):
    712     @classmethod
    713     def dispatch_hook(cls, _pkt=None, *args, **kargs):
    714         if _pkt and len(_pkt) >= 16:
    715             ts_type = struct.unpack("!B", _pkt[4:5])[0]
    716             if ts_type == 4:
    717                 return IKEv2_payload_CERT_CRT
    718             elif ts_type == 7:
    719                 return IKEv2_payload_CERT_CRL
    720             else:
    721                 return IKEv2_payload_CERT_STR
    722         return IKEv2_payload_CERT_STR
    723 
    724 class IKEv2_payload_CERT_CRT(IKEv2_payload_CERT):
    725     name = "IKEv2 Certificate"
    726     fields_desc = [
    727         ByteEnumField("next_payload",None,IKEv2_payload_type),
    728         ByteField("res",0),
    729         FieldLenField("length",None,"x509Cert","H",adjust=lambda pkt,x: x+len(pkt.x509Cert)+5),
    730         ByteEnumField("cert_type",4,IKEv2CertificateEncodings),
    731         PacketLenField("x509Cert", X509_Cert(''), X509_Cert, length_from=lambda x:x.length-5),
    732         ]
    733 
    734 class IKEv2_payload_CERT_CRL(IKEv2_payload_CERT):
    735     name = "IKEv2 Certificate"
    736     fields_desc = [
    737         ByteEnumField("next_payload",None,IKEv2_payload_type),
    738         ByteField("res",0),
    739         FieldLenField("length",None,"x509CRL","H",adjust=lambda pkt,x: x+len(pkt.x509CRL)+5),
    740         ByteEnumField("cert_type",7,IKEv2CertificateEncodings),
    741         PacketLenField("x509CRL", X509_CRL(''), X509_CRL, length_from=lambda x:x.length-5),
    742         ]
    743 
    744 class IKEv2_payload_CERT_STR(IKEv2_payload_CERT):
    745     name = "IKEv2 Certificate"
    746     fields_desc = [
    747         ByteEnumField("next_payload",None,IKEv2_payload_type),
    748         ByteField("res",0),
    749         FieldLenField("length",None,"cert_data","H",adjust=lambda pkt,x: x+5),
    750         ByteEnumField("cert_type",0,IKEv2CertificateEncodings),
    751         StrLenField("cert_data","",length_from=lambda x:x.length-5),
    752         ]
    753 
    754 IKEv2_payload_type_overload = {}
    755 for i, payloadname in enumerate(IKEv2_payload_type):
    756     name = "IKEv2_payload_%s" % payloadname
    757     if name in globals():
    758         IKEv2_payload_type_overload[globals()[name]] = {"next_payload": i}
    759 
    760 del i, payloadname, name
    761 IKEv2_class._overload_fields = IKEv2_payload_type_overload.copy()
    762 
    763 split_layers(UDP, ISAKMP, sport=500)
    764 split_layers(UDP, ISAKMP, dport=500)
    765 
    766 bind_layers( UDP,           IKEv2,        dport=500, sport=500) # TODO: distinguish IKEv1/IKEv2
    767 bind_layers( UDP,           IKEv2,        dport=4500, sport=4500)
    768 
    769 def ikev2scan(ip, **kwargs):
    770     """Send a IKEv2 SA to an IP and wait for answers."""
    771     return sr(IP(dst=ip)/UDP()/IKEv2(init_SPI=RandString(8),
    772                                       exch_type=34)/IKEv2_payload_SA(prop=IKEv2_payload_Proposal()), **kwargs)
    773