一、首先下载libpcap包http://www.tcpdump.org/#latest-release
然后安装,安装完成后进入安装根目录的tests文件夹,编译运行findalldevstest.c(编译时加上-lpcap),查看是否发现所有网络设备。
二、下载wireshark观察抓包软件的各种功能
三、熟悉libpcap工作原理:
讯享网
四、了解libpcap抓包基本流程:

五、编程实现

未完待续。。。
PS:整理了一下libpcap常用的数据类型定义
- libpcap的类型定义:
0)、typedef int bpf_int32
1)、typedef u_int bpf_u_int32
32bit 的无类型整形;
2)、typedef pcap pcap_t
Descriptor of an open capture instance(一个打开的捕获实例的描述符?)这个结构对用户是不透明的。
3)、typedef pcap_dumper pcap_dumper_t
libpcap保存文件的描述符。
4)、typedef pcap_if pcap_if_t
网卡链表的一个元素;
5)、typedef pcap_addr pcap_addr_t
网卡地址的表示;
6)、typedef void (*pcap_handler)(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
- libpcap结构体
Libpcap库函数所必须的数据结构定义主要包含在pcap.h和pcap-int.h两个头文件中
int selectable_fd; / 在 socket 上,可以使用 select() 和 poll() 等 I/O 复用类型函数 /
int snapshot; / 用户期望的捕获数据包最大长度 /
int linktype; / 设备类型 /
int tzoff; / 时区位置,实际上没有被使用 /
int offset; / 边界对齐偏移量 /
int break_loop; / 强制从读数据包循环中跳出的标志 /
struct pcap_sf sf; / 数据包保存到文件的相关配置数据结构 /
struct pcap_md md; / 具体描述如下 /
int bufsize; / 读缓冲区的长度 /
u_char buffer; / 读缓冲区指针 */
u_char *bp;
int cc;
u_char pkt;
/ 相关抽象操作的函数指针,最终指向特定操作系统的处理函数 */
int (*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);
int (*setfilter_op)(pcap_t *, struct bpf_program *);
int (*set_datalink_op)(pcap_t *, int);
int (*getnonblock_op)(pcap_t *, char *);
int (*setnonblock_op)(pcap_t *, int, char *);
int (*stats_op)(pcap_t *, struct pcap_stat *);
void (*close_op)(pcap_t *);
/*如果 BPF 过滤代码不能在内核中执行,则将其保存并在用户空间执行 /
struct bpf_program fcode;
/ 函数调用出错信息缓冲区 /
char errbuf[PCAP_ERRBUF_SIZE + 1];
/ 当前设备支持的、可更改的数据链路类型的个数 /
int dlt_count;
/ 可更改的数据链路类型号链表,在 linux 下没有使用 */
int dlt_list;
/ 数据包自定义头部,对数据包捕获时间、捕获长度、真实长度进行描述 [pcap.h] /
struct pcap_pkthdr pcap_header;
};
/ 包含了捕获句柄的接口、状态、过滤信息 [pcap-int.h] /
struct pcap_md {
/ 捕获状态结构 [pcap.h] /
struct pcap_stat stat;
int use_bpf; / 如果为1,则代表使用内核过滤/
u_long TotPkts;
u_long TotAccepted; / 被接收数据包数目 /
u_long TotDrops; / 被丢弃数据包数目 /
long TotMissed; / 在过滤进行时被接口丢弃的数据包数目 */

long OrigMissed; /在过滤进行前被接口丢弃的数据包数目/
#ifdef linux
int sock_packet; /* 如果为 1,则代表使用 2.0 内核的 SOCK_PACKET 模式 /
int timeout; / pcap_open_live() 函数超时返回时间/
int clear_promisc; / 关闭时设置接口为非混杂模式 /
int cooked; / 使用 SOCK_DGRAM 类型 /
int lo_ifindex; / 回路设备索引号 */
char device; / 接口设备名称 /
/ 以混杂模式打开 SOCK_PACKET 类型 socket 的 pcap_t 链表*/
struct pcap next;
#endif
};
/ [pcap-bpf.h] /
struct bpf_program {
u_int bf_len; / BPF 代码中谓词判断指令的数目 */
struct bpf_insn bf_insns; / 第一个谓词判断指令 /
};
/ 谓词判断指令结构 /
struct bpf_insn {
u_short code;
u_char jt;
u_char jf;
bpf_int32 k;
};
(3)
/usr/include/net/bpf.h
5)、
6)、dump文件格式
首先是Dump文件头
};
然后是每一个包的包头和数据
struct pcap_pkthdr
{
struct timeval ts; / 捕获时间戳 /
bpf_u_int32 caplen; / 捕获到数据包的长度 /
bpf_u_int32 len; / 数据包的真正长度 /
}
/ 单个数据包结构,包含数据包元信息和数据信息 /
struct singleton [pcap.c]
{
struct pcap_pkthdr hdr; / libpcap 自定义数据包头部 */
const u_char * pkt; /* 指向捕获到的网络数据 */
};
7)、pcap_if (libpcap 自定义的接口信息链表 [pcap.h])
struct pcap_if
{
struct pcap_if *next;
char name; / 接口设备名 */
char description; / 接口描述 */
/*接口的 IP 地址, 地址掩码, 广播地址,目的地址 /
struct pcap_addr addresses;
bpf_u_int32 flags; / 接口的参数 */
};
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/157444.html