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.