比较bpftrace中的ip地址?



我正在编写一些bpftrace代码,其中我想将IP地址(存储为32位整数)与地址的字符串表示进行比较。也就是说,我想做这样的事情:

kprobe:netif_receive_skb {
$skb = (struct sk_buff *)arg0;
$dev = $skb->dev;
$name = $dev->name;
$ipheader = ((struct iphdr *) ($skb->head + $skb->network_header));
// This pseudocode conditional is what I am trying to figure out
if ($ipheader->daddr == "8.8.8.8") {
printf("%s %s %s -> %sn",
func, $name, ntop($ipheader->saddr), ntop($ipheader->daddr))
}
}

在上面,$ipheader是一个struct iphdr *,struct iphdr看起来像这样:

struct iphdr {
...
__struct_group(/* no tag */, addrs, /* no attrs */,
__be32  saddr;
__be32  daddr;
);
};

所以saddrdaddr都是32位无符号整数。

我想也许我可以使用pton()函数,像这样:

if ($ipheader->daddr == pton("8.8.8.8")) {

但不幸的是,pton()返回int8[4]数组,而不是单个32位整数,所以这失败了:

traceit.bpf:8:5-41: ERROR: Type mismatch for '==': comparing 'unsigned int32' with 'unsigned int8[4]'
if ($ipheader->daddr == pton("8.8.8.8")) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我接下来试着看看我是否可以将两个值归一化为int8[4]数组,像这样:

$target = pton("8.8.8.8");
$daddr = pton(ntop($ipheader->daddr));
if ($target == $daddr) {

但是这个失败了,因为ntop()实际上没有返回字符串,所以我们得到:

ERROR: Expected string literal, got inet
traceit.bpf:9:10-38: ERROR: pton() expects an string argument of an IPv4/IPv6 address, got
$daddr = pton(ntop($ipheader->daddr));

我意识到我可以把目标指定为一个整数:

if ($ipheader->daddr == 0x08080808) {

但是,虽然对于像8.8.8.8这样的人为地址来说,这很容易解释,但是当地址的十六进制形式是像0xacd9004e这样的时候,它就不透明了。

是否可以使用bpftrace比较32位整数表示的地址与字符串表示的地址(如果可以,规范的方法是什么)?

如果$ipheader->daddr为192.168.2.44,只需将这四个数字转换为十六进制字符,即c0 a8 02 2c。反转字符是2c 02 a8 c0。所以你可以写:

if ($ipheader->daddr == 0x2c02a8c0) {
...
}

相关内容

  • 没有找到相关文章

最新更新