網站首頁 編程語言 正文
文章目錄
- 1. 使用BPF/BCC
- 1.1在centos8操作系統上安裝對應的軟件二進制包
- 1.2 源碼包安裝
- 1.3 程序示例
- 2. Systemtap
- 2.1安裝 systemtap
- 2.2 Stap-prep
- 2.3 程序示例
- 3. bpftrace
- 3.1 安裝軟件
- 3.2 程序示例
- 4 總結
- 參考文獻:
本篇文章通過一個案例,對systemtap、BPF/BCC、bpftrace三種不同類型的內核探測工具進行剖析和對比。這個程序就是簡單對icmp_rcv函數,收到icmp報文,打印出對應的源IP地址和目的IP地址。
1. 使用BPF/BCC
1.1在centos8操作系統上安裝對應的軟件二進制包
1) 安裝kernel-devel包;
2) 安裝dnf -y install bcc-tools
1.2 源碼包安裝
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 clang clang-devel llvm llvm-devel llvm-static ncurses-devel
dnf -y install netperf
pip3 install pyroute2
ln -s /usr/bin/python3 /usr/bin/python
dnf -y install openssl
git clone https://github.com/iovisor/bcc.git
mkdir bcc_build
cmake …/bcc -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LLVM_SHARED=1
cd …/&& make -j10
make install
1.3 程序示例
使用bpf/bcc需要的內核版本最少是4.10以上。
使用下面的bcc代碼,
#!/usr/bin/env python3.6
from __future__ import print_function
from bcc import BPF
from bcc.utils import printb
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>
#include <uapi/linux/icmp.h>
#include <linux/icmp.h>
#include <uapi/linux/ip.h>
#include <linux/ip.h>
static inline struct iphdr *skb_to_iphdr(const struct sk_buff *skb)
{
// unstable API. verify logic in ip_hdr() -> skb_network_header().
return (struct iphdr *)(skb->head + skb->network_header);
}
int icmp_rcv_cb(struct pt_regs *ctx, struct sk_buff *skb)
{
struct icmphdr *icmph ;
struct iphdr *iph = skb_to_iphdr(skb);
bpf_trace_printk("ipsrc:%pI4 ipdst:%pI4 \\n",&iph->saddr, &iph->daddr);
icmph = (struct icmphdr *)skb->data;
bpf_trace_printk("devname:%s ----- icmp_type:%d \\n",skb->dev->name, icmph->type);
return 0;
};
"""
# initialize BPF
b = BPF(text=bpf_text)
b.attach_kprobe(event="icmp_rcv", fn_name="icmp_rcv_cb")
#end format output
while 1:
# Read messages from kernel pipe
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
print("task:%s pid: %d %s " % (task, pid, msg))
#b.trace_print()
2. Systemtap
2.1安裝 systemtap
在centos8 上直接使用yum安裝 yum install systemtap systemtap-runtime
2.2 Stap-prep
通過在http://debuginfo.centos.org/8/x86_64/Packages/下載安裝完debuginfo包后,執行stap-prep命令
簡單測試可以運行成功
2.3 程序示例
下面是systemtap的方式對icmp_rcv函數的探測,對本機收到的ICMP報文打印出,對應的源IP和目的IP地址。
stap -g icmp_systemtap.stp
#!/usr/bin/stap -g
%{
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <net/ip.h>
#include <linux/module.h>
#include <uapi/linux/if_packet.h>
#include <linux/fdtable.h>
#include <net/icmp.h>
static inline void ip2str(char *to,unsigned int from)
{
int size = snprintf(to,16,"%pI4",&from);
to[size] = '\0';
}
%}
function get_icmp_packet_info:string(skb:long)
%{
int ret = -1;
struct sk_buff *skb = (struct sk_buff *)STAP_ARG_skb;
struct iphdr *ip_header;
unsigned int src_ip_1 = 0;
unsigned int dst_ip_1 = 0;
char src_ip[16],dst_ip[16];
struct icmphdr *icmph;
if(!skb)
{
goto EXIT_F;
}
ip_header = (struct iphdr *)skb_network_header(skb);
if(!ip_header)
{
goto EXIT_F;
}
src_ip_1 = (unsigned int)ip_header->saddr;
dst_ip_1 = (unsigned int)ip_header->daddr;
ip2str(src_ip,src_ip_1);
ip2str(dst_ip,dst_ip_1);
icmph = icmp_hdr(skb);
if(icmph->type == 0)
{
goto ECHO_ICMP;
}
if(icmph->type == 8)
{
goto REPLY_ICMP;
}
EXIT_F:
snprintf(STAP_RETVALUE,MAXSTRINGLEN,"ERROR:src_ip:%s dst_ip:%s",src_ip,dst_ip);
ECHO_ICMP:
snprintf(STAP_RETVALUE,MAXSTRINGLEN,"ECHO_ICMP:src_ip:%s dst_ip:%s",src_ip,dst_ip);
REPLY_ICMP:
snprintf(STAP_RETVALUE,MAXSTRINGLEN,"REPLY_ICMP:src_ip:%s dst_ip:%s",src_ip,dst_ip);
%}
global locations
probe begin { printf("Monitoring for recv icmp packets\n") }
probe end { printf("Stropping monitoring packets\n") }
probe kernel.function("icmp_rcv").return
{
printf("%s\n",get_icmp_packet_info($skb))
iphdr = __get_skb_iphdr($skb)
saddr = format_ipaddr(__ip_skb_saddr(iphdr), @const("AF_INET"))
daddr = format_ipaddr(__ip_skb_daddr(iphdr), @const("AF_INET"))
printf("src_ip:%s dst_ip:=%s\n",saddr,daddr);
}
probe timer.sec(5)
{
exit ()
}
下面是運行后的測試結果:
3. bpftrace
3.1 安裝軟件
yum -y install bpftrace
3.2 程序示例
bpftrace是使用自定義單行代碼和簡短腳本的臨時工具的不錯的選擇,而BCC是復雜工具和守護程序的理想選擇、bpftrace和BCC都是BPF的前端工具。
在這里插入代碼片#!/usr/bin/bpftrace
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/socket.h>
BEGIN
{
printf("Tracing icmp rev.Hit Ctrl-C end.\n");
}
kprobe:icmp_rcv
{
$skb = (struct sk_buff *)arg0;
$iph = (struct iphdr*)($skb->head + $skb->network_header);
$src_ip = ntop(AF_INET,$iph->saddr);
$dst_ip = ntop(AF_INET,$iph->daddr);
printf("src_ip:%s ----> dst_ip:%s\n",$src_ip,$dst_ip);
}
END
{
printf("OVER bye!!")
}
運行結果如下:
4 總結
- 使用systemtap工具跟蹤內核需要安裝和內核對應版本的debuginfo包,systemtap作為老牌的內核跟蹤工具,可以支持比較老的內核版本,對于現有存量的內核定位跟蹤有明顯的優勢。
- BPF/BCC作為新的內核跟蹤工具,需要較新的內核版本,最少是4.10版本,最好是4.19版本的內核。
- 通過運行對比發現,編譯和運行BPF/BCC的代碼比systemtap的代碼要快的多。
- BPF有各類安全檢查,避免在內核跟蹤過程中產生panic,systemtap沒有此類的安全檢查,需要開發者在開發systemtap程序時,保證代碼的安全性。
- Bpftrace作為內核跟蹤的一種工具,特別適合簡單的內核跟蹤,適合一條命令搞定的內核跟蹤,bpftrace也有自己的一套語法體系可用。
各種不同類型的內核探測跟蹤技術,適合不同類型的場景,在實際使用中可選擇適合自己的方式。
參考文獻:
https://lwn.net/Articles/852112/
原文鏈接:https://blog.csdn.net/frankzfz/article/details/127248030
- 上一篇:Tomcat 9.x啟動時控制臺亂碼
- 下一篇:CFS調度算法調度時機的理解
相關推薦
- 2022-11-25 Django使用裝飾器限制對視圖的訪問及實現原理_python
- 2022-09-09 python中對開區間和閉區間的理解_python
- 2022-06-08 Jenkins集成Gitlab實現自動化部署的全過程記錄_相關技巧
- 2022-11-29 Rust?模式匹配示例詳解_Rust語言
- 2022-09-07 python?正則表達式如何實現重疊匹配_python
- 2023-03-11 Golang跳轉語句continue與goto使用語法詳解_Golang
- 2022-07-16 SpringMVC基礎工作原理以及實例
- 2022-10-16 Pytorch?linear?多維輸入的參數問題_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支