Skip to content

Instantly share code, notes, and snippets.

@vavrusa
Last active March 31, 2018 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vavrusa/61fd9159b75d728076cf03daeee7a67c to your computer and use it in GitHub Desktop.
Save vavrusa/61fd9159b75d728076cf03daeee7a67c to your computer and use it in GitHub Desktop.
Fun with BPF
$ sudo luarocks install https://raw.githubusercontent.com/iovisor/bcc/master/src/lua/bpf-scm-1.rockspec
$ cat bpf_ttl.lua
local S = require('syscall')
local bpf = require('bpf')
-- Kernel-space part of the program
local map = bpf.map('array', 256)
local prog = assert(bpf(function ()
local net = pkt.net_off -- Socket filter on TCP starts from TCP otherwise
if net.ver == 4 then -- Check for IPv4
local ttl = net.ip.ttl
xadd(map[ttl], 1)
else
local ttl = net.ip6.hop_limit
xadd(map[ttl], 1)
end
return true
end))
-- Guess the starting value and count down from it
local function normalize(ttl)
if ttl > 128 then return 255 - ttl
elseif ttl > 64 then return 128 - ttl
elseif ttl > 32 then return 64 - ttl
end
return 32 - ttl
end
-- User-space part of the program
local pfd = assert(S.bpf_prog_load(S.c.BPF_PROG.SOCKET_FILTER, prog.insn, prog.pc))
for i = 1, #arg do
local family = arg[i]:find(':') and 'inet6' or 'inet'
local sockaddr = (family == 'inet6') and S.t.sockaddr_in6 or S.t.sockaddr_in
local addr = sockaddr(80, arg[i])
local sock = S.socket(family, 'stream')
assert(sock:setsockopt('socket', 'attach_bpf', pfd:getfd()))
assert(sock:connect(addr))
local mindist = 255
for ttl, c in map.pairs, map, 0 do
if c > 0 then
mindist = math.min(normalize(ttl), mindist)
map[ttl] = 0 -- Clear the value
end
end
print('TTL distance to', arg[i], 'is', mindist)
end
$ luajit bpf_ttl.lua 198.41.214.162 172.217.164.110
TTL distance to 198.41.214.162 is 5
TTL distance to 172.217.164.110 is 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment