• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env bcc-lua
2--[[
3Copyright 2016 Marek Vavrusa <mvavrusa@cloudflare.com>
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16]]
17-- Simple parsing example of UDP/DNS that counts frequency of QTYPEs.
18-- It shows how to parse packet variable-length packet structures.
19local ffi = require("ffi")
20local bpf = require("bpf")
21local S = require("syscall")
22
23-- Shared part of the program
24local map = assert(bpf.map('array', 256))
25-- Kernel-space part of the program
26local prog = bpf.socket('lo', function (skb)
27	local ip = pkt.ip   -- Accept only UDP messages
28	if ip.proto ~= c.ip.proto_udp then return false end
29	local udp = ip.udp  -- Only messages >12 octets (DNS header)
30	if udp.length < 12 then return false end
31	-- Unroll QNAME (up to 2 labels)
32	udp = udp.data + 12
33	local label = udp[0]
34	if label > 0 then
35		udp = udp + label + 1
36		label = udp[0]
37		if label > 0 then
38			udp = udp + label + 1
39		end
40	end
41	-- Track QTYPE (low types)
42	if udp[0] == 0 then
43		local qtype = udp[2] -- Low octet from QTYPE
44		xadd(map[qtype], 1)
45	end
46end)
47-- User-space part of the program
48for _ = 1, 10 do
49	for k,v in map.pairs,map,0 do
50		v = tonumber(v)
51		if v > 0 then
52			print(string.format('TYPE%d: %d', k, v))
53		end
54	end
55	S.sleep(1)
56end