分析了下ifconfig 源码,(建议必应搜索net-tools 国外源码下载,百度出来的多是csdn下载还要积分)。

ifconfig 是net-tools软件包中的其中一个工具,源码的分析就不赘述了。

下面是从中提取修改出来的获取 mac ,ip 地址的源码,通过ioctrl 直接和内核(驱动)进行数据交互,有兴趣也可以再写个设置IP的 :

设置ip 调用以下几个

//SIOCSIFADDR    setip
//SIOCSIFNETMASK set netmask
//SIOCSIFFLAGS   set up/down
//SIOCSIFBRDADDR set broadcast

/* ubunt12.04 编译测试通过,直接gcc编译即可*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h> //缺少这个头文件时,编译其报警告 inet_ntoa 返回值为int?? 被就像少 stdio.h头文件是printf被编译器报警告一样

#include <netinet/in.h>
#include <net/if.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


static int skfd = -1;

int main(int argc ,const char*argv[])
{
	char ifname[64]="eth0";
	char buf[32] = {0};
	struct ifreq ifr;
	memset(&ifr,0,sizeof(struct ifreq));
	
	//创建socket
	skfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1 == skfd)
	{
		printf("erro to socket\n");
		return -1;
	}
	
	//状态
	strcpy(ifr.ifr_name, ifname);
	if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
	{
		printf("erro SIOCGIFFLAGS \n");
	}
	else
	{
		if (ifr.ifr_flags & IFF_UP)
		{
			printf("UP \n");
		}
	}
	
	//获取mac地址
	strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
	{
		printf("SIOCGIFHWADDR erro \n");
	}
    else
	{
		memcpy(buf, ifr.ifr_hwaddr.sa_data, 8);
		#if 0
		int i =0;
		for( i =0; i<8;i++)
		{
			printf("%#x ",buf[i]);
		}
		printf("\n");
		#endif
		char buff[64];
		unsigned char *ptr = buf;
		snprintf(buff, sizeof(buff), "%02X:%02X:%02X:%02X:%02X:%02X",
			 (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
			 (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
		);
		printf("MAC:%s\n",buff);
	}
	
	//获取IP,broadcast,netmask,
	strcpy(ifr.ifr_name, ifname);
	ifr.ifr_addr.sa_family = AF_INET;
	if (ioctl(skfd, SIOCGIFADDR, &ifr) == 0) 
	{
	    strcpy(ifr.ifr_name, ifname);
	    if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0)
		{
			printf("SIOCGIFDSTADDR erro\n");
		}
	    else
		{
			struct in_addr  in = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
			printf("ipaddr:%s\n", inet_ntoa(in));
		}

	    strcpy(ifr.ifr_name, ifname);
	    if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0)
		{
			printf("erro SIOCGIFBRDADDR\n");
		}
	    else
		{
			struct in_addr  in = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
			printf("broadaddr:%s\n", inet_ntoa(in));
		}

	    strcpy(ifr.ifr_name, ifname);
	    if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0)
		{
			printf("erro  SIOCGIFNETMASK\n");
		}
	    else
		{
			struct in_addr  in = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr;
			printf("netmask:%s\n", inet_ntoa(in));
		}
	}
	else
	{
		printf("erro SIOCGIFADDR\n");
    }
}

运行结果:

 

Logo

更多推荐