Linux C 网络编程 - 获取本地 ip 地址,mac,通过域名获取对应的 ip

获取本地 ip 地址,mac,通过域名获取对应的 ip,

是网络编程可能遇到的比较常见的操作了,所以总结如下(封装了3个函数),

直接上代码

 
  1 #include <stdio.h>  
  2 #include <stdlib.h>  
  3 #include <string.h>  
  4 #include <errno.h>  
  5 #include <unistd.h>  
  6   
  7 #include <netdb.h>  
  8 #include <net/if.h>  
  9 #include <arpa/inet.h>  
 10 #include <sys/ioctl.h>  
 11 #include <sys/types.h>  
 12 #include <sys/socket.h>  
 13   
 14 #define MAC_SIZE    18  
 15 #define IP_SIZE     16  
 16   
 17 // function declare  
 18 int get_ip_by_domain(const char *domain, char *ip); // 根据域名获取ip  
 19 int get_local_mac(const char *eth_inf, char *mac); // 获取本机mac  
 20 int get_local_ip(const char *eth_inf, char *ip); // 获取本机ip  
 21   
 22   
 23 /****** main test **********/  
 24 int main(void)  
 25 {  
 26     char ip[IP_SIZE];  
 27     char mac[MAC_SIZE];  
 28     const char *test_domain = "www.baidu.com";  
 29     const char *test_eth = "eth0";  
 30   
 31     get_ip_by_domain(test_domain, ip);  
 32     printf("%s ip: %s\n", test_domain, ip);  
 33   
 34     get_local_mac(test_eth, mac);  
 35     printf("local %s mac: %s\n", test_eth, mac);  
 36   
 37     get_local_ip(test_eth, ip);  
 38     printf("local %s ip: %s\n", test_eth, ip);  
 39   
 40     return 0;  
 41 }  
 42   
 43 // 根据域名获取ip  
 44 int get_ip_by_domain(const char *domain, char *ip)  
 45 {  
 46     char **pptr;  
 47     struct hostent *hptr;  
 48   
 49     hptr = gethostbyname(domain);  
 50     if(NULL == hptr)  
 51     {  
 52         printf("gethostbyname error for host:%s/n", domain);  
 53         return -1;  
 54     }  
 55   
 56     for(pptr = hptr->h_addr_list ; *pptr != NULL; pptr++)  
 57     {  
 58         if (NULL != inet_ntop(hptr->h_addrtype, *pptr, ip, IP_SIZE) )  
 59         {  
 60             return 0; // 只获取第一个 ip  
 61         }  
 62     }  
 63   
 64     return -1;  
 65 }  
 66   
 67 // 获取本机mac  
 68 int get_local_mac(const char *eth_inf, char *mac)  
 69 {  
 70     struct ifreq ifr;  
 71     int sd;  
 72       
 73     bzero(&ifr, sizeof(struct ifreq));  
 74     if( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
 75     {  
 76         printf("get %s mac address socket creat error\n", eth_inf);  
 77         return -1;  
 78     }  
 79       
 80     strncpy(ifr.ifr_name, eth_inf, sizeof(ifr.ifr_name) - 1);  
 81   
 82     if(ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)  
 83     {  
 84         printf("get %s mac address error\n", eth_inf);  
 85         close(sd);  
 86         return -1;  
 87     }  
 88   
 89     snprintf(mac, MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",  
 90         (unsigned char)ifr.ifr_hwaddr.sa_data[0],   
 91         (unsigned char)ifr.ifr_hwaddr.sa_data[1],  
 92         (unsigned char)ifr.ifr_hwaddr.sa_data[2],   
 93         (unsigned char)ifr.ifr_hwaddr.sa_data[3],  
 94         (unsigned char)ifr.ifr_hwaddr.sa_data[4],  
 95         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);  
 96   
 97     close(sd);  
 98       
 99     return 0;  
100 }  
101   
102   
103 // 获取本机ip  
104 int get_local_ip(const char *eth_inf, char *ip)  
105 {  
106     int sd;  
107     struct sockaddr_in sin;  
108     struct ifreq ifr;  
109   
110     sd = socket(AF_INET, SOCK_DGRAM, 0);  
111     if (-1 == sd)  
112     {  
113         printf("socket error: %s\n", strerror(errno));  
114         return -1;        
115     }  
116   
117     strncpy(ifr.ifr_name, eth_inf, IFNAMSIZ);  
118     ifr.ifr_name[IFNAMSIZ - 1] = 0;  
119       
120     // if error: No such device  
121     if (ioctl(sd, SIOCGIFADDR, &ifr) < 0)  
122     {  
123         printf("ioctl error: %s\n", strerror(errno));  
124         close(sd);  
125         return -1;  
126     }  
127   
128     memcpy(&sin, &ifr.ifr_addr, sizeof(sin));  
129     snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));  
130   
131     close(sd);  
132     return 0;  
133 }  

 

