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