From 2f7561aeaa1255e29355f4e984114a9b4f14fdf6 Mon Sep 17 00:00:00 2001 From: Lorand Jakab Date: Fri, 15 Apr 2016 17:44:52 +0300 Subject: [PATCH 1/5] Add xTR-ID support to Map-Registers --- lisp.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lisp.py b/lisp.py index 5679b20..98ed3aa 100755 --- a/lisp.py +++ b/lisp.py @@ -227,16 +227,19 @@ class LISP_MapRegister(Packet): name = "LISP Map-Register packet" fields_desc = [ BitField("ptype", 0, 4), - FlagsField("register_flags", None, 1, ["proxy_map_reply"]), - BitField("p3", 0, 18), - FlagsField("register_flags", None, 1, ["want-map-notify"]), + FlagsField("register_flags", None, 4, ["proxy_map_reply", "lisp_sec", "itr_id_present", "rtr"]), + BitField("p3", 0, 15), + FlagsField("additional_register_flags", None, 1, ["want-map-notify"]), FieldLenField("register_count", None, "register_records", "B", count_of="register_records", adjust=lambda pkt,x:x/16 - 1), XLongField("nonce", random.randint(nonce_min, nonce_max)), ShortField("key_id", 0), ShortField("authentication_length", 0), # authentication length expresses itself in bytes, so no modifications needed here StrLenField("authentication_data", None, length_from = lambda pkt: pkt.authentication_length), - PacketListField("register_records", None, LISP_MapRecord, count_from=lambda pkt:pkt.register_count + 1) + PacketListField("register_records", None, LISP_MapRecord, count_from=lambda pkt:pkt.register_count + 1), + ConditionalField(XLongField("xtr_id_high", 0), lambda pkt:pkt.register_flags & 2 == 2), + ConditionalField(XLongField("xtr_id_low", 0), lambda pkt:pkt.register_flags & 2 == 2), + ConditionalField(XLongField("site_id", 0), lambda pkt:pkt.register_flags & 2 == 2) ] class LISP_MapNotify(Packet): From 958e669ebb15e58ff259485c5f06d919430d4f34 Mon Sep 17 00:00:00 2001 From: Lorand Jakab Date: Tue, 19 Apr 2016 13:39:35 +0300 Subject: [PATCH 2/5] Add authentication key support to Map-Registers --- lisp.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lisp.py b/lisp.py index 98ed3aa..bd80047 100755 --- a/lisp.py +++ b/lisp.py @@ -13,7 +13,7 @@ archive for more details. """ -import socket,struct,random,netifaces,sys +import socket,struct,random,netifaces,sys,hmac,hashlib from string import ascii_letters from scapy import * from scapy.all import * @@ -225,6 +225,7 @@ class LISP_MapReply(Packet): class LISP_MapRegister(Packet): """ map reply part used after the first 16 bits have been read by the LISP_Type class""" name = "LISP Map-Register packet" + authentication_key = "password" # the key to use in the HMAC SHA computation fields_desc = [ BitField("ptype", 0, 4), FlagsField("register_flags", None, 4, ["proxy_map_reply", "lisp_sec", "itr_id_present", "rtr"]), @@ -242,6 +243,22 @@ class LISP_MapRegister(Packet): ConditionalField(XLongField("site_id", 0), lambda pkt:pkt.register_flags & 2 == 2) ] + def post_build(self, p, pay): + if self.key_id == 0: + # no HMAC + return p + # add authentication field with the correct length and bytes set to zero + self.authentication_data = '\x00' * self.authentication_length + p = p[:16] + self.authentication_data + p[16:] + if self.key_id == 1: + # compute HMAC-SHA1 checksum + self.authentication_data = hmac.new(self.authentication_key, msg=str(p), digestmod=hashlib.sha1).digest() + elif self.key_id == 2: + # compute HMAC-SHA256 + self.authentication_data = hmac.new(self.authentication_key, msg=str(p), digestmod=hashlib.sha256).digest() + p = p[:16] + self.authentication_data + p[(16+self.authentication_length):] + return p + class LISP_MapNotify(Packet): """ map notify part used after the first 16 bits have been read by the LISP_Type class""" name = "LISP Map-Notify packet" From bb1e4170aacc023b919e9d239fa614c985db203f Mon Sep 17 00:00:00 2001 From: Lorand Jakab Date: Thu, 21 Apr 2016 17:12:45 +0300 Subject: [PATCH 3/5] Determine authentication key length internally --- lisp.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lisp.py b/lisp.py index bd80047..3e78e89 100755 --- a/lisp.py +++ b/lisp.py @@ -46,6 +46,12 @@ "lcaf" : 16387 } +_KEY_LENGTH = { + 0 : 0, + 1 : 20, + 2 : 32 +} + """ nonce_max determines the maximum value of a nonce field. The default is set to 18446744073709551615, since this is the maximum possible value (>>> int('f'*16, 16)). TODO - see about the entropy for this source""" nonce_max = 16777215000 nonce_min = 15000000000 @@ -244,19 +250,20 @@ class LISP_MapRegister(Packet): ] def post_build(self, p, pay): + key_length = _KEY_LENGTH[self.key_id] if self.key_id == 0: # no HMAC return p # add authentication field with the correct length and bytes set to zero - self.authentication_data = '\x00' * self.authentication_length - p = p[:16] + self.authentication_data + p[16:] + self.authentication_data = '\x00' * key_length + p = p[:14] + struct.pack("!H", key_length) + self.authentication_data + p[16:] if self.key_id == 1: # compute HMAC-SHA1 checksum self.authentication_data = hmac.new(self.authentication_key, msg=str(p), digestmod=hashlib.sha1).digest() elif self.key_id == 2: # compute HMAC-SHA256 self.authentication_data = hmac.new(self.authentication_key, msg=str(p), digestmod=hashlib.sha256).digest() - p = p[:16] + self.authentication_data + p[(16+self.authentication_length):] + p = p[:16] + self.authentication_data + p[(16+key_length):] return p class LISP_MapNotify(Packet): From 8ff9cfbe04441621ff50db5e8c696ed5cd0323ac Mon Sep 17 00:00:00 2001 From: Lorand Jakab Date: Wed, 19 Oct 2016 14:34:06 +0300 Subject: [PATCH 4/5] Make it work with Scapy 2.3.3+ --- lisp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp.py b/lisp.py index 3e78e89..d3a4447 100755 --- a/lisp.py +++ b/lisp.py @@ -105,6 +105,7 @@ def guess_payload_class(self, payload): """ class LISP_AddressField(Field): + __slots__ = ["fld_name", "_ip_field", "_ip6_field"] def __init__(self, fld_name, ip_fld_name): Field.__init__(self, ip_fld_name, '0') From 22968d6a70343dea16797c3ae028ca9d4aa51c57 Mon Sep 17 00:00:00 2001 From: Lori Jakab Date: Tue, 17 Dec 2019 16:56:56 +0100 Subject: [PATCH 5/5] Add Map-Register merge support --- lisp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp.py b/lisp.py index d3a4447..d395dd4 100755 --- a/lisp.py +++ b/lisp.py @@ -236,8 +236,8 @@ class LISP_MapRegister(Packet): fields_desc = [ BitField("ptype", 0, 4), FlagsField("register_flags", None, 4, ["proxy_map_reply", "lisp_sec", "itr_id_present", "rtr"]), - BitField("p3", 0, 15), - FlagsField("additional_register_flags", None, 1, ["want-map-notify"]), + BitField("p3", 0, 13), + FlagsField("additional_register_flags", None, 3, ["merge", "something", "want-map-notify"]), FieldLenField("register_count", None, "register_records", "B", count_of="register_records", adjust=lambda pkt,x:x/16 - 1), XLongField("nonce", random.randint(nonce_min, nonce_max)), ShortField("key_id", 0),