1ebfd5b56SFilip Tehlar# Usage:
2ebfd5b56SFilip Tehlar#
3ebfd5b56SFilip Tehlar#   $ python dummy_map_server <bind-ip> <port>
4ebfd5b56SFilip Tehlar#
5ebfd5b56SFilip Tehlar
6ebfd5b56SFilip Tehlarimport sys
7ebfd5b56SFilip Tehlarimport socket
8ebfd5b56SFilip Tehlarimport hmac
9ebfd5b56SFilip Tehlarimport hashlib
10ebfd5b56SFilip Tehlar
11ebfd5b56SFilip Tehlarmap_notify = (b"\x40\x00\x00\x01"
12ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x00"
13ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x00"
14ebfd5b56SFilip Tehlar    + "\x00\x01\x00\x14"  # key ID, Auth data length = 20
15ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x00"
16ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x00"
17ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x00"
18ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x00"
19ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x00" # auth data
20ebfd5b56SFilip Tehlar    + "\x00\x01"
21ebfd5b56SFilip Tehlar    + "\x51\x80\x01\x18\x00\x00\x00\x00\x00\x01\x06\x00\x01\x00\x01\x01"
22ebfd5b56SFilip Tehlar    + "\x00\x00\x00\x04\x00\x01\x06\x00\x03\x01")
23ebfd5b56SFilip Tehlar
24ebfd5b56SFilip Tehlarnotify_nonce_offset = 4
25ebfd5b56SFilip Tehlarnotify_auth_data_len = 20
26ebfd5b56SFilip Tehlarregister_nonce_offset = 4
27ebfd5b56SFilip Tehlarauth_data_offset = 16
28ebfd5b56SFilip Tehlarsecret_key = 'password'
29ebfd5b56SFilip Tehlar
30ebfd5b56SFilip Tehlar
31ebfd5b56SFilip Tehlardef build_notify(nonce):
32ebfd5b56SFilip Tehlar  rp = bytearray(map_notify)
33ebfd5b56SFilip Tehlar
34ebfd5b56SFilip Tehlar  for i in range(0, 8):
35ebfd5b56SFilip Tehlar    rp[notify_nonce_offset + i] = nonce[i]
36ebfd5b56SFilip Tehlar
37ebfd5b56SFilip Tehlar  # compute hash
38ebfd5b56SFilip Tehlar  digest = hmac.new(secret_key, rp, hashlib.sha1).digest()
39ebfd5b56SFilip Tehlar
40ebfd5b56SFilip Tehlar  for i in range(0, notify_auth_data_len):
41ebfd5b56SFilip Tehlar    rp[auth_data_offset + i] = digest[i]
42ebfd5b56SFilip Tehlar
43ebfd5b56SFilip Tehlar  return rp
44ebfd5b56SFilip Tehlar
45ebfd5b56SFilip Tehlar
46ebfd5b56SFilip Tehlardef run(host, port):
47ebfd5b56SFilip Tehlar  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
48ebfd5b56SFilip Tehlar  server_address = (host, int(port))
49ebfd5b56SFilip Tehlar  sock.bind(server_address)
50ebfd5b56SFilip Tehlar
51ebfd5b56SFilip Tehlar  while True:
52ebfd5b56SFilip Tehlar    data, address = sock.recvfrom(4096)
53ebfd5b56SFilip Tehlar
54ebfd5b56SFilip Tehlar    # extract nonce from message
55ebfd5b56SFilip Tehlar    nonce = data[register_nonce_offset:register_nonce_offset+8]
56ebfd5b56SFilip Tehlar
57ebfd5b56SFilip Tehlar    rp = build_notify(nonce)
58ebfd5b56SFilip Tehlar    sock.sendto(rp, address)
59ebfd5b56SFilip Tehlar    print 'Replied to ', ''.join(x.encode('hex') for x in nonce)
60ebfd5b56SFilip Tehlar
61ebfd5b56SFilip Tehlar
62ebfd5b56SFilip Tehlarif __name__ == "__main__":
63ebfd5b56SFilip Tehlar  if len(sys.argv) < 2:
64ebfd5b56SFilip Tehlar    raise Exception('IP and port expected')
65ebfd5b56SFilip Tehlar
66ebfd5b56SFilip Tehlar  run(sys.argv[1], sys.argv[2])