zoukankan      html  css  js  c++  java
  • WinPcap笔记2之获取已经安装设备的高级信息

    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 }
    View Code

    (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] = '';
     34 
     35     /* 获得接口列表 */
     36     if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
     37     {
     38         fprintf(stderr, "Error in pcap_findalldevs: %s
    ", errbuf);
     39         exit(1);
     40     }
     41 
     42     /* 扫描列表并打印每一项 */
     43     for (d = alldevs; d; d = d->next)
     44     {
     45         ifprint(d);
     46     }
     47 
     48     pcap_freealldevs(alldevs);
     49     getchar();
     50     return 1;
     51 }
     52 
     53 
     54 
     55 /* 打印所有可用信息 */
     56 void ifprint(pcap_if_t *d)
     57 {
     58     pcap_addr_t *a;
     59     char ip6str[128];
     60 
     61     /* 设备名(Name) */
     62     printf("%s
    ", d->name);
     63 
     64     /* 设备描述(Description) */
     65     if (d->description)
     66         printf("	Description: %s
    ", d->description);
     67 
     68     /* Loopback Address*/
     69     printf("	Loopback: %s
    ", (d->flags & PCAP_IF_LOOPBACK) ? "yes" : "no");
     70 
     71     /* IP addresses */
     72     for (a = d->addresses; a; a = a->next) {
     73         printf("	Address Family: #%d
    ", a->addr->sa_family);
     74 
     75         switch (a->addr->sa_family)
     76         {
     77         case AF_INET:
     78             printf("	Address Family Name: AF_INET
    ");
     79             if (a->addr)
     80                 printf("	Address: %s
    ", iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
     81             if (a->netmask)
     82                 printf("	Netmask: %s
    ", iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
     83             if (a->broadaddr)
     84                 printf("	Broadcast Address: %s
    ", iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
     85             if (a->dstaddr)
     86                 printf("	Destination Address: %s
    ", iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
     87             break;
     88 
     89         case AF_INET6:
     90             printf("	Address Family Name: AF_INET6
    ");
     91             if (a->addr)
     92                 printf("	Address: %s
    ", ip6tos(a->addr, ip6str, sizeof(ip6str)));
     93             break;
     94 
     95         default:
     96             printf("	Address Family Name: Unknown
    ");
     97             break;
     98         }
     99     }
    100     printf("
    ");
    101 }
    102 
    103 
    104 
    105 /* 将数字类型的IP地址转换成字符串类型的 */
    106 #define IPTOSBUFFERS    12
    107 char *iptos(u_long in)
    108 {
    109     static char output[IPTOSBUFFERS][3 * 4 + 3 + 1];//3*4个数组+3个点+一个空字符结束
    110     static short which;
    111     u_char *p;
    112 
    113     p = (u_char *)&in;
    114     which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);//如果转换IP的个数大于总Buffer数,就从0开始. 
    115     sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
    116     return output[which];
    117 }
    118 
    119 char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
    120 {
    121     socklen_t sockaddrlen;
    122 
    123 #ifdef WIN32
    124     sockaddrlen = sizeof(struct sockaddr_in6);
    125 #else
    126     sockaddrlen = sizeof(struct sockaddr_storage);
    127 #endif
    128 
    129 
    130     if (getnameinfo(sockaddr,
    131         sockaddrlen,
    132         address,
    133         addrlen,
    134         NULL,
    135         0,
    136         NI_NUMERICHOST) != 0) address = NULL;
    137 
    138     return address;
    139 }
    View Code
  • 相关阅读:
    redis接入sentinelPool的配置
    02.Redis主从集群的Sentinel配置
    淘宝大秒系统设计详解
    关于Thread.currentThread()和this的差异
    App开放接口api安全性—Token签名sign的设计与实现
    使用Spring Session做分布式会话管理
    PowerDesigner 15.1 安装步骤详细图解及破解
    解密ThreadLocal
    深入分析 ThreadLocal 内存泄漏问题
    一个经典例子让你彻彻底底理解java回调机制
  • 原文地址:https://www.cnblogs.com/lanjianhappy/p/6667162.html
Copyright © 2011-2022 走看看