libpcap与libnet简单介绍
libpcap使用
libpcap是抓取网络数据包的函数库
1. 获取网络接口
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf);
char * pcap_lookupdev(char * errbuf)
pcap_findalldevs获得所有网卡接口信息(name,descri,…)
pcap_lookupdev返回第一个合适的网卡接口名称 ,如eth0
2. 打开接口,获取操作指针
pcap_t * pcap_open_live(const char * device, int snaplen, int promisc, int to_ms, char * errbuf)
- device即为获取的网络接口名称,或手工设置;
- snaplen为对于每个数据包从开头开始应抓取的字节数,任何协议包大小必小于65535个字节
- promisc设置是否打开混杂模式,0为非混杂,如果要打开混杂模式,那么网卡必须也要打开混杂模式。
- to_ms指定需要等待毫秒数,超过这个数函数返回,若为0则无限等待
返回指定网络接口的pcap_t类型指针,通过该指针操作
2. 获取指定设备的ip地址,子网掩码等信息
int pcap_lookupnet(const char * device, bpf_u_int32 * netp, bpf_u_int32 * maskp, char * errbuf)
3. 数据包过滤规则设置
int pcap_compile(pcap_t * p, struct bpf_program * fp, char * str, int optimize, bpf_u_int32 netmask)
int pcap_setfilter(pcap_t * p, struct bpf_program * fp)
- optimize,是否需要优化过滤表达式
- netmask,掩码
pcap_compile编译过滤表达式str
pcap_setfilter设置使用过滤规则fp
4. 获取数据包
int pcap_loop(pcap_t * p, int cnt, pcap_handler callback, u_char * user)
...
...
- cnt指定需要抓取的数据包个数
- callback回调函数指针,当pcap_loop函数返回时调用该回调函数,一般用来处理数据包
- user,此参数传递给回调函数
此callback函数形式需如下:
void callback(u_char * userarg, const struct pcap_pkthdr * pkthdr, const u_char * packet)
- userarg由pcap_loop传递过来
- pkthdr为收到的数据包的pcap_pkthdr类型的指针
- packet为数据包数据
pcap_pkthdr结构如下:
struct pcap_pkthdr
{
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present*/
bpf_u_int32 len; /* length this packet (off wire) */
};
5. 释放网络接口
void pcap_close(pcap_t * p)
libnet
libnet函数库提供数据报的构造处理和发送
1. 初始化
libnet_t *libnet_init(int injection_type, char *device, char *err_buf);
- injection_type指明了发送数据报使用的接口类型,如数据链路层(link layer)或者原始套接字(raw socket layer)等
- device为网络接口名称
返回libnet_t描述符,供之后使用
2. 数据包构造
libnet_ptag_t
libnet_autobuild_ipv4(uint16_t len, uint8_t prot, uint32_t dst, libnet_t *l);
...
...
3. 数据报发送
int libnet_write(libnet_t *l);
int libnet_adv_write_raw_ipv4(libnet_t *l, const uint8_t *packet, uint32_t packet_s);
...
- packet 要发送的包
- packet_s 包大小
数据报发送有两种方式
1.发送通过该函数库构建的报文
libnet_write发送之前构造的报文
2.发送已构建好的报文如:libnet_adv_write_raw_ipv4
4. 销毁
void libnet_destroy(libnet_t *l);