diff --git a/src/apps/keyed_ipv6_tunnel/tunnel.lua b/src/apps/keyed_ipv6_tunnel/tunnel.lua index 63e571231c..92c2c33757 100644 --- a/src/apps/keyed_ipv6_tunnel/tunnel.lua +++ b/src/apps/keyed_ipv6_tunnel/tunnel.lua @@ -16,6 +16,8 @@ local packet = require("core.packet") local buffer = require("core.buffer") local config = require("core.config") +local macaddress = require("lib.macaddress") + local pcap = require("apps.pcap.pcap") local basic_apps = require("apps.basic.basic_apps") @@ -48,8 +50,9 @@ local pcookie_ctype = ffi.typeof("uint64_t*") local address_ctype = ffi.typeof("uint64_t[2]") local paddress_ctype = ffi.typeof("uint64_t*") local plength_ctype = ffi.typeof("int16_t*") -local psession_id_ctype = ffi.typeof("int32_t*") +local psession_id_ctype = ffi.typeof("uint32_t*") +local DST_MAC_OFFSET = ffi.offsetof(header_struct_ctype, 'dmac') local SRC_IP_OFFSET = ffi.offsetof(header_struct_ctype, 'src_ip') local DST_IP_OFFSET = ffi.offsetof(header_struct_ctype, 'dst_ip') local COOKIE_OFFSET = ffi.offsetof(header_struct_ctype, 'cookie') @@ -105,7 +108,8 @@ function SimpleKeyedTunnel:new (confstring) -- local_cookie, 8 bytes string -- remote_cookie, 8 bytes string -- optional fields: - -- local_session, signed number, must fit to int32_t + -- local_session, unsigned number, must fit to uint32_t + -- default_gateway_MAC, useful for testing assert( type(config.local_cookie) == "string" and #config.local_cookie == 8, @@ -141,7 +145,12 @@ function SimpleKeyedTunnel:new (confstring) if config.local_session then local psession = ffi.cast(psession_id_ctype, header + SESSION_ID_OFFSET) - psession[0] = config.local_session + psession[0] = lib.htonl(config.local_session) + end + + if config.default_gateway_MAC then + local mac = assert(macaddress:new(config.default_gateway_MAC)) + ffi.copy(header + DST_MAC_OFFSET, mac.bytes, 6) end local o = @@ -171,7 +180,7 @@ function SimpleKeyedTunnel:push() -- set payload size local plength = ffi.cast(plength_ctype, new_b.pointer + LENGTH_OFFSET) - plength[0] = C.htons(SESSION_COOKIE_SIZE + p.length) + plength[0] = lib.htons(SESSION_COOKIE_SIZE + p.length) packet.prepend_iovec(p, new_b, HEADER_SIZE) link.transmit(l_out, p) @@ -260,7 +269,8 @@ function selftest () local_address = "00::2:1", remote_address = "00::2:1", local_cookie = "12345678", - remote_cookie = "12345678" + remote_cookie = "12345678", + default_gateway_MAC = "a1:b2:c3:d4:e5:f6" } ]] -- should be symmetric for local "loop-back" test diff --git a/src/apps/packet_filter/packet_filter.lua b/src/apps/packet_filter/packet_filter.lua index 471a1d99c9..990f928a24 100644 --- a/src/apps/packet_filter/packet_filter.lua +++ b/src/apps/packet_filter/packet_filter.lua @@ -242,9 +242,7 @@ local function generatePortMatch(T, offset, port_min, port_max, name) if port_min == port_max then -- specialization for single port matching -- avoid conversion to host order on runtime - local port_network_order = - bit.lshift(bit.band(port_min, 0xff), 8) + bit.rshift(port_min, 8) - -- TODO: generalize htons() + local port_network_order = lib.htons(ourt_min) T("local ",name," = ffi.cast(\"uint16_t*\", buffer + ",offset,")") T("if ",name,"[0] ~= ",port_network_order," then break end") diff --git a/src/core/lib.lua b/src/core/lib.lua index 92baf3ef1e..3148ee3670 100644 --- a/src/core/lib.lua +++ b/src/core/lib.lua @@ -264,6 +264,19 @@ function malloc (type) return ffi.cast(ffi.typeof("$*", ffi_type), ptr) end +-- endian conversion helpers written in Lua +-- avoid C function call overhead while using C.xxxx counterparts +if ffi.abi("be") then + -- nothing to do + function htonl(b) return b end + function htons(b) return b end +else + function htonl(b) return bit.bswap(b) end + function htons(b) return bit.rshift(bit.bswap(b), 16) end +end +ntohl = htonl +ntohs = htons + function selftest () print("selftest: lib") local data = "\x45\x00\x00\x73\x00\x00\x40\x00\x40\x11\xc0\xa8\x00\x01\xc0\xa8\x00\xc7" @@ -278,4 +291,3 @@ function selftest () assert(hexundump('4500 B67D 00FA400040 11', 10) =='\x45\x00\xb6\x7d\x00\xFA\x40\x00\x40\x11', "wrong hex undump") end - diff --git a/src/lib/macaddress.lua b/src/lib/macaddress.lua index 6719ef10ef..fff5f7bb3a 100644 --- a/src/lib/macaddress.lua +++ b/src/lib/macaddress.lua @@ -15,9 +15,16 @@ function mac_mt:new (m) local macobj = mac_t() local i = 0; for b in m:gmatch('[0-9a-fA-F][0-9a-fA-F]') do + if i == 6 then + -- avoid out of bound array index + return nil, "malformed MAC address: " .. m + end macobj.bytes[i] = tonumber(b, 16) i = i + 1 end + if i < 6 then + return nil, "malformed MAC address: " .. m + end return macobj end @@ -39,4 +46,4 @@ end mac_t = ffi.metatype(mac_t, mac_mt) -return mac_mt \ No newline at end of file +return mac_mt