util/ip.lua
author Kim Alvefur <zash@zash.se>
Thu, 04 Nov 2021 01:00:06 +0100
branch0.11
changeset 12093 76b4e3f12b53
parent 11653 aa119de5f6c7
child 11654 a227bc35771e
permissions -rw-r--r--
mod_pep: Wipe pubsub service on user deletion Data is already wiped from storage, but this ensures everything is properly unsubscribed, possibly with notifications etc. Clears recipient cache as well, since it is no longer relevant.
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,
8444
e6e69be59233 util.ip: Do equality checking by comparing packed representation to avoid any variations
Kim Alvefur <zash@zash.se>
parents: 8442
diff changeset
    22
	__eq = function (ipA, ipB) return ipA.packed == ipB.packed; end
8431
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    23
};
ca44e462322c util.ip: Reflow metatable
Kim Alvefur <zash@zash.se>
parents: 8385
diff changeset
    24
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    25
local hex2bits = {
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7489
diff changeset
    26
	["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
    27
	["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
    28
	["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
    29
	["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
    30
};
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    31
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    32
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
    33
	local zone;
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    34
	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
    35
		ipStr, zone = ipStr:match("^(.-)%%(.*)");
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    36
	end
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    37
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    38
	local packed, err = net.pton(ipStr);
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    39
	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
    40
	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
    41
		return nil, "invalid-ipv6";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    42
	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
    43
		return nil, "invalid-ipv4";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    44
	elseif not proto then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    45
		if #packed == 16 then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    46
			proto = "IPv6";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    47
		elseif #packed == 4 then
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    48
			proto = "IPv4";
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    49
		else
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    50
			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
    51
		end
8433
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    52
	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
    53
		return nil, "invalid protocol";
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    54
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    55
8433
a58d560aa8d5 util.ip: Parse IP address using inet_pton
Kim Alvefur <zash@zash.se>
parents: 8432
diff changeset
    56
	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
    57
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    58
8436
ca7f8e60410a util.ip: Add a method returning a normalized IP address
Kim Alvefur <zash@zash.se>
parents: 8435
diff changeset
    59
function ip_methods:normal()
ca7f8e60410a util.ip: Add a method returning a normalized IP address
Kim Alvefur <zash@zash.se>
parents: 8435
diff changeset
    60
	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
    61
end
ca7f8e60410a util.ip: Add a method returning a normalized IP address
Kim Alvefur <zash@zash.se>
parents: 8435
diff changeset
    62
8434
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    63
function ip_methods.bits(ip)
8435
da807f4f706c util.ip: Simplify bitstring method
Kim Alvefur <zash@zash.se>
parents: 8434
diff changeset
    64
	return hex.to(ip.packed):upper():gsub(".", hex2bits);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    65
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    66
8434
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    67
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
    68
	if ip.proto == "IPv4" then
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    69
		ip = ip.toV4mapped;
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    70
	end
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    71
	return ip.bits;
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    72
end
a5a03d40a20c util.ip: Make bit string function into a method
Kim Alvefur <zash@zash.se>
parents: 8433
diff changeset
    73
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    74
local match;
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    75
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    76
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
    77
	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
    78
	for i = 1, 128 do
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    79
		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
    80
			return i-1;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    81
		end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    82
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    83
	return 128;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    84
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
    85
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    86
-- Instantiate once
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    87
local loopback = new_ip("::1");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    88
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
    89
local sixtofour = new_ip("2002::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    90
local teredo = new_ip("2001::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    91
local linklocal = new_ip("fe80::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    92
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
    93
local uniquelocal = new_ip("fc00::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    94
local sitelocal = new_ip("fec0::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    95
local sixbone = new_ip("3ffe::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    96
local defaultunicast = new_ip("::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    97
local multicast = new_ip("ff00::");
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
    98
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
    99
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   100
local function v4scope(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   101
	if match(ip, loopback4, 8) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   102
		return 0x2;
11653
aa119de5f6c7 util.ip: Fix netmask for link-local address range
Kim Alvefur <zash@zash.se>
parents: 9959
diff changeset
   103
	elseif match(ip, linklocal4, 16) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   104
		return 0x2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   105
	else -- Global unicast
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   106
		return 0xE;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   107
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   108
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   109
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   110
local function v6scope(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   111
	if ip == loopback then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   112
		return 0x2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   113
	elseif match(ip, linklocal, 10) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   114
		return 0x2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   115
	elseif match(ip, sitelocal, 10) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   116
		return 0x5;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   117
	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
   118
		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
   119
	else -- Global unicast
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   120
		return 0xE;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   121
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   122
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   123
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   124
local function label(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   125
	if ip == loopback then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   126
		return 0;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   127
	elseif match(ip, sixtofour, 16) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   128
		return 2;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   129
	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
   130
		return 5;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   131
	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
   132
		return 13;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   133
	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
   134
		return 11;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   135
	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
   136
		return 12;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   137
	elseif match(ip, defaultunicast, 96) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   138
		return 3;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   139
	elseif match(ip, ipv6mapped, 96) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   140
		return 4;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   141
	else
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   142
		return 1;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   143
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   144
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   145
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   146
local function precedence(ip)
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   147
	if ip == loopback then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   148
		return 50;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   149
	elseif match(ip, sixtofour, 16) then
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   150
		return 30;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   151
	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
   152
		return 5;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   153
	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
   154
		return 3;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   155
	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
   156
		return 1;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   157
	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
   158
		return 1;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   159
	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
   160
		return 1;
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   161
	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
   162
		return 35;
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   163
	else
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   164
		return 40;
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   165
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   166
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   167
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   168
function ip_methods:toV4mapped()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   169
	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
   170
	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
   171
	return value;
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:label()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   175
	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
   176
		return label(self.toV4mapped);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   177
	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
   178
		return label(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   179
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   180
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   181
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   182
function ip_methods:precedence()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   183
	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
   184
		return precedence(self.toV4mapped);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   185
	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
   186
		return precedence(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   187
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   188
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   189
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   190
function ip_methods:scope()
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   191
	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
   192
		return v4scope(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   193
	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
   194
		return v6scope(self);
4422
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   195
	end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   196
end
b1e49cc314cb util.ip: New module containing IP related functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff changeset
   197
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   198
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
   199
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
   200
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
   201
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
   202
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
   203
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
   204
	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
   205
	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
   206
		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
   207
	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
   208
	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
   209
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
   210
5603
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   211
local function parse_cidr(cidr)
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   212
	local bits;
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   213
	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
   214
	if ip_len then
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   215
		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
   216
		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
   217
	end
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   218
	return new_ip(cidr), bits;
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   219
end
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   220
8438
47195f035d2f util.ip: Instantiate various addresses used for comparisons once
Kim Alvefur <zash@zash.se>
parents: 8437
diff changeset
   221
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
   222
	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
   223
		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
   224
	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
   225
		return true;
5603
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   226
	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
   227
	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
   228
		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
   229
			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
   230
		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
   231
			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
   232
			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
   233
		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
   234
	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
   235
	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
   236
end
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   237
8432
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   238
return {
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   239
	new_ip = new_ip,
5603
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   240
	commonPrefixLength = commonPrefixLength,
e07f4f02e4f9 util.ip: Add CIDR notation parsing and matching
Matthew Wild <mwild1@gmail.com>
parents: 5599
diff changeset
   241
	parse_cidr = parse_cidr,
8432
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   242
	match = match,
b3562a1b1caa util.ip: Reflow module export table
Kim Alvefur <zash@zash.se>
parents: 8431
diff changeset
   243
};