#pragma pack(push) //保存对齐状态
#pragma pack(1)//设定为1字节对齐
// 定义ARP帧
struct APRRequest
{
char chTargetMAC[6]; // 以太网MAC地址(ff ff ff ff ff ff作为广播地址)
char chSourceMAC[6]; // 源主机MAC地址
char chFrameType[2]; // 帧类型(0x0806是ARP帧的类型值)
char chHardwareType[2]; // 硬件类型(0x0001表示以太网)
char chProtocolType[2]; // 协议类型(0x0800表示IP协议)
char chHardwareAddrLen; // 硬件地址(MAC地址)长度为6
char chProtocolAddrLen; // 协议地址(IP地址)长度为4
char chOp[2]; // op为0x0001表示请求目的主机的MAC地址
char chSourceMACAddr[6]; // 源主机MAC地址
char chSourceIPAddr[4]; // 源主机IP地址
char chTargetMACAddr[6]; // 目的主机MAC地址全0待填写
char chTargetIPAddr[4]; // 目的主机IP地址
char chFill[18]; // 由于以太网规定最小数据长度为46字节,
// ARP帧长度只有28字节,因此有18字节填充位,
// 填充位的内容没有定义,与具体实现相关。
} stARP;
#pragma pack(pop)//恢复对齐状态
// 初始化ARP帧
memset(stARP.chTargetMAC, 0xff, sizeof(stARP.chTargetMAC)); // 以太网MAC地址(ff ff ff ff ff ff作为广播地址)
memcpy(stARP.chSourceMAC, chSourceMac, sizeof(stARP.chSourceMAC)); // 源主机MAC地址
memset(stARP.chFrameType, 0x08, 1);
memset(stARP.chFrameType + 1, 0x06, 1); // 帧类型(0x0806是ARP帧的类型值)
memset(stARP.chHardwareType, 0x00, 1);
memset(stARP.chHardwareType + 1, 0x01, 1); // 硬件类型(0x0001表示以太网)
memset(stARP.chProtocolType, 0x08, 1);
memset(stARP.chProtocolType + 1, 0x00, 1); // 协议类型(0x0800表示IP协议)
stARP.chHardwareAddrLen = 6; // 硬件地址(MAC地址)长度为6
stARP.chProtocolAddrLen = 4; // 协议地址(IP地址)长度为4
memset(stARP.chOp, 0x00, 1);
memset(stARP.chOp + 1, 0x01, 1); // op为0x0001表示请求目的主机的MAC地址
memcpy(stARP.chSourceMACAddr, chSourceMac, sizeof(stARP.chSourceMACAddr)); // 源主机MAC地址
// IPIntToChars(nSourceIP, stARP.chSourceIPAddr); // 源主机IP地址
*(UINT*)stARP.chSourceIPAddr = htonl(nSourceIP);
memset(stARP.chTargetMACAddr, 0, sizeof(stARP.chTargetMACAddr)); // 目的主机MAC地址全0待填写
// IPIntToChars(nTargetIP, stARP.chTargetIPAddr); // 目的主机IP地址
*(UINT*)stARP.chTargetIPAddr = htonl(nTargetIP);
// sendto发送RAW原始包
// socket目标信息
sockaddr_in stSock;
stSock.sin_family = AF_INET;
stSock.sin_port = htons(PORT);
stSock.sin_addr.S_un.S_addr = htonl(nTargetIP);
// 发送数据包
sendto(m_nSock, (const char*)&stARP, sizeof(stARP), 0,
(const sockaddr*)&stSock, sizeof(sockaddr_in));
#pragma pack(1)//设定为1字节对齐
// 定义ARP帧
struct APRRequest
{
char chTargetMAC[6]; // 以太网MAC地址(ff ff ff ff ff ff作为广播地址)
char chSourceMAC[6]; // 源主机MAC地址
char chFrameType[2]; // 帧类型(0x0806是ARP帧的类型值)
char chHardwareType[2]; // 硬件类型(0x0001表示以太网)
char chProtocolType[2]; // 协议类型(0x0800表示IP协议)
char chHardwareAddrLen; // 硬件地址(MAC地址)长度为6
char chProtocolAddrLen; // 协议地址(IP地址)长度为4
char chOp[2]; // op为0x0001表示请求目的主机的MAC地址
char chSourceMACAddr[6]; // 源主机MAC地址
char chSourceIPAddr[4]; // 源主机IP地址
char chTargetMACAddr[6]; // 目的主机MAC地址全0待填写
char chTargetIPAddr[4]; // 目的主机IP地址
char chFill[18]; // 由于以太网规定最小数据长度为46字节,
// ARP帧长度只有28字节,因此有18字节填充位,
// 填充位的内容没有定义,与具体实现相关。
} stARP;
#pragma pack(pop)//恢复对齐状态
// 初始化ARP帧
memset(stARP.chTargetMAC, 0xff, sizeof(stARP.chTargetMAC)); // 以太网MAC地址(ff ff ff ff ff ff作为广播地址)
memcpy(stARP.chSourceMAC, chSourceMac, sizeof(stARP.chSourceMAC)); // 源主机MAC地址
memset(stARP.chFrameType, 0x08, 1);
memset(stARP.chFrameType + 1, 0x06, 1); // 帧类型(0x0806是ARP帧的类型值)
memset(stARP.chHardwareType, 0x00, 1);
memset(stARP.chHardwareType + 1, 0x01, 1); // 硬件类型(0x0001表示以太网)
memset(stARP.chProtocolType, 0x08, 1);
memset(stARP.chProtocolType + 1, 0x00, 1); // 协议类型(0x0800表示IP协议)
stARP.chHardwareAddrLen = 6; // 硬件地址(MAC地址)长度为6
stARP.chProtocolAddrLen = 4; // 协议地址(IP地址)长度为4
memset(stARP.chOp, 0x00, 1);
memset(stARP.chOp + 1, 0x01, 1); // op为0x0001表示请求目的主机的MAC地址
memcpy(stARP.chSourceMACAddr, chSourceMac, sizeof(stARP.chSourceMACAddr)); // 源主机MAC地址
// IPIntToChars(nSourceIP, stARP.chSourceIPAddr); // 源主机IP地址
*(UINT*)stARP.chSourceIPAddr = htonl(nSourceIP);
memset(stARP.chTargetMACAddr, 0, sizeof(stARP.chTargetMACAddr)); // 目的主机MAC地址全0待填写
// IPIntToChars(nTargetIP, stARP.chTargetIPAddr); // 目的主机IP地址
*(UINT*)stARP.chTargetIPAddr = htonl(nTargetIP);
// sendto发送RAW原始包
// socket目标信息
sockaddr_in stSock;
stSock.sin_family = AF_INET;
stSock.sin_port = htons(PORT);
stSock.sin_addr.S_un.S_addr = htonl(nTargetIP);
// 发送数据包
sendto(m_nSock, (const char*)&stARP, sizeof(stARP), 0,
(const sockaddr*)&stSock, sizeof(sockaddr_in));