天天看點

winPcap_4_擷取已安裝裝置的進階資訊

由 pcap_findalldevs_ex() 傳回的每一個 pcap_if 結構體,都包含一個 pcap_addr 結構體,這個結構體由如下元素組成:

  • 一個位址清單
  • 一個掩碼清單 (each of which corresponds to an entry in the addresses list).
  • 一個廣播位址清單 (each of which corresponds to an entry in the addresses list).
  • 一個目的位址清單 (each of which corresponds to an entry in the addresses list).

另外,函數 pcap_findalldevs_ex() 還能 傳回遠端擴充卡資訊 和 一個位于所給的本地檔案夾的pcap檔案清單。

下面的範例使用了ifprint()函數來列印出 pcap_if 結構體中所有的内容。程式對每一個由 pcap_findalldevs_ex() 函數傳回的pcap_if,都調用ifprint()函數來實作列印。

winPcap_4_擷取已安裝裝置的進階資訊
winPcap_4_擷取已安裝裝置的進階資訊
1 #include "pcap.h"
  2 #pragma comment(lib, "wpcap.lib")
  3 #pragma comment(lib, "Packet.lib")
  4 #pragma comment(lib, "wsock32.lib")
  5 
  6 
  7 
  8 #ifndef WIN32
  9     #include <sys/socket.h>
 10     #include <netinet/in.h>
 11 #else
 12     #include <winsock.h>
 13 #endif
 14 
 15 
 16 // 函數原型
 17 void ifprint(pcap_if_t *d);
 18 char *iptos(u_long in);
 19 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);
 20 
 21 
 22 int main()
 23 {
 24   pcap_if_t *alldevs;
 25   pcap_if_t *d;
 26   char errbuf[PCAP_ERRBUF_SIZE+1];
 27   char source[PCAP_ERRBUF_SIZE+1];
 28 
 29   printf("Enter the device you want to list:\n"
 30             "rpcap://              ==> lists interfaces in the local machine\n"
 31             "rpcap://hostname:port ==> lists interfaces in a remote machine\n"
 32             "                          (rpcapd daemon must be up and running\n"
 33             "                           and it must accept \'null\' authentication)\n"
 34             "file://foldername     ==> lists all pcap files in the give folder\n\n"
 35             "Enter your choice: ");
 36 
 37   fgets(source, PCAP_ERRBUF_SIZE, stdin);
 38   source[PCAP_ERRBUF_SIZE] = \'\0\';
 39 
 40   /* 獲得接口清單 */
 41   if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
 42   {
 43     fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
 44     exit(1);
 45   }
 46 
 47   /* 掃描清單并列印每一項 */
 48   for(d=alldevs;d;d=d->next)
 49   {
 50     ifprint(d);
 51   }
 52 
 53   pcap_freealldevs(alldevs);
 54 
 55   return 1;
 56 }
 57 
 58 
 59 
 60 /* 列印所有可用資訊 */
 61 void ifprint(pcap_if_t *d)
 62 {
 63   pcap_addr_t *a;
 64   char ip6str[128];
 65 
 66   /* 裝置名(Name) */
 67   printf("%s\n",d->name);
 68 
 69   /* 裝置描述(Description) */
 70   if (d->description)
 71     printf("\tDescription: %s\n",d->description);
 72 
 73   /* Loopback Address*/
 74   printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
 75 
 76   /* IP addresses */
 77   for(a=d->addresses;a;a=a->next) {
 78     printf("\tAddress Family: #%d\n",a->addr->sa_family);
 79   
 80     switch(a->addr->sa_family)
 81     {
 82       case AF_INET:
 83         printf("\tAddress Family Name: AF_INET\n");
 84         if (a->addr)
 85           printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
 86         if (a->netmask)
 87           printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
 88         if (a->broadaddr)
 89           printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
 90         if (a->dstaddr)
 91           printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
 92         break;
 93 /*
 94       case AF_INET6:
 95         printf("\tAddress Family Name: AF_INET6\n");
 96         if (a->addr)
 97           printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
 98        break;
 99 */
100       default:
101         printf("\tAddress Family Name: Unknown\n");
102         break;
103     }
104   }
105   printf("\n");
106 }
107 
108 
109 
110 /* 将數字類型的IP位址轉換成字元串類型的 */
111 #define IPTOSBUFFERS    12
112 char *iptos(u_long in)
113 {
114     static char output[IPTOSBUFFERS][3*4+3+1];
115     static short which;
116     u_char *p;
117 
118     p = (u_char *)&in;
119     which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
120     sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
121     return output[which];
122 }
123 
124 
125 /*
126 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
127 {
128     socklen_t sockaddrlen;
129 
130     #ifdef WIN32
131     sockaddrlen = sizeof(struct sockaddr_in6);
132     #else
133     sockaddrlen = sizeof(struct sockaddr_storage);
134     #endif
135 
136 
137     if(getnameinfo(sockaddr, 
138         sockaddrlen, 
139         address, 
140         addrlen, 
141         NULL, 
142         0, 
143         NI_NUMERICHOST) != 0) address = NULL;
144 
145     return address;
146 }
147 */      

