獲取局域網Max和Ip

GetLocalMac.c

/*============================================================================ 
 Name        : GetLocalMac.cpp 
 Author      : Haier 
 Version     : 1.01 
 Copyright   : Copyright (c) 2014 
 Description : GetLocalMac in C, Compile by Gcc 
 ============================================================================*/ 

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>

typedef struct _Ether_pkg
{
	unsigned char ether_dhost[6];
	unsigned char ether_shost[6];
	unsigned short int ether_type;
	
	unsigned short int ar_hrd;
	unsigned short int ar_pro;
	unsigned char ar_hln;
	unsigned char ar_pln;
	unsigned short int ar_op;
	unsigned char ar_sha[ETH_ALEN];
	unsigned char ar_sip[4];
	unsigned char ar_tha[ETH_ALEN];
	unsigned char ar_tip[4];
}Ether_pkg;

/*----------------------------------------------------------
; 函數:GetLocalMac()
------------------------------------------------------------*/
int GetLocalMac(const char *device, char *mac, char *ip)
{
	int sockfd;
	struct ifreq req;
	struct sockaddr_in *sin;
	
	if((sockfd=socket(PF_INET,SOCK_DGRAM,0))== -1)
	{
		fprintf(stderr, "Sock Error:%s\n",strerror(errno));
		return -1;
	}
	
	memset(&req, 0, sizeof(req));
	strcpy(req.ifr_name, device);
	if(ioctl(sockfd,SIOCGIFHWADDR, (char*)&req) == -1)
	{
		fprintf(stderr, "ioctlSIOCGIFHWADDR:%s\n", strerror(errno));
		close(sockfd);
		return -1;
	}
	memcpy(mac, req.ifr_hwaddr.sa_data,6);
	
	req.ifr_addr.sa_family = PF_INET;
	if(ioctl(sockfd,SIOCGIFADDR, (char*)&req) == -1)
	{
		fprintf(stderr, "SIOCGIFADDR:%s\n",strerror(errno));
		close(sockfd);
		return -1;
	}
	
	sin = (struct sockaddr_in*)&req.ifr_addr;
	memcpy(ip, (char*)&sin->sin_addr,4);
	
	return 0;	
}

/*----------------------------------------------------------
; 函數:mac_ntoa()
------------------------------------------------------------*/
char *mac_ntoa(const unsigned char *mac)
{
	static char buffer[18];
	memset(buffer, 0, sizeof(buffer));
	sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
	
	return buffer;
}

/*----------------------------------------------------------
; 函數:parse_ether_package()
------------------------------------------------------------*/
void parse_ether_package(const Ether_pkg *pkg)
{
	printf("source IP=[%s] MAC=[%s]\n", inet_ntoa(*(struct in_addr *)pkg->ar_sip),mac_ntoa(pkg->ar_sha));
	printf("dest   IP=[%s] MAC=[%s]\n", inet_ntoa(*(struct in_addr *)pkg->ar_tip),mac_ntoa(pkg->ar_tha));
}

/*----------------------------------------------------------
; 函數:sendpkg()
------------------------------------------------------------*/
int sendpkg(char *mac, char *broad_mac, char *ip, char *dest)
{
	Ether_pkg pkg,*parse;
	struct hostent *host = NULL;
	struct sockaddr sa;
	int sockfd, len;
	char buffer[255];
	unsigned char temp_ip[5];
	memset((char*)&pkg, '0', sizeof(pkg));
	
	memcpy((char*)pkg.ether_shost, (char*)mac, 6);
	memcpy((char*)pkg.ether_dhost, (char*)broad_mac, 6);
	pkg.ether_type = htons(ETHERTYPE_ARP);
	
	pkg.ar_hrd = htons(ARPHRD_ETHER);
	pkg.ar_pro = htons(ETHERTYPE_IP);
	pkg.ar_hln = 6;
	pkg.ar_pln = 4;
	pkg.ar_op  = htons(ARPOP_REQUEST);
	memcpy((char*)pkg.ar_sha, (char*)mac, 6);
	memcpy((char*)pkg.ar_sip, (char*)ip, 4);
	memcpy((char*)pkg.ar_tha, (char*)broad_mac, 6);
	
	fflush(stdout);
	memset(temp_ip, 0, sizeof(temp_ip));
	if(inet_aton(dest, (struct in_addr *)temp_ip) == 0)
	{
		if((host = gethostbyname(dest)) == NULL)
		{
			fprintf(stderr, "Fail ! %s\n", hstrerror(h_errno));
			return -1;
		}
		
		memcpy((char*)temp_ip, host->h_addr, 4);
	}
	
	memcpy((char*)pkg.ar_tip, (char*)temp_ip, 4);
	if((sockfd=socket(PF_INET, SOCK_PACKET,htons(ETH_P_ALL))) == -1)
	{
		fprintf(stderr, "Socket Error:%s\n",strerror(errno));
		return 0;
	}
	
	memset(&sa, '0', sizeof(sa));
	strcpy(sa.sa_data,"eth1");
	
	len = sendto(sockfd, &pkg, sizeof(pkg),0,&sa,sizeof(sa));
	if(len != sizeof(pkg))
	{
		fprintf(stderr,"Sendto Error:%s\n",strerror(errno));
		close(sockfd);
		return 0;
	}
	
	fd_set readfds;
	struct timeval tv;
	while(1)
	{
		tv.tv_sec = 0;
		tv.tv_usec= 500000;
		FD_ZERO(&readfds);
		FD_SET(sockfd,&readfds);
		
		len = select(sockfd+1, &readfds, 0, 0, &tv);
		if(len > -1)
		{

			memset(buffer,0,sizeof(buffer));
			len=recvfrom(sockfd,buffer,sizeof(buffer),0,NULL,&len);
			
			parse = (Ether_pkg*)buffer;
			if((ntohs(parse->ether_type) == ETHERTYPE_ARP) && (ntohs(parse->ar_op) == ARPOP_REPLY))
			{
				parse_ether_package(parse);
				break;
			}
			
		}
		
				
	}
	
	close(sockfd);
	return 1;
}

/*----------------------------------------------------------
; 函數:main()
------------------------------------------------------------*/
int main(int argc, char **argv)
{
	struct timeval tvafter,tvpre;
	struct timezone tz;
	gettimeofday(&tvpre,&tz);
	
	unsigned char mac[7];
	unsigned char ip[5];
	char dest[16]={0};
	unsigned char broad_mac[7]={0xff,0xff,0xff,0xff,0xff,0xff,0x00};

	memset(mac,0,sizeof(mac));
	memset(ip,0,sizeof(ip));
	if(GetLocalMac("eth1",mac,ip) == -1)
	{
		return -1;
	}
	
	printf("Local Mac=[%s] Ip=[%s]\n", mac_ntoa(mac),inet_ntoa(*(struct in_addr*)ip));
	sprintf(dest,"255.255.255.255",16);
	sendpkg(mac,broad_mac,ip,dest);
	
	gettimeofday(&tvafter, &tz);
	printf("\nfinished:%dms\n",(tvafter.tv_sec-tvpre.tv_sec)*1000 + (tvafter.tv_usec-tvpre.tv_usec)/1000);
	
	return 0;
	
}

運行示例:

[root@Linux Ping]# ./test.o 
Local Mac=[00:0C:29:AC:1B:2C] Ip=[192.168.64.128]
source IP=[192.168.64.254] MAC=[00:50:56:EF:89:0A]
dest   IP=[192.168.64.128] MAC=[00:0C:29:AC:1B:2C]


發佈了56 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章