使用C套接字编程进行arp请求和回复

使用C套接字编程进行arp请求和回复,第1张

使用C套接字编程进行arp请求和回复

有几件事情可以使您的数据包通过有线/空中传输。

  • 适用于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一样直接发送出去。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5018984.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-15
下一篇2022-11-15

发表评论

登录后才能评论

评论列表(0条)

    保存