util/ip.lua
author Matthew Wild <mwild1@gmail.com>
Mon, 20 Feb 2023 18:10:15 +0000
branch0.12
changeset 12898 0598d822614f
parent 12359 a0ff5c438e9d
child 12935 bbae3acc6694
permissions -rw-r--r--
mod_websocket: Fire pre-session-close event (fixes #1800) This event was added in a7c183bb4e64 and is required to make mod_smacks know that a session was intentionally closed and shouldn't be hibernated (see fcea4d9e7502). Because this was missing from mod_websocket's session.close(), mod_smacks would always attempt to hibernate websocket sessions even if they closed cleanly. That mod_websocket has its own copy of session.close() is something to fix another day (probably not in the stable branch). So for now this commit makes the minimal change to get things working again. Thanks to Damian and the Jitsi team for reporting.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     1
-- Prosody IM
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     2
-- Copyright (C) 2008-2011 Florian Zeitz
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     3
--
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     4
-- This project is MIT/X11 licensed. Please see the
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     5
-- COPYING file in the source package for more information.
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     6
--
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
     7
8433
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
     8
local net = require "util.net";
8435
da807f4f706c util.ip: Simplify bitstring method
Kim Alvefur <zash@zash.se>
parents: 8434
diff changeset
     9
local hex = require "util.hex";
8433
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    10
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    11
local ip_methods = {};
8431
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    12
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    13
local ip_mt = {
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    14
	__index = function (ip, key)
8439
ab9ddfb03d4d util.ip: Cache return values of all methods in one place
Kim Alvefur <zash@zash.se>
parents: 8438
diff changeset
    15
		local method = ip_methods[key];
ab9ddfb03d4d util.ip: Cache return values of all methods in one place
Kim Alvefur <zash@zash.se>
parents: 8438
diff changeset
    16
		if not method then return nil; end
ab9ddfb03d4d util.ip: Cache return values of all methods in one place
Kim Alvefur <zash@zash.se>
parents: 8438
diff changeset
    17
		local ret = method(ip);
ab9ddfb03d4d util.ip: Cache return values of all methods in one place
Kim Alvefur <zash@zash.se>
parents: 8438
diff changeset
    18
		ip[key] = ret;
ab9ddfb03d4d util.ip: Cache return values of all methods in one place
Kim Alvefur <zash@zash.se>
parents: 8438
diff changeset
    19
		return ret;
8431
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    20
	end,
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    21
	__tostring = function (ip) return ip.addr; end,
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    22
};
10597
079b31c8dbf2 util.ip: Fix equality metamethod for Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
    23
ip_mt.__eq = function (ipA, ipB)
079b31c8dbf2 util.ip: Fix equality metamethod for Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
    24
	if getmetatable(ipA) ~= ip_mt or getmetatable(ipB) ~= ip_mt then
079b31c8dbf2 util.ip: Fix equality metamethod for Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
    25
		-- Lua 5.3+ calls this if both operands are tables, even if metatables differ
079b31c8dbf2 util.ip: Fix equality metamethod for Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
    26
		return false;
079b31c8dbf2 util.ip: Fix equality metamethod for Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
    27
	end
079b31c8dbf2 util.ip: Fix equality metamethod for Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
    28
	return ipA.packed == ipB.packed;
079b31c8dbf2 util.ip: Fix equality metamethod for Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
    29
end
8431
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    30
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    31
local hex2bits = {
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    32
	["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011",
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    33
	["4"] = "0100", ["5"] = "0101", ["6"] = "0110", ["7"] = "0111",
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    34
	["8"] = "1000", ["9"] = "1001", ["A"] = "1010", ["B"] = "1011",
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    35
	["C"] = "1100", ["D"] = "1101", ["E"] = "1110", ["F"] = "1111",
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    36
};
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    37
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    38
local function new_ip(ipStr, proto)
8433
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    39
	local zone;
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    40
	if (not proto or proto == "IPv6") and ipStr:find('%', 1, true) then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    41
		ipStr, zone = ipStr:match("^(.-)%%(.*)");
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    42
	end
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    43
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    44
	local packed, err = net.pton(ipStr);
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    45
	if not packed then return packed, err end
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    46
	if proto == "IPv6" and #packed ~= 16 then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    47
		return nil, "invalid-ipv6";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    48
	elseif proto == "IPv4" and #packed ~= 4 then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    49
		return nil, "invalid-ipv4";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    50
	elseif not proto then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    51
		if #packed == 16 then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    52
			proto = "IPv6";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    53
		elseif #packed == 4 then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    54
			proto = "IPv4";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    55
		else
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    56
			return nil, "unknown protocol";
7055
306aabf2d57d util.ip: Automatically determine protocol of IP address if none specified. Return error if invalid. [Backported from 0.10]
Matthew Wild <mwild1@gmail.com>
parents: 5597
diff changeset
    57
		end
8433
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    58
	elseif proto ~= "IPv6" and proto ~= "IPv4" then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    59
		return nil, "invalid protocol";
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    60
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    61
8433
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    62
	return setmetatable({ addr = ipStr, packed = packed, proto = proto, zone = zone }, ip_mt);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    63
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    64
8436
ca7f8e60410a util.ip: Add a method returning a normalized IP address
Kim Alvefur <zash@zash.se>
parents: 8435
diff changeset
    65
function ip_methods:normal()
ca7f8e60410a util.ip: Add a method returning a normalized IP address
Kim Alvefur <zash@zash.se>
parents: 8435
diff changeset
    66
	return net.ntop(self.packed);
ca7f8e60410a util.ip: Add a method returning a normalized IP address
Kim Alvefur <zash@zash.se>
parents: 8435
diff changeset
    67
end
ca7f8e60410a util.ip: Add a method returning a normalized IP address
Kim Alvefur <zash@zash.se>
parents: 8435
diff changeset
    68
8434
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    69
function ip_methods.bits(ip)
12359
a0ff5c438e9d util.hex: Deprecate to/from in favour of encode/decode, for consistency!
Matthew Wild <mwild1@gmail.com>
parents: 11654
diff changeset
    70
	return hex.encode(ip.packed):upper():gsub(".", hex2bits);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    71
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    72
8434
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    73
function ip_methods.bits_full(ip)
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    74
	if ip.proto == "IPv4" then
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    75
		ip = ip.toV4mapped;
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    76
	end
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    77
	return ip.bits;
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    78
end
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    79
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    80
local match;
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    81
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    82
local function commonPrefixLength(ipA, ipB)
8434
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    83
	ipA, ipB = ipA.bits_full, ipB.bits_full;
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    84
	for i = 1, 128 do
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    85
		if ipA:sub(i,i) ~= ipB:sub(i,i) then
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    86
			return i-1;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    87
		end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    88
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    89
	return 128;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    90
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    91
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    92
-- Instantiate once
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    93
local loopback = new_ip("::1");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    94
local loopback4 = new_ip("127.0.0.0");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    95
local sixtofour = new_ip("2002::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    96
local teredo = new_ip("2001::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    97
local linklocal = new_ip("fe80::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    98
local linklocal4 = new_ip("169.254.0.0");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    99
local uniquelocal = new_ip("fc00::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   100
local sitelocal = new_ip("fec0::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   101
local sixbone = new_ip("3ffe::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   102
local defaultunicast = new_ip("::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   103
local multicast = new_ip("ff00::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   104
local ipv6mapped = new_ip("::ffff:0:0");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   105
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   106
local function v4scope(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   107
	if match(ip, loopback4, 8) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   108
		return 0x2;
11653
aa119de5f6c7 util.ip: Fix netmask for link-local address range
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
   109
	elseif match(ip, linklocal4, 16) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   110
		return 0x2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   111
	else -- Global unicast
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   112
		return 0xE;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   113
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   114
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   115
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   116
local function v6scope(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   117
	if ip == loopback then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   118
		return 0x2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   119
	elseif match(ip, linklocal, 10) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   120
		return 0x2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   121
	elseif match(ip, sitelocal, 10) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   122
		return 0x5;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   123
	elseif match(ip, multicast, 10) then
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   124
		return ip.packed:byte(2) % 0x10;
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   125
	else -- Global unicast
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   126
		return 0xE;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   127
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   128
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   129
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   130
local function label(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   131
	if ip == loopback then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   132
		return 0;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   133
	elseif match(ip, sixtofour, 16) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   134
		return 2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   135
	elseif match(ip, teredo, 32) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   136
		return 5;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   137
	elseif match(ip, uniquelocal, 7) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   138
		return 13;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   139
	elseif match(ip, sitelocal, 10) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   140
		return 11;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   141
	elseif match(ip, sixbone, 16) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   142
		return 12;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   143
	elseif match(ip, defaultunicast, 96) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   144
		return 3;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   145
	elseif match(ip, ipv6mapped, 96) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   146
		return 4;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   147
	else
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   148
		return 1;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   149
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   150
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   151
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   152
local function precedence(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   153
	if ip == loopback then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   154
		return 50;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   155
	elseif match(ip, sixtofour, 16) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   156
		return 30;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   157
	elseif match(ip, teredo, 32) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   158
		return 5;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   159
	elseif match(ip, uniquelocal, 7) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   160
		return 3;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   161
	elseif match(ip, sitelocal, 10) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   162
		return 1;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   163
	elseif match(ip, sixbone, 16) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   164
		return 1;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   165
	elseif match(ip, defaultunicast, 96) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   166
		return 1;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   167
	elseif match(ip, ipv6mapped, 96) then
5552
40e7a6cf15ff util.rfc{3484,6724}: Update to RFC 6724
Florian Zeitz <florob@babelmonkeys.de>
parents: 4433
diff changeset
   168
		return 35;
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   169
	else
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   170
		return 40;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   171
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   172
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   173
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   174
function ip_methods:toV4mapped()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   175
	if self.proto ~= "IPv4" then return nil, "No IPv4 address" end
8437
ec8f37baffaa util.ip: Simplify creation of IPv6-mapped IPv4 addresses
Kim Alvefur <zash@zash.se>
parents: 8436
diff changeset
   176
	local value = new_ip("::ffff:" .. self.normal);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   177
	return value;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   178
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   179
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   180
function ip_methods:label()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   181
	if self.proto == "IPv4" then
8472
52d48cea1f60 util.ip: Remove redundant caching of method output (supposed to be done in ab9ddfb03d4d but lost somehow)
Kim Alvefur <zash@zash.se>
parents: 8471
diff changeset
   182
		return label(self.toV4mapped);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   183
	else
8472
52d48cea1f60 util.ip: Remove redundant caching of method output (supposed to be done in ab9ddfb03d4d but lost somehow)
Kim Alvefur <zash@zash.se>
parents: 8471
diff changeset
   184
		return label(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   185
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   186
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   187
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   188
function ip_methods:precedence()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   189
	if self.proto == "IPv4" then
8472
52d48cea1f60 util.ip: Remove redundant caching of method output (supposed to be done in ab9ddfb03d4d but lost somehow)
Kim Alvefur <zash@zash.se>
parents: 8471
diff changeset
   190
		return precedence(self.toV4mapped);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   191
	else
8472
52d48cea1f60 util.ip: Remove redundant caching of method output (supposed to be done in ab9ddfb03d4d but lost somehow)
Kim Alvefur <zash@zash.se>
parents: 8471
diff changeset
   192
		return precedence(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   193
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   194
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   195
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   196
function ip_methods:scope()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   197
	if self.proto == "IPv4" then
8472
52d48cea1f60 util.ip: Remove redundant caching of method output (supposed to be done in ab9ddfb03d4d but lost somehow)
Kim Alvefur <zash@zash.se>
parents: 8471
diff changeset
   198
		return v4scope(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   199
	else
8472
52d48cea1f60 util.ip: Remove redundant caching of method output (supposed to be done in ab9ddfb03d4d but lost somehow)
Kim Alvefur <zash@zash.se>
parents: 8471
diff changeset
   200
		return v6scope(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   201
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   202
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   203
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   204
local rfc1918_8 = new_ip("10.0.0.0");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   205
local rfc1918_12 = new_ip("172.16.0.0");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   206
local rfc1918_16 = new_ip("192.168.0.0");
8442
293dbb08427b util.ip: Add CGNAT network range reserved in RFC 6598
Kim Alvefur <zash@zash.se>
parents: 8441
diff changeset
   207
local rfc6598 = new_ip("100.64.0.0");
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   208
5588
8c1a3243d16f util.ip: Add 'private' method/property to determine whether an IP address is generally expected to be internet-routeable (YMMV)
Matthew Wild <mwild1@gmail.com>
parents: 5587
diff changeset
   209
function ip_methods:private()
8c1a3243d16f util.ip: Add 'private' method/property to determine whether an IP address is generally expected to be internet-routeable (YMMV)
Matthew Wild <mwild1@gmail.com>
parents: 5587
diff changeset
   210
	local private = self.scope ~= 0xE;
8c1a3243d16f util.ip: Add 'private' method/property to determine whether an IP address is generally expected to be internet-routeable (YMMV)
Matthew Wild <mwild1@gmail.com>
parents: 5587
diff changeset
   211
	if not private and self.proto == "IPv4" then
9959
c74c89a96cbf util.ip: Add missing netmask for 192.168/16 range (fixes #1343)
Kim Alvefur <zash@zash.se>
parents: 8472
diff changeset
   212
		return match(self, rfc1918_8, 8) or match(self, rfc1918_12, 12) or match(self, rfc1918_16, 16) or match(self, rfc6598, 10);
5588
8c1a3243d16f util.ip: Add 'private' method/property to determine whether an IP address is generally expected to be internet-routeable (YMMV)
Matthew Wild <mwild1@gmail.com>
parents: 5587
diff changeset
   213
	end
8c1a3243d16f util.ip: Add 'private' method/property to determine whether an IP address is generally expected to be internet-routeable (YMMV)
Matthew Wild <mwild1@gmail.com>
parents: 5587
diff changeset
   214
	return private;
8c1a3243d16f util.ip: Add 'private' method/property to determine whether an IP address is generally expected to be internet-routeable (YMMV)
Matthew Wild <mwild1@gmail.com>
parents: 5587
diff changeset
   215
end
8c1a3243d16f util.ip: Add 'private' method/property to determine whether an IP address is generally expected to be internet-routeable (YMMV)
Matthew Wild <mwild1@gmail.com>
parents: 5587
diff changeset
   216
5603
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   217
local function parse_cidr(cidr)
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   218
	local bits;
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   219
	local ip_len = cidr:find("/", 1, true);
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   220
	if ip_len then
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   221
		bits = tonumber(cidr:sub(ip_len+1, -1));
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   222
		cidr = cidr:sub(1, ip_len-1);
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   223
	end
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   224
	return new_ip(cidr), bits;
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   225
end
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   226
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   227
function match(ipA, ipB, bits)
8441
499663bd0122 util.ip: Do exact match for longer bit counts than available
Kim Alvefur <zash@zash.se>
parents: 8440
diff changeset
   228
	if not bits or bits >= 128 or ipB.proto == "IPv4" and bits >= 32 then
8440
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   229
		return ipA == ipB;
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   230
	elseif bits < 1 then
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   231
		return true;
5603
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   232
	end
8440
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   233
	if ipA.proto ~= ipB.proto then
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   234
		if ipA.proto == "IPv4" then
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   235
			ipA = ipA.toV4mapped;
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   236
		elseif ipB.proto == "IPv4" then
8471
5bfe58539b6c util.ip: Convert the correct IP to IPv6-mapped for comparison (fixes traceback, possibly invalid result)
Kim Alvefur <zash@zash.se>
parents: 8444
diff changeset
   237
			ipB = ipB.toV4mapped;
8440
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   238
			bits = bits + (128 - 32);
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   239
		end
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   240
	end
021129f7b0a3 util.ip: Do CIDR matching by comparing all bits at once instead of using O(n) function
Kim Alvefur <zash@zash.se>
parents: 8439
diff changeset
   241
	return ipA.bits:sub(1, bits) == ipB.bits:sub(1, bits);
5603
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   242
end
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   243
8432
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   244
return {
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   245
	new_ip = new_ip,
5603
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   246
	commonPrefixLength = commonPrefixLength,
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   247
	parse_cidr = parse_cidr,
8432
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   248
	match = match,
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   249
};