7 /* determine if IP address belongs to this mail system instance
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()
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
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.
41 /* The Secure Mailer license must be distributed with this software.
44 /* IBM T.J. Watson Research
46 /* Yorktown Heights, NY 10598, USA
54 /* Utility library. */
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>
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
;
86 const char *sep
= " \t,";
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
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
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
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
);
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
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
));
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
)
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
))
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
)
222 const char *sep
= " \t,";
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
);
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
)
249 if (*var_proxy_interfaces
== 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
))
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
);
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
;
294 msg_fatal("usage: %s protocols interface_list (e.g. \"all all\")",
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
);