Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
b263926f
Commit
b263926f
authored
May 13, 2016
by
Qasim Sarfraz
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into patch-1
parents
f712dca2
a67ef8aa
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
455 additions
and
3 deletions
+455
-3
examples/CMakeLists.txt
examples/CMakeLists.txt
+1
-0
examples/lua/CMakeLists.txt
examples/lua/CMakeLists.txt
+4
-0
examples/networking/CMakeLists.txt
examples/networking/CMakeLists.txt
+2
-0
examples/networking/dns_matching/dns_matching.c
examples/networking/dns_matching/dns_matching.c
+105
-0
examples/networking/dns_matching/dns_matching.py
examples/networking/dns_matching/dns_matching.py
+57
-0
examples/networking/http_filter/CMakeLists.txt
examples/networking/http_filter/CMakeLists.txt
+4
-0
examples/networking/tunnel_monitor/CMakeLists.txt
examples/networking/tunnel_monitor/CMakeLists.txt
+4
-0
src/lua/src/main.c
src/lua/src/main.c
+3
-3
tools/biosnoop.lua
tools/biosnoop.lua
+183
-0
tools/stacksnoop.lua
tools/stacksnoop.lua
+92
-0
No files found.
examples/CMakeLists.txt
View file @
b263926f
...
@@ -3,3 +3,4 @@ install(PROGRAMS ${EXAMPLE_PROGRAMS} DESTINATION share/bcc/examples)
...
@@ -3,3 +3,4 @@ install(PROGRAMS ${EXAMPLE_PROGRAMS} DESTINATION share/bcc/examples)
add_subdirectory
(
networking
)
add_subdirectory
(
networking
)
add_subdirectory
(
tracing
)
add_subdirectory
(
tracing
)
add_subdirectory
(
lua
)
\ No newline at end of file
examples/lua/CMakeLists.txt
0 → 100644
View file @
b263926f
file
(
GLOB C_FILES *.c
)
file
(
GLOB LUA_FILES *.lua
)
install
(
FILES
${
C_FILES
}
DESTINATION share/bcc/examples/lua
)
install
(
PROGRAMS
${
LUA_FILES
}
DESTINATION share/bcc/examples/lua
)
\ No newline at end of file
examples/networking/CMakeLists.txt
View file @
b263926f
...
@@ -6,3 +6,5 @@ install(PROGRAMS ${EXAMPLE_PROGRAMS} DESTINATION share/bcc/examples/networking)
...
@@ -6,3 +6,5 @@ install(PROGRAMS ${EXAMPLE_PROGRAMS} DESTINATION share/bcc/examples/networking)
add_subdirectory
(
distributed_bridge
)
add_subdirectory
(
distributed_bridge
)
add_subdirectory
(
neighbor_sharing
)
add_subdirectory
(
neighbor_sharing
)
add_subdirectory
(
vlan_learning
)
add_subdirectory
(
vlan_learning
)
add_subdirectory
(
tunnel_monitor
)
add_subdirectory
(
http_filter
)
\ No newline at end of file
examples/networking/dns_matching/dns_matching.c
0 → 100644
View file @
b263926f
/*
* dns_matching.c Drop DNS packets requesting DNS name contained in hash map
* For Linux, uses BCC, eBPF. See .py file.
*
* Copyright (c) 2016 Rudi Floren.
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* 11-May-2016 Rudi Floren Created this.
*/
#include <uapi/linux/bpf.h>
#include <uapi/linux/if_ether.h>
#include <uapi/linux/if_packet.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/in.h>
#include <uapi/linux/udp.h>
#include <bcc/proto.h>
#define ETH_LEN 14
struct
dns_hdr_t
{
uint16_t
id
;
uint16_t
flags
;
uint16_t
qdcount
;
uint16_t
ancount
;
uint16_t
nscount
;
uint16_t
arcount
;
}
BPF_PACKET_HEADER
;
struct
dns_query_flags_t
{
uint16_t
qtype
;
uint16_t
qclass
;
}
BPF_PACKET_HEADER
;
struct
dns_char_t
{
char
c
;
}
BPF_PACKET_HEADER
;
struct
Key
{
unsigned
char
p
[
32
];
};
struct
Leaf
{
// Not really needed in this example
unsigned
char
p
[
4
];
};
BPF_TABLE
(
"hash"
,
struct
Key
,
struct
Leaf
,
cache
,
128
);
int
dns_matching
(
struct
__sk_buff
*
skb
)
{
u8
*
cursor
=
0
;
struct
Key
key
=
{};
// Check of ethernet/IP frame.
struct
ethernet_t
*
ethernet
=
cursor_advance
(
cursor
,
sizeof
(
*
ethernet
));
if
(
ethernet
->
type
==
ETH_P_IP
)
{
// Check for UDP.
struct
ip_t
*
ip
=
cursor_advance
(
cursor
,
sizeof
(
*
ip
));
u16
hlen_bytes
=
ip
->
hlen
<<
2
;
if
(
ip
->
nextp
==
IPPROTO_UDP
)
{
// Check for Port 53, DNS packet.
struct
udp_t
*
udp
=
cursor_advance
(
cursor
,
sizeof
(
*
udp
));
if
(
udp
->
dport
==
53
){
// Our Cursor + the length of our udp packet - size of the udp header
// - the two 16bit values for QTYPE and QCLASS.
u8
*
sentinel
=
cursor
+
udp
->
length
-
sizeof
(
*
udp
)
-
4
;
struct
dns_hdr_t
*
dns_hdr
=
cursor_advance
(
cursor
,
sizeof
(
*
dns_hdr
));
// Do nothing if packet is not a request.
if
((
dns_hdr
->
flags
>>
15
)
!=
0
)
{
// Exit if this packet is not a request.
return
-
1
;
}
u16
i
=
0
;
struct
dns_char_t
*
c
;
// This unroll worked not in latest BCC version.
for
(
u8
j
=
0
;
i
<
255
;
i
++
){
if
(
cursor
==
sentinel
)
goto
end
;
c
=
cursor_advance
(
cursor
,
1
);
key
.
p
[
i
++
]
=
c
->
c
;
}
end:
{}
struct
Leaf
*
lookup_leaf
=
cache
.
lookup
(
&
key
);
// If DNS name is contained in our map, drop packet.
if
(
lookup_leaf
)
{
return
0
;
}
}
}
}
return
-
1
;
}
examples/networking/dns_matching/dns_matching.py
0 → 100644
View file @
b263926f
#!/usr/bin/python
from
__future__
import
print_function
from
bcc
import
BPF
from
ctypes
import
*
import
sys
import
socket
import
os
import
struct
def
encode_dns
(
name
):
size
=
32
if
len
(
name
)
>
253
:
raise
Exception
(
"DNS Name too long."
)
b
=
bytearray
(
size
)
i
=
0
;
elements
=
name
.
split
(
"."
)
for
element
in
elements
:
b
[
i
]
=
struct
.
pack
(
"!B"
,
len
(
element
))
i
+=
1
for
j
in
range
(
0
,
len
(
element
)):
b
[
i
]
=
element
[
j
]
i
+=
1
return
(
c_ubyte
*
size
).
from_buffer
(
b
)
# initialize BPF - load source code from http-parse-simple.c
bpf
=
BPF
(
src_file
=
"dns_matching.c"
,
debug
=
0
)
# print(bpf.dump_func("dns_test"))
#load eBPF program http_filter of type SOCKET_FILTER into the kernel eBPF vm
#more info about eBPF program types
#http://man7.org/linux/man-pages/man2/bpf.2.html
function_dns_matching
=
bpf
.
load_func
(
"dns_matching"
,
BPF
.
SOCKET_FILTER
)
#create raw socket, bind it to eth0
#attach bpf program to socket created
BPF
.
attach_raw_socket
(
function_dns_matching
,
"eth1"
)
# Get the table.
cache
=
bpf
.
get_table
(
"cache"
)
# Create first entry for foo.bar
key
=
cache
.
Key
()
key
.
p
=
encode_dns
(
"foo.bar"
)
leaf
=
cache
.
Leaf
()
leaf
.
p
=
(
c_ubyte
*
4
).
from_buffer
(
bytearray
(
4
))
cache
[
key
]
=
leaf
bpf
.
trace_print
()
examples/networking/http_filter/CMakeLists.txt
0 → 100644
View file @
b263926f
set
(
FILES http-parse-complete.c http-parse-simple.c README.md
)
set
(
PROGRAMS http-parse-complete.py http-parse-simple.py
)
install
(
FILES
${
FILES
}
DESTINATION share/bcc/examples/networking/http_filter
)
install
(
PROGRAMS
${
PROGRAMS
}
DESTINATION share/bcc/examples/networking/http_filter
)
examples/networking/tunnel_monitor/CMakeLists.txt
0 → 100644
View file @
b263926f
set
(
FILES README.md chord.png monitor.c simulation.py vxlan.jpg
)
set
(
PROGRAMS main.py monitor.py setup.sh traffic.sh
)
install
(
FILES
${
FILES
}
DESTINATION share/bcc/examples/networking/tunnel_monitor
)
install
(
PROGRAMS
${
PROGRAMS
}
DESTINATION share/bcc/examples/networking/tunnel_monitor
)
\ No newline at end of file
src/lua/src/main.c
View file @
b263926f
...
@@ -29,9 +29,9 @@
...
@@ -29,9 +29,9 @@
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
#include
<luajit-2.0/lauxlib.h>
#include
"lauxlib.h"
#include
<luajit-2.0/lua.h>
#include
"lua.h"
#include
<luajit-2.0/lualib.h>
#include
"lualib.h"
static
lua_State
*
globalL
=
NULL
;
static
lua_State
*
globalL
=
NULL
;
static
const
char
*
progname
=
NULL
;
static
const
char
*
progname
=
NULL
;
...
...
tools/biosnoop.lua
0 → 100644
View file @
b263926f
#!/usr/bin/env bcc-lua
--[[
Copyright 2016 GitHub, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--]]
local
program
=
[[
#include <uapi/linux/ptrace.h>
#include <linux/blkdev.h>
struct val_t {
u32 pid;
char name[TASK_COMM_LEN];
};
struct data_t {
u32 pid;
u64 rwflag;
u64 delta;
u64 sector;
u64 len;
u64 ts;
char disk_name[DISK_NAME_LEN];
char name[TASK_COMM_LEN];
};
BPF_HASH(start, struct request *);
BPF_HASH(infobyreq, struct request *, struct val_t);
BPF_PERF_OUTPUT(events);
// cache PID and comm by-req
int trace_pid_start(struct pt_regs *ctx, struct request *req)
{
struct val_t val = {};
if (bpf_get_current_comm(&val.name, sizeof(val.name)) == 0) {
val.pid = bpf_get_current_pid_tgid();
infobyreq.update(&req, &val);
}
return 0;
}
// time block I/O
int trace_req_start(struct pt_regs *ctx, struct request *req)
{
u64 ts;
ts = bpf_ktime_get_ns();
start.update(&req, &ts);
return 0;
}
// output
int trace_req_completion(struct pt_regs *ctx, struct request *req)
{
u64 *tsp, delta;
u32 *pidp = 0;
struct val_t *valp;
struct data_t data ={};
u64 ts;
// fetch timestamp and calculate delta
tsp = start.lookup(&req);
if (tsp == 0) {
// missed tracing issue
return 0;
}
ts = bpf_ktime_get_ns();
data.delta = ts - *tsp;
data.ts = ts / 1000;
valp = infobyreq.lookup(&req);
if (valp == 0) {
data.len = req->__data_len;
strcpy(data.name,"?");
} else {
data.pid = valp->pid;
data.len = req->__data_len;
data.sector = req->__sector;
bpf_probe_read(&data.name, sizeof(data.name), valp->name);
bpf_probe_read(&data.disk_name, sizeof(data.disk_name),
req->rq_disk->disk_name);
}
if (req->cmd_flags & REQ_WRITE) {
data.rwflag=1;
} else {
data.rwflag=0;
}
events.perf_submit(ctx,&data,sizeof(data));
start.delete(&req);
infobyreq.delete(&req);
return 0;
}
]]
local
ffi
=
require
(
"ffi"
)
return
function
(
BPF
,
utils
)
local
bpf
=
BPF
:
new
{
text
=
program
}
bpf
:
attach_kprobe
{
event
=
"blk_account_io_start"
,
fn_name
=
"trace_pid_start"
}
bpf
:
attach_kprobe
{
event
=
"blk_start_request"
,
fn_name
=
"trace_req_start"
}
bpf
:
attach_kprobe
{
event
=
"blk_mq_start_request"
,
fn_name
=
"trace_req_start"
}
bpf
:
attach_kprobe
{
event
=
"blk_account_io_completion"
,
fn_name
=
"trace_req_completion"
}
print
(
"%-14s %-14s %-6s %-7s %-2s %-9s %-7s %7s"
%
{
"TIME(s)"
,
"COMM"
,
"PID"
,
"DISK"
,
"T"
,
"SECTOR"
,
"BYTES"
,
"LAT(ms)"
})
local
rwflg
=
""
local
start_ts
=
0
local
prev_ts
=
0
local
delta
=
0
local
function
print_event
(
cpu
,
event
)
local
val
=
-
1
local
event_pid
=
event
.
pid
local
event_delta
=
tonumber
(
event
.
delta
)
local
event_sector
=
tonumber
(
event
.
sector
)
local
event_len
=
tonumber
(
event
.
len
)
local
event_ts
=
tonumber
(
event
.
ts
)
local
event_disk_name
=
ffi
.
string
(
event
.
disk_name
)
local
event_name
=
ffi
.
string
(
event
.
name
)
if
event
.
rwflag
==
1
then
rwflg
=
"W"
end
if
event
.
rwflag
==
0
then
rwflg
=
"R"
end
if
not
event_name
:
match
(
"%?"
)
then
val
=
event_sector
end
if
start_ts
==
0
then
prev_ts
=
start_ts
end
if
start_ts
==
1
then
delta
=
delta
+
(
event_ts
-
prev_ts
)
end
print
(
"%-14.9f %-14.14s %-6s %-7s %-2s %-9s %-7s %7.2f"
%
{
delta
/
1000000
,
event_name
,
event_pid
,
event_disk_name
,
rwflg
,
val
,
event_len
,
event_delta
/
1000000
})
prev_ts
=
event_ts
start_ts
=
1
end
local
TASK_COMM_LEN
=
16
-- linux/sched.h
local
DISK_NAME_LEN
=
32
-- linux/genhd.h
bpf
:
get_table
(
"events"
):
open_perf_buffer
(
print_event
,
[[
struct {
uint32_t pid;
uint64_t rwflag;
uint64_t delta;
uint64_t sector;
uint64_t len;
uint64_t ts;
char disk_name[%d];
char name[%d];
}
]]
%
{
DISK_NAME_LEN
,
TASK_COMM_LEN
})
bpf
:
kprobe_poll_loop
()
end
tools/stacksnoop.lua
0 → 100644
View file @
b263926f
#!/usr/bin/env bcc-lua
--[[
Copyright 2016 GitHub, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--]]
local
program
=
[[
#include <uapi/linux/ptrace.h>
BPF_STACK_TRACE(stack_traces, 128)
void trace_stack(struct pt_regs *ctx) {
FILTER
int stack_id = stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID);
if (stack_id >= 0)
bpf_trace_printk("stack_id=%d\n", stack_id);
}
]]
return
function
(
BPF
,
utils
)
local
parser
=
utils
.
argparse
(
"stacksnoop"
,
"Trace and print kernel stack traces for a kernel function"
)
parser
:
flag
(
"-s --offset"
)
parser
:
flag
(
"-v --verbose"
)
parser
:
option
(
"-p --pid"
):
convert
(
tonumber
)
parser
:
argument
(
"function"
,
"kernel function name"
):
target
(
"fn"
)
local
args
=
parser
:
parse
()
local
ksym
=
BPF
.
SymbolCache
()
local
filter
=
""
if
args
.
pid
then
filter
=
[[
u32 pid;
pid = bpf_get_current_pid_tgid();
if (pid != %d) { return; }
]]
%
args
.
pid
end
local
text
=
program
:
gsub
(
"FILTER"
,
filter
)
local
bpf
=
BPF
:
new
{
text
=
text
}
bpf
:
attach_kprobe
{
event
=
args
.
fn
,
fn_name
=
"trace_stack"
}
if
BPF
.
num_open_kprobes
()
==
0
then
print
(
"Function \"
%
s
\
" not found. Exiting."
%
args
.
fn
)
return
end
if
args
.
verbose
then
print
(
"%-18s %-12s %-6s %-3s %s"
%
{
"TIME(s)"
,
"COMM"
,
"PID"
,
"CPU"
,
"SYSCALL"
})
else
print
(
"%-18s %s"
%
{
"TIME(s)"
,
"SYSCALL"
})
end
local
stack_traces
=
bpf
:
get_table
(
"stack_traces"
)
local
pipe
=
bpf
:
pipe
()
while
true
do
local
task
,
pid
,
cpu
,
flags
,
ts
,
msg
=
pipe
:
trace_fields
()
local
stack_id
=
string.match
(
msg
,
"stack_id=(%d+)"
)
if
stack_id
then
if
args
.
verbose
then
print
(
"%-18.9f %-12.12s %-6d %-3d %s"
%
{
ts
,
task
,
pid
,
cpu
,
args
.
fn
})
else
print
(
"%-18.9f %s"
%
{
ts
,
args
.
fn
})
end
for
addr
in
stack_traces
:
walk
(
tonumber
(
stack_id
))
do
local
sym
,
offset
=
ksym
:
resolve
(
addr
)
if
args
.
offset
then
print
(
"
\t
%-16p %s+0x%x"
%
{
addr
,
sym
,
tonumber
(
offset
)})
else
print
(
"
\t
%-16p %s"
%
{
addr
,
sym
})
end
end
end
print
()
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment