Merge from vendor branch WPA_SUPPLICANT:
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / isc / unix / interfaceiter.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: interfaceiter.c,v 1.22.2.2 2004/03/09 06:12:10 marka Exp $ */
19
20 #include <config.h>
21
22 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #ifdef HAVE_SYS_SOCKIO_H
25 #include <sys/sockio.h>         /* Required for ifiter_ioctl.c. */
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <errno.h>
32
33 #include <isc/magic.h>
34 #include <isc/mem.h>
35 #include <isc/msgs.h>
36 #include <isc/net.h>
37 #include <isc/result.h>
38 #include <isc/strerror.h>
39 #include <isc/string.h>
40 #include <isc/types.h>
41 #include <isc/interfaceiter.h>
42 #include <isc/util.h>
43
44 #include <net/if.h>             /* Must follow <isc/net.h>. */
45
46 /* Common utility functions */
47
48 /*
49  * Extract the network address part from a "struct sockaddr".
50  *
51  * The address family is given explicity
52  * instead of using src->sa_family, because the latter does not work
53  * for copying a network mask obtained by SIOCGIFNETMASK (it does
54  * not have a valid address family).
55  */
56
57 static void
58 get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src) {
59         dst->family = family;
60         switch (family) {
61         case AF_INET:
62                 memcpy(&dst->type.in,
63                        &((struct sockaddr_in *) src)->sin_addr,
64                        sizeof(struct in_addr));
65                 break;
66         case    AF_INET6:
67                 memcpy(&dst->type.in6,
68                        &((struct sockaddr_in6 *) src)->sin6_addr,
69                        sizeof(struct in6_addr));
70                 break;
71         default:
72                 INSIST(0);
73                 break;
74         }
75 }
76
77 /*
78  * Include system-dependent code.
79  */
80
81 #if HAVE_IFLIST_SYSCTL
82 #include "ifiter_sysctl.c"
83 #else
84 #include "ifiter_ioctl.c"
85 #endif
86
87 /*
88  * The remaining code is common to the sysctl and ioctl case.
89  */
90
91 isc_result_t
92 isc_interfaceiter_current(isc_interfaceiter_t *iter,
93                           isc_interface_t *ifdata)
94 {
95         REQUIRE(iter->result == ISC_R_SUCCESS);
96         memcpy(ifdata, &iter->current, sizeof(*ifdata));
97         return (ISC_R_SUCCESS);
98 }
99
100 isc_result_t
101 isc_interfaceiter_first(isc_interfaceiter_t *iter) {
102         isc_result_t result;
103
104         REQUIRE(VALID_IFITER(iter));
105
106         iter->pos = 0;
107         for (;;) {
108                 result = internal_current(iter);
109                 if (result != ISC_R_IGNORE)
110                         break;
111                 result = internal_next(iter);
112                 if (result != ISC_R_SUCCESS)
113                         break;
114         }
115         iter->result = result;
116         return (result);
117 }
118
119 isc_result_t
120 isc_interfaceiter_next(isc_interfaceiter_t *iter) {
121         isc_result_t result;
122
123         REQUIRE(VALID_IFITER(iter));
124         REQUIRE(iter->result == ISC_R_SUCCESS);
125
126         for (;;) {
127                 result = internal_next(iter);
128                 if (result != ISC_R_SUCCESS)
129                         break;
130                 result = internal_current(iter);
131                 if (result != ISC_R_IGNORE)
132                         break;
133         }
134         iter->result = result;
135         return (result);
136 }
137
138 void
139 isc_interfaceiter_destroy(isc_interfaceiter_t **iterp)
140 {
141         isc_interfaceiter_t *iter;
142         REQUIRE(iterp != NULL);
143         iter = *iterp;
144         REQUIRE(VALID_IFITER(iter));
145
146         internal_destroy(iter);
147         isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
148
149         iter->magic = 0;
150         isc_mem_put(iter->mctx, iter, sizeof *iter);
151         *iterp = NULL;
152 }