chiark / gitweb /
implement scope flags
[adns.git] / src / adns.h
index 63a46e8b71a3e4841e9918897e3a05500e0dcff7..9ef45997651177b4f4a7ec132757e965a08a820d 100644 (file)
@@ -66,6 +66,7 @@
 #include <netinet/in.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include <net/if.h>
 
 #ifdef __cplusplus
 extern "C" { /* I really dislike this - iwj. */
@@ -135,6 +136,8 @@ typedef enum { /* In general, or together the desired flags: */
  adns_qf_domapv4=       0x00001000,/*  ... any IPv4 addresses should be v6-mapped */
  adns_qf_ipv6_mapv4=    adns_qf_ipv6_ok|adns_qf_domapv4,
  adns__qf_afmask=       0x00001c00,/* all the above flag bits */
+ adns_qf_addrlit_scope_forbid=0x00002000,/* forbid %<scope> in IPv6 literals */
+ adns_qf_addrlit_scope_numeric=0x00004000,/* %<scope> may only be numeric */
  adns__qf_internalmask=  0x0ff00000
 } adns_queryflags;
 
@@ -682,23 +685,59 @@ void adns_finish(adns_state ads);
  * they will be cancelled.
  */
 
-#define ADNS_ADDR2TEXT_BUFLEN (INET6_ADDRSTRLEN +1/*%*/ +9/*uint32*/ +1/*nul*/)
-
-int adns_addr2text(adns_state ads /* may be 0!  used for debug log only */,
-                  const struct sockaddr *sa, socklen_t salen,
-                  char *addr_buffer, int *addr_buflen /* set iff ENOSPC */,
-                  int *port_r);
-int adns_text2addr(adns_state ads /* may be 0!  used for debug log only */,
-                  const char *addr, int port, struct sockaddr *sa,
-                  socklen_t *salen /* set if OK or ENOSPC */);
-  /* These DO NOT return an adns_status.  Instead, 0 on success,
-   * or an errno value on failure.  Error values are:
-   *   EAFNOSUPPORT addr2text only
-   *   EINVAL       addr has invalid syntax
-   *   ENOSPC       only if *buflen < _BUFLEN or *salen < sizeof(adns_sockaddr)
-   *   ENXIO        addr specifies a scope name and if_nametoindex failed
+#define ADNS_ADDR2TEXT_BUFLEN                                  \
+  (INET6_ADDRSTRLEN + 1/*%*/                                   \
+  + ((IF_NAMESIZE-1) > 9 ? (IF_NAMESIZE-1) : 9/*uint32*/)      \
+  + 1/* nul; included in IF_NAMESIZE */)
+
+int adns_text2addr(const char *text, uint16_t port, adns_queryflags flags,
+                  struct sockaddr *sa,
+                  socklen_t *salen /* set if OK or ENOSPC; otherwise undef */);
+int adns_addr2text(const struct sockaddr *sa, adns_queryflags flags,
+                  char *buffer, int *buflen /* set iff ENOSPC */,
+                  int *port_r /* may be 0 */);
+  /*
    * port is always in host byte order and is simply copied to and
    * from the appropriate sockaddr field (byteswapped as necessary).
+   *
+   * The only flags supported are adns_qf_addrlit_...; others are
+   * ignored.
+   *
+   * Error return values are:
+   *
+   *  ENOSPC    Output buffer is too small.  Can only happen if
+   *            *buflen < ADNS_ADDR2TEXT_BUFLEN or
+   *            *salen < sizeof(adns_sockaddr).  On return,
+   *            *buflen or *salen has been updated by adns.
+   *
+   *  EINVAL    text has invalid syntax.
+   *
+   *            text represents an address family not supported by
+   *            this version of adns.
+   *
+   *            Scoped address supplied (text contained "%" or
+   *            sin6_scope_id nonzero) but caller specified
+   *            adns_qf_addrlit_scope_forbid.
+   *
+   *            Scope name (rather than number) supplied in text but
+   *            caller specified adns_qf_addrlit_scope_numeric.
+   *
+   *  EAFNOSUPPORT   sa->sa_family is not supported (addr2text only).
+   *
+   * Only if neither adns_qf_addrlit_scope_forbid nor
+   * adns_qf_addrlit_scope_numeric are set:
+   *
+   *  ENOSYS    Scope name supplied in text but IPv6 address part of
+   *            sockaddr is not a link local address.
+   *
+   *  ENXIO     Scope name supplied in text but if_nametoindex
+   *            said it wasn't a valid local interface name.
+   *
+   *  EIO       Scoped address supplied but if_nametoindex failed
+   *            in an unexpected way; adns has printed a message to
+   *            stderr.
+   *
+   *  any other   if_nametoindex failed in a more-or-less expected way.
    */
 
 void adns_forallqueries_begin(adns_state ads);