~ubuntu-branches/ubuntu/maverick/bind9/maverick

« back to all changes in this revision

Viewing changes to lib/isc/win32/interfaceiter.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones, LaMont Jones, Internet Software Consortium, Inc, localization folks
  • Date: 2008-08-02 14:20:20 UTC
  • mfrom: (1.2.1 upstream) (6.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080802142020-l1hon9jy8lbbjxmg
[LaMont Jones]

* default to using resolvconf if it is installed
* fix sonames and dependencies.  Closes: #149259, #492418
* Do not build-depend libcap2-dev on non-linux.  Closes: #493392
* drop unused query-loc manpage.  Closes: #492564
* lwresd: Deliver /etc/bind directory.  Closes: #490027
* fix query-source comment in default install

[Internet Software Consortium, Inc]

* 9.5.0-P2.  Closes: #492949

[localization folks]

* l10n: Spanish debconf translation.  Closes: #492425 (Ignacio Mondino)
* l10n: Swedish debconf templates.  Closes: #491369 (Martin Ågren)
* l10n: Japanese debconf translations.  Closes: #492048 (Hideki Yamane
  (Debian-JP))
* l10n: Finnish translation.  Closes: #490630 (Esko Arajärvi)
* l10n: Italian debconf translations.  Closes: #492587 (Alessandro Vietta)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
 
2
 * Copyright (C) 2004, 2007, 2008  Internet Systems Consortium, Inc. ("ISC")
3
3
 * Copyright (C) 1999-2001  Internet Software Consortium.
4
4
 *
5
 
 * Permission to use, copy, modify, and distribute this software for any
 
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
6
 * purpose with or without fee is hereby granted, provided that the above
7
7
 * copyright notice and this permission notice appear in all copies.
8
8
 *
15
15
 * PERFORMANCE OF THIS SOFTWARE.
16
16
 */
17
17
 
18
 
/* $Id: interfaceiter.c,v 1.4.12.4 2004/03/08 09:04:59 marka Exp $ */
 
18
/* $Id: interfaceiter.c,v 1.10.128.3 2008/04/18 19:47:26 each Exp $ */
19
19
 
20
20
/*
21
21
 * Note that this code will need to be revisited to support IPv6 Interfaces.
39
39
#include <isc/types.h>
40
40
#include <isc/util.h>
41
41
 
 
42
void InitSockets(void);
 
43
 
42
44
/* Common utility functions */
43
45
 
44
46
/*
60
62
        int                     socket;
61
63
        INTERFACE_INFO          IFData;         /* Current Interface Info */
62
64
        int                     numIF;          /* Current Interface count */
63
 
        int                     totalIF;        /* Total Number
64
 
                                                   of Interfaces */
65
 
        INTERFACE_INFO          *buf;           /* Buffer for WSAIoctl data. */
66
 
        unsigned int            bufsize;        /* Bytes allocated. */
67
 
        INTERFACE_INFO          *pos;           /* Current offset in IF List */
 
65
        int                     v4IF;           /* Number of IPv4 Interfaces */
 
66
        INTERFACE_INFO          *buf4;          /* Buffer for WSAIoctl data. */
 
67
        unsigned int            buf4size;       /* Bytes allocated. */
 
68
        INTERFACE_INFO          *pos4;          /* Current offset in IF List */
 
69
        SOCKET_ADDRESS_LIST     *buf6;
 
70
        unsigned int            buf6size;       /* Bytes allocated. */
 
71
        unsigned int            pos6;
68
72
        isc_interface_t         current;        /* Current interface data. */
69
73
        isc_result_t            result;         /* Last result code. */
70
74
};
92
96
                memcpy(&dst->type.in6,
93
97
                       &((struct sockaddr_in6 *) src)->sin6_addr,
94
98
                       sizeof(struct in6_addr));
 
99
                dst->zone = ((struct sockaddr_in6 *) src)->sin6_scope_id;
95
100
                break;
96
101
        default:
97
102
                INSIST(0);
101
106
 
102
107
isc_result_t
103
108
isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
104
 
        char strbuf[ISC_STRERRORSIZE]; 
 
109
        char strbuf[ISC_STRERRORSIZE];
105
110
        isc_interfaceiter_t *iter;
106
111
        isc_result_t result;
107
112
        int error;
115
120
        if (iter == NULL)
116
121
                return (ISC_R_NOMEMORY);
117
122
 
 
123
        InitSockets();
 
124
 
118
125
        iter->mctx = mctx;
119
 
        iter->buf = NULL;
 
126
        iter->buf4 = NULL;
 
127
        iter->buf6 = NULL;
 
128
        iter->pos4 = NULL;
 
129
        iter->pos6 = 0;
 
130
        iter->buf6size = 0;
 
