diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/iputil.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/iputil.lua new file mode 100644 index 00000000..39e0897a --- /dev/null +++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/iputil.lua @@ -0,0 +1,96 @@ +local bit = require 'bit' +local string = string +local tonumber = tonumber +local table = table +module 'gluon.iputil' + +function IPv6(address) + --[[ + (c) 2008 Jo-Philipp Wich + (c) 2008 Steven Barth + + Licensed under the Apache License, Version 2.0 (the "License"). + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + ]]-- + local data = {} + + local borderl = address:sub(1, 1) == ":" and 2 or 1 + local borderh, zeroh, chunk, block + + if #address > 45 then return nil end + + repeat + borderh = address:find(":", borderl, true) + if not borderh then break end + + block = tonumber(address:sub(borderl, borderh - 1), 16) + if block and block <= 0xFFFF then + data[#data+1] = block + else + if zeroh or borderh - borderl > 1 then return nil end + zeroh = #data + 1 + end + + borderl = borderh + 1 + until #data == 7 + + chunk = address:sub(borderl) + if #chunk > 0 and #chunk <= 4 then + block = tonumber(chunk, 16) + if not block or block > 0xFFFF then return nil end + + data[#data+1] = block + elseif #chunk > 4 then + if #data == 7 or #chunk > 15 then return nil end + borderl = 1 + for i=1, 4 do + borderh = chunk:find(".", borderl, true) + if not borderh and i < 4 then return nil end + borderh = borderh and borderh - 1 + + block = tonumber(chunk:sub(borderl, borderh)) + if not block or block > 255 then return nil end + + if i == 1 or i == 3 then + data[#data+1] = block * 256 + else + data[#data] = data[#data] + block + end + + borderl = borderh and borderh + 2 + end + end + + if zeroh then + if #data == 8 then return nil end + while #data < 8 do + table.insert(data, zeroh, 0) + end + end + + if #data == 8 then + return data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8] + end +end + +function mac_to_ip(prefix, mac) + local m1, m2, m3, m6, m7, m8 = string.match(mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)') + local m4 = 0xff + local m5 = 0xfe + m1 = bit.bxor(tonumber(m1, 16), 0x02) + + local h1 = 0x100 * m1 + tonumber(m2, 16) + local h2 = 0x100 * tonumber(m3, 16) + m4 + local h3 = 0x100 * m5 + tonumber(m6, 16) + local h4 = 0x100 * tonumber(m7, 16) + tonumber(m8, 16) + + local prefix, plen = string.match(prefix, '(.*)/(%d+)') + plen = tonumber(plen, 10) + + local p1, p2, p3, p4, p5, p6, p7, p8 = IPv6(prefix) + + return string.format("%x:%x:%x:%x:%x:%x:%x:%x/%d", p1, p2, p3, p4, h1, h2, h3, h4, 128) +end + diff --git a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 index 7ab3f5ec..1d3f5381 100755 --- a/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 +++ b/package/gluon-mesh-babel/luasrc/lib/gluon/upgrade/300-gluon-mesh-babel-ip6 @@ -1,102 +1,11 @@ #!/usr/bin/lua -local bit = require 'bit' local sysconfig = require 'gluon.sysconfig' local uci = require('simple-uci').cursor() local site = require 'gluon.site' +local iputil = require 'gluon.iputil' - -function IPv6(address) - --[[ - (c) 2008 Jo-Philipp Wich - (c) 2008 Steven Barth - - Licensed under the Apache License, Version 2.0 (the "License"). - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - ]]-- - local data = {} - - local borderl = address:sub(1, 1) == ":" and 2 or 1 - local borderh, zeroh, chunk, block - - if #address > 45 then return nil end - - repeat - borderh = address:find(":", borderl, true) - if not borderh then break end - - block = tonumber(address:sub(borderl, borderh - 1), 16) - if block and block <= 0xFFFF then - data[#data+1] = block - else - if zeroh or borderh - borderl > 1 then return nil end - zeroh = #data + 1 - end - - borderl = borderh + 1 - until #data == 7 - - chunk = address:sub(borderl) - if #chunk > 0 and #chunk <= 4 then - block = tonumber(chunk, 16) - if not block or block > 0xFFFF then return nil end - - data[#data+1] = block - elseif #chunk > 4 then - if #data == 7 or #chunk > 15 then return nil end - borderl = 1 - for i=1, 4 do - borderh = chunk:find(".", borderl, true) - if not borderh and i < 4 then return nil end - borderh = borderh and borderh - 1 - - block = tonumber(chunk:sub(borderl, borderh)) - if not block or block > 255 then return nil end - - if i == 1 or i == 3 then - data[#data+1] = block * 256 - else - data[#data] = data[#data] + block - end - - borderl = borderh and borderh + 2 - end - end - - if zeroh then - if #data == 8 then return nil end - while #data < 8 do - table.insert(data, zeroh, 0) - end - end - - if #data == 8 then - return data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8] - end -end - -function mac_to_ip(prefix, mac) - local m1, m2, m3, m6, m7, m8 = string.match(mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)') - local m4 = 0xff - local m5 = 0xfe - m1 = bit.bxor(tonumber(m1, 16), 0x02) - - local h1 = 0x100 * m1 + tonumber(m2, 16) - local h2 = 0x100 * tonumber(m3, 16) + m4 - local h3 = 0x100 * m5 + tonumber(m6, 16) - local h4 = 0x100 * tonumber(m7, 16) + tonumber(m8, 16) - - local prefix, plen = string.match(prefix, '(.*)/(%d+)') - plen = tonumber(plen, 10) - - local p1, p2, p3, p4, p5, p6, p7, p8 = IPv6(prefix) - - return string.format("%x:%x:%x:%x:%x:%x:%x:%x/%d", p1, p2, p3, p4, h1, h2, h3, h4, 128) -end - -local ip = mac_to_ip(site.node_prefix6(), sysconfig.primary_mac) +local ip = iputil.mac_to_ip(site.node_prefix6(), sysconfig.primary_mac) uci:set('network', 'loopback', 'ip6addr', ip) uci:save('network')