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:

IdentifierDescriptionExample valueTranslated value
0x12Manufacturer43 6f 6d 74 72 6f 6c‘Comtrol’
0x13Device range44 65 76 69 63 65 4d 61 73 74 65 72‘DeviceMaster’
0x14Firmware53 6f 63 6b 65 74 53 65 72 76 65 72 20 31 31 2e 33 34‘SocketServer 11.34’
0x16MAC address00 c0 4e 08 37 f500:c0:4e:08:37:f5
0x17IP (static)00 00 00 000.0.0.0
0x18Subnet mask (static)ff ff ff c0255.255.255.192
0x19Gateway (static)0a 8d 7a 0110.141.122.1
0x1aAddress mode011 = DHCP
0x1cIP (DHCP)0a 8d 7a 0810.141.122.8
0x1dSubnet mask (DHCP)ff ff ff c0255.255.255.192
0x1eGateway (DHCP)0a 8d 7a 0110.141.122.1
0x23Hostname53 65 72 69 61 6c 48 75 62‘SerialHub’
0x27Address mode (IPv6)000 = disabled
0x28IP (IPv6, static)00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00::
0x29Prefix length (static)000
0x2aGateway (IPv6, static)00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00::
0x33IP (IPv6, DHCP)00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00::
0x34Prefix length (DHCP)000
0x35Gateway (IPv6, DHCP)00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00::
0x37Bootloader version34 2e 33 31‘4.31’

The fields I haven’t yet figured out are:

IdentifierExample value
0x10?
0x1b00
0x2b03
0x2c00 4c 53 7e
0x2d01
0x2e2d
0x2f08
0x30ff
0x3201
0x3601

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.