测试运行

结果如下:

 

 

ifreq 结构体分析和使用:

 1 struct ifreq
 2 {
 3 #define IFHWADDRLEN 6
 4  union
 5  {
 6   char ifrn_name[IFNAMSIZ];  
 7  } ifr_ifrn;
 8  
 9  union {
10   struct sockaddr ifru_addr;
11   struct sockaddr ifru_dstaddr;
12   struct sockaddr ifru_broadaddr;
13   struct sockaddr ifru_netmask;
14   struct  sockaddr ifru_hwaddr;
15   short ifru_flags;
16   int ifru_ivalue;
17   int ifru_mtu;
18   struct  ifmap ifru_map;
19   char ifru_slave[IFNAMSIZ]; 
20   char ifru_newname[IFNAMSIZ];
21   void __user * ifru_data;
22   struct if_settings ifru_settings;
23  } ifr_ifru;
24 };
25 
26 #define ifr_name ifr_ifrn.ifrn_name 
27 #define ifr_hwaddr ifr_ifru.ifru_hwaddr 
28 #define ifr_addr ifr_ifru.ifru_addr 
29 #define ifr_dstaddr ifr_ifru.ifru_dstaddr 
30 #define ifr_broadaddr ifr_ifru.ifru_broadaddr 
31 #define ifr_netmask ifr_ifru.ifru_netmask 
32 #define ifr_flags ifr_ifru.ifru_flags 
33 #define ifr_metric ifr_ifru.ifru_ivalue 
34 #define ifr_mtu  ifr_ifru.ifru_mtu 
35 #define ifr_map  ifr_ifru.ifru_map 
36 #define ifr_slave ifr_ifru.ifru_slave 
37 #define ifr_data ifr_ifru.ifru_data 
38 #define ifr_ifindex ifr_ifru.ifru_ivalue 
39 #define ifr_bandwidth ifr_ifru.ifru_ivalue    
40 #define ifr_qlen ifr_ifru.ifru_ivalue 
41 #define ifr_newname ifr_ifru.ifru_newname 
42 #define ifr_settings ifr_ifru.ifru_settings 

 

 

基本介绍: 

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

 

举例说明:

在Linux系统中,ifconfig命令是通过ioctl接口与内核通信,例如,当系统管理员输入如下命令来改变接口eth0的MTU大小:

    ifconfig eth0 mtu 1250

ifconfig命令首先打开一个socket,然后通过系统管理员输入的参数初始化一个数据结构,并通过ioctl调用将数据传送到内核。SIOCSIFMTU是命令标识符。

    struct ifreq data;
    fd = socket(PF_INET, SOCK_DGRAM, 0);
    < ... initialize "data" ...>
    err = ioctl(fd, SIOCSIFMTU, &data);

 

posted @ 2017-02-21 19:43  Boblim  阅读(15764)  评论(0编辑  收藏  举报