summaryrefslogtreecommitdiffstats
path: root/nselib/knx.lua
diff options
context:
space:
mode:
Diffstat (limited to 'nselib/knx.lua')
-rw-r--r--nselib/knx.lua87
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