Postfix3.3.1
inet_addr_local.c
[詳解]
1 /*++
2 /* NAME
3 /* inet_addr_local 3
4 /* SUMMARY
5 /* determine if IP address is local
6 /* SYNOPSIS
7 /* #include <inet_addr_local.h>
8 /*
9 /* int inet_addr_local(addr_list, mask_list, addr_family_list)
10 /* INET_ADDR_LIST *addr_list;
11 /* INET_ADDR_LIST *mask_list;
12 /* unsigned *addr_family;
13 /* DESCRIPTION
14 /* inet_addr_local() determines all active IP interface addresses
15 /* of the local system. Any address found is appended to the
16 /* specified address list. The result value is the number of
17 /* active interfaces found.
18 /*
19 /* The mask_list is either a null pointer, or it is a list that
20 /* receives the netmasks of the interface addresses that were found.
21 /*
22 /* The addr_family_list specifies one or more of AF_INET or AF_INET6.
23 /* DIAGNOSTICS
24 /* Fatal errors: out of memory.
25 /* SEE ALSO
26 /* inet_addr_list(3) address list management
27 /* LICENSE
28 /* .ad
29 /* .fi
30 /* The Secure Mailer license must be distributed with this software.
31 /* AUTHOR(S)
32 /* Wietse Venema
33 /* IBM T.J. Watson Research
34 /* P.O. Box 704
35 /* Yorktown Heights, NY 10598, USA
36 /*
37 /* Dean C. Strik
38 /* Department ICT
39 /* Eindhoven University of Technology
40 /* P.O. Box 513
41 /* 5600 MB Eindhoven, Netherlands
42 /* E-mail: <dean@ipnet6.org>
43 /*--*/
44 
45 /* System library. */
46 
47 #include <sys_defs.h>
48 #include <sys/socket.h>
49 #include <sys/time.h>
50 #include <netinet/in.h>
51 #include <net/if.h>
52 #include <sys/ioctl.h>
53 #include <arpa/inet.h>
54 #include <unistd.h>
55 #ifdef USE_SYS_SOCKIO_H
56 #include <sys/sockio.h>
57 #endif
58 #include <errno.h>
59 #include <string.h>
60 #ifdef HAS_IPV6 /* Linux only? */
61 #include <netdb.h>
62 #include <stdio.h>
63 #endif
64 #ifdef HAVE_GETIFADDRS
65 #include <ifaddrs.h>
66 #endif
67 
68 /* Utility library. */
69 
70 #include <msg.h>
71 #include <mymalloc.h>
72 #include <vstring.h>
73 #include <inet_addr_list.h>
74 #include <inet_addr_local.h>
75 #include <myaddrinfo.h>
76 #include <sock_addr.h>
77 #include <mask_addr.h>
78 #include <hex_code.h>
79 
80  /*
81  * Postfix needs its own interface address information to determine whether
82  * or not it is an MX host for some destination; without this information,
83  * mail would loop between MX hosts. Postfix also needs its interface
84  * addresses to figure out whether or not it is final destination for
85  * addresses of the form username@[ipaddress].
86  *
87  * Postfix needs its own interface netmask information when no explicit
88  * mynetworks setting is given in main.cf, and "mynetworks_style = subnet".
89  * The mynetworks parameter controls, among others, what mail clients are
90  * allowed to relay mail through Postfix.
91  *
92  * Different systems have different ways to find out this information. We will
93  * therefore use OS dependent methods. An overview:
94  *
95  * - Use getifaddrs() when available. This supports both IPv4/IPv6 addresses.
96  * The implementation however is not present in all major operating systems.
97  *
98  * - Use SIOCGLIFCONF when available. This supports both IPv4/IPv6 addresses.
99  * With SIOCGLIFNETMASK we can obtain the netmask for either address family.
100  * Again, this is not present in all major operating systems.
101  *
102  * - On Linux, glibc's getifaddrs(3) has returned IPv4 information for some
103  * time, but IPv6 information was not returned until 2.3.3. With older Linux
104  * versions we get IPv4 interface information with SIOCGIFCONF, and read
105  * IPv6 address/prefix information from a file in the /proc filesystem.
106  *
107  * - On other systems we expect SIOCGIFCONF to return IPv6 addresses. Since
108  * SIOCGIFNETMASK does not work reliably for IPv6 addresses, we always set
109  * the prefix length to /128 (host), and expect the user to configure a more
110  * appropriate mynetworks setting if needed.
111  *
112  * XXX: Each lookup method is implemented by its own function, so we duplicate
113  * some code. In this case, I think this is better than really drowning in
114  * the #ifdefs...
115  *
116  * -- Dean Strik (dcs)
117  */
118 
119 #ifndef HAVE_GETIFADDRS
120 
121 /* ial_socket - make socket for ioctl() operations */
122 
123 static int ial_socket(int af)
124 {
125  const char *myname = "inet_addr_local[socket]";
126  int sock;
127 
128  /*
129  * The host may not be actually configured with IPv6. When IPv6 support
130  * is not actually in the kernel, don't consider failure to create an
131  * IPv6 socket as fatal. This could be tuned better though. For other
132  * families, the error is fatal.
133  *
134  * XXX Now that Postfix controls protocol support centrally with the
135  * inet_proto(3) module, this workaround should no longer be needed.
136  */
137  if ((sock = socket(af, SOCK_DGRAM, 0)) < 0) {
138 #ifdef HAS_IPV6
139  if (af == AF_INET6) {
140  if (msg_verbose)
141  msg_warn("%s: socket: %m", myname);
142  return (-1);
143  }
144 #endif
145  msg_fatal("%s: socket: %m", myname);
146  }
147  return (sock);
148 }
149 
150 #endif
151 
152 #ifdef HAVE_GETIFADDRS
153 
154 /*
155  * The getifaddrs(3) function, introduced by BSD/OS, provides a
156  * platform-independent way of requesting interface addresses,
157  * including IPv6 addresses. The implementation however is not
158  * present in all major operating systems.
159  */
160 
161 /* ial_getifaddrs - determine IP addresses using getifaddrs(3) */
162 
163 static int ial_getifaddrs(INET_ADDR_LIST *addr_list,
164  INET_ADDR_LIST *mask_list,
165  int af)
166 {
167  const char *myname = "inet_addr_local[getifaddrs]";
168  struct ifaddrs *ifap, *ifa;
169  struct sockaddr *sa, *sam;
170 
171  if (getifaddrs(&ifap) < 0)
172  msg_fatal("%s: getifaddrs: %m", myname);
173 
174  /*
175  * Get the address of each IP network interface. According to BIND we
176  * must include interfaces that are down because the machine may still
177  * receive packets for that address (yes, via some other interface).
178  * Having no way to verify this claim on every machine, I will give them
179  * the benefit of the doubt.
180  *
181  * FIX 200501: The IPv6 patch did not report NetBSD loopback interfaces;
182  * fixed by replacing IFF_RUNNING by IFF_UP.
183  *
184  * FIX 200501: The IPV6 patch did not skip wild-card interface addresses
185  * (tested on FreeBSD).
186  */
187  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
188  if (!(ifa->ifa_flags & IFF_UP) || ifa->ifa_addr == 0)
189  continue;
190  sa = ifa->ifa_addr;
191  if (af != AF_UNSPEC && sa->sa_family != af)
192  continue;
193  sam = ifa->ifa_netmask;
194  if (sam == 0) {
195  /* XXX In mynetworks, a null netmask would match everyone. */
196  msg_warn("ignoring interface with null netmask, address family %d",
197  sa->sa_family);
198  continue;
199  }
200  switch (sa->sa_family) {
201  case AF_INET:
202  if (SOCK_ADDR_IN_ADDR(sa).s_addr == INADDR_ANY)
203  continue;
204  break;
205 #ifdef HAS_IPV6
206  case AF_INET6:
207  if (IN6_IS_ADDR_UNSPECIFIED(&SOCK_ADDR_IN6_ADDR(sa)))
208  continue;
209  break;
210 #endif
211  default:
212  continue;
213  }
214 
215  inet_addr_list_append(addr_list, sa);
216  if (mask_list != 0) {
217 
218  /*
219  * Unfortunately, sa_len/sa_family may be broken in the netmask
220  * sockaddr structure. We must fix this manually to have correct
221  * addresses. --dcs
222  */
223 #ifdef HAS_SA_LEN
224  sam->sa_len = sa->sa_family == AF_INET6 ?
225  sizeof(struct sockaddr_in6) :
226  sizeof(struct sockaddr_in);
227 #endif
228  sam->sa_family = sa->sa_family;
229  inet_addr_list_append(mask_list, sam);
230  }
231  }
232  freeifaddrs(ifap);
233  return (0);
234 }
235 
236 #elif defined(HAS_SIOCGLIF) /* HAVE_GETIFADDRS */
237 
238 /*
239  * The SIOCLIF* ioctls are the successors of SIOCGIF* on the Solaris
240  * and HP/UX operating systems. The data is stored in sockaddr_storage
241  * structure. Both IPv4 and IPv6 addresses are returned though these
242  * calls.
243  */
244 #define NEXT_INTERFACE(lifr) (lifr + 1)
245 #define LIFREQ_SIZE(lifr) sizeof(lifr[0])
246 
247 /* ial_siocglif - determine IP addresses using ioctl(SIOCGLIF*) */
248 
249 static int ial_siocglif(INET_ADDR_LIST *addr_list,
250  INET_ADDR_LIST *mask_list,
251  int af)
252 {
253  const char *myname = "inet_addr_local[siocglif]";
254  struct lifconf lifc;
255  struct lifreq *lifr;
256  struct lifreq *lifr_mask;
257  struct lifreq *the_end;
258  struct sockaddr *sa;
259  int sock;
260  VSTRING *buf;
261 
262  /*
263  * See also comments in ial_siocgif()
264  */
265  if (af != AF_INET && af != AF_INET6)
266  msg_fatal("%s: address family was %d, must be AF_INET (%d) or "
267  "AF_INET6 (%d)", myname, af, AF_INET, AF_INET6);
268  sock = ial_socket(af);
269  if (sock < 0)
270  return (0);
271  buf = vstring_alloc(1024);
272  for (;;) {
273  memset(&lifc, 0, sizeof(lifc));
274  lifc.lifc_family = AF_UNSPEC; /* XXX Why??? */
275  lifc.lifc_len = vstring_avail(buf);
276  lifc.lifc_buf = vstring_str(buf);
277  if (ioctl(sock, SIOCGLIFCONF, (char *) &lifc) < 0) {
278  if (errno != EINVAL)
279  msg_fatal("%s: ioctl SIOCGLIFCONF: %m", myname);
280  } else if (lifc.lifc_len < vstring_avail(buf) / 2)
281  break;
282  VSTRING_SPACE(buf, vstring_avail(buf) * 2);
283  }
284 
285  the_end = (struct lifreq *) (lifc.lifc_buf + lifc.lifc_len);
286  for (lifr = lifc.lifc_req; lifr < the_end;) {
287  sa = (struct sockaddr *) &lifr->lifr_addr;
288  if (sa->sa_family != af) {
289  lifr = NEXT_INTERFACE(lifr);
290  continue;
291  }
292  if (af == AF_INET) {
293  if (SOCK_ADDR_IN_ADDR(sa).s_addr == INADDR_ANY) {
294  lifr = NEXT_INTERFACE(lifr);
295  continue;
296  }
297 #ifdef HAS_IPV6
298  } else if (af == AF_INET6) {
299  if (IN6_IS_ADDR_UNSPECIFIED(&SOCK_ADDR_IN6_ADDR(sa))) {
300  lifr = NEXT_INTERFACE(lifr);
301  continue;
302  }
303  }
304 #endif
305  inet_addr_list_append(addr_list, sa);
306  if (mask_list) {
307  lifr_mask = (struct lifreq *) mymalloc(sizeof(struct lifreq));
308  memcpy((void *) lifr_mask, (void *) lifr, sizeof(struct lifreq));
309  if (ioctl(sock, SIOCGLIFNETMASK, lifr_mask) < 0)
310  msg_fatal("%s: ioctl(SIOCGLIFNETMASK): %m", myname);
311  /* XXX: Check whether sa_len/family are honoured --dcs */
312  inet_addr_list_append(mask_list,
313  (struct sockaddr *) &lifr_mask->lifr_addr);
314  myfree((void *) lifr_mask);
315  }
316  lifr = NEXT_INTERFACE(lifr);
317  }
318  vstring_free(buf);
319  (void) close(sock);
320  return (0);
321 }
322 
323 #else /* HAVE_SIOCGLIF */
324 
325 /*
326  * The classic SIOCGIF* ioctls. Modern BSD operating systems will
327  * also return IPv6 addresses through these structure. Note however
328  * that recent versions of these operating systems have getifaddrs.
329  */
330 #if defined(_SIZEOF_ADDR_IFREQ)
331 #define NEXT_INTERFACE(ifr) ((struct ifreq *) \
332  ((char *) ifr + _SIZEOF_ADDR_IFREQ(*ifr)))
333 #define IFREQ_SIZE(ifr) _SIZEOF_ADDR_IFREQ(*ifr)
334 #elif defined(HAS_SA_LEN)
335 #define NEXT_INTERFACE(ifr) ((struct ifreq *) \
336  ((char *) ifr + sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len))
337 #define IFREQ_SIZE(ifr) (sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len)
338 #else
339 #define NEXT_INTERFACE(ifr) (ifr + 1)
340 #define IFREQ_SIZE(ifr) sizeof(ifr[0])
341 #endif
342 
343 /* ial_siocgif - determine IP addresses using ioctl(SIOCGIF*) */
344 
345 static int ial_siocgif(INET_ADDR_LIST *addr_list,
346  INET_ADDR_LIST *mask_list,
347  int af)
348 {
349  const char *myname = "inet_addr_local[siocgif]";
350  struct in_addr addr;
351  struct ifconf ifc;
352  struct ifreq *ifr;
353  struct ifreq *ifr_mask;
354  struct ifreq *the_end;
355  int sock;
356  VSTRING *buf;
357 
358  /*
359  * Get the network interface list. XXX The socket API appears to have no
360  * function that returns the number of network interfaces, so we have to
361  * guess how much space is needed to store the result.
362  *
363  * On BSD-derived systems, ioctl SIOCGIFCONF returns as much information as
364  * possible, leaving it up to the application to repeat the request with
365  * a larger buffer if the result caused a tight fit.
366  *
367  * Other systems, such as Solaris 2.5, generate an EINVAL error when the
368  * buffer is too small for the entire result. Workaround: ignore EINVAL
369  * errors and repeat the request with a larger buffer. The downside is
370  * that the program can run out of memory due to a non-memory problem,
371  * making it more difficult than necessary to diagnose the real problem.
372  */
373  sock = ial_socket(af);
374  if (sock < 0)
375  return (0);
376  buf = vstring_alloc(1024);
377  for (;;) {
378  ifc.ifc_len = vstring_avail(buf);
379  ifc.ifc_buf = vstring_str(buf);
380  if (ioctl(sock, SIOCGIFCONF, (char *) &ifc) < 0) {
381  if (errno != EINVAL)
382  msg_fatal("%s: ioctl SIOCGIFCONF: %m", myname);
383  } else if (ifc.ifc_len < vstring_avail(buf) / 2)
384  break;
385  VSTRING_SPACE(buf, vstring_avail(buf) * 2);
386  }
387 
388  the_end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
389  for (ifr = ifc.ifc_req; ifr < the_end;) {
390  if (ifr->ifr_addr.sa_family != af) {
391  ifr = NEXT_INTERFACE(ifr);
392  continue;
393  }
394  if (af == AF_INET) {
395  addr = ((struct sockaddr_in *) & ifr->ifr_addr)->sin_addr;
396  if (addr.s_addr != INADDR_ANY) {
397  inet_addr_list_append(addr_list, &ifr->ifr_addr);
398  if (mask_list) {
399  ifr_mask = (struct ifreq *) mymalloc(IFREQ_SIZE(ifr));
400  memcpy((void *) ifr_mask, (void *) ifr, IFREQ_SIZE(ifr));
401  if (ioctl(sock, SIOCGIFNETMASK, ifr_mask) < 0)
402  msg_fatal("%s: ioctl SIOCGIFNETMASK: %m", myname);
403 
404  /*
405  * Note that this SIOCGIFNETMASK has truly screwed up the
406  * contents of sa_len/sa_family. We must fix this
407  * manually to have correct addresses. --dcs
408  */
409  ifr_mask->ifr_addr.sa_family = af;
410 #ifdef HAS_SA_LEN
411  ifr_mask->ifr_addr.sa_len = sizeof(struct sockaddr_in);
412 #endif
413  inet_addr_list_append(mask_list, &ifr_mask->ifr_addr);
414  myfree((void *) ifr_mask);
415  }
416  }
417  }
418 #ifdef HAS_IPV6
419  else if (af == AF_INET6) {
420  struct sockaddr *sa;
421 
422  sa = SOCK_ADDR_PTR(&ifr->ifr_addr);
423  if (!(IN6_IS_ADDR_UNSPECIFIED(&SOCK_ADDR_IN6_ADDR(sa)))) {
424  inet_addr_list_append(addr_list, sa);
425  if (mask_list) {
426  /* XXX Assume /128 for everything */
427  struct sockaddr_in6 mask6;
428 
429  mask6 = *SOCK_ADDR_IN6_PTR(sa);
430  memset((void *) &mask6.sin6_addr, ~0,
431  sizeof(mask6.sin6_addr));
432  inet_addr_list_append(mask_list, SOCK_ADDR_PTR(&mask6));
433  }
434  }
435  }
436 #endif
437  ifr = NEXT_INTERFACE(ifr);
438  }
439  vstring_free(buf);
440  (void) close(sock);
441  return (0);
442 }
443 
444 #endif /* HAVE_SIOCGLIF */
445 
446 #ifdef HAS_PROCNET_IFINET6
447 
448 /*
449  * Older Linux versions lack proper calls to retrieve IPv6 interface
450  * addresses. Instead, the addresses can be read from a file in the
451  * /proc tree. The most important issue with this approach however
452  * is that the /proc tree may not always be available, for example
453  * in a chrooted environment or in "hardened" (sic) installations.
454  */
455 
456 /* ial_procnet_ifinet6 - determine IPv6 addresses using /proc/net/if_inet6 */
457 
458 static int ial_procnet_ifinet6(INET_ADDR_LIST *addr_list,
459  INET_ADDR_LIST *mask_list)
460 {
461  const char *myname = "inet_addr_local[procnet_ifinet6]";
462  FILE *fp;
463  char buf[BUFSIZ];
464  unsigned plen;
465  VSTRING *addrbuf;
466  struct sockaddr_in6 addr;
467  struct sockaddr_in6 mask;
468 
469  /*
470  * Example: 00000000000000000000000000000001 01 80 10 80 lo
471  *
472  * Fields: address, interface index, prefix length, scope value
473  * (net/ipv6.h), interface flags (linux/rtnetlink.h), device name.
474  *
475  * FIX 200501 The IPv6 patch used fscanf(), which will hang on unexpected
476  * input. Use fgets() + sscanf() instead.
477  */
478  if ((fp = fopen(_PATH_PROCNET_IFINET6, "r")) != 0) {
479  addrbuf = vstring_alloc(MAI_V6ADDR_BYTES + 1);
480  memset((void *) &addr, 0, sizeof(addr));
481  addr.sin6_family = AF_INET6;
482 #ifdef HAS_SA_LEN
483  addr.sin6_len = sizeof(addr);
484 #endif
485  mask = addr;
486  while (fgets(buf, sizeof(buf), fp) != 0) {
487  /* 200501 hex_decode() is light-weight compared to getaddrinfo(). */
488  if (hex_decode(addrbuf, buf, MAI_V6ADDR_BYTES * 2) == 0
489  || sscanf(buf + MAI_V6ADDR_BYTES * 2, " %*x %x", &plen) != 1
490  || plen > MAI_V6ADDR_BITS) {
491  msg_warn("unexpected data in %s - skipping IPv6 configuration",
492  _PATH_PROCNET_IFINET6);
493  break;
494  }
495  /* vstring_str(addrbuf) has worst-case alignment. */
496  addr.sin6_addr = *(struct in6_addr *) vstring_str(addrbuf);
497  inet_addr_list_append(addr_list, SOCK_ADDR_PTR(&addr));
498 
499  memset((void *) &mask.sin6_addr, ~0, sizeof(mask.sin6_addr));
500  mask_addr((unsigned char *) &mask.sin6_addr,
501  sizeof(mask.sin6_addr), plen);
502  inet_addr_list_append(mask_list, SOCK_ADDR_PTR(&mask));
503  }
504  vstring_free(addrbuf);
505  fclose(fp); /* FIX 200501 */
506  } else {
507  msg_warn("can't open %s (%m) - skipping IPv6 configuration",
508  _PATH_PROCNET_IFINET6);
509  }
510  return (0);
511 }
512 
513 #endif /* HAS_PROCNET_IFINET6 */
514 
515 /* inet_addr_local - find all IP addresses for this host */
516 
517 int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list,
518  unsigned *addr_family_list)
519 {
520  const char *myname = "inet_addr_local";
521  int initial_count = addr_list->used;
522  unsigned family;
523  int count;
524 
525  while ((family = *addr_family_list++) != 0) {
526 
527  /*
528  * IP Version 4
529  */
530  if (family == AF_INET) {
531  count = addr_list->used;
532 #if defined(HAVE_GETIFADDRS)
533  ial_getifaddrs(addr_list, mask_list, AF_INET);
534 #elif defined (HAS_SIOCGLIF)
535  ial_siocglif(addr_list, mask_list, AF_INET);
536 #else
537  ial_siocgif(addr_list, mask_list, AF_INET);
538 #endif
539  if (msg_verbose)
540  msg_info("%s: configured %d IPv4 addresses",
541  myname, addr_list->used - count);
542  }
543 
544  /*
545  * IP Version 6
546  */
547 #ifdef HAS_IPV6
548  else if (family == AF_INET6) {
549  count = addr_list->used;
550 #if defined(HAVE_GETIFADDRS)
551  ial_getifaddrs(addr_list, mask_list, AF_INET6);
552 #elif defined(HAS_PROCNET_IFINET6)
553  ial_procnet_ifinet6(addr_list, mask_list);
554 #elif defined(HAS_SIOCGLIF)
555  ial_siocglif(addr_list, mask_list, AF_INET6);
556 #else
557  ial_siocgif(addr_list, mask_list, AF_INET6);
558 #endif
559  if (msg_verbose)
560  msg_info("%s: configured %d IPv6 addresses", myname,
561  addr_list->used - count);
562  }
563 #endif
564 
565  /*
566  * Something's not right.
567  */
568  else
569  msg_panic("%s: unknown address family %d", myname, family);
570  }
571  return (addr_list->used - initial_count);
572 }
573 
574 #ifdef TEST
575 
576 #include <string.h>
577 #include <vstream.h>
578 #include <msg_vstream.h>
579 #include <inet_proto.h>
580 
581 int main(int unused_argc, char **argv)
582 {
583  INET_ADDR_LIST addr_list;
584  INET_ADDR_LIST mask_list;
585  MAI_HOSTADDR_STR hostaddr;
586  MAI_HOSTADDR_STR hostmask;
587  struct sockaddr *sa;
588  int i;
589  INET_PROTO_INFO *proto_info;
590 
591  msg_vstream_init(argv[0], VSTREAM_ERR);
592  msg_verbose = 1;
593 
594  proto_info = inet_proto_init(argv[0],
595  argv[1] ? argv[1] : INET_PROTO_NAME_ALL);
596  inet_addr_list_init(&addr_list);
597  inet_addr_list_init(&mask_list);
598  inet_addr_local(&addr_list, &mask_list, proto_info->ai_family_list);
599 
600  if (addr_list.used == 0)
601  msg_fatal("cannot find any active network interfaces");
602 
603  if (addr_list.used == 1)
604  msg_warn("found only one active network interface");
605 
606  for (i = 0; i < addr_list.used; i++) {
607  sa = SOCK_ADDR_PTR(addr_list.addrs + i);
609  &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
610  sa = SOCK_ADDR_PTR(mask_list.addrs + i);
612  &hostmask, (MAI_SERVPORT_STR *) 0, 0);
613  vstream_printf("%s/%s\n", hostaddr.buf, hostmask.buf);
615  }
616  inet_addr_list_free(&addr_list);
617  inet_addr_list_free(&mask_list);
618  return (0);
619 }
620 
621 #endif
int msg_verbose
Definition: msg.c:177
void myfree(void *ptr)
Definition: mymalloc.c:207
void mask_addr(unsigned char *addr_bytes, unsigned addr_byte_count, unsigned network_bits)
Definition: mask_addr.c:50
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define vstring_str(vp)
Definition: vstring.h:71
#define VSTREAM_OUT
Definition: vstream.h:67
void inet_addr_list_free(INET_ADDR_LIST *list)
int main(int argc, char **argv)
Definition: anvil.c:1010
INET_PROTO_INFO * inet_proto_init(const char *context, const char *protocols)
Definition: inet_proto.c:180
struct sockaddr_storage * addrs
#define SOCKADDR_TO_HOSTADDR(sa, salen, host, port, sock)
Definition: myaddrinfo.h:197
#define INET_PROTO_NAME_ALL
Definition: mail_params.h:992
int inet_addr_local(INET_ADDR_LIST *addr_list, INET_ADDR_LIST *mask_list, unsigned *addr_family_list)
unsigned int * ai_family_list
Definition: inet_proto.h:19
#define MAI_V6ADDR_BITS
Definition: myaddrinfo.h:125
char buf[MAI_HOSTADDR_STRSIZE]
Definition: myaddrinfo.h:146
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
#define SOCK_ADDR_PTR(ptr)
Definition: sock_addr.h:24
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define vstring_avail(vp)
Definition: vstring.h:86
void inet_addr_list_init(INET_ADDR_LIST *list)
#define MAI_V6ADDR_BYTES
Definition: myaddrinfo.h:127
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
void inet_addr_list_append(INET_ADDR_LIST *list, struct sockaddr *addr)
#define IFREQ_SIZE(ifr)
int int
Definition: smtpd_proxy.h:21
#define VSTRING_SPACE(vp, len)
Definition: vstring.h:70
#define NEXT_INTERFACE(ifr)
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
#define SOCK_ADDR_LEN(sa)
Definition: sock_addr.h:78
void msg_vstream_init(const char *name, VSTREAM *vp)
Definition: msg_vstream.c:77
#define SOCK_ADDR_IN_ADDR(sa)
Definition: sock_addr.h:33
VSTRING * hex_decode(VSTRING *result, const char *in, ssize_t len)
Definition: hex_code.c:80
#define VSTREAM_ERR
Definition: vstream.h:68
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
void msg_info(const char *fmt,...)
Definition: msg.c:199