Harmonised TLS library version reporting.
[exim.git] / src / OS / os.c-IRIX632
CommitLineData
61ec970d
PH
1/* $Cambridge: exim/src/OS/os.c-IRIX632,v 1.1 2004/10/06 15:07:39 ph10 Exp $ */
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
7/* Copyright (c) University of Cambridge 2001 */
8/* See the file NOTICE for conditions of use and distribution. */
9
10/* Irix-specific code. This is concatenated onto the generic src/os.c file.
11Irix has a unique way of finding all the network interfaces, so we provide a
12unique function here, and define FIND_RUNNING_INTERFACES to stop src/os.c
13trying to provide the function. The macro may be set initially anyway, when
14compiling os. for utilities that don't want this function. */
15
16#ifndef FIND_RUNNING_INTERFACES
17#define FIND_RUNNING_INTERFACES
18
19/* This is the special form of the function using sysctl() which is the only
20form that returns all the aliases on IRIX systems. This code has its origins
21in a sample program that came from within SGI. */
22
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>
28
29#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) -1))) \
30 : sizeof(__uint64_t))
31#ifdef _HAVE_SA_LEN
32#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
33#else
34#define ADVANCE(x, n) (x += ROUNDUP(_FAKE_SA_LEN_DST(n)))
35#endif
36
37
38ip_address_item *
39os_find_running_interfaces(void)
40{
41ip_address_item *yield = NULL;
42ip_address_item *last = NULL;
43ip_address_item *next;
44
45size_t needed;
46int mib[6];
47char *buf, *nextaddr, *lim;
48register struct if_msghdr *ifm;
49
50mib[0] = CTL_NET;
51mib[1] = PF_ROUTE;
52mib[2] = 0;
53mib[3] = 0;
54mib[4] = NET_RT_IFLIST;
55mib[5] = 0;
56
57/* Get an estimate of the amount of store needed, then get the store and
58get the data into it. Any error causes a panic death. */
59
60if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
61 log_write(0, LOG_PANIC_DIE, "iflist-sysctl-estimate failed: %s",
62 strerror(errno));
63
64buf = store_get(needed);
65
66if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
67 log_write(0, LOG_PANIC_DIE, "sysctl of ifnet list failed: %s",
68 strerror(errno));
69
70/* Now fish out the data for each interface */
71
72lim = buf + needed;
73for (nextaddr = buf; nextaddr < lim; nextaddr += ifm->ifm_msglen)
74 {
75 ifm = (struct if_msghdr *)nextaddr;
76
77 if (ifm->ifm_type != RTM_IFINFO)
78 {
79 struct ifa_msghdr *ifam = (struct ifa_msghdr *)ifm;
80 struct sockaddr_in *mask = NULL, *addr = NULL;
81
82 if ((ifam->ifam_addrs & RTA_NETMASK) != 0)
83 mask = (struct sockaddr_in *)(ifam + 1);
84
85 if ((ifam->ifam_addrs & RTA_IFA) != 0)
86 {
87 char *cp = (char *)mask;
88 struct sockaddr *sa = (struct sockaddr *)mask;
89 ADVANCE(cp, sa);
90 addr = (struct sockaddr_in *)cp;
91 }
92
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. */
95
96 if (addr != NULL)
97 {
98 next = store_malloc(sizeof(ip_address_item));
99 next->next = NULL;
100 next->port = 0;
101 (void)host_ntoa(-1, addr, next->address, NULL);
102
103 if (yield == NULL) yield = last = next; else
104 {
105 last->next = next;
106 last = next;
107 }
108
109 DEBUG(D_interface) debug_printf("Actual local interface address is %s\n",
110 last->address);
111 }
112 }
113 }
114
115return yield;
116}
117
118#endif /* FIND_RUNNING_INTERFACES */
119
120/* End of os.c-IRIX */