Если у вас есть несколько интерфейсов (один из которых имеет правильный ip), конечно, вы можете привязать интерфейс к исходящему ответу. Взгляните на параметр сокета SO_BINDTODEVICE.
int bind_sock2inf(int sock, char *interface_name)
{
int status = -1;
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), interface_name);
if ( (status = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
(void *)&ifr, sizeof(ifr))) < 0) {
log_debug(4, "Failed binding to interface named %s", inf_name);
}
else log_debug(3, "Binding to interface %s", inf_name);
return status;
}
Теперь ваш исходящий запрос должен автоматически использовать IP-адрес, связанный с этим интерфейсом. Единственным недостатком является то, что вы перестаете получать сообщения на любом другом интерфейсе для этого сокета.
Возможные обходные пути:
Используйте отдельный сокет для прослушивания, который не привязан к какому-либо интерфейсу, и другой для отправки и привязки к любому интерфейсу, который вам нужен перед отправкой.
Привязать к интерфейсу перед отправкой сообщения и снова привязать к «», что сразу после отправки очищает предыдущее связывание. Однако вы можете потерять все пакеты, полученные в течение этого периода времени, к которому ваш сокет должен был подключиться, скажем, eth0, и пакеты пришли в eth1.
Также вы можете просто использовать bind () для привязки исходного IP-адреса для исходящего пакета.