1 主要数据结构定义
(1)重要结构体
1 struct pcap_if//网络接口列表的一个节点 一个网络接口就是一个结点 方便链表 2 { 3 struct pcap_if *next;//网络接口节点 4 char *name;//网络接口名字 5 struct pcap_addr *address;//网络接口地址 6 bpf_u_int32 flags;//标记 7 char *description;//描述信息 8 } 9 10 typedefstruct pcap_ifpcap_if_t; 11 12 typedef struct pcap_addr pcap_addrt//描述网络接口地址 13 { 14 struct pcap_addr *next;//下一个地址 15 struct sockaddr *addr;//接口地址 16 struct sockaddr *netmask;//子网掩码 17 struct sockaddr *broadaddr;//广播地址 18 struct sockaddr *dstaddr;//目标地址 19 }
(2)pcap_findalldevs_ex理解
1 int pcap_findalldevs_ex(char* source, struct pcap_rmtauth *auth, pcap_if_t** alldevs, char* errbuf )
这个函数是’pcap_findalldevs()’的一个超集。’pcap_findalldevs()’比较老,他只允许列出本地机器上的设备。然而,’pcap_findalldevs_ex()’除了可以列出本地及其上的设备,还可以列出远程机器上的设备。此外,它还能列出所有可用的pcap文件到指定的文件夹。’pcap_findalldevs_ex()’是平台无关的,然而它以来于标准的’pcap_findalldevs()’来获得本地机器的地址。pcap_findalldevs_ex()中的source决定的,sourse指定需要监控的网络适配器。他有特定的伪语法:
- file://folder/[列出指定文件夹中的所有文件]
- rpcap://[列出所有本地的适配器]
- rpcap://host:port/[列出远程主机上的可用的设备]
注意:port和host参数可以是数字形式也可以是字符形式
host (字符):例如: host.foo.bar
- host (数字 IPv4): 例如: 10.11.12.13
- host (IPv6型的IPv4数字形式): 例如: [10.11.12.13]
- host (数字 IPv6): 例如: [1:2:3::4]
- port: 也可以是数字 (例如:'80') 或字符 (例如: 'http')
下面举一些实际例子:
- rpcap://host.foo.bar/devicename [全部都是字符形式的,没有端口号]
- rpcap://host.foo.bar:1234/devicename [全部都是字符形式的,有端口号]
- rpcap://10.11.12.13/devicename [IPv4 的数字形式,没有端口号]
- rpcap://10.11.12.13:1234/devicename [IPv4 的数字形式,有端口号]
- rpcap://[10.11.12.13]:1234/devicename [IPv6格式的IPv4数字形式 ,有端口号]
- rpcap://[1:2:3::4]/devicename [IPv6数字形式,没有端口号]
- rpcap://[1:2:3::4]:1234/devicename [IPv6数字形式,有端口号]
- rpcap://[1:2:3::4]:http/devicename [IPv6数字形式,端口号是字符形式]
(3)pcap_addr_t *a;理解
iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));//这句话的相关由来就是下面三个结构体
1 typedef struct sockaddr_in { 2 3 #if(_WIN32_WINNT < 0x0600) 4 short sin_family; 5 #else //(_WIN32_WINNT < 0x0600) 6 ADDRESS_FAMILY sin_family; 7 #endif //(_WIN32_WINNT < 0x0600) 8 9 USHORT sin_port; 10 IN_ADDR sin_addr; 11 CHAR sin_zero[8]; 12 } SOCKADDR_IN, *PSOCKADDR_IN; 13 14 struct pcap_addr { 15 struct pcap_addr *next; 16 struct sockaddr *addr; /* address */ 17 struct sockaddr *netmask; /* netmask for that address */ 18 struct sockaddr *broadaddr; /* broadcast address for that address */ 19 struct sockaddr *dstaddr; /* P2P destination address for that address */ 20 }; 21 22 typedef struct in_addr { 23 union { 24 struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b; 25 struct { USHORT s_w1,s_w2; } S_un_w; 26 ULONG S_addr; 27 } S_un; 28 #define s_addr S_un.S_addr /* can be used for most tcp & ip code */ 29 #define s_host S_un.S_un_b.s_b2 // host on imp 30 #define s_net S_un.S_un_b.s_b1 // network 31 #define s_imp S_un.S_un_w.s_w2 // imp 32 #define s_impno S_un.S_un_b.s_b4 // imp # 33 #define s_lh S_un.S_un_b.s_b3 // logical host 34 } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR; 35 36 #endif
2 基本例子 获取已经安装设备的高级信息
#include "pcap.h" 2 3 #ifndef WIN32 4 #include <sys/socket.h> 5 #include <netinet/in.h> 6 #else 7 #include <winsock.h> 8 #endif 9 10 11 // 函数原型 12 void ifprint(pcap_if_t *d); 13 char *iptos(u_long in); 14 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen); 15 16 17 int main() 18 { 19 pcap_if_t *alldevs; 20 pcap_if_t *d; 21 char errbuf[PCAP_ERRBUF_SIZE + 1]; 22 char source[PCAP_ERRBUF_SIZE + 1]; 23 24 printf("Enter the device you want to list: " 25 "rpcap:// ==> lists interfaces in the local machine " 26 "rpcap://hostname:port ==> lists interfaces in a remote machine " 27 " (rpcapd daemon must be up and running " 28 " and it must accept 'null' authentication) " 29 "file://foldername ==> lists all pcap files in the give folder " 30 "Enter your choice: "); 31 32 fgets(source, PCAP_ERRBUF_SIZE, stdin); 33 source[PCAP_ERRBUF_SIZE] = '