
有几件事情可以使您的数据包通过有线/空中传输。
- 适用于arp回复的.sll_protocol是ETH_P_ARP,来自
<linux/if_ether.h>
设置ah-> arp_op时,字节序错误。它是2个字节的网络字节序字段,因此请使用htons()。
通常,该代码对网络和主机字节顺序有些困惑。当前,它发出的答复非常混乱,但是我不清楚这是代码的恶意意图还是事故。如果要发送真实,正确的IP地址,请在构建回复时使用htonl和htons。
要修复字节顺序:
- 正确包含
<arpa/inet.h>
- 始终使用htons(),htonl()ntohs()和ntohl()。它们的实现使其成为NOP(如果您的平台上不需要)。
- 设置要从主机发送的数据时,请始终使用hton *()处理它
- 解释来自网络的数据时,在与局部变量进行比较之前,请始终先进行ntoh *()。
总而言之,我所做的更改是1).sll_protocol = htons(ETH_P_ARP)。(在发送数据时)2)ah-> arp_op =
htons(ARPOP_REPLY)(在回复arp中)3)删除了ah-> arp_hd和ah->
arp_pr上的毫无意义的ntohs()。填充发送缓冲区时,您不希望将数据转换为主机字节序(除非您实际上确实如此)4)在某些比较中添加了ntohs()转换并进行了适当的定义5)其他一些小的修正6)禁用了位处理系统(“
sudo …”)!
在pastebin的完整代码。这是一个差异:
thuovila@glx:~/src/so/arp$ diff arp2.c arp_orig.c 13d12< #include <arpa/inet.h>20c19< #define DEVICE "eth1"---> #define DEVICE "eth0"25c24< int s = -1; ---> int s = 0; 92c91< socket_address.sll_protocol = htons(ETH_P_ARP);---> socket_address.sll_protocol = htons(ETH_P_IP);95c94< socket_address.sll_pkttype = 0; //PACKET_OTHERHOST;---> socket_address.sll_pkttype = PACKET_OTHERHOST;112c111< if(ntohs(eh->h_proto) == ETH_P_ARP)---> if(htons(eh->h_proto) == 0x806)119c118< if(ntohs(ah->arp_op) != ARPOP_REQUEST)---> if(htons(ah->arp_op) != 0x0001)139d137< #if 0145d142< #endif182c179< eh->h_proto = htons(ETH_P_ARP);---> eh->h_proto = ETH_ARP;200,201c197,198< //ah->arp_hd = ntohs(ah->arp_hd);< //ah->arp_pr = ntohs(ah->arp_pr);---> ah->arp_hd = ntohs(ah->arp_hd);> ah->arp_pr = ntohs(ah->arp_pr);203c200< ah->arp_op = htons(ARPOP_REPLY);---> ah->arp_op = 0x0002;
编辑 一些wireshark建议。捕获 以太原型0x0806 (或简称 arp )。使用捕获任何数据包的伪设备。您的数据包应该变得可见。
在Linux上,如果要停止网络堆栈的干扰,请使用:echo“ 8”> / proc / sys / net / ipv4 / conf / all /
arp_ignore
编辑#2
我不确定ETH_P_ARP。就我而言,这可能是个快速的判断。在ARP标头字段中使用ETH_P_IP是正确的,但是我不确定用于数据包套接字sll_protocol的哪个。另请注意,
socket_address.sll_pkttype= PACKET_OTHERHOST;发送时无效(请参见man 7数据包)。同样是强制性的SO观察,即应始终 至少 使用-
Wall(使用gcc或clang时)作为编译标志。
编辑#3 我改变了一点程序。并相应地更新了答案和差异。确实确实令人惊讶的是,.sll_protocol必须是ETH_P_ARP。我的 man
7数据包 副本甚至没有说它用于任何用途,但是如果没有它,该数据包就不会像ARP一样直接发送出去。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)