2
* Copyright (C) 1999-2001 Internet Software Consortium.
2
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3
* Copyright (C) 1999-2003 Internet Software Consortium.
4
5
* Permission to use, copy, modify, and distribute this software for any
5
6
* purpose with or without fee is hereby granted, provided that the above
6
7
* copyright notice and this permission notice appear in all copies.
8
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
9
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
10
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
11
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
12
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
13
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
14
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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.
18
/* $Id: ifiter_ioctl.c,v 1.34 2002/08/16 00:05:57 marka Exp $ */
18
/* $Id: ifiter_ioctl.c,v 1.19.2.5.2.14 2004/06/22 04:40:23 marka Exp $ */
21
21
* Obtain the list of network interfaces using the SIOCGLIFCONF ioctl.
51
51
#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'T')
52
52
#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
54
#define ISC_IF_INET6_SZ \
55
sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n")
54
57
struct isc_interfaceiter {
55
58
unsigned int magic; /* Magic number. */
60
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
63
63
void *buf; /* Buffer for sysctl data. */
64
64
unsigned int bufsize; /* Bytes allocated. */
65
#ifdef HAVE_TRUCLUSTER
66
int clua_context; /* Cluster alias context */
68
65
unsigned int pos; /* Current offset in
67
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
70
void *buf6; /* Buffer for sysctl data. */
71
unsigned int bufsize6; /* Bytes allocated. */
72
unsigned int pos6; /* Current offset in
69
73
SIOCGLIFCONF data */
74
isc_result_t result6; /* Last result code. */
77
#ifdef HAVE_TRUCLUSTER
78
int clua_context; /* Cluster alias context */
79
isc_boolean_t clua_done;
80
struct sockaddr clua_sa;
84
char entry[ISC_IF_INET6_SZ];
70
88
isc_interface_t current; /* Current interface data. */
71
89
isc_result_t result; /* Last result code. */
157
184
return (ISC_R_UNEXPECTED);
187
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
160
188
static isc_result_t
161
189
getbuf6(isc_interfaceiter_t *iter) {
162
#if !defined(SIOCGLIFCONF) || !defined(SIOCGLIFADDR)
164
return (ISC_R_NOTIMPLEMENTED);
166
190
char strbuf[ISC_STRERRORSIZE];
167
191
isc_result_t result;
169
iter->bufsize = IFCONF_BUFSIZE_INITIAL;
193
iter->bufsize6 = IFCONF_BUFSIZE_INITIAL;
172
iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
173
if (iter->buf == NULL)
196
iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6);
197
if (iter->buf6 == NULL)
174
198
return (ISC_R_NOMEMORY);
176
memset(&iter->lifc.lifc_len, 0, sizeof(iter->lifc.lifc_len));
200
memset(&iter->lifc, 0, sizeof(iter->lifc));
177
201
#ifdef ISC_HAVE_LIFC_FAMILY
178
iter->lifc.lifc_family = AF_UNSPEC;
202
iter->lifc.lifc_family = AF_INET6;
180
204
#ifdef ISC_HAVE_LIFC_FLAGS
181
205
iter->lifc.lifc_flags = 0;
183
iter->lifc.lifc_len = iter->bufsize;
184
iter->lifc.lifc_buf = iter->buf;
207
iter->lifc.lifc_len = iter->bufsize6;
208
iter->lifc.lifc_buf = iter->buf6;
186
210
* Ignore the HP/UX warning about "integer overflow during
187
211
* conversion". It comes from its own macro definition,
188
212
* and is really hard to shut up.
190
if (ioctl(iter->socket, SIOCGLIFCONF, (char *)&iter->lifc)
214
if (ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc)
277
302
return (ISC_R_NOMEMORY);
279
304
iter->mctx = mctx;
280
306
iter->buf = NULL;
307
iter->pos = (unsigned int) -1;
308
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
310
iter->pos6 = (unsigned int) -1;
311
iter->result6 = ISC_R_NOMORE;
313
iter->first6 = ISC_FALSE;
284
* Create an unbound datagram socket to do the SIOCGLIFADDR ioctl on.
317
* Get the interface configuration, allocating more memory if
321
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
322
result = isc_net_probeipv6();
323
if (result == ISC_R_SUCCESS) {
325
* Create an unbound datagram socket to do the SIOCGLIFCONF
326
* ioctl on. HP/UX requires an AF_INET6 socket for
327
* SIOCGLIFCONF to get IPv6 addresses.
329
if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
330
isc__strerror(errno, strbuf, sizeof(strbuf));
331
UNEXPECTED_ERROR(__FILE__, __LINE__,
332
isc_msgcat_get(isc_msgcat,
333
ISC_MSGSET_IFITERIOCTL,
334
ISC_MSG_MAKESCANSOCKET,
338
result = ISC_R_UNEXPECTED;
339
goto socket6_failure;
341
iter->result6 = getbuf6(iter);
342
if (iter->result6 != ISC_R_NOTIMPLEMENTED &&
343
iter->result6 != ISC_R_SUCCESS)
286
347
if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
287
348
isc__strerror(errno, strbuf, sizeof(strbuf));
288
349
UNEXPECTED_ERROR(__FILE__, __LINE__,
343
408
static isc_result_t
344
409
internal_current_clusteralias(isc_interfaceiter_t *iter) {
346
410
struct clua_info ci;
347
while (clua_getaliasaddress(&sa, &iter->clua_context) == CLUA_SUCCESS) {
348
if (clua_getaliasinfo(&sa, &ci) != CLUA_SUCCESS)
350
memset(&iter->current, 0, sizeof(iter->current));
351
iter->current.af = sa.sa_family;
352
memset(iter->current.name, 0, sizeof(iter->current.name));
353
sprintf(iter->current.name, "clua%d", ci.aliasid);
354
iter->current.flags = INTERFACE_F_UP;
355
get_inaddr(&iter->current.address, &ci.addr);
356
get_inaddr(&iter->current.netmask, &ci.netmask);
357
return (ISC_R_SUCCESS);
359
return (ISC_R_NOMORE);
411
if (clua_getaliasinfo(&iter->clua_sa, &ci) != CLUA_SUCCESS)
412
return (ISC_R_IGNORE);
413
memset(&iter->current, 0, sizeof(iter->current));
414
iter->current.af = iter->clua_sa.sa_family;
415
memset(iter->current.name, 0, sizeof(iter->current.name));
416
sprintf(iter->current.name, "clua%d", ci.aliasid);
417
iter->current.flags = INTERFACE_F_UP;
418
get_inaddr(&iter->current.address, &ci.addr);
419
get_inaddr(&iter->current.netmask, &ci.netmask);
420
return (ISC_R_SUCCESS);
426
linux_if_inet6_next(isc_interfaceiter_t *iter) {
427
if (iter->proc != NULL &&
428
fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)
429
iter->valid = ISC_R_SUCCESS;
431
iter->valid = ISC_R_NOMORE;
432
return (iter->valid);
436
linux_if_inet6_first(isc_interfaceiter_t *iter) {
437
if (iter->proc != NULL) {
439
(void)linux_if_inet6_next(iter);
441
iter->valid = ISC_R_NOMORE;
442
iter->first = ISC_FALSE;
446
linux_if_inet6_current(isc_interfaceiter_t *iter) {
448
char name[IF_NAMESIZE+1];
449
char strbuf[ISC_STRERRORSIZE];
450
struct in6_addr addr6;
452
int ifindex, prefix, scope, flags;
456
if (iter->valid != ISC_R_SUCCESS)
457
return (iter->valid);
458
if (iter->proc == NULL) {
459
UNEXPECTED_ERROR(__FILE__, __LINE__,
460
"/proc/net/if_inet6:iter->proc == NULL");
461
return (ISC_R_FAILURE);
465
* Format for /proc/net/if_inet6:
466
* (see iface_proc_info() in net/ipv6/addrconf.c)
467
* <addr6:32> <ifindex:2> <prefix:2> <scope:2> <flags:2> <name:8>
469
res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
470
address, &ifindex, &prefix, &scope, &flags, name);
472
UNEXPECTED_ERROR(__FILE__, __LINE__,
473
"/proc/net/if_inet6:sscanf() -> %d (expected 6)",
475
return (ISC_R_FAILURE);
477
if (strlen(address) != 32) {
478
UNEXPECTED_ERROR(__FILE__, __LINE__,
479
"/proc/net/if_inet6:strlen(%s) != 32", address);
480
return (ISC_R_FAILURE);
482
for (i = 0; i < 16; i++) {
484
static const char hex[] = "0123456789abcdef";
485
byte = ((index(hex, address[i * 2]) - hex) << 4) |
486
(index(hex, address[i * 2 + 1]) - hex);
487
addr6.s6_addr[i] = byte;
489
iter->current.af = AF_INET6;
490
/* iter->current.ifindex = ifindex; */
491
iter->current.flags = 0;
493
memset(&ifreq, 0, sizeof(ifreq));
494
INSIST(sizeof(ifreq.ifr_name) <= sizeof(iter->current.name));
495
strncpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
497
if (ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) {
498
isc__strerror(errno, strbuf, sizeof(strbuf));
499
UNEXPECTED_ERROR(__FILE__, __LINE__,
500
"%s: getting interface flags: %s",
501
ifreq.ifr_name, strbuf);
502
return (ISC_R_IGNORE);
505
if ((ifreq.ifr_flags & IFF_UP) != 0)
506
iter->current.flags |= INTERFACE_F_UP;
507
#ifdef IFF_POINTOPOINT
508
if ((ifreq.ifr_flags & IFF_POINTOPOINT) != 0)
509
iter->current.flags |= INTERFACE_F_POINTTOPOINT;
511
if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0)
512
iter->current.flags |= INTERFACE_F_LOOPBACK;
513
if ((ifreq.ifr_flags & IFF_BROADCAST) != 0)
514
iter->current.flags |= INTERFACE_F_BROADCAST;
516
if ((ifreq.ifr_flags & IFF_MULTICAST) != 0)
517
iter->current.flags |= INTERFACE_F_MULTICAST;
521
* enable_multicast_if() requires scopeid for setsockopt,
522
* so associate address with their corresponding ifindex.
524
isc_netaddr_fromin6(&iter->current.address, &addr6);
525
isc_netaddr_setzone(&iter->current.address, (isc_uint32_t)ifindex);
527
for (i = 0; i < 16; i++) {
529
addr6.s6_addr[i] = 0xff;
532
addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;
536
isc_netaddr_fromin6(&iter->current.netmask, &addr6);
537
strncpy(iter->current.name, name, sizeof(iter->current.name));
538
return (ISC_R_SUCCESS);
374
553
struct ifreq ifreq;
376
555
char strbuf[ISC_STRERRORSIZE];
377
#if !defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
378
struct if_laddrreq if_laddrreq;
556
#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR)
557
struct lifreq lifreq;
561
int i, bits, prefixlen;
382
566
REQUIRE(VALID_IFITER(iter));
383
567
REQUIRE (iter->pos < (unsigned int) iter->ifc.ifc_len);
570
result = linux_if_inet6_current(iter);
571
if (result != ISC_R_NOMORE)
573
iter->first = ISC_TRUE;
385
576
ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
387
578
memset(&ifreq, 0, sizeof(ifreq));
388
579
memcpy(&ifreq, ifrp, sizeof(ifreq));
390
581
family = ifreq.ifr_addr.sa_family;
391
#if !defined (SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
392
defined(ISC_PLATFORM_HAVEIPV6)
582
#if defined(ISC_PLATFORM_HAVEIPV6)
393
583
if (family != AF_INET && family != AF_INET6)
395
585
if (family != AF_INET)
472
#if !defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
473
if (family == AF_INET)
656
if (family == AF_INET)
476
memset(&if_laddrreq, 0, sizeof(if_laddrreq));
477
memcpy(if_laddrreq.iflr_name, iter->current.name,
478
sizeof(if_laddrreq.iflr_name));
479
memcpy(&if_laddrreq.addr, &iter->current.address.type.in6,
659
#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR)
660
memset(&lifreq, 0, sizeof(lifreq));
661
memcpy(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name));
662
memcpy(&lifreq.lifr_addr, &iter->current.address.type.in6,
480
663
sizeof(iter->current.address.type.in6));
482
if (ioctl(iter->socket, SIOCGLIFADDR, &if_laddrreq) < 0) {
665
if (ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) {
483
666
isc__strerror(errno, strbuf, sizeof(strbuf));
484
667
UNEXPECTED_ERROR(__FILE__, __LINE__,
485
668
"%s: getting interface address: %s",
486
669
ifreq.ifr_name, strbuf);
487
670
return (ISC_R_IGNORE);
672
prefixlen = lifreq.lifr_addrlen;
674
isc_netaddr_format(&iter->current.address, sabuf, sizeof(sabuf));
675
UNEXPECTED_ERROR(__FILE__, __LINE__,
676
isc_msgcat_get(isc_msgcat,
677
ISC_MSGSET_IFITERIOCTL,
679
"prefix length for %s is unknown "
680
"(assume 128)"), sabuf);
491
685
* Netmask already zeroed.
493
687
iter->current.netmask.family = family;
494
688
for (i = 0; i < 16; i++) {
495
if (if_laddrreq.prefixlen > 8) {
497
if_laddrreq.prefixlen -= 8;
499
bits = 8 - if_laddrreq.prefixlen;
500
if_laddrreq.prefixlen = 0;
693
bits = 8 - prefixlen;
502
696
iter->current.netmask.type.in6.s6_addr[i] = (~0 << bits) & 0xff;
504
698
return (ISC_R_SUCCESS);
508
701
if (family != AF_INET)
509
702
return (ISC_R_IGNORE);
703
#ifdef IFF_POINTOPOINT
511
705
* If the interface is point-to-point, get the destination address.
575
769
return (ISC_R_IGNORE);
577
771
get_addr(family, &iter->current.netmask,
578
(struct sockaddr *)&ifreq.ifr_addr);
772
(struct sockaddr *)&ifreq.ifr_addr, ifreq.ifr_name);
579
773
return (ISC_R_SUCCESS);
776
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
582
777
static isc_result_t
583
778
internal_current6(isc_interfaceiter_t *iter) {
584
#if !defined(SIOCGLIFCONF) || !defined(SIOCGLIFADDR)
586
return (ISC_R_NOTIMPLEMENTED);
588
779
struct LIFREQ *ifrp;
589
780
struct LIFREQ lifreq;
591
782
char strbuf[ISC_STRERRORSIZE];
593
785
REQUIRE(VALID_IFITER(iter));
594
REQUIRE (iter->pos < (unsigned int) iter->lifc.lifc_len);
786
if (iter->result6 != ISC_R_SUCCESS)
787
return (iter->result6);
788
REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
596
ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos);
790
ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6);
598
792
memset(&lifreq, 0, sizeof(lifreq));
599
793
memcpy(&lifreq, ifrp, sizeof(lifreq));
642
834
iter->current.flags = 0;
836
if (family == AF_INET6)
645
842
* Ignore the HP/UX warning about "integer overflow during
646
843
* conversion. It comes from its own macro definition,
647
844
* and is really hard to shut up.
649
if (ioctl(iter->socket, SIOCGLIFFLAGS, (char *) &lifreq) < 0) {
652
* XXX This should be looked at further since it looks strange.
653
* If we get an ENXIO then we ignore the error and not worry
656
if (errno != ENXIO) {
657
isc__strerror(errno, strbuf, sizeof(strbuf));
658
UNEXPECTED_ERROR(__FILE__, __LINE__,
846
if (ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) {
847
isc__strerror(errno, strbuf, sizeof(strbuf));
848
UNEXPECTED_ERROR(__FILE__, __LINE__,
659
849
"%s: getting interface flags: %s",
660
850
lifreq.lifr_name, strbuf);
661
return (ISC_R_IGNORE);
851
return (ISC_R_IGNORE);
665
854
if ((lifreq.lifr_flags & IFF_UP) != 0)
666
855
iter->current.flags |= INTERFACE_F_UP;
857
#ifdef IFF_POINTOPOINT
668
858
if ((lifreq.lifr_flags & IFF_POINTOPOINT) != 0)
669
859
iter->current.flags |= INTERFACE_F_POINTTOPOINT;
671
862
if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0)
672
863
iter->current.flags |= INTERFACE_F_LOOPBACK;
725
920
return (ISC_R_IGNORE);
727
922
get_addr(family, &iter->current.broadcast,
728
(struct sockaddr *)&lifreq.lifr_broadaddr);
923
(struct sockaddr *)&lifreq.lifr_broadaddr,
730
926
#endif /* SIOCGLIFBRDADDR */
733
* Get the network mask.
929
* Get the network mask. Netmask already zeroed.
735
931
memset(&lifreq, 0, sizeof(lifreq));
736
932
memcpy(&lifreq, ifrp, sizeof(lifreq));
740
* Ignore the HP/UX warning about "integer overflow during
741
* conversion. It comes from its own macro definition,
742
* and is really hard to shut up.
744
if (ioctl(iter->socket, SIOCGLIFNETMASK, (char *)&lifreq)
746
isc__strerror(errno, strbuf, sizeof(strbuf));
747
UNEXPECTED_ERROR(__FILE__, __LINE__,
748
isc_msgcat_get(isc_msgcat,
749
ISC_MSGSET_IFITERIOCTL,
751
"%s: getting netmask: %s"),
752
lifreq.lifr_name, strbuf);
753
return (ISC_R_IGNORE);
755
get_addr(family, &iter->current.netmask,
756
(struct sockaddr *)&lifreq.lifr_addr);
759
934
#ifdef lifr_addrlen
936
* Special case: if the system provides lifr_addrlen member, the
937
* netmask of an IPv6 address can be derived from the length, since
938
* an IPv6 address always has a contiguous mask.
940
if (family == AF_INET6) {
763
* Netmask already zeroed.
765
943
iter->current.netmask.family = family;
766
944
for (i = 0; i < lifreq.lifr_addrlen; i += 8) {
767
945
bits = lifreq.lifr_addrlen - i;
769
947
iter->current.netmask.type.in6.s6_addr[i / 8] =
770
948
(~0 << bits) & 0xff;
951
return (ISC_R_SUCCESS);
956
* Ignore the HP/UX warning about "integer overflow during
957
* conversion. It comes from its own macro definition,
958
* and is really hard to shut up.
960
if (ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) {
961
isc__strerror(errno, strbuf, sizeof(strbuf));
962
UNEXPECTED_ERROR(__FILE__, __LINE__,
963
isc_msgcat_get(isc_msgcat,
964
ISC_MSGSET_IFITERIOCTL,
966
"%s: getting netmask: %s"),
967
lifreq.lifr_name, strbuf);
968
return (ISC_R_IGNORE);
970
get_addr(family, &iter->current.netmask,
971
(struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
777
973
return (ISC_R_SUCCESS);
781
977
static isc_result_t
782
978
internal_current(isc_interfaceiter_t *iter) {
784
return (internal_current6(iter));
979
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
980
if (iter->mode == 6) {
981
iter->result6 = internal_current6(iter);
982
if (iter->result6 != ISC_R_NOMORE)
983
return (iter->result6);
986
#ifdef HAVE_TRUCLUSTER
987
if (!iter->clua_done)
988
return(internal_current_clusteralias(iter));
785
990
return (internal_current4(iter));
817
1024
return (ISC_R_SUCCESS);
1027
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
820
1028
static isc_result_t
821
1029
internal_next6(isc_interfaceiter_t *iter) {
822
#if !defined(SIOCGLIFCONF) || !defined(SIOCGLIFADDR)
824
return (ISC_R_NOTIMPLEMENTED);
826
1030
struct LIFREQ *ifrp;
828
REQUIRE (iter->pos < (unsigned int) iter->lifc.lifc_len);
830
ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos);
1032
if (iter->result6 != ISC_R_SUCCESS && iter->result6 != ISC_R_IGNORE)
1033
return (iter->result6);
1035
REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
1037
ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6);
832
1039
#ifdef ISC_PLATFORM_HAVESALEN
833
1040
if (ifrp->lifr_addr.sa_len > sizeof(struct sockaddr))
834
iter->pos += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len;
1041
iter->pos6 += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len;
837
iter->pos += sizeof(*ifrp);
1044
iter->pos6 += sizeof(*ifrp);
839
if (iter->pos >= (unsigned int) iter->lifc.lifc_len)
1046
if (iter->pos6 >= (unsigned int) iter->lifc.lifc_len)
840
1047
return (ISC_R_NOMORE);
842
1049
return (ISC_R_SUCCESS);
846
1053
static isc_result_t
847
1054
internal_next(isc_interfaceiter_t *iter) {
849
return (internal_next6(iter));
1055
#ifdef HAVE_TRUCLUSTER
1058
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
1059
if (iter->mode == 6) {
1060
iter->result6 = internal_next6(iter);
1061
if (iter->result6 != ISC_R_NOMORE)
1062
return (iter->result6);
1064
iter->first6 = ISC_FALSE;
1065
return (ISC_R_SUCCESS);
1069
#ifdef HAVE_TRUCLUSTER
1070
if (!iter->clua_done) {
1071
clua_result = clua_getaliasaddress(&iter->clua_sa,
1072
&iter->clua_context);
1073
if (clua_result != CLUA_SUCCESS)
1074
iter->clua_done = ISC_TRUE;
1075
return (ISC_R_SUCCESS);
850
1078
return (internal_next4(iter));
854
1082
internal_destroy(isc_interfaceiter_t *iter) {
855
1083
(void) close(iter->socket);
1084
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
1085
if (iter->socket6 != -1)
1086
(void) close(iter->socket6);
1087
if (iter->buf6 != NULL) {
1088
isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
1092
if (iter->proc != NULL)
1098
void internal_first(isc_interfaceiter_t *iter) {
1099
#ifdef HAVE_TRUCLUSTER
1103
#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
1105
if (iter->result6 == ISC_R_NOMORE)
1106
iter->result6 = ISC_R_SUCCESS;
1107
iter->first6 = ISC_TRUE;
1109
#ifdef HAVE_TRUCLUSTER
1110
iter->clua_context = 0;
1111
clua_result = clua_getaliasaddress(&iter->clua_sa,
1112
&iter->clua_context);
1113
iter->clua_done = ISC_TF(clua_result != CLUA_SUCCESS);
1116
linux_if_inet6_first(iter);