Во-первых, позвольте мне кратко описать проблему. У меня есть две программы, которые отправляют IP-пакеты с хоста (192.168.0.101) на другой хост (192.168.0.106). Эти две программы написаны соответственно на C и C++, но имеют одинаковые функциональные возможности.
Если я запускаю программу C, когда необработанный сокет собирается отправлять IP-пакеты (программа создает IP-пакет без заголовка MAC/Ethernet) с целевым IP-адресом 192.168.0.106, из захваченных tcpdump пакетов, я замечаю, что хост транслирует Запрос ARP для MAC 192.168.0.106, и поэтому он может успешно доставить пакеты на этот хост.
Если я запускаю программу C++, она не передает ARP для запроса MAC 192.168.0.106 и добавляет неправильный заголовок MAC к IP-пакетам и, таким образом, переносит его на неправильный хост (который также связывается с хостом 192.168). .0.101 в сценариях как на С, так и на С ++)
Я действительно озадачен тем фактом, что трансляция ARP происходит в первом сценарии, а не во втором, есть ли потенциальные причины для такой разницы? почему во втором сценарии система не выполняет трансляцию запросов ARP, что приводит к неправильной доставке?
Длинная история:
У меня есть три ноутбука в WLAN, A и C используют wlan0, но B подключен к беспроводному маршрутизатору через кабель и использует eth0.
Я написал программу на C для эксперимента с перехватом TCP, а затем изменил ее на C++.
- A устанавливает TCP-соединение с B
- C запускает программу и маскируется под B, поэтому она отправляет пакеты с src_ip = IP(B) и dst_ip = IP(A)
- Я использую tcpdump для захвата пакетов на A, B и C
- Ожидается, что tcpdump на A может перехватывать пакеты IP-спуфинга. С оригинальной C-программой это так. Но когда я запускаю программу на C++, странно, что tcpdump на B перехватывает пакеты, а tcpdump на A не может.
После некоторого расследования я заметил, что это связано с MAC-адресом. Когда программа на C++ работала, ядро / система добавляет MAC-адрес B в качестве MAC-адреса назначения в пакеты IP-спуфинга (ожидается, что ядро добавляет MAC-адрес A, поскольку IP-адрес назначения имеет A). Тем не менее, я написал пакеты на уровне IP и использовал необработанный сокет, как показано ниже, как в программе на C, так и в программе на C++:
send_sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW));
...
sendto(send_sd, packet, ip_len, 0, (struct sockaddr*)&client_addr, addr_len);
Странно, что когда я запускал эти две программы, ядро / система добавляли разные MAC-адреса назначения. Каковы возможные причины?