tcp - 如何在 kprobe 程序中使用 enum tcp mib 定义?
问题描述
在这里,我尝试编写一个程序(kprobe)来包含像@tcp_states 这样的枚举tcp mib 在BPF Performance Tools bpftrace 一书中。枚举 tcp mib 位于“/include/uapi/linux/snmp.h”中:
#!/usr/local/bin/bpftrace
#include <net/net_namespace.h>
#include <net/netns/mib.h>
#include <net/snmp.h>
#include <uapi/linux/snmp.h>
#define TCP_MIB_MAX __TCP_MIB_MAX
kprobe:sk_alloc
{
$net = (struct net *)arg0;
$mi = (struct netns_mib *)$net->mib;
$ib = (struct tcp_mib *)$mi;
@mib[1] = "TCP_MIB_NUM";
@mib[2] = "TCP_MIB_RTOALGORITHM";
@mib[3] = "TCP_MIB_RTOMIN";
@mib[4] = "TCP_MIB_RTOMAX;
@mib[5] = "TCP_MIB_MAXCONN";
@mib[6] = "TCP_MIB_ACTIVEOPENS";
@mib[7] = "TCP_MIB_PASSIVEOPENS";
@mib[8] = "TCP_MIB_ATTEMPTFAILS";
@mib[9] = "TCP_MIB_ESTABRESETS";
@mib[10] = "TCP_MIB_CURRESTAB";
@mib[11] = "TCP_MIB_INSEGS";
@mib[12] = "TCP_MIB_OUTSEGS";
@mib[13] = "TCP_MIB_RETRANSSEGS";
@mib[14] = "TCP_MIB_INERRS";
@mib[15] = "TCP_MIB_OUTRSTS";
@mib[16] = "TCP_MIB_CSUMERRORS";
printf("-------------------------------\n");
time();
printf("sk_alloc: %s pid: %d\n", comm, pid);
printf("\n");
printf("$ib: %u\n", $ib->miss[6]);
$mib_s = $ib->mibs[TCP_MIB_MAX];
$mib_str = @mib[$mib_s];
printf("TCP mib is: %s\n", $mib_str);
clear(@mib);
}
当我尝试运行它时,输出是:
the index 94779518808448 is out of bounds for array of size 16
然后我尝试代替 TCP_MIB_MAX 来放置特定的数组位置,例如 5,(我修改了上面的代码):
$mib_s = $ib->mibs[5];
当我尝试运行它时,输出是:
...
-----------------------------
21:40:15
sk_alloc: systemd-logind pid: 920
$ib: 1516359680
TCP mib is:
-----------------------------
21:40:15
sk_alloc: systemd-logind pid: 920
$ib: 1516359680
TCP mib is:
...
为什么不显示 TCP mib?并且在输出中什么也不显示?如何正确使用数组来显示@mib?
解决方案
TCP_MIB_MAX
并且__TCP_MIB_MAX
等于16,等于struct tcp_mib
内核中的大小:
enum
{
TCP_MIB_NUM = 0,
TCP_MIB_RTOALGORITHM, /* RtoAlgorithm */
TCP_MIB_RTOMIN, /* RtoMin */
TCP_MIB_RTOMAX, /* RtoMax */
TCP_MIB_MAXCONN, /* MaxConn */
TCP_MIB_ACTIVEOPENS, /* ActiveOpens */
TCP_MIB_PASSIVEOPENS, /* PassiveOpens */
TCP_MIB_ATTEMPTFAILS, /* AttemptFails */
TCP_MIB_ESTABRESETS, /* EstabResets */
TCP_MIB_CURRESTAB, /* CurrEstab */
TCP_MIB_INSEGS, /* InSegs */
TCP_MIB_OUTSEGS, /* OutSegs */
TCP_MIB_RETRANSSEGS, /* RetransSegs */
TCP_MIB_INERRS, /* InErrs */
TCP_MIB_OUTRSTS, /* OutRsts */
TCP_MIB_CSUMERRORS, /* InCsumErrors */ // == 15
__TCP_MIB_MAX // == 16
};
和
#define TCP_MIB_MAX __TCP_MIB_MAX
struct tcp_mib {
unsigned long mibs[TCP_MIB_MAX];
};
(包括/uapi/linux/snmp.h 和包括/net/snmp.h)
但是因为数组是从 0 开始索引的,所以你只能到TCP_MIB_MAX - 1
when indexing $ib->mibs
。这就是您收到有关超出范围索引的投诉的原因。
然后当您选择较小的索引时,您可以按预期访问数组项。但我不确定你要做什么:
$mib_s = $ib->mibs[5];
$mib_str = @mib[$mib_s];
在我看来,您似乎正在从 MIB ( $ib->mibs[TCP_MIB_ACTIVEOPENS]
) 中读取值,它可能提供任何值,可能很大,并且可能为 null(我怀疑这里就是这种情况)。然后您将该值用作...中的索引@mib
?因此,如果计数器为 10k,您是否尝试获取 16 大小数组的第 10,000 个单元格?我想在您的情况下,该值为 0,因此您正在执行$mib_str = @mib[0]
,这可能是一个空字符串,因为您从未为@mib[0]
.
为了解决所有这些问题,我将从对数组使用正确的索引(从 0 到 15)开始@mib
,以避免任何混淆。然后您可能需要重新考虑您要打印的确切内容,但我不确定上面的两行是否是您想要的。
推荐阅读
- c# - 将字符串转换为八进制
- drake - 在模拟过程中创建焊缝
- python - 在 AWS Cloudformation 上调用 ListStacks 时出现 ValidationError
- git - 使用 Ansible 创建 CD
- .net - 在 Wix 安装程序中使用 FileInUse 元素
- php - 未定义的属性:stdClass::$notifications
- laravel - Laravel 存储,我应该在数据库中组织我的文件吗?
- c++ - 继承 - 如何在 C++ 的继承类中只调用一个构造函数?
- sql - 如何在 PostgreSQL 中为我的两个类别中的每一个选择前 10 名?
- bash - 如何自动检查文件是否已更改?