5 * Copyright 1990,1991 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, please see the file
11 * Return the protocol addresses supported by this host.
13 * XNS support is untested, but "Should just work".
16 #if !defined(lint) && !defined(SABER)
17 static char rcsid_getaddr_c[] =
19 #endif /* !lint & !SABER */
21 #include <krb5/krb5.h>
22 #include <krb5/osconf.h>
24 #include <krb5/ext-proto.h>
26 #include <sys/ioctl.h>
27 #include <sys/socket.h>
29 #include <sys/errno.h>
32 * The SIOCGIF* ioctls require a socket.
33 * It doesn't matter *what* kind of socket they use, but it has to be
36 * Of course, you can't just ask the kernel for a socket of arbitrary
37 * type; you have to ask for one with a valid type.
42 #include <netinet/in.h>
45 #define USE_AF AF_INET
46 #define USE_TYPE SOCK_DGRAM
58 #define USE_TYPE SOCK_DGRAM
59 #define USE_PROTO 0 /* guess */
64 * Add more address families here.
70 * Return all the protocol addresses of this host.
72 * We could kludge up something to return all addresses, assuming that
73 * they're valid kerberos protocol addresses, but we wouldn't know the
74 * real size of the sockaddr or know which part of it was actually the
77 * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's.
80 krb5_error_code krb5_os_localaddr(addr)
87 krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ];
91 ifc.ifc_len = sizeof(buf);
94 s = socket (USE_AF, USE_TYPE, USE_PROTO);
98 code = ioctl (s, SIOCGIFCONF, (char *)&ifc);
104 n = ifc.ifc_len / sizeof (struct ifreq);
106 for (n_found=0, i=0; i<n && ! mem_err; i++) {
107 krb5_address *address;
108 ifr = &ifc.ifc_req[i];
110 if (ioctl (s, SIOCGIFFLAGS, (char *)ifr) < 0)
114 if (ifr->ifr_flags & IFF_LOOPBACK)
118 if (!(ifr->ifr_flags & IFF_UP))
119 /* interface is down; skip */
122 if (ioctl (s, SIOCGIFADDR, (char *)ifr) < 0)
123 /* can't get address */
126 /* ifr->ifr_addr has what we want! */
127 switch (ifr->ifr_addr.sa_family) {
131 struct sockaddr_in *in =
132 (struct sockaddr_in *)&ifr->ifr_addr;
134 address = (krb5_address *)
135 malloc (sizeof(krb5_address));
137 address->addrtype = ADDRTYPE_INET;
138 address->length = sizeof(struct in_addr);
139 address->contents = (unsigned char *)malloc(address->length);
140 if (!address->contents) {
145 memcpy ((char *)address->contents,
146 (char *)&in->sin_addr,
156 struct sockaddr_ns *ns =
157 (struct sockaddr_ns *)&ifr->ifr_addr;
158 address = (krb5_address *)
159 malloc (sizeof (krb5_address) + sizeof (struct ns_addr));
161 address->addrtype = ADDRTYPE_XNS;
163 /* XXX should we perhaps use ns_host instead? */
165 address->length = sizeof(struct ns_addr);
166 address->contents = (unsigned char *)malloc(address->length);
167 if (!address->contents) {
172 memcpy ((char *)address->contents,
173 (char *)&ns->sns_addr,
182 * Add more address families here..
188 addr_temp[n_found++] = address;
193 *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1));
198 for (i=0; i<n_found; i++) {
205 for (i=0; i<n_found; i++) {
206 (*addr)[i] = addr_temp[i];
208 (*addr)[n_found] = 0;