我想实现过滤tcp数据包中端口22上的所有数据我在代码中使用了tcpdump生成的bpf代码来应用它,但它不起作用
下面是我的测试代码
int main()
{
/* From the example above: tcpdump -d host 127.0.0.1 and port 22 -i lo */
struct sock_filter code[] = {
{0x28, 0, 0, 0x0000000c},
{0x15, 0, 16, 0x00000800},
{0x20, 0, 0, 0x0000001a},
{0x15, 2, 0, 0x7f000001},
{0x20, 0, 0, 0x0000001e},
{0x15, 0, 12, 0x7f000001},
{0x30, 0, 0, 0x00000017},
{0x15, 2, 0, 0x00000084},
{0x15, 1, 0, 0x00000006},
{0x15, 0, 8, 0x00000011},
{0x28, 0, 0, 0x00000014},
{0x45, 6, 0, 0x00001fff},
{0xb1, 0, 0, 0x0000000e},
{0x48, 0, 0, 0x0000000e},
{0x15, 2, 0, 0x00000016},
{0x48, 0, 0, 0x00000010},
{0x15, 0, 1, 0x00000016},
{0x6, 0, 0, 0x00040000},
{0x6, 0, 0, 0x00000000},
};
struct sock_fprog bpf = {
.len = ARRAY_SIZE(code),
.filter = code,
};
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
int enable_hdrincl = 1;
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &enable_hdrincl, sizeof(enable_hdrincl));
int ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
char buffer[4096];
while (1) {
memset(buffer, 0, sizeof(buffer));
ssize_t recv_len = recv(sock, buffer, sizeof(buffer), 0);
if (recv_len < 0) {
perror("recv failed");
close(sock);
exit(-1);
}
printf("xxx\r\n");
}
return 0;
}
当我在命令行上使用tcpdump时,它会正常过滤
lcx@lcx-virtual-machine:/mnt/hgfs/share/tcp_demo/test$ sudo tcpdump host 127.0.0.1 and port 22 -i lo
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:50:34.761640 IP lcx-virtual-machine.2222 > localhost.ssh: Flags [S], seq 1234, win 65535, length 0
1条答案
按热度按时间pw9qyyiw1#
示例
sock_filter code
中的分组偏移量指的是包括以太网报头的整个分组;由于测试程序中的套接字被设置为仅包括IP报头,所以偏移不匹配,并且过滤器失败。为了读取整个以太网数据包并能够使用给定的过滤器,可以使用然后你可以把
IP_HDRINCL
也放进去。如果出于某种奇怪的原因,您不想读取以太网报头,您必须调整BPF代码中的偏移量-括号中的数字以其人类可读的形式表示: