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.
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.
61
63
INTERFACE_INFO IFData; /* Current Interface Info */
62
64
int numIF; /* Current Interface count */
63
int totalIF; /* Total Number
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. */
68
72
isc_interface_t current; /* Current interface data. */
69
73
isc_result_t result; /* Last result code. */
136
153
* Get the interface configuration, allocating more memory if
139
iter->bufsize = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
156
iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
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;
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)
152
169
error = WSAGetLastError();
170
187
* case and retry.
172
189
if (bytesReturned > 0 &&
173
(bytesReturned < iter->bufsize))
190
(bytesReturned < iter->buf4size))
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;
183
isc_mem_put(mctx, iter->buf, iter->bufsize);
200
isc_mem_put(mctx, iter->buf4, iter->buf4size);
185
iter->bufsize += IFCONF_SIZE_INCREMENT *
202
iter->buf4size += IFCONF_SIZE_INCREMENT *
186
203
sizeof(INTERFACE_INFO);
190
207
* A newly created iterator has an undefined position
191
208
* until isc_interfaceiter_first() is called.
194
iter->result = ISC_R_FAILURE;
196
iter->totalIF = bytesReturned/sizeof(INTERFACE_INFO);
210
iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO);
212
/* We don't need the socket any more, so close it */
213
closesocket(iter->socket);
217
* Create an unbound datagram socket to do the
218
* SIO_ADDRESS_LIST_QUERY WSAIoctl on.
220
if ((iter->socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
221
error = WSAGetLastError();
222
if (error == WSAEAFNOSUPPORT)
224
isc__strerror(error, strbuf, sizeof(strbuf));
225
UNEXPECTED_ERROR(__FILE__, __LINE__,
226
"making interface scan socket: %s",
228
result = ISC_R_UNEXPECTED;
233
* Get the interface configuration, allocating more memory if
236
iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) +
237
IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS);
240
iter->buf6 = isc_mem_get(mctx, iter->buf6size);
241
if (iter->buf6 == NULL) {
242
result = ISC_R_NOMEMORY;
246
if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY,
247
0, 0, iter->buf6, iter->buf6size,
248
&bytesReturned, 0, 0) == SOCKET_ERROR)
250
error = WSAGetLastError();
251
if (error != WSAEFAULT && error != WSAENOBUFS) {
253
isc__strerror(error, strbuf, sizeof(strbuf));
254
UNEXPECTED_ERROR(__FILE__, __LINE__,
255
"sio address list query: %s",
257
result = ISC_R_UNEXPECTED;
261
* EINVAL. Retry with a bigger buffer.
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;
273
isc_mem_put(mctx, iter->buf6, iter->buf6size);
275
iter->buf6size += IFCONF_SIZE_INCREMENT *
276
sizeof(SOCKET_ADDRESS);
279
closesocket(iter->socket);
199
282
iter->magic = IFITER_MAGIC;
201
/* We don't need the socket any more, so close it */
202
closesocket(iter->socket);
203
284
return (ISC_R_SUCCESS);
287
isc_mem_put(mctx, iter->buf6, iter->buf6size);
206
isc_mem_put(mctx, iter->buf, iter->bufsize);
290
if (iter->buf4 != NULL)
291
isc_mem_put(mctx, iter->buf4, iter->buf4size);
209
(void) closesocket(iter->socket);
294
if (iter->socket >= 0)
295
(void) closesocket(iter->socket);
212
298
isc_mem_put(mctx, iter, sizeof(*iter));
230
316
REQUIRE(iter->numIF >= 0);
232
318
memset(&iter->current, 0, sizeof(iter->current));
233
iter->current.af = family;
319
iter->current.af = AF_INET;
235
get_addr(family, &iter->current.address,
321
get_addr(AF_INET, &iter->current.address,
236
322
(struct sockaddr *)&(iter->IFData.iiAddress));
274
360
* Get the network mask.
278
get_addr(family, &iter->current.netmask,
279
(struct sockaddr *)&(iter->IFData.iiNetmask));
362
get_addr(AF_INET, &iter->current.netmask,
363
(struct sockaddr *)&(iter->IFData.iiNetmask));
365
return (ISC_R_SUCCESS);
369
internal_current6(isc_interfaceiter_t *iter) {
370
BOOL ifNamed = FALSE;
373
REQUIRE(VALID_IFITER(iter));
374
REQUIRE(iter->pos6 >= 0);
375
REQUIRE(iter->buf6 != 0);
377
memset(&iter->current, 0, sizeof(iter->current));
378
iter->current.af = AF_INET6;
380
get_addr(AF_INET6, &iter->current.address,
381
iter->buf6->Address[iter->pos6].lpSockaddr);
384
* Get interface flags.
387
iter->current.flags = INTERFACE_F_UP;
389
if (ifNamed == FALSE)
390
sprintf(iter->current.name,
391
"TCP/IPv6 Interface %d", iter->pos6 + 1);
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);
303
414
* Microsoft's implementation is peculiar for returning
304
415
* the list in reverse order
307
418
if (iter->numIF == 0)
308
iter->pos = (INTERFACE_INFO *)(iter->buf + (iter->totalIF));
419
iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF));
311
if (&(iter->pos) < &(iter->buf))
422
if (&(iter->pos4) < &(iter->buf4))
312
423
return (ISC_R_NOMORE);
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));
318
429
return (ISC_R_SUCCESS);
433
internal_next6(isc_interfaceiter_t *iter) {
435
return (ISC_R_NOMORE);
437
return (ISC_R_SUCCESS);
322
441
isc_interfaceiter_current(isc_interfaceiter_t *iter,
323
442
isc_interface_t *ifdata) {
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)
472
result = internal_current6(iter);
473
if (result != ISC_R_IGNORE)
475
} else if (result != ISC_R_SUCCESS)
359
result = internal_current(iter,AF_INET);
477
result = internal_current(iter);
360
478
if (result != ISC_R_IGNORE)