我有一个嵌入式应用程序,它将部署在许多第三方系统上,我需要它来检查它与之通信的每个目标地址是否使用了确定性和静态源 IP 地址(我知道它将与哪些目标 IP 地址通信)。
第三方必须保持自由,以他们认为合适的方式实施其 IP 路由(同时遵守这些限制),我只需要检查它是否是确定性和静态的,并且理想情况下知道它将是什么。
它是一个 C 应用程序,但可以在 Solaris 或 Linux 上运行。
我想这可能需要询问路由表?
有任何想法吗?
它对我的工作方式(在 Windows 和 Linux 机器上)是创建一个 socket SOCK_DGRAM
,并connect()
在这个 socket 上调用所需的目标地址。如果调用成功,则调用getsockname()
以获取通过此套接字发送数据时将使用的本地地址。
有点像这样(基于工作代码,为简洁起见删除了错误检查):
const char * destination_address = "8.8.8.8";
sockaddr_storage Addr = { 0 };
unsigned long addr = inet_addr( destination_address );
( ( struct sockaddr_in * ) &Addr)->sin_addr.s_addr = addr;
( ( struct sockaddr_in * ) &Addr)->sin_family = AF_INET;
( ( struct sockaddr_in * ) &Addr)->sin_port = htons( 9 ); //9 is discard port
int Handle = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
socklen_t AddrLen = sizeof(Addr);
connect( Handle, (sockaddr*)&Addr, AddrLen);
getsockname(Handle, (sockaddr*)&Addr, &AddrLen);
char* source_address = inet_ntoa(((struct sockaddr_in *)&Addr)->sin_addr);
printf( "source address: %s\n", source_address );
destination_address
您要到达的地址在哪里,source_address
应该包含 IP 堆栈选择到达它的地址。
我希望我没听错...
您必须说服这些第三方管理员在以太网端口上添加一个额外的 IP(假设只有一个)。在您的 C 程序中,您可以使用 bind() 将您的套接字绑定到该 IP 地址。发送的数据包将以绑定的 IP 作为源地址。我在 Linux 上使用它,但 Solaris 也应该这样做。
我假设我们正在谈论传出连接。
应用程序的 ip 地址bind()
将是正在使用的源地址。所以它可以完全在应用程序的命令下使用哪个 ip-address。
无论如何,应用程序可以bind()
通过在调用connect()
.
路由不会改变源 IP 地址。
另一方面,NAT(网络地址转换)确实改变了源 IP 地址。