Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programatically determine which source IP address will be used to reach a given destination IP address

I have an embedded application which will be deployed on numerous third party systems and I need it to check that a deterministic and static source IP address is used for each destination address it communicates with (I know which destination IP addresses it will talk to).

The third party must remain free to implement their IP routing how they feel fit (while complying to these constraints), I just need to check that it is deterministic and static and ideally know what it will be.

Its a C application though can run on either Solaris or Linux.

I imagine that this could require interrogation of Routing tables?

Any ideas?

like image 726
Howard May Avatar asked Oct 29 '25 01:10

Howard May


2 Answers

The way it works for me (both in Windows and Linux machines) is to create a socket SOCK_DGRAM, and call connect() on this socket to the desired destination address. If the call is successful, then call getsockname() to get which local address would be used if you sent data over this socket.

Kinda like this (based on working code, error checking removed for brevity):

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 );

Where destination_address is the address you want to reach, source_address should contain the address that the IP stack chose to reach it.

like image 186
Vargas Avatar answered Oct 30 '25 18:10

Vargas


I hope I got you right...

You have to convince these third party administrators to add an additional IP the ethernet port (assumed, there is just one). In your C program you can use bind() to bind your socket to this IP address. Sent packets will have the bound IP as source address. I use this on Linux, but Solaris should do it as well.

like image 22
rockdaboot Avatar answered Oct 30 '25 17:10

rockdaboot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!