1f7d24e3fSHanoh Haim## This file is part of Scapy
2f7d24e3fSHanoh Haim## See http://www.secdev.org/projects/scapy for more informations
3f7d24e3fSHanoh Haim## Copyright (C) Philippe Biondi <phil@secdev.org>
4f7d24e3fSHanoh Haim## This program is published under a GPLv2 license
5f7d24e3fSHanoh Haim
6f7d24e3fSHanoh Haim"""
7f7d24e3fSHanoh HaimISAKMP (Internet Security Association and Key Management Protocol).
8f7d24e3fSHanoh Haim"""
9f7d24e3fSHanoh Haim
10f7d24e3fSHanoh Haimimport struct
11f7d24e3fSHanoh Haimfrom scapy.packet import *
12f7d24e3fSHanoh Haimfrom scapy.fields import *
13f7d24e3fSHanoh Haimfrom scapy.ansmachine import *
14f7d24e3fSHanoh Haimfrom scapy.layers.inet import IP,UDP
15f7d24e3fSHanoh Haimfrom scapy.sendrecv import sr
16f7d24e3fSHanoh Haim
17f7d24e3fSHanoh Haim
18f7d24e3fSHanoh Haim# see http://www.iana.org/assignments/ipsec-registry for details
19f7d24e3fSHanoh HaimISAKMPAttributeTypes= { "Encryption":    (1, { "DES-CBC"  : 1,
20f7d24e3fSHanoh Haim                                                "IDEA-CBC" : 2,
21f7d24e3fSHanoh Haim                                                "Blowfish-CBC" : 3,
22f7d24e3fSHanoh Haim                                                "RC5-R16-B64-CBC" : 4,
23f7d24e3fSHanoh Haim                                                "3DES-CBC" : 5,
24f7d24e3fSHanoh Haim                                                "CAST-CBC" : 6,
25f7d24e3fSHanoh Haim                                                "AES-CBC" : 7,
26f7d24e3fSHanoh Haim                                                "CAMELLIA-CBC" : 8, }, 0),
27f7d24e3fSHanoh Haim                         "Hash":          (2, { "MD5": 1,
28f7d24e3fSHanoh Haim                                                "SHA": 2,
29f7d24e3fSHanoh Haim                                                "Tiger": 3,
30f7d24e3fSHanoh Haim                                                "SHA2-256": 4,
31f7d24e3fSHanoh Haim                                                "SHA2-384": 5,
32f7d24e3fSHanoh Haim                                                "SHA2-512": 6,}, 0),
33f7d24e3fSHanoh Haim                         "Authentication":(3, { "PSK": 1,
34f7d24e3fSHanoh Haim                                                "DSS": 2,
35f7d24e3fSHanoh Haim                                                "RSA Sig": 3,
36f7d24e3fSHanoh Haim                                                "RSA Encryption": 4,
37f7d24e3fSHanoh Haim                                                "RSA Encryption Revised": 5,
38f7d24e3fSHanoh Haim                                                "ElGamal Encryption": 6,
39f7d24e3fSHanoh Haim                                                "ElGamal Encryption Revised": 7,
40f7d24e3fSHanoh Haim                                                "ECDSA Sig": 8,
41f7d24e3fSHanoh Haim                                                "HybridInitRSA": 64221,
42f7d24e3fSHanoh Haim                                                "HybridRespRSA": 64222,
43f7d24e3fSHanoh Haim                                                "HybridInitDSS": 64223,
44f7d24e3fSHanoh Haim                                                "HybridRespDSS": 64224,
45f7d24e3fSHanoh Haim                                                "XAUTHInitPreShared": 65001,
46f7d24e3fSHanoh Haim                                                "XAUTHRespPreShared": 65002,
47f7d24e3fSHanoh Haim                                                "XAUTHInitDSS": 65003,
48f7d24e3fSHanoh Haim                                                "XAUTHRespDSS": 65004,
49f7d24e3fSHanoh Haim                                                "XAUTHInitRSA": 65005,
50f7d24e3fSHanoh Haim                                                "XAUTHRespRSA": 65006,
51f7d24e3fSHanoh Haim                                                "XAUTHInitRSAEncryption": 65007,
52f7d24e3fSHanoh Haim                                                "XAUTHRespRSAEncryption": 65008,
53f7d24e3fSHanoh Haim                                                "XAUTHInitRSARevisedEncryption": 65009,
54f7d24e3fSHanoh Haim                                                "XAUTHRespRSARevisedEncryptio": 65010, }, 0),
55f7d24e3fSHanoh Haim                         "GroupDesc":     (4, { "768MODPgr"  : 1,
56f7d24e3fSHanoh Haim                                                "1024MODPgr" : 2,
57f7d24e3fSHanoh Haim                                                "EC2Ngr155"  : 3,
58f7d24e3fSHanoh Haim                                                "EC2Ngr185"  : 4,
59f7d24e3fSHanoh Haim                                                "1536MODPgr" : 5,
60f7d24e3fSHanoh Haim                                                "2048MODPgr" : 14,
61f7d24e3fSHanoh Haim                                                "3072MODPgr" : 15,
62f7d24e3fSHanoh Haim                                                "4096MODPgr" : 16,
63f7d24e3fSHanoh Haim                                                "6144MODPgr" : 17,
64f7d24e3fSHanoh Haim                                                "8192MODPgr" : 18, }, 0),
65f7d24e3fSHanoh Haim                         "GroupType":      (5,  {"MODP":       1,
66f7d24e3fSHanoh Haim                                                 "ECP":        2,
67f7d24e3fSHanoh Haim                                                 "EC2N":       3}, 0),
68f7d24e3fSHanoh Haim                         "GroupPrime":     (6,  {}, 1),
69f7d24e3fSHanoh Haim                         "GroupGenerator1":(7,  {}, 1),
70f7d24e3fSHanoh Haim                         "GroupGenerator2":(8,  {}, 1),
71f7d24e3fSHanoh Haim                         "GroupCurveA":    (9,  {}, 1),
72f7d24e3fSHanoh Haim                         "GroupCurveB":    (10, {}, 1),
73f7d24e3fSHanoh Haim                         "LifeType":       (11, {"Seconds":     1,
74f7d24e3fSHanoh Haim                                                 "Kilobytes":   2,  }, 0),
75f7d24e3fSHanoh Haim                         "LifeDuration":   (12, {}, 1),
76f7d24e3fSHanoh Haim                         "PRF":            (13, {}, 0),
77f7d24e3fSHanoh Haim                         "KeyLength":      (14, {}, 0),
78f7d24e3fSHanoh Haim                         "FieldSize":      (15, {}, 0),
79f7d24e3fSHanoh Haim                         "GroupOrder":     (16, {}, 1),
80f7d24e3fSHanoh Haim                         }
81f7d24e3fSHanoh Haim
82f7d24e3fSHanoh Haim# the name 'ISAKMPTransformTypes' is actually a misnomer (since the table
83f7d24e3fSHanoh Haim# holds info for all ISAKMP Attribute types, not just transforms, but we'll
84f7d24e3fSHanoh Haim# keep it for backwards compatibility... for now at least
85f7d24e3fSHanoh HaimISAKMPTransformTypes = ISAKMPAttributeTypes
86f7d24e3fSHanoh Haim
87f7d24e3fSHanoh HaimISAKMPTransformNum = {}
88f7d24e3fSHanoh Haimfor n in ISAKMPTransformTypes:
89f7d24e3fSHanoh Haim    val = ISAKMPTransformTypes[n]
90f7d24e3fSHanoh Haim    tmp = {}
91f7d24e3fSHanoh Haim    for e in val[1]:
92f7d24e3fSHanoh Haim        tmp[val[1][e]] = e
93f7d24e3fSHanoh Haim    ISAKMPTransformNum[val[0]] = (n,tmp, val[2])
94f7d24e3fSHanoh Haimdel(n)
95f7d24e3fSHanoh Haimdel(e)
96f7d24e3fSHanoh Haimdel(tmp)
97f7d24e3fSHanoh Haimdel(val)
98f7d24e3fSHanoh Haim
99f7d24e3fSHanoh Haim
100f7d24e3fSHanoh Haimclass ISAKMPTransformSetField(StrLenField):
101f7d24e3fSHanoh Haim    islist=1
102f7d24e3fSHanoh Haim    def type2num(self, (typ,val)):
103f7d24e3fSHanoh Haim        type_val,enc_dict,tlv = ISAKMPTransformTypes.get(typ, (typ,{},0))
104f7d24e3fSHanoh Haim        val = enc_dict.get(val, val)
105f7d24e3fSHanoh Haim        s = ""
106f7d24e3fSHanoh Haim        if (val & ~0xffff):
107f7d24e3fSHanoh Haim            if not tlv:
108f7d24e3fSHanoh Haim                warning("%r should not be TLV but is too big => using TLV encoding" % typ)
109f7d24e3fSHanoh Haim            n = 0
110f7d24e3fSHanoh Haim            while val:
111f7d24e3fSHanoh Haim                s = chr(val&0xff)+s
112f7d24e3fSHanoh Haim                val >>= 8
113f7d24e3fSHanoh Haim                n += 1
114f7d24e3fSHanoh Haim            val = n
115f7d24e3fSHanoh Haim        else:
116f7d24e3fSHanoh Haim            type_val |= 0x8000
117f7d24e3fSHanoh Haim        return struct.pack("!HH",type_val, val)+s
118f7d24e3fSHanoh Haim    def num2type(self, typ, enc):
119f7d24e3fSHanoh Haim        val = ISAKMPTransformNum.get(typ,(typ,{}))
120f7d24e3fSHanoh Haim        enc = val[1].get(enc,enc)
121f7d24e3fSHanoh Haim        return (val[0],enc)
122f7d24e3fSHanoh Haim    def i2m(self, pkt, i):
123f7d24e3fSHanoh Haim        if i is None:
124f7d24e3fSHanoh Haim            return ""
125f7d24e3fSHanoh Haim        i = map(self.type2num, i)
126f7d24e3fSHanoh Haim        return "".join(i)
127f7d24e3fSHanoh Haim    def m2i(self, pkt, m):
128f7d24e3fSHanoh Haim        # I try to ensure that we don't read off the end of our packet based
129f7d24e3fSHanoh Haim        # on bad length fields we're provided in the packet. There are still
130f7d24e3fSHanoh Haim        # conditions where struct.unpack() may not get enough packet data, but
131f7d24e3fSHanoh Haim        # worst case that should result in broken attributes (which would
132f7d24e3fSHanoh Haim        # be expected). (wam)
133f7d24e3fSHanoh Haim        lst = []
134f7d24e3fSHanoh Haim        while len(m) >= 4:
135f7d24e3fSHanoh Haim            trans_type, = struct.unpack("!H", m[:2])
136f7d24e3fSHanoh Haim            is_tlv = not (trans_type & 0x8000)
137f7d24e3fSHanoh Haim            if is_tlv:
138f7d24e3fSHanoh Haim                # We should probably check to make sure the attribute type we
139f7d24e3fSHanoh Haim                # are looking at is allowed to have a TLV format and issue a
140f7d24e3fSHanoh Haim                # warning if we're given an TLV on a basic attribute.
141f7d24e3fSHanoh Haim                value_len, = struct.unpack("!H", m[2:4])
142f7d24e3fSHanoh Haim                if value_len+4 > len(m):
143f7d24e3fSHanoh Haim                    warning("Bad length for ISAKMP tranform type=%#6x" % trans_type)
144f7d24e3fSHanoh Haim                value = m[4:4+value_len]
145f7d24e3fSHanoh Haim                value = reduce(lambda x,y: (x<<8L)|y, struct.unpack("!%s" % ("B"*len(value),), value),0)
146f7d24e3fSHanoh Haim            else:
147f7d24e3fSHanoh Haim                trans_type &= 0x7fff
148f7d24e3fSHanoh Haim                value_len=0
149f7d24e3fSHanoh Haim                value, = struct.unpack("!H", m[2:4])
150f7d24e3fSHanoh Haim            m=m[4+value_len:]
151f7d24e3fSHanoh Haim            lst.append(self.num2type(trans_type, value))
152f7d24e3fSHanoh Haim        if len(m) > 0:
153f7d24e3fSHanoh Haim            warning("Extra bytes after ISAKMP transform dissection [%r]" % m)
154f7d24e3fSHanoh Haim        return lst
155f7d24e3fSHanoh Haim
156f7d24e3fSHanoh Haim
157f7d24e3fSHanoh HaimISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash",
158f7d24e3fSHanoh Haim                       "SIG","Nonce","Notification","Delete","VendorID"]
159f7d24e3fSHanoh Haim
160f7d24e3fSHanoh HaimISAKMP_exchange_type = ["None","base","identity prot.",
161f7d24e3fSHanoh Haim                        "auth only", "aggressive", "info"]
162f7d24e3fSHanoh Haim
163f7d24e3fSHanoh Haim
164f7d24e3fSHanoh Haimclass ISAKMP_class(Packet):
165f7d24e3fSHanoh Haim    def guess_payload_class(self, payload):
166f7d24e3fSHanoh Haim        np = self.next_payload
167f7d24e3fSHanoh Haim        if np == 0:
168f7d24e3fSHanoh Haim            return conf.raw_layer
169f7d24e3fSHanoh Haim        elif np < len(ISAKMP_payload_type):
170f7d24e3fSHanoh Haim            pt = ISAKMP_payload_type[np]
171f7d24e3fSHanoh Haim            return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload)
172f7d24e3fSHanoh Haim        else:
173f7d24e3fSHanoh Haim            return ISAKMP_payload
174f7d24e3fSHanoh Haim
175f7d24e3fSHanoh Haim
176f7d24e3fSHanoh Haimclass ISAKMP(ISAKMP_class): # rfc2408
177f7d24e3fSHanoh Haim    name = "ISAKMP"
178f7d24e3fSHanoh Haim    fields_desc = [
179f7d24e3fSHanoh Haim        StrFixedLenField("init_cookie","",8),
180f7d24e3fSHanoh Haim        StrFixedLenField("resp_cookie","",8),
181f7d24e3fSHanoh Haim        ByteEnumField("next_payload",0,ISAKMP_payload_type),
182f7d24e3fSHanoh Haim        XByteField("version",0x10),
183f7d24e3fSHanoh Haim        ByteEnumField("exch_type",0,ISAKMP_exchange_type),
184f7d24e3fSHanoh Haim        FlagsField("flags",0, 8, ["encryption","commit","auth_only","res3","res4","res5","res6","res7"]), # XXX use a Flag field
185f7d24e3fSHanoh Haim        IntField("id",0),
186f7d24e3fSHanoh Haim        IntField("length",None)
187f7d24e3fSHanoh Haim        ]
188f7d24e3fSHanoh Haim
189f7d24e3fSHanoh Haim    def guess_payload_class(self, payload):
190f7d24e3fSHanoh Haim        if self.flags & 1:
191f7d24e3fSHanoh Haim            return conf.raw_layer
192f7d24e3fSHanoh Haim        return ISAKMP_class.guess_payload_class(self, payload)
193f7d24e3fSHanoh Haim
194f7d24e3fSHanoh Haim    def answers(self, other):
195f7d24e3fSHanoh Haim        if isinstance(other, ISAKMP):
196f7d24e3fSHanoh Haim            if other.init_cookie == self.init_cookie:
197f7d24e3fSHanoh Haim                return 1
198f7d24e3fSHanoh Haim        return 0
199f7d24e3fSHanoh Haim    def post_build(self, p, pay):
200f7d24e3fSHanoh Haim        p += pay
201f7d24e3fSHanoh Haim        if self.length is None:
202f7d24e3fSHanoh Haim            p = p[:24]+struct.pack("!I",len(p))+p[28:]
203f7d24e3fSHanoh Haim        return p
204f7d24e3fSHanoh Haim
205f7d24e3fSHanoh Haim
206f7d24e3fSHanoh Haim
207f7d24e3fSHanoh Haim
208f7d24e3fSHanoh Haimclass ISAKMP_payload_Transform(ISAKMP_class):
209f7d24e3fSHanoh Haim    name = "IKE Transform"
210f7d24e3fSHanoh Haim    fields_desc = [
211f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
212f7d24e3fSHanoh Haim        ByteField("res",0),
213f7d24e3fSHanoh Haim#        ShortField("len",None),
214f7d24e3fSHanoh Haim        ShortField("length",None),
215f7d24e3fSHanoh Haim        ByteField("num",None),
216f7d24e3fSHanoh Haim        ByteEnumField("id",1,{1:"KEY_IKE"}),
217f7d24e3fSHanoh Haim        ShortField("res2",0),
218f7d24e3fSHanoh Haim        ISAKMPTransformSetField("transforms",None,length_from=lambda x:x.length-8)
219f7d24e3fSHanoh Haim#        XIntField("enc",0x80010005L),
220f7d24e3fSHanoh Haim#        XIntField("hash",0x80020002L),
221f7d24e3fSHanoh Haim#        XIntField("auth",0x80030001L),
222f7d24e3fSHanoh Haim#        XIntField("group",0x80040002L),
223f7d24e3fSHanoh Haim#        XIntField("life_type",0x800b0001L),
224f7d24e3fSHanoh Haim#        XIntField("durationh",0x000c0004L),
225f7d24e3fSHanoh Haim#        XIntField("durationl",0x00007080L),
226f7d24e3fSHanoh Haim        ]
227f7d24e3fSHanoh Haim    def post_build(self, p, pay):
228f7d24e3fSHanoh Haim        if self.length is None:
229f7d24e3fSHanoh Haim            l = len(p)
230f7d24e3fSHanoh Haim            p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
231f7d24e3fSHanoh Haim        p += pay
232f7d24e3fSHanoh Haim        return p
233f7d24e3fSHanoh Haim
234f7d24e3fSHanoh Haim
235f7d24e3fSHanoh Haim
236f7d24e3fSHanoh Haim
237f7d24e3fSHanoh Haimclass ISAKMP_payload_Proposal(ISAKMP_class):
238f7d24e3fSHanoh Haim    name = "IKE proposal"
239f7d24e3fSHanoh Haim#    ISAKMP_payload_type = 0
240f7d24e3fSHanoh Haim    fields_desc = [
241f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
242f7d24e3fSHanoh Haim        ByteField("res",0),
243f7d24e3fSHanoh Haim        FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8),
244f7d24e3fSHanoh Haim        ByteField("proposal",1),
245f7d24e3fSHanoh Haim        ByteEnumField("proto",1,{1:"ISAKMP"}),
246f7d24e3fSHanoh Haim        FieldLenField("SPIsize",None,"SPI","B"),
247f7d24e3fSHanoh Haim        ByteField("trans_nb",None),
248f7d24e3fSHanoh Haim        StrLenField("SPI","",length_from=lambda x:x.SPIsize),
249f7d24e3fSHanoh Haim        PacketLenField("trans",conf.raw_layer(),ISAKMP_payload_Transform,length_from=lambda x:x.length-8),
250f7d24e3fSHanoh Haim        ]
251f7d24e3fSHanoh Haim
252f7d24e3fSHanoh Haim
253f7d24e3fSHanoh Haimclass ISAKMP_payload(ISAKMP_class):
254f7d24e3fSHanoh Haim    name = "ISAKMP payload"
255f7d24e3fSHanoh Haim    fields_desc = [
256f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
257f7d24e3fSHanoh Haim        ByteField("res",0),
258f7d24e3fSHanoh Haim        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
259f7d24e3fSHanoh Haim        StrLenField("load","",length_from=lambda x:x.length-4),
260f7d24e3fSHanoh Haim        ]
261f7d24e3fSHanoh Haim
262f7d24e3fSHanoh Haim
263f7d24e3fSHanoh Haimclass ISAKMP_payload_VendorID(ISAKMP_class):
264f7d24e3fSHanoh Haim    name = "ISAKMP Vendor ID"
265f7d24e3fSHanoh Haim    overload_fields = { ISAKMP: { "next_payload":13 }}
266f7d24e3fSHanoh Haim    fields_desc = [
267f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
268f7d24e3fSHanoh Haim        ByteField("res",0),
269f7d24e3fSHanoh Haim        FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4),
270f7d24e3fSHanoh Haim        StrLenField("vendorID","",length_from=lambda x:x.length-4),
271f7d24e3fSHanoh Haim        ]
272f7d24e3fSHanoh Haim
273f7d24e3fSHanoh Haimclass ISAKMP_payload_SA(ISAKMP_class):
274f7d24e3fSHanoh Haim    name = "ISAKMP SA"
275f7d24e3fSHanoh Haim    overload_fields = { ISAKMP: { "next_payload":1 }}
276f7d24e3fSHanoh Haim    fields_desc = [
277f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
278f7d24e3fSHanoh Haim        ByteField("res",0),
279f7d24e3fSHanoh Haim        FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+12),
280f7d24e3fSHanoh Haim        IntEnumField("DOI",1,{1:"IPSEC"}),
281f7d24e3fSHanoh Haim        IntEnumField("situation",1,{1:"identity"}),
282f7d24e3fSHanoh Haim        PacketLenField("prop",conf.raw_layer(),ISAKMP_payload_Proposal,length_from=lambda x:x.length-12),
283f7d24e3fSHanoh Haim        ]
284f7d24e3fSHanoh Haim
285f7d24e3fSHanoh Haimclass ISAKMP_payload_Nonce(ISAKMP_class):
286f7d24e3fSHanoh Haim    name = "ISAKMP Nonce"
287f7d24e3fSHanoh Haim    overload_fields = { ISAKMP: { "next_payload":10 }}
288f7d24e3fSHanoh Haim    fields_desc = [
289f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
290f7d24e3fSHanoh Haim        ByteField("res",0),
291f7d24e3fSHanoh Haim        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
292f7d24e3fSHanoh Haim        StrLenField("load","",length_from=lambda x:x.length-4),
293f7d24e3fSHanoh Haim        ]
294f7d24e3fSHanoh Haim
295f7d24e3fSHanoh Haimclass ISAKMP_payload_KE(ISAKMP_class):
296f7d24e3fSHanoh Haim    name = "ISAKMP Key Exchange"
297f7d24e3fSHanoh Haim    overload_fields = { ISAKMP: { "next_payload":4 }}
298f7d24e3fSHanoh Haim    fields_desc = [
299f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
300f7d24e3fSHanoh Haim        ByteField("res",0),
301f7d24e3fSHanoh Haim        FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4),
302f7d24e3fSHanoh Haim        StrLenField("load","",length_from=lambda x:x.length-4),
303f7d24e3fSHanoh Haim        ]
304f7d24e3fSHanoh Haim
305f7d24e3fSHanoh Haimclass ISAKMP_payload_ID(ISAKMP_class):
306f7d24e3fSHanoh Haim    name = "ISAKMP Identification"
307f7d24e3fSHanoh Haim    overload_fields = { ISAKMP: { "next_payload":5 }}
308f7d24e3fSHanoh Haim    fields_desc = [
309f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
310f7d24e3fSHanoh Haim        ByteField("res",0),
311f7d24e3fSHanoh Haim        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8),
312f7d24e3fSHanoh Haim        ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
313f7d24e3fSHanoh Haim        ByteEnumField("ProtoID",0,{0:"Unused"}),
314f7d24e3fSHanoh Haim        ShortEnumField("Port",0,{0:"Unused"}),
315f7d24e3fSHanoh Haim#        IPField("IdentData",""),
316f7d24e3fSHanoh Haim        StrLenField("load","",length_from=lambda x:x.length-8),
317f7d24e3fSHanoh Haim        ]
318f7d24e3fSHanoh Haim
319f7d24e3fSHanoh Haim
320f7d24e3fSHanoh Haim
321f7d24e3fSHanoh Haimclass ISAKMP_payload_Hash(ISAKMP_class):
322f7d24e3fSHanoh Haim    name = "ISAKMP Hash"
323f7d24e3fSHanoh Haim    overload_fields = { ISAKMP: { "next_payload":8 }}
324f7d24e3fSHanoh Haim    fields_desc = [
325f7d24e3fSHanoh Haim        ByteEnumField("next_payload",None,ISAKMP_payload_type),
326f7d24e3fSHanoh Haim        ByteField("res",0),
327f7d24e3fSHanoh Haim        FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4),
328f7d24e3fSHanoh Haim        StrLenField("load","",length_from=lambda x:x.length-4),
329f7d24e3fSHanoh Haim        ]
330f7d24e3fSHanoh Haim
331f7d24e3fSHanoh Haim
332f7d24e3fSHanoh Haim
333f7d24e3fSHanoh HaimISAKMP_payload_type_overload = {}
334f7d24e3fSHanoh Haimfor i in range(len(ISAKMP_payload_type)):
335f7d24e3fSHanoh Haim    name = "ISAKMP_payload_%s" % ISAKMP_payload_type[i]
336f7d24e3fSHanoh Haim    if name in globals():
337f7d24e3fSHanoh Haim        ISAKMP_payload_type_overload[globals()[name]] = {"next_payload":i}
338f7d24e3fSHanoh Haim
339f7d24e3fSHanoh Haimdel(i)
340f7d24e3fSHanoh Haimdel(name)
341f7d24e3fSHanoh HaimISAKMP_class.overload_fields = ISAKMP_payload_type_overload.copy()
342f7d24e3fSHanoh Haim
343f7d24e3fSHanoh Haim
344f7d24e3fSHanoh Haimbind_layers( UDP,           ISAKMP,        dport=500, sport=500)
345f7d24e3fSHanoh Haimdef ikescan(ip):
346f7d24e3fSHanoh Haim    return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8),
347f7d24e3fSHanoh Haim                                      exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
348f7d24e3fSHanoh Haim