Использование skb_make_writable и skb_ensure_writable в Linux ядре - PullRequest
0 голосов
/ 16 января 2020

Я написал ловушку netfilter для изменения некоторых данных на прикладном уровне. Я пытаюсь получить начало и конец данных приложения:

sturct iphdr* iph = ip_hdr(skb);
struct tcphdr* tcph;
char *data_start, *data_end;
if(iph -> protocol != IPPROTO_TCP)
    return NF_ACCEPT;
tcph = tcp_hdr(skb);
data_start = (char *)tcph + tcph -> doff * 4;
data_end = (char *)tcph + ntohs(iph -> tot_len) - iph -> ihl * 4;

А затем, например, вывести первый символ:

if(data_end - data_start >= 1)
    printk("%x\n", *data_start);

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

Я нашел решение: используйте skb_ensure_writable (или skb_make_writable в старом ядре) перед чтением данных приложения и повторно -get заголовки и указатели символов:

sturct iphdr* iph = ip_hdr(skb);
struct tcphdr* tcph;
char *data_start, *data_end;
if(iph -> protocol != IPPROTO_TCP)
    return NF_ACCEPT;
tcph = tcp_hdr(skb);
data_end = (char *)tcph + ntohs(iph -> tot_len) - iph -> ihl * 4;

skb_ensure_writable(skb, (char*)data_end - (char*)skb -> data);

iph = ip_hdr(skb);
tcph = tcp_hdr(skb);
data_start = (char *)tcph + tcph -> doff * 4;
data_end = (char *)tcph + ntohs(iph -> tot_len) - iph -> ihl * 4;

Но у меня все еще есть несколько вопросов:

  1. Почему данные приложения не предназначены для того, чтобы лежать позади заголовка TCP?
  2. Может ли заголовок TCP также не находиться за заголовком IP? Если да, как я могу получить второй параметр для skb_ensure_writable?
  3. Что именно skb_ensure_writable или skb_make_writeable делает? Я едва мог найти какой-либо документ.
...