вторник, 1 января 2013 г.

Пример перехвата сетевого траффика с помощью Raw Sockets

Иногда бывает необходимость в получении сырых данных поступающих на сетевой интерфейс. Один из вариантов решения задачи — создать сетевой драйвер использующий интерфейсы netfilter. Хотя этот вариант будет иметь наибольшую производительность, существует более простой путь с точки зрения реализации. Для этого не надо писать никаких драйверов, достаточно просто открыть Raw Socket (сырой сокет) в программе рижима пользователя.

Ниже приведён пример программы, печатающей на экран весь входящий трафик:


#include <stdio.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <linux/if_ether.h> // ETH_P_ALL
#include <linux/if_packet.h> // sockaddr_ll

int main(int argc, char **argv)
{
    int s;
    struct sockaddr_in src_addr;
    char packet[50] = {0};
    struct sockaddr_ll    sll = {0};

    if ((s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) { // (1)
        perror("socket");
        return -1;
    }

    sll.sll_family        = AF_PACKET;
    sll.sll_ifindex        = 3; // Interface index (2)
    sll.sll_protocol    = htons(ETH_P_ALL);

    if( bind(s, (struct sockaddr *) &sll, sizeof(sll)) == -1 ) {
        perror("bind");
    }

    socklen_t *len = (socklen_t *)sizeof(src_addr);
    int fromlen = sizeof(src_addr);

    while(1) {
        if (recvfrom(s, &packet, sizeof(packet), 0,
                    (struct sockaddr *)&src_addr, &fromlen) < 0)
            perror("recvfrom");

        int i = sizeof(struct iphdr); // print the payload

        for(; i < sizeof(packet); i++) {
            printf("%02X ", (unsigned char) packet[i]);
        }

        printf("\n");
    }
    return 0;
}
 

Комментарии:

  1. Чтобы открыть сырой сокет, необходимы права суперпользователя. 
  2. Номер интерфейса можно получить в том числе командой "ip addr sh"
Код тестировался на Ubuntu 12.04 x64

Ссылки:

  1. Код основан на примере из ответа на stackoverflow . Оригинальный код у меня не заработал и я его немного изменил.
  2.  libpcap использует этот-же механизм для перехвата траффика (pcap-linux.c/activate_new()). Эту библиотеку используют такие популярные утилиты как tcpdump и wireshark.

Комментариев нет:

Отправить комментарий