libpcap
函数调用顺序层次
pcap_open_live()
pcap_create() //通过device创建pcap结构体并初始化
pcap_create_interface() //不同的操作系统环境调用不同的接口函数
pcap_create_common() //动态分配pcap_t内存
initialize_ops() //初始化一系列回调函数和参数
pcap_set_snaplen()
pcap_set_promisc()
pcap_set_timeout()
p->oldstyle = 1;
pcap_activate() //执行pcap_activate_bpf()
pcap基本数据结构
//libpcap 1.74
struct pcap {
read_op_t read_op; /* Method to call to read packets on a live capture. */ int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **); /* Mtehod to call to read to read packets from a savefile. */ #ifdef WIN32 ADAPTER *adapter; LPPACKET Packet; int nonblock; #else int fd; int selectable_fd; #endif /* WIN32 */ int bufsize; /* Read buffer */ u_char *buffer; /* Read buffer */ u_char *bp; /* Read buffer */ int cc; /* Read buffer */ int break_loop; /* flag set to force break from packet-reading loop */ void *priv; /* private data for methods(不同的系统对应不同的结构体,linux 为 struct pcap_linux) */ int swapped; FILE *rfile; /* null if live capture, non-null if savefile */ int fddipad; struct pcap *next; /* list of open pcaps that need stuff cleared on close */ int version_major; int version_minor; int snapshot; /* 抓取一个数据报的最大长度 */ int linktype; /* Network linktype */ int linktype_ext; /* Extended information stored in the linktype field of a file */ int tzoff; /* timezone offset */ int offset; /* offset for proper alignment */ int activated; /* true if the capture is really started */ int oldstyle; /* if we're opening with pcap_open_live() */ struct pcap_opt opt;
u_char *pkt; /* Place holder for pcap_next(). */ pcap_direction_t direction; /* We're accepting only packets in this direction/these directions. */ int bpf_codegen_flags; /* Flags to affect BPF code generation. */ struct bpf_program fcode; /* Placeholder for filter code if bpf not in kernel. */ char errbuf[PCAP_ERRBUF_SIZE + 1]; int dlt_count; u_int *dlt_list; int tstamp_type_count; u_int *tstamp_type_list; int tstamp_precision_count; u_int *tstamp_precision_list; struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */ /* * More methods. */ activate_op_t activate_op; can_set_rfmon_op_t can_set_rfmon_op; inject_op_t inject_op; setfilter_op_t setfilter_op; setdirection_op_t setdirection_op; set_datalink_op_t set_datalink_op; getnonblock_op_t getnonblock_op; setnonblock_op_t setnonblock_op; stats_op_t stats_op; /* * Routine to use as callback for pcap_next()/pcap_next_ex(). */ pcap_handler oneshot_callback; #ifdef WIN32 /* * These are, at least currently, specific to the Win32 NPF * driver. */
setbuff_op_t setbuff_op; setmode_op_t setmode_op; setmintocopy_op_t setmintocopy_op; getadapter_op_t getadapter_op; #endif cleanup_op_t cleanup_op; };
//linux 下的priv
struct pcap_linux { u_int packets_read; /* count of packets read with recvfrom() */ long proc_dropped; /* packets reported dropped by /proc/net/dev */ struct pcap_stat stat; char *device; /* device name */ int filter_in_userland; /* must filter in userland */ int blocks_to_filter_in_userland; int must_do_on_close; /* stuff we must do when we close */ int timeout; /* timeout for buffering */ int sock_packet; /* using Linux 2.0 compatible interface */ int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */ int ifindex; /* interface index of device we're bound to */ int lo_ifindex; /* interface index of the loopback device */ bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */ char *mondevice; /* mac80211 monitor device we created */ u_char *mmapbuf; /* memory-mapped region pointer */ size_t mmapbuflen; /* size of region */ int vlan_offset; /* offset at which to insert vlan tags; if -1, don't insert */ u_int tp_version; /* version of tpacket_hdr for mmaped ring */ u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */ u_char *oneshot_buffer; /* buffer for copy of packet */ #ifdef HAVE_TPACKET3 unsigned char *current_packet; /* Current packet within the TPACKET_V3 block. Move to next block if NULL. */ int packets_left; /* Unhandled packets left within the block from previous call to pcap_read_linux_mmap_v3 in case of TPACKET_V3. */ #endif };
libpcap 中 linux 下的bfp
/* * Structure for "pcap_compile()", "pcap_setfilter()", etc.. */ struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; /* * The instruction(指令)structure. */ struct bpf_insn { u_short code; //操作码,可以实现数值运算、加载、比较等操作 u_char jt; //如果匹配成功跳转到的位置 u_char jf; //如果匹配失败跳转到的位置 bpf_u_int32 k; //参数字段,不同的操作码有不同的用途 };
常用函数
//函数名称:pcap_t *pcap_open_offline(const char *fname, char *errbuf) //函数功能:打开以前保存的 pcap 数据包,用于读取。 //函数位置:savefile.c //函数名称:pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname) //函数功能:打开用于保存捕获数据的文件,用于写入。 //函数位置:sf-pcap.c //函数名称:void pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) //函数功能:向pcap_dump_open()函数打开的文件输出一个数据包。 //函数位置:sf-pcap.c //函数名称:char *pcap_lookupdev (char *ebuf) //函数功能:用于返回可被pcap_open_live()或pcap_lookupnet()函数调用的网络设备名指针。 //函数位置:pcap-dos.c //函数名称:int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,bpf_u_int32 *netmask, char *errbuf) //函数功能:获得指定网络设备的网络好和掩码 //函数位置:pcap-dos.c //函数名称:int pcap_compile(pcap_t *p, struct bpf_program *program, const char *buf, int optimize, bpf_u_int32 mask) //函数功能:间buf中的字符串编译到过滤程序中。把 buf 编译到 program 中等待使用。 //函数位置:gencode.c //函数名称:static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) //函数功能:指定一个过滤器。 吧 fp 规则指定打 p 中等待使用。 //函数位置:pcap-bpf.c // ====== pcap.c ===== //函数名称:pcap_t *pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) //函数功能:获得用于捕获网络数据包的数据包捕获描述字。 //函数名称:int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) //函数功能:捕获并处理数据包。 //函数名称:int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) //函数功能:捕获并处理数据包,与pcap_dispatch有区别。 //函数名称:pcap_next(pcap_t *p, struct pcap_pkthdr *h) //函数功能:返回指向下一个数据包的 u_char 指针。 //函数名称:int pcap_datalink(pcap_t *p) //函数功能:返回数据链路层类型。 //函数名称:int pcap_snapshot(pcap_t *p) //函数功能:返回pcap_open_live()被调用后的 snapshot 值。 //函数名称:int pcap_is_swapped(pcap_t *p) //函数功能:返回当前主机系统的字节序和被打开文件的字节序是否相同。 //函数名称:int pcap_major_version(pcap_t *p) //函数功能:获取主版本号。 //函数名称:int pcap_minor_version(pcap_t *p) //函数功能:获取次版本号。 //函数名称:int pcap_stats(pcap_t *p, struct pcap_stat *ps) //函数功能:向pcap_stat结构体赋值 //函数名称:FILE *pcap_file(pcap_t *p) //函数功能:返回被打开的文件。 //函数名称:int pcap_fileno(pcap_t *p) //函数功能:返回被打开的文件描述符号码。 //函数名称:void pcap_perror(pcap_t *p, char *prefix) //函数功能:打印最后一个pcap_t错误消息到屏幕。 //函数名称:char *pcap_geterr(pcap_t *p) //函数功能:返回最后一个pcap_t错误信息。 //函数名称:const char * pcap_strerror(int errnum) //函数功能: //函数位置: //函数名称:void pcap_close(pcap_t *p) //函数功能:关闭pcap_t参数的相应文件,并释放资源。 //函数名称: //函数功能: //函数位置:
Method to call to read packets on a live capture