1 /* $Cambridge: exim/src/OS/os.c-IRIX6,v 1.1 2004/10/06 15:07:39 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 2001 */
8 /* See the file NOTICE for conditions of use and distribution. */
10 /* Irix-specific code. This is concatenated onto the generic src/os.c file.
11 Irix has a unique way of finding all the network interfaces, so we provide a
12 unique function here, and define FIND_RUNNING_INTERFACES to stop src/os.c
13 trying to provide the function. The macro may be set initially anyway, when
14 compiling os. for utilities that don't want this function. */
16 #ifndef FIND_RUNNING_INTERFACES
17 #define FIND_RUNNING_INTERFACES
19 /* This is the special form of the function using sysctl() which is the only
20 form that returns all the aliases on IRIX systems. This code has its origins
21 in a sample program that came from within SGI. */
23 #include <sys/sysctl.h>
24 #include <net/if_dl.h>
25 #include <net/if_types.h>
26 #include <net/soioctl.h>
27 #include <net/route.h>
29 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) -1))) \
32 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
34 #define ADVANCE(x, n) (x += ROUNDUP(_FAKE_SA_LEN_DST(n)))
39 os_find_running_interfaces(void)
41 ip_address_item *yield = NULL;
42 ip_address_item *last = NULL;
43 ip_address_item *next;
47 char *buf, *nextaddr, *lim;
48 register struct if_msghdr *ifm;
54 mib[4] = NET_RT_IFLIST;
57 /* Get an estimate of the amount of store needed, then get the store and
58 get the data into it. Any error causes a panic death. */
60 if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
61 log_write(0, LOG_PANIC_DIE, "iflist-sysctl-estimate failed: %s",
64 buf = store_get(needed);
66 if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
67 log_write(0, LOG_PANIC_DIE, "sysctl of ifnet list failed: %s",
70 /* Now fish out the data for each interface */
73 for (nextaddr = buf; nextaddr < lim; nextaddr += ifm->ifm_msglen)
75 ifm = (struct if_msghdr *)nextaddr;
77 if (ifm->ifm_type != RTM_IFINFO)
79 struct ifa_msghdr *ifam = (struct ifa_msghdr *)ifm;
80 struct sockaddr_in *mask = NULL, *addr = NULL;
82 if ((ifam->ifam_addrs & RTA_NETMASK) != 0)
83 mask = (struct sockaddr_in *)(ifam + 1);
85 if ((ifam->ifam_addrs & RTA_IFA) != 0)
87 char *cp = (char *)mask;
88 struct sockaddr *sa = (struct sockaddr *)mask;
90 addr = (struct sockaddr_in *)cp;
93 /* Create a data block for the address, fill in the data, and put it on
94 the chain. This data has to survive for ever, so use malloc. */
98 next = store_malloc(sizeof(ip_address_item));
101 (void)host_ntoa(-1, addr, next->address, NULL);
103 if (yield == NULL) yield = last = next; else
109 DEBUG(D_interface) debug_printf("Actual local interface address is %s\n",
118 #endif /* FIND_RUNNING_INTERFACES */
120 /* End of os.c-IRIX */