1 主要数据结构定义

(1)重要结构体

 struct pcap_if//网络接口列表的一个节点 一个网络接口就是一个结点 方便链表
{
struct pcap_if *next;//网络接口节点
char *name;//网络接口名字
struct pcap_addr *address;//网络接口地址
bpf_u_int32 flags;//标记
char *description;//描述信息
} typedefstruct pcap_ifpcap_if_t; typedef struct pcap_addr pcap_addrt//描述网络接口地址
{
struct pcap_addr *next;//下一个地址
struct sockaddr *addr;//接口地址
struct sockaddr *netmask;//子网掩码
struct sockaddr *broadaddr;//广播地址
struct sockaddr *dstaddr;//目标地址
}

(2)pcap_findalldevs_ex理解

 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));//这句话的相关由来就是下面三个结构体

 typedef struct sockaddr_in {

 #if(_WIN32_WINNT < 0x0600)
short sin_family;
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600) USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[];
} SOCKADDR_IN, *PSOCKADDR_IN; struct pcap_addr {
struct pcap_addr *next;
struct sockaddr *addr; /* address */
struct sockaddr *netmask; /* netmask for that address */
struct sockaddr *broadaddr; /* broadcast address for that address */
struct sockaddr *dstaddr; /* P2P destination address for that address */
}; typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr /* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR; #endif

2 基本例子 获取已经安装设备的高级信息

#include "pcap.h"

   #ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock.h>
#endif // 函数原型
void ifprint(pcap_if_t *d);
char *iptos(u_long in);
char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen); int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
char errbuf[PCAP_ERRBUF_SIZE + ];
char source[PCAP_ERRBUF_SIZE + ]; printf("Enter the device you want to list:\n"
"rpcap:// ==> lists interfaces in the local machine\n"
"rpcap://hostname:port ==> lists interfaces in a remote machine\n"
" (rpcapd daemon must be up and running\n"
" and it must accept 'null' authentication)\n"
"file://foldername ==> lists all pcap files in the give folder\n\n"
"Enter your choice: "); fgets(source, PCAP_ERRBUF_SIZE, stdin);
source[PCAP_ERRBUF_SIZE] = '\0'; /* 获得接口列表 */
if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -)
{
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
exit();
} /* 扫描列表并打印每一项 */
for (d = alldevs; d; d = d->next)
{
ifprint(d);
} pcap_freealldevs(alldevs);
getchar();
return ;
} /* 打印所有可用信息 */
void ifprint(pcap_if_t *d)
{
pcap_addr_t *a;
char ip6str[]; /* 设备名(Name) */
printf("%s\n", d->name); /* 设备描述(Description) */
if (d->description)
printf("\tDescription: %s\n", d->description); /* Loopback Address*/
printf("\tLoopback: %s\n", (d->flags & PCAP_IF_LOOPBACK) ? "yes" : "no"); /* IP addresses */
for (a = d->addresses; a; a = a->next) {
printf("\tAddress Family: #%d\n", a->addr->sa_family); switch (a->addr->sa_family)
{
case AF_INET:
printf("\tAddress Family Name: AF_INET\n");
if (a->addr)
printf("\tAddress: %s\n", iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
if (a->netmask)
printf("\tNetmask: %s\n", iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
if (a->broadaddr)
printf("\tBroadcast Address: %s\n", iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
if (a->dstaddr)
printf("\tDestination Address: %s\n", iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
break; case AF_INET6:
printf("\tAddress Family Name: AF_INET6\n");
if (a->addr)
printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
break; default:
printf("\tAddress Family Name: Unknown\n");
break;
}
}
printf("\n");
} /* 将数字类型的IP地址转换成字符串类型的 */
#define IPTOSBUFFERS 12
char *iptos(u_long in)
{
static char output[IPTOSBUFFERS][ * + + ];//3*4个数组+3个点+一个空字符结束
static short which;
u_char *p; p = (u_char *)&in;
which = (which + == IPTOSBUFFERS ? : which + );//如果转换IP的个数大于总Buffer数,就从0开始.
sprintf(output[which], "%d.%d.%d.%d", p[], p[], p[], p[]);
return output[which];
} char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
{
socklen_t sockaddrlen; #ifdef WIN32
sockaddrlen = sizeof(struct sockaddr_in6);
#else
sockaddrlen = sizeof(struct sockaddr_storage);
#endif if (getnameinfo(sockaddr,
sockaddrlen,
address,
addrlen,
NULL,
,
NI_NUMERICHOST) != ) address = NULL; return address;
}

WinPcap笔记2之获取已经安装设备的高级信息的更多相关文章

  1. winPcap_4_获取已安装设备的高级信息

    由 pcap_findalldevs_ex() 返回的每一个 pcap_if 结构体,都包含一个 pcap_addr 结构体,这个结构体由如下元素组成: 一个地址列表 一个掩码列表 (each of ...

  2. 如何直接在 PC 端获取其它端设备的 UserAgent 信息呢?

    如何直接在 PC 端获取其它端设备的 UserAgent 信息呢 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5909615.html 序 希望收 ...

  3. MAVEN学习笔记-maven的获取和安装

      windows下maven的安装步骤:      1.下载压缩包http://maven.apache.org/download.cgi选择apache-maven-3.3.9-bin.zip下载 ...

  4. 关于Android的Build类——获取Android手机设备各种信息

    经常遇到要获取Android手机设备的相关信息,来进行业务的开发,比如经常会遇到要获取CPU的类型来进行so库的动态的下载.而这些都是在Android的Build类里面.相关信息如下: private ...

  5. Android之——获取手机安装的应用程序

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47114331 前几篇有关Android的博文中.向大家介绍了几个项目中经常使用的有 ...

  6. Android菜鸟笔记- 获取未安装的APK图标、版本号、包名、名称、是否安装、安装、打开

    周末闲来无事,把Android的基础知识拿出来复习复习,今天主题是<获取未安装的APK图标.版本号.包名.名称.是否安装.跳转安装.打开> 一.获取APK图标 通常读取APK的图标能够用, ...

  7. Unity获取安卓手机运营商,电量,wifi信号强度,本地Toast,获取已安装apk,调用第三方应用,强制自动重启本应用

    一个完整的游戏项目上线需要不断的完善优化,但是到了后期的开发不再仅仅是游戏了,它的复杂度远远大于纯粹的应用开发.首先必须要考虑的就是集成第三方SDK,支付这块渠道商已经帮你我们做好了,只需要按照文档对 ...

  8. iOS学习——获取iOS设备的各种信息

    不管是在Android开发还是iOS开发过程中,有时候我们需要经常根据设备的一些状态或信息进行不同的设置和性能配置,例如横竖屏切换时,电池电量低时,内存不够时,网络切换时等等,我们在这时候需要进行一些 ...

  9. go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE

    go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE Go语言是谷歌2009发布的专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速 ...

随机推荐

  1. lubuntu通过Smb访问Windows共享目录

    lubuntu通过Smb访问Windows共享目录 如果未安装Smb,先安装: apt-get install smbclient smbfs 安装后,查看共享主机上的共享目录: CentOS/Red ...

  2. 洛谷P2814 家谱(gen)

    题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. 输入输出格式 输入格式: 输入由多行组成,首先是一系列有关父子关系的描述,其中每一组 ...

  3. SHELL脚本运行的几种方法以及区别

    #1 给脚本加上执行权限chmod u+x a.sh, 而后就可以直接用全路径来执行脚本了,比如当前文件夹下用./a.sh,如果如果脚本所在目录在PATH环境变量之中, 则直接用a.sh即可(这和运行 ...

  4. ACM-ICPC 2018 徐州赛区网络预赛 D 杜教筛 前缀和

    链接 https://nanti.jisuanke.com/t/31456 参考题解  https://blog.csdn.net/ftx456789/article/details/82590044 ...

  5. hdu 4819 Mosaic

    无论是线段树还是树状数组维护最大值最小值的时候一定要注意,如果有修改操作的话,这个最小值和最大值的更新一定不能由原来的和修改的值得到,一定要重新查询一次,否则可能出现当前最小值是原来的未修改值,但事实 ...

  6. GPIO简介

    GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平. GPIO口一是 ...

  7. Java SpringMVC实现PC端网页微信扫码支付完整版

    一:前期微信支付扫盲知识 前提条件是已经有申请了微信支付功能的公众号,然后我们需要得到公众号APPID和微信商户号,这个分别在微信公众号和微信支付商家平台上面可以发现.其实在你申请成功支付功能之后,微 ...

  8. IntelliJ 中类似于Eclipse ctrl+q的是Ctrl+Shift+Backspace

    IntelliJ 中类似于Eclipse ctrl+q的是Ctrl+Shift+Backspace 回到刚刚编辑的地方: ctrl+alt+Left 是回到刚刚浏览的地方,不一定是编辑的地方,可能已经 ...

  9. 改动Android启动画面

    一.Android的启动步骤 1.启动Linux 2.载入Android 3.显示Android桌面 二.分析 Android载入开机动画的源代码文件是: /opt/android4.3/framew ...

  10. 谈一谈关于NODE里的N管理

    模块可能与当前的NODE版本不和,NODE升级问题? 一切尽在掌握 1.首先设置好PATH(你安装的目录) Debian系列: sudo gedit /etc/profile Redhat系列: su ...