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 }  

 

測試運行dom

結果以下:socket

 

 

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結構一般是用來保存全部接口的信息的。spa

 

舉例說明:.net

在Linux系統中,ifconfig命令是經過ioctl接口與內核通訊,例如,當系統管理員輸入以下命令來改變接口eth0的MTU大小:code

    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);

相關文章
相關標籤/搜索