先貼上代碼網絡
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include "pcap.h" 5 #include <winsock2.h> 6 7 typedef struct sockaddr_in sockad; 8 9 /* 從tcptraceroute數字IP地址轉換爲字符串 */ 10 #define IPTOSBUFFERS 12 11 char *iptos(u_long in) 12 { 13 static char output[IPTOSBUFFERS][3*4+3+1]; 14 static short which; 15 u_char *p; 16 17 p = (u_char *)∈ 18 which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1); 19 sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); 20 return output[which]; 21 } 22 23 /* 給定的接口上打印全部可用的信息 */ 24 void ifprint(pcap_if_t *d) 25 { 26 pcap_addr_t *a; 27 28 /* 名字 */ 29 printf("%s\n",d->name); 30 31 /* 描述 */ 32 if (d->description) 33 printf("\t描述: %s\n",d->description); 34 35 /* 環回地址*/ 36 printf("\t環回: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no"); 37 38 /* IP addresses */ 39 for(a=d->addresses;a;a=a->next) { 40 printf("\tAddress Family: #%d\n",a->addr->sa_family); 41 42 switch(a->addr->sa_family) 43 { 44 case AF_INET: 45 printf("\tAddress Family Name: AF_INET\n"); 46 if (a->addr) 47 printf("\tIP地址: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr)); 48 if (a->netmask) 49 printf("\t子網掩碼: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr)); 50 if (a->broadaddr) 51 printf("\t廣播地址: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr)); 52 if (a->dstaddr) 53 printf("\t目標地址: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr)); 54 break; 55 default: 56 printf("\tAddress Family Name: Unknown\n"); 57 break; 58 } 59 } 60 printf("\n"); 61 } 62 63 int main() 64 { 65 pcap_if_t *alldevs; 66 pcap_if_t *d; 67 char errbuf[PCAP_ERRBUF_SIZE+1]; 68 69 /* 獲取設備列表 */ 70 if (pcap_findalldevs(&alldevs, errbuf) == -1) 71 { 72 fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); 73 exit(1); 74 } 75 for(d=alldevs;d;d=d->next) 76 { 77 ifprint(d); 78 } 79 return 0; 80 }
主要思路就是將獲得的 pcap_if_t 展開來看,先看一下pcap_if_t 的結構:數據結構
有五個屬性,名字、描述、pcap_addr類型的地址、flags、與指向下一個元素的指針。主要看看addresses:tcp
pacp_addr 一樣有五個屬性,ip地址、子網掩碼、廣播地址、目標地址。spa
sockaddr定義以下:指針
struct sockaddr {
unsigned short sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};code
通常sockaddr與sockaddr_in是能夠互相轉換的:htm
struct sockaddr_in {
short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
sin_family:指代協議族,可取值以下blog
AF_INET 2 IPv4
AF_INET6 23 IPv6
AF_UNSPEC 0 協議無關
sin_port:存儲端口號(使用網絡字節順序)
sin_addr:存儲IP地址,使用in_addr這個數據結構
sin_zero:是爲了讓sockaddr與sockaddr_in兩個數據結構保持大小相同而保留的空字節。接口
而其中IP地址的定義:ip
這裏先吧sockaddr強制轉換成aockaddr_in,而後取其中的sin_addr中的s_addr表示方式,而後將這個 unsigned long轉換成可讀的ip地址。
u_char是無符號字符類型,最大值是255。
輸出結果: