ioctl 获取相关地址及开启和关闭网卡

12 篇文章 0 订阅

1,结构体

struct ifreq
{
#define IFHWADDRLEN 6
 union
 {
  char ifrn_name[IFNAMSIZ];  
 } ifr_ifrn;
 
 union 
 {
  struct sockaddr ifru_addr;
  struct sockaddr ifru_dstaddr;
  struct sockaddr ifru_broadaddr;
  struct sockaddr ifru_netmask;
  struct  sockaddr ifru_hwaddr;
  short ifru_flags;
  int ifru_ivalue;
  int ifru_mtu;
  struct  ifmap ifru_map;
  char ifru_slave[IFNAMSIZ]; 
  char ifru_newname[IFNAMSIZ];
  void __user * ifru_data;
  struct if_settings ifru_settings;
 } ifr_ifru;
};
#define ifr_name ifr_ifrn.ifrn_name 
#define ifr_hwaddr ifr_ifru.ifru_hwaddr 
#define ifr_addr ifr_ifru.ifru_addr 
#define ifr_dstaddr ifr_ifru.ifru_dstaddr 
#define ifr_broadaddr ifr_ifru.ifru_broadaddr 
#define ifr_netmask ifr_ifru.ifru_netmask 
#define ifr_flags ifr_ifru.ifru_flags 
#define ifr_metric ifr_ifru.ifru_ivalue 
#define ifr_mtu  ifr_ifru.ifru_mtu 
#define ifr_map  ifr_ifru.ifru_map 
#define ifr_slave ifr_ifru.ifru_slave 
#define ifr_data ifr_ifru.ifru_data 
#define ifr_ifindex ifr_ifru.ifru_ivalue 
#define ifr_bandwidth ifr_ifru.ifru_ivalue    
#define ifr_qlen ifr_ifru.ifru_ivalue 
#define ifr_newname ifr_ifru.ifru_newname 
#define ifr_settings ifr_ifru.ifru_settings 

struct ifconf 
{
	int ifc_len; /* size of buffer    */
	union 
	{
		char *ifcu_buf; /* input from user->kernel*/
		struct ifreq *ifcu_req; /* return from kernel->user*/
	} ifc_ifcu;
};

   ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口的名字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。ifreq包含在ifconf结构中。而 ifconf结构通常是用来保存所有接口的信息的。

 

2,获取相关地址类似于ifconfig

#include <stdio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/*参数1: eth0 eth1 lo */
int get_addr(const char * interface_name, int type, char *ip , int len)
{
	struct ifreq ifr;
	struct sockaddr_in * ptr = NULL;
	struct in_addr addr_temp;
	unsigned char *pmac;
	int fd  = -1; 
	if (NULL == interface_name ||  NULL == ip)
	{
		printf("get_local_ipaddr param err.\n");
		return -1;
	}
	if (SIOCGIFHWADDR == type)
	{
		if (len < 18)
		{
			printf("mac need 18 byte..\n");
			return -1;
		}
	}
	else 
	{
		if (len < 16 )
		{
			printf("addr need 16 byte..\n");
			return -1;
		}
	}


	fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd < 0)
	{
		perror("socket erro");
		return -1;
	}

	strcpy(ifr.ifr_name, interface_name);
	if (ioctl(fd, type, &ifr) < 0)
	{
		printf("ioctl  is error\n");
		close(fd);
		return -1;
	}
	if (SIOCGIFADDR == type)
	{
		ptr = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_addr;//ip地址 
	}
	else if (SIOCGIFBRDADDR == type)
	{
		ptr = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_broadaddr;//广播地址 
	}
	else if (SIOCGIFDSTADDR == type)
	{
		ptr = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_dstaddr;//目的地址 
	}
	else if(SIOCGIFNETMASK == type) 
	{
		ptr = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_netmask;//子网掩码	
	} 
	else if (SIOCGIFHWADDR == type)
	{
		pmac = (unsigned char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];
		snprintf(ip, len, "%02x-%02x-%02x-%02x-%02x-%02x", *pmac, *(pmac+1),*(pmac+2),*(pmac+3),*(pmac+4),*(pmac+5));
	}
	else
	{
		printf("type is erro!!!\n");
		close(fd);
		return -1;
	}
	if (SIOCGIFHWADDR != type)
	{
		addr_temp = ptr->sin_addr;
		inet_ntop(AF_INET, &addr_temp, ip, len);
	}
	close(fd);

	return 0;
}

