Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - /*
 - * Get the local address the OS will be (presumably) using
 - * to connect to 'dst_host' and put it into local_addr_buf
 - *
 - * e.g. imagine the application running on a machine
 - * with two interfaces:
 - * eth0, configured with 192.168.0.1/24
 - * lo, configured with 127.0.0.1/8
 - *
 - * Depending on the host we need to connect to
 - * our local address will be different:
 - * if we need to connect to 192.168.0.212, our local address is 192.168.0.1
 - * if we need to connect to 127.0.0.1, our local address is 127.0.0.1
 - * if we're connecting outside on the Internet
 - * and we're behing a router/NAT, we're out of luck.
 - *
 - * Note: we're returning a numeric host as we don't know if our peer's DNS
 - * resolves an hostname to the same IP address as ours.
 - * Note 2: dual stack ready!
 - */
 - int get_local_address(const char *dst_host, char *addr_buf, size_t addr_buf_len, int *is_ipv6)
 - {
 - struct addrinfo *addrinfo, *result;
 - struct addrinfo hints;
 - struct sockaddr_storage local_addr;
 - socklen_t local_addr_len;
 - int sock, s;
 - // First, resolve the destination host
 - // Tell getaddrinfo we are only interested in datagram (UDP socket):
 - // with UDP sockets we can get our local address
 - // without sending a single packet
 - memset(&hints, 0, sizeof(struct addrinfo));
 - hints.ai_family = AF_UNSPEC;
 - hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
 - hints.ai_socktype = SOCK_DGRAM;
 - s = getaddrinfo(dst_host, NULL, &hints, &addrinfo);
 - if (s != 0) {
 - g_message("get_local_address: %s", gai_strerror(s));
 - return -1;
 - }
 - // Iterate all the addresses found for dst_host
 - sock = -1;
 - for (result = addrinfo; result != NULL; result = result->ai_next) {
 - if (sock >= 0) {
 - close(sock);
 - }
 - // Create a socket to test the address
 - sock = socket(result->ai_family, result->ai_socktype,
 - result->ai_protocol);
 - if (sock < 0)
 - continue;
 - // Connect as UDP to our destination address on whatever port
 - // it doesn't matter, we're not sending anything
 - if (connect(sock, result->ai_addr, result->ai_addrlen) < 0) {
 - continue;
 - }
 - // Get our local address
 - local_addr_len = sizeof(struct sockaddr_storage);
 - if (getsockname(sock, (struct sockaddr *)&local_addr, &local_addr_len) < 0) {
 - continue;
 - }
 - // Convert the address to a human-readable string
 - if (getnameinfo((struct sockaddr *)&local_addr, local_addr_len,
 - addr_buf, addr_buf_len,
 - NULL, 0, NI_NUMERICHOST) < 0) {
 - g_message("get_local_address: %s", gai_strerror(s));
 - continue;
 - }
 - if (is_ipv6 != NULL) {
 - if (result->ai_family == AF_INET6) {
 - *is_ipv6 = 1;
 - } else {
 - *is_ipv6 = 0;
 - }
 - }
 - close(sock);
 - return 0;
 - }
 - // Nothing found.
 - g_message("get_local_address: couldn\'t determine local IP address");
 - return -1;
 - }
 
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment