pcap_compile

使用方法

#include<pcap.h>int pcap_comile(pcap_t *p,struct bpf_program *fp,const char *str,int optimize, bpf_u_int32 netmask);

参数及函数说明

这个函数将str编译为一个过滤程序(filter program),str的语法在pcap-filter中进行了定义。fp是一个指向bpf_program结构体的指针,其存储了执行函数后的pcap过滤器结构。optimize控制是否对resulting code执行优化(1代表进行优化,0代表不进行优化)。netmask指定包捕获时对应网络的IPv4子网掩码,它仅在检查过滤程序中的IPv4广播地址时才会使用。If the netmask of the network on which packets are being captured isn’t known to the program, or if packets are being captured on the Linux “any” pseudo-interface that can capture on more than one network, a value of PCAP_NETMASK_UNKNOWN can be supplied; tests for IPv4 broadcast addresses will fail to compile, but all other tests in the filter program will be OK

返回值

当函数成功执行时,返回0,否则会返回PCAP_ERROR(-1)。如果返回了PCAP_ERROR,pcap_geterr(3PCAP) or pcap_perror(3PCAP) may be called with p as an argument to fetch or display the error text.

参考


pcap-filter

pcap_compile用于将一个字符串编译成一个filter program。最终获取的filter program可以被用于一些stream of packet,进而判断这些包是提供给pcap_loop(3PCAP),pcap_dispatch(3PCAP),pcap_next(3PCAP)还是pcap_next_ex(3PCAP)。

filter expression由一个或多个primitive组成。Primitives usually consist of an id (name or number) preceded by one or more qualifiers.总共有如下三种qualifier:

  • type:type qualifier表示id name或number所指的类型。可能的类型有host、net、port和portrange。例如,“host foo”、“net 128.3”、“port 20”、“portrange 6000-6008”。如果没有type qualifier,则假定其为host。
  • dir:dir qualifiers specify a particular transfer direction to and/or from id. Possible directions are src, dst, src or dst, src and dst, ra, ta, addr1, addr2, addr3, and addr4. E.g., src foo',dst net 128.3’, src or dst port ftp-data'. If there is no dir qualifier,src or dst’ is assumed. The ra, ta, addr1, addr2, addr3, and addr4 qualifiers are only valid for IEEE 802.11 Wireless LAN link layers.
  • proto:proto qualifiers restrict the match to a particular protocol. Possible protos are: ether, fddi, tr, wlan, ip, ip6, arp, rarp, decnet, tcp and udp. E.g., ether src foo',arp net 128.3’, tcp port 21',udp portrange 7000-7009’, wlan addr2 0:2:3:4:5:6'. If there is no proto qualifier, all protocols consistent with the type are assumed. E.g.,src foo’ means (ip or arp or rarp) src foo' (except the latter is not legal syntax),net bar’ means (ip or arp or rarp) net bar' andport 53’ means `(tcp or udp) port 53’.

[fddi is actually an alias for ether; the parser treats them identically as meaning ``the data link level used on the specified network interface’’. FDDI headers contain Ethernet-like source and destination addresses, and often contain Ethernet-like packet types, so you can filter on these FDDI fields just as with the analogous Ethernet fields. FDDI headers also contain other fields, but you cannot name them explicitly in a filter expression.

Similarly, tr and wlan are aliases for ether; the previous paragraph’s statements about FDDI headers also apply to Token Ring and 802.11 wireless LAN headers. For 802.11 headers, the destination address is the DA field and the source address is the SA field; the BSSID, RA, and TA fields aren’t tested.]

