我是从头开始用C编写网络库 . 我已经实现了以太网协议,现在我想让ARP工作 . 发送请求/回复工作正常但接收效果不佳 . 当我发送一个请求并等待它之后的回复时,recvfrom()只接受第一个传入的ARP数据包 . 但是我想得到主持人回复我的请求的答复 .
我不能只是收到数据包,直到正确的到达,因为库应该支持套接字超时 . (使用setsockopt()设置)
套接字是这样创建的:
int sfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))
输出我的测试程序:
Sending ARP-Request ...
0o0o0o0 ARP-FRAME DUMP 0o0o0o0
HwType: 256 (0x7ab74e358670)
PrType: 8 (0x7ab74e358672)
HwALen: 6 (0x7ab74e358674)
PrALen: 4 (0x7ab74e358675)
ArpOP : 256 (0x7ab74e358676)
Sha : 84:4b:10:14:a0:04 (0x7ab74e358678)
Spa : 192.168.12.1 (0x7ab74e35867e)
Tha : 00:00:00:00:00:00 (0x7ab74e358682)
Tpa : 192.168.0.3 (0x7ab74e358688)
Receiving ARP-Reply ...
0o0o0o0 ARP-FRAME DUMP 0o0o0o0
HwType: 256 (0x7ab74e358670)
PrType: 8 (0x7ab74e358672)
HwALen: 6 (0x7ab74e358674)
PrALen: 4 (0x7ab74e358675)
ArpOP : 512 (0x7ab74e358676)
Sha : 10:00:00:00:00:01 (0x7ab74e358678)
Spa : 192.168.12.78 (0x7ab74e35867e)
Tha : 84:4b:10:14:a0:04 (0x7ab74e358682)
Tpa : 192.168.12.1 (0x7ab74e358688)
是否可以过滤传入的ARP数据包/如何进行?
提前致谢 .
---编辑---
我玩过BPF,它可以很好地过滤掉ARP数据包 . 它写了这个过滤器
ld [28]
jne #0x4e0ca8c0, drop
ret #-1
drop: ret #0
过滤传入的ARP回复 . 它应该从数据包加载源IP并将其与代码中定义的IP进行比较 . 0x4e0ca8c0是有效的IP地址 . 主人的回复我想要的 . tcpdump显示传入的回复,但我的程序冻结(永远等待) . 我像这样使用BPF:
struct sock_fprog prog;
struct sock_filter filter[4] =\
{{ 0x20, 0, 0, 0x0000001c },
{ 0x15, 0, 1, 0x4e0ca8c0 },
{ 0x06, 0, 0, 0xffffffff },
{ 0x06, 0, 0, 0000000000 }};
prog.len = 4;
prog.filter = filter;
if(setsockopt(sfd, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) ==\
-1) {
fprintf(stderr, "ERROR enabling bpf: setsockopt(): %s\n",\
strerror(errno));
goto ... (error handler);
}
/* Receive incoming ARP reply */
我希望我没有犯过任何愚蠢/明显的错误 .
提前致谢!
- 最后编辑 -
IP地址 . 必须在NBO . 所以使用正确的BPF:
struct sock_filter filter[4] =\
{{ 0x20, 0, 0, 0x0000001c },
{ 0x15, 0, 1, 0xc0a80c4e },
{ 0x06, 0, 0, 0xffffffff },
{ 0x06, 0, 0, 0000000000 }};
...仅接受/接收来自192.168.12.78(0xc0a80c4e)的回复 .
非常感谢Ctx!
1 回答
您可以使用(正确配置的) Berkeley Packet Filter (BPF) .
为此,您必须编写一个(小)BPF过滤器,它与您要查找的回复完全匹配 .
"language"非常基本,并描述here
然后将说明放在一起进入BPF程序:
最后,您可以将过滤器连接到套接字:
如果您正确配置了过滤器,那么从现在开始,您只会在套接字上收到匹配的arp回复 .
对于下一个请求/回复,您必须重新配置过滤器以匹配新参数(SO_DETACH_FILTER后跟SO_ATTACH_FILTER和新程序) .
对于ARP数据包,构建过滤器特别容易,因为数据包中字段的偏移是固定的 .