LINUX.ORG.RU

пользовательские данные,sk_buff


0

1

Доброго времени суток, помогите плиз разовбраться как правильно получить доступ к данным пользователя в 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

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

С уважением.

Опять ты, и опять с тем же вопросом... Только у тебя уже есть мой код...

ХЗ в чем тут у тебя дело. tcpdump (wireshark) работают же на новом сервере?

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

большое тебе человеческое спасибо добрый человек !

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

в смысле опять ? я вопрос тут задавал про libnet и отправку пакета, но не про skbuff ...

вполне возможно что использовал примеры которые Вы приводили тут, или ещё где на просторах инета, это разве возбраняется ?

tcpdump (wireshark) работают, и показывают целые пакеты, или нужно смотреть на что-то особенное ?

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

As I think, you didn't solve the problem. So, if tcpdump program has it good output, that's meant that the kernel network system work good.

Never mind, just look inside the kernel network subsystem. I will think, that you'll find the way out

Dennis7
()

Да ты хотя бы побайтово выведи

Dennis7
()

У тебя там strlen() используется, а ты хоть знаешь, как оно рабоает в ядре? Тут тебе не libc

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

Of course, because PF_PACKET code does a copy for all skb fragments in the following loop: for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)

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

So, if tcpdump program has it good output, that's meant that the kernel network system work good.

tcpdump пакеты, в том числе их содержимое, показывает правильно. Как-то не подумал что Вы предположите, что я это сам первым делом не глянул ...

У тебя там strlen() используется

в тестовых целях, знаю что -производительность и если нет \0 то есть шанс выйти за границы. Может что-то ещё есть ?

я понимаю, система фрагментирует sk_buff не просто так, может подскажите, для чего это делается ? есть ли в этом какая-то выгода ? и если она есть, но мала, то как отказаться от фрагментации.

с уважением !

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