2016-09-05 21 views
6

Mã này hoạt động hoàn toàn tốt đẹp trên Ubuntu 16.04 và in giá trị đúng (ETHERTYPE_IP) khi tôi quăng xung quanh UDP byte thông qua giao diện loopback:gói Chụp trên loopback

#include <pcap.h> 
#include <iostream> 
#include <net/ethernet.h> 

int main(int argc,char **argv) 
{ 
    char errbuf[PCAP_ERRBUF_SIZE]; 
    auto pcap = pcap_open_live("lo0", BUFSIZ, 0, 1000, errbuf); 

    pcap_loop(pcap,0, [] (u_char *self, const struct pcap_pkthdr *header, 
          const u_char *packet) { 
     auto eth = (struct ether_header *) packet; 
     auto eth_type = ntohs(eth->ether_type); 
     std::cout << "eth_type: " << std::hex << eth_type << std::endl; 
    }, nullptr); 

    return 0; 
} 

netcat: sản lượng

➜ ~ nc -uv -l 54321 
Listening on [0.0.0.0] (family 0, port 54321) 

➜ ~ nc -4u localhost 54321 
hello 

Chương trình :

➜ ~ sudo ./a.out 
eth_type: 800 

Tuy nhiên trên OS X 10.11.5 nó in eth_type: 4 011. Thú vị là nó hoạt động tốt với bộ chuyển đổi en1.

Tại sao có sự khác biệt như vậy giữa các bộ điều hợp loopback và non-loopback và cách thức chính xác để nắm bắt các gói dữ liệu trên cả hai?

Cập nhật: tcpdump cũng làm việc:

➜ ~ sudo tcpdump -i lo0 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode 
listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes 
15:09:00.160664 IP localhost.54321 > localhost.63543: UDP, length 4 
+0

Bạn có thể phải sử dụng "lo0" chứ không phải "lo". Để biên dịch điều này trên một mac thử: clang ++ -std = C++ 11 -stdlib = libC++ -lpcap test.cpp -o kiểm tra ... Tôi cũng nhận được các giá trị rác cho ether_type. – sdsykes

+0

đó là một lỗi đánh máy trong đoạn mã, nó thực sự là lo0. – lstipakov

Trả lời

1

Là loại liên kết không phải là ethernet, tiêu đề không chứa dữ liệu phù hợp cho ether_header.

Thêm mã này sau khi lấy tay cầm với pcap_open_live để xem các loại tiêu đề link-layer:

if (pcap_datalink(pcap) != DLT_EN10MB) { 
    fprintf(stderr, "Device doesn't provide Ethernet headers - link type was %d\n", pcap_datalink(pcap)); 
    return 1; 
} 

Chạy điều này chỉ ra rằng giá trị linkType cho lo0 là 0, DLT_NULL. Tài liệu này nói rằng điều này có nghĩa là "đóng gói vòng lặp BSD; tiêu đề lớp liên kết là trường 4 byte, trong thứ tự byte máy chủ, chứa giá trị PF_ từ socket.h cho giao thức tầng mạng của gói."

Thật vậy, khi tôi nhìn vào 4 byte đầu tiên của trường ether_dhost tôi thấy giá trị 2, tương ứng với PF_INET. Cuối cùng, điều này không giúp bạn nhiều nếu bạn đang cố gắng phân biệt các gói UDP.

Bạn có thể tìm thêm tài liệu tại đây: http://www.tcpdump.org/linktypes.html

Các vấn đề liên quan