libpcap 库使用(一)
参考资料:
http://www.tcpdump.org/
DESCRIPTION
The Packet Capture library provides a high level interface to packet capture systems. All packets on the network, even those destined for other hosts, are accessible through this mechanism. It also supports saving captured packets to a ``savefile'', and reading packets from a ``savefile''.
Getting Started: The format of a pcap application
The first thing to understand is the general layout of a pcap sniffer. The flow of code is as follows:
- We begin by determining which interface we want to sniff on. In Linux this may be something like eth0, in BSD it may be xl1, etc. We can either define this device in a string, or we can ask pcap to provide us with the name of an interface that will do the job.
- Initialize pcap. This is where we actually tell pcap what device we are sniffing on. We can, if we want to, sniff on multiple devices(如何同时探测多个设备?). How do we differentiate between them? Using file handles. Just like opening a file for reading or writing, we must name our sniffing "session" so we can tell it apart from other such sessions.
- In the event that we only want to sniff specific traffic (e.g.: only TCP/IP packets, only packets going to port 23, etc) we must create a rule set, "compile" it, and apply it. This is a three phase process, all of which is closely related. The rule set is kept in a string, and is converted into a format that pcap can read (hence compiling it.) The compilation is actually just done by calling a function within our program; it does not involve the use of an external application. Then we tell pcap to apply it to whichever session we wish for it to filter.
- Finally, we tell pcap to enter it's primary execution loop. In this state, pcap waits until it has received however many packets we want it to. Every time it gets a new packet in, it calls another function that we have already defined. The function that it calls can do anything we want; it can dissect the packet and print it to the user, it can save it in a file, or it can do nothing at all.
- After our sniffing needs are satisfied, we close our session and are complete.
This is actually a very simple process. Five steps total, one of which is optional (step 3, in case you were wondering.) Let's take a look at each of the steps and how to implement them.
翻译:
1.确定要探测的dev;
#include <stdio.h>
#include <pcap.h> int main(int argc, char *argv[])
{
char *dev = argv[]; printf("Device: %s\n", dev);
return();
} //或者 #include <stdio.h>
#include <pcap.h> int main(int argc, char *argv[])
{
char *dev, errbuf[PCAP_ERRBUF_SIZE]; dev = pcap_lookupdev(errbuf); //随便找一个默认的interface
if (dev == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
return();
}
printf("Device: %s\n", dev);
return();
}
2.初始化pcap;
#include <pcap.h>
...
pcap_t *handle; handle = pcap_open_live(dev, BUFSIZ, , , errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return();
}
3.想要探测特定类型的报文,设置rule;
#include <pcap.h>
#include <stdio.h> int main(int argc, char *argv[])
{
pcap_t *handle; /* Session handle */
char *dev; /* The device to sniff on */
char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
struct bpf_program fp; /* The compiled filter */
char filter_exp[] = "port 23"; /* The filter expression */
bpf_u_int32 mask; /* Our netmask */
bpf_u_int32 net; /* Our IP */
struct pcap_pkthdr header; /* The header that pcap gives us */
const u_char *packet; /* The actual packet */ /* Define the device */
dev = pcap_lookupdev(errbuf);
if (dev == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
return();
}
/* Find the properties for the device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
net = ;
mask = ;
}
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, , , errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return();
}
/* Compile and apply the filter */
if (pcap_compile(handle, &fp, filter_exp, , net) == -) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
return();
}
if (pcap_setfilter(handle, &fp) == -) {
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
return();
}
/* Grab a packet */
packet = pcap_next(handle, &header);
/* Print its length */
printf("Jacked a packet with length of [%d]\n", header.len);
/* And close the session */
pcap_close(handle);
return();
}
4.报文接收;
//抓取单个报文
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h) //抓取多个报文
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); //回调函数
报文解析:
/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN 6 /* Ethernet header */
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
}; /* IP header */
struct sniff_ip {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4) /* TCP header */
typedef u_int tcp_seq; struct sniff_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
5.探测结束之后,关闭我们的session。
void pcap_close(pcap_t *p);
总结:
上述描述了一个通过libpcap实现抓包的基本框架
libpcap 库使用(一)的更多相关文章
- 基于 libpcap库的sniffer程序
基于 libpcap库的sniffer程序 Libpcap库是WireSharek和Tcpdump抓包程序的基础,利用libcap我们自己也可以实现自己的抓包程序,在网络上实时抓包分析,或者利用处理的 ...
- python3使用libpcap库进行抓包及数据处理
python版本:python 3.9 libpcap版本:1.11.0b7 python libpcap库是底层绑定c语言libpcap库的开发包,旨在提供python应用可访问的unix c li ...
- libpcap 库使用(三)
1.为了使收到的报文尽快给我们的处理程序,需要设置成immediate模式: int pcap_set_immediate_mode(pcap_t *p, int immediate_mode);
- libpcap 库使用(二)
参考资料: http://www.tcpdump.org/manpages/pcap.3pcap.html 分类介绍了该lib的函数 Opening a capture handle for read ...
- 初识函数库libpcap
由于工作上的需要,最近简单学习了抓包函数库libpcap,顺便记下笔记,方便以后查看 一.libpcap简介 libpcap(Packet Capture Library),即数据包捕获函数库, ...
- Linux链接库一(动态库,静态库,库放在什么路径下)
http://www.cppblog.com/wolf/articles/74928.html http://www.cppblog.com/wolf/articles/77828.html http ...
- GCC 编译使用动态链接库和静态链接库
1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...
- CentOS安装libpcap
1.安装GCC: yum -y install gcc-c++ 2.安装flex: yum -y install flex 没有flex,直接安装libpcap会提示"Your o ...
- libpcap使用
libpcap是一个网络数据包捕获函数库,功能非常强大,Linux下著名的tcpdump就是以它为基础的.今天我们利用它来完成一个我们自己的网络嗅探器(sniffer) 首先先介绍一下本次实验的环境: ...
随机推荐
- hibernate 性能问题
hibernate的目标是快速开发,数据库数据转换为java对象,业务逻辑中只使用对象进行处理. 性能开销有: 数据-对象转换时间,状态记录(是否为脏数据),sql优化(默认是对表字段全部更新,增加网 ...
- vue set
Vue 可以通过数组变异的方法可以控制数组的增减,却不能更改数组及对象,vue可以通过set方法改变数组的长度,改变某项的值,在组件中可以使用$set方法改变数组长度和某项的值 调用方法:Vue.se ...
- SQL语句中LEFT JOIN、JOIN、INNER JOIN、RIGHT JOIN的区别?
w3school的一套sql教程: http://www.w3school.com.cn/sql/index.asp left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录.r ...
- ROW_NUMBER() OVER(PARTITION BY ORDER BY )RN 只选一行
') ; SELECT DISTINCT PEGGED_SO_ID,PEGGED_SO_LINE_ID ,ITEM_ID ,QUANTITY ,LOCATION ,SITEID ,ROW_NUMBER ...
- date命令转换日期命令提示date: illegal time format
问题:运行date命令抛错 date -j -f "%a %b %d %T %Z %Y" "Sat Sep 29 11:33:00 CST 2018" &quo ...
- commit 流程
COMMIT是一个非常快的操作,当我们发布commit命令时,真正困难的动作已经完成,在数据库中已经执行了数据更改,所以已经完成了99%的任务,例如:下列操作已经产生: 1.在SGA(Buffer C ...
- PHP从规定字符中生成固定位数随即串
}
- CUDA error 100 & Decoder not initialized
项目中用cuda解码时候遇到该错误,这是调用cuda相关库中一些so库版本错误造成的.
- 查看linux发行版版本
可以通过查看/etc/issue文件查看发行版版本号,不论系统是redhat\suse\debian
- DBCP连接数据库了解一下
---恢复内容开始--- package com.kevin.Utils; import javax.sql.DataSource; import org.apache.commons.dbcp.Ba ...