Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> пользовательские данные, sk_buff 
:(
    Опции темы
bodigard
Дата 11.9.2013, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Доброго времени суток, помогите плиз разовбраться как правильно получить доступ к данным пользователя в sk_buff. 
есть модуль фильтрации http трафика и работал он прекрасно, но понадобилось перенести на другой сервер, в результате код работающий на 1ном железе перестал работать на другом :(

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

на виртуалке получаю данные пользовалетя так 
Код

user_data_ptr = (char *)(skb->data + sizeof(struct iphdr) + sizeof(struct tcphdr));

работает прекрасно, см результат 2

если тоже самое сделать на железном сервере то получу результат 1

далее, на железном сервере вставляю мощьный костыль в виде копирования sk_buff посредством skb_copy и получаю правельный результат, результат 2. но от этого костыля очень хочеться уйти ...

есть подозрение что на железном сервере каким-то образом в памяти фрагментируется sk_buff, но как правильно к этому подойти ума не приложу :(

вот кусок кода (за стиль извиняюсь, переписывал его раз на 20ть по разному, но работает только этот, с копированием)


Код

unsigned int main_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
                int (*okfn)(struct sk_buff*))
{
        int i,get_len;
        struct iphdr *ip;// = (struct iphdr *)skb->data;
        struct tcphdr *tcp;// = (struct tcphdr *)(skb->data + sizeof(struct iphdr));
        char *p, *user_data_ptr;
        struct sk_buff *cpy = NULL;

        //cpy = kmalloc(skb->truesize,GFP_ATOMIC);
        //if(cpy != NULL) cpy = skb_copy(skb,GFP_ATOMIC);
        //else return NF_ACCEPT;

        //делаем копию skb
        cpy = skb_copy(skb,GFP_ATOMIC);
        if(cpy == NULL){
             printk("error SKB_COPY\n");
             return NF_ACCEPT;
        }

        ip = (struct iphdr *)cpy->data;
        tcp = (struct tcphdr *)(cpy->data + sizeof(struct iphdr));

        if(ip->version == 4 && ip->protocol == IPPROTO_TCP ){
/*
                printk("pro=TCP, src=%d.%d.%d.%d:%d\t", ntohl(ip->saddr)>>24, (ntohl(ip->saddr)>>16)&0x00FF,
                                                            (ntohl(ip->saddr)>>8)&0x0000FF, (ntohl(ip->saddr))&0x000000FF,ntohs(tcp->source));
                printk("dst=%d.%d.%d.%d:%d\n", ntohl(ip->daddr)>>24, (ntohl(ip->daddr)>>16)&0x00FF,
                                                            (ntohl(ip->daddr)>>8)&0x0000FF, (ntohl(ip->daddr))&0x000000FF,ntohs(tcp->dest));
*/
                if(tcp->dest == htons(80)){
                        
                        //получаем указатель на данные пользователя из копии
                        user_data_ptr = (char *)(cpy->data + sizeof(struct iphdr) + sizeof(struct tcphdr));
                        
                        //получаем указатель на данные пользователя из оригинала
                        //user_data_ptr = (char *)(skb->data + sizeof(struct iphdr) + sizeof(struct tcphdr));
                
                        //DEBUG инофрмация о размерах
                        get_len = cpy->tail - cpy->data;
                        if(get_len > 40){
                            printk("len - %i\n",get_len);
                            printk("len1 - %i\n",strlen(user_data_ptr));
                            printk("skb->len - %i\n",cpy->len);
                            printk("skb->data_len - %i\n",cpy->data_len);
                        }
                       
                        get_len = strlen(user_data_ptr); //skb->data_len;

                        if(get_len > 100){ //handshake и разный мусор нам не интересен
                            printk("\nSTART ORIGIN_DATA\n");
                            for(i=0;i<get_len;i++){
                                //printk("%x", user_data_ptr[i]);
                                printk("%c",user_data_ptr[i]);
                            }
                            printk("\nEND ORIGIN_DATA\n");
                            kfree_skb(cpy);
                            return NF_ACCEPT;
                        }
                }
        }
    kfree_skb(cpy);
    return NF_ACCEPT;
}


так регестрирую функцию
Код

//netfilter out
        nf_outgoing.hook = main_hook;
        nf_outgoing.pf = PF_INET;
        nf_outgoing.hooknum = NF_INET_PRE_ROUTING;//NF_INET_PRE_ROUTING;//NF_INET_FORWARD;//NF_INET_POST_ROUTING;//NF_INET_LOCAL_IN;4;//NF_INET_LOCAL_OUT;
        nf_outgoing.priority = NF_IP_PRI_FIRST;
        nf_register_hook(&nf_outgoing);


Результат 1
Код

Sep 10 15:53:26 proxy kernel: len - 40
Sep 10 15:53:26 proxy kernel: len1 - 14
Sep 10 15:53:26 proxy kernel: skb->len - 429
Sep 10 15:53:26 proxy kernel: skb->data_len - 389
Sep 10 15:53:26 proxy kernel:
Sep 10 15:53:26 proxy kernel: START ORIGIN_DATA
Sep 10 15:53:26 proxy kernel: 5efffffff5yfffffffb2cfffffff51111ffffffa5Bfffffff6ffffff8e201005efffffff5yfffffffb8ffffffca13e26ffffffbfqfffffff414000044000010pffffffceffffff8613ffffffc1ffffffc8ffffffc7ffffff99fff
fffe8c1c60223effffffcc75fffffff9bffffff87ffffff88KDfffffff015ffffffc535ffffffdbffffffc0fffffff0ffffffacffffff8bffffffe7c113833fRffffffb829ffffff8920ffffff97o7f26ffffffb9fffffff7W5bffffffb5Effffffbdffffffb3ffffff
b7ffffff9e17ffffff8dffffffefk1d2effffffa811ffffff91f3ffffffc7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sep 10 15:53:26 proxy kernel: END ORIGIN_DATA   



Результат 2
Код

Sep 10 16:45:27 proxy kernel: len - 532
Sep 10 16:45:27 proxy kernel: len1 - 492
Sep 10 16:45:27 proxy kernel: skb->len - 532
Sep 10 16:45:27 proxy kernel: skb->data_len - 0
Sep 10 16:45:27 proxy kernel:
Sep 10 16:45:27 proxy kernel: START ORIGIN_DATA
Sep 10 16:45:27 proxy kernel: GET /su/ HTTP/1.1
Sep 10 16:45:27 proxy kernel: Accept: text/html, application/xhtml+xml, */*
Sep 10 16:45:27 proxy kernel: Referer: http://ya.ru/
Sep 10 16:45:27 proxy kernel: Accept-Language: ru-RU
Sep 10 16:45:27 proxy kernel: User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Sep 10 16:45:27 proxy kernel: Accept-Encoding: gzip, deflate
Sep 10 16:45:27 proxy kernel: Host: kiks.yandex.ru
Sep 10 16:45:27 proxy kernel: Connection: Keep-Alive
Sep 10 16:45:27 proxy kernel: Cookie: ys=gsync.1378790047; yandexuid=1471721651378795249; fuid01=522ebef255999fb9.qOOODita1WHGvfdQjHhsPF4h2eDNI62T1gxRp8ZM5taWSHeLQaQheLKMsmAYJPj7JxTvF32pF5rBgfz4xrFGSpnIU00oyRBG9
nX16VOtoS2h_X1-snwHoCTc4gTuOB2N
Sep 10 16:45:27 proxy kernel: END ORIGIN_DATA


Заранее благодарен !

С уважением.

PM MAIL   Вверх
borisbn
Дата 11.9.2013, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 2
Всего: 135



Может данные по указателю skb перетираются в другом потоке ?
А если быстренько скопировать данные, то перетирание исходных на это не влияет...
Попробуй перед копированием вставить задержку - если увидишь битые данные и в копии, то это подтвердит мои слова


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
feodorv
Дата 12.9.2013, 03:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(bodigard @  11.9.2013,  10:58 Найти цитируемый пост)
так регестрирую функцию

Обратил внимание, что в структуре
Код

struct nf_hook_ops
{
        struct list_head list;

        /* User fills in from here down. */
        nf_hookfn *hook;
        struct module *owner;
        u_int8_t pf;
        unsigned int hooknum;
        /* Hooks are ordered in ascending priority. */
        int priority;
};

может быть ещё одно поле owner, которое Вы не инициализируете. Когда это поле добавилось, я не знаю, но на новеньком сервере оно вполне может иметь место.


В добавок:
Цитата(bodigard @  11.9.2013,  10:58 Найти цитируемый пост)
                        get_len = strlen(user_data_ptr); //skb->data_len;

Это самоубийство...

Добавлено через 7 минут и 35 секунд
К тому же лучше пользоваться функциями ip_hdr, skb_network_header, ip_hdrlen etc (например, в заголовке IP могут присутствовать опции).


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 12.9.2013, 04:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(feodorv @  12.9.2013,  04:48 Найти цитируемый пост)
Когда это поле добавилось, я не знаю

Вот здесь так написано:
Код

#if (LINUX_VERSION_CODE >= 0x020500)
  .owner = THIS_MODULE,
#endif 



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
bodigard
Дата 12.9.2013, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(feodorv @  12.9.2013,  03:48 Найти цитируемый пост)
поле owner, которое Вы не инициализируете

благодарю, гляну на что это влияет. 

Цитата(feodorv @  12.9.2013,  03:48 Найти цитируемый пост)
Это самоубийство...

знаю smile сервер пока не в работе, так что пока пытаюсь заставить работать без костыля, производительность на 2м месте ... 

Цитата(feodorv @  12.9.2013,  03:48 Найти цитируемый пост)
К тому же лучше пользоваться функциями ip_hdr, skb_network_header, ip_hdrlen etc (например, в заголовке IP могут присутствовать опции). 

учту на будущее 

пробовал так 
Код
ip = (struct iphdr *)skb_network_header(skb);
skb_set_transport_header(skb, ip->ihl * 4); //если этого не сделать то tcp заголовок не верный
tcp = (struct tcphdr *)skb_transport_header(skb);


результат идентичен моему

Цитата(borisbn @  11.9.2013,  15:31 Найти цитируемый пост)
Может данные по указателю skb перетираются в другом потоке ?

даже если так, то не соображу, что это даст ?


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


Это сообщение отредактировал(а) feodorv - 12.9.2013, 16:33
PM MAIL   Вверх
feodorv
Дата 12.9.2013, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(bodigard @  12.9.2013,  15:10 Найти цитируемый пост)
производительность на 2м месте

Я, в сущности, иное имел в виду  smile 
Если в данных user_data_ptr отсутствует '\0', то Вы уезжаете за пределы предоставленных данных....


Цитата(bodigard @  12.9.2013,  15:10 Найти цитируемый пост)
//если этого не сделать то tcp заголовок не верный

А так не годится?
Код

            tcp = (struct tcphdr *)(skb_network_header(skb) + ip_hdrlen(skb));



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
bodigard
Дата 13.9.2013, 07:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(feodorv @  12.9.2013,  17:42 Найти цитируемый пост)
Я, в сущности, иное имел в виду

каюсь, запамятовал, спасибо что напомнили  smile 


Цитата(feodorv @  12.9.2013,  17:42 Найти цитируемый пост)
А так не годится?

почему-же, вполне , только проблема у меня не с заголовками, а с содержимым, что идёт после заголовков ...
PM MAIL   Вверх
feodorv
Дата 13.9.2013, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



owner не помог?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
bodigard
Дата 16.9.2013, 06:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(feodorv @  13.9.2013,  23:48 Найти цитируемый пост)
owner не помог? 



нет к сожалению. 

проблема видимо глубже, хотя думаю что ядро не зря фрагментирует пакеты, осталось понять зачем оно это делает и какая в этом выгода ...
PM MAIL   Вверх
feodorv
Дата 16.9.2013, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(bodigard @  16.9.2013,  07:15 Найти цитируемый пост)
хотя думаю что ядро не зря фрагментирует пакеты, осталось понять зачем оно это делает и какая в этом выгода ... 

А я думал, что речь идёт об IP-фрагментах, а не о фрагментах Netfilter-данных...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1052 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.