summaryrefslogtreecommitdiffstats
path: root/tests/data_plane/vpp_lite_topo/scripts/dummy_mr.py
blob: 4740586e828aa70d0ac937ce9f5005ce62c1e053 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#/usr/bin/env python

# Simple map resolver
#
# This script creates an UDP socket and starts listening on it.
# When a map-request is received nonce is extracted from the request and
# used in map-reply.
#
# Notes:
# * works only with ipv4 in both under/over-lays.
# * exact address matching is done while looking for a mapping
#
# Usage:
#   ./dummy_mr <bind-ip> <port>
#

import sys
import socket

# mapping between EIDs and RLOCs
mappings = {
  b'\x06\x00\x02\x02' : (b'\x06\x00\x03\x02', ),
  b'\x06\x00\x01\x02' : (b'\x06\x00\x03\x01', )
}

# LISP map-reply message
reply_data = (b'\x20\x00\x00\x01'   # type, PES, reserved, record count
             + '\x00\x00\x00\x00'   # nonce
             + '\x00\x00\x00\x00'   # nonce
             + '\x00\x00\x05\xa0'   # record TTL
             + '\x01\x18\x10\x00'   # loc-count, EID-len, ACT
             + '\x00\x00\x00\x01'   # rsvd, map-version, EID-AFI=ipv4
             + '\x06\x00\x02\x00'   # EID prefix
             + '\x01\x01\xff\x00'   # prio, weight, mprio, mweight
             + '\x00\x05\x00\x01'   # unused, LpR, Loc-AFI
             + '\x06\x00\x03\x02')  # locator

request_nonce_offset = 36
reply_nonce_offset = 4

request_eid_offset = 60
reply_eid_offset = 24

reply_rloc_offset = 36


def build_reply(nonce, deid):
  if deid not in mappings:
    raise Exception('No mapping found for eid {}!'.format(repr(deid)))
  m = mappings[deid]

  # prepare reply data
  reply = bytearray(reply_data)

  # update rloc field in reply message
  rloc = bytearray(m[0])

  for i in range(0, 4):
    reply[reply_rloc_offset + i] = rloc[i]

  # update eid prefix field
  for i in range(0, 4):
    reply[reply_eid_offset + i] = deid[i]

  # update nonce
  for i in range(0, 8):
    reply[reply_nonce_offset + i] = nonce[i]

  return reply


def run(host, port):
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  server_address = (host, int(port))
  sock.bind(server_address)

  while True:
    data, address = sock.recvfrom(4096)

    # extract nonce from request
    nonce = data[request_nonce_offset:request_nonce_offset+8]

    # extract deid
    deid = data[request_eid_offset:request_eid_offset+4]

    rp = build_reply(nonce, deid)
    sock.sendto(rp, address)


if __name__ == "__main__":
  if len(sys.argv) < 2:
    raise Exception('IP and port expected')

  run(sys.argv[1], sys.argv[2])