擷取已安裝裝置的進階資訊.c

  結果:

winPcap_4_擷取已安裝裝置的進階資訊

此處隻能顯示電腦的ipv4的網卡資訊,不知道為什麼不能有ipv6的代碼時,不能編譯通過,不知道是包不支援,還是系統不支援;

int pcap_findalldevs_ex  ( char *  source,  
  struct pcap_rmtauth *  auth,  
  pcap_if_t **  alldevs,  
  char *  errbuf   
 )       

  ·該函數請檢視前一篇;

struct pcap_rmtauth{
  int    type
     //Type of the authentication required.
  char *    username
     //Zero-terminated string containing the username that has to be used on the remote machine for authentication.
  char *    password
     //Zero-terminated string containing the password that has to be used on the remote machine for authentication. 
};      

typedef struct pcap_if pcap_if_t;

struct  pcap_if {
    pcap_if *    next
    //if not NULL, a pointer to the next element in the list; NULL for the last element of the list
    char *    name
    //a pointer to a string giving a name for the device to pass to pcap_open_live()
    char *    description
    //if not NULL, a pointer to a string giving a human-readable description of the device
    pcap_addr *    addresses
    //a pointer to the first element of a list of addresses for the interface
    u_int    flags
    //PCAP_IF_ interface flags. Currently the only possible flag is PCAP_IF_LOOPBACK, that is set if the interface is a loopback interface.
};      

typedef struct pcap_addr pcap_addr_t;

struct  pcap_addr
{
    pcap_addr *    next
    //if not NULL, a pointer to the next element in the list; NULL for the last element of the list
    sockaddr *    addr
    //a pointer to a struct sockaddr containing an address
    sockaddr *    netmask
    //if not NULL, a pointer to a struct sockaddr that contains the netmask corresponding to the address pointed to by addr.
    sockaddr *    broadaddr
    //if not NULL, a pointer to a struct sockaddr that contains the broadcast address corre­ sponding to the address pointed to by addr; may be null if the interface doesn\'t support broadcasts
    sockaddr *    dstaddr
    //if not NULL, a pointer to a struct sockaddr that contains the destination address corre­ sponding to the address pointed to by addr; may be null if the interface isn\'t a point- to-point interface
};      
struct sockaddr {
    unsigned short sa_family;
    char           sa_data[14];
};      

   ·詳細的請看前面的socket程式設計;

struct sockaddr_in{
    short                 sin_family;
    unsigned short        sin_port;
    struct   in_addr      sin_addr;
    char                  sin_zero[8];
};      

in_addr

The in_addr structure represents a host by its Internet address.

struct in_addr {
  union {
          struct { u_char s_b1,s_b2,s_b3,s_b4; }   S_un_b;
          struct { u_short s_w1,s_w2; }            S_un_w;
          u_long                                   S_addr;
  } S_un;
};      

Members

S_un_b
Address of the host formatted as four u_chars.
S_un_w
Address of the host formatted as two u_shorts.
S_addr
Address of the host formatted as a u_long. 

fgets, fgetws

Get a string from a stream.

char *fgets( char *string, int n, FILE *stream );

wchar_t *fgetws( wchar_t *string, int n, FILE *stream );      
winPcap_4_擷取已安裝裝置的進階資訊