LINUX.ORG.RU

Перехват и модификация udp-трафика


0

0

Мне необходимо перехватить udp-трафик и немного его модифицировать. Я это делаю с помощью модуля ядра. Проблема в том, что необходимо это сделать без пересобирания ядра, а в том, что есть, похоже отключен netfilter (я так решил, т.к. при попытке подгрузить модуль, использующий nf_register_hook, пишет «Unknown symbol nf_register_hook»).

Вот так я подменяю стандартный обработчик:

#include "linux/module.h"
#include "net/udp.h"

int (*orginalRecv)(struct kiocb*, struct sock*, struct msghdr*, size_t, int, int, int*);

int moniter_recv_udp(struct kiocb* iocb, struct sock* sk, struct msghdr*msg, size_t len, int noblock, int flags, int* addr_len)
{
    //тут надо что-то придумать
    return orginalRecv( iocb, sk, msg, len, noblock, flags, addr_len );
}


int init_module()
{
    orginalRecv = udp_prot.recvmsg;
    udp_prot.recvmsg = moniter_recv_udp;

    return 0;
}


void cleanup_module()
{
    udp_prot.recvmsg = orginalRecv;

}

Но никак не пойму, где там живет принимаемый буфер и как с ним работать. Вроде бы в sk->sk_receive_queue, т.е. вот так делаю и весь трафик блокируется:

int moniter_recv_udp(struct kiocb* iocb, struct sock* sk, struct msghdr*msg, size_t len, int noblock, int flags, int* addr_len)
{
    int ret = orginalRecv( iocb, sk, msg, len, noblock, flags, addr_len );

    sk->sk_receive_queue.next = sk->sk_receive_queue.prev = (struct sk_buff*)(&sk->sk_receive_queue);
    sk->sk_receive_queue.qlen = 0;

    return ret;
}

Может, подскажет кто?

★★

Кулхацкер? Вообще х его з. Про символ пожет быть всё просто:
1) У тебя в программе юзается этот символ, а его на деле нет и не должно быть.
2) Ядро вызывает этот символ, а у тебя его нет.
Это чисто так, на вскидку. Сам то я ничего так не писал «ядерного».
Как альтернативу могу предложить libpcap.

tia
()
Ответ на: комментарий от tia

Не угадал - мы не хакаем *смайлик*

Хм, всегда думал, что libpcap лишь статистику собирает, а подменять трафик не может. Примером кинуть в меня не желаешь?

kulti ★★
() автор топика
Ответ на: комментарий от kulti

libpcap лишь статистику собирает, а подменять трафик не может

да, не может.

Мне необходимо перехватить udp-трафик и немного его модифицировать

что именно?!

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Boy_from_Jungle

>>Мне необходимо перехватить udp-трафик и немного его модифицировать

что именно?!

Есть железяка, которая может нешифрованный контент понимать, но нам хочется хоть немного защититься, а менять в ней мы ничего особо не можем. Так что нужно перехватить и дешифровать, потому и спрашиваю в общих чертах, куда еще почитать.

kulti ★★
() автор топика
Ответ на: комментарий от kulti

ак что нужно перехватить и дешифровать, потому и спрашиваю в общих чертах, куда еще почитать.

Может я чего-то сильно недопонимаю, но почему бы пакеты, приходящие извне (они должны быть зашифрованы?) и предназначенные этой железке перенаправлять iptables'ом на порт проги-дешифровщика, которая будет дешифровывать и отправлять их железке?

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

Там ядрышко 2.6.12 с неизвестным конфигом, но видимо netfilter отрублен, разве он для iptables не нужен? Последний iptables под него не собирается, но я пока не пробовал старые версии, ибо не видел нигде, какой для какого ядра начинает работать.

kulti ★★
() автор топика
Ответ на: комментарий от kulti

Since 2.6.14 libipq/ip_queue deprecated, use libnetfilter_queue/nfnetlink_queue instead.

Только без netfilter ничего из этого все равно работать не будет.

nnz ★★★★
()
Ответ на: комментарий от nnz

Только без netfilter ничего из этого все равно работать не будет.

угу, и я о том же.

Собрал iptables-1.3.6, nuff said:

#./iptables -L
modprobe: module ip_tables not found.
modprobe: failed to load module ip_tables
iptables v1.3.6: can't initialize iptables table `filter': iptables who? (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
Ладно, буду дальше с модулем ядра возиться.

kulti ★★
() автор топика

Если я правильно помню, то трафик прогонять через user-space с его модификацией позволяло правило iptables -j QUEUE, но не понятно, есть ли оно в вашем ядре.

mky ★★★★★
()
Ответ на: комментарий от kulti

>2.6.12

Боюсь, что в эти далекие времена со структурой netfilter (в частности, по части возможностей расширения) была полная задница.

В принципе, можете впадать в отчаяние и забивать на netfilter.

А вариант с libpcap не покатит?

nnz ★★★★
()
Ответ на: комментарий от nnz

А в чем конкретно проблема?

Может я не совсем правильно выразился, т.к. не до конца понял что автор темы хочет конкретно. С помощью pcap можно выловить определённые типы пакетов, а потом зашифровать/дешифровать, но будет ли оно работать на его железяки?!

Boy_from_Jungle ★★★★
()

Эм...

sk->sk_receive_queue.next = sk->sk_receive_queue.prev = (struct sk_buff*)(&sk->sk_receive_queue); 
sk->sk_receive_queue.qlen = 0; 

Вышеприведённый код, грубо и тупо рубит все пакеты, принятые данным сокетом. Без учета того что где-то (например в планировщике) эти пактеты могут использоваться. Кроме того, он не совсем корректен, ибо sk_receive_queue имеет тип sk_buff_head, хотя и может быть приведён к sk_buff. Однако никто не гарантирует что первым элементом sk_buff_head так и останется sk_buff.

Сами данные к вам приходят через параметр «struct msghdr*msg», а если точнее, то msg->msg_iov->... и далее по списку.

Оригинальный хандлер лучше вызывать не сначала, а после обработки данных из сокета во избежание чудес и неожиданностей.

jr_A
()
Ответ на: комментарий от jr_A

Ага! Т.е., если я правильно понял, нужно писать что-то вроде:

int moniter_recv_udp(struct kiocb* iocb, struct sock* sk, struct msghdr*msg, size_t len, int noblock, int flags, int* addr_len) 
{
    //меняем что-нибудь в sk->sk_receive_queue
    ret = orginalRecv( iocb, sk, msg, len, noblock, flags, addr_len ); 
    return ret; 
}
и тогда тому, кто сделал вызов recv* придут уже измененные данные? Спасибо, скоро попробую.

kulti ★★
() автор топика

1. перехват трафика без его дальнейшего ресенда

2. выбрато из него то, что нужно

3. составить свою дейтаграмму через socket(AF_INET,SOCK_RAW,IPPROTO_IP);

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.