1. 程式人生 > >socket 通過 ioctl獲取 設定 網絡卡 IP 子網掩碼 本地廣播地址

socket 通過 ioctl獲取 設定 網絡卡 IP 子網掩碼 本地廣播地址

參看 http://blog.chinaunix.net/uid-20692625-id-3172833.html




類別

Request

說明

資料型別

套 
接 

SIOCATMARK 
SIOCSPGRP 
SIOCGPGRP

是否位於帶外標記 
設定套介面的程序ID 或程序組ID 
獲取套介面的程序ID 或程序組ID

int 
int 
int

文 

FIONBIN 
FIOASYNC 
FIONREAD 
FIOSETOWN 
FIOGETOWN

設定/ 清除非阻塞I/O 標誌 
設定/ 清除訊號驅動非同步I/O 標誌 
獲取接收快取區中的位元組數 
設定檔案的程序ID 或程序組ID 
獲取檔案的程序ID 或程序組ID

int 
int 
int 
int 
int

接 

SIOCGIFCONF 
SIOCSIFADDR 
SIOCGIFADDR 
SIOCSIFFLAGS 
SIOCGIFFLAGS 
SIOCSIFDSTADDR 
SIOCGIFDSTADDR 
SIOCGIFBRDADDR 
SIOCSIFBRDADDR 
SIOCGIFNETMASK 
SIOCSIFNETMASK 
SIOCGIFMETRIC 
SIOCSIFMETRIC 
SIOCGIFMTU 
SIOCxxx

獲取所有介面的清單 
設定介面地址 
獲取介面地址 
設定介面標誌 
獲取介面標誌 
設定點到點地址 
獲取點到點地址 
獲取廣播地址 
設定廣播地址 
獲取子網掩碼 
設定子網掩碼 
獲取介面的測度 
設定介面的測度 
獲取介面MTU 
(還有很多取決於系統的實現)

struct ifconf 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq 
struct ifreq

ARP

SIOCSARP 
SIOCGARP 
SIOCDARP

建立/ 修改ARP 表項 
獲取ARP 表項 
刪除ARP 表項

struct arpreq 
struct arpreq 
struct arpreq

路 

SIOCADDRT 
SIOCDELRT

增加路徑 
刪除路徑

struct rtentry 
struct rtentry

I_xxx

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#if 0
struct ifreq
{
	char ifr_name[IFNAMSIZ]; /* Interface name */ 
	union { 
		struct sockaddr ifr_addr; 
		struct sockaddr ifr_dstaddr; 
		struct sockaddr ifr_broadaddr; 
		struct sockaddr ifr_netmask; 
		struct sockaddr ifr_hwaddr; 
		short ifr_flags; 
		int ifr_ifindex; 
		int ifr_metric; 
		int ifr_mtu; 
		struct ifmap ifr_map; 
		char ifr_slave[IFNAMSIZ]; 
		char ifr_newname[IFNAMSIZ]; 
		char * ifr_data; 
		}; 
}
struct ifconf { 
	int ifc_len; /* size of buffer */
	union { 
		char * ifc_buf; /* buffer ddress */ 
		struct ifreq *ifc_req; /* array of structures */
	}; 
};
#endif 

