xref: /openbsd-src/lib/libc/rpc/get_myaddress.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: get_myaddress.c,v 1.12 2005/08/08 08:05:35 espie Exp $ */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30 
31 /*
32  * get_myaddress.c
33  *
34  * Get client's IP address via ioctl.  This avoids using the yellowpages.
35  * Copyright (C) 1984, Sun Microsystems, Inc.
36  */
37 
38 #include <rpc/types.h>
39 #include <rpc/xdr.h>
40 #include <rpc/pmap_prot.h>
41 #include <sys/socket.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <net/if.h>
46 #include <netinet/in.h>
47 #include <ifaddrs.h>
48 
49 /*
50  * don't use gethostbyname, which would invoke yellow pages
51  *
52  * Avoid loopback interfaces.  We return information from a loopback
53  * interface only if there are no other possible interfaces.
54  */
55 int
56 get_myaddress(struct sockaddr_in *addr)
57 {
58 	struct ifaddrs *ifap, *ifa;
59 	int loopback = 0, gotit = 0;
60 
61 	if (getifaddrs(&ifap) != 0)
62 		return (-1);
63 
64   again:
65 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
66 		if ((ifa->ifa_flags & IFF_UP) &&
67 		    ifa->ifa_addr->sa_family == AF_INET &&
68 		    (loopback == 1 && (ifa->ifa_flags & IFF_LOOPBACK))) {
69 			*addr = *((struct sockaddr_in *)ifa->ifa_addr);
70 			addr->sin_port = htons(PMAPPORT);
71 			gotit = 1;
72 			break;
73 		}
74 	}
75 	if (gotit == 0 && loopback == 0) {
76 		loopback = 1;
77 		goto again;
78 	}
79 	freeifaddrs(ifap);
80 	return (0);
81 }
82