2016-09-25 22 views
1

我想解析包括不同类型的网络包(有些被标记为VLAN,有些不是)使用#包括一个pcap文件。 这里是我到目前为止的代码:如何使用libpcap和C获取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和跃过他们correctly.How我应该区分非虚拟局域网VLAN的报文?

+0

谢谢您的格式正确的问题,不过,我不确定如果你问“如何以最佳方式组织该代码”还是你问“我怎么取使用'libpcap''的VLAN标记,如果是的话,你是针对802.1q&ISL吗? –

+0

非常感谢。我已经改变了这个问题。是的,我真正想看的只是IP头。 – mazkopolo

回答

1

(如果你是在一个“活”的环境中测试这一点,要记住,路由器可以转发到非集群行之前删除802.1Q标签是非常重要的。)

如果你有一个特定的平台&协议有鉴于此,最快办法做到这一点永远是“手动”检查框:

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 or 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); 
} 

... 
相关问题