【无标题】ubantu下扫描局域网中的主机及对饮IP

宏定义中的HOST_NAME是网卡设备名

scan.h

#ifndef __SCAN__H_
#define __SCAN__H_

#include <stdio.h>
#include <sys/time.h>
#include <netdb.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <net/if.h>
#include <netinet/ip_icmp.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <pthread.h>
#include <linux/if.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <sys/ioctl.h>

#define IP_LEN 4
#define MAC_LEN 6
#define ON 1
#define OFF 0
#define ETH_HEAD_LEN 14
#define ARP_LEN 28
#define BUFF_LEN (ETH_HEAD_LEN+ARP_LEN+18)
#define TOTAL_HOST_NUM 256
#define HOST_NAME "ens33"
#define SEND_LEN 64
#define WAIT_TIME 50000
#define ARP_TYPE 0x0806

struct host {
    unsigned char IP[IP_LEN];
    unsigned char MAC[MAC_LEN];
    int is_on;
    struct host *next;
};

struct eth_head {
    unsigned char des_mac[6];
    unsigned char src_mac[6];
    unsigned short type;
};

struct arp_msg {
    unsigned short hdware_type;
    unsigned short protocol;
    unsigned char mac_len;
    unsigned char ip_len;
    unsigned short op_type;
    unsigned char src_mac[6];
    unsigned char src_ip[4];
    unsigned char des_mac[6];
    unsigned char des_ip[4];
};

struct host* host_init();

struct host* host_insert(struct host *head,char *IP,char *MAC);

int host_select(struct host *head,char *IP);

int host_update(struct host *head,char *IP,int stat);

struct host* scan(struct host* head);

int show_online(struct host* head);

int set_eth_head(struct eth_head *eth,char *des_mac);

int set_arp_msg(struct arp_msg* arp,char *des_ip,char *des_mac);

int initialize_sockaddr_ll(struct sockaddr_ll *sock_addr , struct ifreq *ifr ,int ifindex);

int get_local_mac(unsigned char *mac);

int get_local_ip(unsigned char *ip);

int show_online_host(struct host *head);

int free_host(struct host *head);

#endif

scan.c

#include "scan.h"

struct host * host_init()
{
	unsigned char mac[MAC_LEN+1] = {0};
	unsigned char ip[IP_LEN+1] = {0};
    
    struct host *head = (struct host *)malloc(sizeof(struct host));
	if(-1 == get_local_mac(mac))
	{
        printf("%s\n",__func__);
		return NULL;
	}
    
	if(-1 == get_local_ip(ip))
	{
        printf("%s\n",__func__);
		return NULL;
	}

	strncpy(head->IP,ip,IP_LEN);
	memmove(head->MAC,mac,MAC_LEN);

	head->next = NULL;
	head->is_on = ON;
    
