获取局域网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]


### 查看局域网内所有设备的IP地址 为了在机房环境中查看局域网内的所有IP地址,可以采用多种方法技术来实现这一目标。以下是几种常用的方法: #### 方法一:使用命令行工具 `arp` `nmap` ##### 使用 ARP 命令 ARP (Address Resolution Protocol) 协议用于将 IP 地址解析为 MAC 地址。通过查询本地缓存中的 ARP 表,可以获得当前已知的 IP 到 MAC 的映射关系。 ```bash arp -a ``` 这条命令会显示所有已经与本机通信过的设备及其对应的 IP 地址 MAC 地址[^3]。 ##### 使用 NMAP 工具 NMAP 是一款强大的网络扫描工具,能够高效地发现网络上的主机服务。安装并运行 nmap 可以轻松获取整个子网范围内的活动主机列表。 对于 C 类网络(假设子网掩码为 255.255.255.0),执行如下命令即可完成扫描: ```bash sudo nmap -sn 192.168.1.0/24 ``` 这里 `-sn` 参数表示仅做 ping 扫描而不尝试端口探测;而 `/24` 表示 CIDR 记法下的子网大小,即最后八位作为主机号变化的空间[^4]。 #### 方法二:利用 DHCP 服务器日志或管理界面 如果机房内部署有 DHCP 服务器,则可以直接查阅其分配记录或者登录到相应的管理系统中查看在线客户端的信息。这种方法通常能提供最全面准确的结果,因为所有的动态 IP 都是由该服务器统一分配出去的[^2]。 #### 方法三:编写自定义脚本进行主动探测 当上述两种方式不适用时,还可以考虑编写简单的 Python 脚本来遍历可能存在的 IP 段,并对每一个地址发起 ICMP 请求(ping)。成功回应者则被认为是活跃节点之一。 下面是一个基于 Python 的简单例子: ```python import os from concurrent.futures import ThreadPoolExecutor def check_ip(ip): response = os.system(f"ping -c 1 {ip} >/dev/null") if response == 0: print(f"{ip}: up") else: print(f"{ip}: down") with ThreadPoolExecutor(max_workers=256) as executor: for i in range(1, 255): ip = f"192.168.1.{i}" executor.submit(check_ip, ip) ``` 这段代码创建了一个线程池来进行并发 Ping 测试,从而加快速度。请注意调整 IP 地址段以匹配实际环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爻渡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值