c - 如何使用 libpcap 和 C 获取 VLAN 标签?

标签 c libpcap vlan

我正在尝试使用 #include 解析包含不同类型网络数据包的 pcap 文件(有些被标记为 VLAN,有些则没有)。 到目前为止,这是我的代码:

pcap_t *pcap;
const unsigned char *packet;
char errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr header;
pcap = pcap_open_offline(argv[0], errbuf);
if (pcap == NULL)
    {
    fprintf(stderr, "error reading pcap file: %s\n", errbuf);
    exit(1);
}
while ((packet = pcap_next(pcap, &header)) != NULL)
{
    struct ip_header *ip;
    unsigned int IP_header_length;
    packet += sizeof(struct ether_header);
    capture_len -= sizeof(struct ether_header);
    ip = (struct ip_header*) packet;
    IP_header_length = ip->vhl * 4; /* ip_hl is in 4-byte words */
    char *sinfo = strdup(inet_ntoa(ip->src));
    char *dinfo = strdup(inet_ntoa(ip->dst));
    printf ("%s<-__->%s\n", sinfo ,dinfo);
    free (sinfo);
    free (dinfo);
}

代码中肯定有地方检查VLAN并正确跳过它们。我应该如何区分VLAN数据包和非VLAN数据包?

最佳答案

(如果您在“实时”环境中对此进行测试,请务必记住路由器可以在转发到非中继线路之前删除 802.1q 标签。)

如果您有特定的平台和协议(protocol),最快的方法始终是“手动”检查帧:

htonl( ((uint32_t)(ETH_P_8021Q) << 16U)
     | ((uint32_t)customer_tci & 0xFFFFU) ) T

但是,libpcap 以函数的形式为 compiling a BPF filters 提供了一个便携且干净的数据包过滤器。并将它们应用于数据包流(尽管重要的是要注意在线过滤和离线过滤有不同的功能集)

以这种方式,我们可以使用 pcap_offline_filter将编译后的 BPF 过滤器指令应用于 PCAP 文件。我在这里使用了过滤器表达式 vlan,您可能需要其他东西,例如 vlan 或 ip。如果您需要更复杂的东西,you can consult the documentation )

...

pcap_t *pcap;
char errbuf[PCAP_ERRBUF_SIZE];
const unsigned char *packet;
struct pcap_pkthdr header;
struct bpf_program fp; // Our filter expression
pcap = pcap_open_offline(argv[0], errbuf);
if (pcap == NULL) {
    fprintf(stderr, "error reading pcap file: %s\n", errbuf);
    exit(1);
}

// Compile a basic filter expression, you can exam
if (pcap_compile(pcap, &fp, "vlan", 0, net) == -1) {
    fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
    return 2;
}

while ((packet = pcap_next(pcap, &header) != NULL)
       && pcap_offline_filter(&fp, header, packet)) {
    struct ip_header *ip;
    unsigned int IP_header_length;
    packet += sizeof(struct ether_header);
    capture_len -= sizeof(struct ether_header);
    ip = (struct ip_header*) packet;
    IP_header_length = ip->vhl * 4; /* ip_hl is in 4-byte words */
    char *sinfo = strdup(inet_ntoa(ip->src));
    char *dinfo = strdup(inet_ntoa(ip->dst));
    printf ("%s<-__->%s\n", sinfo ,dinfo);
    free (sinfo);
    free (dinfo);
}

...

关于c - 如何使用 libpcap 和 C 获取 VLAN 标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39691084/

相关文章:

linux - 在 Linux 网桥上过滤掉 VLAN 标记的数据包

C函数删除字符串

c - execve() 传递的未知 open() 标志

c - 重复文件查找算法的建议(使用 C)

c - C 中的递归目录

perl - 在 Windows 10 上使用草莓 perl 安装 Net::Pcap

types - 为什么一些像 nginx 和 pcap 这样的开源项目使用自己的 'nginx_uint_t' 和 'bpf_u_int32' 而不是内置类型 'unsigned int'

linux - 如何确定目的MAC地址

相当于 ovs add port with vlan 的 Linux 命令

python - 遇到端口应用程序阻塞问题