2013-02-19 2 views
2

У меня есть клиент на ПК. У меня есть сервер на ПК. Клиент и сервер подключаются через маршрутизатор с прошивкой на базе ОС Linux.
Клиент отправляет пакет на сервер и получает ответ. Маршрутизатор должен перехватывать пакеты и изменять их. Что-то вроде нюхать, но это не нюхать, потому что мне нужно модифицировать пакеты.
Я должен написать программу для этого.
Я попытался открыть сырой сокет на маршрутизаторе, но revvfrom на raw socket не перехватывает пакет и просто копирует его. Пакет продолжается.
Не могли бы вы предложить мне любой способ решить эту проблему?
P.S. Извините за мой плохой английский. :)Перехват udp-пакетов на маршрутизаторе

+0

Что вы попробовали? – bash0r

+0

Я написал программу для маршрутизатора.Эта программа открывает сырой сокет и принимает UDP-пакеты. Обычно прием выполняется, но пакет продолжает перемещаться к исходному приемнику. Мне нужно «вырвать» этот пакет, изменить его и «вернуть». – someuser

ответ

1

Я написал модуль для ядра и некоторых приложений. Модуль использует netfilter и отбрасывает пакеты, которые мне нужны для netfilter_queue. Приложение обрабатывает очередь, и я решаю, что делать с каждым пакетом.

uint hook_main(uint hooknum, 
        struct sk_buff *skb, 
        const struct net_device *in, 
        const struct net_device *out, 
        int (*okfn)(struct sk_buff *) ) 
{ 
    struct iphdr *ip; 
    struct udphdr *udp; 
    if (skb->protocol == htons(ETH_P_IP)){ 
     ip = (struct iphdr *)(skb->data); 
     if (ip->version == 4 && ip->protocol == IPPROTO_UDP){ 
      udp = (struct udphdr *)(skb->data + sizeof(struct iphdr)); 
      if(ntohs(udp->dest) == SOME_PORT){ 
       return NF_QUEUE; 
      } 
     } 
    } 
    return NF_ACCEPT; 
} 

int init_module() 
{ 
    printk("[udp-catch] start udp-catch\n"); 

    catch_hook.hook = hook_main; 
    catch_hook.owner = THIS_MODULE; 
    catch_hook.pf = PF_INET; 
    catch_hook.hooknum = NF_INET_FORWARD; 
    catch_hook.priority = NF_IP_PRI_FIRST; 
    nf_register_hook(&catch_hook); 

    return 0; 
} 

И a redesigned sample from netfilter.org - приложение.

0

Маршрутизаторы будут автоматически отправлять все, что они получают на своих других портах.

например. Для 4-портового маршрутизатора то, что входит в порт 1, будет отправлено на порты 2,3 & 4.

Для выполнения необходимых действий вам нужен другой компьютер с 2 сетевыми картами. Подключите свой клиентский ПК к одной сетевой карте, а серверный ПК - к другой.

Тогда ваша программа будет необходимо recvfrom на одной сетевой карты, изменять пакет и SendTo на другой сетевой карте.

+0

У меня есть только два компьютера и маршрутизатор. И конкретная работа. – someuser

+0

Возможно, какой-то способ настроить аппаратное обеспечение не перенаправлять пакеты на другие порты, но попытаться сделать то, что вы делаете в программном обеспечении, не будет иметь большой пропускной способности. – Neil

+0

Вы предлагаете настроить маршрутизатор, чтобы он не отправлял трафик дальше? – someuser

4

Я хотел бы использовать сочетание iptables и libnetfilter_queue (предполагается, что ваше ядро ​​относительно недавно)

  1. Добавить в iptables на правилах, которые пересылают все УДП пакеты на NFQUEUE 0 для того, чтобы получить пакеты от ядро для пользовательского пространства.

    iptables -A INPUT -p udp -m udp --dport xxxxx -j NFQUEUE --queue-num 0

  2. построить процесс, который прослушать NFQUEUE number 0, изменять полезную нагрузку и дать полный пакет обратно в пространство ядра, используя libnetfilter_queue возможности. Следуйте за this link, чтобы узнать, как это сделать.

В двух словах вы должны открыть очередь 0 (nfq_create_queue), установите режим для того, чтобы получить содержимое пакета (nfq_set_mode), затем цикл в бесконечной recv, чтобы получить когда-либо UDP пакет фильтруется iptables

fd = nfq_fd(h); 

while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) { 
    printf("pkt received\n"); 
    nfq_handle_packet(h, buf, rv); 
} 

Everytime вы называете nfq_handle_packet называется, обратный вызов определяется во время фазы nfq_create_queue называется. В этом обратном вызове вам необходимо изменить полезную нагрузку, обновить размер и пересчитать контрольную сумму, а затем установить как «действительный» с nfq_set_verdict

+0

Звучит интересно. Благодарю. – someuser