Commit | Line | Data |
---|---|---|
61ec970d PH |
1 | /* $Cambridge: exim/src/OS/os.c-IRIX,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. | |
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. */ | |
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 | |
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. */ | |
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 | ||
38 | ip_address_item * | |
39 | os_find_running_interfaces(void) | |
40 | { | |
41 | ip_address_item *yield = NULL; | |
42 | ip_address_item *last = NULL; | |
43 | ip_address_item *next; | |
44 | ||
45 | size_t needed; | |
46 | int mib[6]; | |
47 | char *buf, *nextaddr, *lim; | |
48 | register struct if_msghdr *ifm; | |
49 | ||
50 | mib[0] = CTL_NET; | |
51 | mib[1] = PF_ROUTE; | |
52 | mib[2] = 0; | |
53 | mib[3] = 0; | |
54 | mib[4] = NET_RT_IFLIST; | |
55 | mib[5] = 0; | |
56 | ||
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. */ | |
59 | ||
60 | if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) | |
61 | log_write(0, LOG_PANIC_DIE, "iflist-sysctl-estimate failed: %s", | |
62 | strerror(errno)); | |
63 | ||
64 | buf = store_get(needed); | |
65 | ||
66 | if (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 | ||
72 | lim = buf + needed; | |
73 | for (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 | ||
115 | return yield; | |
116 | } | |
117 | ||
118 | #endif /* FIND_RUNNING_INTERFACES */ | |
119 | ||
120 | /* End of os.c-IRIX */ |