获取到当前网段中所有机器的MAC地址:
每次指定一个机器发送MAC请求,通过发送多次ARP,即可得到当前网段内所有机器的MAC。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ether.h>
#include <netpacket/packet.h>
#include <pthread.h>
void *fun(void *arg)
{
int sock_raw_fd = *(int *)arg;
while(1)
{
unsigned char recv_msg[1024] = "";
recvfrom(sock_raw_fd, recv_msg, sizeof(recv_msg),0, NULL, NULL);
if(recv_msg[21] == 2) //ARP应答
{
char resp_mac[18] = "";
char resp_ip[18] = "";
sprintf(resp_mac, "%02x:%02x:%02x:%02x:%02x:%02x", \
recv_msg[22], recv_msg[23], recv_msg[24], \
recv_msg[25], recv_msg[26], recv_msg[27]);
sprintf(resp_ip, "%d.%d.%d.%d", recv_msg[28], \
recv_msg[29], recv_msg[30], recv_msg[31]);
printf("IP:%s - Mac:%s\n", resp_ip, resp_mac);
}
}
return NULL;
}
int main(int argc, char *argv[])
{
int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if(sock_raw_fd < 0)
{
perror("sock_raw_fd");
}
unsigned char send_buf[1024] = "";
unsigned char d_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
unsigned char s_mac[6] = {0x00, 0x29, 0xc3, 0xfd, 0xe8, 0x33};
unsigned char d_ip[4] = {10, 221, 1, 1};
unsigned char s_ip[4] = {10, 221, 1, 55};
//组mac头 14字节
//memcpy(send_buf, d_mac, 6);
//memcpy(send_buf+6, s_mac, 6);
//*(unsigned short *)(buf+12) = htons(0x0806);//转大端格式
struct ether_header *eth = (struct ether_header *)send_buf;
memcpy(eth->ether_dhost, d_mac, 6);
memcpy(eth->ether_shost, s_mac, 6);
eth->ether_type = htons(0x0806);
//组arp头 28字节
struct arphdr *arp = (struct arphdr *)(send_buf+14);//去掉头部14字节
arp->ar_hrd = htons(1);
arp->ar_pro = htons(0x0806);
arp->ar_hln = 6;
arp->ar_pln = 4;
arp->ar_op = htons(1);
memcpy(arp->__ar_sha, s_mac, 6);
memcpy(arp->__ar_sip, s_ip, 4);
memcpy(arp->__ar_tip, d_ip, 4);
struct ifreq ethreq; //网络接口地址
strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); //指定网卡名称
if(-1 == ioctl(sock_raw_fd, SIOCGIFINDEX, ðreq))
{
perror("ioctl");
close(sock_raw_fd);
exit(-1);
}
struct sockaddr_ll sll; //原始套接字地址结构
bzero(&sll, sizeof(sll));
sll.sll_ifindex = ethreq.ifr_ifindex;
pthread_t pth;
pthread_create(&pth, NULL, fun, &sock_raw_fd);
int i = 0;
unsigned char send_msg[1024] = "";
for(i=1; i<255; i++)
{
send_msg[41] = i;
int len = sendto(sock_raw_fd, send_msg, 42, 0, \
(struct sockaddr *)&sll, sizeof(sll));
if(len == -1)
{
perror("sendto");
}
}
pthread_join(pth, NULL);
return 0;
}