2010-07-29 30 views
7

Tôi đang viết mã để gửi khung Ethernet thô giữa hai hộp Linux. Để kiểm tra điều này, tôi chỉ muốn nhận một máy khách đơn giản gửi và nhận máy chủ.Ổ cắm ethernet nguyên linux liên kết với giao thức cụ thể

Tôi có ứng dụng khách tạo gói dữ liệu một cách chính xác (tôi có thể xem chúng bằng cách sử dụng gói sniffer).

Về phía server tôi khởi tạo các ổ cắm như vậy:

fd = socket(PF_PACKET, SOCK_RAW, htons(MY_ETH_PROTOCOL)); 

nơi MY_ETH_PROTOCOL là 2 byte liên tục tôi sử dụng như một EtherType vì vậy tôi không nghe lưu lượng mạng không liên quan.

khi tôi gắn ổ cắm này để giao diện của tôi, tôi phải vượt qua nó một giao thức một lần nữa trong struct socket_addr: socket_address.sll_protocol = htons(MY_ETH_PROTOCOL);
Nếu tôi biên dịch và chạy mã như thế này thì nó không thành công. Máy chủ của tôi không thấy gói. Tuy nhiên, nếu tôi thay đổi mã như vậy:
socket_address.sll_protocol = htons(ETH_P_ALL); Máy chủ có thể xem gói được gửi từ máy khách (cũng như nhiều gói khác), vì vậy tôi phải kiểm tra gói để xem gói khớp với số MY_ETH_PROTOCOL.

Nhưng tôi không muốn máy chủ của mình nghe lưu lượng truy cập không được gửi trên giao thức được chỉ định nên đây không phải là giải pháp. Làm thế nào để tôi làm điều này?

+0

Bạn có thể dán mã nơi bạn thiết lập 'socket_address' của mình không? – bstpierre

Trả lời

5

Tôi đã giải quyết được vấn đề.

Theo http://linuxreviews.org/dictionary/Ethernet/ đề cập đến lĩnh vực 2 byte sau các địa chỉ MAC:

"giá trị của lĩnh vực đó giữa 64 và 1522 cho thấy việc sử dụng các định dạng 802.3 Ethernet mới với một lĩnh vực chiều dài, trong khi các giá trị 1536 thập phân (0600 hệ thập lục phân) và lớn hơn cho biết việc sử dụng định dạng khung DIX hoặc Ethernet II gốc với một định danh giao thức phụ EtherType. "

vì vậy tôi phải đảm bảo ethertype của mình> = 0x0600.

Theo http://standards.ieee.org/regauth/ethertype/eth.txt sử dụng 0x88b5 và 0x88b6 là "có sẵn để sử dụng công khai cho nguyên mẫu và phát triển giao thức dành riêng cho nhà cung cấp." Vì vậy, đây là những gì tôi sẽ sử dụng như một ethertype. Tôi không cần phải lọc thêm nữa vì hạt nhân nên đảm bảo chỉ nhận các khung ethernet với địa chỉ MAC đích phù hợp và sử dụng giao thức đó.

+0

Tôi đã làm như bạn đã nói.Nhưng khách hàng của tôi không thể nhận được gói giao thức được chỉ định. Bạn có thể dán mã của mình không? cảm ơn bạn! email: [email protected] –

0

Tôi đã làm việc xung quanh vấn đề này trong quá khứ bằng cách sử dụng bộ lọc gói.

tay vẫy (chưa được kiểm tra mã giả)

struct bpf_insn my_filter[] = { 
    ... 
} 

s = socket(PF_PACKET, SOCK_DGRAM, htons(protocol)); 
struct sock_fprog pf; 
pf.filter = my_filter; 
pf.len = my_filter_len; 
setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)); 

sll.sll_family = PF_PACKET; 
sll.sll_protocol = htons(protocol); 
sll.sll_ifindex = if_nametoindex("eth0"); 

bind(s, &sll, sizeof(sll)); 

kiểm tra lỗi và nhận được bộ lọc gói tin đúng là trái như một bài tập cho người đọc ...

Tùy thuộc vào ứng dụng của bạn, một thay thế có thể dễ dàng hơn để làm việc là libpcap.

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