winPcap編程之獲取適配器詳細信息(三)

顯示適配器詳細信息

先貼上代碼網絡

 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 *)&in;
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

typedef struct in_addr {
   union {
   struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b;
   struct{ unsigned short s_w1, s_w2;} S_un_w;
   unsigned long S_addr;
  } S_un;
  } IN_ADDR;
闡述下in_addr的含義,很顯然它是一個存儲ip地址的 共用體有三種表達方式:
第一種用四個字節來表示IP地址的四個數字;
第二種用兩個雙字節來表示IP地址;
第三種用一個長整型來表示IP地址。

 這裏先吧sockaddr強制轉換成aockaddr_in,而後取其中的sin_addr中的s_addr表示方式,而後將這個 unsigned long轉換成可讀的ip地址。

u_char是無符號字符類型,最大值是255。

輸出結果:

相關文章
相關標籤/搜索