Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion FAQ.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ A: The so-called Kernel lockdown might be the root cause. Try disabling it with
echo 1 > /proc/sys/kernel/sysrq
echo x > /proc/sysrq-trigger
Also see https://github.com/iovisor/bcc/issues/2525

If you have Secure Boot enabled you need to press Alt-PrintScr-x on the keyboard instead:
```
This sysrq operation is disabled from userspace.
Expand Down
16 changes: 8 additions & 8 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ mv /lib/modules/$KERNEL_VERSION-microsoft-standard-WSL2+/ /lib/modules/$KERNEL_V

Then you can install bcc tools package according your distribution.

If you met some problems, try to
If you met some problems, try to
```
sudo mount -t debugfs debugfs /sys/kernel/debug
```
Expand Down Expand Up @@ -387,7 +387,7 @@ sudo apt install -y zip bison build-essential cmake flex git libedit-dev \
sudo apt install -y zip bison build-essential cmake flex git libedit-dev \
libllvm14 llvm-14-dev libclang-14-dev python3 zlib1g-dev libelf-dev libfl-dev python3-setuptools \
liblzma-dev libdebuginfod-dev arping netperf iperf

# For Lunar Lobster (23.04)
sudo apt install -y zip bison build-essential cmake flex git libedit-dev \
libllvm15 llvm-15-dev libclang-15-dev python3 zlib1g-dev libelf-dev libfl-dev python3-setuptools \
Expand Down Expand Up @@ -433,7 +433,7 @@ suppose you're running with root or add sudo first
### Install build dependencies
```
dnf install -y bison cmake ethtool flex git iperf3 libstdc++-devel python3-netaddr python3-pip gcc gcc-c++ make zlib-devel elfutils-libelf-devel
# dnf install -y luajit luajit-devel ## if use luajit, will report some lua function(which in lua5.3) undefined problem
# dnf install -y luajit luajit-devel ## if use luajit, will report some lua function(which in lua5.3) undefined problem
dnf install -y clang clang-devel llvm llvm-devel llvm-static ncurses-devel
dnf -y install netperf
pip3 install pyroute2
Expand All @@ -449,7 +449,7 @@ cd bcc-build/
## here llvm should always link shared library
cmake ../bcc -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LLVM_SHARED=1
make -j10
make install
make install

```
after install, you may add bcc directory to your $PATH, which you can add to ~/.bashrc
Expand All @@ -460,20 +460,20 @@ export PATH=$bcctools:$bccexamples:$PATH
```
### let path take effect
```
source ~/.bashrc
source ~/.bashrc
```
then run
then run
```
hello_world.py
```
Or
Or
```
cd /usr/share/bcc/examples
./hello_world.py
./tracing/bitehist.py

cd /usr/share/bcc/tools
./bitesize
./bitesize

```

Expand Down
2 changes: 1 addition & 1 deletion docker/build/Dockerfile.ubuntu
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ do \
then \
apt-get install -y libpolly-${version}-dev; \
fi; \
done \
done \
&& \
apt-get -y clean'

Expand Down
2 changes: 1 addition & 1 deletion docs/reference_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2616,7 +2616,7 @@ cannot call GPL only function from proprietary program

eBPF program compilation needs kernel sources or kernel headers with headers
compiled. In case your kernel sources are at a non-standard location where BCC
cannot find then, its possible to provide BCC the absolute path of the location
cannot find then, it's possible to provide BCC the absolute path of the location
by setting `BCC_KERNEL_SOURCE` to it.

## 2. Kernel version overriding
Expand Down
14 changes: 7 additions & 7 deletions docs/tutorial_bcc_python_developer.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ if BPF.get_kprobe_functions(b'blk_start_request'):
b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_start")

if BPF.get_kprobe_functions(b'__blk_account_io_done'):
# __blk_account_io_done is available before kernel v6.4.
# __blk_account_io_done is available before kernel v6.4.
b.attach_kprobe(event="__blk_account_io_done", fn_name="trace_completion")
elif BPF.get_kprobe_functions(b'blk_account_io_done'):
# blk_account_io_done is traceable (not inline) before v5.16.
# blk_account_io_done is traceable (not inline) before v5.16.
b.attach_kprobe(event="blk_account_io_done", fn_name="trace_completion")
else:
b.attach_kprobe(event="blk_mq_end_request", fn_name="trace_completion")
Expand Down Expand Up @@ -531,7 +531,7 @@ print("%-14s %-12s %-6s %s" % ("TIME(s)", "COMMAND", "PID", "UID"))

