2014-01-22 3 views
1

Я разрабатываю приложение, которое выполняет NAT между двумя сетевыми интерфейсами на компьютере под управлением Windows, и у меня есть небольшая проблема с пониманием того, что происходит.NAT-реализация

Есть 2 сетевые интерфейсы в системе:

  • физический сетевой интерфейс (00: 0c: 29: BC: 4с: 11 192.168.133.130), который использует в качестве шлюза 00:50:56: eb: f5: 15 - 192.168.133.2 (управляется VMware)
  • виртуальный сетевой интерфейс TAP (00: ff: 15: 08: ac: 26 192.168.200.100), используемый моим приложением, использующим в качестве шлюза 03:03 : 03: 03: 03: 03 - 192.168.200.1 (управляемый мое приложение)

Что мое приложение делает:

  • отвечает на ARP запросы 192.168.200.1 (виртуальный шлюз)
  • выполняет один-к-одному NAT для ICMP, UDP и TCP между интерфейсом TAP и физическим

Чтобы продемонстрировать то, что Продолжайте. Я приложил .cap file с пакетами, снятыми Microsoft Network Monitor 3.4 (его также можно открыть Wireshark) во время теста. Тест состоит в установлении TCP-соединения с google.com:80. Сначала соединение устанавливается непосредственно через физический интерфейс, чтобы доказать, что есть подключение к Интернету, а затем соединение устанавливается через интерфейс TAP для тестирования NAT.

Анализ пакетов сверху вниз:

  • 1 - TCP SYN отправлен на google.com непосредственно через физический интерфейс
  • 2 - TCP SYN-ACK, полученного от google.com через физический, если
  • 3 - TCP-ACK отправлен на google.com через физический если
  • 4 - TCP RST-ACK отправлен на google.com через физическое, если, чтобы закрыть соединение

Все хорошо, у нас есть подключение к интернету. Теперь я могу изменить шлюз по умолчанию, виртуальный маршрутизатор управляется мое приложение (192.168.200.1)

  • 5 - Windows замечает шлюз по умолчанию изменен на 192.168.200.1 и отправляет запрос ARP на 192.168.200.1
  • 6 - мое приложение сообщает, что 192.168.200.1 находится в 03: 03: 03: 03: 03: 03
  • 7 - TCP SYN отправлен на google.com через интерфейс TAP (192.168.200.100) на виртуальный маршрутизатор (192.168. 200.1)
  • 8 - мое приложение выполняет NAT на пакете (соответственно изменяется исходный и целевой MAC-адрес, а IP-адрес источника изменяется на 192.168.133.130) и отправляет пакет на физическое cal to 00: 50: 56: eb: f5: 15 (192.168.133.2)
  • 9 - ответ не получен, поэтому второй TCP SYN посылается на кране, если
  • 10 - мое приложение выполняет NAT, так же, как и посылает пакет на физическом если
  • 11 - опять нет ответа, поэтому третья попытка
  • 12 - мое приложение выполняет NAT таким же образом

После NAT, пакет, который посылается на физический интерфейс, практически идентичен тому, который послал в первом тесте, и в топологии сети ничего не меняется. Почему второе соединение TCP не увенчалось успехом? Это не имеет никакого смысла.

Программа использует WinPcap. Here - код, если он заинтересован.

ответ

1

Я проверил захваченный файл, и я не вижу разницы на уровнях уровня TCP и MAC-уровня (между успешным SYN и неудачным). Только я вижу, что в успешном SYN контрольная сумма IP-заголовка равна 0, вероятно, потому, что вычисление выгружено на интерфейсную карту. В неудачной SYN контрольная сумма рассчитывается и корректируется согласно Wireshark. Это не должно быть проблемой, если контрольная сумма правильная. Это единственное различие, которое я вижу на уровне IP.

Я бы сказал, что либо Google, либо кто-то посередине фильтрует ваши следующие сообщения.

Теперь, что-то странное для меня, поэтому, когда ваше приложение закрывает сокет в индексе потока 0, оно отправляет RST вместо FIN. Может быть, какой-то узел пытается предотвратить атаку RST с вашего IP-адреса? Есть ли способ закрыть сокет и отправить сообщение [FIN, ACK]? Можете ли вы подождать больше времени, прежде чем запускать второй тест?

Другая странность в том, что во втором тесте оба соединения 192.168.200.100-ваше приложение (03: 03: 03: 03: 03: 03) и «ваше приложение» -Google использует тот же исходный порт 49181. Это не означает, t кажется проблемой, потому что это две разные машины, но я бы исследовал там как очень последний ресурс. Я не думаю, что это проблема.

Отредактировано:

После объяснил TCP сегмент сдавал неизмененной я понял, проблема в том, что вы не пересчитывая TCP контрольной суммы !!! Оба SYN-сообщения (кадры 7 и 8) имеют одну и ту же контрольную сумму TCP. Если IP-адреса меняются, контрольная сумма TCP должна измениться.

BTW, это очень интересная проблема.

+0

Тестовое приложение использует Ws2_32 \ socket и Ws2_32 \ подключает функции WinAPI для установления TCP-соединения. После этого тестовое приложение закрывается, сокет умирает, а Windows отправляет RST. Это не проблема. Я могу запустить 2 последовательных успешных теста, используя физическое if. Порт не переводится, потому что это индивидуальный NAT (на данный момент), поэтому изменяется только IP, TCP нетронутый. – Chris

+1

Эй! Проблема в том, что вы не пересчитываете контрольную сумму TCP !!! Оба SYN-сообщения (кадры 7 и 8) имеют одну и ту же контрольную сумму TCP. Если IP-адреса меняются, контрольная сумма TCP должна измениться. Я отредактирую свой ответ. – rodolk

+0

Вы правы! Я включил «Проверка контрольной суммы TCP» в Wireshark, а пакет 8 имеет недопустимую контрольную сумму TCP. Но почему? Пакет TCP не изменился, и контрольная сумма TCP включает только заголовок и данные TCP. Контрольная сумма TCP также включает заголовок IP? – Chris