void my_ifconfig()
{
	char buf[16];
	char mac[18];
	
	bzero(mac, sizeof(mac));
	bzero(buf, sizeof(buf));
	get_addr("eth0",SIOCGIFADDR, buf, sizeof(buf));//ip地址 
	printf("addr:%s\n",buf);
	
	bzero(buf, sizeof(buf));
	get_addr("eth0",SIOCGIFDSTADDR, buf, sizeof(buf));//目的地址 
	printf("dstaddr:%s\n",buf);
	
	bzero(buf, sizeof(buf));
	get_addr("eth0",SIOCGIFBRDADDR, buf, sizeof(buf));//广播地址 
	printf("broadaddr:%s\n",buf);
	
	bzero(buf, sizeof(buf));
	get_addr("eth0",SIOCGIFNETMASK, buf, sizeof(buf));//子网掩码 
	printf("netmask:%s\n",buf);
	
	get_addr("eth0", SIOCGIFHWADDR, mac ,sizeof(mac));
	printf("mac:%s\n",mac); 
	
	
	return ;
}
int main(int argc, char ** argv)
{

	my_ifconfig();
	
	return 0; 
}


3,开启和关闭网卡

ifconfig eth0 up 开启

ifconfig eth0 down 关闭

#include <stdio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int if_up(char * interface_name)
{
	int fd;
	struct ifreq ifr;
	short flag;
	if (NULL == interface_name)
	{
		return -1;
	}
	
	if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		return -1; 
	}
	
	strcpy(ifr.ifr_name, interface_name);
	
	if (strcmp("eth0", interface_name) == 0)
	{
		flag = IFF_UP | IFF_PROMISC;
	}
	else
	{
		flag = IFF_UP;
	}
	
	if (ioctl(fd , SIOCGIFFLAGS, &ifr) < 0)
	{
		close(fd);
		return -1;
	}
	
	ifr.ifr_ifru.ifru_flags |= flag;
	
	if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
	{
		close(fd);
		return -1;
	}
	
	close(fd);
	return 0;
}


int if_down(char * interface_name)
{
	int s;
	struct ifreq ifr;
	short flag;

	if (NULL == interface_name) 
	{
		return -1;
	}

	if(strcmp(interface_name,"lo") == 0) 
	{
		printf("You can't pull down interface lo\n");
		return -1;
	}

	if((s = socket(PF_INET,SOCK_STREAM,0)) < 0) 
	{
		return -1;
	}

	strcpy(ifr.ifr_name,interface_name);

	if (strcmp("eth0",interface_name)==0)
		flag = ~(IFF_UP|IFF_PROMISC);
	else
		flag = ~(IFF_UP);
	
	if(ioctl(s,SIOCGIFFLAGS,&ifr) < 0) 
	{
		printf("if_down ioctl error \n");
		close(s);
		return -1;
	}

	ifr.ifr_ifru.ifru_flags &= flag;

	if(ioctl(s,SIOCSIFFLAGS,&ifr) < 0) 
	{
		printf("if_down ioctl error\n");
		close(s);
		return -1;
	}
	close(s);
	return 0;
}

int main(int argc, char **argv)
{
	int ret =-1;
	if (argc !=2)
	{
		printf("argc is not 2\n");
		return -1;
	}

	if(strncmp(argv[1],"up", 2) == 0)
	{
		ret = if_up("eth0");
	}
	else if (strncmp(argv[1], "down", 4) == 0)
	{
		ret = if_down("eth0");
	}
	else 
	{
		printf("error\n");
		return -1;
	}
	
	return ret;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值