我正在使用 RAW 套接字发送 ARP 数据包。这是代码:
#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <arpa/inet.h>
#include <stdio.h>
using namespace std;
uint16_t hard_type = 1;
uint16_t proto_type = 0x0800;
uint16_t op_code = 1;
struct sockaddr_in socket_address;
struct arp_header{
uint16_t hardware_type = htons(hard_type);
uint16_t protocol_type = htons(proto_type);
uint8_t hardware_length = 6;
uint8_t protocol_length = 4;
uint16_t opcode = htons(op_code);
uint8_t sender_hardware_address[6] = {0x00,0x45,0xe2,0x7a,0x01,0x53};
uint32_t sender_protocol_address;
uint8_t target_hadrware_address[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
uint32_t target_protocol_address;
}arp_req;
void ipv4_address_assign(){
const char *source_ipv4 = "192.168.1.7";
const char *dest_ipv4 = "192.168.1.1";
uint32_t src_ip_ver_4;
uint32_t dst_ip_ver_4;
inet_pton(AF_INET,source_ipv4,&src_ip_ver_4);
inet_pton(AF_INET,dest_ipv4,&dst_ip_ver_4);
arp_req.sender_protocol_address = htonl(src_ip_ver_4);
arp_req.target_protocol_address = htonl(dst_ip_ver_4);
}
int main() {
int sockfd = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if (sockfd == -1) {
cout << "Cannot open socket"<< endl;
return 0;
}
ipv4_address_assign();
sendto(sockfd,&arp_req,sizeof arp_req,0,(struct sockaddr*)&socket_address,sizeof socket_address);
char buffer[sizeof arp_req];
socklen_t len = sizeof arp_req;
cout<<"Waiting For Arp Packet"<<endl;
recvfrom(sockfd,buffer,sizeof arp_req,0,(struct sockaddr*)&socket_address,&len);
cout<<"Arp Packet Have Been Receive"<<endl;
return 0;
}
我使用Wireshark查看数据包发送情况是否良好,结果没有问题,而且我还在Wireshark中看到了ARP响应,这是我想要的。
但问题是如何在监视器中以十六进制形式显示标头,甚至提取一些信息并将其存储在某个变量中,而且我还应该需要将其从网络字节顺序转换为主机字节顺序,但如何做到这一点?
这是输出缓冲区值的方法:
#include <array>
#include <iostream>
#include <format>
int main()
{
std::array<std::uint8_t,8> values{0,1,2,3,11,12,13,15};
for(const auto byte : values ) std::cout << std::format("{:02X} ",byte);
}
输出将是:
00 01 02 03 0B 0C 0D 0F