131
        iter->buf4size = 0;
 
132
        iter->result = ISC_R_FAILURE;
 
133
        iter->numIF = 0;
 
134
        iter->v4IF = 0;
120
135
 
121
136
        /*
122
137
         * Create an unbound datagram socket to do the
124
139
         */
125
140
        if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
126
141
                error = WSAGetLastError();
 
142
                if (error == WSAEAFNOSUPPORT)
 
143
                        goto inet6_only;
127
144
                isc__strerror(error, strbuf, sizeof(strbuf));
128
145
                UNEXPECTED_ERROR(__FILE__, __LINE__,
129
146
                                "making interface scan socket: %s",
136
153
         * Get the interface configuration, allocating more memory if
137
154
         * necessary.
138
155
         */
139
 
        iter->bufsize = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
 
156
        iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
140
157
 
141
158
        for (;;) {
142
 
                iter->buf = isc_mem_get(mctx, iter->bufsize);
143
 
                if (iter->buf == NULL) {
 
159
                iter->buf4 = isc_mem_get(mctx, iter->buf4size);
 
160
                if (iter->buf4 == NULL) {
144
161
                        result = ISC_R_NOMEMORY;
145
162
                        goto alloc_failure;
146
163
                }
147
164
 
148
165
                if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST,
149
 
                             0, 0, iter->buf, iter->bufsize,
 
166
                             0, 0, iter->buf4, iter->buf4size,
150
167
                             &bytesReturned, 0, 0) == SOCKET_ERROR)
151
168
                {
152
169
                        error = WSAGetLastError();
170
187
                         * case and retry.
171
188
                         */
172
189
                        if (bytesReturned > 0 &&
173
 
                            (bytesReturned < iter->bufsize))
 
190
                            (bytesReturned < iter->buf4size))
174
191
                                break;
175
192
                }
176
 
                if (iter->bufsize >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
 
193
                if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
177
194
                        UNEXPECTED_ERROR(__FILE__, __LINE__,
178
195
                                         "get interface configuration: "
179
196
                                         "maximum buffer size exceeded");
180
197
                        result = ISC_R_UNEXPECTED;
181
198
                        goto ioctl_failure;
182
199
                }
183
 
                isc_mem_put(mctx, iter->buf, iter->bufsize);
 
200
                isc_mem_put(mctx, iter->buf4, iter->buf4size);
184
201
 
185
 
                iter->bufsize += IFCONF_SIZE_INCREMENT *
 
202
                iter->buf4size += IFCONF_SIZE_INCREMENT *
186
203
                        sizeof(INTERFACE_INFO);
187
204
        }
188
205
 
190
207
         * A newly created iterator has an undefined position
191
208
         * until isc_interfaceiter_first() is called.
192
209
         */
193
 
        iter->pos = NULL;
194
 
        iter->result = ISC_R_FAILURE;
195
 
        iter->numIF = 0;
196
 
        iter->totalIF = bytesReturned/sizeof(INTERFACE_INFO);
197
 
 
198
 
 
 
210
        iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO);
 
211
 
 
212
        /* We don't need the socket any more, so close it */
 
213
        closesocket(iter->socket);
 
214
 
 
215
 inet6_only:
 
216
        /*
 
217
         * Create an unbound datagram socket to do the
 
218
         * SIO_ADDRESS_LIST_QUERY WSAIoctl on.
 
219
         */
 
220
        if ((iter->socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
 
221
                error = WSAGetLastError();
 
222
                if (error == WSAEAFNOSUPPORT)
 
223
                        goto inet_only;
 
224
                isc__strerror(error, strbuf, sizeof(strbuf));
 
225
                UNEXPECTED_ERROR(__FILE__, __LINE__,
 
226
                                "making interface scan socket: %s",
 
227
                                strbuf);
 
228
                result = ISC_R_UNEXPECTED;
 
229
                goto ioctl_failure;
 
230
        }
 
231
 
 
232
        /*
 
233
         * Get the interface configuration, allocating more memory if
 
234
         * necessary.
 
235
         */
 
236
        iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) +
 
237
                         IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS);
 
238
 
 
239
        for (;;) {
 
240
                iter->buf6 = isc_mem_get(mctx, iter->buf6size);
 
241
                if (iter->buf6 == NULL) {
 
242
                        result = ISC_R_NOMEMORY;
 
243
                        goto ioctl_failure;
 
244
                }
 
245
 
 
246
                if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY,
 
247
                             0, 0, iter->buf6, iter->buf6size,
 
248
                             &bytesReturned, 0, 0) == SOCKET_ERROR)
 
