Пробую внести изменения в IPv4 пакет - добавить 4 байта опций. Проверяю конкретно на DNS запросах, смотрю wiresharkом.
Опции добавляются, тело DNS запроса - корректное, а вот в UDP заголовке - все нормально, кроме порта назначения - он может быть какой угодно. При этом проверял на выходе из функции-обработчика - все значения стоят какие надо.
Где этот dstport может перетираться? Почему? Уже не пойму, куда рыть..
Так вешается обработчик:
nfho.hook = hook_func;
nfho.hooknum = NF_INET_POST_ROUTING;
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;functions
nf_register_hook(&nfho);
switch (ip_hdr(skb)->protocol)
{
case IPPROTO_UDP:
if (skb_is_nonlinear(skb)) {
if (skb_linearize(skb)) {
printk(KERN_ERR "LABEL: Can't linearize skb.\n");
goto out;
}
}
if (skb_tailroom(skb) < 4) {
if (pskb_expand_head(skb, 0, 4, GFP_ATOMIC)) {
printk(KERN_ERR "LABEL: Can't get memory for options.\n");
goto out;
}
}
if (!skb_make_writable(skb, skb->len)) {
printk(KERN_ERR "LABEL: skb not writable.\n");
goto out;
}
data = skb_network_header((skb)) + ip_hdrlen((skb)); //char *data;
data_size = skb_tail_pointer(skb) - data; // int data_size
memmove(data + 4, data, data_size);
memmove(data, OWN_OPT, 4); // unsigned char OWN_OPT[4]
// узакониваем все наши изменения
skb_put(skb, 4);
ip_hdr(skb)->ihl += 1;
ip_hdr(skb)->tot_len = ntohs(skb->len);
ip_send_check(ip_hdr(skb));
skb_set_transport_header(skb, ip_hdr(skb)->ihl * 4);
break;
}
out:
return NF_ACCEPT;