2008-09-22 28 views
9

Tôi muốn viết công cụ phân tích thời gian thực cho lưu lượng truy cập không dây.Đọc từ thiết bị mạng không liên quan

Có ai biết cách đọc từ thiết bị gián tiếp (hoặc đánh hơi) trong C không?

Tôi biết rằng bạn cần có quyền truy cập root để thực hiện điều đó. Tôi đã tự hỏi nếu có ai biết những chức năng là cần thiết để làm điều này. Ổ cắm bình thường dường như không có ý nghĩa ở đây.

+0

Trong Linux? Bài viết của bạn không chỉ ra hệ điều hành, nhưng chúng ta nên giả sử bằng cách sử dụng của bạn 'root' bạn có nghĩa là Linux? – GEOCHET

+1

yep, vì vậy thẻ tôi đoán – jbleners

Trả lời

16

Trên Linux bạn sử dụng một ổ cắm PF_PACKET để đọc dữ liệu từ một thiết bị thô, chẳng hạn như một giao diện ethernet chạy ở chế độ promiscuous:

s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) 

này sẽ gửi bản sao của tất cả các gói tin nhận được lên đến ổ cắm của bạn. Nó là khá có khả năng rằng bạn không thực sự muốn tất cả các gói tin, mặc dù. Nhân có thể thực hiện mức lọc đầu tiên bằng BPF, Berkeley Packet Filter. Về cơ bản, BPF là một máy ảo dựa trên stack: nó xử lý một tập hợp nhỏ các hướng dẫn như:

ldh = load halfword (from packet) 
jeq = jump if equal 
ret = return with exit code 

Mã thoát BPF cho hạt nhân biết có nên sao chép gói vào ổ cắm hay không. Có thể viết trực tiếp các chương trình BPF tương đối nhỏ, sử dụng setsockopt (s, SOL_SOCKET, SO_ATTACH_FILTER,). (CẢNH BÁO: Hạt nhân lấy cấu trúc sock_fprog, không phải là cấu trúc bpf_program, không trộn lẫn chúng lên hoặc chương trình của bạn sẽ không hoạt động trên một số nền tảng).

Đối với mọi thứ phức tạp, bạn thực sự muốn sử dụng libpcap. BPF được giới hạn trong những gì nó có thể làm, đặc biệt là trong số lượng các hướng dẫn nó có thể thực hiện cho mỗi gói. libpcap sẽ xử lý việc tách một bộ lọc phức tạp thành hai phần, với hạt nhân thực hiện mức lọc đầu tiên và mã không gian người dùng có khả năng hơn sẽ giảm các gói mà nó không thực sự muốn xem.

libpcap cũng tóm tắt giao diện hạt nhân ra khỏi mã ứng dụng của bạn. Linux và BSD sử dụng các API tương tự, nhưng Solaris yêu cầu DLPI và Windows sử dụng một cái gì đó khác.

+0

Cảm ơn bạn đã trả lời! – jbleners

+0

Thực ra, không, libpcap sẽ không chia bộ lọc thành hai phần. Nhưng, có, libpcap là những gì bạn muốn sử dụng - nó biết cách đặt giao diện vào chế độ promiscuous trên các nền tảng khác nhau (chỉ sử dụng 'ETH_P_ALL' không đủ trên Linux, ví dụ; đó là" SAP promiscuous ", trong đó bạn nhận được tất cả các gói bất kể loại giao thức, nhưng nó không phải là "vật lý promiscuous", trong đó adapter sẽ không cung cấp cho các gói host unicast không được gửi đến máy chủ). –

0

Tại sao bạn không sử dụng một cái gì đó như WireShark?

Đây là nguồn mở, vì vậy ít nhất bạn có thể học một vài điều từ nó nếu bạn không muốn chỉ sử dụng nó.

+0

Tôi không chắc chắn nếu WireShark có thể nắm bắt gói không dây đầy đủ. Tôi nghĩ rằng nó được cấu hình cho MAC thông thường không phải MAC không dây. Tôi cần để có thể xem xét lưu lượng truy cập từ nhiều nguyên tố. – jbleners

+0

Một lần nữa, tôi sẽ bắt đầu bằng cách xem xét mã nguồn của Wireshark. – GEOCHET

+1

WireShark không hoạt động với thẻ không dây trên Windows (dừng hoàn toàn). – leppie

7

Tôi đã từng phải nghe trên khung ethernet thô và kết thúc việc tạo trình bao bọc cho việc này. Bằng cách gọi hàm bằng tên thiết bị, ví dụ: eth0 Tôi nhận được một socket ở chế độ promiscuous. Những gì bạn cần làm là tạo một ổ cắm thô và sau đó đặt nó vào chế độ promiscuous. Đây là cách tôi đã làm nó.

int raw_init (const char *device) 
{ 
    struct ifreq ifr; 
    int raw_socket; 

    memset (&ifr, 0, sizeof (struct ifreq)); 

    /* Open A Raw Socket */ 
    if ((raw_socket = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 1) 
    { 
     printf ("ERROR: Could not open socket, Got #?\n"); 
     exit (1); 
    } 

    /* Set the device to use */ 
    strcpy (ifr.ifr_name, device); 

    /* Get the current flags that the device might have */ 
    if (ioctl (raw_socket, SIOCGIFFLAGS, &ifr) == -1) 
    { 
     perror ("Error: Could not retrive the flags from the device.\n"); 
     exit (1); 
    } 

    /* Set the old flags plus the IFF_PROMISC flag */ 
    ifr.ifr_flags |= IFF_PROMISC; 
    if (ioctl (raw_socket, SIOCSIFFLAGS, &ifr) == -1) 
    { 
     perror ("Error: Could not set flag IFF_PROMISC"); 
     exit (1); 
    } 
    printf ("Entering promiscuous mode\n"); 

    /* Configure the device */ 

    if (ioctl (raw_socket, SIOCGIFINDEX, &ifr) < 0) 
    { 
     perror ("Error: Error getting the device index.\n"); 
     exit (1); 
    } 

    return raw_socket; 
} 

Sau đó, khi bạn có ổ cắm, bạn có thể sử dụng lựa chọn để xử lý các gói khi chúng đến.

0

WireShark trên linux có khả năng thu thập thông tin tiêu đề PLCP (giao thức hội tụ lớp vật lý).

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