def print_event(cpu, data, size):
event = b["events"].event(data)
printb(b"%-14.3f %-12s %-6d %d" % ((event.ts/1000000000),
printb(b"%-14.3f %-12s %-6d %d" % ((event.ts/1000000000),
event.comm, event.pid, event.uid))

# loop with callback to print_event
Expand All @@ -553,8 +553,8 @@ list``` for a list of tracepoints. Linux >= 4.7 is required to attach BPF
programs to tracepoints.
1. ```args->uid```: ```args``` is auto-populated to be a structure of the
tracepoint arguments. The comment above says where you can see that structure.
Eg:
Eg:

```
# sudo cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_setuid/format
name: sys_enter_setuid
Expand All @@ -564,10 +564,10 @@ Eg:
field:unsigned char common_flags; offset:2; size:1; signed:0;
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
field:int common_pid; offset:4; size:4; signed:1;

field:int __syscall_nr; offset:8; size:4; signed:1;
field:uid_t uid; offset:16; size:8; signed:0;

print fmt: "uid: 0x%08lx", ((unsigned long)(REC->uid))
```
In this case, there are only one member `uid` to be printed.
Expand Down
4 changes: 2 additions & 2 deletions examples/networking/http_filter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ eBPF application that parses HTTP packets and extracts (and prints on screen) th
## Usage Example


$ sudo python http-parse-complete.py
$ sudo python http-parse-complete.py
GET /pipermail/iovisor-dev/ HTTP/1.1
HTTP/1.1 200 OK
GET /favicon.ico HTTP/1.1
Expand Down Expand Up @@ -42,6 +42,6 @@ Two versions of this code are available in this repository:
## How to execute this sample

This sample can be executed by typing either one the two commands below:

$ sudo python http-parse-simple.py
$ sudo python http-parse-complete.py
26 changes: 13 additions & 13 deletions examples/networking/net_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#
# net_monitor.py Aggregates incoming network traffic
# outputs source ip, destination ip, the number of their network traffic, and current time
# how to use : net_monitor.py <net_interface>
#
# how to use : net_monitor.py <net_interface>
#
# Copyright (c) 2020 YoungEun Choe

from bcc import BPF
Expand Down Expand Up @@ -34,36 +34,36 @@ def help():
#define ETH_HLEN 14

BPF_PERF_OUTPUT(skb_events);
BPF_HASH(packet_cnt, u64, long, 256);
BPF_HASH(packet_cnt, u64, long, 256);

int packet_monitor(struct __sk_buff *skb) {
u8 *cursor = 0;
u32 saddr, daddr;
long* count = 0;
long one = 1;
u64 pass_value = 0;

struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
if (ip->ver != 4)
return 0;
if (ip->nextp != IP_TCP)
if (ip->nextp != IP_TCP)
{
if (ip -> nextp != IP_UDP)
if (ip -> nextp != IP_UDP)
{
if (ip -> nextp != IP_ICMP)
return 0;
if (ip -> nextp != IP_ICMP)
return 0;
}
}

saddr = ip -> src;
daddr = ip -> dst;

pass_value = saddr;
pass_value = pass_value << 32;
pass_value = pass_value + daddr;

count = packet_cnt.lookup(&pass_value);
count = packet_cnt.lookup(&pass_value);
if (count) // check if this map exists
*count += 1;
else // if the map for the key doesn't exist, create one
Expand Down Expand Up @@ -113,7 +113,7 @@ def decimal_to_human(input_value):
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
if output_len != 0:
print('\ncurrent packet nums:')

for i in range(0,output_len):
srcdst = packet_cnt_output[i][0].value
src = (srcdst >> 32) & 0xFFFFFFFF
Expand All @@ -124,8 +124,8 @@ def decimal_to_human(input_value):
decimal_to_human(str(dst)) + ' ' + str(pkt_num) + ' ' + 'time : ' + formatted_time
print(monitor_result)

packet_cnt.clear() # delete map entries after printing output. confirmed it deletes values and keys too
packet_cnt.clear() # delete map entries after printing output. confirmed it deletes values and keys too

except KeyboardInterrupt:
sys.stdout.close()
pass
Expand Down
14 changes: 7 additions & 7 deletions examples/networking/tcp_mon_block/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# eBPF tcp_mon_block

This eBPF program uses netlink TC, kernel tracepoints and kprobes to monitor outgoing connections from given PIDs (usually HTTP web servers) and block connections to all addresses initiated from them, unless they are listed in allow_list.json
This eBPF program uses netlink TC, kernel tracepoints and kprobes to monitor outgoing connections from given PIDs (usually HTTP web servers) and block connections to all addresses initiated from them, unless they are listed in allow_list.json

To run the example:

1. Run python3 web_server.py . Note the server's PID (will be printed to stdout)
2. Add the server's PID to allow_list.json . You can replace the first entry on the JSON file and put your PID instead
3. Run tcp_mon_block.py -i network_interface_name (-v for verbose output). For example: python3 tcp_mon_block.py -i eth0
4. Put your web_server's listening IP in 'server_address' variable in http_client.py and run python3 http_client.py
4. Put your web_server's listening IP in 'server_address' variable in http_client.py and run python3 http_client.py

**Explanation**:

web_server.py is a simple HTTP web server built with flask. It has a SSRF vulnerability in the route to /public_ip (you can read more about this vulnerability here https://portswigger.net/web-security/ssrf).

This route demonstrates a web server which connects to some remote API server (which is pretty common behavior) and receives some data. The attached POC simply connects to https://api.ipify.org and fetches the server's public IP, then sends it back to the client.
However, this specific route receives the API address to connect to from the user (http_client.py is used as the client in this POC, but in real life scenarios it will probably be a web browser).
This route demonstrates a web server which connects to some remote API server (which is pretty common behavior) and receives some data. The attached POC simply connects to https://api.ipify.org and fetches the server's public IP, then sends it back to the client.
However, this specific route receives the API address to connect to from the user (http_client.py is used as the client in this POC, but in real life scenarios it will probably be a web browser).

This creates a SSRF vulnerability as an attacker can put any address he/she wishes to force the web server to connect to it instead of the intended API address (https://api.ipify.org)

**Run the POC twice:**
**Run the POC twice:**

**First**, run only web_server.py and http_client.py . http_client.py will send 2 requests to the web server:

Expand All @@ -28,7 +28,7 @@ This creates a SSRF vulnerability as an attacker can put any address he/she wish

**Now run the POC again**

First run web_server.py but this time add the web server's PID to allow_list.json and then run tcp_mon_block.py as mentioned earlier.
First run web_server.py but this time add the web server's PID to allow_list.json and then run tcp_mon_block.py as mentioned earlier.

This will make sure the web server will only connect to the predefined allow_list of addresses (this can be either an IPv4, URL or domain name), essentially blocking any connection to any address not listed in the allow_list.

Expand All @@ -49,7 +49,7 @@ After web_server.py initiated a connection to a non-allowed address:



**Prerequisites**:
**Prerequisites**:

1. BCC and pyroute2 for tcp_mon_block
2. Python3 flask and requests in order to run the web_server.py and http_client.py POC
Expand Down
4 changes: 2 additions & 2 deletions examples/networking/tunnel_monitor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dependencies. You will need nodejs+npm installed on the system to run this, but
the setup script will only install packages in the local directory.

```
[user@localhost tunnel_monitor]$ ./setup.sh
[user@localhost tunnel_monitor]$ ./setup.sh
Cloning into 'chord-transitions'...
remote: Counting objects: 294, done.
...
Expand All @@ -40,7 +40,7 @@ fastclick#1.0.6 bower_components/fastclick
Then, start the simulation by running main.py:

```
[root@bcc-dev tunnel_monitor]# python main.py
[root@bcc-dev tunnel_monitor]# python main.py
Launching host 1 of 9
Launching host 2 of 9
...
Expand Down
12 changes: 6 additions & 6 deletions examples/networking/vlan_filter/data-plane-tracing.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#define IP_TCP 6
#define IP_UDP 17
#define IP_ICMP 1
/*
/*
In 802.3, both the source and destination addresses are 48 bits (4 bytes) MAC address.
6 bytes (src) + 6 bytes (dst) + 2 bytes (type) = 14 bytes
6 bytes (src) + 6 bytes (dst) + 2 bytes (type) = 14 bytes
*/
#define ETH_HLEN 14

Expand All @@ -18,18 +18,18 @@
return 0 -> DROP the packet
return -1 -> KEEP the packet and return it to user space (userspace can read it from the socket_fd )
*/
int vlan_filter(struct __sk_buff *skb) {
u8 *cursor = 0;
int vlan_filter(struct __sk_buff *skb) {
u8 *cursor = 0;

struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));

//filter IP packets (ethernet type = 0x0800) 0x0800 is IPv4 packet
switch(ethernet->type){
case 0x0800: goto IP;
default: goto DROP;
}


IP: ;
struct ip_t *ip = cursor_advance(cursor, sizeof(*ip)); // IP header (datagram)
switch (ip->nextp){
Expand Down
Loading
Loading