Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / own_inet_addr.c
bloba475010356e2d34650fdd3d58dd9f2bd705ff9ad
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* own_inet_addr 3
6 /* SUMMARY
7 /* determine if IP address belongs to this mail system instance
8 /* SYNOPSIS
9 /* #include <own_inet_addr.h>
11 /* int own_inet_addr(addr)
12 /* struct sockaddr *addr;
14 /* INET_ADDR_LIST *own_inet_addr_list()
16 /* INET_ADDR_LIST *own_inet_mask_list()
18 /* int proxy_inet_addr(addr)
19 /* struct in_addr *addr;
21 /* INET_ADDR_LIST *proxy_inet_addr_list()
22 /* DESCRIPTION
23 /* own_inet_addr() determines if the specified IP address belongs
24 /* to this mail system instance, i.e. if this mail system instance
25 /* is supposed to be listening on this specific IP address.
27 /* own_inet_addr_list() returns the list of all addresses that
28 /* belong to this mail system instance.
30 /* own_inet_mask_list() returns the list of all corresponding
31 /* netmasks.
33 /* proxy_inet_addr() determines if the specified IP address is
34 /* listed with the proxy_interfaces configuration parameter.
36 /* proxy_inet_addr_list() returns the list of all addresses that
37 /* belong to proxy network interfaces.
38 /* LICENSE
39 /* .ad
40 /* .fi
41 /* The Secure Mailer license must be distributed with this software.
42 /* AUTHOR(S)
43 /* Wietse Venema
44 /* IBM T.J. Watson Research
45 /* P.O. Box 704
46 /* Yorktown Heights, NY 10598, USA
47 /*--*/
49 /* System library. */
51 #include <sys_defs.h>
52 #include <string.h>
54 /* Utility library. */
56 #include <msg.h>
57 #include <mymalloc.h>
58 #include <inet_addr_list.h>
59 #include <inet_addr_local.h>
60 #include <inet_addr_host.h>
61 #include <stringops.h>
62 #include <myaddrinfo.h>
63 #include <sock_addr.h>
64 #include <inet_proto.h>
66 /* Global library. */
68 #include <mail_params.h>
69 #include <own_inet_addr.h>
71 /* Application-specific. */
73 static INET_ADDR_LIST saved_addr_list;
74 static INET_ADDR_LIST saved_mask_list;
75 static INET_ADDR_LIST saved_proxy_list;
77 /* own_inet_addr_init - initialize my own address list */
79 static void own_inet_addr_init(INET_ADDR_LIST *addr_list,
80 INET_ADDR_LIST *mask_list)
82 INET_ADDR_LIST local_addrs;
83 INET_ADDR_LIST local_masks;
84 char *hosts;
85 char *host;
86 const char *sep = " \t,";
87 char *bufp;
88 int nvirtual;
89 int nlocal;
90 MAI_HOSTADDR_STR hostaddr;
91 struct sockaddr_storage *sa;
92 struct sockaddr_storage *ma;
94 inet_addr_list_init(addr_list);
95 inet_addr_list_init(mask_list);
98 * If we are listening on all interfaces (default), ask the system what
99 * the interfaces are.
101 if (strcmp(var_inet_interfaces, INET_INTERFACES_ALL) == 0) {
102 if (inet_addr_local(addr_list, mask_list,
103 inet_proto_info()->ai_family_list) == 0)
104 msg_fatal("could not find any active network interfaces");
108 * Select all loopback interfaces from the system's available interface
109 * list.
111 else if (strcmp(var_inet_interfaces, INET_INTERFACES_LOCAL) == 0) {
112 inet_addr_list_init(&local_addrs);
113 inet_addr_list_init(&local_masks);
114 if (inet_addr_local(&local_addrs, &local_masks,
115 inet_proto_info()->ai_family_list) == 0)
116 msg_fatal("could not find any active network interfaces");
117 for (sa = local_addrs.addrs, ma = local_masks.addrs;
118 sa < local_addrs.addrs + local_addrs.used; sa++, ma++) {
119 if (sock_addr_in_loopback(SOCK_ADDR_PTR(sa))) {
120 inet_addr_list_append(addr_list, SOCK_ADDR_PTR(sa));
121 inet_addr_list_append(mask_list, SOCK_ADDR_PTR(ma));
124 inet_addr_list_free(&local_addrs);
125 inet_addr_list_free(&local_masks);
129 * If we are supposed to be listening only on specific interface
130 * addresses (virtual hosting), look up the addresses of those
131 * interfaces.
133 else {
134 bufp = hosts = mystrdup(var_inet_interfaces);
135 while ((host = mystrtok(&bufp, sep)) != 0)
136 if (inet_addr_host(addr_list, host) == 0)
137 msg_fatal("config variable %s: host not found: %s",
138 VAR_INET_INTERFACES, host);
139 myfree(hosts);
142 * Weed out duplicate IP addresses. Duplicates happen when the same
143 * IP address is listed under multiple hostnames. If we don't weed
144 * out duplicates, Postfix can suddenly stop working after the DNS is
145 * changed.
147 inet_addr_list_uniq(addr_list);
150 * Find out the netmask for each virtual interface, by looking it up
151 * among all the local interfaces.
153 inet_addr_list_init(&local_addrs);
154 inet_addr_list_init(&local_masks);
155 if (inet_addr_local(&local_addrs, &local_masks,
156 inet_proto_info()->ai_family_list) == 0)
157 msg_fatal("could not find any active network interfaces");
158 for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
159 for (nlocal = 0; /* see below */ ; nlocal++) {
160 if (nlocal >= local_addrs.used) {
161 SOCKADDR_TO_HOSTADDR(
162 SOCK_ADDR_PTR(addr_list->addrs + nvirtual),
163 SOCK_ADDR_LEN(addr_list->addrs + nvirtual),
164 &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
165 msg_fatal("parameter %s: no local interface found for %s",
166 VAR_INET_INTERFACES, hostaddr.buf);
168 if (SOCK_ADDR_EQ_ADDR(addr_list->addrs + nvirtual,
169 local_addrs.addrs + nlocal)) {
170 inet_addr_list_append(mask_list,
171 SOCK_ADDR_PTR(local_masks.addrs + nlocal));
172 break;
176 inet_addr_list_free(&local_addrs);
177 inet_addr_list_free(&local_masks);
181 /* own_inet_addr - is this my own internet address */
183 int own_inet_addr(struct sockaddr * addr)
185 int i;
187 if (saved_addr_list.used == 0)
188 own_inet_addr_init(&saved_addr_list, &saved_mask_list);
190 for (i = 0; i < saved_addr_list.used; i++)
191 if (SOCK_ADDR_EQ_ADDR(addr, saved_addr_list.addrs + i))
192 return (1);
193 return (0);
196 /* own_inet_addr_list - return list of addresses */
198 INET_ADDR_LIST *own_inet_addr_list(void)
200 if (saved_addr_list.used == 0)
201 own_inet_addr_init(&saved_addr_list, &saved_mask_list);
203 return (&saved_addr_list);
206 /* own_inet_mask_list - return list of addresses */
208 INET_ADDR_LIST *own_inet_mask_list(void)
210 if (saved_addr_list.used == 0)
211 own_inet_addr_init(&saved_addr_list, &saved_mask_list);
213 return (&saved_mask_list);
216 /* proxy_inet_addr_init - initialize my proxy interface list */
218 static void proxy_inet_addr_init(INET_ADDR_LIST *addr_list)
220 char *hosts;
221 char *host;
222 const char *sep = " \t,";
223 char *bufp;
226 * Parse the proxy_interfaces parameter, and expand any symbolic
227 * hostnames into IP addresses.
229 inet_addr_list_init(addr_list);
230 bufp = hosts = mystrdup(var_proxy_interfaces);
231 while ((host = mystrtok(&bufp, sep)) != 0)
232 if (inet_addr_host(addr_list, host) == 0)
233 msg_fatal("config variable %s: host not found: %s",
234 VAR_PROXY_INTERFACES, host);
235 myfree(hosts);
238 * Weed out duplicate IP addresses.
240 inet_addr_list_uniq(addr_list);
243 /* proxy_inet_addr - is this my proxy internet address */
245 int proxy_inet_addr(struct sockaddr * addr)
247 int i;
249 if (*var_proxy_interfaces == 0)
250 return (0);
252 if (saved_proxy_list.used == 0)
253 proxy_inet_addr_init(&saved_proxy_list);
255 for (i = 0; i < saved_proxy_list.used; i++)
256 if (SOCK_ADDR_EQ_ADDR(addr, saved_proxy_list.addrs + i))
257 return (1);
258 return (0);
261 /* proxy_inet_addr_list - return list of addresses */
263 INET_ADDR_LIST *proxy_inet_addr_list(void)
265 if (*var_proxy_interfaces != 0 && saved_proxy_list.used == 0)
266 proxy_inet_addr_init(&saved_proxy_list);
268 return (&saved_proxy_list);
271 #ifdef TEST
272 #include <inet_proto.h>
274 static void inet_addr_list_print(INET_ADDR_LIST *list)
276 MAI_HOSTADDR_STR hostaddr;
277 struct sockaddr_storage *sa;
279 for (sa = list->addrs; sa < list->addrs + list->used; sa++) {
280 SOCKADDR_TO_HOSTADDR(SOCK_ADDR_PTR(sa), SOCK_ADDR_LEN(sa),
281 &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
282 msg_info("%s", hostaddr.buf);
286 char *var_inet_interfaces;
288 int main(int argc, char **argv)
290 INET_PROTO_INFO *proto_info;
291 INET_ADDR_LIST *list;
293 if (argc != 3)
294 msg_fatal("usage: %s protocols interface_list (e.g. \"all all\")",
295 argv[0]);
296 msg_verbose = 10;
297 proto_info = inet_proto_init(argv[0], argv[1]);
298 var_inet_interfaces = argv[2];
299 list = own_inet_addr_list();
300 inet_addr_list_print(list);
301 return (0);
304 #endif