Kemp’s Blog

A technical blog about technical things

DeviceMaster protocol, part 2: UDP fields

We ended the last post having split up the UDP scan/refresh response into individual fields, with each consisting of a value identifier, a length, and the actual content of the field. Now we come to deciphering the meaning of those fields.

As a reminder, the response looked like this:

a9 8d fd 53 7a 1c b0 de 00 00
2c 00
02 00
16 06 00 c0 4e 08 37 f5
10 00
2b 01 03
2c 04 00 4c 53 7e
2f 01 08
30 01 ff
32 01 01
2d 01 01
2e 01 2d
12 07 43 6f 6d 74 72 6f 6c
13 0c 44 65 76 69 63 65 4d 61 73 74 65 72
14 12 53 6f 63 6b 65 74 53 65 72 76 65 72 20 31 31 2e 33 34
23 00
1a 01 01
1b 01 00
36 01 01
17 04 00 00 00 00
18 04 ff ff ff c0
19 04 0a 8d 7a 01
1c 04 0a 8d 7a 08
1d 04 ff ff ff c0
1e 04 0a 8d 7a 01
27 01 00
28 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2a 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
29 01 00
33 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
34 01 00
35 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
37 04 34 2e 33 31

I had already guessed that items 0x18 and 0x1d are subnet masks. With the fields separated out like this I could see that there are two groups of three items with the last two of each triplet being the subnet mask and 0x0a 0x8d 0x7a 0x01 in each case. That final value in each triplet (0x19 and 0x1e) translates to 10.141.122.1, which makes sense as a gateway address, The first value of each triplet should therefore logically be an IP address. One of them (0x17) is 0.0.0.0 while the other (0x1c) is 10.141.122.8. Why are there two sets of settings though? Well the device offers static and DHCP based addressing, so I investigated that. The device was configured with DHCP at the time so I switched it to static and suddenly 0x17 contained an IP address. Value 0x1a also flipped from 0x01 to 0x00, so I took that to be the static/DHCP flag.

While I was on IP addresses I took a look at IPv6 configuration. To cut a long story short, I tried a few configurations and determined that 0x28, 0x29, and 0x2a are the address, prefix length, and gateway for static configuration, 0x33, 0x34, and 0x35 are the same three values for DHCP configuration, and 0x27 is the addressing mode (0 = disabled, 1 = static, 2 = DHCP).

Next up was to take the remaining values and check if any make sense as ASCII strings. For this I wrote a quick Python script that takes the message as I formatted it above, converts the value in each row to a string, and prints them all out (there’s few enough that checking by eye was better than trusting detection by the script). This quickly revealed 0x12 as ‘Comtrol’, 0x13 as ‘DeviceMaster’, 0x14 as ‘SocketServer 11.34’, and 0x37 as ‘4.31’. Some more configuration adjustments showed that 0x23 contains the hostname.

That leaves my list of known values as:

Identifier Description Example value Translated value
0x12 Manufacturer 43 6f 6d 74 72 6f 6c ‘Comtrol’
0x13 Device range 44 65 76 69 63 65 4d 61 73 74 65 72 ‘DeviceMaster’
0x14 Firmware 53 6f 63 6b 65 74 53 65 72 76 65 72 20 31 31 2e 33 34 ‘SocketServer 11.34’
0x16 MAC address 00 c0 4e 08 37 f5 00:c0:4e:08:37:f5
0x17 IP (static) 00 00 00 00 0.0.0.0
0x18 Subnet mask (static) ff ff ff c0 255.255.255.192
0x19 Gateway (static) 0a 8d 7a 01 10.141.122.1
0x1a Address mode 01 1 = DHCP
0x1c IP (DHCP) 0a 8d 7a 08 10.141.122.8
0x1d Subnet mask (DHCP) ff ff ff c0 255.255.255.192
0x1e Gateway (DHCP) 0a 8d 7a 01 10.141.122.1
0x23 Hostname 53 65 72 69 61 6c 48 75 62 ‘SerialHub’
0x27 Address mode (IPv6) 00 0 = disabled
0x28 IP (IPv6, static) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ::
0x29 Prefix length (static) 00 0
0x2a Gateway (IPv6, static) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ::
0x33 IP (IPv6, DHCP) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ::
0x34 Prefix length (DHCP) 00 0
0x35 Gateway (IPv6, DHCP) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ::
0x37 Bootloader version 34 2e 33 31 ‘4.31’

The fields I haven’t yet figured out are:

Identifier Example value
0x10 ?
0x1b 00
0x2b 03
0x2c 00 4c 53 7e
0x2d 01
0x2e 2d
0x2f 08
0x30 ff
0x32 01
0x36 01

As you can see, they don’t give much to go on. 0x2c translates to ‘<null>LS~’ as a string, but the fact that 3 of the 4 digits map to ASCII characters is probably coincidence. 0x2f could be the number of ports, as otherwise this doesn’t appear to be reported, but that’s an assumption. It’s possible one of the other fields maps to an enumeration that completely identifies the specific model, which would include this information.

With much of the UDP discovery protocol figured out, the next part moves on to the TCP-based protocol for actually using the device.