In addition to the above, there are some special `primitive’ keywords that don’t follow the pattern: gateway, broadcast, less, greater and arithmetic expressions. All of these are described below.

More complex filter expressions are built up by using the words and, or and not (or equivalently: &&',||’ and !' respectively) to combine primitives. E.g.,host foo and not port ftp and not port ftp-data’. To save typing, identical qualifier lists can be omitted. E.g., tcp dst port ftp or ftp-data or domain' is exactly the same astcp dst port ftp or tcp dst port ftp-data or tcp dst port domain’.

可使用的primitive有:

  • dst host host:当IPv4/v6的destination field是host时为真,host可以为address或name
  • src host host:当IPv4/v6的source field是host是为真
  • host host:当IPv4/v6的source或destination为host时为真
    Any of the above host expressions can be prepended with the keywords, ip, arp, rarp, or ip6 as in:
    ip host host
    这和如下的形式等同:
    ether proto \ip and host host
    如果host是一个有着多个IPv4地址的name,那么每个地址都会被检查看是否符合匹配
  • ether dst ehost:如果Ethernet的destination地址为ehost时为真。Ehost可以是一个来自于/etc/ethers的name,也可以是数字化表示的MAC地址,形式为"xx:xx:xx:xx:xx:xx", “xx.xx.xx.xx.xx.xx”, “xx-xx-xx-xx-xx-xx”, “xxxx.xxxx.xxxx”, “xxxxxxxxxxxx”, or various mixes of ‘:’, ‘.’, and ‘-’, where each “x” is a hex digit (0-9, a-f, or A-F).
  • ether src ehost:True if the Ethernet source address is ehost.
  • ether host ehost:True if either the Ethernet source or destination address is ehost.
  • gateway host:当包用host作为gateway时为真。例如,Ethernet source或destination address为host但IP source和IP destination都不是host。Host must be a name and must be found both by the machine’s host-name-to-IP-address resolution mechanisms (host name file, DNS, NIS, etc.) and by the machine’s host-name-to-Ethernet-address resolution mechanism (/etc/ethers, etc.). (An equivalent expression is
    ether host ehost and not host host
    which can be used with either names or numbers for host / ehost.) This syntax does not work in IPv6-enabled configuration at this moment.
  • dst net net
  • portrange port1-port2:当包的source或destination port在port1port2之间时为真(port1port2这两个值包含在内)。
    Any of the above port or port range expressions can be prepended with the keywords, tcp or udp, as in:
    tcp src port port
    这种情况下只匹配source port为port的TCP包

参考:

https://www.tcpdump.org/manpages/pcap-filter.7.html


pcap_lookupdev

char *pcap_lookupdev(char *errbuf)

返回第一个合适的,可被pcap_open_live()或pcap_lookupnet()函数调用的网络设备名指针。如果函数出错,则返回NULL,同时errbuf中存放相关的错误消息。


pcap_lookupnet

使用方法

#include<pcap.h>char errbuf[PCAP_ERRBUF_SIZE];int pcap_lookupnet(const char *device,bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf);

函数简介及参数

pcap_lookupnet()函数用于获取和网卡device绑定的IPv4 网络号(number)和子网掩码(mask)。netp以及maskp都是bpf_u_int32指针。

网络号和子网掩码都是以网络字节序存放的,比如一个IP为10.108.20.0,那么netp中存放的这个地址就是1338378。转化为二进制表示形式为:

数据的高位------------------>数据的低位
00000000 00010100 01101100 00001010

网络字节序采用大端表示,而主机字节序有用大端表示,也有用小端表示,因此要进行一步转化。

采用小端编址时,上面的数据为:

00001010 01101100 00010100 00000000

返回值

函数执行成功时返回0,执行失败时返回PCAP_ERROR(-1)。如果返回了PCAP_ERROR,此时errbuf会用适当的错误信息进行填充。

参考:

https://www.tcpdump.org/manpages/pcap_lookupnet.3pcap.html


pcap_loop

int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

其功能基本与pcap_dispatch()函数相同,但是多了一个cnt参数,这个参数告知pcap_loop应该嗅探到多少个包后返回(一个负值的含义是它应该一直嗅探,直到错误发生)。调用pcap_breakloop()函数也可以终止pcap_loop的执行。

第三个参数是一个回调函数指针,它必须是如下的形式:

void callback(u_char * userarg, const struct pcap_pkthdr * pkthdr, const u_char * packet)

其第一个参数是pcap_loop的最后一个参数,当收到足够数量的包后pcap_loop会调用callback回调函数,同时将pcap_loop的user参数传递给它。第二个参数是收到的数据包的pcap_pkthdr类型的指针,第三个参数是收到的数据包的数据。注意这个函数的返回值为void,因为pcap_loop()不知道如何处理一个回调返回值。


pcap_next

u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

第二个参数是保存收到的第一个数据包的pcap_pkthdr类型的指针。同时函数返回指向下一个数据包的u_char指针。


PCAP_NEXT_EX

使用方法

#include<pcap/pcap.h>int pcap_next_ex(pcap_t *p,struct pcap_pkthdr **pkt_header,const u_char **pkt_data);const u_char *pcap_next(pcap_t *p,struct pcap_pkthdr *h);

使用简介及参数

pcap_next_ex()读取下一个包并且会返回函数是否执行成功。如果读取包没有发生错误,那么pkt_header所指向的指针会被设定为指向这个包的pcap_pkhdr结构体,同时pkt_data所指向的指针会被设定为指向包中的数据部分。注意,结构体pcap_pkthdr以及包数据并不由调用者进行释放,同时它们也不保证在下次调用pcap_next_ex(), pcap_next(), pcap_loop(3PCAP), or pcap_dispatch(3PCAP)时仍有效,所以使用者在获取到了这个信息后,需要自己将信息进行拷贝。

pcap_next()函数读取下一个包(通过调用pcap_dispath()函数,其中cnt为1)并且返回一个u_char指针指向这个包中的数据部分。包中的数据不由调用者释放,同时它们也不保证在下次调用pcap_next_ex(), pcap_next(), pcap_loop(3PCAP), or pcap_dispatch(3PCAP)时仍有效,所以使用者在获取到了这个信息后,需要自己将信息进行拷贝。h指针指向的pcap_pkhdr数结构is filled with the appropriate values for the packet。

包中的数据字节以一个链路层首部为开始。链路层首部的格式由pcap_datalink(3PCAP)程序指明when handed the pcap_t value also passed to pcap_loop() or pcap_dispatch(). https://www.tcpdump.org/linktypes.html列出了pcap_datalink()可能返回的值并描述了和这些值对应的包的格式。 The value it returns will be valid for all packets received unless and until pcap_set_datalink(3PCAP) is called; after a successful call to pcap_set_datalink(), all subsequent packets will have a link-layer header of the type specified by the link-layer header type value passed to pcap_set_datalink().

Do NOT assume that the packets for a given capture or savefile will have any given link-layer header type, such as DLT_EN10MB for Ethernet. For example, the “any” device on Linux will have a link-layer header type of DLT_LINUX_SLL or DLT_LINUX_SLL2 even if all devices on the system at the time the “any” device is opened have some other data link type, such as DLT_EN10MB for Ethernet.

通过试验,在调用pcap_next_ex()之后系统会分配一部分内存(大概有500KB左右)供其使用,返回的报文内容存放在这部分内存中,不过这只是暂存,不可能将大量的数据内容放在这一部分内容中;通过调试后可以看到,pcap_next_ex()将返回的报文内容线性的存储在这一部分内存中,当数据量占满了这部分内存后,会从开始位置覆盖原有数据,所以如果想要保存报文内容,需要写入本地文件或者另外开辟内存空间存储。

返回值

当函数成功执行时并读取到包信息时,pcap_next_ex()返回1,0 if packets are being read from a live capture and the packet buffer timeout expired, PCAP_ERROR if an error occurred while reading the packet, and PCAP_ERROR_BREAK if packets are being read from a ``savefile’’ and there are no more packets to read from the savefile. If PCAP_ERROR is returned, pcap_geterr(3PCAP) or pcap_perror(3PCAP) may be called with p as an argument to fetch or display the error text.

pcap_next() returns a pointer to the packet data on success, and returns NULL if an error occurred, or if no packets were read from a live capture (if, for example, they were discarded because they didn’t pass the packet filter, or if, on platforms that support a packet buffer timeout that starts before any packets arrive, the timeout expires before any packets arrive, or if the file descriptor for the capture device is in non-blocking mode and no packets were available to be read), or if no more packets are available in a ``savefile.’’ Unfortunately, there is no way to determine whether an error occurred or not.

参考


pcap_open_live

pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)

获得用于捕获网络数据包的数据包捕获句柄。

  • device参数为指定打开的网络设备名(即网卡,在Linux 2.2及以后的版本中这个参数传入"any"或NULL可以被用于在所有接口上获取包)。
  • snaplen参数定义捕获数据的最大字节数(我们可以设置这个值来只抓每个数据包的首部,而不关心具体内容)。如果这个值小于被捕获的数据包的大小,则只显示前snaplen位
  • promisc参数指定是否打开混杂模式。如果打开混杂模式,那么网卡必须也要打开混杂模式,可以使用如下的命令打开eth0混杂模式:
    ifconfig eth0 promisc
  • to_ms参数指定需要等待的毫秒数(0代表不设置超时;在某些平台上,设置这个参数代表着我们可以在这个时间内获取一定的包后一起返回,所以建议使用一个非零值)
  • ,超过这个数值后,pcap_next等函数就会立即返回,0表示一直等待到有数据包到来。这是一个非负值,单位为millisecond。这个参数的含义是让捕捉程序没有必要看到一个数据包就返回,而是设定一个返回时间,这个时间内可能读取很多个数据包,然后一起返回
  • ebuf参数则仅在pcap_open_live()函数出错返回NULL时用于传递错误消息。

混杂模式与非混杂模式的区别:一般来说,非混杂模式的嗅探器中,主机仅嗅探那些跟它直接有关的通信,如发向它的,从它发出的,或经由它路由的等都会被嗅探器捕捉。而在混杂模式中则嗅探传输线路上的所有通信。在非交换式网络中,这将是整个网络的通信。这样做最明显的优点是使更多的包被嗅探到,但是在高负荷的网络中,主机的系统资源将消耗的非常严重。

函数成功执行时返回一个pcap_t*指针,如果函数执行失败,返回NULL。


PCAP_SETFILTER

#include<pcap.h>int pcap_setfilter(pcap_t *p, struct bpf_program *fp);

参数及使用说明

这个函数用于指定一个过滤程序(filter program)。fp是一个指向bpf_program结构体的指针,通常是调用pcap_compile()函数后返回的值。p通常是pcap_open_live()函数返回的结果。

返回值

函数执行成功时返回0,执行失败时返回PCAP_ERROR。
If PCAP_ERROR is returned, pcap_geterr(3PCAP) or pcap_perror(3PCAP) may be called with p as an argument to fetch or display the error text.

参考


pcap_set_immediate_mode

int pcap_set_immediate_mode(pcap_t *p,int immediate_mode);

pcap_set_immediate_mode将一个没有激活的捕获句柄设定为immediate模式。在immediate模式下,包在它们到达时就被送达而不经过缓存。如果immediate_mode参数非零,那么会将句柄设定为immediate模式,否则不会设定为immediate模式。

当函数执行成功时返回0,当对一个已经激活的句柄调用这个函数时会返回PCAP_ERROR_ACTIVATED

https://www.tcpdump.org/manpages/pcap_set_immediate_mode.3pcap.html


pcap_setnonblock

int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf);

当参数nonblock为非零值时,函数将一个捕获句柄设置为非阻塞模式,而当参数nonblock为0时取消一个捕获句柄的非阻塞模式。它对于“savefiles”没有影响。

在非阻塞模式下,任何尝试从捕获文件描述符中获取信息的pcap_dispatch、pcap_next_ex以及pcap_loop等函数,在当前没有可读包时,会立即返回0而不是一直阻塞等待新包的到来(如果是阻塞模式那么这些函数会一直阻塞到新包的到来)。(但是实验测试对pcap_next_ex函数,这个函数的设定是无效的,pcap_next_ex仍然会阻塞直到新包的到来)

pcap_loop(3PCAP) will loop forever, consuming CPU time when no packets are currently available; pacp_dispatch() should be used instead. pcap_next(3PCAP) will return NULL if there are no packets currently available to read; this is indistinguishable from an error, so pcap_next_ex() should be used instead.

当首次利用pcap_activate激活一个句柄或使用pcap_open_live打开一个句柄时,这个捕获句柄并未处于非阻塞模式,此时我们需要调用pcap_setnonblock来将它置于非阻塞模式。

当函数执行成功时返回0,失败时返回-1。

pcap_getnonblock()返回当前捕获文件描述符是否位于非阻塞状态,它对于“savefile”总返回0。如果发生了错误,那么那么返回PCAP_ERROR并且将错误信息填充进errbuf。

pcap简单使用和简单解释

libpcap中主要函数使用介绍相关推荐

  1. mariadb mysql 语法_Mariadb MySQL、Mariadb中GROUP_CONCAT函数使用介绍

    MySQL.Mariadb中GROUP_CONCAT 函数使用介绍 By:授客 QQ:1033553122 语法: GROUP_CONCAT([DISTINCT] column_name [ORDER ...

  2. java sessionid长度_php中session_id()函数详细介绍,会话id生成过程及session id长度

    php中session_id()函数原型及说明session_id()函数说明:stringsession_id([string$id])session_id() 可以用来获取/设置 当前会话 ID. ...

  3. php中session_id()函数详细介绍,会话id生成过程及session id长度

    php中session_id()函数原型及说明session_id()函数说明:stringsession_id([string$id])session_id() 可以用来获取/设置 当前会话 ID. ...

  4. SQL中 decode() 函数使用介绍

    [SQL]SQL中 decode() 函数介绍 主要作用:将查询结果翻译成其他值(即以其他形式表现出来) decode() 函数的语法: select decode(columnname,值1,翻译值 ...

  5. Python3.9标准库math中的函数汇总介绍(53个函数和5个常数)

    为了更好的用计算机帮助我们运算,首先要了解自己使用的库中有什么方法,否则就会做会多费力不讨好的重复工作. 本篇博文我们来了解Python标准库的math函数. 参考资料: Python3.9的math ...

  6. Oracle 中 LISTAGG 函数的介绍以及使用

    LISTAGG 函数介绍 listagg 函数是 Oracle 11.2 推出的新特性. 其主要功能类似于 wmsys.wm_concat 函数, 即将数据分组后, 把指定列的数据再通过指定符号合并. ...

  7. JS学习笔记——高级编程中compose函数的介绍和基本实现

    1.前言 在之前探讨redux的中间件的时候,applyMiddleware源码中有遇到过compose()函数,当时不太明白起作用,所以就上网好好查了一下,做了个总结. 2.普通函数 在函数式编程当 ...

  8. php 常用简单函数,PHP中常用函数简单介绍

    1. var_dump  打印变量的相关信息 void var_dump ( $expression [, 此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值.数组将递归展开值,通过缩进显 ...

  9. MySQL中字符串函数详细介绍

    MySQL字符串函数对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str)返回字符串str的 最左面字符的ASCII代码值.如果str是空字符串, 返回0.如果str是NULL,返回N ...

  10. java能用绝对值吗_Java中绝对值函数的介绍与其妙用

    一.绝对值函数使用说明 绝对值函数是jdk中math.java中的实现方法,其用来得到表达式的绝对值. 其实现非常简单,源码如下: /** * returns the absolute value o ...

最新文章

  1. xunsearch php,GitHub - ziyueit/xunsearch: 迅搜的一个PHP封装类
  2. scikit-learn一般实例之一:绘制交叉验证预测
  3. MySQL relay log 详细参数解释
  4. 关于 SAP 访问关键字的说明
  5. zemax设置 像方远心_[入门] [ZEMAX] [成像] 手把手教程:一个双高斯类镜头
  6. 《WinHex》误使用Ghost恢复系统恢复数据图文教程
  7. matlab随机欠采样,欠采样技术
  8. xp系统关于无线网络连接服务器,八步骤搞定XP系统无线网络设置问题
  9. 14-CompletableFuture异步编排
  10. Win10·不重装系统·扩充C盘
  11. golang实现最简单的麻将胡牌算法(不包括牌型,有需求后续可以更新牌型计算)
  12. ps4欧洲服务器注册,ps4pro注册港服教程
  13. python 函数enumerate用法
  14. python实现目标检测voc格式标签数据增强
  15. 数控木工机械和精美家具制作
  16. 阅读《精通Python爬虫框架Scrapy》
  17. 区块链游戏开发注意事项
  18. Discourse开源论坛搭建
  19. stm32流水灯c语言程序,stm32流水灯程序源码
  20. c语言程序个人实验报告,C语言程序设计实验报告(5)

热门文章

  1. python获取灰度图边界
  2. linux以http方式搭建git服务器
  3. linux日常检查,Linux日常检查的shell
  4. 实习踩坑之路:URL传参错误,导致后台查不到数据,但是不报错
  5. Java数值溢出问题以及简单的算法实例
  6. Android View的滚动原理简单解析
  7. ios上传闪退 php,iOS应用上架后出现闪退原因浅析
  8. 突发 , 谷歌官宣安卓改名了!
  9. 听说大家想补补算法和数据结构,给大家推荐一个GitHub 15k星的图文版开源项目...
  10. 百兆以太网口通信速率_千兆以太网的传输速度