Я подключил tcp_cleanup_rbuf() и пытаюсь получить информацию об IP и порте из очереди skb. Но вроде пусто. Это верно? Был ли он уже свободен в этот момент?
Вот сценарий оболочки, который я тестирую. Исправьте путь к вашему собственному исходному каталогу ядра, запустите его, а также запустите ncat --keep-open --listen 0.0.0.0 5555
и ncat <IP-адрес сервера> 5555
.
очистить && bpftrace -e '
#include "/usr/src/kernels/3.10.0-957.el7.x86_64/include/net/sock.h"
#include "/usr/src/kernels/3.10.0-957.el7.x86_64/include/net/tcp.h"
#include "/usr/src/kernels/3.10.0-957.el7.x86_64/include/net/ip.h"
#include "/usr/src/kernels/3.10.0-957.el7.x86_64/include/linux/skbuff.h"
// static void tcp_cleanup_rbuf (структура sock *sk, int скопирована)
// https://elixir.bootlin.com/linux/v4.9/source/net/ipv4/tcp.c#L1416
//
kprobe:tcp_cleanup_rbuf/comm == "ncat"/
{
$sock = (структура носка *) arg0;
$skb = (struct sk_buff *) $sock->sk_receive_queue.next;
$queue = (struct sk_buff_head *)$sock->sk_receive_queue;
printf("%p\t", $queue);
printf("%p \n", (struct sk_buff *) $sock->sk_receive_queue);
printf("%p\n", $queue->next);
printf("%p\n", $queue->prev);
printf("%u %u\n", $queue->qlen, arg1);
если(1)
{
$iph = (struct iphdr *)($skb->head + $skb->network_header); // https://elixir.bootlin.com/linux/v4.9/source/include/uapi/linux/ip.h#L85
$th = (struct tcphdr *)($skb->head + $skb->transport_header); // https://elixir.bootlin.com/linux/v4.9/source/include/uapi/linux/tcp.h#L24
$протокол = $iph->протокол; // 6 — TCP 17 — UDP https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
$ipv = $iph->версия; // 4 - IPv4 6 - IPv6
$size = (($iph->tot_len >> 8) | (($iph->tot_len & 0xff) << 8)) - ($th->doff * 4) - ($iph->ihl * 4) ;
printf("%s\t%u\t",
связь,
pid
);
printf("%s:%u\t>\t%s:%u\t%u\n",
ntop($iph->saddr),
(uint16)($th->source << 8) | ($th->источник >> 8),
ntop($iph->daddr),
(uint16)($th->dest << 8) | ($th->назначение >> 8),
$ размер
);
}
}'
Если кто-нибудь знает, сделал ли я что-то не так или лучше зацепил функцию, я был бы очень признателен.