1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 2022 */
6 /* Copyright (c) University of Cambridge 2001 */
7 /* See the file NOTICE for conditions of use and distribution. */
9 /* Irix-specific code. This is concatenated onto the generic src/os.c file.
10 Irix has a unique way of finding all the network interfaces, so we provide a
11 unique function here, and define FIND_RUNNING_INTERFACES to stop src/os.c
12 trying to provide the function. The macro may be set initially anyway, when
13 compiling os. for utilities that don't want this function. */
15 #ifndef FIND_RUNNING_INTERFACES
16 #define FIND_RUNNING_INTERFACES
18 /* This is the special form of the function using sysctl() which is the only
19 form that returns all the aliases on IRIX systems. This code has its origins
20 in a sample program that came from within SGI. */
22 #include <sys/sysctl.h>
23 #include <net/if_dl.h>
24 #include <net/if_types.h>
25 #include <net/soioctl.h>
26 #include <net/route.h>
28 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) -1))) \
31 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
33 #define ADVANCE(x, n) (x += ROUNDUP(_FAKE_SA_LEN_DST(n)))
38 os_find_running_interfaces(void)
40 ip_address_item *yield = NULL;
41 ip_address_item *last = NULL;
42 ip_address_item *next;
46 char *buf, *nextaddr, *lim;
47 register struct if_msghdr *ifm;
53 mib[4] = NET_RT_IFLIST;
56 /* Get an estimate of the amount of store needed, then get the store and
57 get the data into it. Any error causes a panic death. */
59 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
60 log_write(0, LOG_PANIC_DIE, "iflist-sysctl-estimate failed: %s",
63 buf = store_get(needed, GET_UNTAINTED);
65 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
66 log_write(0, LOG_PANIC_DIE, "sysctl of ifnet list failed: %s",
69 /* Now fish out the data for each interface */
72 for (nextaddr = buf; nextaddr < lim; nextaddr += ifm->ifm_msglen)
74 ifm = (struct if_msghdr *)nextaddr;
76 if (ifm->ifm_type != RTM_IFINFO)
78 struct ifa_msghdr *ifam = (struct ifa_msghdr *)ifm;
79 struct sockaddr_in *mask = NULL, *addr = NULL;
81 if ((ifam->ifam_addrs & RTA_NETMASK) != 0)
82 mask = (struct sockaddr_in *)(ifam + 1);
84 if ((ifam->ifam_addrs & RTA_IFA) != 0)
87 struct sockaddr *sa = (struct sockaddr *)mask;
89 addr = (struct sockaddr_in *)cp;
92 /* Create a data block for the address, fill in the data, and put it on
93 the chain. This data has to survive for ever, so use malloc. */
97 next = store_malloc(sizeof(ip_address_item));
100 (void)host_ntoa(-1, addr, next->address, NULL);
102 if (yield == NULL) yield = last = next; else
108 DEBUG(D_interface) debug_printf("Actual local interface address is %s\n",
117 #endif /* FIND_RUNNING_INTERFACES */
119 /* End of os.c-IRIX */