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