Назад | Перейти на главную страницу

Привязка порта udp в VMware Linux

В моем приложении два физических компьютера, оба в среде Windows. На компьютере 2 (с IP-адресом "192.168.2.2") установлена ​​виртуальная машина VMware Linux (с IP-адресом "192.168.80.129"). Я хочу отправить сокет UDP с виртуальной машины на компьютер 1 (с IP-адресом «192.168.2.1»).

В соответствии с требованиями моего приложения, когда udp отправляется через виртуальную машину на компьютер 2, должны быть указаны порты.

Моя ситуация такова, что когда я создаю и настраиваю сокеты udp в Linux, я указываю два порта LOCAL_PORT (9000) и REMOTE_PORT (9001).

Когда я открываю WireShark для мониторинга, в виртуальной машине Linux исходный порт - LOCAL_PORT (9001), однако порт назначения - «iua (9900)». IP-адрес источника - 192.168.80.129, IP-адрес назначения - 192.168.2.1, что является правильным.

Когда я открываю Wireshark в Windows на компьютере 1 или 2, отображается исходный IP-адрес «192.168.2.2», а IP-адрес назначения - «192.168.2.1». Это кажется понятным, поскольку отправителем является виртуальная машина, поэтому Udp фактически отправляется с главного компьютера (компьютер 2). Порт назначения правильный как 9001, однако порт источника кажется произвольным.

Кто-нибудь знает, что я могу сделать в виртуальной машине, чтобы исходным портом мог быть номер (9900), назначенный вместо произвольного номера? Спасибо!

int sock1; struct sockaddr_in slAddr, myAddr; memset(&slAddr, 0, sizeof(slAddr)); memset(&myAddr, 0, sizeof(myAddr)); slAddr.sin_family = AF_INET; slAddr.sin_port = htons(RM_PORT);//RM_PORT=9900 slAddr.sin_addr.s_addr = inet_addr(SL_IP);//SL_IP="192.168.2.1" myAddr.sin_family = AF_INET; myAddr.sin_port = htons(LC_PORT);//LC_PORT=9901 myAddr.sin_addr.s_addr = inet_addr(MY_IP);//MY_IP="192.168.80.129" sock1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); bind(sock1, (struct sockaddr *)&myAddr, sizeof(myAddr)); sendto(sock1, packeddata, 8, 0, (struct sockaddr*)&slAddr, sizeof(slAddr));

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

Ваша проблема в том, что ваш хост VMWare выполняет NAT для всех исходящих пакетов.

Вам нужен NAT, чтобы переписать исходный IP-адрес вашей виртуальной машины в соответствии с сетью 192.168.2. *. Чтобы сделать это для многих исходных IP-адресов (здесь у вас их два, ваша виртуальная машина и ваша физическая машина), NAT также должен иметь возможность перезаписывать исходный порт. Он использует порт источника, чтобы запомнить, откуда пришел пакет. Вам это не нужно, потому что у вас было только одно приложение, но NAT этого не знает.

(На самом деле, согласно классической терминологии Cisco, вы выполняете PAT, и NAT без перегрузки решит вашу проблему, требуя IP-адрес 192.168.2. *, Выделенный для вашей виртуальной машины, но я не думаю, что кто-то больше использует это ... )

Я не думаю, что VMWare может выполнять NAT, сохраняя исходный порт. Поэтому вам нужно отключить NAT (сделав слой 2 мост между вашей физической LAN и сетевым адаптером вашей виртуальной машины). Это означает, что вам придется дать вашему виртуальному компьютеру IP-адрес с тем же адресом 192.168.2. *, Что и физическим серверам (иначе вам придется выполнять маршрутизацию, что будет намного сложнее).

Что вы сделали (в соответствии с вашим комментарием), так это написать прокси, который привязывается к порту 9901 на главном компьютере. Это ваш прокси-сервер, который переводит IP-адрес из 192.168.80.129 в 192.168.2.2 и обратно, и он сохраняет исходный порт, потому что вы его так написали.

Если в вашем случае это решение подходит вам, то это хорошо!

Обычно в Интернете программы и протоколы пишутся так, чтобы не заботиться об исходном порте; порт источника - это просто номер> 1023, который должен использоваться как порт назначения для ответного пакета. Протоколы, которые действовали иначе (на ум приходят DNS и NTP), эволюционировали, чтобы разрешить нефиксированные исходные порты.