249
                {
 
250
                        error = WSAGetLastError();
 
251
                        if (error != WSAEFAULT && error != WSAENOBUFS) {
 
252
                                errno = error;
 
253
                                isc__strerror(error, strbuf, sizeof(strbuf));
 
254
                                UNEXPECTED_ERROR(__FILE__, __LINE__,
 
255
                                                 "sio address list query: %s",
 
256
                                                 strbuf);
 
257
                                result = ISC_R_UNEXPECTED;
 
258
                                goto ioctl6_failure;
 
259
                        }
 
260
                        /*
 
261
                         * EINVAL.  Retry with a bigger buffer.
 
262
                         */
 
263
                } else
 
264
                        break;
 
265
 
 
266
                if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) {
 
267
                        UNEXPECTED_ERROR(__FILE__, __LINE__,
 
268
                                         "get interface configuration: "
 
269
                                         "maximum buffer size exceeded");
 
270
                        result = ISC_R_UNEXPECTED;
 
271
                        goto ioctl6_failure;
 
272
                }
 
273
                isc_mem_put(mctx, iter->buf6, iter->buf6size);
 
274
 
 
275
                iter->buf6size += IFCONF_SIZE_INCREMENT *
 
276
                        sizeof(SOCKET_ADDRESS);
 
277
        }
 
278
 
 
279
        closesocket(iter->socket);
 
280
 
 
281
 inet_only:
199
282
        iter->magic = IFITER_MAGIC;
200
283
        *iterp = iter;
201
 
        /* We don't need the socket any more, so close it */
202
 
        closesocket(iter->socket);
203
284
        return (ISC_R_SUCCESS);
204
285
 
 
286
 ioctl6_failure:
 
287
        isc_mem_put(mctx, iter->buf6, iter->buf6size);
 
288
 
205
289
 ioctl_failure:
206
 
        isc_mem_put(mctx, iter->buf, iter->bufsize);
 
290
        if (iter->buf4 != NULL)
 
291
                isc_mem_put(mctx, iter->buf4, iter->buf4size);
207
292
 
208
293
 alloc_failure:
209
 
        (void) closesocket(iter->socket);
 
294
        if (iter->socket >= 0)
 
295
                (void) closesocket(iter->socket);
210
296
 
211
297
 socket_failure:
212
298
        isc_mem_put(mctx, iter, sizeof(*iter));
222
308
 */
223
309
 
224
310
static isc_result_t
225
 
internal_current(isc_interfaceiter_t *iter, int family) {
 
311
internal_current(isc_interfaceiter_t *iter) {
226
312
        BOOL ifNamed = FALSE;
227
313
        unsigned long flags;
228
314
 
230
316
        REQUIRE(iter->numIF >= 0);
231
317
 
232
318
        memset(&iter->current, 0, sizeof(iter->current));
233
 
        iter->current.af = family;
 
319
        iter->current.af = AF_INET;
234
320
 
235
 
        get_addr(family, &iter->current.address,
 
321
        get_addr(AF_INET, &iter->current.address,
236
322
                 (struct sockaddr *)&(iter->IFData.iiAddress));
237
323
 
238
324
        /*
262
348
         * If the interface is point-to-point, get the destination address.
263
349
         */
264
350
        if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
265
 
                get_addr(family, &iter->current.dstaddress,
 
351
                get_addr(AF_INET, &iter->current.dstaddress,
266
352
                (struct sockaddr *)&(iter->IFData.iiBroadcastAddress));
267
353
        }
268
354
 
273
359
        /*
274
360
         * Get the network mask.
275
361
         */
276
 
        switch (family) {
277
 
        case AF_INET:
278
 
                get_addr(family, &iter->current.netmask,
279
 
                         (struct sockaddr *)&(iter->IFData.iiNetmask));
280
 
                break;
281
 
        case AF_INET6:
282
 
                break;
283
 
        }
284
 
 
 
362
        get_addr(AF_INET, &iter->current.netmask,
 
363
                 (struct sockaddr *)&(iter->IFData.iiNetmask));
 
364
 
 
365
        return (ISC_R_SUCCESS);
 
366
}
 
367
 
 
368
static isc_result_t
 
369
internal_current6(isc_interfaceiter_t *iter) {
 
370
        BOOL ifNamed = FALSE;
 
371
        int i;
 
372
 
 
373
        REQUIRE(VALID_IFITER(iter));
 
374
        REQUIRE(iter->pos6 >= 0);
 
375
        REQUIRE(iter->buf6 != 0);
 
376
 
 
377
        memset(&iter->current, 0, sizeof(iter->current));
 
378
        iter->current.af = AF_INET6;
 
379
 
 
380
        get_addr(AF_INET6, &iter->current.address,
 
381
                 iter->buf6->Address[iter->pos6].lpSockaddr);
 
382
 
 
383
        /*
 
384
         * Get interface flags.
 
385
         */
 
386
 
 
387
        iter->current.flags = INTERFACE_F_UP;
 
388
 
 
389
        if (ifNamed == FALSE)
 
390
                sprintf(iter->current.name,
 
391
                        "TCP/IPv6 Interface %d", iter->pos6 + 1);
 
392
 
 
393
        for (i = 0; i< 16; i++)
 
394
                iter->current.netmask.type.in6.s6_addr[i] = 0xff;
 
395
        iter->current.netmask.family = AF_INET6;
285
396
        return (ISC_R_SUCCESS);
286
397
}
287
398
 
294
405
 */
295
406
static isc_result_t
296
407
internal_next(isc_interfaceiter_t *iter) {
297
 
        if (iter->numIF >= iter->totalIF)
 
408
        if (iter->numIF >= iter->v4IF)
298
409
                return (ISC_R_NOMORE);
299
410
 
300
411
        /*
303
414
         * Microsoft's implementation is peculiar for returning
304
415
         * the list in reverse order
305
416
         */
306
 
         
 
417
 
307
418
        if (iter->numIF == 0)
308
 
                iter->pos = (INTERFACE_INFO *)(iter->buf + (iter->totalIF));
 
419
                iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF));
309
420
 
310
 
        iter->pos--;
311
 
        if (&(iter->pos) < &(iter->buf))
 
421
        iter->pos4--;
 
422
        if (&(iter->pos4) < &(iter->buf4))
312
423
                return (ISC_R_NOMORE);
313
424
 
314
425
        memset(&(iter->IFData), 0, sizeof(INTERFACE_INFO));
315
 
        memcpy(&(iter->IFData), iter->pos, sizeof(INTERFACE_INFO));
 
426
        memcpy(&(iter->IFData), iter->pos4, sizeof(INTERFACE_INFO));
316
427
        iter->numIF++;
317
428
 
318
429
        return (ISC_R_SUCCESS);
319
430
}
320
431
 
 
432
static isc_result_t
 
