由 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()函数来实现打印。
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 */
结果:
此处只能显示电脑的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 );