1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-01 04:19:02 +00:00

Convert ipOps from bin.lua to string.pack. Improved efficiency and added tests

This commit is contained in:
dmiller
2017-03-07 21:24:30 +00:00
parent 73963022dd
commit 4a5ff0472a

View File

@@ -243,13 +243,9 @@ compare_ip = function( left, op, right )
return nil, table.concat( err, " " )
end
if #left > #right then
left = bin.pack( "CA", 0x06, left )
right = bin.pack( "CA", 0x04, right )
elseif #right > #left then
right = bin.pack( "CA", 0x06, right )
left = bin.pack( "CA", 0x04, left )
end
-- by prepending the length, IPv4 (length 4) sorts before IPv6 (length 16)
left = string.pack("s1", left)
right = string.pack("s1", right)
if ( op == "eq" ) then
return ( left == right )
@@ -527,12 +523,12 @@ ip_to_str = function( ip, family )
if not ip:match( ":" ) then
-- ipv4 string
for octet in string.gmatch( ip, "%d+" ) do
t[#t+1] = bin.pack( ">C", tonumber(octet) )
t[#t+1] = string.pack("B", octet)
end
else
-- ipv6 string
for hdt in string.gmatch( ip, "%x+" ) do
t[#t+1] = bin.pack( ">S", tonumber(hdt, 16) )
t[#t+1] = string.pack( ">I2", tonumber(hdt, 16) )
end
end
@@ -550,11 +546,9 @@ end
-- @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)
return ("%d.%d.%d.%d"):format(string.unpack("BBBB", ip))
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)
local full = ("%x:%x:%x:%x:%x:%x:%x:%x"):format(string.unpack((">I2"):rep(8), ip))
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
@@ -651,6 +645,10 @@ end
local bin_lookup = {
[0]="0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111",
}
---
-- Converts a string of hexadecimal digits into the corresponding string of
-- binary digits.
@@ -663,14 +661,22 @@ end
-- <code>nil</code> in case of an error).
-- @return String error message in case of an error.
hex_to_bin = function( hex )
if type( hex ) ~= "string" or hex == "" or hex:match( "[^%x]+" ) then
return nil, "Error in ipOps.hex_to_bin: Expected string representing a hexadecimal number."
if type( hex ) ~= "string" then
return nil, "Error in ipOps.hex_to_bin: Expected string"
end
local d = bin.pack("H", hex)
local _, b = bin.unpack("B" .. #d, d)
return b:sub(1, #hex * 4)
local status, result = pcall( string.gsub, hex, ".", function(nibble)
local n = bin_lookup[tonumber(nibble, 16)]
if n then
return n
else
error("Error in ipOps.hex_to_bin: Expected string representing a hexadecimal number.")
end
end)
if status then
return result
end
return status, result
end
--Ignore the rest if we are not testing.
@@ -749,6 +755,20 @@ do
end
end
do
for _, h in ipairs({
{"a", "1010"},
{"aa", "10101010"},
{"12", "00010010"},
{"54321", "01010100001100100001"},
{"123error", false},
{"", ""},
{"bad 123", false},
}) do
test_suite:add_test(unittest.equal(hex_to_bin(h[1]), h[2]))
end
end
do
for _, op in ipairs({
{"192.168.13.1", "192/8", unittest.is_true, "IPv4 CIDR"},