433
internal_next6(isc_interfaceiter_t *iter) {
 
434
        if (iter->pos6 == 0)
 
435
                return (ISC_R_NOMORE);
 
436
        iter->pos6--;
 
437
        return (ISC_R_SUCCESS);
 
438
}
 
439
 
321
440
isc_result_t
322
441
isc_interfaceiter_current(isc_interfaceiter_t *iter,
323
442
                          isc_interface_t *ifdata) {
328
447
 
329
448
isc_result_t
330
449
isc_interfaceiter_first(isc_interfaceiter_t *iter) {
331
 
        isc_result_t result;
332
450
 
333
451
        REQUIRE(VALID_IFITER(iter));
334
452
 
335
 
        iter->numIF = 0;
336
 
        for (;;) {
337
 
                result = internal_next(iter);
338
 
                if (result != ISC_R_SUCCESS)
339
 
                        break;
340
 
                result = internal_current(iter, AF_INET);
341
 
                if (result != ISC_R_IGNORE)
342
 
                        break;
343
 
        }
344
 
        iter->result = result;
345
 
        return (result);
 
453
        if (iter->buf6 != NULL)
 
454
                iter->pos6 = iter->buf6->iAddressCount;
 
455
        iter->result = ISC_R_SUCCESS;
 
456
        return (isc_interfaceiter_next(iter));
346
457
}
347
458
 
348
459
isc_result_t
354
465
 
355
466
        for (;;) {
356
467
                result = internal_next(iter);
357
 
                if (result != ISC_R_SUCCESS)
 
468
                if (result == ISC_R_NOMORE) {
 
469
                        result = internal_next6(iter);
 
470
                        if (result != ISC_R_SUCCESS)
 
471
                                break;
 
472
                        result = internal_current6(iter);
 
473
                        if (result != ISC_R_IGNORE)
 
474
                                break;
 
475
                } else if (result != ISC_R_SUCCESS)
358
476
                        break;
359
 
                result = internal_current(iter,AF_INET);
 
477
                result = internal_current(iter);
360
478
                if (result != ISC_R_IGNORE)
361
479
                        break;
362
480
        }
371
489
        iter = *iterp;
372
490
        REQUIRE(VALID_IFITER(iter));
373
491
 
374
 
        isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
 
492
        if (iter->buf4 != NULL)
 
493
                isc_mem_put(iter->mctx, iter->buf4, iter->buf4size);
 
494
        if (iter->buf6 != NULL)
 
495
                isc_mem_put(iter->mctx, iter->buf6, iter->buf6size);
375
496
 
376
497
        iter->magic = 0;
377
498
        isc_mem_put(iter->mctx, iter, sizeof(*iter));
378
499
        *iterp = NULL;
379
500
}
380