linux下主机发现,llinux 下用libpcap发送ARP包实现局域网内主机发现

#include #define MAC_BCAST_ADDR (uint8_t *) "\xff\xff\xff\xff\xff\xff"

#define ETHER_LEN sizeof(struct eth_header)

#define ARP_LEN sizeof(struct arp_header)

pcap_t* pcap_handle;

char error_content[PCAP_ERRBUF_SIZE];

char *net_interface;

char bpf_filter_string[] = "arp";

bpf_u_int32 net_mask;

bpf_u_int32 net_ip;

struct eth_header {

u_int8_t ether_dhost[6];

u_int8_t ether_shost[6];

u_int16_t ether_type;

};

typedef u_int32_t in_addr_t;

struct arp_header {

u_int16_t arp_hardware_type;

u_int16_t arp_protocol_type;

u_int8_t arp_hardware_length;

u_int8_t arp_protocol_length;

u_int16_t arp_operation_code;

u_int8_t arp_source_ethernet_address[6];

u_int8_t arp_source_ip_address[4];

u_int8_t arp_destination_ethernet_address[6];

u_int8_t arp_destination_ip_address[4];

};

int get_interface(char *dev, char * mac, int maclen, struct in_addr *lc_addr, int iplen){

int reqfd, n;

struct ifreq macreq;

reqfd = socket(AF_INET, SOCK_DGRAM, 0);

strcpy(macreq.ifr_name, dev);

/* 获取本地接口MAC地址*/

if(ioctl(reqfd, SIOCGIFHWADDR, &macreq) != 0)

return 1;

memcpy(mac, macreq.ifr_hwaddr.sa_data, maclen);

/* 获取本地接口IP地址*/

if(ioctl(reqfd, SIOCGIFADDR, &macreq) != 0)

return 1;

memcpy(lc_addr, &((struct sockaddr_in *)(&macreq.ifr_addr))->sin_addr, iplen);

return 0;

}

void arp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr* packet_header, const u_char* packet_content) {

struct arp_header *arp_protocol;

u_short operation_code;

u_char *mac_string;

struct in_addr source_ip_address;

arp_protocol = (struct arp_header *) (packet_content + 14);

operation_code = ntohs(arp_protocol->arp_operation_code);

if(operation_code == 2){

memcpy((void *) & source_ip_address, (void *) & arp_protocol->arp_source_ip_address, sizeof (struct in_addr));

printf("IP:%s ", inet_ntoa(source_ip_address));

printf("MAC:");

mac_string = arp_protocol->arp_source_ethernet_address;

printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac_string, *(mac_string + 1), *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));

}

}

void capture(){

struct bpf_program bpf_filter;

printf("Capturing ARP packet.............\n");

pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);

pcap_setfilter(pcap_handle, &bpf_filter);

if (pcap_datalink(pcap_handle) != DLT_EN10MB)

return;

pcap_loop(pcap_handle, -1, arp_protocol_packet_callback, NULL);

pcap_close(pcap_handle);

}

int main() {

struct arp_header a_header;

struct eth_header e_header;

struct in_addr local_addr;

u_char *mac;

int n;

u_char frame[ETHER_LEN + ARP_LEN];

unsigned long sendip;

pthread_t tid;

mac = (char *) malloc(ETH_ALEN);

bzero(&a_header, sizeof (a_header));

bzero(&e_header, sizeof (e_header));

if (get_interface("eth0", mac, ETH_ALEN, &local_addr, 4)) {

fprintf(stderr, "Error: Get host’s information failed\n");

exit(0);

}

printf("Local IP:%s\n",inet_ntoa(local_addr.s_addr));

memcpy(e_header.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN);

memcpy(e_header.ether_shost, mac, ETH_ALEN);

e_header.ether_type = htons(ETHERTYPE_ARP);

memcpy(frame, &e_header, ARP_LEN);

a_header.arp_hardware_type = htons(ARPHRD_ETHER);

a_header.arp_protocol_type = htons(ETHERTYPE_IP);

a_header.arp_hardware_length = ETH_ALEN;

a_header.arp_protocol_length = 4;

a_header.arp_operation_code = htons(ARPOP_REQUEST);

memcpy(a_header.arp_source_ethernet_address, mac, ETH_ALEN);

memcpy(a_header.arp_source_ip_address, &local_addr, 4);

net_interface = pcap_lookupdev(error_content);

pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);

pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content);

printf("Local Net: %s \n",inet_ntoa(net_ip));

printf("Net Mask:%s \n", inet_ntoa(net_mask));

if ((errno = pthread_create(&tid, NULL, capture, NULL)) < 0)

perror("pthread:");

sleep(1);

for (n = 1; n < 255; n++) {

sendip = htonl(net_ip) + n;

inet_aton(inet_ntoa(htonl(sendip)), a_header.arp_destination_ip_address);

memset(a_header.arp_destination_ethernet_address, 0, 6);

memcpy(&frame[ETHER_LEN], &a_header, ARP_LEN);

pcap_sendpacket(pcap_handle, frame, ETHER_LEN + ARP_LEN);

//printf("Send IP: %s \n", inet_ntoa(htonl(sendip)));

}

pthread_join(tid, NULL);

return 0;

}

运行结果:

Local IP:172.16.1.106

Local Net: 172.16.1.0

Net Mask:255.255.255.0

Capturing ARP packet.............

IP:172.16.1.1 MAC:d8:5d:4c:22:69:14

IP:172.16.1.100 MAC:00:1c:bf:c4:c6:92

IP:172.16.1.101 MAC:00:1b:9e:9a:ef:87

IP:172.16.1.103 MAC:00:13:e8:98:8e:71

IP:172.16.1.104 MAC:00:23:12:6a:08:cf

IP:172.16.1.105 MAC:00:13:e8:6e:13:f9

IP:172.16.1.102 MAC:00:26:08:ec:e9:65

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值