Задать вопрос
@grizzli771

Linux kernel module: не работает изменение адреса назначения tcp пакета, как это исправить?

Формирую и отправляю TCP пакет через RAW-socket( socket(PF_INET, SOCK_RAW, IPPROTO_TCP) ) на заданный IP (main_server_ip).
На машине запущен модуль ядра Linux, который отлавливает TCP пакеты на этот IP адрес(main_server_ip) и меняет адрес места назначения на другой(other_server_ip). Пакеты не приходят в место назначения. Перехватываю Wireshark - ом пакеты между машинами и наблюдаю картину: в IP заголовке пакета указан правильный IP адрес (other_server_ip), но в заголовки Ethenet прописан MAC - адрес соответствующий первоначальному IP адресу(other_server_ip). Т. е. получается, что IP адрес изменился, но MAC остался от старого IP адреса.
Не могу понять с чем это связано и как исправить...
Если отправлять данные через обычные сокеты, то все успешно работает. Версия ядра: 3.13.0-65-generic.

Ниже привожу код, который использую для изменения IP адреса места назначения в модуле ядра:
struct iphdr *ip_header = (struct iphdr *) skb_network_header(skb);
unsigned int dest_ip = (unsigned int) ip_header->daddr;
struct tcphdr *tcp_header;
if (dest_ip == main_server_ip) {
printk(KERN_INFO "Protocol: %d\n", ip_header->protocol);
if (ip_header->protocol == 6) {
tcp_header = (struct tcphdr*) ((char*) ip_header + (ip_header->ihl * 4));
tcp_header->check = 0;
}
unsigned char* pack = ((char*) ip_header + (ip_header->ihl * 4));
tcp_len = ntohs(ip_header->tot_len) - (ip_header->ihl * 4);
ip_header->daddr = other_server_ip;
if (ip_header->protocol == 6) {
tcp_header = (struct tcphdr*) ((char*) ip_header + (ip_header->ihl * 4));
len = skb->len;
tcp_header->check = 0;
tcp_header->check = tcp_v4_check(len - 4 * ip_header->ihl,
ip_header->saddr, ip_header->daddr,
csum_partial((char *) tcp_header, len - 4 * ip_header->ihl,
0));
skb->ip_summed = CHECKSUM_NONE;
ip_header->check = 0;
ip_header->check = ip_fast_csum((u8 *) ip_header, ip_header->ihl);
printk(KERN_INFO "IP addr after change: %u", ip_header->daddr);
return NF_ACCEPT;
}
}
  • Вопрос задан
  • 705 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
Olej
@Olej
инженер, программист, преподаватель
но в заголовки Ethenet прописан MAC - адрес соответствующий первоначальному IP адресу

Так и должно быть, потому что MAC и IP должны соответствовать, соответствие это разрешается через ARP, для ваших RAW-пакетов разрешение ARP не будет работать (ещё хуже, что в кэше ARP стоит старое соответствие).
Добивайтесь точного соответствия MAC и IP.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы