Skip to content

Instantly share code, notes, and snippets.

@dberzano
Last active January 3, 2016 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dberzano/8516009 to your computer and use it in GitHub Desktop.
Save dberzano/8516009 to your computer and use it in GitHub Desktop.
Returns the IPv4 address used for outbound connections by means of a "dummy" UDP socket. Tested on Linux and OS X (it should be POSIX compliant).
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
int getoutipv4(std::string *outip) {
if (!outip)
return -1;
int fd;
struct sockaddr_in bind_addr, out_addr, det_addr;
socklen_t det_addr_len;
memset( &bind_addr, 0, sizeof(bind_addr) );
memset( &out_addr, 0, sizeof(out_addr) );
memset( &det_addr, 0, sizeof(det_addr) );
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
return -1;
bind_addr.sin_family = AF_INET;
bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind_addr.sin_port = htons(0);
if ( bind(fd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) < 0 ) {
close(fd);
return -1;
}
out_addr.sin_family = AF_INET;
out_addr.sin_addr.s_addr = inet_addr("1.2.3.4");
out_addr.sin_port = htons(1);
if ( connect(fd, (struct sockaddr *)&out_addr, sizeof(out_addr) ) < 0) {
close(fd);
return -1;
}
det_addr_len = sizeof(det_addr);
if ( getsockname(fd, (struct sockaddr *)&det_addr, &det_addr_len) < 0 ) {
close(fd);
return -1;
}
*outip = inet_ntoa(det_addr.sin_addr);
close(fd);
return 0;
}
int main(int argn, char *argv[]) {
std::string outip;
if ( getoutipv4(&outip) == 0 )
std::cout << outip << std::endl;
else
std::cout << "An error occurred" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment