2013-04-26 18 views
6

Tôi đang cố gửi một khung ethernet OAM bằng cách sử dụng ổ cắm thô. Tôi đã thành công khi làm như vậy.chức năng sendto không sử dụng địa chỉ MAC được cung cấp trong struct sockaddr_ll khi gửi các gói dữ liệu thô

Các gửi chức năng tôi đã viết là:

int send_frame(sock_info *info,char *buf,int length) 
    { 
     struct sockaddr_ll dest_addr; 
     memset(&dest_addr,0,sizeof(struct sockaddr_ll)); 
     dest_addr.sll_family = PF_PACKET; 
     dest_addr.sll_protocol = htons(8902); 
     dest_addr.sll_ifindex = info->if_index; 
     dest_addr.sll_halen = ETH_MAC_ADDR_LEN; 
     dest_addr.sll_pkttype = PACKET_OTHERHOST; 
     dest_addr.sll_hatype = ARPHRD_ETHER; 
     memset(dest_addr.sll_addr,0,8); 

     dest_addr.sll_addr[0] = 0x00; 
     dest_addr.sll_addr[1] = 0xE0; 
     dest_addr.sll_addr[2] = 0x0C; 
     dest_addr.sll_addr[3] = 0x00; 
     dest_addr.sll_addr[4] = 0x95; 
     dest_addr.sll_addr[5] = 0x02; 

     return sendto(info->sock_fd, buf, length, 0, (struct sockaddr*) &dest_addr, sizeof(struct sockaddr_ll)); 
    } 

tôi đã không thể nắm bắt được gói tin sử dụng Wireshark. Sau khi tryiing quá nhiều thứ, tôi phát hiện ra rằng bộ đệm được sử dụng để gửi nên có tất cả các lĩnh vực khung ethernet (bắt đầu từ địa chỉ đích). Khi tôi thêm địa chỉ đích và nguồn và các trường ethernet khác vào bộ đệm, tôi đã có thể nắm bắt gói tin bằng cách sử dụng wireshark. Vì vậy, chức năng gửi không sử dụng địa chỉ MAC được lưu trữ trong dest_addr.sll_addr.

Câu hỏi của tôi là, Sau đó, nhu cầu của trường sll_addr trong số struct sockaddr_ll là gì? Hướng dẫn sử dụng nói rằng đó là địa chỉ MAC đích.

Trả lời

3

Đối với tôi nó có vẻ như nó hoạt động như các trang hướng dẫn mô tả nó (người đàn ông 7 gói):

gói SOCK_RAW được truyền đến và đi từ trình điều khiển thiết bị mà không bất kỳ thay đổi trong dữ liệu gói. Khi nhận được gói, địa chỉ là vẫn được phân tích cú pháp và được chuyển vào cấu trúc địa chỉ sockaddr_ll tiêu chuẩn. Khi truyền gói, bộ đệm do người dùng cung cấp phải chứa tiêu đề lớp vật lý . Sau đó, gói đó được xếp hàng chưa được sửa đổi thành trình điều khiển mạng của giao diện được xác định bởi địa chỉ đích. Một số trình điều khiển thiết bị luôn thêm các tiêu đề khác. SOCK_RAW tương tự như nhưng không tương thích với PF_INET/SOCK_PACKET lỗi thời của Linux 2.0.

Bộ đệm ở đây đề cập đến tham số thứ 2 của sendto(). Vì vậy, sockaddr_ll stuct chỉ được sử dụng để trả lại dữ liệu cho người gọi, không phải để định dạng gói RAW. Có thể bạn muốn sử dụng số điện thoại SOCK_DGRAM hoặc libpcap thay thế?