美文网首页
Libcat开发

Libcat开发

作者: 二进制人类 | 来源:发表于2022-09-23 09:47 被阅读0次

基本步骤

  1. 打开网络设备
  2. 设置过滤规则
  3. 捕获数据包
  4. 关闭网络设备

相关API

#include <pcap/pcap.h>
char errbuf[PCAP_ERRBUF_SIZE];
/*
功能:找到要捕获的默认设备
参数:errbuf传递的是数组首元素地址,用来返回错误信息;
返回值:成功返回网络设备的名称,失败返回NULL且设置errbuf指针指向空间(错误消息)
*/
char *pcap_lookupdev(char *errbuf);
#include <pcap/pcap.h>
char errbuf[PCAP_ERRBUF_SIZE];
/**
 * [pcap_open_live 打开捕获数据的设备]
 * @param  device  [需要打开设备的名称]
 * @param  snaplen [捕获数据包的长度]
 * @param  promisc [捕获数据的模式:1 代表混杂模式;其它非混杂模式,一般使用0]
 * @param  to_ms   [捕获数据的超时时间,以ms为单位]
 * @param  errbuf  [存储错误消息]
 * @return         [成功返回设备的句柄,失败返回NULL且通过errbuf返回错误消息]
 */
pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf);
#include <pcap/pcap.h>
char errbuf[PCAP_ERRBUF_SIZE];
/**
 * [pcap_lookupnet 获取网络设备的设备号和掩码]
 * @param  device [需要获取网络设备的名称]
 * @param  netp   [返回网络设备号]
 * @param  maskp  [返回子网掩码]
 * @param  errbuf [存储错误消息]
 * @return        [成功返回0,失败返回-1]
 */
int pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf);
#include <pcap/pcap.h>
/**
 * [pcap_next  捕获一个数据包]
 * @param  p [已打开的网络设备句柄]
 * @param  h [捕获到的数据包的头部]
 * @return   [成功返回捕获的数据包,失败返回NULL]
 */
const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);
#include <pcap/pcap.h>

typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h,const u_char *bytes);
/**
 * [pcap_loop 循环捕获网络数据包,直到遇到错误或者满足退出条件;每次捕获一个数据包就会调用 callback 指示的回调函数,所以,可以在回调函数中进行数据包的处理操作]
 * @param  p        [已打开的网络设备句柄]
 * @param  cnt      [循环捕获数据包的条数]
 * @param  callback [捕获的数据的回调函数]
 * @param  user     [需要给回调函数传递的参数]
 * @return          [成功返回0,失败返回负数]
 */
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
#include <pcap/pcap.h>
/**
 * [pcap_compile 过滤规则]
 * @param  p        [打开网络设备的句柄]
 * @param  fp       [过滤规则(由libpcap库所能识别的过滤规则)]
 * @param  str      [过滤规则(由用户所能识别的过滤规则)]
 * @param  optimize [优化选项,一般使用0]
 * @param  netmask  [子网掩码。255.255.255.0 (0xffffff00)]
 * @return          [成功返回0,识别返回-1]
 */
int pcap_compile(pcap_t *p, struct bpf_program *fp, const char *str, int optimize, bpf_u_int32 netmask);
#include <pcap/pcap.h>
/*将编译好的过滤规则fp设置给已打开网络句柄p的网络设备*/
int pcap_setfilter(pcap_t *p, struct bpf_program *fp);

过滤规则

  1. 协议过滤

tcp udp tftp http icmp 表示协议过滤

  1. mac地址过滤

ether src 11:22:33:44:55:66 捕获源mac地址为11:22:33:44:55:66的数据包

ether dest 11:22:33:44:55:66 捕获目的mac地址为11:22:33:44:55:66的数据包

ether host 11:22:33:44:55:66 捕获目的(或者源)mac地址为11:22:33:44:55:66的数据包

  1. IP地址过滤

src host 192.168.4.250 捕获源IP为192.168.4.250的数据包

dest host 192.168.4.250 捕获目的IP为192.168.4.250的数据包

host 192.168.4.250 捕获目的(或者源)IP为192.168.4.250的数据包

ip src host 192.168.4.250 捕获源IP为192.168.4.250的数据包

ip dest host 192.168.4.250 捕获目的IP为192.168.4.250的数据包

  1. 端口过滤

src port 8888 捕获源端口为8888的数据包

dest port 8888 捕获目的端口为8888的数据包

port 8888 捕获目的(或者源)端口为8888的数据包

tcp src port 8888 捕获源端口为8888的tcp数据包

tcp dest port 8888 捕获目的端口为8888的tcp数据包

udp src port 8888 捕获源端口为8888的udp数据包

udp dest port 8888 捕获目的端口为8888的udp数据包

  1. 多条件过滤

and 满足所有的条件

or 只有满足其中一个条件都会过滤

实例

#include <stdio.h>
#include <pcap/pcap.h>
char errbuf[PCAP_ERRBUF_SIZE];
void my_pcap_handler(u_char *user, const struct pcap_pkthdr *h,const u_char *bytes)
{   
    /* 捕获到的数据包内容:bytes */
    unsigned char src_mac[28] = {0};
    unsigned char dest_mac[28] = {0};
    /* 对于接收到的数据,是以太网数据包:解析 */
    sprintf(dest_mac, "%02x:%02x:%02x:%02x:%02x:%02x", bytes[0], bytes[1],bytes[2], bytes[3], bytes[4], bytes[5]);
    sprintf(src_mac, "%02x:%02x:%02x:%02x:%02x:%02x", bytes[6], bytes[7], bytes[8], bytes[9], bytes[10], bytes[11]);
    printf("%s -> %s\n", src_mac, dest_mac);
}

int main()
{
    int ret;
    char *dev_name;
    pcap_t * my_pcap;
    struct pcap_pkthdr h;
    struct bpf_program fp;
    /* 获取默认捕获数据设备 */
    dev_name = pcap_lookupdev(errbuf);
    if (dev_name == NULL) {
        fprintf(stderr, "pcap_lookupdev errbuf: %s\n", errbuf);
        return -1;
    }
    printf("dev_name:%s\n", dev_name);
    /* 打开捕获数据设备 */
    my_pcap = pcap_open_live(dev_name, 1024, 0, 0, errbuf);
    if (my_pcap == NULL) {
        fprintf(stderr, "pcap_open_live errbuf: %s\n", errbuf);
        return -1;
    }
    printf("pcap_open_live success\n");
    /* 编译过滤规则 */
    ret = pcap_compile(my_pcap, &fp, "arp or ip", 0, 0xffffff00);
    if (ret == -1) {
        fprintf(stderr, "pcap_compile fail\n");
        return -1;
    }
    /* 设置编译规则 */
    ret = pcap_setfilter(my_pcap, &fp);
    if (ret == -1) {
        fprintf(stderr, "pcap_setfilter fail\n");
        return -1;
    }
    /* 循环捕获10条数据包 */
    ret = pcap_loop(my_pcap, 10, my_pcap_handler, NULL);
    //while(1);
    pcap_close(my_pcap);
    return 0;
}   

相关文章

网友评论

      本文标题:Libcat开发

      本文链接:https://www.haomeiwen.com/subject/gcnnortx.html