Rarp:反向地址解析协议;在局域网中,知道某个主机的MAC地址,可以查询到该主机的IP地址。
包结构体:
// MAC 广播地址
#define MAC_BCAST_ADDR (unsigned char *) "\xff\xff\xff\xff\xff\xff"
// rarp类型
#define ETH_P_RARP 0x8035
// ip类型
#define ETH_P_IP 0x0800
// 数据链路层
#define ARPHRD_ETHER 1
// 链路层报文结构
struct ethhdr{
unsigned char h_dest[6];
unsigned char h_source[6];
WORD h_proto;
};
// arp/rarp报文结构
struct arpMsg
{
struct ethhdr ethhdr; /* Ethernet header */
u_short htype; /* hardware type (must be ARPHRD_ETHER) */
u_short ptype; /* protocol type (must be ETH_P_IP) */
u_char hlen; /* hardware address length (must be 6) */
u_char plen; /* protocol address length (must be 4) */
u_short operation; /* ARP opcode */
u_char sHaddr[6]; /* sender's hardware address */
u_char sInaddr[4]; /* sender's IP address */
u_char tHaddr[6]; /* target's hardware address */
u_char tInaddr[4]; /* target's IP address */
u_char pad[18]; /* pad for min. Ethernet payload (60 bytes) */
};
发包的主要代码如下(没有接收返回包):
int i=0;
pcap_t *fp;
pcap_if_t *d = NULL;
char errbuf[PCAP_ERRBUF_SIZE] = {0};
struct arpMsg arp;
int iPos=((CComboBox*)GetDlgItem(IDC_NETWORK_ADAPTER))->GetCurSel();
d=m_alldevs;
for(;i<iPos;i++)
{
if(d==NULL)
{
return ;
}
d=d->next;
}
/* Open the device */
if ((fp= pcap_open_live(d->name,
100 /*snaplen*/,
0 /*flags*/,
100 /*read timeout*/,
errbuf)
) == NULL)
{
return ;
}
memset(&arp, 0, sizeof(arp));
memcpy(arp.ethhdr.h_dest, phoneMac6, 6); /* MAC DA */
memcpy(arp.ethhdr.h_source, m_localMac, 6); /* MAC SA */
arp.ethhdr.h_proto = htons(ETH_P_RARP); /* protocol type (Ethernet) */
arp.htype = htons(ARPHRD_ETHER); /* hardware type */
arp.ptype = htons(ETH_P_IP); /* protocol type (ARP message) */
arp.hlen = 6; /* hardware address length */
arp.plen = 4; /* protocol address length */
arp.operation = htons(3); /* RARP request code */
localIp = inet_addr(m_localIp);
arp.sInaddr[0] = (u_char)(localIp);
arp.sInaddr[1] = (u_char)(localIp>>8);
arp.sInaddr[2] = (u_char)(localIp>>16);
arp.sInaddr[3] = (u_char)(localIp>>24);
memcpy(arp.tHaddr, phoneMac6, 6);
/* Send down the packet */
if (pcap_sendpacket(fp, // Adapter
(u_char*)&arp, // buffer with the packet
sizeof(arp) // size
) != 0)
{
pcap_close(fp);
return ;
}
pcap_close(fp);