Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Aug 1995 11:05:10 -0400
From:      Garrett Wollman <wollman@halloran-eldar.lcs.mit.edu>
To:        freebsd-current@FreeBSD.org (FreeBSD-current users), joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch)
Subject:   workaround for talk's address problem
Message-ID:  <9508071505.AA00541@halloran-eldar.lcs.mit.edu>
In-Reply-To: <199508061603.SAA07779@uriah.heep.sax.de>
References:  <199508061603.SAA07779@uriah.heep.sax.de>

next in thread | previous in thread | raw e-mail | index | archive | help
<<On Sun, 6 Aug 1995 18:03:27 +0200 (MET DST), J Wunsch <j@uriah.heep.sax.de> said:

> The correct solution would be asking the routing socket to see which
> interface address must be used to get in contact with the remote
> peer.

Not necessarily.  The following program figures out which address to
use to contact a host passed on the command line:

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <sysexits.h>

int
main(int argc, char **argv)
{
        struct sockaddr_in local, remote;
        struct hostent *hp;
        int s, rv, namelen;

        argc--, argv++;

        if (!*argv) {
                errx(EX_USAGE, "must supply a hostname");
        }

        hp = gethostbyname(*argv);
        if (!hp) {
                errx(EX_NOHOST, "cannot resolve hostname: %s", *argv);
        }

        memcpy(&remote.sin_addr, hp->h_addr_list[0], sizeof remote.sin_addr);
        remote.sin_port = htons(60000);
        remote.sin_family = AF_INET;
        remote.sin_len = sizeof remote;

        local.sin_addr.s_addr = htonl(INADDR_ANY);
        local.sin_port = htons(60000);
        local.sin_family = AF_INET;
        local.sin_len = sizeof local;

        s = socket(PF_INET, SOCK_DGRAM, 0);
        if (s < 0)
                err(EX_OSERR, "socket");

        do {
                rv = bind(s, (struct sockaddr *)&local, sizeof local);
                local.sin_port++;
        } while(rv < 0 && errno == EADDRINUSE);

        if (rv < 0)
                err(EX_OSERR, "bind");

        do {
                rv = connect(s, (struct sockaddr *)&remote, sizeof remote);
                remote.sin_port++;
        } while(rv < 0 && errno == EADDRINUSE);

        if (rv < 0)
                err(EX_OSERR, "connect");

        namelen = sizeof local;
        rv = getsockname(s, (struct sockaddr *)&local, &namelen);
        if (rv < 0)
                err(EX_OSERR, "getsockname");

        printf("Route to %s is out %s\n", *argv, inet_ntoa(local.sin_addr));
        return 0;
}

-GAWollman

--
Garrett A. Wollman   | Shashish is simple, it's discreet, it's brief. ... 
wollman@lcs.mit.edu  | Shashish is the bonding of hearts in spite of distance.
Opinions not those of| It is a bond more powerful than absence.  We like people
MIT, LCS, ANA, or NSA| who like Shashish.  - Claude McKenzie + Florent Vollant



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9508071505.AA00541>