1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright (c) 1999 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate * All rights reserved.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <syslog.h>
32*0Sstevel@tonic-gate #include <sys/types.h>
33*0Sstevel@tonic-gate #include <sys/socket.h>
34*0Sstevel@tonic-gate #include <sys/sockio.h>
35*0Sstevel@tonic-gate #include <arpa/inet.h>
36*0Sstevel@tonic-gate #include <net/if.h>
37*0Sstevel@tonic-gate #include <unistd.h>
38*0Sstevel@tonic-gate #include <netdb.h>
39*0Sstevel@tonic-gate #include <nss_dbdefs.h>
40*0Sstevel@tonic-gate #include <slp-internal.h>
41*0Sstevel@tonic-gate #include <slp_net_utils.h>
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate typedef struct slp_ifinfo {
44*0Sstevel@tonic-gate struct sockaddr_in addr;
45*0Sstevel@tonic-gate struct sockaddr_in netmask;
46*0Sstevel@tonic-gate struct sockaddr_in bc_addr;
47*0Sstevel@tonic-gate short flags;
48*0Sstevel@tonic-gate } slp_ifinfo_t;
49*0Sstevel@tonic-gate
50*0Sstevel@tonic-gate typedef struct slp_handle_ifinfo {
51*0Sstevel@tonic-gate slp_ifinfo_t *all_ifs;
52*0Sstevel@tonic-gate int numifs;
53*0Sstevel@tonic-gate } slp_handle_ifinfo_t;
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate static SLPError get_all_interfaces(slp_handle_ifinfo_t *info);
57*0Sstevel@tonic-gate
58*0Sstevel@tonic-gate /*
59*0Sstevel@tonic-gate * Obtains the broadcast addresses for all local interfaces given in
60*0Sstevel@tonic-gate * addrs.
61*0Sstevel@tonic-gate *
62*0Sstevel@tonic-gate * hp IN / OUT holds cached-per-handle if info
63*0Sstevel@tonic-gate * given_ifs IN an array of local interfaces
64*0Sstevel@tonic-gate * num_givenifs IN number of addresses in given_ifs
65*0Sstevel@tonic-gate * bc_addrs OUT an array of broadcast addresses for local interfaces
66*0Sstevel@tonic-gate * num_addrs OUT number of addrs returned in bc_addrs
67*0Sstevel@tonic-gate *
68*0Sstevel@tonic-gate * Returns SLP_OK if at least one broadcast address was found; if none
69*0Sstevel@tonic-gate * were found, returns err != SLP_OK and *bc_addrs = NULL;
70*0Sstevel@tonic-gate * Caller must free *bc_addrs when done.
71*0Sstevel@tonic-gate */
slp_broadcast_addrs(slp_handle_impl_t * hp,struct in_addr * given_ifs,int num_givenifs,struct sockaddr_in * bc_addrs[],int * num_addrs)72*0Sstevel@tonic-gate SLPError slp_broadcast_addrs(slp_handle_impl_t *hp, struct in_addr *given_ifs,
73*0Sstevel@tonic-gate int num_givenifs,
74*0Sstevel@tonic-gate struct sockaddr_in *bc_addrs[],
75*0Sstevel@tonic-gate int *num_addrs) {
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gate SLPError err;
78*0Sstevel@tonic-gate int i, j;
79*0Sstevel@tonic-gate slp_ifinfo_t *all_ifs;
80*0Sstevel@tonic-gate slp_handle_ifinfo_t *ifinfo;
81*0Sstevel@tonic-gate int numifs;
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gate if (!hp->ifinfo) {
84*0Sstevel@tonic-gate if (!(ifinfo = malloc(sizeof (*ifinfo)))) {
85*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_broadcast_addrs",
86*0Sstevel@tonic-gate "out of memory");
87*0Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
88*0Sstevel@tonic-gate }
89*0Sstevel@tonic-gate if ((err = get_all_interfaces(ifinfo)) != SLP_OK) {
90*0Sstevel@tonic-gate free(ifinfo);
91*0Sstevel@tonic-gate return (err);
92*0Sstevel@tonic-gate }
93*0Sstevel@tonic-gate hp->ifinfo = ifinfo;
94*0Sstevel@tonic-gate }
95*0Sstevel@tonic-gate all_ifs = ((slp_handle_ifinfo_t *)hp->ifinfo)->all_ifs;
96*0Sstevel@tonic-gate numifs = ((slp_handle_ifinfo_t *)hp->ifinfo)->numifs;
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gate /* allocate memory for reply */
99*0Sstevel@tonic-gate if (!(*bc_addrs = calloc(num_givenifs, sizeof (**bc_addrs)))) {
100*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_broadcast_addrs", "out of memory");
101*0Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
102*0Sstevel@tonic-gate }
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gate /* copy bc addrs for all desired interfaces which are bc-enabled */
105*0Sstevel@tonic-gate *num_addrs = 0;
106*0Sstevel@tonic-gate for (j = 0; j < num_givenifs; j++) {
107*0Sstevel@tonic-gate for (i = 0; i < numifs; i++) {
108*0Sstevel@tonic-gate
109*0Sstevel@tonic-gate if (!(all_ifs[i].flags & IFF_BROADCAST)) {
110*0Sstevel@tonic-gate continue;
111*0Sstevel@tonic-gate }
112*0Sstevel@tonic-gate
113*0Sstevel@tonic-gate if (memcmp(&(all_ifs[i].addr.sin_addr.s_addr),
114*0Sstevel@tonic-gate &(given_ifs[j].s_addr),
115*0Sstevel@tonic-gate sizeof (given_ifs[j].s_addr)) == 0 &&
116*0Sstevel@tonic-gate all_ifs[i].bc_addr.sin_addr.s_addr != 0) {
117*0Sstevel@tonic-gate
118*0Sstevel@tonic-gate /* got it, so copy it to bc_addrs */
119*0Sstevel@tonic-gate (void) memcpy(
120*0Sstevel@tonic-gate *bc_addrs + *num_addrs,
121*0Sstevel@tonic-gate &(all_ifs[i].bc_addr),
122*0Sstevel@tonic-gate sizeof (all_ifs[i].bc_addr));
123*0Sstevel@tonic-gate (*num_addrs)++;
124*0Sstevel@tonic-gate
125*0Sstevel@tonic-gate break;
126*0Sstevel@tonic-gate }
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate }
129*0Sstevel@tonic-gate
130*0Sstevel@tonic-gate if (*num_addrs == 0) {
131*0Sstevel@tonic-gate /* none found */
132*0Sstevel@tonic-gate free (*bc_addrs);
133*0Sstevel@tonic-gate bc_addrs = NULL;
134*0Sstevel@tonic-gate return (SLP_INTERNAL_SYSTEM_ERROR);
135*0Sstevel@tonic-gate }
136*0Sstevel@tonic-gate return (SLP_OK);
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate
139*0Sstevel@tonic-gate /*
140*0Sstevel@tonic-gate * Returns true if addr is on a subnet local to the local host.
141*0Sstevel@tonic-gate */
slp_on_subnet(slp_handle_impl_t * hp,struct in_addr addr)142*0Sstevel@tonic-gate SLPBoolean slp_on_subnet(slp_handle_impl_t *hp, struct in_addr addr) {
143*0Sstevel@tonic-gate int i;
144*0Sstevel@tonic-gate struct in_addr netmask, net_addr, masked_addr;
145*0Sstevel@tonic-gate slp_ifinfo_t *all_ifs;
146*0Sstevel@tonic-gate slp_handle_ifinfo_t *ifinfo;
147*0Sstevel@tonic-gate int numifs;
148*0Sstevel@tonic-gate
149*0Sstevel@tonic-gate if (!hp->ifinfo) {
150*0Sstevel@tonic-gate if (!(ifinfo = malloc(sizeof (*ifinfo)))) {
151*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_broadcast_addrs",
152*0Sstevel@tonic-gate "out of memory");
153*0Sstevel@tonic-gate return (SLP_FALSE);
154*0Sstevel@tonic-gate }
155*0Sstevel@tonic-gate if (get_all_interfaces(ifinfo) != SLP_OK) {
156*0Sstevel@tonic-gate free(ifinfo);
157*0Sstevel@tonic-gate return (SLP_FALSE);
158*0Sstevel@tonic-gate }
159*0Sstevel@tonic-gate hp->ifinfo = ifinfo;
160*0Sstevel@tonic-gate }
161*0Sstevel@tonic-gate all_ifs = ((slp_handle_ifinfo_t *)hp->ifinfo)->all_ifs;
162*0Sstevel@tonic-gate numifs = ((slp_handle_ifinfo_t *)hp->ifinfo)->numifs;
163*0Sstevel@tonic-gate
164*0Sstevel@tonic-gate for (i = 0; i < numifs; i++) {
165*0Sstevel@tonic-gate /* get netmask */
166*0Sstevel@tonic-gate netmask.s_addr = all_ifs[i].netmask.sin_addr.s_addr;
167*0Sstevel@tonic-gate /* get network address */
168*0Sstevel@tonic-gate net_addr.s_addr =
169*0Sstevel@tonic-gate all_ifs[i].addr.sin_addr.s_addr & netmask.s_addr;
170*0Sstevel@tonic-gate /* apply netmask to input addr */
171*0Sstevel@tonic-gate masked_addr.s_addr = addr.s_addr & netmask.s_addr;
172*0Sstevel@tonic-gate
173*0Sstevel@tonic-gate if (memcmp(&(masked_addr.s_addr), &(net_addr.s_addr),
174*0Sstevel@tonic-gate sizeof (net_addr.s_addr)) == 0) {
175*0Sstevel@tonic-gate return (SLP_TRUE);
176*0Sstevel@tonic-gate }
177*0Sstevel@tonic-gate }
178*0Sstevel@tonic-gate
179*0Sstevel@tonic-gate return (SLP_FALSE);
180*0Sstevel@tonic-gate }
181*0Sstevel@tonic-gate
182*0Sstevel@tonic-gate /*
183*0Sstevel@tonic-gate * Returns true if any local interface if configured with addr.
184*0Sstevel@tonic-gate */
slp_on_localhost(slp_handle_impl_t * hp,struct in_addr addr)185*0Sstevel@tonic-gate SLPBoolean slp_on_localhost(slp_handle_impl_t *hp, struct in_addr addr) {
186*0Sstevel@tonic-gate int i;
187*0Sstevel@tonic-gate slp_ifinfo_t *all_ifs;
188*0Sstevel@tonic-gate slp_handle_ifinfo_t *ifinfo;
189*0Sstevel@tonic-gate int numifs;
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate if (!hp->ifinfo) {
192*0Sstevel@tonic-gate if (!(ifinfo = malloc(sizeof (*ifinfo)))) {
193*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_broadcast_addrs",
194*0Sstevel@tonic-gate "out of memory");
195*0Sstevel@tonic-gate return (SLP_FALSE);
196*0Sstevel@tonic-gate }
197*0Sstevel@tonic-gate if (get_all_interfaces(ifinfo) != SLP_OK) {
198*0Sstevel@tonic-gate free(ifinfo);
199*0Sstevel@tonic-gate return (SLP_FALSE);
200*0Sstevel@tonic-gate }
201*0Sstevel@tonic-gate hp->ifinfo = ifinfo;
202*0Sstevel@tonic-gate }
203*0Sstevel@tonic-gate all_ifs = ((slp_handle_ifinfo_t *)hp->ifinfo)->all_ifs;
204*0Sstevel@tonic-gate numifs = ((slp_handle_ifinfo_t *)hp->ifinfo)->numifs;
205*0Sstevel@tonic-gate
206*0Sstevel@tonic-gate for (i = 0; i < numifs; i++) {
207*0Sstevel@tonic-gate if (memcmp(&(addr.s_addr), &(all_ifs[i].addr.sin_addr.s_addr),
208*0Sstevel@tonic-gate sizeof (addr)) == 0) {
209*0Sstevel@tonic-gate
210*0Sstevel@tonic-gate return (SLP_TRUE);
211*0Sstevel@tonic-gate }
212*0Sstevel@tonic-gate }
213*0Sstevel@tonic-gate
214*0Sstevel@tonic-gate return (SLP_FALSE);
215*0Sstevel@tonic-gate }
216*0Sstevel@tonic-gate
slp_free_ifinfo(void * hi)217*0Sstevel@tonic-gate void slp_free_ifinfo(void *hi) {
218*0Sstevel@tonic-gate free(((slp_handle_ifinfo_t *)hi)->all_ifs);
219*0Sstevel@tonic-gate }
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate /*
222*0Sstevel@tonic-gate * Populates all_ifs.
223*0Sstevel@tonic-gate */
get_all_interfaces(slp_handle_ifinfo_t * info)224*0Sstevel@tonic-gate static SLPError get_all_interfaces(slp_handle_ifinfo_t *info) {
225*0Sstevel@tonic-gate int i, n, s = 0;
226*0Sstevel@tonic-gate int numifs;
227*0Sstevel@tonic-gate char *buf = NULL;
228*0Sstevel@tonic-gate size_t bufsize;
229*0Sstevel@tonic-gate struct ifconf ifc;
230*0Sstevel@tonic-gate struct ifreq *ifrp, ifr;
231*0Sstevel@tonic-gate slp_ifinfo_t *all_ifs = NULL;
232*0Sstevel@tonic-gate SLPError err = SLP_OK;
233*0Sstevel@tonic-gate
234*0Sstevel@tonic-gate /* create a socket with which to get interface info */
235*0Sstevel@tonic-gate if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
236*0Sstevel@tonic-gate goto cleanup;
237*0Sstevel@tonic-gate }
238*0Sstevel@tonic-gate
239*0Sstevel@tonic-gate /* how many interfaces are configured? */
240*0Sstevel@tonic-gate if (ioctl(s, SIOCGIFNUM, (char *)&numifs) < 0) {
241*0Sstevel@tonic-gate goto cleanup;
242*0Sstevel@tonic-gate }
243*0Sstevel@tonic-gate
244*0Sstevel@tonic-gate /* allocate memory for ifinfo_t array */
245*0Sstevel@tonic-gate if (!(all_ifs = calloc(numifs, sizeof (*all_ifs)))) {
246*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "get_all_interfaces", "out of memory");
247*0Sstevel@tonic-gate err = SLP_MEMORY_ALLOC_FAILED;
248*0Sstevel@tonic-gate goto cleanup;
249*0Sstevel@tonic-gate }
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate /* allocate memory for interface info */
252*0Sstevel@tonic-gate bufsize = numifs * sizeof (struct ifreq);
253*0Sstevel@tonic-gate if (!(buf = malloc(bufsize))) {
254*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "get_all_interfaces", "out of memory");
255*0Sstevel@tonic-gate err = SLP_MEMORY_ALLOC_FAILED;
256*0Sstevel@tonic-gate goto cleanup;
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate
259*0Sstevel@tonic-gate /* get if info */
260*0Sstevel@tonic-gate ifc.ifc_len = bufsize;
261*0Sstevel@tonic-gate ifc.ifc_buf = buf;
262*0Sstevel@tonic-gate if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
263*0Sstevel@tonic-gate goto cleanup;
264*0Sstevel@tonic-gate }
265*0Sstevel@tonic-gate
266*0Sstevel@tonic-gate ifrp = ifc.ifc_req;
267*0Sstevel@tonic-gate i = 0;
268*0Sstevel@tonic-gate for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifrp++) {
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate /* ignore if interface is not up */
271*0Sstevel@tonic-gate (void) memset((char *)&ifr, 0, sizeof (ifr));
272*0Sstevel@tonic-gate (void) strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof (ifr.ifr_name));
273*0Sstevel@tonic-gate if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
274*0Sstevel@tonic-gate continue;
275*0Sstevel@tonic-gate }
276*0Sstevel@tonic-gate if (!(ifr.ifr_flags & IFF_UP)) {
277*0Sstevel@tonic-gate continue;
278*0Sstevel@tonic-gate }
279*0Sstevel@tonic-gate
280*0Sstevel@tonic-gate all_ifs[i].flags = ifr.ifr_flags;
281*0Sstevel@tonic-gate
282*0Sstevel@tonic-gate /* get the interface's address */
283*0Sstevel@tonic-gate if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
284*0Sstevel@tonic-gate continue;
285*0Sstevel@tonic-gate }
286*0Sstevel@tonic-gate
287*0Sstevel@tonic-gate (void) memcpy(&(all_ifs[i].addr), &ifr.ifr_addr,
288*0Sstevel@tonic-gate sizeof (all_ifs[i].addr));
289*0Sstevel@tonic-gate
290*0Sstevel@tonic-gate /* get the interface's broadcast address */
291*0Sstevel@tonic-gate if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
292*0Sstevel@tonic-gate (void) memset(&(all_ifs[i].bc_addr), 0,
293*0Sstevel@tonic-gate sizeof (all_ifs[i].bc_addr));
294*0Sstevel@tonic-gate } else {
295*0Sstevel@tonic-gate (void) memcpy(&(all_ifs[i].bc_addr), &ifr.ifr_addr,
296*0Sstevel@tonic-gate sizeof (all_ifs[i].bc_addr));
297*0Sstevel@tonic-gate }
298*0Sstevel@tonic-gate
299*0Sstevel@tonic-gate /* get the interface's subnet mask */
300*0Sstevel@tonic-gate if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
301*0Sstevel@tonic-gate (void) memset(&(all_ifs[i].netmask), 0,
302*0Sstevel@tonic-gate sizeof (all_ifs[i].netmask));
303*0Sstevel@tonic-gate } else {
304*0Sstevel@tonic-gate (void) memcpy(&(all_ifs[i].netmask), &ifr.ifr_addr,
305*0Sstevel@tonic-gate sizeof (all_ifs[i].netmask));
306*0Sstevel@tonic-gate }
307*0Sstevel@tonic-gate
308*0Sstevel@tonic-gate i++;
309*0Sstevel@tonic-gate }
310*0Sstevel@tonic-gate
311*0Sstevel@tonic-gate /* i contains the number we actually got info on */
312*0Sstevel@tonic-gate info->numifs = i;
313*0Sstevel@tonic-gate info->all_ifs = all_ifs;
314*0Sstevel@tonic-gate
315*0Sstevel@tonic-gate if (i == 0) {
316*0Sstevel@tonic-gate err = SLP_INTERNAL_SYSTEM_ERROR;
317*0Sstevel@tonic-gate free(all_ifs);
318*0Sstevel@tonic-gate info->all_ifs = NULL;
319*0Sstevel@tonic-gate }
320*0Sstevel@tonic-gate
321*0Sstevel@tonic-gate cleanup:
322*0Sstevel@tonic-gate if (s) (void) close(s);
323*0Sstevel@tonic-gate if (buf) free(buf);
324*0Sstevel@tonic-gate
325*0Sstevel@tonic-gate return (err);
326*0Sstevel@tonic-gate }
327*0Sstevel@tonic-gate
328*0Sstevel@tonic-gate /*
329*0Sstevel@tonic-gate * Converts a SLPSrvURL to a network address. 'sa' must have been
330*0Sstevel@tonic-gate * allocated by the caller.
331*0Sstevel@tonic-gate * Assumes that addresses are given as specified in the protocol spec,
332*0Sstevel@tonic-gate * i.e. as IP addresses and not host names.
333*0Sstevel@tonic-gate */
slp_surl2sin(SLPSrvURL * surl,struct sockaddr_in * sa)334*0Sstevel@tonic-gate SLPError slp_surl2sin(SLPSrvURL *surl, struct sockaddr_in *sa) {
335*0Sstevel@tonic-gate struct sockaddr_in *sin = (struct sockaddr_in *)sa;
336*0Sstevel@tonic-gate
337*0Sstevel@tonic-gate if (slp_pton(surl->s_pcHost, &(sin->sin_addr)) < 1)
338*0Sstevel@tonic-gate return (SLP_PARAMETER_BAD);
339*0Sstevel@tonic-gate sin->sin_family = AF_INET;
340*0Sstevel@tonic-gate /* port number */
341*0Sstevel@tonic-gate sin->sin_port = htons(
342*0Sstevel@tonic-gate (surl->s_iPort == 0 ? SLP_PORT : surl->s_iPort));
343*0Sstevel@tonic-gate
344*0Sstevel@tonic-gate return (SLP_OK);
345*0Sstevel@tonic-gate }
346*0Sstevel@tonic-gate
347*0Sstevel@tonic-gate /*
348*0Sstevel@tonic-gate * A wrapper around gethostbyaddr_r. This checks the useGetXXXbyYYY
349*0Sstevel@tonic-gate * property first to determine whether a name service lookup should
350*0Sstevel@tonic-gate * be used. If not, it converts the address in 'addr' to a string
351*0Sstevel@tonic-gate * and just returns that.
352*0Sstevel@tonic-gate *
353*0Sstevel@tonic-gate * The core functionality herein will be replaced with getaddrinfo
354*0Sstevel@tonic-gate * when it becomes available.
355*0Sstevel@tonic-gate */
356*0Sstevel@tonic-gate
slp_gethostbyaddr(const char * addr,int size)357*0Sstevel@tonic-gate char *slp_gethostbyaddr(const char *addr, int size) {
358*0Sstevel@tonic-gate char storebuf[SLP_NETDB_BUFSZ], addrbuf[INET6_ADDRSTRLEN], *cname;
359*0Sstevel@tonic-gate const char *use_xbyy;
360*0Sstevel@tonic-gate struct hostent namestruct[1], *name;
361*0Sstevel@tonic-gate int herrno;
362*0Sstevel@tonic-gate
363*0Sstevel@tonic-gate /* default: copy in the IP address */
364*0Sstevel@tonic-gate cname = slp_ntop(addrbuf, INET6_ADDRSTRLEN, (const void *) addr);
365*0Sstevel@tonic-gate if (cname && !(cname = strdup(cname))) {
366*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_gethostbyaddr", "out of memory");
367*0Sstevel@tonic-gate return (NULL);
368*0Sstevel@tonic-gate }
369*0Sstevel@tonic-gate
370*0Sstevel@tonic-gate if ((use_xbyy = SLPGetProperty(SLP_CONFIG_USEGETXXXBYYYY)) != NULL &&
371*0Sstevel@tonic-gate strcasecmp(use_xbyy, "false") == 0) {
372*0Sstevel@tonic-gate return (cname);
373*0Sstevel@tonic-gate }
374*0Sstevel@tonic-gate
375*0Sstevel@tonic-gate while (!(name = gethostbyaddr_r(addr, size,
376*0Sstevel@tonic-gate AF_INET,
377*0Sstevel@tonic-gate namestruct,
378*0Sstevel@tonic-gate storebuf,
379*0Sstevel@tonic-gate SLP_NETDB_BUFSZ,
380*0Sstevel@tonic-gate &herrno))) {
381*0Sstevel@tonic-gate switch (herrno) {
382*0Sstevel@tonic-gate case NO_RECOVERY:
383*0Sstevel@tonic-gate case NO_DATA:
384*0Sstevel@tonic-gate return (cname);
385*0Sstevel@tonic-gate case TRY_AGAIN:
386*0Sstevel@tonic-gate continue;
387*0Sstevel@tonic-gate default:
388*0Sstevel@tonic-gate return (cname); /* IP address */
389*0Sstevel@tonic-gate }
390*0Sstevel@tonic-gate }
391*0Sstevel@tonic-gate
392*0Sstevel@tonic-gate free(cname);
393*0Sstevel@tonic-gate if (!(cname = strdup(name->h_name))) {
394*0Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_gethostbyaddr", "out of memory");
395*0Sstevel@tonic-gate return (NULL);
396*0Sstevel@tonic-gate }
397*0Sstevel@tonic-gate
398*0Sstevel@tonic-gate return (cname);
399*0Sstevel@tonic-gate }
400*0Sstevel@tonic-gate
401*0Sstevel@tonic-gate /* @@@ currently getting these from libresolv2 -> change? */
402*0Sstevel@tonic-gate
403*0Sstevel@tonic-gate /*
404*0Sstevel@tonic-gate * Converts the address pointed to by 'addr' to a string. Currently
405*0Sstevel@tonic-gate * just calls inet_ntoa, but is structured to be a wrapper to
406*0Sstevel@tonic-gate * inet_ntop. Returns NULL on failure.
407*0Sstevel@tonic-gate *
408*0Sstevel@tonic-gate * This wrapper allows callers to be protocol agnostic. Right now it
409*0Sstevel@tonic-gate * only handles IPv4.
410*0Sstevel@tonic-gate */
411*0Sstevel@tonic-gate /*ARGSUSED*/
slp_ntop(char * buf,int buflen,const void * addr)412*0Sstevel@tonic-gate char *slp_ntop(char *buf, int buflen, const void *addr) {
413*0Sstevel@tonic-gate return (inet_ntoa(*(struct in_addr *)addr));
414*0Sstevel@tonic-gate }
415*0Sstevel@tonic-gate
416*0Sstevel@tonic-gate /*
417*0Sstevel@tonic-gate * convert from presentation format (which usually means ASCII printable)
418*0Sstevel@tonic-gate * to network format (which is usually some kind of binary format).
419*0Sstevel@tonic-gate * return:
420*0Sstevel@tonic-gate * 1 if the address was valid for the specified address family
421*0Sstevel@tonic-gate * 0 if the address wasn't valid (`dst' is untouched in this case)
422*0Sstevel@tonic-gate * -1 if some other error occurred (`dst' is untouched in this case, too)
423*0Sstevel@tonic-gate *
424*0Sstevel@tonic-gate * This wrapper allows callers to be protocol agnostic. Right now it
425*0Sstevel@tonic-gate * only handles IPv4.
426*0Sstevel@tonic-gate */
slp_pton(const char * addrstr,void * addr)427*0Sstevel@tonic-gate int slp_pton(const char *addrstr, void *addr) {
428*0Sstevel@tonic-gate return (inet_pton(AF_INET, addrstr, addr));
429*0Sstevel@tonic-gate }
430