int MyifconfigTest()
{
	int i = 0;
	struct ifreq * ifr = NULL;
	struct ifconf ifc;
	//初始化ifconf
	unsigned char buf[1024] = {0};
	ifc.ifc_len = 1024;
	ifc.ifc_buf = buf;

	int sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0){
	    perror("create socket failed:");
	    return -1;
	}
	
	if (ioctl(sock, SIOCGIFCONF, (char *) &ifc) < 0){
	    perror("ioctl-conf:");
		close(sock);
	    return -1;
	}	
	//printf("ifc.ifc_len %d\n",ifc.ifc_len);
	//printf("We have %d network card\n",ifc.ifc_len/sizeof(struct ifreq));
	ifr = (struct ifreq*)buf;  
	for(i = 0;i < ifc.ifc_len/sizeof(struct ifreq);i++){
	//網絡卡名
		printf("\n%s", ifr->ifr_name);
	//網絡卡flags值
		if(ioctl(sock, SIOCGIFFLAGS, ifr)>=0){
			if(IFF_UP & ifr->ifr_flags){
				printf(" [UP]\n");
			}else /*if(IFF_DOWN & ifr->ifr_flags)*/{
				printf(" [DOWN]\n");
			}
		}else{
			perror("	ioctl SIOCGIFFLAGS error");
		}
		
	//網絡卡硬體地址
		if(ioctl(sock, SIOCGIFHWADDR, ifr)>=0){
			u_int8_t hd[6] = {0};
			memcpy(hd, ifr->ifr_hwaddr.sa_data, sizeof(hd));
			printf("	HWaddr: %02X:%02X:%02X:%02X:%02X:%02X\n", hd[0], hd[1], hd[2], hd[3], hd[4], hd[5]);
		}else{
			perror("	ioctl SIOCGIFHWADDR error");
		}
		
	//網絡卡本地IP地址
		//Get
		if(ioctl(sock, SIOCGIFADDR, ifr)>=0){
			printf("	IP: %s\n",inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr));
		}else{
			perror("	ioctl SIOCGIFADDR error");
		}	
		//Set
		//if(0 == strncmp("vmnet8",ifr->ifr_name,strlen("vmnet8")))
		if(0)
		{
			printf("	!!set vmnet8 IP!!\n");
			inet_aton( "192.168.117.4",&(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr));
			if(ioctl( sock, SIOCSIFADDR, ifr)>=0)
				printf("	ioctl SIOCSIFADDR success.\n");
			else    
				perror("	ioctl SIOCSIFADDR error");
		}
		
	//網絡卡本地廣播地址
		//Get
		if(ioctl(sock, SIOCGIFBRDADDR, ifr)>=0){
			printf("	Bcast: %s\n",inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_broadaddr))->sin_addr));
		}else{
			perror("	ioctl SIOCGIFBRDADDR error");
		}
		//Set
		//if(0 == strncmp("vmnet8",ifr->ifr_name,strlen("vmnet8")))
		if(0)
		{
			printf("	!!set vmnet8 Bcast!!\n");
			inet_aton( "192.168.117.255",&(((struct sockaddr_in*)&(ifr->ifr_broadaddr))->sin_addr));
			if(ioctl( sock, SIOCSIFBRDADDR, ifr)>=0)
				printf("	ioctl SIOCSIFBRDADDR success.\n");
			else    
				perror("	ioctl SIOCSIFBRDADDR error");
		}
		
	//網絡卡子網掩碼地址
		//Get
		if(ioctl(sock, SIOCGIFNETMASK, ifr)>=0){
			printf("	Mask: %s\n",inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_netmask))->sin_addr));
		}else{
			perror("	ioctl SIOCGIFNETMASK error");
		}	
		//Set
		//if(0 == strncmp("vmnet8",ifr->ifr_name,strlen("vmnet8")))
		if(0)
		{
			printf("	!!set vmnet8 Mask!!\n");
			inet_aton( "255.255.255.0",&(((struct sockaddr_in*)&(ifr->ifr_netmask))->sin_addr));
			if(ioctl( sock, SIOCSIFNETMASK, ifr)>=0)
				printf("	ioctl SIOCSIFNETMASK success.\n");
			else    
				perror("	ioctl SIOCSIFNETMASK error");
		}
		
		//網絡卡MTU值
		if(ioctl(sock, SIOCGIFMTU, ifr)>=0){
			printf("	MTU: %d\n",ifr->ifr_mtu);
		}else{
			perror("	ioctl SIOCGIFMTU error");
		}
		
		//網絡卡NREAD值
		int nread = 0;
		if(ioctl(sock, FIONREAD, &nread)>=0){
			printf("	nread: %d\n",nread);
		}else{
			perror("	ioctl FIONREAD error");
		}			
		ifr++;	  
	}
	close(sock);
}
int main(int argc,char **argv)
{	
	MyifconfigTest();	
}