我有一个嵌入式应用程序,将部署在许多第三方系统上,我需要它来检查与其通信的每个目标地址是否使用了确定性和静态源 IP 地址(我知道它将与哪些目标 IP 地址通信) 。
第三方必须保持自由地按照他们认为合适的方式实施他们的 IP 路由(同时遵守这些限制),我只需要检查它是否是确定性和静态的,并且最好知道它会是什么。
它是一个 C 应用程序,但可以在 Solaris 或 Linux 上运行。
我想这可能需要询问路由表?
有什么想法吗?
它对我的工作方式(在 Windows 和 Linux 机器中)是创建一个套接字
SOCK_DGRAM
,并在此套接字上调用 connect()
到所需的目标地址。如果调用成功,则调用 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 也应该这样做。
我假设我们正在谈论传出连接。
应用程序
bind()
的IP地址将是正在使用的源地址。所以它可以完全在应用程序的命令下使用哪个 IP 地址。
无论如何,应用程序可以选择不关心使用哪个 IP 地址,方法是在调用
bind()
之前不明确 connect()
。
路由不会更改源 IP 地址。
另一方面,NAT(网络地址转换)确实会更改源 IP 地址。
ip route get
,您可以添加任何支持的限定符:
例如
ip route get iif eth1 from 1.1.1.1 to 8.8.8.8 dport 666 sport 111
它将向您显示数据包将被路由到的位置并添加缺少的信息(例如本地连接的源 IP)。如果你想在你的应用程序中使用它,请参阅netlink,你可以直接查询内核,无需fork。