2016-09-25 25 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); 
} 

... 
相關問題