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) 首先先介绍一下本次实验的环境: ...
随机推荐
- 2017面向对象程序设计(Java) 第1周学习指导及要求(2017.8.24-2017.8.27)
2017面向对象程序设计(Java) 第1周学习指导及要求(2017.8.24-2017.8.27) 学习目标 了解课程上课方式及老师教学要求,掌握课程学习必要的软件工具: 简单了解Java特点及 ...
- Bootstrap 辅助类
[Bootstrap 辅助类] 1.背景色 2. <p>插入符实例 <span class="caret"></span> </p> ...
- msf客户端渗透(十):社会工程学
启动社会工程学攻击组件 生成二维码攻击模块 输入你想生成二维码的url,这里做演示用www.baidu.com 二维码生成后,在这个路径下 生成u盘,DVD的多媒体攻击载荷 通过修改autorun.i ...
- 【C++】SGI-STL空间配置器
第一级配置器是对C的内存分配函数malloc,free,realloc的简单封装,用来分配大于128bytes的区块. 第二级配置器管理16个free-lists链表,各自管理8-128bytes的小 ...
- HOOK -- DLL的远程注入技术详解(1)
DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...
- css3修改滚动条样式
/*滚动条整体样式*/ /*高宽分别对应横竖滚动条的尺寸*/ .content-box::-webkit-scrollbar{ width: 4px; height: 4px; } /*滚动条里面小方 ...
- pta6-15(双端循环队列)
题目链接:https://pintia.cn/problem-sets/1101307589335527424/problems/1101313244863737856 题意:实现双段队列的队首出队. ...
- oracle数据库新建库
1.https://jingyan.baidu.com/article/76a7e409f3f37bfc3b6e15de.html 利用工具新建库. 2.创建时报错 out of memory 调节s ...
- JavaScript各种继承方式(四):原型式继承(prototypal inheritance)
一 原理 利用工具函数,通过原型对象直接得到父类的实例,并当作子类对实例使用. function inherit(obj){ // 在闭包中创建子类,对外隐藏子类 function Temp(){ } ...
- 最小生成树kruskal模板
算法思路:每次选取权值最小的边,判断这两个点是否在同一个集合内,如果在则跳过,如果不在则加上这条边的权值 可以使用并查集储存结点,可以快速判断结点是否在同一集合内. #include<iostr ...