	return head;
}
int get_local_mac(unsigned char *mac)
{
	if(NULL == mac){
		printf("%s\n",__func__);
		return -1;
	}
	struct ifreq ifr;

	bzero(&ifr,sizeof(struct ifreq));
	strncpy(ifr.ifr_name, "ens33", sizeof(ifr.ifr_name) - 1);
	int sd = socket(AF_INET,SOCK_STREAM,0);
	if(0>sd){
		printf("%s\n",__func__);
		return -1;
	}
	int ret = ioctl(sd, SIOCGIFHWADDR, &ifr);
	if(0>ret){
		printf("%s\n",__func__);
		close(sd);
		return -1;
	}
	for(int i=0;i<MAC_LEN;i++){
		mac[i]=(unsigned char)ifr.ifr_hwaddr.sa_data[i];
	}
	//printf("%p\n",mac);
	close(sd);
}
int get_local_ip(unsigned char *ip)
{
	if(NULL == ip){
		printf("%s\n",__func__);
		return -1;
	}
	struct ifreq ifr;

	bzero(&ifr,sizeof(struct ifreq));
	strncpy(ifr.ifr_name, "ens33", sizeof(ifr.ifr_name) - 1);
	int sd = socket(AF_INET,SOCK_STREAM,0);
	if(0>sd){
		printf("%s\n",__func__);
		return -1;
	}
	int ret = ioctl(sd, SIOCGIFADDR, &ifr);
	if(0>ret){
		perror("ioctl IP");
		close(sd);
		return -1;
	}
	struct sockaddr_in sin;
	memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
	memmove(ip,&sin.sin_addr, IP_LEN);
	return 0;
}
struct host* host_insert(struct host *head,char *IP,char *MAC)
{
	if(NULL == head){
		printf("insert head\n");
		return NULL;
	}
	if(NULL == IP){
		printf("insert IP\n");
		return NULL;
	}
	if(NULL == MAC){
		printf("insert MAC\n");
		return NULL;
	}
	struct host *ptr = (struct host *)malloc(sizeof(struct host));
	memmove(ptr->IP,IP,IP_LEN);
	memmove(ptr->MAC,MAC,MAC_LEN);
	ptr->is_on = 1;
	ptr->next = head;
	head = ptr;
	return head;
}
int host_select(struct host *head,char *IP)
{
	struct host *ptr = head;
	while (ptr)
	{
		if(0 == strncmp(ptr->IP,IP,IP_LEN)){
			break;
		}
		ptr = ptr->next;
	}
	if(ptr){
		return 1;
	}else{
		return 0;
	}
}
int host_update(struct host *head,char *IP,int stat)
{
	struct host *ptr = head;
	while (ptr)
	{
		if(0 == strncmp(ptr->IP,IP,IP_LEN)){
			break;
		}
		ptr = ptr->next;
	}
	if(ptr){
		ptr->is_on = stat;
	}else{
		printf("no such IP!!\n");
		return -1;
	}
	return 0;
}
struct host * scan(struct host* head)
{
	if(NULL!=head->next){
		printf("head node is not local");
		return NULL;
	}
	printf("scanning.....\n");
	struct ifreq ifr;		//用于存放网卡的相关信息
	struct sockaddr_ll sock_addr;
	int addrlen = sizeof(sock_addr);
	unsigned char ip[IP_LEN+1] = {0};
	unsigned char mac[MAC_LEN+1] = {0};
	char send_buffer[BUFF_LEN+1] = {0};
	char recv_buffer[BUFF_LEN+1] = {0};
	struct eth_head *ethhead = (struct eth_head *)send_buffer;
	struct arp_msg *arpmsg = (struct arp_msg *)(send_buffer + ETH_HEAD_LEN);
	strncpy(ip,head->IP,IP_LEN);
	unsigned long ul = 1;
	int ret = 0;
	int sock_scan=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ARP));
	if(0 > sock_scan){
		perror("socket");
		return NULL;
	}
    
	//设置为非阻塞接收
	ret = ioctl(sock_scan,FIONBIO,(unsigned long*)&ul);
	if(0 > ret){
		perror("ioctlsocket");
		close(sock_scan);
		return NULL;
	}
    
	//网卡信息
	strncpy(ifr.ifr_name,HOST_NAME,sizeof(ifr.ifr_name)-1);		
	if(ioctl(sock_scan,SIOCGIFINDEX,&ifr)==-1)	

	{
		perror("SIOCGIFINDEX");
		close(sock_scan);
		return NULL;
	}
	int ifindex = ifr.ifr_ifindex;

	if(ioctl(sock_scan,SIOCGIFHWADDR,&ifr)==-1)	//通过ioctl获取网卡MAC地址存放到ifr结构体中
	{
		perror("SIOCGIFHWADDR");
		close(sock_scan);
		return NULL;
	}
	
    //设置sockaddr_ll
	if(initialize_sockaddr_ll(&sock_addr , &ifr ,ifindex) == -1)
	{
		printf("sockaddr_ll error\n");
		close(sock_scan);
		return NULL;
	}

	for (int i = 0; i < TOTAL_HOST_NUM; i++)
	{
		ip[3] = i;
		if(-1 == set_eth_head(ethhead,NULL)){
			printf("set eth head error!!\n");
			close(sock_scan);
			return NULL;
		}
		if(-1 == set_arp_msg(arpmsg,ip,NULL)){
			printf("set_arp_msg error!!\n");
			close(sock_scan);
			return NULL;
		}
		if(sendto(sock_scan,send_buffer,SEND_LEN,0,(struct sockaddr*)&sock_addr,sizeof(sock_addr))==-1)
		{
			perror("sendtos");
			close(sock_scan);
			return NULL;
		}
		usleep(WAIT_TIME);
		ret = recvfrom(sock_scan,recv_buffer,BUFF_LEN,0,(struct sockaddr*)&sock_addr,&addrlen);
			if(0 == ret)
				continue;
			else if(ret>0){
				memmove(mac,&recv_buffer[6],MAC_LEN);
				if((unsigned char)recv_buffer[31] == (unsigned char)i){
					if(NULL == (head = host_insert(head,ip,mac))){
						close(sock_scan);
						return NULL;
					}
				}
			}
		bzero(send_buffer,sizeof(send_buffer));
		bzero(recv_buffer,sizeof(recv_buffer));
	}
    return head;

}
int set_eth_head(struct eth_head *eth,char *des_mac)
{
	if(NULL == eth){
		printf("eth_head point to NULL!!\n");
		return -1;
	}
    
	unsigned char local_mac[MAC_LEN+1] = {0};
	if(NULL == des_mac){
		for(int i=0;i<MAC_LEN;i++){
			eth->des_mac[i] = (unsigned char)0xff;
		}
	}else{
		strncpy(eth->des_mac,des_mac,MAC_LEN);
	}
	if(-1 == get_local_mac(local_mac)){
		
		return -1;
	}
    
	//printf("%p\n",local_mac);

	memmove(eth->src_mac,local_mac,MAC_LEN);
	//printf("%02x:%02x:%02x:%02x:%02x:%02x\n",eth->src_mac[0],eth->src_mac[1],eth->src_mac[2],eth->src_mac[3],eth->src_mac[4],eth->src_mac[5]);
	
	eth->type = htons(ARP_TYPE);
}
int set_arp_msg(struct arp_msg* arp,char *des_ip,char *des_mac)
{
	if(NULL == arp||NULL == des_ip)
	{
		printf("%s\n",__func__);
		return -1;
	}
	if(NULL == des_mac){
		for (int i = 0; i < MAC_LEN; i++){
			arp->des_mac[i] = 0;
	    }
	}else{
			strncpy(arp->des_mac,des_mac,MAC_LEN);
	}
	arp->hdware_type = htons(0x01);
	arp->protocol = htons(0x0800);
	arp->mac_len = 6;
	arp->ip_len = 4;
	arp->op_type = htons(1);
	unsigned char send_mac[MAC_LEN+1] = {0};
    if(-1 == get_local_ip(arp->src_ip)){
        printf("%s\n",__func__);
        return -1;
    }
    if(-1 == get_local_mac(send_mac)){
        printf("%s\n",__func__);
        return -1;
    }
    strncpy(arp->des_ip,des_ip,IP_LEN);
	memmove(arp->src_mac,send_mac,MAC_LEN);
    return 0;
}
int initialize_sockaddr_ll(struct sockaddr_ll *sock_addr , struct ifreq *ifr ,int ifindex)
{
	if(sock_addr == NULL || ifr ==NULL)
	{
		printf("sockaddr_ll or ifreq is a null pointer\n");
		return -1;
	}
	int i =0;
	//设置sockaddr_ll结构体的信息
	for(i=0;i<MAC_LEN;i++)
	{
		sock_addr->sll_addr[i]=(unsigned char)ifr->ifr_hwaddr.sa_data[i];	
	}
	sock_addr->sll_family = PF_PACKET;	
	sock_addr->sll_protocol = htons(ETH_P_ARP);	//协议类型
	sock_addr->sll_ifindex =ifindex;	//网卡序列号
	//printf("%d,%d\n",ifindex,ifr->ifr_ifindex);
	sock_addr->sll_hatype = htons(ARPHRD_ETHER);	//ARP硬件地址类型
	sock_addr->sll_halen = ETH_ALEN;	//硬件地址长度
	return 0;
}
int show_online_host(struct host *head)
{
    struct host *node = head;
    while(node){
        if(node->is_on){
            printf("IP:");
            for(int i=0;i<IP_LEN;i++){
                if(i == IP_LEN-1){
                    printf("%d",node->IP[i]);
                }else{
                    printf("%d.",node->IP[i]);
                }
            }
            printf("-------MAC");
            for(int i=0;i<MAC_LEN;i++){
                printf(":%02x",node->MAC[i]);
            }
            printf("---------on\n");
        }
        node = node->next;
    }
    return -1;
}
int free_host(struct host *head)
{
	if(NULL == head){
		printf("head point to NULL!!\n");
		return -1;
	}

	struct host *ptr;
	ptr = head->next;
	while (ptr)
	{
		free(head);
		head = ptr;
		ptr = ptr->next;
	}
	free(head);
	return 0;
	
}

main.c

#include "scan.h"

struct host *head = NULL;

int main()
{
    struct host *head;
    head = host_init(head);
    head = scan(head);
    show_online_host(head);

    free_host(head);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值