diff options
Diffstat (limited to 'nselib/knx.lua')
-rw-r--r-- | nselib/knx.lua | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/nselib/knx.lua b/nselib/knx.lua new file mode 100644 index 0000000..64cc58c --- /dev/null +++ b/nselib/knx.lua @@ -0,0 +1,87 @@ +--- Functions for communicating with Konnex (KNX) devices +-- +-- @author Niklaus Schiess, Dominik Schneider +-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html +-- @class module +-- @name knx + +local ipOps = require "ipOps" +local string = require "string" +local _ENV = {} + +knxServiceFamilies = { + [0x02]="KNXnet/IP Core", + [0x03]="KNXnet/IP Device Management", + [0x04]="KNXnet/IP Tunnelling", + [0x05]="KNXnet/IP Routing", + [0x06]="KNXnet/IP Remote Logging", + [0x08]="KNXnet/IP Object Server", + [0x07]="KNXnet/IP Remote Configuration and Diagnosis" +} + +knxDibDescriptionTypes = { + [0x01]="Device Information", + [0x02]="Supp_Svc_families", + [0x03]="IP_Config", + [0x04]="IP_Cur_Config", + [0x05]="IP_Config" +} + +knxMediumTypes = { + [0x01]="reserved", + [0x02]="KNX TP1", + [0x04]="KNX PL110", + [0x08]="reserved", + [0x10]="KNX RF", + [0x20]="KNX IP" +} + +--- Returns a raw knx request +-- @param service KNX service type of the request +-- @param ip_address IP address of the sending host +-- @param port Port where gateways should respond to +query = function(service, ip_address, port) + return string.pack(">BB I2 I2 BB I4 I2", + 0x06, -- Header length + 0x10, -- Protocol version + service, -- Service type + 0x000e, -- Total length + 0x08, -- Structure length + 0x01, -- Host protocol + ipOps.todword(ip_address), + port + ) +end + +--- Parse a KNX address from raw bytes +-- @param addr Unpacked 2 bytes +-- @return KNX address in dotted-decimal format +parseKnxAddress = function(addr) + local a = (addr & 0xf000) >> 12 + local b = (addr & 0x0f00) >> 8 + local c = addr & 0xff + return a..'.'..b..'.'..c +end + +--- Parse a KNX header +-- @param knxMessage A KNX message packet as a string +-- @return knx_header_length, or nil on error +-- @return knx_protocol_version, or error message +-- @return knx_service_type +-- @return knx_total_length +-- @return pos The position just after the header +parseHeader = function(knxMessage) + if #knxMessage < 6 then + return nil, "Message too short for KNX header" + end + local knx_header_length, knx_protocol_version, knx_service_type, knx_total_length, pos = string.unpack(">BB I2 I2", knxMessage) + + -- TODO: Should this be 'or' instead of 'and'? + if knx_header_length ~= 0x06 and knx_protocol_version ~= 0x10 and knx_service_type ~= 0x0204 then + return nil, "Unknown KNX header format" + end + + return knx_header_length, knx_protocol_version, knx_service_type, knx_total_length, pos +end + +return _ENV |