get_iface.c revision 200418
1234353Sdim/* 2199481Srdivacky * Copyright 1994, 1995 Massachusetts Institute of Technology 3199481Srdivacky * 4199481Srdivacky * Permission to use, copy, modify, and distribute this software and 5199481Srdivacky * its documentation for any purpose and without fee is hereby 6199481Srdivacky * granted, provided that both the above copyright notice and this 7199481Srdivacky * permission notice appear in all copies, that both the above 8199481Srdivacky * copyright notice and this permission notice appear in all 9199481Srdivacky * supporting documentation, and that the name of M.I.T. not be used 10218893Sdim * in advertising or publicity pertaining to distribution of the 11199481Srdivacky * software without specific, written prior permission. M.I.T. makes 12199481Srdivacky * no representations about the suitability of this software for any 13218893Sdim * purpose. It is provided "as is" without express or implied 14199481Srdivacky * warranty. 15199481Srdivacky * 16199481Srdivacky * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 17199481Srdivacky * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 18199481Srdivacky * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19199481Srdivacky * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 20218893Sdim * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21218893Sdim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22226633Sdim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 23218893Sdim * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24199481Srdivacky * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25199481Srdivacky * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26249423Sdim * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27249423Sdim * SUCH DAMAGE. 28218893Sdim */ 29212904Sdim 30199481Srdivacky#include <sys/cdefs.h> 31199481Srdivacky 32226633Sdim__FBSDID("$FreeBSD: head/usr.bin/talk/get_iface.c 200418 2009-12-11 23:23:57Z delphij $"); 33226633Sdim 34226633Sdim/* 35226633Sdim * From: 36199481Srdivacky * Id: find_interface.c,v 1.1 1995/08/14 16:08:39 wollman Exp 37199481Srdivacky */ 38199481Srdivacky 39199481Srdivacky#include <errno.h> 40212904Sdim#include <string.h> 41199481Srdivacky#include <unistd.h> 42218893Sdim 43208599Srdivacky#include "talk.h" 44218893Sdim 45218893Sdim/* 46199481Srdivacky * Try to find the interface address that is used to route an IP 47199481Srdivacky * packet to a remote peer. 48199481Srdivacky */ 49199481Srdivacky 50199481Srdivackyint 51199481Srdivackyget_iface(struct in_addr *dst, struct in_addr *iface) 52199481Srdivacky{ 53199481Srdivacky static struct sockaddr_in local; 54208599Srdivacky struct sockaddr_in remote; 55208599Srdivacky socklen_t namelen; 56218893Sdim int s, rv; 57218893Sdim 58199481Srdivacky memcpy(&remote.sin_addr, dst, sizeof remote.sin_addr); 59218893Sdim remote.sin_port = htons(60000); 60218893Sdim remote.sin_family = AF_INET; 61218893Sdim remote.sin_len = sizeof remote; 62218893Sdim 63234353Sdim local.sin_addr.s_addr = htonl(INADDR_ANY); 64218893Sdim local.sin_port = htons(60000); 65218893Sdim local.sin_family = AF_INET; 66199481Srdivacky local.sin_len = sizeof local; 67199481Srdivacky 68199481Srdivacky s = socket(PF_INET, SOCK_DGRAM, 0); 69199481Srdivacky if (s < 0) 70208599Srdivacky return -1; 71208599Srdivacky 72208599Srdivacky do { 73208599Srdivacky rv = bind(s, (struct sockaddr *)&local, sizeof local); 74208599Srdivacky local.sin_port = htons(ntohs(local.sin_port) + 1); 75224145Sdim } while(rv < 0 && errno == EADDRINUSE); 76208599Srdivacky 77208599Srdivacky if (rv < 0) { 78208599Srdivacky close(s); 79208599Srdivacky return -1; 80208599Srdivacky } 81218893Sdim 82208599Srdivacky do { 83218893Sdim rv = connect(s, (struct sockaddr *)&remote, sizeof remote); 84208599Srdivacky remote.sin_port = htons(ntohs(remote.sin_port) + 1); 85208599Srdivacky } while(rv < 0 && errno == EADDRINUSE); 86208599Srdivacky 87218893Sdim if (rv < 0) { 88218893Sdim close(s); 89218893Sdim return -1; 90218893Sdim } 91218893Sdim 92218893Sdim namelen = sizeof local; 93218893Sdim rv = getsockname(s, (struct sockaddr *)&local, &namelen); 94218893Sdim close(s); 95218893Sdim if (rv < 0) 96218893Sdim return -1; 97218893Sdim 98218893Sdim memcpy(iface, &local.sin_addr, sizeof local.sin_addr); 99218893Sdim return 0; 100218893Sdim} 101234353Sdim