1 /* $NetBSD: lwdgnba.c,v 1.5 2014/12/10 04:37:51 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007, 2008, 2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: lwdgnba.c,v 1.22 2008/01/14 23:46:56 tbox Exp */
26 #include <isc/socket.h>
27 #include <isc/string.h> /* Required for HP/UX (and others?) */
31 #include <dns/byaddr.h>
32 #include <dns/result.h>
34 #include <named/types.h>
35 #include <named/lwdclient.h>
37 static void start_byaddr(ns_lwdclient_t
*);
40 byaddr_done(isc_task_t
*task
, isc_event_t
*event
) {
41 ns_lwdclient_t
*client
;
42 ns_lwdclientmgr_t
*cm
;
43 dns_byaddrevent_t
*bevent
;
48 lwres_result_t lwresult
;
51 lwres_gnbaresponse_t
*gnba
;
52 isc_uint16_t naliases
;
57 client
= event
->ev_arg
;
58 cm
= client
->clientmgr
;
59 INSIST(client
->byaddr
== (dns_byaddr_t
*)event
->ev_sender
);
61 bevent
= (dns_byaddrevent_t
*)event
;
64 ns_lwdclient_log(50, "byaddr event result = %s",
65 isc_result_totext(bevent
->result
));
67 result
= bevent
->result
;
68 if (result
!= ISC_R_SUCCESS
) {
69 dns_byaddr_destroy(&client
->byaddr
);
70 isc_event_free(&event
);
73 if (client
->na
.family
!= AF_INET6
||
74 (client
->options
& DNS_BYADDROPT_IPV6INT
) != 0) {
75 if (result
== DNS_R_NCACHENXDOMAIN
||
76 result
== DNS_R_NCACHENXRRSET
||
77 result
== DNS_R_NXDOMAIN
||
78 result
== DNS_R_NXRRSET
)
79 lwresult
= LWRES_R_NOTFOUND
;
81 lwresult
= LWRES_R_FAILURE
;
82 ns_lwdclient_errorpktsend(client
, lwresult
);
87 * Fall back to ip6.int reverse if the default ip6.arpa
90 client
->options
|= DNS_BYADDROPT_IPV6INT
;
96 for (name
= ISC_LIST_HEAD(bevent
->names
);
98 name
= ISC_LIST_NEXT(name
, link
))
100 b
= client
->recv_buffer
;
102 result
= dns_name_totext(name
, ISC_TRUE
, &client
->recv_buffer
);
103 if (result
!= ISC_R_SUCCESS
)
105 ns_lwdclient_log(50, "found name '%.*s'",
106 (int)(client
->recv_buffer
.used
- b
.used
),
107 (char *)(b
.base
) + b
.used
);
108 if (gnba
->realname
== NULL
) {
109 gnba
->realname
= (char *)(b
.base
) + b
.used
;
110 gnba
->realnamelen
= client
->recv_buffer
.used
- b
.used
;
112 naliases
= gnba
->naliases
;
113 if (naliases
>= LWRES_MAX_ALIASES
)
115 gnba
->aliases
[naliases
] = (char *)(b
.base
) + b
.used
;
116 gnba
->aliaslen
[naliases
] =
117 client
->recv_buffer
.used
- b
.used
;
122 dns_byaddr_destroy(&client
->byaddr
);
123 isc_event_free(&event
);
128 client
->pkt
.recvlength
= LWRES_RECVLENGTH
;
129 client
->pkt
.authtype
= 0; /* XXXMLG */
130 client
->pkt
.authlength
= 0;
131 client
->pkt
.result
= LWRES_R_SUCCESS
;
133 lwres
= lwres_gnbaresponse_render(cm
->lwctx
,
134 gnba
, &client
->pkt
, &lwb
);
135 if (lwres
!= LWRES_R_SUCCESS
)
140 client
->sendbuf
= r
.base
;
141 client
->sendlength
= r
.length
;
142 result
= ns_lwdclient_sendreply(client
, &r
);
143 if (result
!= ISC_R_SUCCESS
)
146 NS_LWDCLIENT_SETSEND(client
);
151 if (client
->byaddr
!= NULL
)
152 dns_byaddr_destroy(&client
->byaddr
);
153 if (lwb
.base
!= NULL
)
154 lwres_context_freemem(cm
->lwctx
,
155 lwb
.base
, lwb
.length
);
158 isc_event_free(&event
);
162 start_byaddr(ns_lwdclient_t
*client
) {
164 ns_lwdclientmgr_t
*cm
;
166 cm
= client
->clientmgr
;
168 INSIST(client
->byaddr
== NULL
);
170 result
= dns_byaddr_create(cm
->mctx
, &client
->na
, cm
->view
,
171 client
->options
, cm
->task
, byaddr_done
,
172 client
, &client
->byaddr
);
173 if (result
!= ISC_R_SUCCESS
) {
174 ns_lwdclient_errorpktsend(client
, LWRES_R_FAILURE
);
180 init_gnba(ns_lwdclient_t
*client
) {
184 * Initialize the real name and alias arrays in the reply we're
187 for (i
= 0; i
< LWRES_MAX_ALIASES
; i
++) {
188 client
->aliases
[i
] = NULL
;
189 client
->aliaslen
[i
] = 0;
191 for (i
= 0; i
< LWRES_MAX_ADDRS
; i
++) {
192 client
->addrs
[i
].family
= 0;
193 client
->addrs
[i
].length
= 0;
194 memset(client
->addrs
[i
].address
, 0, LWRES_ADDR_MAXLEN
);
195 LWRES_LINK_INIT(&client
->addrs
[i
], link
);
198 client
->gnba
.naliases
= 0;
199 client
->gnba
.realname
= NULL
;
200 client
->gnba
.aliases
= client
->aliases
;
201 client
->gnba
.realnamelen
= 0;
202 client
->gnba
.aliaslen
= client
->aliaslen
;
203 client
->gnba
.base
= NULL
;
204 client
->gnba
.baselen
= 0;
205 isc_buffer_init(&client
->recv_buffer
, client
->buffer
, LWRES_RECVLENGTH
);
209 ns_lwdclient_processgnba(ns_lwdclient_t
*client
, lwres_buffer_t
*b
) {
210 lwres_gnbarequest_t
*req
;
213 ns_lwdclientmgr_t
*cm
;
215 REQUIRE(NS_LWDCLIENT_ISRECVDONE(client
));
216 INSIST(client
->byaddr
== NULL
);
218 cm
= client
->clientmgr
;
221 result
= lwres_gnbarequest_parse(cm
->lwctx
,
222 b
, &client
->pkt
, &req
);
223 if (result
!= LWRES_R_SUCCESS
)
227 if (req
->addr
.family
== LWRES_ADDRTYPE_V4
) {
228 client
->na
.family
= AF_INET
;
229 if (req
->addr
.length
!= 4)
231 memmove(&client
->na
.type
.in
, req
->addr
.address
, 4);
232 } else if (req
->addr
.family
== LWRES_ADDRTYPE_V6
) {
233 client
->na
.family
= AF_INET6
;
234 if (req
->addr
.length
!= 16)
236 memmove(&client
->na
.type
.in6
, req
->addr
.address
, 16);
240 isc_sockaddr_fromnetaddr(&sa
, &client
->na
, 53);
242 ns_lwdclient_log(50, "client %p looking for addrtype %08x",
243 client
, req
->addr
.family
);
246 * We no longer need to keep this around.
248 lwres_gnbarequest_free(cm
->lwctx
, &req
);
251 * Initialize the real name and alias arrays in the reply we're
260 start_byaddr(client
);
265 * We're screwed. Return an error packet to our caller.
269 lwres_gnbarequest_free(cm
->lwctx
, &req
);
271 ns_lwdclient_errorpktsend(client
, LWRES_R_FAILURE
);