C++ 中的冒号函数和 $ 变量?
Colon functions and $ variables in c++?
我对 c++ 还是有点陌生,我无法理解这段代码的作用:
#include <net/sock.h>
BEGIN
{
printf("%-8s %-6s %-16s %-2s %-16s %-5s\n", "TIME", "PID", "COMM",
"IP", "RADDR", "RPORT");
}
kprobe:ip4_datagram_connect,
kprobe:ip6_datagram_connect
{
$sk = (struct sock *)arg0;
$sa = (struct sockaddr *)arg1;
if (($sa->sa_family == AF_INET || $sa->sa_family == AF_INET6) &&
$sk->sk_protocol == IPPROTO_UDP) {
time("%H:%M:%S ");
if ($sa->sa_family == AF_INET) {
$s = (struct sockaddr_in *)arg1;
$port = ($s->sin_port >> 8) |
(($s->sin_port << 8) & 0xff00);
printf("%-6d %-16s 4 %-16s %-5d\n", pid, comm,
ntop(AF_INET, $s->sin_addr.s_addr), $port);
} else {
$s6 = (struct sockaddr_in6 *)arg1;
$port = ($s6->sin6_port >> 8) |
(($s6->sin6_port << 8) & 0xff00);
printf("%-6d %-16s 6 %-16s %-5d\n", pid, comm,
ntop(AF_INET6, $s6->sin6_addr.in6_u.u6_addr8),
$port);
}
}
}
我认为它的“BEGIN”部分定义了一个宏,但我不完全确定。我真正感到困惑的是
kprobe:ip4_datagram_connect,
kprobe:ip6_datagram_connect
{
这是在做什么?这看起来像是一个函数声明,但在这种情况下单冒号是什么意思?这是某种初始化列表但用于函数吗?这是将 ip4 和 ip6 都设置为该功能吗?
另外,美元符号变量名有什么意义吗?或者它们只是声明变量的有效方式?
这是密件抄送工具中 udpconnect.bt 的代码。我尝试将其转换为 python.
如评论中所述,这是bpftrace的脚本。您可能想查看此工具的 the reference guide。
BEGIN
块在程序的开头 运行(就像 awk
脚本一样,如果您熟悉的话)。在这种情况下,它用于将数组的 header 行打印到控制台输出。
然后区块:
kprobe:ip4_datagram_connect,
kprobe:ip6_datagram_connect
{
... 定义将被翻译成 eBPF program 的指令(中间步骤作为 LLVM 中间表示),并附加到 Linux 内核中的一个或多个挂钩。在当前情况下,kprobe:...
定义了钩子:程序将 运行 作为函数 ip4_datagram_connect
及其在内核中对应的 IPv6 的 kprobe 函数。换句话说,每次内核进入这些函数时它都会运行。
快速浏览一下,我认为该程序应该在每次 UDP 流启动时打印时间、打开套接字的进程的 PID 和名称、IP 地址、远程地址和远程端口。第一个if
检查数据包是(IPv4 or IPv6) and UDP
,下面的if/else
将这两种情况拆分IPv4/IPv6。
我对 c++ 还是有点陌生,我无法理解这段代码的作用:
#include <net/sock.h>
BEGIN
{
printf("%-8s %-6s %-16s %-2s %-16s %-5s\n", "TIME", "PID", "COMM",
"IP", "RADDR", "RPORT");
}
kprobe:ip4_datagram_connect,
kprobe:ip6_datagram_connect
{
$sk = (struct sock *)arg0;
$sa = (struct sockaddr *)arg1;
if (($sa->sa_family == AF_INET || $sa->sa_family == AF_INET6) &&
$sk->sk_protocol == IPPROTO_UDP) {
time("%H:%M:%S ");
if ($sa->sa_family == AF_INET) {
$s = (struct sockaddr_in *)arg1;
$port = ($s->sin_port >> 8) |
(($s->sin_port << 8) & 0xff00);
printf("%-6d %-16s 4 %-16s %-5d\n", pid, comm,
ntop(AF_INET, $s->sin_addr.s_addr), $port);
} else {
$s6 = (struct sockaddr_in6 *)arg1;
$port = ($s6->sin6_port >> 8) |
(($s6->sin6_port << 8) & 0xff00);
printf("%-6d %-16s 6 %-16s %-5d\n", pid, comm,
ntop(AF_INET6, $s6->sin6_addr.in6_u.u6_addr8),
$port);
}
}
}
我认为它的“BEGIN”部分定义了一个宏,但我不完全确定。我真正感到困惑的是
kprobe:ip4_datagram_connect,
kprobe:ip6_datagram_connect
{
这是在做什么?这看起来像是一个函数声明,但在这种情况下单冒号是什么意思?这是某种初始化列表但用于函数吗?这是将 ip4 和 ip6 都设置为该功能吗?
另外,美元符号变量名有什么意义吗?或者它们只是声明变量的有效方式?
这是密件抄送工具中 udpconnect.bt 的代码。我尝试将其转换为 python.
如评论中所述,这是bpftrace的脚本。您可能想查看此工具的 the reference guide。
BEGIN
块在程序的开头 运行(就像 awk
脚本一样,如果您熟悉的话)。在这种情况下,它用于将数组的 header 行打印到控制台输出。
然后区块:
kprobe:ip4_datagram_connect,
kprobe:ip6_datagram_connect
{
... 定义将被翻译成 eBPF program 的指令(中间步骤作为 LLVM 中间表示),并附加到 Linux 内核中的一个或多个挂钩。在当前情况下,kprobe:...
定义了钩子:程序将 运行 作为函数 ip4_datagram_connect
及其在内核中对应的 IPv6 的 kprobe 函数。换句话说,每次内核进入这些函数时它都会运行。
快速浏览一下,我认为该程序应该在每次 UDP 流启动时打印时间、打开套接字的进程的 PID 和名称、IP 地址、远程地址和远程端口。第一个if
检查数据包是(IPv4 or IPv6) and UDP
,下面的if/else
将这两种情况拆分IPv4/IPv6。