dummy_mr.py revision f9c4cfa7
1#/usr/bin/env python
2
3# Simple map resolver
4#
5# This script creates an UDP socket and starts listening on it.
6# When a map-request is received nonce is extracted from the request and
7# used in map-reply.
8#
9# Notes:
10# * works only with ipv4 in both under/over-lays.
11# * exact address matching is done while looking for a mapping
12#
13# Usage:
14#   ./dummy_mr <bind-ip> <port>
15#
16
17import sys
18import socket
19
20# mapping between EIDs and RLOCs
21mappings = {
22  b'\x06\x00\x02\x02' : (b'\x06\x00\x03\x02', ),
23  b'\x06\x00\x01\x02' : (b'\x06\x00\x03\x01', )
24}
25
26# LISP map-reply message
27reply_data = (b'\x20\x00\x00\x01'   # type, PES, reserved, record count
28             + '\x00\x00\x00\x00'   # nonce
29             + '\x00\x00\x00\x00'   # nonce
30             + '\x00\x00\x05\xa0'   # record TTL
31             + '\x01\x18\x10\x00'   # loc-count, EID-len, ACT
32             + '\x00\x00\x00\x01'   # rsvd, map-version, EID-AFI=ipv4
33             + '\x06\x00\x02\x00'   # EID prefix
34             + '\x01\x01\xff\x00'   # prio, weight, mprio, mweight
35             + '\x00\x05\x00\x01'   # unused, LpR, Loc-AFI
36             + '\x06\x00\x03\x02')  # locator
37
38request_nonce_offset = 36
39reply_nonce_offset = 4
40
41request_eid_offset = 60
42reply_eid_offset = 24
43
44reply_rloc_offset = 36
45
46
47def build_reply(nonce, deid):
48  if deid not in mappings:
49    raise Exception('No mapping found for eid {}!'.format(repr(deid)))
50  m = mappings[deid]
51
52  # prepare reply data
53  reply = bytearray(reply_data)
54
55  # update rloc field in reply message
56  rloc = bytearray(m[0])
57
58  for i in range(0, 4):
59    reply[reply_rloc_offset + i] = rloc[i]
60
61  # update eid prefix field
62  for i in range(0, 4):
63    reply[reply_eid_offset + i] = deid[i]
64
65  # update nonce
66  for i in range(0, 8):
67    reply[reply_nonce_offset + i] = nonce[i]
68
69  return reply
70
71
72def run(host, port):
73  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
74  server_address = (host, int(port))
75  sock.bind(server_address)
76
77  while True:
78    data, address = sock.recvfrom(4096)
79
80    # extract nonce from request
81    nonce = data[request_nonce_offset:request_nonce_offset+8]
82
83    # extract deid
84    deid = data[request_eid_offset:request_eid_offset+4]
85
86    rp = build_reply(nonce, deid)
87    sock.sendto(rp, address)
88
89
90if __name__ == "__main__":
91  if len(sys.argv) < 2:
92    raise Exception('IP and port expected')
93
94  run(sys.argv[1], sys.argv[2])
95