diff options
author | Mike Crute <mcrute@gmail.com> | 2016-08-16 20:36:46 -0700 |
---|---|---|
committer | Mike Crute <mcrute@gmail.com> | 2016-08-16 20:36:46 -0700 |
commit | 0eff7800aeb524f490ddaf58282fed46a4d933b5 (patch) | |
tree | ab3fb28cd57cdb1dc58b23158e7b36d361dd36f8 | |
parent | 6f8b8f590de536e7c6f46f1062fdc7730ef1679b (diff) | |
download | ubntmfi-0eff7800aeb524f490ddaf58282fed46a4d933b5.tar.bz2 ubntmfi-0eff7800aeb524f490ddaf58282fed46a4d933b5.tar.xz ubntmfi-0eff7800aeb524f490ddaf58282fed46a4d933b5.zip |
Update protocol spec
-rw-r--r-- | inform_protocol.md | 257 |
1 files changed, 238 insertions, 19 deletions
diff --git a/inform_protocol.md b/inform_protocol.md index cadbe24..f06ddb3 100644 --- a/inform_protocol.md +++ b/inform_protocol.md | |||
@@ -1,5 +1,4 @@ | |||
1 | Ubiquiti Inform Protocol | 1 | # Ubiquiti Inform Protocol |
2 | ======================== | ||
3 | 2 | ||
4 | The mFi uses the Ubiquiti inform protocol to handle all communications to and | 3 | The mFi uses the Ubiquiti inform protocol to handle all communications to and |
5 | from the controller. This is the way that it transmits the current state of the | 4 | from the controller. This is the way that it transmits the current state of the |
@@ -19,8 +18,7 @@ response instead of a noop response it will immediately do another inform; this | |||
19 | continues until the controller sends the next noop response. Responses never | 18 | continues until the controller sends the next noop response. Responses never |
20 | appear to contain multiple commands. | 19 | appear to contain multiple commands. |
21 | 20 | ||
22 | Raw Packet Structure | 21 | ## Raw Packet Structure |
23 | -------------------- | ||
24 | 4 bytes magic number integer | 22 | 4 bytes magic number integer |
25 | 4 bytes version integer | 23 | 4 bytes version integer |
26 | 6 bytes hwaddr string | 24 | 6 bytes hwaddr string |
@@ -30,21 +28,19 @@ Raw Packet Structure | |||
30 | 4 bytes data length integer | 28 | 4 bytes data length integer |
31 | n bytes AES encrypted payload string | 29 | n bytes AES encrypted payload string |
32 | 30 | ||
33 | Raw Packet Constraints | 31 | ## Raw Packet Constraints |
34 | ---------------------- | ||
35 | magic must == 1414414933 | 32 | magic must == 1414414933 |
36 | data version must < 1 | 33 | data version must < 1 |
37 | flags & 0x1 != 0 means encrypted | 34 | flags & 0x1 != 0 means encrypted |
38 | flags & 0x2 != 0 means compressed | 35 | flags & 0x2 != 0 means compressed |
39 | 36 | ||
40 | Payload Types | 37 | ## Payload Types |
41 | ------------- | ||
42 | The payload is AES encrypted in CBC mode using PKCS5 padding. They key is the | 38 | The payload is AES encrypted in CBC mode using PKCS5 padding. They key is the |
43 | device auth key from the database or a master key that is hard coded if the | 39 | device auth key from the database or a master key that is hard coded if the |
44 | device has not been provisioned yet. The master key is hard coded in the | 40 | device has not been provisioned yet. The master key is hard coded in the |
45 | controller code in the DeviceManager class and pretty easy to find. | 41 | controller code in the DeviceManager class and pretty easy to find. |
46 | 42 | ||
47 | MASTER_KEY = "ba86f2bbe107c7c57eb5f2690775c712" | 43 | MASTER_KEY = "ba86f2bbe107c7c57eb5f2690775c712" |
48 | 44 | ||
49 | On devices running protocol version 1 the encrypted payload is just JSON data. | 45 | On devices running protocol version 1 the encrypted payload is just JSON data. |
50 | In version 0 of the protocol the data was key=value pairs separated by | 46 | In version 0 of the protocol the data was key=value pairs separated by |
@@ -54,16 +50,11 @@ The payloads break down into two categories; those coming into the controller | |||
54 | and those going out of the controller. | 50 | and those going out of the controller. |
55 | 51 | ||
56 | 52 | ||
57 | Output Payloads | 53 | ## Output Payloads |
58 | --------------- | ||
59 | Output payloads are those that originate from the controller and are bound for | 54 | Output payloads are those that originate from the controller and are bound for |
60 | the device. These always appear to contain a _type field. I have observed the | 55 | the device. These always appear to contain a _type field. I have observed the |
61 | following output payloads. | 56 | following output payloads. |
62 | 57 | ||
63 | "mgmt_cfg": "mgmt.is_default=false\nmgmt.authkey=41d6529fd555fbb1bdeeafeb995510fa\nmgmt.cfgversion=f1bb359840b519a4\nmgmt.servers.1.url=http://172.16.0.38:6080/inform\nmgmt.selfrun_guest=pass\nselfrun_guest=pass\ncfgversion=f1bb359840b519a4\n", | ||
64 | "port_cfg": "port.0.sensorId=52210822e4b0959e7fe94009\nvpower.1.rep_output=1\nvpower.1.rep_pf=1\nvpower.1.rep_energy_sum=1\nvpower.1.rep_v_rms=1\nvpower.1.rep_i_rms=1\nvpower.1.rep_active_pwr=1\nvpower.1.relay=1\nvpower.1.output_tag=output\nvpower.1.pf_tag=pf\nvpower.1.energy_sum_tag=energy_sum\nvpower.1.v_rms_tag=v_rms\nvpower.1.i_rms_tag=i_rms\nvpower.1.active_pwr_tag=active_pwr\nport.1.sensorId=5221082be4b0959e7fe9400a\nvpower.2.rep_output=1\nvpower.2.rep_pf=1\nvpower.2.rep_energy_sum=1\nvpower.2.rep_v_rms=1\nvpower.2.rep_i_rms=1\nvpower.2.rep_active_pwr=1\nvpower.2.relay=1\nvpower.2.output_tag=output\nvpower.2.pf_tag=pf\nvpower.2.energy_sum_tag=energy_sum\nvpower.2.v_rms_tag=v_rms\nvpower.2.i_rms_tag=i_rms\nvpower.2.active_pwr_tag=active_pwr\nport.2.sensorId=5221083be4b0959e7fe9400b\nvpower.3.rep_output=1\nvpower.3.rep_pf=1\nvpower.3.rep_energy_sum=1\nvpower.3.rep_v_rms=1\nvpower.3.rep_i_rms=1\nvpower.3.rep_active_pwr=1\nvpower.3.relay=0\nvpower.3.output_tag=output\nvpower.3.pf_tag=pf\nvpower.3.energy_sum_tag=energy_sum\nvpower.3.v_rms_tag=v_rms\nvpower.3.i_rms_tag=i_rms\nvpower.3.active_pwr_tag=active_pwr\n", | ||
65 | "system_cfg": "# users\nusers.status=enabled\nusers.1.name=admin\nusers.1.password=Mq9xt5C8DjcLA\nusers.1.status=enabled\n# bridge\nbridge.status=disabled\nbridge.1.devname=br0\nbridge.1.fd=1\nbridge.1.stp.status=disabled\nbridge.1.port.1.devname=eth1\nsnmp.status=disabled\nppp.status=disabled\npwdog.status=disabled\ndnsmasq.status=disabled\ndhcpd.status=disabled\nhttpd.status=disabled\nhttpd.port.http=80\nhttpd.port=80\nigmpproxy.status=disabled\ntelnetd.status=disabled\ntshaper.status=disabled\nnetmode=bridge\nntpclient.status=disabled\nntpclient.1.server=pool.ntp.org\nntpclient.1.status=disabled\nsyslog.status=enabled\nresolv.status=enabled\nresolv.host.1.name=OfficePowerStrip\nresolv.nameserver.1.status=disabled\nresolv.nameserver.2.status=disabled\ndhcpc.status=enabled\ndhcpc.1.status=enabled\ndhcpc.1.devname=eth1\nroute.status=enabled\nvlan.status=disabled\nradio.1.ack.auto=disabled\nradio.1.ackdistance=300\nradio.1.acktimeout=30\nradio.1.ampdu.status=enabled\nradio.1.clksel=1\nradio.1.countrycode=840\nradio.1.cwm.enable=0\nradio.1.cwm.mode=1\nradio.1.forbiasauto=0\nradio.1.channel=0\nradio.1.ieee_mode=11nght40\nradio.1.mcastrate=auto\nradio.1.mode=managed\nradio.1.puren=0\nradio.1.rate.auto=enabled\nradio.1.rate.mcs=auto\nradio.1.txpower=auto\n# wlans (radio)\nradio.status=enabled\nradio.countrycode=840\naaa.status=disabled\nwireless.status=enabled\ndhcpc.2.status=enabled\ndhcpc.2.devname=ath0\nbridge.1.port.2.devname=ath0\nradio.1.devname=ath0\nradio.1.status=enabled\naaa.1.br.devname=br0\naaa.1.devname=ath0\naaa.1.driver=madwifi\naaa.1.ssid=\naaa.1.status=disabled\nwireless.1.mode=managed\nwireless.1.devname=ath0\nwireless.1.status=enabled\nwireless.1.authmode=1\nwireless.1.l2_isolation=disabled\nwireless.1.is_guest=false\nwireless.1.security=none\nwireless.1.addmtikie=disabled\nwireless.1.ssid=\nwireless.1.hide_ssid=enabled\nwireless.1.mac_acl.status=disabled\nwireless.1.mac_acl.policy=deny\nwireless.1.wmm=enabled\n# netconf\nnetconf.status=enabled\nnetconf.1.devname=eth1\nnetconf.1.autoip.status=disabled\nnetconf.1.ip=0.0.0.0\nnetconf.1.promisc=enabled\nnetconf.1.status=enabled\nnetconf.1.up=enabled\nnetconf.2.devname=br0\nnetconf.2.autoip.status=disabled\nnetconf.2.ip=0.0.0.0\nnetconf.2.status=enabled\nnetconf.2.up=enabled\nnetconf.3.devname=ath0\nnetconf.3.autoip.status=disabled\nnetconf.3.ip=0.0.0.0\nnetconf.3.promisc=enabled\nnetconf.3.status=enabled\nnetconf.3.up=enabled\nqos.status=enabled\nqos.group.1.rate=100\nqos.group.2.rate=100\nqos.group.6.rate=100\nqos.if.1.devname=eth1\nqos.if.1.devspeed=100\nqos.if.1.group=1\nqos.if.2.devname=ath0\nqos.if.2.devspeed=150\nqos.if.2.group=20\n" | ||
66 | |||
67 | _type: firmware upgrade (upgrade) | 58 | _type: firmware upgrade (upgrade) |
68 | url: full url to firmware.bin | 59 | url: full url to firmware.bin |
69 | datetime: rfc3339 formatted date, server time | 60 | datetime: rfc3339 formatted date, server time |
@@ -115,11 +106,12 @@ following output payloads. | |||
115 | // val and volt set to 1 to turn on, 0 to turn off | 106 | // val and volt set to 1 to turn on, 0 to turn off |
116 | 107 | ||
117 | 108 | ||
118 | Input Payloads | 109 | ## Input Payloads |
119 | -------------- | ||
120 | Incoming packets appear to be a JSON version of the out put of the `mca-dump` | 110 | Incoming packets appear to be a JSON version of the out put of the `mca-dump` |
121 | command on the device. There is definitely some AirOS legacy in here. I do not | 111 | command on the device. There is definitely some Unifi legacy in here. It |
122 | document the whole input payload since most of it is not interesting. | 112 | appears that mFi is just using the Unfi firmware and has hacked it a bit for |
113 | their use-case so most of the fields outside of alarm are not relevant to the | ||
114 | mFi use-case. | ||
123 | 115 | ||
124 | callback from device: javascript object | 116 | callback from device: javascript object |
125 | alarm: list of sensors | 117 | alarm: list of sensors |
@@ -138,6 +130,52 @@ document the whole input payload since most of it is not interesting. | |||
138 | type: sensor type (output, analog, rmsSum, rms) | 130 | type: sensor type (output, analog, rmsSum, rms) |
139 | val: value (float) | 131 | val: value (float) |
140 | 132 | ||
133 | if_table: list of interfaces and stats | ||
134 | ip: interface ip | ||
135 | mac: interface mac address | ||
136 | name: interface device name (dev handle) | ||
137 | rx_bytes: bytes received on the interface | ||
138 | rx_dropped: packets dropped by the interface | ||
139 | rx_errors: receive errors on the interface | ||
140 | rx_packets: packets received on the interface | ||
141 | tx_bytes: bytes transmitted by the interface | ||
142 | tx_dropped: trasmit drops on the interface | ||
143 | tx_errors: transmit errors on the interface | ||
144 | tx_packets: number of packets transmitted by the interface | ||
145 | type: appears to be the same as name | ||
146 | |||
147 | radio_table: list of radios in the device | ||
148 | builtin_ant_gain: gain of builtin antenna | ||
149 | builtin_antenna: boolean, does device have antenna | ||
150 | max_txpower: maximum transmit power | ||
151 | name: name of radio | ||
152 | radio: radio type (ex: ng) | ||
153 | scan_table: list, unknown | ||
154 | |||
155 | vap_table: table of joined wireless networks | ||
156 | bssid: network SSID | ||
157 | ccq: client connection qality | ||
158 | channel: channel number | ||
159 | essid: network friendly name | ||
160 | id: mode? (ex: user) | ||
161 | name: uplink device name | ||
162 | num_sta: number of connected stations (always 0) | ||
163 | radio: radio type (ex: ng) | ||
164 | rx_bytes: bytes received on the interface | ||
165 | rx_dropped: packets dropped by the interface | ||
166 | rx_errors: receive errors on the interface | ||
167 | rx_packets: packets received on the interface | ||
168 | tx_bytes: bytes transmitted by the interface | ||
169 | tx_dropped: trasmit drops on the interface | ||
170 | tx_errors: transmit errors on the interface | ||
171 | tx_packets: number of packets transmitted by the interface | ||
172 | rx_crypts: unknown | ||
173 | rx_frags: received fragmented packets | ||
174 | rx_nwids: received network beacons | ||
175 | tx_power: transmitting power of the radio (assumed in dBm) | ||
176 | tx_retries: number of transmit retries on interface | ||
177 | usage: same as id | ||
178 | |||
141 | hostname: hostname of device ("ubnt" unless changed) | 179 | hostname: hostname of device ("ubnt" unless changed) |
142 | ip: IP of device | 180 | ip: IP of device |
143 | mac: mac address of primary interface | 181 | mac: mac address of primary interface |
@@ -148,3 +186,184 @@ document the whole input payload since most of it is not interesting. | |||
148 | uptime: uptime in seconds since last reboot | 186 | uptime: uptime in seconds since last reboot |
149 | version: firmware version | 187 | version: firmware version |
150 | default: boolean, device is unconfigured | 188 | default: boolean, device is unconfigured |
189 | cfgversion: string, unknown (ex: c3846443e1b4860b) | ||
190 | guest_token: string, unknown (ex: 364E8B215D16AB963A53232E3873000C) | ||
191 | inform_url: string, url to which the device is reporting | ||
192 | isolated: boolean, can the device reach the rest of the network | ||
193 | localversion: string, unknown (ex: ?) | ||
194 | locating: boolean, is the device in locating mode (blinking LED) | ||
195 | portversion: string, unknown (ex: 443eb55240f26367) | ||
196 | time: integer, device time as unix timestamp | ||
197 | trackable: boolean as string, unknown | ||
198 | uplink: string, unix device name (dev handle) of the primary uplink device | ||
199 | |||
200 | |||
201 | ## Config Samples | ||
202 | These are some observed configuration payloads for the configuration packets. | ||
203 | |||
204 | ### mgmt cfg | ||
205 | mgmt.is_default=false | ||
206 | mgmt.authkey=41d6529fd555fbb1bdeeafeb995510fa | ||
207 | mgmt.cfgversion=f1bb359840b519a4 | ||
208 | mgmt.servers.1.url=http://172.16.0.38:6080/inform | ||
209 | mgmt.selfrun_guest=pass | ||
210 | selfrun_guest=pass | ||
211 | cfgversion=f1bb359840b519a4 | ||
212 | |||
213 | |||
214 | ### port cfg | ||
215 | port.0.sensorId=52210822e4b0959e7fe94009 | ||
216 | vpower.1.rep_output=1 | ||
217 | vpower.1.rep_pf=1 | ||
218 | vpower.1.rep_energy_sum=1 | ||
219 | vpower.1.rep_v_rms=1 | ||
220 | vpower.1.rep_i_rms=1 | ||
221 | vpower.1.rep_active_pwr=1 | ||
222 | vpower.1.relay=1 | ||
223 | vpower.1.output_tag=output | ||
224 | vpower.1.pf_tag=pf | ||
225 | vpower.1.energy_sum_tag=energy_sum | ||
226 | vpower.1.v_rms_tag=v_rms | ||
227 | vpower.1.i_rms_tag=i_rms | ||
228 | vpower.1.active_pwr_tag=active_pwr | ||
229 | port.1.sensorId=5221082be4b0959e7fe9400a | ||
230 | vpower.2.rep_output=1 | ||
231 | vpower.2.rep_pf=1 | ||
232 | vpower.2.rep_energy_sum=1 | ||
233 | vpower.2.rep_v_rms=1 | ||
234 | vpower.2.rep_i_rms=1 | ||
235 | vpower.2.rep_active_pwr=1 | ||
236 | vpower.2.relay=1 | ||
237 | vpower.2.output_tag=output | ||
238 | vpower.2.pf_tag=pf | ||
239 | vpower.2.energy_sum_tag=energy_sum | ||
240 | vpower.2.v_rms_tag=v_rms | ||
241 | vpower.2.i_rms_tag=i_rms | ||
242 | vpower.2.active_pwr_tag=active_pwr | ||
243 | port.2.sensorId=5221083be4b0959e7fe9400b | ||
244 | vpower.3.rep_output=1 | ||
245 | vpower.3.rep_pf=1 | ||
246 | vpower.3.rep_energy_sum=1 | ||
247 | vpower.3.rep_v_rms=1 | ||
248 | vpower.3.rep_i_rms=1 | ||
249 | vpower.3.rep_active_pwr=1 | ||
250 | vpower.3.relay=0 | ||
251 | vpower.3.output_tag=output | ||
252 | vpower.3.pf_tag=pf | ||
253 | vpower.3.energy_sum_tag=energy_sum | ||
254 | vpower.3.v_rms_tag=v_rms | ||
255 | vpower.3.i_rms_tag=i_rms | ||
256 | vpower.3.active_pwr_tag=active_pwr | ||
257 | |||
258 | |||
259 | ### system cfg | ||
260 | # users | ||
261 | users.status=enabled | ||
262 | users.1.name=admin | ||
263 | users.1.password=Mq9xt5C8DjcLA | ||
264 | users.1.status=enabled | ||
265 | # bridge | ||
266 | bridge.status=disabled | ||
267 | bridge.1.devname=br0 | ||
268 | bridge.1.fd=1 | ||
269 | bridge.1.stp.status=disabled | ||
270 | bridge.1.port.1.devname=eth1 | ||
271 | snmp.status=disabled | ||
272 | ppp.status=disabled | ||
273 | pwdog.status=disabled | ||
274 | dnsmasq.status=disabled | ||
275 | dhcpd.status=disabled | ||
276 | httpd.status=disabled | ||
277 | httpd.port.http=80 | ||
278 | httpd.port=80 | ||
279 | igmpproxy.status=disabled | ||
280 | telnetd.status=disabled | ||
281 | tshaper.status=disabled | ||
282 | netmode=bridge | ||
283 | ntpclient.status=disabled | ||
284 | ntpclient.1.server=pool.ntp.org | ||
285 | ntpclient.1.status=disabled | ||
286 | syslog.status=enabled | ||
287 | resolv.status=enabled | ||
288 | resolv.host.1.name=OfficePowerStrip | ||
289 | resolv.nameserver.1.status=disabled | ||
290 | resolv.nameserver.2.status=disabled | ||
291 | dhcpc.status=enabled | ||
292 | dhcpc.1.status=enabled | ||
293 | dhcpc.1.devname=eth1 | ||
294 | route.status=enabled | ||
295 | vlan.status=disabled | ||
296 | radio.1.ack.auto=disabled | ||
297 | radio.1.ackdistance=300 | ||
298 | radio.1.acktimeout=30 | ||
299 | radio.1.ampdu.status=enabled | ||
300 | radio.1.clksel=1 | ||
301 | radio.1.countrycode=840 | ||
302 | radio.1.cwm.enable=0 | ||
303 | radio.1.cwm.mode=1 | ||
304 | radio.1.forbiasauto=0 | ||
305 | radio.1.channel=0 | ||
306 | radio.1.ieee_mode=11nght40 | ||
307 | radio.1.mcastrate=auto | ||
308 | radio.1.mode=managed | ||
309 | radio.1.puren=0 | ||
310 | radio.1.rate.auto=enabled | ||
311 | radio.1.rate.mcs=auto | ||
312 | radio.1.txpower=auto | ||
313 | # wlans (radio) | ||
314 | radio.status=enabled | ||
315 | radio.countrycode=840 | ||
316 | aaa.status=disabled | ||
317 | wireless.status=enabled | ||
318 | dhcpc.2.status=enabled | ||
319 | dhcpc.2.devname=ath0 | ||
320 | bridge.1.port.2.devname=ath0 | ||
321 | radio.1.devname=ath0 | ||
322 | radio.1.status=enabled | ||
323 | aaa.1.br.devname=br0 | ||
324 | aaa.1.devname=ath0 | ||
325 | aaa.1.driver=madwifi | ||
326 | aaa.1.ssid= | ||
327 | aaa.1.status=disabled | ||
328 | wireless.1.mode=managed | ||
329 | wireless.1.devname=ath0 | ||
330 | wireless.1.status=enabled | ||
331 | wireless.1.authmode=1 | ||
332 | wireless.1.l2_isolation=disabled | ||
333 | wireless.1.is_guest=false | ||
334 | wireless.1.security=none | ||
335 | wireless.1.addmtikie=disabled | ||
336 | wireless.1.ssid= | ||
337 | wireless.1.hide_ssid=enabled | ||
338 | wireless.1.mac_acl.status=disabled | ||
339 | wireless.1.mac_acl.policy=deny | ||
340 | wireless.1.wmm=enabled | ||
341 | # netconf | ||
342 | netconf.status=enabled | ||
343 | netconf.1.devname=eth1 | ||
344 | netconf.1.autoip.status=disabled | ||
345 | netconf.1.ip=0.0.0.0 | ||
346 | netconf.1.promisc=enabled | ||
347 | netconf.1.status=enabled | ||
348 | netconf.1.up=enabled | ||
349 | netconf.2.devname=br0 | ||
350 | netconf.2.autoip.status=disabled | ||
351 | netconf.2.ip=0.0.0.0 | ||
352 | netconf.2.status=enabled | ||
353 | netconf.2.up=enabled | ||
354 | netconf.3.devname=ath0 | ||
355 | netconf.3.autoip.status=disabled | ||
356 | netconf.3.ip=0.0.0.0 | ||
357 | netconf.3.promisc=enabled | ||
358 | netconf.3.status=enabled | ||
359 | netconf.3.up=enabled | ||
360 | qos.status=enabled | ||
361 | qos.group.1.rate=100 | ||
362 | qos.group.2.rate=100 | ||
363 | qos.group.6.rate=100 | ||
364 | qos.if.1.devname=eth1 | ||
365 | qos.if.1.devspeed=100 | ||
366 | qos.if.1.group=1 | ||
367 | qos.if.2.devname=ath0 | ||
368 | qos.if.2.devspeed=150 | ||
369 | qos.if.2.group=20 | ||