functions to detect the local IP to use

the mechanism used is very simple:
 - create a temporary UDP socket
 - connect it to the remote destination
 - use getsockname to read the local IP
sayer/1.4-spce2.6
Raphael Coeffic 16 years ago
parent 5d5adb0e2e
commit 6dd81ab3e6

@ -847,6 +847,85 @@ int write_to_socket(int sd, const char* to_addr, const char * buf, unsigned int
return ret;
}
int get_local_addr_for_dest(sockaddr_storage* remote_ip, sockaddr_storage* local)
{
int temp_sock = socket(remote_ip->ss_family, SOCK_DGRAM, 0 );
if (temp_sock == -1) {
ERROR("socket() failed: %s\n",
strerror(errno));
return -1;
}
socklen_t len=sizeof(sockaddr_storage);
if (connect(temp_sock, (sockaddr*)remote_ip,
remote_ip->ss_family == AF_INET ?
sizeof(sockaddr_in) : sizeof(sockaddr_in6))==-1) {
ERROR("connect failed: %s\n",
strerror(errno));
goto error;
}
if (getsockname(temp_sock, (sockaddr*)local, &len)==-1) {
ERROR("getsockname failed: %s\n",
strerror(errno));
goto error;
}
close(temp_sock);
return 0;
error:
close(temp_sock);
return -1;
}
int get_local_addr_for_dest(const string& remote_ip, string& local)
{
sockaddr_storage remote_ip_ss;
sockaddr_storage local_ss;
int err = inet_pton(AF_INET,remote_ip.c_str(),&((sockaddr_in*)&remote_ip_ss)->sin_addr);
if(err == 1){
remote_ip_ss.ss_family = AF_INET;
}
else if(err == 0){
err = inet_pton(AF_INET6,remote_ip.c_str(),&((sockaddr_in6*)&remote_ip_ss)->sin6_addr);
if(err == 1){
remote_ip_ss.ss_family = AF_INET6;
}
}
if(err == 0){
ERROR("Wrong address format: '%s'",remote_ip.c_str());
return -1;
}
else if(err == -1){
ERROR("While converting address: %s",strerror(errno));
return -1;
}
err = get_local_addr_for_dest(&remote_ip_ss, &local_ss);
if(err < 0){
return -1;
}
return ip_addr_to_str(&local_ss,local);
}
int ip_addr_to_str(sockaddr_storage* ss, string& addr)
{
char ntop_buffer[INET6_ADDRSTRLEN];
if(!inet_ntop(ss->ss_family, &((sockaddr_in*)ss)->sin_addr,
ntop_buffer,INET6_ADDRSTRLEN)) {
ERROR("Could not convert address to string: %s",strerror(errno));
return -1;
}
addr = string(ntop_buffer);
return 0;
}
string extract_tag(const string& addr)
{

@ -33,6 +33,7 @@
#include <errno.h>
#include <sys/types.h>
#include <regex.h>
#include <sys/socket.h>
#include <string>
using std::string;
@ -308,6 +309,19 @@ short get_port_v6(struct sockaddr_storage* ss);
int write_to_fifo(const string& fifo, const char * buf, unsigned int len);
int write_to_socket(int sd, const char* to_addr, const char * buf, unsigned int len);
/*
* Computes the local address for a specific destination address.
* This is done by opening a connected UDP socket and reading the
* local address with getsockname().
*/
int get_local_addr_for_dest(sockaddr_storage* remote_ip, sockaddr_storage* local);
int get_local_addr_for_dest(const string& remote_ip, string& local);
/**
* Converts an IP address contained in a sockaddr_storage into a string.
*/
int ip_addr_to_str(sockaddr_storage* ss, string& addr);
string extract_tag(const string& addr);
/** returns true if key is in s_list, a list of items delimited by list_delim

Loading…
Cancel
Save