2 * Check if an address belongs to the local system. Adapted from:
4 * @(#)pmap_svc.c 1.32 91/03/11 Copyright 1984,1990 Sun Microsystems, Inc.
5 * @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC.
9 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
10 * unrestricted use provided that this legend is included on all tape
11 * media and as a part of the software program in whole or part. Users
12 * may copy or modify Sun RPC without charge, but are not authorized
13 * to license or distribute it to anyone else except as part of a product or
14 * program developed by the user or with the express written consent of
15 * Sun Microsystems, Inc.
17 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
18 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
21 * Sun RPC is provided with no support and without any obligation on the
22 * part of Sun Microsystems, Inc. to assist in its use, correction,
23 * modification or enhancement.
25 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
26 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
27 * OR ANY PART THEREOF.
29 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
30 * or profits or other special, indirect and consequential damages, even if
31 * Sun has been advised of the possibility of such damages.
33 * Sun Microsystems, Inc.
35 * Mountain View, California 94043
37 * @(#) from_local.c 1.2 93/11/16 21:50:02
38 * $FreeBSD: src/usr.sbin/portmap/from_local.c,v 1.10.2.1 2000/08/16 14:04:37 brian Exp $
39 * $DragonFly: src/usr.sbin/portmap/from_local.c,v 1.3 2004/03/30 02:58:59 cpressey Exp $
46 #include <sys/types.h>
47 #include <sys/ioctl.h>
48 #include <sys/socket.h>
49 #include <sys/sysctl.h>
52 #include <net/if_dl.h>
53 #include <net/route.h>
54 #include <netinet/in.h>
64 #include "pmap_check.h"
71 #define ROUNDUP(x) ((x) ? (1 + (((x) - 1) | (sizeof(long) - 1))) : sizeof(long))
73 /* How many interfaces could there be on a computer? */
75 #define ESTIMATED_LOCAL 20
76 static int num_local
= -1;
77 static struct in_addr
*addrs
;
80 rtiparse(struct ifa_msghdr
*ifam
, struct rt_addrinfo
*ai
)
85 wp
= (char *)(ifam
+ 1);
87 ai
->rti_addrs
= ifam
->ifam_addrs
;
88 for (rtax
= 0; rtax
< sizeof ai
->rti_info
/ sizeof *ai
->rti_info
; rtax
++)
89 if (ifam
->ifam_addrs
& (1 << rtax
)) {
90 ai
->rti_info
[rtax
] = (struct sockaddr
*)wp
;
91 wp
+= ROUNDUP(ai
->rti_info
[rtax
]->sa_len
);
93 ai
->rti_info
[rtax
] = NULL
;
96 /* find_local - find all IP addresses for this host */
101 int mib
[6], n
, s
, alloced
;
103 char *buf
, *end
, *ptr
;
104 struct if_msghdr
*ifm
;
105 struct ifa_msghdr
*ifam
;
106 struct rt_addrinfo ai
;
108 struct sockaddr_dl
*dl
;
112 mib
[4] = NET_RT_IFLIST
;
113 mib
[2] = mib
[3] = mib
[5] = 0;
115 if ((s
= socket(PF_INET
, SOCK_DGRAM
, 0)) < 0) {
119 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0) {
121 perror("sysctl(NET_RT_IFLIST)");
124 if ((buf
= (char *)malloc(needed
)) == NULL
) {
129 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0) {
132 perror("sysctl(NET_RT_IFLIST)(after malloc)");
144 for (ptr
= buf
; ptr
< end
; ptr
+= ifm
->ifm_msglen
) {
145 ifm
= (struct if_msghdr
*)ptr
;
146 dl
= (struct sockaddr_dl
*)(ifm
+ 1);
148 if (ifm
->ifm_index
!= dl
->sdl_index
|| dl
->sdl_nlen
== 0)
149 /* Skip over remaining ifa_msghdrs */
152 n
= dl
->sdl_nlen
> sizeof ifr
.ifr_name
?
153 sizeof ifr
.ifr_name
: dl
->sdl_nlen
;
154 strncpy(ifr
.ifr_name
, dl
->sdl_data
, n
);
155 if (n
< sizeof ifr
.ifr_name
)
156 ifr
.ifr_name
[n
] = '\0';
158 /* we only want the first address from each interface */
159 if (ioctl(s
, SIOCGIFFLAGS
, &ifr
) < 0)
160 fprintf(stderr
, "%.*s: SIOCGIFFLAGS: %s\n", n
, ifr
.ifr_name
,
162 else if (ifr
.ifr_flags
& IFF_UP
) { /* active interface */
163 ifam
= (struct ifa_msghdr
*)(ptr
+ ifm
->ifm_msglen
);
164 while ((char *)ifam
< end
&& ifam
->ifam_type
== RTM_NEWADDR
) {
167 if (ai
.rti_info
[RTAX_IFA
] != NULL
&&
168 ai
.rti_info
[RTAX_IFA
]->sa_family
== AF_INET
) {
169 if (alloced
< num_local
+ 1) {
170 alloced
+= ESTIMATED_LOCAL
;
171 addrs
= (struct in_addr
*)realloc(addrs
, alloced
* sizeof addrs
[0]);
173 perror("malloc/realloc");
178 addrs
[num_local
++] = ((struct sockaddr_in
*)
179 ai
.rti_info
[RTAX_IFA
])->sin_addr
;
182 ifam
= (struct ifa_msghdr
*)((char *)ifam
+ ifam
->ifam_msglen
);
192 /* from_local - determine whether request comes from the local system */
195 from_local(struct sockaddr_in
*addr
)
199 if (num_local
== -1 && find_local() == 0)
200 syslog(LOG_ERR
, "cannot find any active local network interfaces");
202 for (i
= 0; i
< num_local
; i
++) {
203 if (memcmp((char *) &(addr
->sin_addr
), (char *) &(addrs
[i
]),
204 sizeof(struct in_addr
)) == 0)
213 main(int argc
, char **argv
)
219 for (i
= 0; i
< num_local
; i
++)
220 printf("%s\n", inet_ntoa(addrs
[i
]));