xref: /aosp_15_r20/external/bcc/examples/lua/sock-parse-http.lua (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
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 TCP/HTTP that counts frequency of types of requests
18*387f9dfdSAndroid Build Coastguard Worker-- and shows more complicated pattern matching constructions and slices.
19*387f9dfdSAndroid Build Coastguard Worker-- Rewrite of a BCC example:
20*387f9dfdSAndroid Build Coastguard Worker-- https://github.com/iovisor/bcc/blob/master/examples/networking/http_filter/http-parse-simple.c
21*387f9dfdSAndroid Build Coastguard Workerlocal ffi = require("ffi")
22*387f9dfdSAndroid Build Coastguard Workerlocal bpf = require("bpf")
23*387f9dfdSAndroid Build Coastguard Workerlocal S = require("syscall")
24*387f9dfdSAndroid Build Coastguard Worker
25*387f9dfdSAndroid Build Coastguard Worker-- Shared part of the program
26*387f9dfdSAndroid Build Coastguard Workerlocal map = bpf.map('hash', 64)
27*387f9dfdSAndroid Build Coastguard Worker-- Kernel-space part of the program
28*387f9dfdSAndroid Build Coastguard Workerlocal prog = bpf.socket('lo', function (skb)
29*387f9dfdSAndroid Build Coastguard Worker	-- Only ingress so we don't count twice on loopback
30*387f9dfdSAndroid Build Coastguard Worker	if skb.ingress_ifindex == 0 then return end
31*387f9dfdSAndroid Build Coastguard Worker	local data = pkt.ip.tcp.data  -- Get TCP protocol dissector
32*387f9dfdSAndroid Build Coastguard Worker	-- Continue only if we have 7 bytes of TCP data
33*387f9dfdSAndroid Build Coastguard Worker	if data + 7 > skb.len then return end
34*387f9dfdSAndroid Build Coastguard Worker	-- Fetch 4 bytes of TCP data and compare
35*387f9dfdSAndroid Build Coastguard Worker	local h = data(0, 4)
36*387f9dfdSAndroid Build Coastguard Worker	if h == 'HTTP' or h == 'GET ' or
37*387f9dfdSAndroid Build Coastguard Worker	   h == 'POST' or h == 'PUT ' or
38*387f9dfdSAndroid Build Coastguard Worker	   h == 'HEAD' or h == 'DELE' then
39*387f9dfdSAndroid Build Coastguard Worker	   	-- If hash key doesn't exist, create it
40*387f9dfdSAndroid Build Coastguard Worker	   	-- otherwise increment counter
41*387f9dfdSAndroid Build Coastguard Worker	   local v = map[h]
42*387f9dfdSAndroid Build Coastguard Worker	   if not v then map[h] = 1
43*387f9dfdSAndroid Build Coastguard Worker	   else          xadd(map[h], 1)
44*387f9dfdSAndroid Build Coastguard Worker	   end
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	local strkey = ffi.new('uint32_t [1]')
50*387f9dfdSAndroid Build Coastguard Worker	local s = ''
51*387f9dfdSAndroid Build Coastguard Worker	for k,v in map.pairs,map,0 do
52*387f9dfdSAndroid Build Coastguard Worker		strkey[0] = bpf.ntoh(k)
53*387f9dfdSAndroid Build Coastguard Worker		s = s..string.format('%s %d ', ffi.string(strkey, 4):match '^%s*(.-)%s*$', tonumber(v))
54*387f9dfdSAndroid Build Coastguard Worker	end
55*387f9dfdSAndroid Build Coastguard Worker	if #s > 0 then print(s..'messages') end
56*387f9dfdSAndroid Build Coastguard Worker	S.sleep(1)
57*387f9dfdSAndroid Build Coastguard Workerend