ircu2.10.12 pk910 fork
[ircu2.10.12-pk.git] / include / res.h
1 /** @file
2  * @brief IRC resolver API.
3  * @version $Id: res.h 1823 2007-08-09 03:41:18Z entrope $
4  */
5
6 #ifndef INCLUDED_res_h
7 #define INCLUDED_res_h
8
9 #ifndef INCLUDED_config_h
10 #include "config.h"
11 #endif
12
13 #ifndef INCLUDED_sys_types_h
14 #include <sys/types.h>
15 #define INCLUDED_sys_types_h
16 #endif
17
18 #ifndef INCLUDED_sys_socket_h
19 #include <sys/socket.h>
20 #define INCLUDED_sys_socket_h
21 #endif
22
23 #include <netdb.h>
24
25 #ifndef INCLUDED_netinet_in_h
26 #include <netinet/in.h>
27 #define INCLUDED_netinet_in_h
28 #endif
29
30 #ifdef HAVE_STDINT_H
31 #ifndef INCLUDED_stdint_h
32 #include <stdint.h>
33 #define INCLUDED_stdint_h
34 #endif
35 #endif
36
37 struct Client;
38 struct StatDesc;
39
40 /* Here we define some values lifted from nameser.h */
41 #define NS_INT16SZ 2 /**< Size of a 16-bit value. */
42 #define NS_INT32SZ 4 /**< Size of a 32-bit value. */
43 #define NS_CMPRSFLGS 0xc0 /**< Prefix flags that indicate special types */
44 #define NS_MAXCDNAME 255 /**< Maximum length of a compressed domain name. */
45 #define QUERY 0      /**< Forward (normal) DNS query operation. */
46 #define NO_ERRORS 0  /**< No errors processing a query. */
47 #define SERVFAIL 2   /**< Server error while processing a query. */
48 #define NXDOMAIN 3   /**< Domain name in query does not exist. */
49 #define T_A 1        /**< Hostname -> IPv4 query type. */
50 #define T_AAAA 28    /**< Hostname -> IPv6 query type. */
51 #define T_PTR 12     /**< IP(v4 or v6) -> hostname query type. */
52 #define T_CNAME 5    /**< Canonical name resolution query type. */
53 #define C_IN 1       /**< Internet query class. */
54 #define QFIXEDSZ 4   /**< Length of fixed-size part of query. */
55 #define HFIXEDSZ 12  /**< Length of fixed-size DNS header. */
56
57 /** Structure to store an IP address. */
58 struct irc_in_addr
59 {
60   unsigned short in6_16[8]; /**< IPv6 encoded parts, little-endian. */
61 };
62
63 /** Structure to store an IP address and port number. */
64 struct irc_sockaddr
65 {
66   struct irc_in_addr addr; /**< IP address. */
67   unsigned short port;     /**< Port number, host-endian. */
68 };
69
70 /** DNS callback function signature. */
71 typedef void (*dns_callback_f)(void *vptr, const struct irc_in_addr *addr, const char *h_name);
72
73 /** DNS query and response header. */
74 typedef struct
75 {
76         unsigned        id :16;         /**< query identification number */
77 #ifdef WORDS_BIGENDIAN
78                         /* fields in third byte */
79         unsigned        qr: 1;          /**< response flag */
80         unsigned        opcode: 4;      /**< purpose of message */
81         unsigned        aa: 1;          /**< authoritive answer */
82         unsigned        tc: 1;          /**< truncated message */
83         unsigned        rd: 1;          /**< recursion desired */
84                         /* fields in fourth byte */
85         unsigned        ra: 1;          /**< recursion available */
86         unsigned        unused :1;      /**< unused bits (MBZ as of 4.9.3a3) */
87         unsigned        ad: 1;          /**< authentic data from named */
88         unsigned        cd: 1;          /**< checking disabled by resolver */
89         unsigned        rcode :4;       /**< response code */
90 #else
91                         /* fields in third byte */
92         unsigned        rd :1;          /**< recursion desired */
93         unsigned        tc :1;          /**< truncated message */
94         unsigned        aa :1;          /**< authoritive answer */
95         unsigned        opcode :4;      /**< purpose of message */
96         unsigned        qr :1;          /**< response flag */
97                         /* fields in fourth byte */
98         unsigned        rcode :4;       /**< response code */
99         unsigned        cd: 1;          /**< checking disabled by resolver */
100         unsigned        ad: 1;          /**< authentic data from named */
101         unsigned        unused :1;      /**< unused bits (MBZ as of 4.9.3a3) */
102         unsigned        ra :1;          /**< recursion available */
103 #endif
104                         /* remaining bytes */
105         unsigned        qdcount :16;    /**< number of question entries */
106         unsigned        ancount :16;    /**< number of answer entries */
107         unsigned        nscount :16;    /**< number of authority entries */
108         unsigned        arcount :16;    /**< number of resource entries */
109 } HEADER;
110
111 extern void restart_resolver(void);
112 extern void clear_nameservers(void);
113 extern void add_nameserver(const char *ipaddr);
114 extern void add_local_domain(char *hname, size_t size);
115 extern size_t cres_mem(struct Client* cptr);
116 extern void delete_resolver_queries(const void *vptr);
117 extern void report_dns_servers(struct Client *source_p, const struct StatDesc *sd, char *param);
118 extern void gethost_byname(const char *name, dns_callback_f callback, void *ctx);
119 extern void gethost_byaddr(const struct irc_in_addr *addr, dns_callback_f callback, void *ctx);
120
121 /** Evaluate to non-zero if \a ADDR is an unspecified (all zeros) address. */
122 #define irc_in_addr_unspec(ADDR) (((ADDR)->in6_16[0] == 0) \
123                                   && ((ADDR)->in6_16[1] == 0) \
124                                   && ((ADDR)->in6_16[2] == 0) \
125                                   && ((ADDR)->in6_16[3] == 0) \
126                                   && ((ADDR)->in6_16[4] == 0) \
127                                   && ((ADDR)->in6_16[6] == 0) \
128                                   && ((ADDR)->in6_16[7] == 0) \
129                                   && ((ADDR)->in6_16[5] == 0 \
130                                       || (ADDR)->in6_16[5] == 65535))
131 /** Evaluate to non-zero if \a ADDR is a valid address (not all 0s and not all 1s). */
132 #define irc_in_addr_valid(ADDR) (((ADDR)->in6_16[0] && ~(ADDR)->in6_16[0]) \
133                                  || (ADDR)->in6_16[1] != (ADDR)->in6_16[0] \
134                                  || (ADDR)->in6_16[2] != (ADDR)->in6_16[0] \
135                                  || (ADDR)->in6_16[3] != (ADDR)->in6_16[0] \
136                                  || (ADDR)->in6_16[4] != (ADDR)->in6_16[0] \
137                                  || (ADDR)->in6_16[5] != (ADDR)->in6_16[0] \
138                                  || (ADDR)->in6_16[6] != (ADDR)->in6_16[0] \
139                                  || (ADDR)->in6_16[7] != (ADDR)->in6_16[0])
140 /** Evaluate to non-zero if \a ADDR (of type struct irc_in_addr) is an IPv4 address. */
141 #define irc_in_addr_is_ipv4(ADDR) (!(ADDR)->in6_16[0] && !(ADDR)->in6_16[1] && !(ADDR)->in6_16[2] \
142                                    && !(ADDR)->in6_16[3] && !(ADDR)->in6_16[4] \
143                                    && ((!(ADDR)->in6_16[5] && (ADDR)->in6_16[6]) \
144                                        || (ADDR)->in6_16[5] == 65535))
145 /** Evaluate to non-zero if \a A is a different IP than \a B. */
146 #define irc_in_addr_cmp(A,B) (irc_in_addr_is_ipv4(A) ? ((A)->in6_16[6] != (B)->in6_16[6] \
147                                   || (A)->in6_16[7] != (B)->in6_16[7] || !irc_in_addr_is_ipv4(B)) \
148                               : memcmp((A), (B), sizeof(struct irc_in_addr)))
149 /** Evaluate to non-zero if \a ADDR is a loopback address. */
150 #define irc_in_addr_is_loopback(ADDR) (!(ADDR)->in6_16[0] && !(ADDR)->in6_16[1] && !(ADDR)->in6_16[2] \
151                                        && !(ADDR)->in6_16[3] && !(ADDR)->in6_16[4] \
152                                        && ((!(ADDR)->in6_16[5] \
153                                             && ((!(ADDR)->in6_16[6] && (ADDR)->in6_16[7] == htons(1)) \
154                                                 || (ntohs((ADDR)->in6_16[6]) & 0xff00) == 0x7f00)) \
155                                            || (((ADDR)->in6_16[5] == 65535) \
156                                                && (ntohs((ADDR)->in6_16[6]) & 0xff00) == 0x7f00)))
157
158 #endif