From d9cf8adf04fa7e37a82e5c10eeeedc560874051b Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 18 Dec 2014 00:22:46 +0000 Subject: [PATCH] New ipOps.str_to_ip function --- nselib/ipOps.lua | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/nselib/ipOps.lua b/nselib/ipOps.lua index 9740ffd2c..23d25311e 100644 --- a/nselib/ipOps.lua +++ b/nselib/ipOps.lua @@ -507,7 +507,7 @@ get_last_ip = function( ip, prefix ) end --- --- Converts an IP address into an opaque string. +-- Converts an IP address into an opaque string (big-endian) -- @param ip String representing an IPv4 or IPv6 address. -- @param family (optional) Address family to convert to. "ipv6" converts IPv4 -- addresses to IPv4-mapped IPv6. @@ -540,6 +540,28 @@ ip_to_str = function( ip, family ) return table.concat( t ) end +--- +-- Converts an opaque string (big-endian) into an IP address +-- +-- @param ip Opaque string representing an IP address. If length 4, then IPv4 +-- is assumed. If length 16, then IPv6 is assumed. +-- @return IP address in readable notation (or nil in case of an +-- error) +-- @return String error message in case of an error +str_to_ip = function (ip) + if #ip == 4 then + local _, a, b, c, d = bin.unpack("C4", ip) + return ("%d.%d.%d.%d"):format(a, b, c, d) + elseif #ip == 16 then + local _, a, b, c, d, e, f, g, h = bin.unpack(">S8", ip) + local full = ("%x:%x:%x:%x:%x:%x:%x:%x"):format(a, b, c, d, e, f, g, h) + full = full:gsub(":[:0]+", "::", 1) -- Collapse the first (should be longest?) series of :0: + full = full:gsub("^0::", "::", 1) -- handle special case of ::1 + return full + else + return nil, "Invalid length" + end +end --- -- Converts an IP address into a string representing the address as binary @@ -661,6 +683,9 @@ test_suite:add_test(unittest.is_true(isPrivate("192.168.123.123")), "192.168.123 test_suite:add_test(unittest.is_false(isPrivate("1.1.1.1")), "1.1.1.1 is not private") test_suite:add_test(unittest.equal(todword("65.66.67.68"),0x41424344), "todword") test_suite:add_test(unittest.equal(fromdword(0xffffffff),"255.255.255.255"), "fromdword") +test_suite:add_test(unittest.equal(str_to_ip("\x01\x02\x03\x04"),"1.2.3.4"), "str_to_ip (ipv4)") +test_suite:add_test(unittest.equal(str_to_ip("\0\x01\xbe\xef\0\0\0\0\0\0\x02\x03\0\0\0\x01"),"1:beef::203:0:1"), "str_to_ip (ipv6)") +test_suite:add_test(unittest.equal(str_to_ip(("\0"):rep(15) .. "\x01"),"::1"), "str_to_ip (ipv6)") test_suite:add_test(function() local parts, err = get_parts_as_number("8.255.0.1") if parts == nil then return false, err end