1*48a54d36SAndroid Build Coastguard Worker /*
2*48a54d36SAndroid Build Coastguard Worker NICTA Public Software Licence
3*48a54d36SAndroid Build Coastguard Worker Version 1.0
4*48a54d36SAndroid Build Coastguard Worker
5*48a54d36SAndroid Build Coastguard Worker Copyright © 2004 National ICT Australia Ltd
6*48a54d36SAndroid Build Coastguard Worker
7*48a54d36SAndroid Build Coastguard Worker All rights reserved.
8*48a54d36SAndroid Build Coastguard Worker
9*48a54d36SAndroid Build Coastguard Worker By this licence, National ICT Australia Ltd (NICTA) grants permission,
10*48a54d36SAndroid Build Coastguard Worker free of charge, to any person who obtains a copy of this software
11*48a54d36SAndroid Build Coastguard Worker and any associated documentation files ("the Software") to use and
12*48a54d36SAndroid Build Coastguard Worker deal with the Software in source code and binary forms without
13*48a54d36SAndroid Build Coastguard Worker restriction, with or without modification, and to permit persons
14*48a54d36SAndroid Build Coastguard Worker to whom the Software is furnished to do so, provided that the
15*48a54d36SAndroid Build Coastguard Worker following conditions are met:
16*48a54d36SAndroid Build Coastguard Worker
17*48a54d36SAndroid Build Coastguard Worker - Redistributions of source code must retain the above copyright
18*48a54d36SAndroid Build Coastguard Worker notice, this list of conditions and the following disclaimers.
19*48a54d36SAndroid Build Coastguard Worker - Redistributions in binary form must reproduce the above copyright
20*48a54d36SAndroid Build Coastguard Worker notice, this list of conditions and the following disclaimers in
21*48a54d36SAndroid Build Coastguard Worker the documentation and/or other materials provided with the
22*48a54d36SAndroid Build Coastguard Worker distribution.
23*48a54d36SAndroid Build Coastguard Worker - The name of NICTA may not be used to endorse or promote products
24*48a54d36SAndroid Build Coastguard Worker derived from this Software without specific prior written permission.
25*48a54d36SAndroid Build Coastguard Worker
26*48a54d36SAndroid Build Coastguard Worker EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
27*48a54d36SAndroid Build Coastguard Worker PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS" AND
28*48a54d36SAndroid Build Coastguard Worker NICTA MAKES NO REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY
29*48a54d36SAndroid Build Coastguard Worker KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY
30*48a54d36SAndroid Build Coastguard Worker REPRESENTATIONS, WARRANTIES OR CONDITIONS REGARDING THE CONTENTS
31*48a54d36SAndroid Build Coastguard Worker OR ACCURACY OF THE SOFTWARE, OR OF TITLE, MERCHANTABILITY, FITNESS
32*48a54d36SAndroid Build Coastguard Worker FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, THE ABSENCE OF LATENT
33*48a54d36SAndroid Build Coastguard Worker OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR
34*48a54d36SAndroid Build Coastguard Worker NOT DISCOVERABLE.
35*48a54d36SAndroid Build Coastguard Worker
36*48a54d36SAndroid Build Coastguard Worker TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
37*48a54d36SAndroid Build Coastguard Worker NICTA BE LIABLE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
38*48a54d36SAndroid Build Coastguard Worker NEGLIGENCE) FOR ANY LOSS OR DAMAGE WHATSOEVER, INCLUDING (WITHOUT
39*48a54d36SAndroid Build Coastguard Worker LIMITATION) LOSS OF PRODUCTION OR OPERATION TIME, LOSS, DAMAGE OR
40*48a54d36SAndroid Build Coastguard Worker CORRUPTION OF DATA OR RECORDS; OR LOSS OF ANTICIPATED SAVINGS,
41*48a54d36SAndroid Build Coastguard Worker OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR OTHER ECONOMIC LOSS;
42*48a54d36SAndroid Build Coastguard Worker OR ANY SPECIAL, INCIDENTAL, INDIRECT, CONSEQUENTIAL, PUNITIVE OR
43*48a54d36SAndroid Build Coastguard Worker EXEMPLARY DAMAGES ARISING OUT OF OR IN CONNECTION WITH THIS LICENCE,
44*48a54d36SAndroid Build Coastguard Worker THE SOFTWARE OR THE USE OF THE SOFTWARE, EVEN IF NICTA HAS BEEN
45*48a54d36SAndroid Build Coastguard Worker ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
46*48a54d36SAndroid Build Coastguard Worker
47*48a54d36SAndroid Build Coastguard Worker If applicable legislation implies warranties or conditions, or
48*48a54d36SAndroid Build Coastguard Worker imposes obligations or liability on NICTA in respect of the Software
49*48a54d36SAndroid Build Coastguard Worker that cannot be wholly or partly excluded, restricted or modified,
50*48a54d36SAndroid Build Coastguard Worker NICTA's liability is limited, to the full extent permitted by the
51*48a54d36SAndroid Build Coastguard Worker applicable legislation, at its option, to:
52*48a54d36SAndroid Build Coastguard Worker
53*48a54d36SAndroid Build Coastguard Worker a. in the case of goods, any one or more of the following:
54*48a54d36SAndroid Build Coastguard Worker i. the replacement of the goods or the supply of equivalent goods;
55*48a54d36SAndroid Build Coastguard Worker ii. the repair of the goods;
56*48a54d36SAndroid Build Coastguard Worker iii. the payment of the cost of replacing the goods or of acquiring
57*48a54d36SAndroid Build Coastguard Worker equivalent goods;
58*48a54d36SAndroid Build Coastguard Worker iv. the payment of the cost of having the goods repaired; or
59*48a54d36SAndroid Build Coastguard Worker b. in the case of services:
60*48a54d36SAndroid Build Coastguard Worker i. the supplying of the services again; or
61*48a54d36SAndroid Build Coastguard Worker ii. the payment of the cost of having the services supplied
62*48a54d36SAndroid Build Coastguard Worker again.
63*48a54d36SAndroid Build Coastguard Worker */
64*48a54d36SAndroid Build Coastguard Worker
65*48a54d36SAndroid Build Coastguard Worker /*
66*48a54d36SAndroid Build Coastguard Worker NSSwitch Implementation of mDNS interface.
67*48a54d36SAndroid Build Coastguard Worker
68*48a54d36SAndroid Build Coastguard Worker Andrew White ([email protected])
69*48a54d36SAndroid Build Coastguard Worker May 2004
70*48a54d36SAndroid Build Coastguard Worker */
71*48a54d36SAndroid Build Coastguard Worker
72*48a54d36SAndroid Build Coastguard Worker #include <stdlib.h>
73*48a54d36SAndroid Build Coastguard Worker #include <stdio.h>
74*48a54d36SAndroid Build Coastguard Worker #include <string.h>
75*48a54d36SAndroid Build Coastguard Worker #include <errno.h>
76*48a54d36SAndroid Build Coastguard Worker #include <syslog.h>
77*48a54d36SAndroid Build Coastguard Worker #include <pthread.h>
78*48a54d36SAndroid Build Coastguard Worker #include <ctype.h>
79*48a54d36SAndroid Build Coastguard Worker
80*48a54d36SAndroid Build Coastguard Worker #include <sys/types.h>
81*48a54d36SAndroid Build Coastguard Worker #include <sys/time.h>
82*48a54d36SAndroid Build Coastguard Worker #include <sys/socket.h>
83*48a54d36SAndroid Build Coastguard Worker
84*48a54d36SAndroid Build Coastguard Worker #include <netinet/in.h>
85*48a54d36SAndroid Build Coastguard Worker
86*48a54d36SAndroid Build Coastguard Worker #include <arpa/inet.h>
87*48a54d36SAndroid Build Coastguard Worker #define BIND_8_COMPAT 1
88*48a54d36SAndroid Build Coastguard Worker #include <arpa/nameser.h>
89*48a54d36SAndroid Build Coastguard Worker
90*48a54d36SAndroid Build Coastguard Worker #include <dns_sd.h>
91*48a54d36SAndroid Build Coastguard Worker
92*48a54d36SAndroid Build Coastguard Worker
93*48a54d36SAndroid Build Coastguard Worker //----------
94*48a54d36SAndroid Build Coastguard Worker // Public functions
95*48a54d36SAndroid Build Coastguard Worker
96*48a54d36SAndroid Build Coastguard Worker /*
97*48a54d36SAndroid Build Coastguard Worker Count the number of dots in a name string.
98*48a54d36SAndroid Build Coastguard Worker */
99*48a54d36SAndroid Build Coastguard Worker int
100*48a54d36SAndroid Build Coastguard Worker count_dots (const char * name);
101*48a54d36SAndroid Build Coastguard Worker
102*48a54d36SAndroid Build Coastguard Worker
103*48a54d36SAndroid Build Coastguard Worker /*
104*48a54d36SAndroid Build Coastguard Worker Test whether a domain name is local.
105*48a54d36SAndroid Build Coastguard Worker
106*48a54d36SAndroid Build Coastguard Worker Returns
107*48a54d36SAndroid Build Coastguard Worker 1 if name ends with ".local" or ".local."
108*48a54d36SAndroid Build Coastguard Worker 0 otherwise
109*48a54d36SAndroid Build Coastguard Worker */
110*48a54d36SAndroid Build Coastguard Worker int
111*48a54d36SAndroid Build Coastguard Worker islocal (const char * name);
112*48a54d36SAndroid Build Coastguard Worker
113*48a54d36SAndroid Build Coastguard Worker
114*48a54d36SAndroid Build Coastguard Worker /*
115*48a54d36SAndroid Build Coastguard Worker Format an address structure as a string appropriate for DNS reverse (PTR)
116*48a54d36SAndroid Build Coastguard Worker lookup, based on address type.
117*48a54d36SAndroid Build Coastguard Worker
118*48a54d36SAndroid Build Coastguard Worker Parameters
119*48a54d36SAndroid Build Coastguard Worker prefixlen
120*48a54d36SAndroid Build Coastguard Worker Prefix length, in bits. When formatting, this will be rounded up
121*48a54d36SAndroid Build Coastguard Worker to the nearest appropriate size. If -1, assume maximum.
122*48a54d36SAndroid Build Coastguard Worker buf
123*48a54d36SAndroid Build Coastguard Worker Output buffer. Must be long enough to hold largest possible
124*48a54d36SAndroid Build Coastguard Worker output.
125*48a54d36SAndroid Build Coastguard Worker Returns
126*48a54d36SAndroid Build Coastguard Worker Pointer to (first character of) output buffer,
127*48a54d36SAndroid Build Coastguard Worker or NULL on error.
128*48a54d36SAndroid Build Coastguard Worker */
129*48a54d36SAndroid Build Coastguard Worker char *
130*48a54d36SAndroid Build Coastguard Worker format_reverse_addr (int af, const void * addr, int prefixlen, char * buf);
131*48a54d36SAndroid Build Coastguard Worker
132*48a54d36SAndroid Build Coastguard Worker
133*48a54d36SAndroid Build Coastguard Worker /*
134*48a54d36SAndroid Build Coastguard Worker Format an address structure as a string appropriate for DNS reverse (PTR)
135*48a54d36SAndroid Build Coastguard Worker lookup for AF_INET. Output is in .in-addr.arpa domain.
136*48a54d36SAndroid Build Coastguard Worker
137*48a54d36SAndroid Build Coastguard Worker Parameters
138*48a54d36SAndroid Build Coastguard Worker prefixlen
139*48a54d36SAndroid Build Coastguard Worker Prefix length, in bits. When formatting, this will be rounded up
140*48a54d36SAndroid Build Coastguard Worker to the nearest byte (8). If -1, assume 32.
141*48a54d36SAndroid Build Coastguard Worker buf
142*48a54d36SAndroid Build Coastguard Worker Output buffer. Must be long enough to hold largest possible
143*48a54d36SAndroid Build Coastguard Worker output. For AF_INET, this is 29 characters (including null).
144*48a54d36SAndroid Build Coastguard Worker Returns
145*48a54d36SAndroid Build Coastguard Worker Pointer to (first character of) output buffer,
146*48a54d36SAndroid Build Coastguard Worker or NULL on error.
147*48a54d36SAndroid Build Coastguard Worker */
148*48a54d36SAndroid Build Coastguard Worker char *
149*48a54d36SAndroid Build Coastguard Worker format_reverse_addr_in (
150*48a54d36SAndroid Build Coastguard Worker const struct in_addr * addr,
151*48a54d36SAndroid Build Coastguard Worker int prefixlen,
152*48a54d36SAndroid Build Coastguard Worker char * buf
153*48a54d36SAndroid Build Coastguard Worker );
154*48a54d36SAndroid Build Coastguard Worker #define DNS_PTR_AF_INET_SIZE 29
155*48a54d36SAndroid Build Coastguard Worker
156*48a54d36SAndroid Build Coastguard Worker /*
157*48a54d36SAndroid Build Coastguard Worker Format an address structure as a string appropriate for DNS reverse (PTR)
158*48a54d36SAndroid Build Coastguard Worker lookup for AF_INET6. Output is in .ip6.arpa domain.
159*48a54d36SAndroid Build Coastguard Worker
160*48a54d36SAndroid Build Coastguard Worker Parameters
161*48a54d36SAndroid Build Coastguard Worker prefixlen
162*48a54d36SAndroid Build Coastguard Worker Prefix length, in bits. When formatting, this will be rounded up
163*48a54d36SAndroid Build Coastguard Worker to the nearest nibble (4). If -1, assume 128.
164*48a54d36SAndroid Build Coastguard Worker buf
165*48a54d36SAndroid Build Coastguard Worker Output buffer. Must be long enough to hold largest possible
166*48a54d36SAndroid Build Coastguard Worker output. For AF_INET6, this is 72 characters (including null).
167*48a54d36SAndroid Build Coastguard Worker Returns
168*48a54d36SAndroid Build Coastguard Worker Pointer to (first character of) output buffer,
169*48a54d36SAndroid Build Coastguard Worker or NULL on error.
170*48a54d36SAndroid Build Coastguard Worker */
171*48a54d36SAndroid Build Coastguard Worker char *
172*48a54d36SAndroid Build Coastguard Worker format_reverse_addr_in6 (
173*48a54d36SAndroid Build Coastguard Worker const struct in6_addr * addr,
174*48a54d36SAndroid Build Coastguard Worker int prefixlen,
175*48a54d36SAndroid Build Coastguard Worker char * buf
176*48a54d36SAndroid Build Coastguard Worker );
177*48a54d36SAndroid Build Coastguard Worker #define DNS_PTR_AF_INET6_SIZE 72
178*48a54d36SAndroid Build Coastguard Worker
179*48a54d36SAndroid Build Coastguard Worker
180*48a54d36SAndroid Build Coastguard Worker /*
181*48a54d36SAndroid Build Coastguard Worker Compare whether the given dns name has the given domain suffix.
182*48a54d36SAndroid Build Coastguard Worker A single leading '.' on the name or leading or trailing '.' on the
183*48a54d36SAndroid Build Coastguard Worker domain is ignored for the purposes of the comparison.
184*48a54d36SAndroid Build Coastguard Worker Multiple leading or trailing '.'s are an error. Other DNS syntax
185*48a54d36SAndroid Build Coastguard Worker errors are not checked for. The comparison is case insensitive.
186*48a54d36SAndroid Build Coastguard Worker
187*48a54d36SAndroid Build Coastguard Worker Returns
188*48a54d36SAndroid Build Coastguard Worker 1 on success (match)
189*48a54d36SAndroid Build Coastguard Worker 0 on failure (no match)
190*48a54d36SAndroid Build Coastguard Worker < 0 on error
191*48a54d36SAndroid Build Coastguard Worker */
192*48a54d36SAndroid Build Coastguard Worker int
193*48a54d36SAndroid Build Coastguard Worker cmp_dns_suffix (const char * name, const char * domain);
194*48a54d36SAndroid Build Coastguard Worker enum
195*48a54d36SAndroid Build Coastguard Worker {
196*48a54d36SAndroid Build Coastguard Worker CMP_DNS_SUFFIX_SUCCESS = 1,
197*48a54d36SAndroid Build Coastguard Worker CMP_DNS_SUFFIX_FAILURE = 0,
198*48a54d36SAndroid Build Coastguard Worker CMP_DNS_SUFFIX_BAD_NAME = 1,
199*48a54d36SAndroid Build Coastguard Worker CMP_DNS_SUFFIX_BAD_DOMAIN = -2
200*48a54d36SAndroid Build Coastguard Worker };
201*48a54d36SAndroid Build Coastguard Worker
202*48a54d36SAndroid Build Coastguard Worker typedef int ns_type_t;
203*48a54d36SAndroid Build Coastguard Worker typedef int ns_class_t;
204*48a54d36SAndroid Build Coastguard Worker
205*48a54d36SAndroid Build Coastguard Worker /*
206*48a54d36SAndroid Build Coastguard Worker Convert a DNS resource record (RR) code to an address family (AF) code.
207*48a54d36SAndroid Build Coastguard Worker
208*48a54d36SAndroid Build Coastguard Worker Parameters
209*48a54d36SAndroid Build Coastguard Worker rrtype
210*48a54d36SAndroid Build Coastguard Worker resource record type (from nameser.h)
211*48a54d36SAndroid Build Coastguard Worker
212*48a54d36SAndroid Build Coastguard Worker Returns
213*48a54d36SAndroid Build Coastguard Worker Appropriate AF code (from socket.h), or AF_UNSPEC if an appropriate
214*48a54d36SAndroid Build Coastguard Worker mapping couldn't be determined
215*48a54d36SAndroid Build Coastguard Worker */
216*48a54d36SAndroid Build Coastguard Worker int
217*48a54d36SAndroid Build Coastguard Worker rr_to_af (ns_type_t rrtype);
218*48a54d36SAndroid Build Coastguard Worker
219*48a54d36SAndroid Build Coastguard Worker
220*48a54d36SAndroid Build Coastguard Worker /*
221*48a54d36SAndroid Build Coastguard Worker Convert an address family (AF) code to a DNS resource record (RR) code.
222*48a54d36SAndroid Build Coastguard Worker
223*48a54d36SAndroid Build Coastguard Worker Parameters
224*48a54d36SAndroid Build Coastguard Worker int
225*48a54d36SAndroid Build Coastguard Worker address family code (from socket.h)
226*48a54d36SAndroid Build Coastguard Worker Returns
227*48a54d36SAndroid Build Coastguard Worker Appropriate RR code (from nameser.h), or ns_t_invalid if an appropriate
228*48a54d36SAndroid Build Coastguard Worker mapping couldn't be determined
229*48a54d36SAndroid Build Coastguard Worker */
230*48a54d36SAndroid Build Coastguard Worker ns_type_t
231*48a54d36SAndroid Build Coastguard Worker af_to_rr (int af);
232*48a54d36SAndroid Build Coastguard Worker
233*48a54d36SAndroid Build Coastguard Worker
234*48a54d36SAndroid Build Coastguard Worker /*
235*48a54d36SAndroid Build Coastguard Worker Convert a string to an address family (case insensitive).
236*48a54d36SAndroid Build Coastguard Worker
237*48a54d36SAndroid Build Coastguard Worker Returns
238*48a54d36SAndroid Build Coastguard Worker Matching AF code, or AF_UNSPEC if no match found.
239*48a54d36SAndroid Build Coastguard Worker */
240*48a54d36SAndroid Build Coastguard Worker int
241*48a54d36SAndroid Build Coastguard Worker str_to_af (const char * str);
242*48a54d36SAndroid Build Coastguard Worker
243*48a54d36SAndroid Build Coastguard Worker
244*48a54d36SAndroid Build Coastguard Worker /*
245*48a54d36SAndroid Build Coastguard Worker Convert a string to an ns_class_t (case insensitive).
246*48a54d36SAndroid Build Coastguard Worker
247*48a54d36SAndroid Build Coastguard Worker Returns
248*48a54d36SAndroid Build Coastguard Worker Matching ns_class_t, or ns_c_invalid if no match found.
249*48a54d36SAndroid Build Coastguard Worker */
250*48a54d36SAndroid Build Coastguard Worker ns_class_t
251*48a54d36SAndroid Build Coastguard Worker str_to_ns_class (const char * str);
252*48a54d36SAndroid Build Coastguard Worker
253*48a54d36SAndroid Build Coastguard Worker
254*48a54d36SAndroid Build Coastguard Worker /*
255*48a54d36SAndroid Build Coastguard Worker Convert a string to an ns_type_t (case insensitive).
256*48a54d36SAndroid Build Coastguard Worker
257*48a54d36SAndroid Build Coastguard Worker Returns
258*48a54d36SAndroid Build Coastguard Worker Matching ns_type_t, or ns_t_invalid if no match found.
259*48a54d36SAndroid Build Coastguard Worker */
260*48a54d36SAndroid Build Coastguard Worker ns_type_t
261*48a54d36SAndroid Build Coastguard Worker str_to_ns_type (const char * str);
262*48a54d36SAndroid Build Coastguard Worker
263*48a54d36SAndroid Build Coastguard Worker
264*48a54d36SAndroid Build Coastguard Worker /*
265*48a54d36SAndroid Build Coastguard Worker Convert an address family code to a string.
266*48a54d36SAndroid Build Coastguard Worker
267*48a54d36SAndroid Build Coastguard Worker Returns
268*48a54d36SAndroid Build Coastguard Worker String representation of AF,
269*48a54d36SAndroid Build Coastguard Worker or NULL if address family unrecognised or invalid.
270*48a54d36SAndroid Build Coastguard Worker */
271*48a54d36SAndroid Build Coastguard Worker const char *
272*48a54d36SAndroid Build Coastguard Worker af_to_str (int in);
273*48a54d36SAndroid Build Coastguard Worker
274*48a54d36SAndroid Build Coastguard Worker
275*48a54d36SAndroid Build Coastguard Worker /*
276*48a54d36SAndroid Build Coastguard Worker Convert an ns_class_t code to a string.
277*48a54d36SAndroid Build Coastguard Worker
278*48a54d36SAndroid Build Coastguard Worker Returns
279*48a54d36SAndroid Build Coastguard Worker String representation of ns_class_t,
280*48a54d36SAndroid Build Coastguard Worker or NULL if ns_class_t unrecognised or invalid.
281*48a54d36SAndroid Build Coastguard Worker */
282*48a54d36SAndroid Build Coastguard Worker const char *
283*48a54d36SAndroid Build Coastguard Worker ns_class_to_str (ns_class_t in);
284*48a54d36SAndroid Build Coastguard Worker
285*48a54d36SAndroid Build Coastguard Worker
286*48a54d36SAndroid Build Coastguard Worker /*
287*48a54d36SAndroid Build Coastguard Worker Convert an ns_type_t code to a string.
288*48a54d36SAndroid Build Coastguard Worker
289*48a54d36SAndroid Build Coastguard Worker Returns
290*48a54d36SAndroid Build Coastguard Worker String representation of ns_type_t,
291*48a54d36SAndroid Build Coastguard Worker or NULL if ns_type_t unrecognised or invalid.
292*48a54d36SAndroid Build Coastguard Worker */
293*48a54d36SAndroid Build Coastguard Worker const char *
294*48a54d36SAndroid Build Coastguard Worker ns_type_to_str (ns_type_t in);
295*48a54d36SAndroid Build Coastguard Worker
296*48a54d36SAndroid Build Coastguard Worker
297*48a54d36SAndroid Build Coastguard Worker /*
298*48a54d36SAndroid Build Coastguard Worker Convert DNS rdata in label format (RFC1034, RFC1035) to a name.
299*48a54d36SAndroid Build Coastguard Worker
300*48a54d36SAndroid Build Coastguard Worker On error, partial data is written to name (as much as was successfully
301*48a54d36SAndroid Build Coastguard Worker processed) and an error code is returned. Errors include a name too
302*48a54d36SAndroid Build Coastguard Worker long for the buffer and a pointer in the label (which cannot be
303*48a54d36SAndroid Build Coastguard Worker resolved).
304*48a54d36SAndroid Build Coastguard Worker
305*48a54d36SAndroid Build Coastguard Worker Parameters
306*48a54d36SAndroid Build Coastguard Worker rdata
307*48a54d36SAndroid Build Coastguard Worker Rdata formatted as series of labels.
308*48a54d36SAndroid Build Coastguard Worker rdlen
309*48a54d36SAndroid Build Coastguard Worker Length of rdata buffer.
310*48a54d36SAndroid Build Coastguard Worker name
311*48a54d36SAndroid Build Coastguard Worker Buffer to store fully qualified result in.
312*48a54d36SAndroid Build Coastguard Worker By RFC1034 section 3.1, a 255 character buffer (256 characters
313*48a54d36SAndroid Build Coastguard Worker including null) is long enough for any legal name.
314*48a54d36SAndroid Build Coastguard Worker name_len
315*48a54d36SAndroid Build Coastguard Worker Number of characters available in name buffer, not including
316*48a54d36SAndroid Build Coastguard Worker trailing null.
317*48a54d36SAndroid Build Coastguard Worker
318*48a54d36SAndroid Build Coastguard Worker Returns
319*48a54d36SAndroid Build Coastguard Worker Length of name buffer (not including trailing null).
320*48a54d36SAndroid Build Coastguard Worker < 0 on error.
321*48a54d36SAndroid Build Coastguard Worker A return of 0 implies the empty domain.
322*48a54d36SAndroid Build Coastguard Worker */
323*48a54d36SAndroid Build Coastguard Worker int
324*48a54d36SAndroid Build Coastguard Worker dns_rdata_to_name (const char * rdata, int rdlen, char * name, int name_len);
325*48a54d36SAndroid Build Coastguard Worker enum
326*48a54d36SAndroid Build Coastguard Worker {
327*48a54d36SAndroid Build Coastguard Worker DNS_RDATA_TO_NAME_BAD_FORMAT = -1,
328*48a54d36SAndroid Build Coastguard Worker // Format is broken. Usually because we ran out of data
329*48a54d36SAndroid Build Coastguard Worker // (according to rdata) before the labels said we should.
330*48a54d36SAndroid Build Coastguard Worker DNS_RDATA_TO_NAME_TOO_LONG = -2,
331*48a54d36SAndroid Build Coastguard Worker // The converted rdata is longer than the name buffer.
332*48a54d36SAndroid Build Coastguard Worker DNS_RDATA_TO_NAME_PTR = -3,
333*48a54d36SAndroid Build Coastguard Worker // The rdata contains a pointer.
334*48a54d36SAndroid Build Coastguard Worker };
335*48a54d36SAndroid Build Coastguard Worker
336*48a54d36SAndroid Build Coastguard Worker #define DNS_LABEL_MAXLEN 63
337*48a54d36SAndroid Build Coastguard Worker // Maximum length of a single DNS label
338*48a54d36SAndroid Build Coastguard Worker #define DNS_NAME_MAXLEN 256
339*48a54d36SAndroid Build Coastguard Worker // Maximum length of a DNS name
340*48a54d36SAndroid Build Coastguard Worker
341*48a54d36SAndroid Build Coastguard Worker //----------
342*48a54d36SAndroid Build Coastguard Worker // Public types
343*48a54d36SAndroid Build Coastguard Worker
344*48a54d36SAndroid Build Coastguard Worker typedef int errcode_t;
345*48a54d36SAndroid Build Coastguard Worker // Used for 0 = success, non-zero = error code functions
346*48a54d36SAndroid Build Coastguard Worker
347*48a54d36SAndroid Build Coastguard Worker
348*48a54d36SAndroid Build Coastguard Worker //----------
349*48a54d36SAndroid Build Coastguard Worker // Public functions
350*48a54d36SAndroid Build Coastguard Worker
351*48a54d36SAndroid Build Coastguard Worker /*
352*48a54d36SAndroid Build Coastguard Worker Test whether a domain name is in a domain covered by nss_mdns.
353*48a54d36SAndroid Build Coastguard Worker The name is assumed to be fully qualified (trailing dot optional);
354*48a54d36SAndroid Build Coastguard Worker unqualified names will be processed but may return unusual results
355*48a54d36SAndroid Build Coastguard Worker if the unqualified prefix happens to match a domain suffix.
356*48a54d36SAndroid Build Coastguard Worker
357*48a54d36SAndroid Build Coastguard Worker Returns
358*48a54d36SAndroid Build Coastguard Worker 1 success
359*48a54d36SAndroid Build Coastguard Worker 0 failure
360*48a54d36SAndroid Build Coastguard Worker -1 error, check errno
361*48a54d36SAndroid Build Coastguard Worker */
362*48a54d36SAndroid Build Coastguard Worker int
363*48a54d36SAndroid Build Coastguard Worker config_is_mdns_suffix (const char * name);
364*48a54d36SAndroid Build Coastguard Worker
365*48a54d36SAndroid Build Coastguard Worker
366*48a54d36SAndroid Build Coastguard Worker /*
367*48a54d36SAndroid Build Coastguard Worker Loads all relevant data from configuration file. Other code should
368*48a54d36SAndroid Build Coastguard Worker rarely need to call this function, since all other public configuration
369*48a54d36SAndroid Build Coastguard Worker functions do so implicitly. Once loaded, configuration info doesn't
370*48a54d36SAndroid Build Coastguard Worker change.
371*48a54d36SAndroid Build Coastguard Worker
372*48a54d36SAndroid Build Coastguard Worker Returns
373*48a54d36SAndroid Build Coastguard Worker 0 configuration ready
374*48a54d36SAndroid Build Coastguard Worker non-zero configuration error code
375*48a54d36SAndroid Build Coastguard Worker */
376*48a54d36SAndroid Build Coastguard Worker errcode_t
377*48a54d36SAndroid Build Coastguard Worker init_config ();
378*48a54d36SAndroid Build Coastguard Worker
379*48a54d36SAndroid Build Coastguard Worker #define ENTNAME hostent
380*48a54d36SAndroid Build Coastguard Worker #define DATABASE "hosts"
381*48a54d36SAndroid Build Coastguard Worker
382*48a54d36SAndroid Build Coastguard Worker #include <nss.h>
383*48a54d36SAndroid Build Coastguard Worker // For nss_status
384*48a54d36SAndroid Build Coastguard Worker #include <netdb.h>
385*48a54d36SAndroid Build Coastguard Worker // For hostent
386*48a54d36SAndroid Build Coastguard Worker #include <sys/types.h>
387*48a54d36SAndroid Build Coastguard Worker // For size_t
388*48a54d36SAndroid Build Coastguard Worker
389*48a54d36SAndroid Build Coastguard Worker typedef enum nss_status nss_status;
390*48a54d36SAndroid Build Coastguard Worker typedef struct hostent hostent;
391*48a54d36SAndroid Build Coastguard Worker
392*48a54d36SAndroid Build Coastguard Worker /*
393*48a54d36SAndroid Build Coastguard Worker gethostbyname implementation
394*48a54d36SAndroid Build Coastguard Worker
395*48a54d36SAndroid Build Coastguard Worker name:
396*48a54d36SAndroid Build Coastguard Worker name to look up
397*48a54d36SAndroid Build Coastguard Worker result_buf:
398*48a54d36SAndroid Build Coastguard Worker resulting entry
399*48a54d36SAndroid Build Coastguard Worker buf:
400*48a54d36SAndroid Build Coastguard Worker auxillary buffer
401*48a54d36SAndroid Build Coastguard Worker buflen:
402*48a54d36SAndroid Build Coastguard Worker length of auxillary buffer
403*48a54d36SAndroid Build Coastguard Worker errnop:
404*48a54d36SAndroid Build Coastguard Worker pointer to errno
405*48a54d36SAndroid Build Coastguard Worker h_errnop:
406*48a54d36SAndroid Build Coastguard Worker pointer to h_errno
407*48a54d36SAndroid Build Coastguard Worker */
408*48a54d36SAndroid Build Coastguard Worker nss_status
409*48a54d36SAndroid Build Coastguard Worker _nss_mdns_gethostbyname_r (
410*48a54d36SAndroid Build Coastguard Worker const char *name,
411*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
412*48a54d36SAndroid Build Coastguard Worker char *buf,
413*48a54d36SAndroid Build Coastguard Worker size_t buflen,
414*48a54d36SAndroid Build Coastguard Worker int *errnop,
415*48a54d36SAndroid Build Coastguard Worker int *h_errnop
416*48a54d36SAndroid Build Coastguard Worker );
417*48a54d36SAndroid Build Coastguard Worker
418*48a54d36SAndroid Build Coastguard Worker
419*48a54d36SAndroid Build Coastguard Worker /*
420*48a54d36SAndroid Build Coastguard Worker gethostbyname2 implementation
421*48a54d36SAndroid Build Coastguard Worker
422*48a54d36SAndroid Build Coastguard Worker name:
423*48a54d36SAndroid Build Coastguard Worker name to look up
424*48a54d36SAndroid Build Coastguard Worker af:
425*48a54d36SAndroid Build Coastguard Worker address family
426*48a54d36SAndroid Build Coastguard Worker result_buf:
427*48a54d36SAndroid Build Coastguard Worker resulting entry
428*48a54d36SAndroid Build Coastguard Worker buf:
429*48a54d36SAndroid Build Coastguard Worker auxillary buffer
430*48a54d36SAndroid Build Coastguard Worker buflen:
431*48a54d36SAndroid Build Coastguard Worker length of auxillary buffer
432*48a54d36SAndroid Build Coastguard Worker errnop:
433*48a54d36SAndroid Build Coastguard Worker pointer to errno
434*48a54d36SAndroid Build Coastguard Worker h_errnop:
435*48a54d36SAndroid Build Coastguard Worker pointer to h_errno
436*48a54d36SAndroid Build Coastguard Worker */
437*48a54d36SAndroid Build Coastguard Worker nss_status
438*48a54d36SAndroid Build Coastguard Worker _nss_mdns_gethostbyname2_r (
439*48a54d36SAndroid Build Coastguard Worker const char *name,
440*48a54d36SAndroid Build Coastguard Worker int af,
441*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
442*48a54d36SAndroid Build Coastguard Worker char *buf,
443*48a54d36SAndroid Build Coastguard Worker size_t buflen,
444*48a54d36SAndroid Build Coastguard Worker int *errnop,
445*48a54d36SAndroid Build Coastguard Worker int *h_errnop
446*48a54d36SAndroid Build Coastguard Worker );
447*48a54d36SAndroid Build Coastguard Worker
448*48a54d36SAndroid Build Coastguard Worker
449*48a54d36SAndroid Build Coastguard Worker /*
450*48a54d36SAndroid Build Coastguard Worker gethostbyaddr implementation
451*48a54d36SAndroid Build Coastguard Worker
452*48a54d36SAndroid Build Coastguard Worker addr:
453*48a54d36SAndroid Build Coastguard Worker address structure to look up
454*48a54d36SAndroid Build Coastguard Worker len:
455*48a54d36SAndroid Build Coastguard Worker length of address structure
456*48a54d36SAndroid Build Coastguard Worker af:
457*48a54d36SAndroid Build Coastguard Worker address family
458*48a54d36SAndroid Build Coastguard Worker result_buf:
459*48a54d36SAndroid Build Coastguard Worker resulting entry
460*48a54d36SAndroid Build Coastguard Worker buf:
461*48a54d36SAndroid Build Coastguard Worker auxillary buffer
462*48a54d36SAndroid Build Coastguard Worker buflen:
463*48a54d36SAndroid Build Coastguard Worker length of auxillary buffer
464*48a54d36SAndroid Build Coastguard Worker errnop:
465*48a54d36SAndroid Build Coastguard Worker pointer to errno
466*48a54d36SAndroid Build Coastguard Worker h_errnop:
467*48a54d36SAndroid Build Coastguard Worker pointer to h_errno
468*48a54d36SAndroid Build Coastguard Worker */
469*48a54d36SAndroid Build Coastguard Worker nss_status
470*48a54d36SAndroid Build Coastguard Worker _nss_mdns_gethostbyaddr_r (
471*48a54d36SAndroid Build Coastguard Worker const void *addr,
472*48a54d36SAndroid Build Coastguard Worker socklen_t len,
473*48a54d36SAndroid Build Coastguard Worker int af,
474*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
475*48a54d36SAndroid Build Coastguard Worker char *buf,
476*48a54d36SAndroid Build Coastguard Worker size_t buflen,
477*48a54d36SAndroid Build Coastguard Worker int *errnop,
478*48a54d36SAndroid Build Coastguard Worker int *h_errnop
479*48a54d36SAndroid Build Coastguard Worker );
480*48a54d36SAndroid Build Coastguard Worker
481*48a54d36SAndroid Build Coastguard Worker
482*48a54d36SAndroid Build Coastguard Worker //----------
483*48a54d36SAndroid Build Coastguard Worker // Types and Constants
484*48a54d36SAndroid Build Coastguard Worker
485*48a54d36SAndroid Build Coastguard Worker const int MDNS_VERBOSE = 0;
486*48a54d36SAndroid Build Coastguard Worker // This enables verbose syslog messages
487*48a54d36SAndroid Build Coastguard Worker // If zero, only "imporant" messages will appear in syslog
488*48a54d36SAndroid Build Coastguard Worker
489*48a54d36SAndroid Build Coastguard Worker #define k_hostname_maxlen 256
490*48a54d36SAndroid Build Coastguard Worker // As per RFC1034 and RFC1035
491*48a54d36SAndroid Build Coastguard Worker #define k_aliases_max 15
492*48a54d36SAndroid Build Coastguard Worker #define k_addrs_max 15
493*48a54d36SAndroid Build Coastguard Worker
494*48a54d36SAndroid Build Coastguard Worker typedef struct buf_header
495*48a54d36SAndroid Build Coastguard Worker {
496*48a54d36SAndroid Build Coastguard Worker char hostname [k_hostname_maxlen + 1];
497*48a54d36SAndroid Build Coastguard Worker char * aliases [k_aliases_max + 1];
498*48a54d36SAndroid Build Coastguard Worker char * addrs [k_addrs_max + 1];
499*48a54d36SAndroid Build Coastguard Worker } buf_header_t;
500*48a54d36SAndroid Build Coastguard Worker
501*48a54d36SAndroid Build Coastguard Worker typedef struct result_map
502*48a54d36SAndroid Build Coastguard Worker {
503*48a54d36SAndroid Build Coastguard Worker int done;
504*48a54d36SAndroid Build Coastguard Worker nss_status status;
505*48a54d36SAndroid Build Coastguard Worker hostent * hostent;
506*48a54d36SAndroid Build Coastguard Worker buf_header_t * header;
507*48a54d36SAndroid Build Coastguard Worker int aliases_count;
508*48a54d36SAndroid Build Coastguard Worker int addrs_count;
509*48a54d36SAndroid Build Coastguard Worker char * buffer;
510*48a54d36SAndroid Build Coastguard Worker int addr_idx;
511*48a54d36SAndroid Build Coastguard Worker // Index for addresses - grow from low end
512*48a54d36SAndroid Build Coastguard Worker // Index points to first empty space
513*48a54d36SAndroid Build Coastguard Worker int alias_idx;
514*48a54d36SAndroid Build Coastguard Worker // Index for aliases - grow from high end
515*48a54d36SAndroid Build Coastguard Worker // Index points to lowest entry
516*48a54d36SAndroid Build Coastguard Worker int r_errno;
517*48a54d36SAndroid Build Coastguard Worker int r_h_errno;
518*48a54d36SAndroid Build Coastguard Worker } result_map_t;
519*48a54d36SAndroid Build Coastguard Worker
520*48a54d36SAndroid Build Coastguard Worker static const struct timeval
521*48a54d36SAndroid Build Coastguard Worker k_select_time = { 0, 500000 };
522*48a54d36SAndroid Build Coastguard Worker // 0 seconds, 500 milliseconds
523*48a54d36SAndroid Build Coastguard Worker
524*48a54d36SAndroid Build Coastguard Worker //----------
525*48a54d36SAndroid Build Coastguard Worker // Local prototypes
526*48a54d36SAndroid Build Coastguard Worker
527*48a54d36SAndroid Build Coastguard Worker static nss_status
528*48a54d36SAndroid Build Coastguard Worker mdns_gethostbyname2 (
529*48a54d36SAndroid Build Coastguard Worker const char *name,
530*48a54d36SAndroid Build Coastguard Worker int af,
531*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
532*48a54d36SAndroid Build Coastguard Worker char *buf,
533*48a54d36SAndroid Build Coastguard Worker size_t buflen,
534*48a54d36SAndroid Build Coastguard Worker int *errnop,
535*48a54d36SAndroid Build Coastguard Worker int *h_errnop
536*48a54d36SAndroid Build Coastguard Worker );
537*48a54d36SAndroid Build Coastguard Worker
538*48a54d36SAndroid Build Coastguard Worker
539*48a54d36SAndroid Build Coastguard Worker /*
540*48a54d36SAndroid Build Coastguard Worker Lookup name using mDNS server
541*48a54d36SAndroid Build Coastguard Worker */
542*48a54d36SAndroid Build Coastguard Worker static nss_status
543*48a54d36SAndroid Build Coastguard Worker mdns_lookup_name (
544*48a54d36SAndroid Build Coastguard Worker const char * fullname,
545*48a54d36SAndroid Build Coastguard Worker int af,
546*48a54d36SAndroid Build Coastguard Worker result_map_t * result
547*48a54d36SAndroid Build Coastguard Worker );
548*48a54d36SAndroid Build Coastguard Worker
549*48a54d36SAndroid Build Coastguard Worker /*
550*48a54d36SAndroid Build Coastguard Worker Lookup address using mDNS server
551*48a54d36SAndroid Build Coastguard Worker */
552*48a54d36SAndroid Build Coastguard Worker static nss_status
553*48a54d36SAndroid Build Coastguard Worker mdns_lookup_addr (
554*48a54d36SAndroid Build Coastguard Worker const void * addr,
555*48a54d36SAndroid Build Coastguard Worker socklen_t len,
556*48a54d36SAndroid Build Coastguard Worker int af,
557*48a54d36SAndroid Build Coastguard Worker const char * addr_str,
558*48a54d36SAndroid Build Coastguard Worker result_map_t * result
559*48a54d36SAndroid Build Coastguard Worker );
560*48a54d36SAndroid Build Coastguard Worker
561*48a54d36SAndroid Build Coastguard Worker
562*48a54d36SAndroid Build Coastguard Worker /*
563*48a54d36SAndroid Build Coastguard Worker Handle incoming MDNS events
564*48a54d36SAndroid Build Coastguard Worker */
565*48a54d36SAndroid Build Coastguard Worker static nss_status
566*48a54d36SAndroid Build Coastguard Worker handle_events (DNSServiceRef sdref, result_map_t * result, const char * str);
567*48a54d36SAndroid Build Coastguard Worker
568*48a54d36SAndroid Build Coastguard Worker
569*48a54d36SAndroid Build Coastguard Worker // Callback for mdns_lookup operations
570*48a54d36SAndroid Build Coastguard Worker //DNSServiceQueryRecordReply mdns_lookup_callback;
571*48a54d36SAndroid Build Coastguard Worker typedef void
572*48a54d36SAndroid Build Coastguard Worker mdns_lookup_callback_t
573*48a54d36SAndroid Build Coastguard Worker (
574*48a54d36SAndroid Build Coastguard Worker DNSServiceRef sdref,
575*48a54d36SAndroid Build Coastguard Worker DNSServiceFlags flags,
576*48a54d36SAndroid Build Coastguard Worker uint32_t interface_index,
577*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType error_code,
578*48a54d36SAndroid Build Coastguard Worker const char *fullname,
579*48a54d36SAndroid Build Coastguard Worker uint16_t rrtype,
580*48a54d36SAndroid Build Coastguard Worker uint16_t rrclass,
581*48a54d36SAndroid Build Coastguard Worker uint16_t rdlen,
582*48a54d36SAndroid Build Coastguard Worker const void *rdata,
583*48a54d36SAndroid Build Coastguard Worker uint32_t ttl,
584*48a54d36SAndroid Build Coastguard Worker void *context
585*48a54d36SAndroid Build Coastguard Worker );
586*48a54d36SAndroid Build Coastguard Worker
587*48a54d36SAndroid Build Coastguard Worker mdns_lookup_callback_t mdns_lookup_callback;
588*48a54d36SAndroid Build Coastguard Worker
589*48a54d36SAndroid Build Coastguard Worker
590*48a54d36SAndroid Build Coastguard Worker static int
591*48a54d36SAndroid Build Coastguard Worker init_result (
592*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
593*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
594*48a54d36SAndroid Build Coastguard Worker char * buf,
595*48a54d36SAndroid Build Coastguard Worker size_t buflen
596*48a54d36SAndroid Build Coastguard Worker );
597*48a54d36SAndroid Build Coastguard Worker
598*48a54d36SAndroid Build Coastguard Worker static int
599*48a54d36SAndroid Build Coastguard Worker callback_body_ptr (
600*48a54d36SAndroid Build Coastguard Worker const char * fullname,
601*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
602*48a54d36SAndroid Build Coastguard Worker int rdlen,
603*48a54d36SAndroid Build Coastguard Worker const void * rdata
604*48a54d36SAndroid Build Coastguard Worker );
605*48a54d36SAndroid Build Coastguard Worker
606*48a54d36SAndroid Build Coastguard Worker static void *
607*48a54d36SAndroid Build Coastguard Worker add_address_to_buffer (result_map_t * result, const void * data, int len);
608*48a54d36SAndroid Build Coastguard Worker static char *
609*48a54d36SAndroid Build Coastguard Worker add_alias_to_buffer (result_map_t * result, const char * data, int len);
610*48a54d36SAndroid Build Coastguard Worker static char *
611*48a54d36SAndroid Build Coastguard Worker add_hostname_len (result_map_t * result, const char * fullname, int len);
612*48a54d36SAndroid Build Coastguard Worker static char *
613*48a54d36SAndroid Build Coastguard Worker add_hostname_or_alias (result_map_t * result, const char * data, int len);
614*48a54d36SAndroid Build Coastguard Worker
615*48a54d36SAndroid Build Coastguard Worker static void *
616*48a54d36SAndroid Build Coastguard Worker contains_address (result_map_t * result, const void * data, int len);
617*48a54d36SAndroid Build Coastguard Worker static char *
618*48a54d36SAndroid Build Coastguard Worker contains_alias (result_map_t * result, const char * data);
619*48a54d36SAndroid Build Coastguard Worker
620*48a54d36SAndroid Build Coastguard Worker
621*48a54d36SAndroid Build Coastguard Worker static const char *
622*48a54d36SAndroid Build Coastguard Worker is_applicable_name (
623*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
624*48a54d36SAndroid Build Coastguard Worker const char * name,
625*48a54d36SAndroid Build Coastguard Worker char * lookup_name
626*48a54d36SAndroid Build Coastguard Worker );
627*48a54d36SAndroid Build Coastguard Worker
628*48a54d36SAndroid Build Coastguard Worker static const char *
629*48a54d36SAndroid Build Coastguard Worker is_applicable_addr (
630*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
631*48a54d36SAndroid Build Coastguard Worker const void * addr,
632*48a54d36SAndroid Build Coastguard Worker int af,
633*48a54d36SAndroid Build Coastguard Worker char * addr_str
634*48a54d36SAndroid Build Coastguard Worker );
635*48a54d36SAndroid Build Coastguard Worker
636*48a54d36SAndroid Build Coastguard Worker
637*48a54d36SAndroid Build Coastguard Worker // Error code functions
638*48a54d36SAndroid Build Coastguard Worker
639*48a54d36SAndroid Build Coastguard Worker static nss_status
640*48a54d36SAndroid Build Coastguard Worker set_err (result_map_t * result, nss_status status, int err, int herr);
641*48a54d36SAndroid Build Coastguard Worker
642*48a54d36SAndroid Build Coastguard Worker static nss_status set_err_notfound (result_map_t * result);
643*48a54d36SAndroid Build Coastguard Worker static nss_status set_err_bad_hostname (result_map_t * result);
644*48a54d36SAndroid Build Coastguard Worker static nss_status set_err_buf_too_small (result_map_t * result);
645*48a54d36SAndroid Build Coastguard Worker static nss_status set_err_internal_resource_full (result_map_t * result);
646*48a54d36SAndroid Build Coastguard Worker static nss_status set_err_system (result_map_t * result);
647*48a54d36SAndroid Build Coastguard Worker static nss_status set_err_mdns_failed (result_map_t * result);
648*48a54d36SAndroid Build Coastguard Worker static nss_status set_err_success (result_map_t * result);
649*48a54d36SAndroid Build Coastguard Worker
650*48a54d36SAndroid Build Coastguard Worker
651*48a54d36SAndroid Build Coastguard Worker //----------
652*48a54d36SAndroid Build Coastguard Worker // Global variables
653*48a54d36SAndroid Build Coastguard Worker
654*48a54d36SAndroid Build Coastguard Worker
655*48a54d36SAndroid Build Coastguard Worker //----------
656*48a54d36SAndroid Build Coastguard Worker // NSS functions
657*48a54d36SAndroid Build Coastguard Worker
658*48a54d36SAndroid Build Coastguard Worker nss_status
_nss_mdns_gethostbyname_r(const char * name,hostent * result_buf,char * buf,size_t buflen,int * errnop,int * h_errnop)659*48a54d36SAndroid Build Coastguard Worker _nss_mdns_gethostbyname_r (
660*48a54d36SAndroid Build Coastguard Worker const char *name,
661*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
662*48a54d36SAndroid Build Coastguard Worker char *buf,
663*48a54d36SAndroid Build Coastguard Worker size_t buflen,
664*48a54d36SAndroid Build Coastguard Worker int *errnop,
665*48a54d36SAndroid Build Coastguard Worker int *h_errnop
666*48a54d36SAndroid Build Coastguard Worker )
667*48a54d36SAndroid Build Coastguard Worker {
668*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
669*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
670*48a54d36SAndroid Build Coastguard Worker "mdns: Called nss_mdns_gethostbyname with %s",
671*48a54d36SAndroid Build Coastguard Worker name
672*48a54d36SAndroid Build Coastguard Worker );
673*48a54d36SAndroid Build Coastguard Worker
674*48a54d36SAndroid Build Coastguard Worker return
675*48a54d36SAndroid Build Coastguard Worker mdns_gethostbyname2 (
676*48a54d36SAndroid Build Coastguard Worker name, AF_INET, result_buf, buf, buflen, errnop, h_errnop
677*48a54d36SAndroid Build Coastguard Worker );
678*48a54d36SAndroid Build Coastguard Worker }
679*48a54d36SAndroid Build Coastguard Worker
680*48a54d36SAndroid Build Coastguard Worker
681*48a54d36SAndroid Build Coastguard Worker nss_status
_nss_mdns_gethostbyname2_r(const char * name,int af,hostent * result_buf,char * buf,size_t buflen,int * errnop,int * h_errnop)682*48a54d36SAndroid Build Coastguard Worker _nss_mdns_gethostbyname2_r (
683*48a54d36SAndroid Build Coastguard Worker const char *name,
684*48a54d36SAndroid Build Coastguard Worker int af,
685*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
686*48a54d36SAndroid Build Coastguard Worker char *buf,
687*48a54d36SAndroid Build Coastguard Worker size_t buflen,
688*48a54d36SAndroid Build Coastguard Worker int *errnop,
689*48a54d36SAndroid Build Coastguard Worker int *h_errnop
690*48a54d36SAndroid Build Coastguard Worker )
691*48a54d36SAndroid Build Coastguard Worker {
692*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
693*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
694*48a54d36SAndroid Build Coastguard Worker "mdns: Called nss_mdns_gethostbyname2 with %s",
695*48a54d36SAndroid Build Coastguard Worker name
696*48a54d36SAndroid Build Coastguard Worker );
697*48a54d36SAndroid Build Coastguard Worker
698*48a54d36SAndroid Build Coastguard Worker return
699*48a54d36SAndroid Build Coastguard Worker mdns_gethostbyname2 (
700*48a54d36SAndroid Build Coastguard Worker name, af, result_buf, buf, buflen, errnop, h_errnop
701*48a54d36SAndroid Build Coastguard Worker );
702*48a54d36SAndroid Build Coastguard Worker }
703*48a54d36SAndroid Build Coastguard Worker
704*48a54d36SAndroid Build Coastguard Worker
705*48a54d36SAndroid Build Coastguard Worker nss_status
_nss_mdns_gethostbyaddr_r(const void * addr,socklen_t len,int af,hostent * result_buf,char * buf,size_t buflen,int * errnop,int * h_errnop)706*48a54d36SAndroid Build Coastguard Worker _nss_mdns_gethostbyaddr_r (
707*48a54d36SAndroid Build Coastguard Worker const void *addr,
708*48a54d36SAndroid Build Coastguard Worker socklen_t len,
709*48a54d36SAndroid Build Coastguard Worker int af,
710*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
711*48a54d36SAndroid Build Coastguard Worker char *buf,
712*48a54d36SAndroid Build Coastguard Worker size_t buflen,
713*48a54d36SAndroid Build Coastguard Worker int *errnop,
714*48a54d36SAndroid Build Coastguard Worker int *h_errnop
715*48a54d36SAndroid Build Coastguard Worker )
716*48a54d36SAndroid Build Coastguard Worker {
717*48a54d36SAndroid Build Coastguard Worker char addr_str [NI_MAXHOST + 1];
718*48a54d36SAndroid Build Coastguard Worker result_map_t result;
719*48a54d36SAndroid Build Coastguard Worker int err_status;
720*48a54d36SAndroid Build Coastguard Worker
721*48a54d36SAndroid Build Coastguard Worker if (inet_ntop (af, addr, addr_str, NI_MAXHOST) == NULL)
722*48a54d36SAndroid Build Coastguard Worker {
723*48a54d36SAndroid Build Coastguard Worker const char * family = af_to_str (af);
724*48a54d36SAndroid Build Coastguard Worker if (family == NULL)
725*48a54d36SAndroid Build Coastguard Worker {
726*48a54d36SAndroid Build Coastguard Worker family = "Unknown";
727*48a54d36SAndroid Build Coastguard Worker }
728*48a54d36SAndroid Build Coastguard Worker
729*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
730*48a54d36SAndroid Build Coastguard Worker "mdns: Couldn't covert address, family %d (%s) in nss_mdns_gethostbyaddr: %s",
731*48a54d36SAndroid Build Coastguard Worker af,
732*48a54d36SAndroid Build Coastguard Worker family,
733*48a54d36SAndroid Build Coastguard Worker strerror (errno)
734*48a54d36SAndroid Build Coastguard Worker );
735*48a54d36SAndroid Build Coastguard Worker
736*48a54d36SAndroid Build Coastguard Worker // This address family never applicable to us, so return NOT_FOUND
737*48a54d36SAndroid Build Coastguard Worker
738*48a54d36SAndroid Build Coastguard Worker *errnop = ENOENT;
739*48a54d36SAndroid Build Coastguard Worker *h_errnop = HOST_NOT_FOUND;
740*48a54d36SAndroid Build Coastguard Worker return NSS_STATUS_NOTFOUND;
741*48a54d36SAndroid Build Coastguard Worker }
742*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
743*48a54d36SAndroid Build Coastguard Worker {
744*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
745*48a54d36SAndroid Build Coastguard Worker "mdns: Called nss_mdns_gethostbyaddr with %s",
746*48a54d36SAndroid Build Coastguard Worker addr_str
747*48a54d36SAndroid Build Coastguard Worker );
748*48a54d36SAndroid Build Coastguard Worker }
749*48a54d36SAndroid Build Coastguard Worker
750*48a54d36SAndroid Build Coastguard Worker // Initialise result
751*48a54d36SAndroid Build Coastguard Worker err_status = init_result (&result, result_buf, buf, buflen);
752*48a54d36SAndroid Build Coastguard Worker if (err_status)
753*48a54d36SAndroid Build Coastguard Worker {
754*48a54d36SAndroid Build Coastguard Worker *errnop = err_status;
755*48a54d36SAndroid Build Coastguard Worker *h_errnop = NETDB_INTERNAL;
756*48a54d36SAndroid Build Coastguard Worker return NSS_STATUS_TRYAGAIN;
757*48a54d36SAndroid Build Coastguard Worker }
758*48a54d36SAndroid Build Coastguard Worker
759*48a54d36SAndroid Build Coastguard Worker if (is_applicable_addr (&result, addr, af, addr_str))
760*48a54d36SAndroid Build Coastguard Worker {
761*48a54d36SAndroid Build Coastguard Worker nss_status rv;
762*48a54d36SAndroid Build Coastguard Worker
763*48a54d36SAndroid Build Coastguard Worker rv = mdns_lookup_addr (addr, len, af, addr_str, &result);
764*48a54d36SAndroid Build Coastguard Worker if (rv == NSS_STATUS_SUCCESS)
765*48a54d36SAndroid Build Coastguard Worker {
766*48a54d36SAndroid Build Coastguard Worker return rv;
767*48a54d36SAndroid Build Coastguard Worker }
768*48a54d36SAndroid Build Coastguard Worker }
769*48a54d36SAndroid Build Coastguard Worker
770*48a54d36SAndroid Build Coastguard Worker // Return current error status (defaults to NOT_FOUND)
771*48a54d36SAndroid Build Coastguard Worker
772*48a54d36SAndroid Build Coastguard Worker *errnop = result.r_errno;
773*48a54d36SAndroid Build Coastguard Worker *h_errnop = result.r_h_errno;
774*48a54d36SAndroid Build Coastguard Worker return result.status;
775*48a54d36SAndroid Build Coastguard Worker }
776*48a54d36SAndroid Build Coastguard Worker
777*48a54d36SAndroid Build Coastguard Worker
778*48a54d36SAndroid Build Coastguard Worker //----------
779*48a54d36SAndroid Build Coastguard Worker // Local functions
780*48a54d36SAndroid Build Coastguard Worker
781*48a54d36SAndroid Build Coastguard Worker nss_status
mdns_gethostbyname2(const char * name,int af,hostent * result_buf,char * buf,size_t buflen,int * errnop,int * h_errnop)782*48a54d36SAndroid Build Coastguard Worker mdns_gethostbyname2 (
783*48a54d36SAndroid Build Coastguard Worker const char *name,
784*48a54d36SAndroid Build Coastguard Worker int af,
785*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
786*48a54d36SAndroid Build Coastguard Worker char *buf,
787*48a54d36SAndroid Build Coastguard Worker size_t buflen,
788*48a54d36SAndroid Build Coastguard Worker int *errnop,
789*48a54d36SAndroid Build Coastguard Worker int *h_errnop
790*48a54d36SAndroid Build Coastguard Worker )
791*48a54d36SAndroid Build Coastguard Worker {
792*48a54d36SAndroid Build Coastguard Worker char lookup_name [k_hostname_maxlen + 1];
793*48a54d36SAndroid Build Coastguard Worker result_map_t result;
794*48a54d36SAndroid Build Coastguard Worker int err_status;
795*48a54d36SAndroid Build Coastguard Worker
796*48a54d36SAndroid Build Coastguard Worker // Initialise result
797*48a54d36SAndroid Build Coastguard Worker err_status = init_result (&result, result_buf, buf, buflen);
798*48a54d36SAndroid Build Coastguard Worker if (err_status)
799*48a54d36SAndroid Build Coastguard Worker {
800*48a54d36SAndroid Build Coastguard Worker *errnop = err_status;
801*48a54d36SAndroid Build Coastguard Worker *h_errnop = NETDB_INTERNAL;
802*48a54d36SAndroid Build Coastguard Worker return NSS_STATUS_TRYAGAIN;
803*48a54d36SAndroid Build Coastguard Worker }
804*48a54d36SAndroid Build Coastguard Worker
805*48a54d36SAndroid Build Coastguard Worker if (is_applicable_name (&result, name, lookup_name))
806*48a54d36SAndroid Build Coastguard Worker {
807*48a54d36SAndroid Build Coastguard Worker // Try using mdns
808*48a54d36SAndroid Build Coastguard Worker nss_status rv;
809*48a54d36SAndroid Build Coastguard Worker
810*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
811*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
812*48a54d36SAndroid Build Coastguard Worker "mdns: Local name: %s",
813*48a54d36SAndroid Build Coastguard Worker name
814*48a54d36SAndroid Build Coastguard Worker );
815*48a54d36SAndroid Build Coastguard Worker
816*48a54d36SAndroid Build Coastguard Worker rv = mdns_lookup_name (name, af, &result);
817*48a54d36SAndroid Build Coastguard Worker if (rv == NSS_STATUS_SUCCESS)
818*48a54d36SAndroid Build Coastguard Worker {
819*48a54d36SAndroid Build Coastguard Worker return rv;
820*48a54d36SAndroid Build Coastguard Worker }
821*48a54d36SAndroid Build Coastguard Worker }
822*48a54d36SAndroid Build Coastguard Worker
823*48a54d36SAndroid Build Coastguard Worker // Return current error status (defaults to NOT_FOUND)
824*48a54d36SAndroid Build Coastguard Worker
825*48a54d36SAndroid Build Coastguard Worker *errnop = result.r_errno;
826*48a54d36SAndroid Build Coastguard Worker *h_errnop = result.r_h_errno;
827*48a54d36SAndroid Build Coastguard Worker return result.status;
828*48a54d36SAndroid Build Coastguard Worker }
829*48a54d36SAndroid Build Coastguard Worker
830*48a54d36SAndroid Build Coastguard Worker
831*48a54d36SAndroid Build Coastguard Worker /*
832*48a54d36SAndroid Build Coastguard Worker Lookup a fully qualified hostname using the default record type
833*48a54d36SAndroid Build Coastguard Worker for the specified address family.
834*48a54d36SAndroid Build Coastguard Worker
835*48a54d36SAndroid Build Coastguard Worker Parameters
836*48a54d36SAndroid Build Coastguard Worker fullname
837*48a54d36SAndroid Build Coastguard Worker Fully qualified hostname. If not fully qualified the code will
838*48a54d36SAndroid Build Coastguard Worker still 'work', but the lookup is unlikely to succeed.
839*48a54d36SAndroid Build Coastguard Worker af
840*48a54d36SAndroid Build Coastguard Worker Either AF_INET or AF_INET6. Other families are not supported.
841*48a54d36SAndroid Build Coastguard Worker result
842*48a54d36SAndroid Build Coastguard Worker Initialised 'result' data structure.
843*48a54d36SAndroid Build Coastguard Worker */
844*48a54d36SAndroid Build Coastguard Worker static nss_status
mdns_lookup_name(const char * fullname,int af,result_map_t * result)845*48a54d36SAndroid Build Coastguard Worker mdns_lookup_name (
846*48a54d36SAndroid Build Coastguard Worker const char * fullname,
847*48a54d36SAndroid Build Coastguard Worker int af,
848*48a54d36SAndroid Build Coastguard Worker result_map_t * result
849*48a54d36SAndroid Build Coastguard Worker )
850*48a54d36SAndroid Build Coastguard Worker {
851*48a54d36SAndroid Build Coastguard Worker // Lookup using mDNS.
852*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType errcode;
853*48a54d36SAndroid Build Coastguard Worker DNSServiceRef sdref;
854*48a54d36SAndroid Build Coastguard Worker ns_type_t rrtype;
855*48a54d36SAndroid Build Coastguard Worker nss_status status;
856*48a54d36SAndroid Build Coastguard Worker
857*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
858*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
859*48a54d36SAndroid Build Coastguard Worker "mdns: Attempting lookup of %s",
860*48a54d36SAndroid Build Coastguard Worker fullname
861*48a54d36SAndroid Build Coastguard Worker );
862*48a54d36SAndroid Build Coastguard Worker
863*48a54d36SAndroid Build Coastguard Worker switch (af)
864*48a54d36SAndroid Build Coastguard Worker {
865*48a54d36SAndroid Build Coastguard Worker case AF_INET:
866*48a54d36SAndroid Build Coastguard Worker rrtype = kDNSServiceType_A;
867*48a54d36SAndroid Build Coastguard Worker result->hostent->h_length = 4;
868*48a54d36SAndroid Build Coastguard Worker // Length of an A record
869*48a54d36SAndroid Build Coastguard Worker break;
870*48a54d36SAndroid Build Coastguard Worker
871*48a54d36SAndroid Build Coastguard Worker case AF_INET6:
872*48a54d36SAndroid Build Coastguard Worker rrtype = kDNSServiceType_AAAA;
873*48a54d36SAndroid Build Coastguard Worker result->hostent->h_length = 16;
874*48a54d36SAndroid Build Coastguard Worker // Length of an AAAA record
875*48a54d36SAndroid Build Coastguard Worker break;
876*48a54d36SAndroid Build Coastguard Worker
877*48a54d36SAndroid Build Coastguard Worker default:
878*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
879*48a54d36SAndroid Build Coastguard Worker "mdns: Unsupported address family %d",
880*48a54d36SAndroid Build Coastguard Worker af
881*48a54d36SAndroid Build Coastguard Worker );
882*48a54d36SAndroid Build Coastguard Worker return set_err_bad_hostname (result);
883*48a54d36SAndroid Build Coastguard Worker }
884*48a54d36SAndroid Build Coastguard Worker result->hostent->h_addrtype = af;
885*48a54d36SAndroid Build Coastguard Worker
886*48a54d36SAndroid Build Coastguard Worker errcode =
887*48a54d36SAndroid Build Coastguard Worker DNSServiceQueryRecord (
888*48a54d36SAndroid Build Coastguard Worker &sdref,
889*48a54d36SAndroid Build Coastguard Worker kDNSServiceFlagsForceMulticast, // force multicast query
890*48a54d36SAndroid Build Coastguard Worker kDNSServiceInterfaceIndexAny, // all interfaces
891*48a54d36SAndroid Build Coastguard Worker fullname, // full name to query for
892*48a54d36SAndroid Build Coastguard Worker rrtype, // resource record type
893*48a54d36SAndroid Build Coastguard Worker kDNSServiceClass_IN, // internet class records
894*48a54d36SAndroid Build Coastguard Worker mdns_lookup_callback, // callback
895*48a54d36SAndroid Build Coastguard Worker result // Context - result buffer
896*48a54d36SAndroid Build Coastguard Worker );
897*48a54d36SAndroid Build Coastguard Worker
898*48a54d36SAndroid Build Coastguard Worker if (errcode)
899*48a54d36SAndroid Build Coastguard Worker {
900*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
901*48a54d36SAndroid Build Coastguard Worker "mdns: Failed to initialise lookup, error %d",
902*48a54d36SAndroid Build Coastguard Worker errcode
903*48a54d36SAndroid Build Coastguard Worker );
904*48a54d36SAndroid Build Coastguard Worker return set_err_mdns_failed (result);
905*48a54d36SAndroid Build Coastguard Worker }
906*48a54d36SAndroid Build Coastguard Worker
907*48a54d36SAndroid Build Coastguard Worker status = handle_events (sdref, result, fullname);
908*48a54d36SAndroid Build Coastguard Worker DNSServiceRefDeallocate (sdref);
909*48a54d36SAndroid Build Coastguard Worker return status;
910*48a54d36SAndroid Build Coastguard Worker }
911*48a54d36SAndroid Build Coastguard Worker
912*48a54d36SAndroid Build Coastguard Worker
913*48a54d36SAndroid Build Coastguard Worker /*
914*48a54d36SAndroid Build Coastguard Worker Reverse (PTR) lookup for the specified address.
915*48a54d36SAndroid Build Coastguard Worker
916*48a54d36SAndroid Build Coastguard Worker Parameters
917*48a54d36SAndroid Build Coastguard Worker addr
918*48a54d36SAndroid Build Coastguard Worker Either a struct in_addr or a struct in6_addr
919*48a54d36SAndroid Build Coastguard Worker addr_len
920*48a54d36SAndroid Build Coastguard Worker size of the address
921*48a54d36SAndroid Build Coastguard Worker af
922*48a54d36SAndroid Build Coastguard Worker Either AF_INET or AF_INET6. Other families are not supported.
923*48a54d36SAndroid Build Coastguard Worker Must match addr
924*48a54d36SAndroid Build Coastguard Worker addr_str
925*48a54d36SAndroid Build Coastguard Worker Address in format suitable for PTR lookup.
926*48a54d36SAndroid Build Coastguard Worker AF_INET: a.b.c.d -> d.c.b.a.in-addr.arpa
927*48a54d36SAndroid Build Coastguard Worker AF_INET6: reverse nibble format, x.x.x...x.ip6.arpa
928*48a54d36SAndroid Build Coastguard Worker result
929*48a54d36SAndroid Build Coastguard Worker Initialised 'result' data structure.
930*48a54d36SAndroid Build Coastguard Worker */
931*48a54d36SAndroid Build Coastguard Worker static nss_status
mdns_lookup_addr(const void * addr,socklen_t addr_len,int af,const char * addr_str,result_map_t * result)932*48a54d36SAndroid Build Coastguard Worker mdns_lookup_addr (
933*48a54d36SAndroid Build Coastguard Worker const void * addr,
934*48a54d36SAndroid Build Coastguard Worker socklen_t addr_len,
935*48a54d36SAndroid Build Coastguard Worker int af,
936*48a54d36SAndroid Build Coastguard Worker const char * addr_str,
937*48a54d36SAndroid Build Coastguard Worker result_map_t * result
938*48a54d36SAndroid Build Coastguard Worker )
939*48a54d36SAndroid Build Coastguard Worker {
940*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType errcode;
941*48a54d36SAndroid Build Coastguard Worker DNSServiceRef sdref;
942*48a54d36SAndroid Build Coastguard Worker nss_status status;
943*48a54d36SAndroid Build Coastguard Worker
944*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
945*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
946*48a54d36SAndroid Build Coastguard Worker "mdns: Attempting lookup of %s",
947*48a54d36SAndroid Build Coastguard Worker addr_str
948*48a54d36SAndroid Build Coastguard Worker );
949*48a54d36SAndroid Build Coastguard Worker
950*48a54d36SAndroid Build Coastguard Worker result->hostent->h_addrtype = af;
951*48a54d36SAndroid Build Coastguard Worker result->hostent->h_length = addr_len;
952*48a54d36SAndroid Build Coastguard Worker
953*48a54d36SAndroid Build Coastguard Worker // Query address becomes "address" in result.
954*48a54d36SAndroid Build Coastguard Worker if (! add_address_to_buffer (result, addr, addr_len))
955*48a54d36SAndroid Build Coastguard Worker {
956*48a54d36SAndroid Build Coastguard Worker return result->status;
957*48a54d36SAndroid Build Coastguard Worker }
958*48a54d36SAndroid Build Coastguard Worker
959*48a54d36SAndroid Build Coastguard Worker result->hostent->h_name [0] = 0;
960*48a54d36SAndroid Build Coastguard Worker
961*48a54d36SAndroid Build Coastguard Worker errcode =
962*48a54d36SAndroid Build Coastguard Worker DNSServiceQueryRecord (
963*48a54d36SAndroid Build Coastguard Worker &sdref,
964*48a54d36SAndroid Build Coastguard Worker kDNSServiceFlagsForceMulticast, // force multicast query
965*48a54d36SAndroid Build Coastguard Worker kDNSServiceInterfaceIndexAny, // all interfaces
966*48a54d36SAndroid Build Coastguard Worker addr_str, // address string to query for
967*48a54d36SAndroid Build Coastguard Worker kDNSServiceType_PTR, // pointer RRs
968*48a54d36SAndroid Build Coastguard Worker kDNSServiceClass_IN, // internet class records
969*48a54d36SAndroid Build Coastguard Worker mdns_lookup_callback, // callback
970*48a54d36SAndroid Build Coastguard Worker result // Context - result buffer
971*48a54d36SAndroid Build Coastguard Worker );
972*48a54d36SAndroid Build Coastguard Worker
973*48a54d36SAndroid Build Coastguard Worker if (errcode)
974*48a54d36SAndroid Build Coastguard Worker {
975*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
976*48a54d36SAndroid Build Coastguard Worker "mdns: Failed to initialise mdns lookup, error %d",
977*48a54d36SAndroid Build Coastguard Worker errcode
978*48a54d36SAndroid Build Coastguard Worker );
979*48a54d36SAndroid Build Coastguard Worker return set_err_mdns_failed (result);
980*48a54d36SAndroid Build Coastguard Worker }
981*48a54d36SAndroid Build Coastguard Worker
982*48a54d36SAndroid Build Coastguard Worker status = handle_events (sdref, result, addr_str);
983*48a54d36SAndroid Build Coastguard Worker DNSServiceRefDeallocate (sdref);
984*48a54d36SAndroid Build Coastguard Worker return status;
985*48a54d36SAndroid Build Coastguard Worker }
986*48a54d36SAndroid Build Coastguard Worker
987*48a54d36SAndroid Build Coastguard Worker
988*48a54d36SAndroid Build Coastguard Worker /*
989*48a54d36SAndroid Build Coastguard Worker Wait on result of callback, and process it when it arrives.
990*48a54d36SAndroid Build Coastguard Worker
991*48a54d36SAndroid Build Coastguard Worker Parameters
992*48a54d36SAndroid Build Coastguard Worker sdref
993*48a54d36SAndroid Build Coastguard Worker dns-sd reference
994*48a54d36SAndroid Build Coastguard Worker result
995*48a54d36SAndroid Build Coastguard Worker Initialised 'result' data structure.
996*48a54d36SAndroid Build Coastguard Worker str
997*48a54d36SAndroid Build Coastguard Worker lookup string, used for status/error reporting.
998*48a54d36SAndroid Build Coastguard Worker */
999*48a54d36SAndroid Build Coastguard Worker static nss_status
handle_events(DNSServiceRef sdref,result_map_t * result,const char * str)1000*48a54d36SAndroid Build Coastguard Worker handle_events (DNSServiceRef sdref, result_map_t * result, const char * str)
1001*48a54d36SAndroid Build Coastguard Worker {
1002*48a54d36SAndroid Build Coastguard Worker int dns_sd_fd = DNSServiceRefSockFD(sdref);
1003*48a54d36SAndroid Build Coastguard Worker int nfds = dns_sd_fd + 1;
1004*48a54d36SAndroid Build Coastguard Worker fd_set readfds;
1005*48a54d36SAndroid Build Coastguard Worker struct timeval tv;
1006*48a54d36SAndroid Build Coastguard Worker int select_result;
1007*48a54d36SAndroid Build Coastguard Worker
1008*48a54d36SAndroid Build Coastguard Worker while (! result->done)
1009*48a54d36SAndroid Build Coastguard Worker {
1010*48a54d36SAndroid Build Coastguard Worker FD_ZERO(&readfds);
1011*48a54d36SAndroid Build Coastguard Worker FD_SET(dns_sd_fd, &readfds);
1012*48a54d36SAndroid Build Coastguard Worker
1013*48a54d36SAndroid Build Coastguard Worker tv = k_select_time;
1014*48a54d36SAndroid Build Coastguard Worker
1015*48a54d36SAndroid Build Coastguard Worker select_result =
1016*48a54d36SAndroid Build Coastguard Worker select (nfds, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tv);
1017*48a54d36SAndroid Build Coastguard Worker if (select_result > 0)
1018*48a54d36SAndroid Build Coastguard Worker {
1019*48a54d36SAndroid Build Coastguard Worker if (FD_ISSET(dns_sd_fd, &readfds))
1020*48a54d36SAndroid Build Coastguard Worker {
1021*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
1022*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
1023*48a54d36SAndroid Build Coastguard Worker "mdns: Reply received for %s",
1024*48a54d36SAndroid Build Coastguard Worker str
1025*48a54d36SAndroid Build Coastguard Worker );
1026*48a54d36SAndroid Build Coastguard Worker DNSServiceProcessResult(sdref);
1027*48a54d36SAndroid Build Coastguard Worker }
1028*48a54d36SAndroid Build Coastguard Worker else
1029*48a54d36SAndroid Build Coastguard Worker {
1030*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1031*48a54d36SAndroid Build Coastguard Worker "mdns: Unexpected return from select on lookup of %s",
1032*48a54d36SAndroid Build Coastguard Worker str
1033*48a54d36SAndroid Build Coastguard Worker );
1034*48a54d36SAndroid Build Coastguard Worker }
1035*48a54d36SAndroid Build Coastguard Worker }
1036*48a54d36SAndroid Build Coastguard Worker else
1037*48a54d36SAndroid Build Coastguard Worker {
1038*48a54d36SAndroid Build Coastguard Worker // Terminate loop due to timer expiry
1039*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
1040*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
1041*48a54d36SAndroid Build Coastguard Worker "mdns: %s not found - timer expired",
1042*48a54d36SAndroid Build Coastguard Worker str
1043*48a54d36SAndroid Build Coastguard Worker );
1044*48a54d36SAndroid Build Coastguard Worker set_err_notfound (result);
1045*48a54d36SAndroid Build Coastguard Worker break;
1046*48a54d36SAndroid Build Coastguard Worker }
1047*48a54d36SAndroid Build Coastguard Worker }
1048*48a54d36SAndroid Build Coastguard Worker
1049*48a54d36SAndroid Build Coastguard Worker return result->status;
1050*48a54d36SAndroid Build Coastguard Worker }
1051*48a54d36SAndroid Build Coastguard Worker
1052*48a54d36SAndroid Build Coastguard Worker
1053*48a54d36SAndroid Build Coastguard Worker /*
1054*48a54d36SAndroid Build Coastguard Worker Examine incoming data and add to relevant fields in result structure.
1055*48a54d36SAndroid Build Coastguard Worker This routine is called from DNSServiceProcessResult where appropriate.
1056*48a54d36SAndroid Build Coastguard Worker */
1057*48a54d36SAndroid Build Coastguard Worker void
mdns_lookup_callback(DNSServiceRef sdref,DNSServiceFlags flags,uint32_t interface_index,DNSServiceErrorType error_code,const char * fullname,uint16_t rrtype,uint16_t rrclass,uint16_t rdlen,const void * rdata,uint32_t ttl,void * context)1058*48a54d36SAndroid Build Coastguard Worker mdns_lookup_callback
1059*48a54d36SAndroid Build Coastguard Worker (
1060*48a54d36SAndroid Build Coastguard Worker DNSServiceRef sdref,
1061*48a54d36SAndroid Build Coastguard Worker DNSServiceFlags flags,
1062*48a54d36SAndroid Build Coastguard Worker uint32_t interface_index,
1063*48a54d36SAndroid Build Coastguard Worker DNSServiceErrorType error_code,
1064*48a54d36SAndroid Build Coastguard Worker const char *fullname,
1065*48a54d36SAndroid Build Coastguard Worker uint16_t rrtype,
1066*48a54d36SAndroid Build Coastguard Worker uint16_t rrclass,
1067*48a54d36SAndroid Build Coastguard Worker uint16_t rdlen,
1068*48a54d36SAndroid Build Coastguard Worker const void *rdata,
1069*48a54d36SAndroid Build Coastguard Worker uint32_t ttl,
1070*48a54d36SAndroid Build Coastguard Worker void *context
1071*48a54d36SAndroid Build Coastguard Worker )
1072*48a54d36SAndroid Build Coastguard Worker {
1073*48a54d36SAndroid Build Coastguard Worker // A single record is received
1074*48a54d36SAndroid Build Coastguard Worker
1075*48a54d36SAndroid Build Coastguard Worker result_map_t * result = (result_map_t *) context;
1076*48a54d36SAndroid Build Coastguard Worker
1077*48a54d36SAndroid Build Coastguard Worker (void)sdref; // Unused
1078*48a54d36SAndroid Build Coastguard Worker (void)interface_index; // Unused
1079*48a54d36SAndroid Build Coastguard Worker (void)ttl; // Unused
1080*48a54d36SAndroid Build Coastguard Worker
1081*48a54d36SAndroid Build Coastguard Worker if (! (flags & kDNSServiceFlagsMoreComing) )
1082*48a54d36SAndroid Build Coastguard Worker {
1083*48a54d36SAndroid Build Coastguard Worker result->done = 1;
1084*48a54d36SAndroid Build Coastguard Worker }
1085*48a54d36SAndroid Build Coastguard Worker
1086*48a54d36SAndroid Build Coastguard Worker if (error_code == kDNSServiceErr_NoError)
1087*48a54d36SAndroid Build Coastguard Worker {
1088*48a54d36SAndroid Build Coastguard Worker ns_type_t expected_rr_type =
1089*48a54d36SAndroid Build Coastguard Worker af_to_rr (result->hostent->h_addrtype);
1090*48a54d36SAndroid Build Coastguard Worker
1091*48a54d36SAndroid Build Coastguard Worker // Idiot check class
1092*48a54d36SAndroid Build Coastguard Worker if (rrclass != C_IN)
1093*48a54d36SAndroid Build Coastguard Worker {
1094*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1095*48a54d36SAndroid Build Coastguard Worker "mdns: Received bad RR class: expected %d (%s),"
1096*48a54d36SAndroid Build Coastguard Worker " got %d (%s), RR type %d (%s)",
1097*48a54d36SAndroid Build Coastguard Worker C_IN,
1098*48a54d36SAndroid Build Coastguard Worker ns_class_to_str (C_IN),
1099*48a54d36SAndroid Build Coastguard Worker rrclass,
1100*48a54d36SAndroid Build Coastguard Worker ns_class_to_str (rrclass),
1101*48a54d36SAndroid Build Coastguard Worker rrtype,
1102*48a54d36SAndroid Build Coastguard Worker ns_type_to_str (rrtype)
1103*48a54d36SAndroid Build Coastguard Worker );
1104*48a54d36SAndroid Build Coastguard Worker return;
1105*48a54d36SAndroid Build Coastguard Worker }
1106*48a54d36SAndroid Build Coastguard Worker
1107*48a54d36SAndroid Build Coastguard Worker // If a PTR
1108*48a54d36SAndroid Build Coastguard Worker if (rrtype == kDNSServiceType_PTR)
1109*48a54d36SAndroid Build Coastguard Worker {
1110*48a54d36SAndroid Build Coastguard Worker if (callback_body_ptr (fullname, result, rdlen, rdata) < 0)
1111*48a54d36SAndroid Build Coastguard Worker return;
1112*48a54d36SAndroid Build Coastguard Worker }
1113*48a54d36SAndroid Build Coastguard Worker else if (rrtype == expected_rr_type)
1114*48a54d36SAndroid Build Coastguard Worker {
1115*48a54d36SAndroid Build Coastguard Worker if (!
1116*48a54d36SAndroid Build Coastguard Worker add_hostname_or_alias (
1117*48a54d36SAndroid Build Coastguard Worker result,
1118*48a54d36SAndroid Build Coastguard Worker fullname,
1119*48a54d36SAndroid Build Coastguard Worker strlen (fullname)
1120*48a54d36SAndroid Build Coastguard Worker )
1121*48a54d36SAndroid Build Coastguard Worker )
1122*48a54d36SAndroid Build Coastguard Worker {
1123*48a54d36SAndroid Build Coastguard Worker result->done = 1;
1124*48a54d36SAndroid Build Coastguard Worker return;
1125*48a54d36SAndroid Build Coastguard Worker // Abort on error
1126*48a54d36SAndroid Build Coastguard Worker }
1127*48a54d36SAndroid Build Coastguard Worker
1128*48a54d36SAndroid Build Coastguard Worker if (! add_address_to_buffer (result, rdata, rdlen) )
1129*48a54d36SAndroid Build Coastguard Worker {
1130*48a54d36SAndroid Build Coastguard Worker result->done = 1;
1131*48a54d36SAndroid Build Coastguard Worker return;
1132*48a54d36SAndroid Build Coastguard Worker // Abort on error
1133*48a54d36SAndroid Build Coastguard Worker }
1134*48a54d36SAndroid Build Coastguard Worker }
1135*48a54d36SAndroid Build Coastguard Worker else
1136*48a54d36SAndroid Build Coastguard Worker {
1137*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1138*48a54d36SAndroid Build Coastguard Worker "mdns: Received bad RR type: expected %d (%s),"
1139*48a54d36SAndroid Build Coastguard Worker " got %d (%s)",
1140*48a54d36SAndroid Build Coastguard Worker expected_rr_type,
1141*48a54d36SAndroid Build Coastguard Worker ns_type_to_str (expected_rr_type),
1142*48a54d36SAndroid Build Coastguard Worker rrtype,
1143*48a54d36SAndroid Build Coastguard Worker ns_type_to_str (rrtype)
1144*48a54d36SAndroid Build Coastguard Worker );
1145*48a54d36SAndroid Build Coastguard Worker return;
1146*48a54d36SAndroid Build Coastguard Worker }
1147*48a54d36SAndroid Build Coastguard Worker
1148*48a54d36SAndroid Build Coastguard Worker if (result->status != NSS_STATUS_SUCCESS)
1149*48a54d36SAndroid Build Coastguard Worker set_err_success (result);
1150*48a54d36SAndroid Build Coastguard Worker }
1151*48a54d36SAndroid Build Coastguard Worker else
1152*48a54d36SAndroid Build Coastguard Worker {
1153*48a54d36SAndroid Build Coastguard Worker // For now, dump message to syslog and continue
1154*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1155*48a54d36SAndroid Build Coastguard Worker "mdns: callback returned error %d",
1156*48a54d36SAndroid Build Coastguard Worker error_code
1157*48a54d36SAndroid Build Coastguard Worker );
1158*48a54d36SAndroid Build Coastguard Worker }
1159*48a54d36SAndroid Build Coastguard Worker }
1160*48a54d36SAndroid Build Coastguard Worker
1161*48a54d36SAndroid Build Coastguard Worker static int
callback_body_ptr(const char * fullname,result_map_t * result,int rdlen,const void * rdata)1162*48a54d36SAndroid Build Coastguard Worker callback_body_ptr (
1163*48a54d36SAndroid Build Coastguard Worker const char * fullname,
1164*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
1165*48a54d36SAndroid Build Coastguard Worker int rdlen,
1166*48a54d36SAndroid Build Coastguard Worker const void * rdata
1167*48a54d36SAndroid Build Coastguard Worker )
1168*48a54d36SAndroid Build Coastguard Worker {
1169*48a54d36SAndroid Build Coastguard Worker char result_name [k_hostname_maxlen + 1];
1170*48a54d36SAndroid Build Coastguard Worker int rv;
1171*48a54d36SAndroid Build Coastguard Worker
1172*48a54d36SAndroid Build Coastguard Worker // Fullname should be .in-addr.arpa or equivalent, which we're
1173*48a54d36SAndroid Build Coastguard Worker // not interested in. Ignore it.
1174*48a54d36SAndroid Build Coastguard Worker
1175*48a54d36SAndroid Build Coastguard Worker rv = dns_rdata_to_name (rdata, rdlen, result_name, k_hostname_maxlen);
1176*48a54d36SAndroid Build Coastguard Worker if (rv < 0)
1177*48a54d36SAndroid Build Coastguard Worker {
1178*48a54d36SAndroid Build Coastguard Worker const char * errmsg;
1179*48a54d36SAndroid Build Coastguard Worker
1180*48a54d36SAndroid Build Coastguard Worker switch (rv)
1181*48a54d36SAndroid Build Coastguard Worker {
1182*48a54d36SAndroid Build Coastguard Worker case DNS_RDATA_TO_NAME_BAD_FORMAT:
1183*48a54d36SAndroid Build Coastguard Worker errmsg = "mdns: PTR '%s' result badly formatted ('%s...')";
1184*48a54d36SAndroid Build Coastguard Worker break;
1185*48a54d36SAndroid Build Coastguard Worker
1186*48a54d36SAndroid Build Coastguard Worker case DNS_RDATA_TO_NAME_TOO_LONG:
1187*48a54d36SAndroid Build Coastguard Worker errmsg = "mdns: PTR '%s' result too long ('%s...')";
1188*48a54d36SAndroid Build Coastguard Worker break;
1189*48a54d36SAndroid Build Coastguard Worker
1190*48a54d36SAndroid Build Coastguard Worker case DNS_RDATA_TO_NAME_PTR:
1191*48a54d36SAndroid Build Coastguard Worker errmsg = "mdns: PTR '%s' result contained pointer ('%s...')";
1192*48a54d36SAndroid Build Coastguard Worker break;
1193*48a54d36SAndroid Build Coastguard Worker
1194*48a54d36SAndroid Build Coastguard Worker default:
1195*48a54d36SAndroid Build Coastguard Worker errmsg = "mdns: PTR '%s' result conversion failed ('%s...')";
1196*48a54d36SAndroid Build Coastguard Worker }
1197*48a54d36SAndroid Build Coastguard Worker
1198*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1199*48a54d36SAndroid Build Coastguard Worker errmsg,
1200*48a54d36SAndroid Build Coastguard Worker fullname,
1201*48a54d36SAndroid Build Coastguard Worker result_name
1202*48a54d36SAndroid Build Coastguard Worker );
1203*48a54d36SAndroid Build Coastguard Worker
1204*48a54d36SAndroid Build Coastguard Worker return -1;
1205*48a54d36SAndroid Build Coastguard Worker }
1206*48a54d36SAndroid Build Coastguard Worker
1207*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
1208*48a54d36SAndroid Build Coastguard Worker {
1209*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
1210*48a54d36SAndroid Build Coastguard Worker "mdns: PTR '%s' resolved to '%s'",
1211*48a54d36SAndroid Build Coastguard Worker fullname,
1212*48a54d36SAndroid Build Coastguard Worker result_name
1213*48a54d36SAndroid Build Coastguard Worker );
1214*48a54d36SAndroid Build Coastguard Worker }
1215*48a54d36SAndroid Build Coastguard Worker
1216*48a54d36SAndroid Build Coastguard Worker // Data should be a hostname
1217*48a54d36SAndroid Build Coastguard Worker if (!
1218*48a54d36SAndroid Build Coastguard Worker add_hostname_or_alias (
1219*48a54d36SAndroid Build Coastguard Worker result,
1220*48a54d36SAndroid Build Coastguard Worker result_name,
1221*48a54d36SAndroid Build Coastguard Worker rv
1222*48a54d36SAndroid Build Coastguard Worker )
1223*48a54d36SAndroid Build Coastguard Worker )
1224*48a54d36SAndroid Build Coastguard Worker {
1225*48a54d36SAndroid Build Coastguard Worker result->done = 1;
1226*48a54d36SAndroid Build Coastguard Worker return -1;
1227*48a54d36SAndroid Build Coastguard Worker }
1228*48a54d36SAndroid Build Coastguard Worker
1229*48a54d36SAndroid Build Coastguard Worker return 0;
1230*48a54d36SAndroid Build Coastguard Worker }
1231*48a54d36SAndroid Build Coastguard Worker
1232*48a54d36SAndroid Build Coastguard Worker
1233*48a54d36SAndroid Build Coastguard Worker /*
1234*48a54d36SAndroid Build Coastguard Worker Add an address to the buffer.
1235*48a54d36SAndroid Build Coastguard Worker
1236*48a54d36SAndroid Build Coastguard Worker Parameter
1237*48a54d36SAndroid Build Coastguard Worker result
1238*48a54d36SAndroid Build Coastguard Worker Result structure to write to
1239*48a54d36SAndroid Build Coastguard Worker data
1240*48a54d36SAndroid Build Coastguard Worker Incoming address data buffer
1241*48a54d36SAndroid Build Coastguard Worker Must be 'int' aligned
1242*48a54d36SAndroid Build Coastguard Worker len
1243*48a54d36SAndroid Build Coastguard Worker Length of data buffer (in bytes)
1244*48a54d36SAndroid Build Coastguard Worker Must match data alignment
1245*48a54d36SAndroid Build Coastguard Worker
1246*48a54d36SAndroid Build Coastguard Worker Result
1247*48a54d36SAndroid Build Coastguard Worker Pointer to start of newly written data,
1248*48a54d36SAndroid Build Coastguard Worker or NULL on error.
1249*48a54d36SAndroid Build Coastguard Worker If address already exists in buffer, returns pointer to that instead.
1250*48a54d36SAndroid Build Coastguard Worker */
1251*48a54d36SAndroid Build Coastguard Worker static void *
add_address_to_buffer(result_map_t * result,const void * data,int len)1252*48a54d36SAndroid Build Coastguard Worker add_address_to_buffer (result_map_t * result, const void * data, int len)
1253*48a54d36SAndroid Build Coastguard Worker {
1254*48a54d36SAndroid Build Coastguard Worker int new_addr;
1255*48a54d36SAndroid Build Coastguard Worker void * start;
1256*48a54d36SAndroid Build Coastguard Worker void * temp;
1257*48a54d36SAndroid Build Coastguard Worker
1258*48a54d36SAndroid Build Coastguard Worker if ((temp = contains_address (result, data, len)))
1259*48a54d36SAndroid Build Coastguard Worker {
1260*48a54d36SAndroid Build Coastguard Worker return temp;
1261*48a54d36SAndroid Build Coastguard Worker }
1262*48a54d36SAndroid Build Coastguard Worker
1263*48a54d36SAndroid Build Coastguard Worker if (result->addrs_count >= k_addrs_max)
1264*48a54d36SAndroid Build Coastguard Worker {
1265*48a54d36SAndroid Build Coastguard Worker // Not enough addr slots
1266*48a54d36SAndroid Build Coastguard Worker set_err_internal_resource_full (result);
1267*48a54d36SAndroid Build Coastguard Worker syslog (LOG_ERR,
1268*48a54d36SAndroid Build Coastguard Worker "mdns: Internal address buffer full; increase size"
1269*48a54d36SAndroid Build Coastguard Worker );
1270*48a54d36SAndroid Build Coastguard Worker return NULL;
1271*48a54d36SAndroid Build Coastguard Worker }
1272*48a54d36SAndroid Build Coastguard Worker
1273*48a54d36SAndroid Build Coastguard Worker // Idiot check
1274*48a54d36SAndroid Build Coastguard Worker if (len != result->hostent->h_length)
1275*48a54d36SAndroid Build Coastguard Worker {
1276*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1277*48a54d36SAndroid Build Coastguard Worker "mdns: Unexpected rdata length for address. Expected %d, got %d",
1278*48a54d36SAndroid Build Coastguard Worker result->hostent->h_length,
1279*48a54d36SAndroid Build Coastguard Worker len
1280*48a54d36SAndroid Build Coastguard Worker );
1281*48a54d36SAndroid Build Coastguard Worker // XXX And continue for now.
1282*48a54d36SAndroid Build Coastguard Worker }
1283*48a54d36SAndroid Build Coastguard Worker
1284*48a54d36SAndroid Build Coastguard Worker new_addr = result->addr_idx + len;
1285*48a54d36SAndroid Build Coastguard Worker
1286*48a54d36SAndroid Build Coastguard Worker if (new_addr > result->alias_idx)
1287*48a54d36SAndroid Build Coastguard Worker {
1288*48a54d36SAndroid Build Coastguard Worker // Not enough room
1289*48a54d36SAndroid Build Coastguard Worker set_err_buf_too_small (result);
1290*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
1291*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
1292*48a54d36SAndroid Build Coastguard Worker "mdns: Ran out of buffer when adding address %d",
1293*48a54d36SAndroid Build Coastguard Worker result->addrs_count + 1
1294*48a54d36SAndroid Build Coastguard Worker );
1295*48a54d36SAndroid Build Coastguard Worker return NULL;
1296*48a54d36SAndroid Build Coastguard Worker }
1297*48a54d36SAndroid Build Coastguard Worker
1298*48a54d36SAndroid Build Coastguard Worker start = result->buffer + result->addr_idx;
1299*48a54d36SAndroid Build Coastguard Worker memcpy (start, data, len);
1300*48a54d36SAndroid Build Coastguard Worker result->addr_idx = new_addr;
1301*48a54d36SAndroid Build Coastguard Worker result->header->addrs [result->addrs_count] = start;
1302*48a54d36SAndroid Build Coastguard Worker result->addrs_count ++;
1303*48a54d36SAndroid Build Coastguard Worker result->header->addrs [result->addrs_count] = NULL;
1304*48a54d36SAndroid Build Coastguard Worker
1305*48a54d36SAndroid Build Coastguard Worker return start;
1306*48a54d36SAndroid Build Coastguard Worker }
1307*48a54d36SAndroid Build Coastguard Worker
1308*48a54d36SAndroid Build Coastguard Worker
1309*48a54d36SAndroid Build Coastguard Worker static void *
contains_address(result_map_t * result,const void * data,int len)1310*48a54d36SAndroid Build Coastguard Worker contains_address (result_map_t * result, const void * data, int len)
1311*48a54d36SAndroid Build Coastguard Worker {
1312*48a54d36SAndroid Build Coastguard Worker int i;
1313*48a54d36SAndroid Build Coastguard Worker
1314*48a54d36SAndroid Build Coastguard Worker // Idiot check
1315*48a54d36SAndroid Build Coastguard Worker if (len != result->hostent->h_length)
1316*48a54d36SAndroid Build Coastguard Worker {
1317*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1318*48a54d36SAndroid Build Coastguard Worker "mdns: Unexpected rdata length for address. Expected %d, got %d",
1319*48a54d36SAndroid Build Coastguard Worker result->hostent->h_length,
1320*48a54d36SAndroid Build Coastguard Worker len
1321*48a54d36SAndroid Build Coastguard Worker );
1322*48a54d36SAndroid Build Coastguard Worker // XXX And continue for now.
1323*48a54d36SAndroid Build Coastguard Worker }
1324*48a54d36SAndroid Build Coastguard Worker
1325*48a54d36SAndroid Build Coastguard Worker for (i = 0; result->header->addrs [i]; i++)
1326*48a54d36SAndroid Build Coastguard Worker {
1327*48a54d36SAndroid Build Coastguard Worker if (memcmp (result->header->addrs [i], data, len) == 0)
1328*48a54d36SAndroid Build Coastguard Worker {
1329*48a54d36SAndroid Build Coastguard Worker return result->header->addrs [i];
1330*48a54d36SAndroid Build Coastguard Worker }
1331*48a54d36SAndroid Build Coastguard Worker }
1332*48a54d36SAndroid Build Coastguard Worker
1333*48a54d36SAndroid Build Coastguard Worker return NULL;
1334*48a54d36SAndroid Build Coastguard Worker }
1335*48a54d36SAndroid Build Coastguard Worker
1336*48a54d36SAndroid Build Coastguard Worker
1337*48a54d36SAndroid Build Coastguard Worker /*
1338*48a54d36SAndroid Build Coastguard Worker Add an alias to the buffer.
1339*48a54d36SAndroid Build Coastguard Worker
1340*48a54d36SAndroid Build Coastguard Worker Parameter
1341*48a54d36SAndroid Build Coastguard Worker result
1342*48a54d36SAndroid Build Coastguard Worker Result structure to write to
1343*48a54d36SAndroid Build Coastguard Worker data
1344*48a54d36SAndroid Build Coastguard Worker Incoming alias (null terminated)
1345*48a54d36SAndroid Build Coastguard Worker len
1346*48a54d36SAndroid Build Coastguard Worker Length of data buffer (in bytes), including trailing null
1347*48a54d36SAndroid Build Coastguard Worker
1348*48a54d36SAndroid Build Coastguard Worker Result
1349*48a54d36SAndroid Build Coastguard Worker Pointer to start of newly written data,
1350*48a54d36SAndroid Build Coastguard Worker or NULL on error
1351*48a54d36SAndroid Build Coastguard Worker If alias already exists in buffer, returns pointer to that instead.
1352*48a54d36SAndroid Build Coastguard Worker */
1353*48a54d36SAndroid Build Coastguard Worker static char *
add_alias_to_buffer(result_map_t * result,const char * data,int len)1354*48a54d36SAndroid Build Coastguard Worker add_alias_to_buffer (result_map_t * result, const char * data, int len)
1355*48a54d36SAndroid Build Coastguard Worker {
1356*48a54d36SAndroid Build Coastguard Worker int new_alias;
1357*48a54d36SAndroid Build Coastguard Worker char * start;
1358*48a54d36SAndroid Build Coastguard Worker char * temp;
1359*48a54d36SAndroid Build Coastguard Worker
1360*48a54d36SAndroid Build Coastguard Worker if ((temp = contains_alias (result, data)))
1361*48a54d36SAndroid Build Coastguard Worker {
1362*48a54d36SAndroid Build Coastguard Worker return temp;
1363*48a54d36SAndroid Build Coastguard Worker }
1364*48a54d36SAndroid Build Coastguard Worker
1365*48a54d36SAndroid Build Coastguard Worker if (result->aliases_count >= k_aliases_max)
1366*48a54d36SAndroid Build Coastguard Worker {
1367*48a54d36SAndroid Build Coastguard Worker // Not enough alias slots
1368*48a54d36SAndroid Build Coastguard Worker set_err_internal_resource_full (result);
1369*48a54d36SAndroid Build Coastguard Worker syslog (LOG_ERR,
1370*48a54d36SAndroid Build Coastguard Worker "mdns: Internal alias buffer full; increase size"
1371*48a54d36SAndroid Build Coastguard Worker );
1372*48a54d36SAndroid Build Coastguard Worker return NULL;
1373*48a54d36SAndroid Build Coastguard Worker }
1374*48a54d36SAndroid Build Coastguard Worker
1375*48a54d36SAndroid Build Coastguard Worker new_alias = result->alias_idx - len;
1376*48a54d36SAndroid Build Coastguard Worker
1377*48a54d36SAndroid Build Coastguard Worker if (new_alias < result->addr_idx)
1378*48a54d36SAndroid Build Coastguard Worker {
1379*48a54d36SAndroid Build Coastguard Worker // Not enough room
1380*48a54d36SAndroid Build Coastguard Worker set_err_buf_too_small (result);
1381*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
1382*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
1383*48a54d36SAndroid Build Coastguard Worker "mdns: Ran out of buffer when adding alias %d",
1384*48a54d36SAndroid Build Coastguard Worker result->aliases_count + 1
1385*48a54d36SAndroid Build Coastguard Worker );
1386*48a54d36SAndroid Build Coastguard Worker return NULL;
1387*48a54d36SAndroid Build Coastguard Worker }
1388*48a54d36SAndroid Build Coastguard Worker
1389*48a54d36SAndroid Build Coastguard Worker start = result->buffer + new_alias;
1390*48a54d36SAndroid Build Coastguard Worker memcpy (start, data, len);
1391*48a54d36SAndroid Build Coastguard Worker result->alias_idx = new_alias;
1392*48a54d36SAndroid Build Coastguard Worker result->header->aliases [result->aliases_count] = start;
1393*48a54d36SAndroid Build Coastguard Worker result->aliases_count ++;
1394*48a54d36SAndroid Build Coastguard Worker result->header->aliases [result->aliases_count] = NULL;
1395*48a54d36SAndroid Build Coastguard Worker
1396*48a54d36SAndroid Build Coastguard Worker return start;
1397*48a54d36SAndroid Build Coastguard Worker }
1398*48a54d36SAndroid Build Coastguard Worker
1399*48a54d36SAndroid Build Coastguard Worker
1400*48a54d36SAndroid Build Coastguard Worker static char *
contains_alias(result_map_t * result,const char * alias)1401*48a54d36SAndroid Build Coastguard Worker contains_alias (result_map_t * result, const char * alias)
1402*48a54d36SAndroid Build Coastguard Worker {
1403*48a54d36SAndroid Build Coastguard Worker int i;
1404*48a54d36SAndroid Build Coastguard Worker
1405*48a54d36SAndroid Build Coastguard Worker for (i = 0; result->header->aliases [i]; i++)
1406*48a54d36SAndroid Build Coastguard Worker {
1407*48a54d36SAndroid Build Coastguard Worker if (strcmp (result->header->aliases [i], alias) == 0)
1408*48a54d36SAndroid Build Coastguard Worker {
1409*48a54d36SAndroid Build Coastguard Worker return result->header->aliases [i];
1410*48a54d36SAndroid Build Coastguard Worker }
1411*48a54d36SAndroid Build Coastguard Worker }
1412*48a54d36SAndroid Build Coastguard Worker
1413*48a54d36SAndroid Build Coastguard Worker return NULL;
1414*48a54d36SAndroid Build Coastguard Worker }
1415*48a54d36SAndroid Build Coastguard Worker
1416*48a54d36SAndroid Build Coastguard Worker
1417*48a54d36SAndroid Build Coastguard Worker /*
1418*48a54d36SAndroid Build Coastguard Worker Add fully qualified hostname to result.
1419*48a54d36SAndroid Build Coastguard Worker
1420*48a54d36SAndroid Build Coastguard Worker Parameter
1421*48a54d36SAndroid Build Coastguard Worker result
1422*48a54d36SAndroid Build Coastguard Worker Result structure to write to
1423*48a54d36SAndroid Build Coastguard Worker fullname
1424*48a54d36SAndroid Build Coastguard Worker Fully qualified hostname
1425*48a54d36SAndroid Build Coastguard Worker
1426*48a54d36SAndroid Build Coastguard Worker Result
1427*48a54d36SAndroid Build Coastguard Worker Pointer to start of hostname buffer,
1428*48a54d36SAndroid Build Coastguard Worker or NULL on error (usually hostname too long)
1429*48a54d36SAndroid Build Coastguard Worker */
1430*48a54d36SAndroid Build Coastguard Worker
1431*48a54d36SAndroid Build Coastguard Worker static char *
add_hostname_len(result_map_t * result,const char * fullname,int len)1432*48a54d36SAndroid Build Coastguard Worker add_hostname_len (result_map_t * result, const char * fullname, int len)
1433*48a54d36SAndroid Build Coastguard Worker {
1434*48a54d36SAndroid Build Coastguard Worker if (len >= k_hostname_maxlen)
1435*48a54d36SAndroid Build Coastguard Worker {
1436*48a54d36SAndroid Build Coastguard Worker set_err_bad_hostname (result);
1437*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1438*48a54d36SAndroid Build Coastguard Worker "mdns: Hostname too long '%.*s': len %d, max %d",
1439*48a54d36SAndroid Build Coastguard Worker len,
1440*48a54d36SAndroid Build Coastguard Worker fullname,
1441*48a54d36SAndroid Build Coastguard Worker len,
1442*48a54d36SAndroid Build Coastguard Worker k_hostname_maxlen
1443*48a54d36SAndroid Build Coastguard Worker );
1444*48a54d36SAndroid Build Coastguard Worker return NULL;
1445*48a54d36SAndroid Build Coastguard Worker }
1446*48a54d36SAndroid Build Coastguard Worker
1447*48a54d36SAndroid Build Coastguard Worker result->hostent->h_name =
1448*48a54d36SAndroid Build Coastguard Worker strcpy (result->header->hostname, fullname);
1449*48a54d36SAndroid Build Coastguard Worker
1450*48a54d36SAndroid Build Coastguard Worker return result->header->hostname;
1451*48a54d36SAndroid Build Coastguard Worker }
1452*48a54d36SAndroid Build Coastguard Worker
1453*48a54d36SAndroid Build Coastguard Worker
1454*48a54d36SAndroid Build Coastguard Worker /*
1455*48a54d36SAndroid Build Coastguard Worker Add fully qualified name as hostname or alias.
1456*48a54d36SAndroid Build Coastguard Worker
1457*48a54d36SAndroid Build Coastguard Worker If hostname is not fully qualified this is not an error, but the data
1458*48a54d36SAndroid Build Coastguard Worker returned may be not what the application wanted.
1459*48a54d36SAndroid Build Coastguard Worker
1460*48a54d36SAndroid Build Coastguard Worker Parameter
1461*48a54d36SAndroid Build Coastguard Worker result
1462*48a54d36SAndroid Build Coastguard Worker Result structure to write to
1463*48a54d36SAndroid Build Coastguard Worker data
1464*48a54d36SAndroid Build Coastguard Worker Incoming alias (null terminated)
1465*48a54d36SAndroid Build Coastguard Worker len
1466*48a54d36SAndroid Build Coastguard Worker Length of data buffer (in bytes), including trailing null
1467*48a54d36SAndroid Build Coastguard Worker
1468*48a54d36SAndroid Build Coastguard Worker Result
1469*48a54d36SAndroid Build Coastguard Worker Pointer to start of newly written data,
1470*48a54d36SAndroid Build Coastguard Worker or NULL on error
1471*48a54d36SAndroid Build Coastguard Worker If alias or hostname already exists, returns pointer to that instead.
1472*48a54d36SAndroid Build Coastguard Worker */
1473*48a54d36SAndroid Build Coastguard Worker static char *
add_hostname_or_alias(result_map_t * result,const char * data,int len)1474*48a54d36SAndroid Build Coastguard Worker add_hostname_or_alias (result_map_t * result, const char * data, int len)
1475*48a54d36SAndroid Build Coastguard Worker {
1476*48a54d36SAndroid Build Coastguard Worker char * hostname = result->hostent->h_name;
1477*48a54d36SAndroid Build Coastguard Worker
1478*48a54d36SAndroid Build Coastguard Worker if (*hostname)
1479*48a54d36SAndroid Build Coastguard Worker {
1480*48a54d36SAndroid Build Coastguard Worker if (strcmp (hostname, data) == 0)
1481*48a54d36SAndroid Build Coastguard Worker {
1482*48a54d36SAndroid Build Coastguard Worker return hostname;
1483*48a54d36SAndroid Build Coastguard Worker }
1484*48a54d36SAndroid Build Coastguard Worker else
1485*48a54d36SAndroid Build Coastguard Worker {
1486*48a54d36SAndroid Build Coastguard Worker return add_alias_to_buffer (result, data, len);
1487*48a54d36SAndroid Build Coastguard Worker }
1488*48a54d36SAndroid Build Coastguard Worker }
1489*48a54d36SAndroid Build Coastguard Worker else
1490*48a54d36SAndroid Build Coastguard Worker {
1491*48a54d36SAndroid Build Coastguard Worker return add_hostname_len (result, data, len);
1492*48a54d36SAndroid Build Coastguard Worker }
1493*48a54d36SAndroid Build Coastguard Worker }
1494*48a54d36SAndroid Build Coastguard Worker
1495*48a54d36SAndroid Build Coastguard Worker
1496*48a54d36SAndroid Build Coastguard Worker static int
init_result(result_map_t * result,hostent * result_buf,char * buf,size_t buflen)1497*48a54d36SAndroid Build Coastguard Worker init_result (
1498*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
1499*48a54d36SAndroid Build Coastguard Worker hostent * result_buf,
1500*48a54d36SAndroid Build Coastguard Worker char * buf,
1501*48a54d36SAndroid Build Coastguard Worker size_t buflen
1502*48a54d36SAndroid Build Coastguard Worker )
1503*48a54d36SAndroid Build Coastguard Worker {
1504*48a54d36SAndroid Build Coastguard Worker if (buflen < sizeof (buf_header_t))
1505*48a54d36SAndroid Build Coastguard Worker {
1506*48a54d36SAndroid Build Coastguard Worker return ERANGE;
1507*48a54d36SAndroid Build Coastguard Worker }
1508*48a54d36SAndroid Build Coastguard Worker
1509*48a54d36SAndroid Build Coastguard Worker result->hostent = result_buf;
1510*48a54d36SAndroid Build Coastguard Worker result->header = (buf_header_t *) buf;
1511*48a54d36SAndroid Build Coastguard Worker result->header->hostname[0] = 0;
1512*48a54d36SAndroid Build Coastguard Worker result->aliases_count = 0;
1513*48a54d36SAndroid Build Coastguard Worker result->header->aliases[0] = NULL;
1514*48a54d36SAndroid Build Coastguard Worker result->addrs_count = 0;
1515*48a54d36SAndroid Build Coastguard Worker result->header->addrs[0] = NULL;
1516*48a54d36SAndroid Build Coastguard Worker result->buffer = buf + sizeof (buf_header_t);
1517*48a54d36SAndroid Build Coastguard Worker result->addr_idx = 0;
1518*48a54d36SAndroid Build Coastguard Worker result->alias_idx = buflen - sizeof (buf_header_t);
1519*48a54d36SAndroid Build Coastguard Worker result->done = 0;
1520*48a54d36SAndroid Build Coastguard Worker set_err_notfound (result);
1521*48a54d36SAndroid Build Coastguard Worker
1522*48a54d36SAndroid Build Coastguard Worker // Point hostent to the right buffers
1523*48a54d36SAndroid Build Coastguard Worker result->hostent->h_name = result->header->hostname;
1524*48a54d36SAndroid Build Coastguard Worker result->hostent->h_aliases = result->header->aliases;
1525*48a54d36SAndroid Build Coastguard Worker result->hostent->h_addr_list = result->header->addrs;
1526*48a54d36SAndroid Build Coastguard Worker
1527*48a54d36SAndroid Build Coastguard Worker return 0;
1528*48a54d36SAndroid Build Coastguard Worker }
1529*48a54d36SAndroid Build Coastguard Worker
1530*48a54d36SAndroid Build Coastguard Worker /*
1531*48a54d36SAndroid Build Coastguard Worker Set the status in the result.
1532*48a54d36SAndroid Build Coastguard Worker
1533*48a54d36SAndroid Build Coastguard Worker Parameters
1534*48a54d36SAndroid Build Coastguard Worker result
1535*48a54d36SAndroid Build Coastguard Worker Result structure to update
1536*48a54d36SAndroid Build Coastguard Worker status
1537*48a54d36SAndroid Build Coastguard Worker New nss_status value
1538*48a54d36SAndroid Build Coastguard Worker err
1539*48a54d36SAndroid Build Coastguard Worker New errno value
1540*48a54d36SAndroid Build Coastguard Worker herr
1541*48a54d36SAndroid Build Coastguard Worker New h_errno value
1542*48a54d36SAndroid Build Coastguard Worker
1543*48a54d36SAndroid Build Coastguard Worker Returns
1544*48a54d36SAndroid Build Coastguard Worker New status value
1545*48a54d36SAndroid Build Coastguard Worker */
1546*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err(result_map_t * result,nss_status status,int err,int herr)1547*48a54d36SAndroid Build Coastguard Worker set_err (result_map_t * result, nss_status status, int err, int herr)
1548*48a54d36SAndroid Build Coastguard Worker {
1549*48a54d36SAndroid Build Coastguard Worker result->status = status;
1550*48a54d36SAndroid Build Coastguard Worker result->r_errno = err;
1551*48a54d36SAndroid Build Coastguard Worker result->r_h_errno = herr;
1552*48a54d36SAndroid Build Coastguard Worker
1553*48a54d36SAndroid Build Coastguard Worker return status;
1554*48a54d36SAndroid Build Coastguard Worker }
1555*48a54d36SAndroid Build Coastguard Worker
1556*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err_notfound(result_map_t * result)1557*48a54d36SAndroid Build Coastguard Worker set_err_notfound (result_map_t * result)
1558*48a54d36SAndroid Build Coastguard Worker {
1559*48a54d36SAndroid Build Coastguard Worker return set_err (result, NSS_STATUS_NOTFOUND, ENOENT, HOST_NOT_FOUND);
1560*48a54d36SAndroid Build Coastguard Worker }
1561*48a54d36SAndroid Build Coastguard Worker
1562*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err_bad_hostname(result_map_t * result)1563*48a54d36SAndroid Build Coastguard Worker set_err_bad_hostname (result_map_t * result)
1564*48a54d36SAndroid Build Coastguard Worker {
1565*48a54d36SAndroid Build Coastguard Worker return set_err (result, NSS_STATUS_TRYAGAIN, ENOENT, NO_RECOVERY);
1566*48a54d36SAndroid Build Coastguard Worker }
1567*48a54d36SAndroid Build Coastguard Worker
1568*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err_buf_too_small(result_map_t * result)1569*48a54d36SAndroid Build Coastguard Worker set_err_buf_too_small (result_map_t * result)
1570*48a54d36SAndroid Build Coastguard Worker {
1571*48a54d36SAndroid Build Coastguard Worker return set_err (result, NSS_STATUS_TRYAGAIN, ERANGE, NETDB_INTERNAL);
1572*48a54d36SAndroid Build Coastguard Worker }
1573*48a54d36SAndroid Build Coastguard Worker
1574*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err_internal_resource_full(result_map_t * result)1575*48a54d36SAndroid Build Coastguard Worker set_err_internal_resource_full (result_map_t * result)
1576*48a54d36SAndroid Build Coastguard Worker {
1577*48a54d36SAndroid Build Coastguard Worker return set_err (result, NSS_STATUS_RETURN, ERANGE, NO_RECOVERY);
1578*48a54d36SAndroid Build Coastguard Worker }
1579*48a54d36SAndroid Build Coastguard Worker
1580*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err_system(result_map_t * result)1581*48a54d36SAndroid Build Coastguard Worker set_err_system (result_map_t * result)
1582*48a54d36SAndroid Build Coastguard Worker {
1583*48a54d36SAndroid Build Coastguard Worker return set_err (result, NSS_STATUS_UNAVAIL, errno, NETDB_INTERNAL);
1584*48a54d36SAndroid Build Coastguard Worker }
1585*48a54d36SAndroid Build Coastguard Worker
1586*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err_mdns_failed(result_map_t * result)1587*48a54d36SAndroid Build Coastguard Worker set_err_mdns_failed (result_map_t * result)
1588*48a54d36SAndroid Build Coastguard Worker {
1589*48a54d36SAndroid Build Coastguard Worker return set_err (result, NSS_STATUS_TRYAGAIN, EAGAIN, TRY_AGAIN);
1590*48a54d36SAndroid Build Coastguard Worker }
1591*48a54d36SAndroid Build Coastguard Worker
1592*48a54d36SAndroid Build Coastguard Worker static nss_status
set_err_success(result_map_t * result)1593*48a54d36SAndroid Build Coastguard Worker set_err_success (result_map_t * result)
1594*48a54d36SAndroid Build Coastguard Worker {
1595*48a54d36SAndroid Build Coastguard Worker result->status = NSS_STATUS_SUCCESS;
1596*48a54d36SAndroid Build Coastguard Worker return result->status;
1597*48a54d36SAndroid Build Coastguard Worker }
1598*48a54d36SAndroid Build Coastguard Worker
1599*48a54d36SAndroid Build Coastguard Worker
1600*48a54d36SAndroid Build Coastguard Worker /*
1601*48a54d36SAndroid Build Coastguard Worker Test whether name is applicable for mdns to process, and if so copy into
1602*48a54d36SAndroid Build Coastguard Worker lookup_name buffer (if non-NULL).
1603*48a54d36SAndroid Build Coastguard Worker
1604*48a54d36SAndroid Build Coastguard Worker Returns
1605*48a54d36SAndroid Build Coastguard Worker Pointer to name to lookup up, if applicable, or NULL otherwise.
1606*48a54d36SAndroid Build Coastguard Worker */
1607*48a54d36SAndroid Build Coastguard Worker static const char *
is_applicable_name(result_map_t * result,const char * name,char * lookup_name)1608*48a54d36SAndroid Build Coastguard Worker is_applicable_name (
1609*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
1610*48a54d36SAndroid Build Coastguard Worker const char * name,
1611*48a54d36SAndroid Build Coastguard Worker char * lookup_name
1612*48a54d36SAndroid Build Coastguard Worker )
1613*48a54d36SAndroid Build Coastguard Worker {
1614*48a54d36SAndroid Build Coastguard Worker int match = config_is_mdns_suffix (name);
1615*48a54d36SAndroid Build Coastguard Worker if (match > 0)
1616*48a54d36SAndroid Build Coastguard Worker {
1617*48a54d36SAndroid Build Coastguard Worker if (lookup_name)
1618*48a54d36SAndroid Build Coastguard Worker {
1619*48a54d36SAndroid Build Coastguard Worker strncpy (lookup_name, name, k_hostname_maxlen + 1);
1620*48a54d36SAndroid Build Coastguard Worker return lookup_name;
1621*48a54d36SAndroid Build Coastguard Worker }
1622*48a54d36SAndroid Build Coastguard Worker else
1623*48a54d36SAndroid Build Coastguard Worker {
1624*48a54d36SAndroid Build Coastguard Worker return name;
1625*48a54d36SAndroid Build Coastguard Worker }
1626*48a54d36SAndroid Build Coastguard Worker }
1627*48a54d36SAndroid Build Coastguard Worker else
1628*48a54d36SAndroid Build Coastguard Worker {
1629*48a54d36SAndroid Build Coastguard Worker if (match < 0)
1630*48a54d36SAndroid Build Coastguard Worker {
1631*48a54d36SAndroid Build Coastguard Worker set_err_system (result);
1632*48a54d36SAndroid Build Coastguard Worker }
1633*48a54d36SAndroid Build Coastguard Worker return NULL;
1634*48a54d36SAndroid Build Coastguard Worker }
1635*48a54d36SAndroid Build Coastguard Worker }
1636*48a54d36SAndroid Build Coastguard Worker
1637*48a54d36SAndroid Build Coastguard Worker /*
1638*48a54d36SAndroid Build Coastguard Worker Test whether address is applicable for mdns to process, and if so copy into
1639*48a54d36SAndroid Build Coastguard Worker addr_str buffer as an address suitable for ptr lookup.
1640*48a54d36SAndroid Build Coastguard Worker
1641*48a54d36SAndroid Build Coastguard Worker Returns
1642*48a54d36SAndroid Build Coastguard Worker Pointer to name to lookup up, if applicable, or NULL otherwise.
1643*48a54d36SAndroid Build Coastguard Worker */
1644*48a54d36SAndroid Build Coastguard Worker static const char *
is_applicable_addr(result_map_t * result,const void * addr,int af,char * addr_str)1645*48a54d36SAndroid Build Coastguard Worker is_applicable_addr (
1646*48a54d36SAndroid Build Coastguard Worker result_map_t * result,
1647*48a54d36SAndroid Build Coastguard Worker const void * addr,
1648*48a54d36SAndroid Build Coastguard Worker int af,
1649*48a54d36SAndroid Build Coastguard Worker char * addr_str
1650*48a54d36SAndroid Build Coastguard Worker )
1651*48a54d36SAndroid Build Coastguard Worker {
1652*48a54d36SAndroid Build Coastguard Worker int match;
1653*48a54d36SAndroid Build Coastguard Worker
1654*48a54d36SAndroid Build Coastguard Worker if (! format_reverse_addr (af, addr, -1, addr_str))
1655*48a54d36SAndroid Build Coastguard Worker {
1656*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
1657*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
1658*48a54d36SAndroid Build Coastguard Worker "mdns: Failed to create reverse address"
1659*48a54d36SAndroid Build Coastguard Worker );
1660*48a54d36SAndroid Build Coastguard Worker return NULL;
1661*48a54d36SAndroid Build Coastguard Worker }
1662*48a54d36SAndroid Build Coastguard Worker
1663*48a54d36SAndroid Build Coastguard Worker if (MDNS_VERBOSE)
1664*48a54d36SAndroid Build Coastguard Worker syslog (LOG_DEBUG,
1665*48a54d36SAndroid Build Coastguard Worker "mdns: Reverse address: %s",
1666*48a54d36SAndroid Build Coastguard Worker addr_str
1667*48a54d36SAndroid Build Coastguard Worker );
1668*48a54d36SAndroid Build Coastguard Worker
1669*48a54d36SAndroid Build Coastguard Worker match = config_is_mdns_suffix (addr_str);
1670*48a54d36SAndroid Build Coastguard Worker if (match > 0)
1671*48a54d36SAndroid Build Coastguard Worker {
1672*48a54d36SAndroid Build Coastguard Worker return addr_str;
1673*48a54d36SAndroid Build Coastguard Worker }
1674*48a54d36SAndroid Build Coastguard Worker else
1675*48a54d36SAndroid Build Coastguard Worker {
1676*48a54d36SAndroid Build Coastguard Worker if (match < 0)
1677*48a54d36SAndroid Build Coastguard Worker {
1678*48a54d36SAndroid Build Coastguard Worker set_err_system (result);
1679*48a54d36SAndroid Build Coastguard Worker }
1680*48a54d36SAndroid Build Coastguard Worker return NULL;
1681*48a54d36SAndroid Build Coastguard Worker }
1682*48a54d36SAndroid Build Coastguard Worker }
1683*48a54d36SAndroid Build Coastguard Worker
1684*48a54d36SAndroid Build Coastguard Worker //----------
1685*48a54d36SAndroid Build Coastguard Worker // Types and Constants
1686*48a54d36SAndroid Build Coastguard Worker
1687*48a54d36SAndroid Build Coastguard Worker const char * k_conf_file = "/etc/nss_mdns.conf";
1688*48a54d36SAndroid Build Coastguard Worker #define CONF_LINE_SIZE 1024
1689*48a54d36SAndroid Build Coastguard Worker
1690*48a54d36SAndroid Build Coastguard Worker const char k_comment_char = '#';
1691*48a54d36SAndroid Build Coastguard Worker
1692*48a54d36SAndroid Build Coastguard Worker const char * k_keyword_domain = "domain";
1693*48a54d36SAndroid Build Coastguard Worker
1694*48a54d36SAndroid Build Coastguard Worker const char * k_default_domains [] =
1695*48a54d36SAndroid Build Coastguard Worker {
1696*48a54d36SAndroid Build Coastguard Worker "local",
1697*48a54d36SAndroid Build Coastguard Worker "254.169.in-addr.arpa",
1698*48a54d36SAndroid Build Coastguard Worker "8.e.f.ip6.int",
1699*48a54d36SAndroid Build Coastguard Worker "8.e.f.ip6.arpa",
1700*48a54d36SAndroid Build Coastguard Worker "9.e.f.ip6.int",
1701*48a54d36SAndroid Build Coastguard Worker "9.e.f.ip6.arpa",
1702*48a54d36SAndroid Build Coastguard Worker "a.e.f.ip6.int",
1703*48a54d36SAndroid Build Coastguard Worker "a.e.f.ip6.arpa",
1704*48a54d36SAndroid Build Coastguard Worker "b.e.f.ip6.int",
1705*48a54d36SAndroid Build Coastguard Worker "b.e.f.ip6.arpa",
1706*48a54d36SAndroid Build Coastguard Worker NULL
1707*48a54d36SAndroid Build Coastguard Worker // Always null terminated
1708*48a54d36SAndroid Build Coastguard Worker };
1709*48a54d36SAndroid Build Coastguard Worker
1710*48a54d36SAndroid Build Coastguard Worker // Linked list of domains
1711*48a54d36SAndroid Build Coastguard Worker typedef struct domain_entry
1712*48a54d36SAndroid Build Coastguard Worker {
1713*48a54d36SAndroid Build Coastguard Worker char * domain;
1714*48a54d36SAndroid Build Coastguard Worker struct domain_entry * next;
1715*48a54d36SAndroid Build Coastguard Worker } domain_entry_t;
1716*48a54d36SAndroid Build Coastguard Worker
1717*48a54d36SAndroid Build Coastguard Worker
1718*48a54d36SAndroid Build Coastguard Worker // Config
1719*48a54d36SAndroid Build Coastguard Worker typedef struct
1720*48a54d36SAndroid Build Coastguard Worker {
1721*48a54d36SAndroid Build Coastguard Worker domain_entry_t * domains;
1722*48a54d36SAndroid Build Coastguard Worker } config_t;
1723*48a54d36SAndroid Build Coastguard Worker
1724*48a54d36SAndroid Build Coastguard Worker const config_t k_empty_config =
1725*48a54d36SAndroid Build Coastguard Worker {
1726*48a54d36SAndroid Build Coastguard Worker NULL
1727*48a54d36SAndroid Build Coastguard Worker };
1728*48a54d36SAndroid Build Coastguard Worker
1729*48a54d36SAndroid Build Coastguard Worker
1730*48a54d36SAndroid Build Coastguard Worker // Context - tracks position in config file, used for error reporting
1731*48a54d36SAndroid Build Coastguard Worker typedef struct
1732*48a54d36SAndroid Build Coastguard Worker {
1733*48a54d36SAndroid Build Coastguard Worker const char * filename;
1734*48a54d36SAndroid Build Coastguard Worker int linenum;
1735*48a54d36SAndroid Build Coastguard Worker } config_file_context_t;
1736*48a54d36SAndroid Build Coastguard Worker
1737*48a54d36SAndroid Build Coastguard Worker
1738*48a54d36SAndroid Build Coastguard Worker //----------
1739*48a54d36SAndroid Build Coastguard Worker // Local prototypes
1740*48a54d36SAndroid Build Coastguard Worker
1741*48a54d36SAndroid Build Coastguard Worker static errcode_t
1742*48a54d36SAndroid Build Coastguard Worker load_config (config_t * conf);
1743*48a54d36SAndroid Build Coastguard Worker
1744*48a54d36SAndroid Build Coastguard Worker static errcode_t
1745*48a54d36SAndroid Build Coastguard Worker process_config_line (
1746*48a54d36SAndroid Build Coastguard Worker config_t * conf,
1747*48a54d36SAndroid Build Coastguard Worker char * line,
1748*48a54d36SAndroid Build Coastguard Worker config_file_context_t * context
1749*48a54d36SAndroid Build Coastguard Worker );
1750*48a54d36SAndroid Build Coastguard Worker
1751*48a54d36SAndroid Build Coastguard Worker static char *
1752*48a54d36SAndroid Build Coastguard Worker get_next_word (char * input, char **next);
1753*48a54d36SAndroid Build Coastguard Worker
1754*48a54d36SAndroid Build Coastguard Worker static errcode_t
1755*48a54d36SAndroid Build Coastguard Worker default_config (config_t * conf);
1756*48a54d36SAndroid Build Coastguard Worker
1757*48a54d36SAndroid Build Coastguard Worker static errcode_t
1758*48a54d36SAndroid Build Coastguard Worker add_domain (config_t * conf, const char * domain);
1759*48a54d36SAndroid Build Coastguard Worker
1760*48a54d36SAndroid Build Coastguard Worker static int
1761*48a54d36SAndroid Build Coastguard Worker contains_domain (const config_t * conf, const char * domain);
1762*48a54d36SAndroid Build Coastguard Worker
1763*48a54d36SAndroid Build Coastguard Worker static int
1764*48a54d36SAndroid Build Coastguard Worker contains_domain_suffix (const config_t * conf, const char * addr);
1765*48a54d36SAndroid Build Coastguard Worker
1766*48a54d36SAndroid Build Coastguard Worker
1767*48a54d36SAndroid Build Coastguard Worker //----------
1768*48a54d36SAndroid Build Coastguard Worker // Global variables
1769*48a54d36SAndroid Build Coastguard Worker
1770*48a54d36SAndroid Build Coastguard Worker static config_t * g_config = NULL;
1771*48a54d36SAndroid Build Coastguard Worker // Configuration info
1772*48a54d36SAndroid Build Coastguard Worker
1773*48a54d36SAndroid Build Coastguard Worker pthread_mutex_t g_config_mutex =
1774*48a54d36SAndroid Build Coastguard Worker #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
1775*48a54d36SAndroid Build Coastguard Worker PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
1776*48a54d36SAndroid Build Coastguard Worker #else
1777*48a54d36SAndroid Build Coastguard Worker PTHREAD_MUTEX_INITIALIZER;
1778*48a54d36SAndroid Build Coastguard Worker #endif
1779*48a54d36SAndroid Build Coastguard Worker
1780*48a54d36SAndroid Build Coastguard Worker
1781*48a54d36SAndroid Build Coastguard Worker //----------
1782*48a54d36SAndroid Build Coastguard Worker // Configuration functions
1783*48a54d36SAndroid Build Coastguard Worker
1784*48a54d36SAndroid Build Coastguard Worker
1785*48a54d36SAndroid Build Coastguard Worker /*
1786*48a54d36SAndroid Build Coastguard Worker Initialise the configuration from the config file.
1787*48a54d36SAndroid Build Coastguard Worker
1788*48a54d36SAndroid Build Coastguard Worker Returns
1789*48a54d36SAndroid Build Coastguard Worker 0 success
1790*48a54d36SAndroid Build Coastguard Worker non-zero error code on failure
1791*48a54d36SAndroid Build Coastguard Worker */
1792*48a54d36SAndroid Build Coastguard Worker errcode_t
init_config()1793*48a54d36SAndroid Build Coastguard Worker init_config ()
1794*48a54d36SAndroid Build Coastguard Worker {
1795*48a54d36SAndroid Build Coastguard Worker if (g_config)
1796*48a54d36SAndroid Build Coastguard Worker {
1797*48a54d36SAndroid Build Coastguard Worker /*
1798*48a54d36SAndroid Build Coastguard Worker Safe to test outside mutex.
1799*48a54d36SAndroid Build Coastguard Worker If non-zero, initialisation is complete and g_config can be
1800*48a54d36SAndroid Build Coastguard Worker safely used read-only. If zero, then we do proper mutex
1801*48a54d36SAndroid Build Coastguard Worker testing before initialisation.
1802*48a54d36SAndroid Build Coastguard Worker */
1803*48a54d36SAndroid Build Coastguard Worker return 0;
1804*48a54d36SAndroid Build Coastguard Worker }
1805*48a54d36SAndroid Build Coastguard Worker else
1806*48a54d36SAndroid Build Coastguard Worker {
1807*48a54d36SAndroid Build Coastguard Worker int errcode = -1;
1808*48a54d36SAndroid Build Coastguard Worker int presult;
1809*48a54d36SAndroid Build Coastguard Worker config_t * temp_config;
1810*48a54d36SAndroid Build Coastguard Worker
1811*48a54d36SAndroid Build Coastguard Worker // Acquire mutex
1812*48a54d36SAndroid Build Coastguard Worker presult = pthread_mutex_lock (&g_config_mutex);
1813*48a54d36SAndroid Build Coastguard Worker if (presult)
1814*48a54d36SAndroid Build Coastguard Worker {
1815*48a54d36SAndroid Build Coastguard Worker syslog (LOG_ERR,
1816*48a54d36SAndroid Build Coastguard Worker "mdns: Fatal mutex lock error in nss_mdns:init_config, %s:%d: %d: %s",
1817*48a54d36SAndroid Build Coastguard Worker __FILE__, __LINE__, presult, strerror (presult)
1818*48a54d36SAndroid Build Coastguard Worker );
1819*48a54d36SAndroid Build Coastguard Worker return presult;
1820*48a54d36SAndroid Build Coastguard Worker }
1821*48a54d36SAndroid Build Coastguard Worker
1822*48a54d36SAndroid Build Coastguard Worker // Test again now we have mutex, in case initialisation occurred while
1823*48a54d36SAndroid Build Coastguard Worker // we were waiting
1824*48a54d36SAndroid Build Coastguard Worker if (! g_config)
1825*48a54d36SAndroid Build Coastguard Worker {
1826*48a54d36SAndroid Build Coastguard Worker temp_config = (config_t *) malloc (sizeof (config_t));
1827*48a54d36SAndroid Build Coastguard Worker if (temp_config)
1828*48a54d36SAndroid Build Coastguard Worker {
1829*48a54d36SAndroid Build Coastguard Worker // Note: This code will leak memory if initialisation fails
1830*48a54d36SAndroid Build Coastguard Worker // repeatedly. This should only happen in the case of a memory
1831*48a54d36SAndroid Build Coastguard Worker // error, so I'm not sure if it's a meaningful problem. - AW
1832*48a54d36SAndroid Build Coastguard Worker *temp_config = k_empty_config;
1833*48a54d36SAndroid Build Coastguard Worker errcode = load_config (temp_config);
1834*48a54d36SAndroid Build Coastguard Worker
1835*48a54d36SAndroid Build Coastguard Worker if (! errcode)
1836*48a54d36SAndroid Build Coastguard Worker {
1837*48a54d36SAndroid Build Coastguard Worker g_config = temp_config;
1838*48a54d36SAndroid Build Coastguard Worker }
1839*48a54d36SAndroid Build Coastguard Worker }
1840*48a54d36SAndroid Build Coastguard Worker else
1841*48a54d36SAndroid Build Coastguard Worker {
1842*48a54d36SAndroid Build Coastguard Worker syslog (LOG_ERR,
1843*48a54d36SAndroid Build Coastguard Worker "mdns: Can't allocate memory in nss_mdns:init_config, %s:%d",
1844*48a54d36SAndroid Build Coastguard Worker __FILE__, __LINE__
1845*48a54d36SAndroid Build Coastguard Worker );
1846*48a54d36SAndroid Build Coastguard Worker errcode = errno;
1847*48a54d36SAndroid Build Coastguard Worker }
1848*48a54d36SAndroid Build Coastguard Worker }
1849*48a54d36SAndroid Build Coastguard Worker
1850*48a54d36SAndroid Build Coastguard Worker presult = pthread_mutex_unlock (&g_config_mutex);
1851*48a54d36SAndroid Build Coastguard Worker if (presult)
1852*48a54d36SAndroid Build Coastguard Worker {
1853*48a54d36SAndroid Build Coastguard Worker syslog (LOG_ERR,
1854*48a54d36SAndroid Build Coastguard Worker "mdns: Fatal mutex unlock error in nss_mdns:init_config, %s:%d: %d: %s",
1855*48a54d36SAndroid Build Coastguard Worker __FILE__, __LINE__, presult, strerror (presult)
1856*48a54d36SAndroid Build Coastguard Worker );
1857*48a54d36SAndroid Build Coastguard Worker errcode = presult;
1858*48a54d36SAndroid Build Coastguard Worker }
1859*48a54d36SAndroid Build Coastguard Worker
1860*48a54d36SAndroid Build Coastguard Worker return errcode;
1861*48a54d36SAndroid Build Coastguard Worker }
1862*48a54d36SAndroid Build Coastguard Worker }
1863*48a54d36SAndroid Build Coastguard Worker
1864*48a54d36SAndroid Build Coastguard Worker
1865*48a54d36SAndroid Build Coastguard Worker int
config_is_mdns_suffix(const char * name)1866*48a54d36SAndroid Build Coastguard Worker config_is_mdns_suffix (const char * name)
1867*48a54d36SAndroid Build Coastguard Worker {
1868*48a54d36SAndroid Build Coastguard Worker int errcode = init_config ();
1869*48a54d36SAndroid Build Coastguard Worker if (! errcode)
1870*48a54d36SAndroid Build Coastguard Worker {
1871*48a54d36SAndroid Build Coastguard Worker return contains_domain_suffix (g_config, name);
1872*48a54d36SAndroid Build Coastguard Worker }
1873*48a54d36SAndroid Build Coastguard Worker else
1874*48a54d36SAndroid Build Coastguard Worker {
1875*48a54d36SAndroid Build Coastguard Worker errno = errcode;
1876*48a54d36SAndroid Build Coastguard Worker return -1;
1877*48a54d36SAndroid Build Coastguard Worker }
1878*48a54d36SAndroid Build Coastguard Worker }
1879*48a54d36SAndroid Build Coastguard Worker
1880*48a54d36SAndroid Build Coastguard Worker
1881*48a54d36SAndroid Build Coastguard Worker //----------
1882*48a54d36SAndroid Build Coastguard Worker // Local functions
1883*48a54d36SAndroid Build Coastguard Worker
1884*48a54d36SAndroid Build Coastguard Worker static errcode_t
load_config(config_t * conf)1885*48a54d36SAndroid Build Coastguard Worker load_config (config_t * conf)
1886*48a54d36SAndroid Build Coastguard Worker {
1887*48a54d36SAndroid Build Coastguard Worker FILE * cf;
1888*48a54d36SAndroid Build Coastguard Worker char line [CONF_LINE_SIZE];
1889*48a54d36SAndroid Build Coastguard Worker config_file_context_t context;
1890*48a54d36SAndroid Build Coastguard Worker
1891*48a54d36SAndroid Build Coastguard Worker context.filename = k_conf_file;
1892*48a54d36SAndroid Build Coastguard Worker context.linenum = 0;
1893*48a54d36SAndroid Build Coastguard Worker
1894*48a54d36SAndroid Build Coastguard Worker
1895*48a54d36SAndroid Build Coastguard Worker cf = fopen (context.filename, "r");
1896*48a54d36SAndroid Build Coastguard Worker if (! cf)
1897*48a54d36SAndroid Build Coastguard Worker {
1898*48a54d36SAndroid Build Coastguard Worker syslog (LOG_INFO,
1899*48a54d36SAndroid Build Coastguard Worker "mdns: Couldn't open nss_mdns configuration file %s, using default.",
1900*48a54d36SAndroid Build Coastguard Worker context.filename
1901*48a54d36SAndroid Build Coastguard Worker );
1902*48a54d36SAndroid Build Coastguard Worker return default_config (conf);
1903*48a54d36SAndroid Build Coastguard Worker }
1904*48a54d36SAndroid Build Coastguard Worker
1905*48a54d36SAndroid Build Coastguard Worker while (fgets (line, CONF_LINE_SIZE, cf))
1906*48a54d36SAndroid Build Coastguard Worker {
1907*48a54d36SAndroid Build Coastguard Worker int errcode;
1908*48a54d36SAndroid Build Coastguard Worker context.linenum++;
1909*48a54d36SAndroid Build Coastguard Worker errcode = process_config_line (conf, line, &context);
1910*48a54d36SAndroid Build Coastguard Worker if (errcode)
1911*48a54d36SAndroid Build Coastguard Worker {
1912*48a54d36SAndroid Build Coastguard Worker // Critical error, give up
1913*48a54d36SAndroid Build Coastguard Worker fclose(cf);
1914*48a54d36SAndroid Build Coastguard Worker return errcode;
1915*48a54d36SAndroid Build Coastguard Worker }
1916*48a54d36SAndroid Build Coastguard Worker }
1917*48a54d36SAndroid Build Coastguard Worker
1918*48a54d36SAndroid Build Coastguard Worker fclose (cf);
1919*48a54d36SAndroid Build Coastguard Worker
1920*48a54d36SAndroid Build Coastguard Worker return 0;
1921*48a54d36SAndroid Build Coastguard Worker }
1922*48a54d36SAndroid Build Coastguard Worker
1923*48a54d36SAndroid Build Coastguard Worker
1924*48a54d36SAndroid Build Coastguard Worker /*
1925*48a54d36SAndroid Build Coastguard Worker Parse a line of the configuration file.
1926*48a54d36SAndroid Build Coastguard Worker For each keyword recognised, perform appropriate handling.
1927*48a54d36SAndroid Build Coastguard Worker If the keyword is not recognised, print a message to syslog
1928*48a54d36SAndroid Build Coastguard Worker and continue.
1929*48a54d36SAndroid Build Coastguard Worker
1930*48a54d36SAndroid Build Coastguard Worker Returns
1931*48a54d36SAndroid Build Coastguard Worker 0 success, or recoverable config file error
1932*48a54d36SAndroid Build Coastguard Worker non-zero serious system error, processing aborted
1933*48a54d36SAndroid Build Coastguard Worker */
1934*48a54d36SAndroid Build Coastguard Worker static errcode_t
process_config_line(config_t * conf,char * line,config_file_context_t * context)1935*48a54d36SAndroid Build Coastguard Worker process_config_line (
1936*48a54d36SAndroid Build Coastguard Worker config_t * conf,
1937*48a54d36SAndroid Build Coastguard Worker char * line,
1938*48a54d36SAndroid Build Coastguard Worker config_file_context_t * context
1939*48a54d36SAndroid Build Coastguard Worker )
1940*48a54d36SAndroid Build Coastguard Worker {
1941*48a54d36SAndroid Build Coastguard Worker char * curr = line;
1942*48a54d36SAndroid Build Coastguard Worker char * word;
1943*48a54d36SAndroid Build Coastguard Worker
1944*48a54d36SAndroid Build Coastguard Worker word = get_next_word (curr, &curr);
1945*48a54d36SAndroid Build Coastguard Worker if (! word || word [0] == k_comment_char)
1946*48a54d36SAndroid Build Coastguard Worker {
1947*48a54d36SAndroid Build Coastguard Worker // Nothing interesting on this line
1948*48a54d36SAndroid Build Coastguard Worker return 0;
1949*48a54d36SAndroid Build Coastguard Worker }
1950*48a54d36SAndroid Build Coastguard Worker
1951*48a54d36SAndroid Build Coastguard Worker if (strcmp (word, k_keyword_domain) == 0)
1952*48a54d36SAndroid Build Coastguard Worker {
1953*48a54d36SAndroid Build Coastguard Worker word = get_next_word (curr, &curr);
1954*48a54d36SAndroid Build Coastguard Worker if (word)
1955*48a54d36SAndroid Build Coastguard Worker {
1956*48a54d36SAndroid Build Coastguard Worker int errcode = add_domain (conf, word);
1957*48a54d36SAndroid Build Coastguard Worker if (errcode)
1958*48a54d36SAndroid Build Coastguard Worker {
1959*48a54d36SAndroid Build Coastguard Worker // something badly wrong, bail
1960*48a54d36SAndroid Build Coastguard Worker return errcode;
1961*48a54d36SAndroid Build Coastguard Worker }
1962*48a54d36SAndroid Build Coastguard Worker
1963*48a54d36SAndroid Build Coastguard Worker if (get_next_word (curr, NULL))
1964*48a54d36SAndroid Build Coastguard Worker {
1965*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1966*48a54d36SAndroid Build Coastguard Worker "%s, line %d: ignored extra text found after domain",
1967*48a54d36SAndroid Build Coastguard Worker context->filename,
1968*48a54d36SAndroid Build Coastguard Worker context->linenum
1969*48a54d36SAndroid Build Coastguard Worker );
1970*48a54d36SAndroid Build Coastguard Worker }
1971*48a54d36SAndroid Build Coastguard Worker }
1972*48a54d36SAndroid Build Coastguard Worker else
1973*48a54d36SAndroid Build Coastguard Worker {
1974*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1975*48a54d36SAndroid Build Coastguard Worker "%s, line %d: no domain specified",
1976*48a54d36SAndroid Build Coastguard Worker context->filename,
1977*48a54d36SAndroid Build Coastguard Worker context->linenum
1978*48a54d36SAndroid Build Coastguard Worker );
1979*48a54d36SAndroid Build Coastguard Worker }
1980*48a54d36SAndroid Build Coastguard Worker }
1981*48a54d36SAndroid Build Coastguard Worker else
1982*48a54d36SAndroid Build Coastguard Worker {
1983*48a54d36SAndroid Build Coastguard Worker syslog (LOG_WARNING,
1984*48a54d36SAndroid Build Coastguard Worker "%s, line %d: unknown keyword %s - skipping",
1985*48a54d36SAndroid Build Coastguard Worker context->filename,
1986*48a54d36SAndroid Build Coastguard Worker context->linenum,
1987*48a54d36SAndroid Build Coastguard Worker word
1988*48a54d36SAndroid Build Coastguard Worker );
1989*48a54d36SAndroid Build Coastguard Worker }
1990*48a54d36SAndroid Build Coastguard Worker
1991*48a54d36SAndroid Build Coastguard Worker return 0;
1992*48a54d36SAndroid Build Coastguard Worker }
1993*48a54d36SAndroid Build Coastguard Worker
1994*48a54d36SAndroid Build Coastguard Worker
1995*48a54d36SAndroid Build Coastguard Worker /*
1996*48a54d36SAndroid Build Coastguard Worker Get next word (whitespace separated) from input string.
1997*48a54d36SAndroid Build Coastguard Worker A null character is written into the first whitespace character following
1998*48a54d36SAndroid Build Coastguard Worker the word.
1999*48a54d36SAndroid Build Coastguard Worker
2000*48a54d36SAndroid Build Coastguard Worker Parameters
2001*48a54d36SAndroid Build Coastguard Worker input
2002*48a54d36SAndroid Build Coastguard Worker Input string. This string is modified by get_next_word.
2003*48a54d36SAndroid Build Coastguard Worker next
2004*48a54d36SAndroid Build Coastguard Worker If non-NULL and the result is non-NULL, a pointer to the
2005*48a54d36SAndroid Build Coastguard Worker character following the end of the word (after the null)
2006*48a54d36SAndroid Build Coastguard Worker is written to 'next'.
2007*48a54d36SAndroid Build Coastguard Worker If no word is found, the original value is unchanged.
2008*48a54d36SAndroid Build Coastguard Worker If the word extended to the end of the string, 'next' points
2009*48a54d36SAndroid Build Coastguard Worker to the trailling NULL.
2010*48a54d36SAndroid Build Coastguard Worker It is safe to pass 'str' as 'input' and '&str' as 'next'.
2011*48a54d36SAndroid Build Coastguard Worker Returns
2012*48a54d36SAndroid Build Coastguard Worker Pointer to the first non-whitespace character (and thus word) found.
2013*48a54d36SAndroid Build Coastguard Worker if no word is found, returns NULL.
2014*48a54d36SAndroid Build Coastguard Worker */
2015*48a54d36SAndroid Build Coastguard Worker static char *
get_next_word(char * input,char ** next)2016*48a54d36SAndroid Build Coastguard Worker get_next_word (char * input, char **next)
2017*48a54d36SAndroid Build Coastguard Worker {
2018*48a54d36SAndroid Build Coastguard Worker char * curr = input;
2019*48a54d36SAndroid Build Coastguard Worker char * result;
2020*48a54d36SAndroid Build Coastguard Worker
2021*48a54d36SAndroid Build Coastguard Worker while (isspace (*curr))
2022*48a54d36SAndroid Build Coastguard Worker {
2023*48a54d36SAndroid Build Coastguard Worker curr ++;
2024*48a54d36SAndroid Build Coastguard Worker }
2025*48a54d36SAndroid Build Coastguard Worker
2026*48a54d36SAndroid Build Coastguard Worker if (*curr == 0)
2027*48a54d36SAndroid Build Coastguard Worker {
2028*48a54d36SAndroid Build Coastguard Worker return NULL;
2029*48a54d36SAndroid Build Coastguard Worker }
2030*48a54d36SAndroid Build Coastguard Worker
2031*48a54d36SAndroid Build Coastguard Worker result = curr;
2032*48a54d36SAndroid Build Coastguard Worker while (*curr && ! isspace (*curr))
2033*48a54d36SAndroid Build Coastguard Worker {
2034*48a54d36SAndroid Build Coastguard Worker curr++;
2035*48a54d36SAndroid Build Coastguard Worker }
2036*48a54d36SAndroid Build Coastguard Worker if (*curr)
2037*48a54d36SAndroid Build Coastguard Worker {
2038*48a54d36SAndroid Build Coastguard Worker *curr = 0;
2039*48a54d36SAndroid Build Coastguard Worker if (next)
2040*48a54d36SAndroid Build Coastguard Worker {
2041*48a54d36SAndroid Build Coastguard Worker *next = curr+1;
2042*48a54d36SAndroid Build Coastguard Worker }
2043*48a54d36SAndroid Build Coastguard Worker }
2044*48a54d36SAndroid Build Coastguard Worker else
2045*48a54d36SAndroid Build Coastguard Worker {
2046*48a54d36SAndroid Build Coastguard Worker if (next)
2047*48a54d36SAndroid Build Coastguard Worker {
2048*48a54d36SAndroid Build Coastguard Worker *next = curr;
2049*48a54d36SAndroid Build Coastguard Worker }
2050*48a54d36SAndroid Build Coastguard Worker }
2051*48a54d36SAndroid Build Coastguard Worker
2052*48a54d36SAndroid Build Coastguard Worker return result;
2053*48a54d36SAndroid Build Coastguard Worker }
2054*48a54d36SAndroid Build Coastguard Worker
2055*48a54d36SAndroid Build Coastguard Worker
2056*48a54d36SAndroid Build Coastguard Worker static errcode_t
default_config(config_t * conf)2057*48a54d36SAndroid Build Coastguard Worker default_config (config_t * conf)
2058*48a54d36SAndroid Build Coastguard Worker {
2059*48a54d36SAndroid Build Coastguard Worker int i;
2060*48a54d36SAndroid Build Coastguard Worker for (i = 0; k_default_domains [i]; i++)
2061*48a54d36SAndroid Build Coastguard Worker {
2062*48a54d36SAndroid Build Coastguard Worker int errcode =
2063*48a54d36SAndroid Build Coastguard Worker add_domain (conf, k_default_domains [i]);
2064*48a54d36SAndroid Build Coastguard Worker if (errcode)
2065*48a54d36SAndroid Build Coastguard Worker {
2066*48a54d36SAndroid Build Coastguard Worker // Something has gone (badly) wrong - let's bail
2067*48a54d36SAndroid Build Coastguard Worker return errcode;
2068*48a54d36SAndroid Build Coastguard Worker }
2069*48a54d36SAndroid Build Coastguard Worker }
2070*48a54d36SAndroid Build Coastguard Worker
2071*48a54d36SAndroid Build Coastguard Worker return 0;
2072*48a54d36SAndroid Build Coastguard Worker }
2073*48a54d36SAndroid Build Coastguard Worker
2074*48a54d36SAndroid Build Coastguard Worker
2075*48a54d36SAndroid Build Coastguard Worker static errcode_t
add_domain(config_t * conf,const char * domain)2076*48a54d36SAndroid Build Coastguard Worker add_domain (config_t * conf, const char * domain)
2077*48a54d36SAndroid Build Coastguard Worker {
2078*48a54d36SAndroid Build Coastguard Worker if (! contains_domain (conf, domain))
2079*48a54d36SAndroid Build Coastguard Worker {
2080*48a54d36SAndroid Build Coastguard Worker domain_entry_t * d =
2081*48a54d36SAndroid Build Coastguard Worker (domain_entry_t *) malloc (sizeof (domain_entry_t));
2082*48a54d36SAndroid Build Coastguard Worker if (! d)
2083*48a54d36SAndroid Build Coastguard Worker {
2084*48a54d36SAndroid Build Coastguard Worker syslog (LOG_ERR,
2085*48a54d36SAndroid Build Coastguard Worker "mdns: Can't allocate memory in nss_mdns:init_config, %s:%d",
2086*48a54d36SAndroid Build Coastguard Worker __FILE__, __LINE__
2087*48a54d36SAndroid Build Coastguard Worker );
2088*48a54d36SAndroid Build Coastguard Worker return ENOMEM;
2089*48a54d36SAndroid Build Coastguard Worker }
2090*48a54d36SAndroid Build Coastguard Worker
2091*48a54d36SAndroid Build Coastguard Worker d->domain = strdup (domain);
2092*48a54d36SAndroid Build Coastguard Worker if (! d->domain)
2093*48a54d36SAndroid Build Coastguard Worker {
2094*48a54d36SAndroid Build Coastguard Worker syslog (LOG_ERR,
2095*48a54d36SAndroid Build Coastguard Worker "mdns: Can't allocate memory in nss_mdns:init_config, %s:%d",
2096*48a54d36SAndroid Build Coastguard Worker __FILE__, __LINE__
2097*48a54d36SAndroid Build Coastguard Worker );
2098*48a54d36SAndroid Build Coastguard Worker free (d);
2099*48a54d36SAndroid Build Coastguard Worker return ENOMEM;
2100*48a54d36SAndroid Build Coastguard Worker }
2101*48a54d36SAndroid Build Coastguard Worker d->next = conf->domains;
2102*48a54d36SAndroid Build Coastguard Worker conf->domains = d;
2103*48a54d36SAndroid Build Coastguard Worker }
2104*48a54d36SAndroid Build Coastguard Worker
2105*48a54d36SAndroid Build Coastguard Worker return 0;
2106*48a54d36SAndroid Build Coastguard Worker }
2107*48a54d36SAndroid Build Coastguard Worker
2108*48a54d36SAndroid Build Coastguard Worker
2109*48a54d36SAndroid Build Coastguard Worker static int
contains_domain(const config_t * conf,const char * domain)2110*48a54d36SAndroid Build Coastguard Worker contains_domain (const config_t * conf, const char * domain)
2111*48a54d36SAndroid Build Coastguard Worker {
2112*48a54d36SAndroid Build Coastguard Worker const domain_entry_t * curr = conf->domains;
2113*48a54d36SAndroid Build Coastguard Worker
2114*48a54d36SAndroid Build Coastguard Worker while (curr != NULL)
2115*48a54d36SAndroid Build Coastguard Worker {
2116*48a54d36SAndroid Build Coastguard Worker if (strcasecmp (curr->domain, domain) == 0)
2117*48a54d36SAndroid Build Coastguard Worker {
2118*48a54d36SAndroid Build Coastguard Worker return 1;
2119*48a54d36SAndroid Build Coastguard Worker }
2120*48a54d36SAndroid Build Coastguard Worker
2121*48a54d36SAndroid Build Coastguard Worker curr = curr->next;
2122*48a54d36SAndroid Build Coastguard Worker }
2123*48a54d36SAndroid Build Coastguard Worker
2124*48a54d36SAndroid Build Coastguard Worker return 0;
2125*48a54d36SAndroid Build Coastguard Worker }
2126*48a54d36SAndroid Build Coastguard Worker
2127*48a54d36SAndroid Build Coastguard Worker
2128*48a54d36SAndroid Build Coastguard Worker static int
contains_domain_suffix(const config_t * conf,const char * addr)2129*48a54d36SAndroid Build Coastguard Worker contains_domain_suffix (const config_t * conf, const char * addr)
2130*48a54d36SAndroid Build Coastguard Worker {
2131*48a54d36SAndroid Build Coastguard Worker const domain_entry_t * curr = conf->domains;
2132*48a54d36SAndroid Build Coastguard Worker
2133*48a54d36SAndroid Build Coastguard Worker while (curr != NULL)
2134*48a54d36SAndroid Build Coastguard Worker {
2135*48a54d36SAndroid Build Coastguard Worker if (cmp_dns_suffix (addr, curr->domain) > 0)
2136*48a54d36SAndroid Build Coastguard Worker {
2137*48a54d36SAndroid Build Coastguard Worker return 1;
2138*48a54d36SAndroid Build Coastguard Worker }
2139*48a54d36SAndroid Build Coastguard Worker
2140*48a54d36SAndroid Build Coastguard Worker curr = curr->next;
2141*48a54d36SAndroid Build Coastguard Worker }
2142*48a54d36SAndroid Build Coastguard Worker
2143*48a54d36SAndroid Build Coastguard Worker return 0;
2144*48a54d36SAndroid Build Coastguard Worker }
2145*48a54d36SAndroid Build Coastguard Worker
2146*48a54d36SAndroid Build Coastguard Worker //----------
2147*48a54d36SAndroid Build Coastguard Worker // Types and Constants
2148*48a54d36SAndroid Build Coastguard Worker
2149*48a54d36SAndroid Build Coastguard Worker static const char * k_local_suffix = "local";
2150*48a54d36SAndroid Build Coastguard Worker static const char k_dns_separator = '.';
2151*48a54d36SAndroid Build Coastguard Worker
2152*48a54d36SAndroid Build Coastguard Worker static const int k_label_maxlen = DNS_LABEL_MAXLEN;
2153*48a54d36SAndroid Build Coastguard Worker // Label entries longer than this are actually pointers.
2154*48a54d36SAndroid Build Coastguard Worker
2155*48a54d36SAndroid Build Coastguard Worker typedef struct
2156*48a54d36SAndroid Build Coastguard Worker {
2157*48a54d36SAndroid Build Coastguard Worker int value;
2158*48a54d36SAndroid Build Coastguard Worker const char * name;
2159*48a54d36SAndroid Build Coastguard Worker const char * comment;
2160*48a54d36SAndroid Build Coastguard Worker } table_entry_t;
2161*48a54d36SAndroid Build Coastguard Worker
2162*48a54d36SAndroid Build Coastguard Worker static const table_entry_t k_table_af [] =
2163*48a54d36SAndroid Build Coastguard Worker {
2164*48a54d36SAndroid Build Coastguard Worker { AF_UNSPEC, NULL, NULL },
2165*48a54d36SAndroid Build Coastguard Worker { AF_LOCAL, "LOCAL", NULL },
2166*48a54d36SAndroid Build Coastguard Worker { AF_UNIX, "UNIX", NULL },
2167*48a54d36SAndroid Build Coastguard Worker { AF_INET, "INET", NULL },
2168*48a54d36SAndroid Build Coastguard Worker { AF_INET6, "INET6", NULL }
2169*48a54d36SAndroid Build Coastguard Worker };
2170*48a54d36SAndroid Build Coastguard Worker static const int k_table_af_size =
2171*48a54d36SAndroid Build Coastguard Worker sizeof (k_table_af) / sizeof (* k_table_af);
2172*48a54d36SAndroid Build Coastguard Worker
2173*48a54d36SAndroid Build Coastguard Worker static const char * k_table_ns_class [] =
2174*48a54d36SAndroid Build Coastguard Worker {
2175*48a54d36SAndroid Build Coastguard Worker NULL,
2176*48a54d36SAndroid Build Coastguard Worker "IN"
2177*48a54d36SAndroid Build Coastguard Worker };
2178*48a54d36SAndroid Build Coastguard Worker static const int k_table_ns_class_size =
2179*48a54d36SAndroid Build Coastguard Worker sizeof (k_table_ns_class) / sizeof (* k_table_ns_class);
2180*48a54d36SAndroid Build Coastguard Worker
2181*48a54d36SAndroid Build Coastguard Worker static const char * k_table_ns_type [] =
2182*48a54d36SAndroid Build Coastguard Worker {
2183*48a54d36SAndroid Build Coastguard Worker NULL,
2184*48a54d36SAndroid Build Coastguard Worker "A",
2185*48a54d36SAndroid Build Coastguard Worker "NS",
2186*48a54d36SAndroid Build Coastguard Worker "MD",
2187*48a54d36SAndroid Build Coastguard Worker "MF",
2188*48a54d36SAndroid Build Coastguard Worker "CNAME",
2189*48a54d36SAndroid Build Coastguard Worker "SOA",
2190*48a54d36SAndroid Build Coastguard Worker "MB",
2191*48a54d36SAndroid Build Coastguard Worker "MG",
2192*48a54d36SAndroid Build Coastguard Worker "MR",
2193*48a54d36SAndroid Build Coastguard Worker "NULL",
2194*48a54d36SAndroid Build Coastguard Worker "WKS",
2195*48a54d36SAndroid Build Coastguard Worker "PTR",
2196*48a54d36SAndroid Build Coastguard Worker "HINFO",
2197*48a54d36SAndroid Build Coastguard Worker "MINFO",
2198*48a54d36SAndroid Build Coastguard Worker "MX",
2199*48a54d36SAndroid Build Coastguard Worker "TXT",
2200*48a54d36SAndroid Build Coastguard Worker "RP",
2201*48a54d36SAndroid Build Coastguard Worker "AFSDB",
2202*48a54d36SAndroid Build Coastguard Worker "X25",
2203*48a54d36SAndroid Build Coastguard Worker "ISDN",
2204*48a54d36SAndroid Build Coastguard Worker "RT",
2205*48a54d36SAndroid Build Coastguard Worker "NSAP",
2206*48a54d36SAndroid Build Coastguard Worker NULL,
2207*48a54d36SAndroid Build Coastguard Worker "SIG",
2208*48a54d36SAndroid Build Coastguard Worker "KEY",
2209*48a54d36SAndroid Build Coastguard Worker "PX",
2210*48a54d36SAndroid Build Coastguard Worker "GPOS",
2211*48a54d36SAndroid Build Coastguard Worker "AAAA",
2212*48a54d36SAndroid Build Coastguard Worker "LOC",
2213*48a54d36SAndroid Build Coastguard Worker "NXT",
2214*48a54d36SAndroid Build Coastguard Worker "EID",
2215*48a54d36SAndroid Build Coastguard Worker "NIMLOC",
2216*48a54d36SAndroid Build Coastguard Worker "SRV",
2217*48a54d36SAndroid Build Coastguard Worker "ATMA",
2218*48a54d36SAndroid Build Coastguard Worker "NAPTR",
2219*48a54d36SAndroid Build Coastguard Worker "KX",
2220*48a54d36SAndroid Build Coastguard Worker "CERT",
2221*48a54d36SAndroid Build Coastguard Worker "A6",
2222*48a54d36SAndroid Build Coastguard Worker "DNAME",
2223*48a54d36SAndroid Build Coastguard Worker "SINK",
2224*48a54d36SAndroid Build Coastguard Worker "OPT"
2225*48a54d36SAndroid Build Coastguard Worker };
2226*48a54d36SAndroid Build Coastguard Worker static const int k_table_ns_type_size =
2227*48a54d36SAndroid Build Coastguard Worker sizeof (k_table_ns_type) / sizeof (* k_table_ns_type);
2228*48a54d36SAndroid Build Coastguard Worker
2229*48a54d36SAndroid Build Coastguard Worker
2230*48a54d36SAndroid Build Coastguard Worker //----------
2231*48a54d36SAndroid Build Coastguard Worker // Local prototypes
2232*48a54d36SAndroid Build Coastguard Worker
2233*48a54d36SAndroid Build Coastguard Worker static int
2234*48a54d36SAndroid Build Coastguard Worker simple_table_index (const char * table [], int size, const char * str);
2235*48a54d36SAndroid Build Coastguard Worker
2236*48a54d36SAndroid Build Coastguard Worker static int
2237*48a54d36SAndroid Build Coastguard Worker table_index_name (const table_entry_t table [], int size, const char * str);
2238*48a54d36SAndroid Build Coastguard Worker
2239*48a54d36SAndroid Build Coastguard Worker static int
2240*48a54d36SAndroid Build Coastguard Worker table_index_value (const table_entry_t table [], int size, int n);
2241*48a54d36SAndroid Build Coastguard Worker
2242*48a54d36SAndroid Build Coastguard Worker
2243*48a54d36SAndroid Build Coastguard Worker //----------
2244*48a54d36SAndroid Build Coastguard Worker // Global variables
2245*48a54d36SAndroid Build Coastguard Worker
2246*48a54d36SAndroid Build Coastguard Worker
2247*48a54d36SAndroid Build Coastguard Worker //----------
2248*48a54d36SAndroid Build Coastguard Worker // Util functions
2249*48a54d36SAndroid Build Coastguard Worker
2250*48a54d36SAndroid Build Coastguard Worker int
count_dots(const char * name)2251*48a54d36SAndroid Build Coastguard Worker count_dots (const char * name)
2252*48a54d36SAndroid Build Coastguard Worker {
2253*48a54d36SAndroid Build Coastguard Worker int count = 0;
2254*48a54d36SAndroid Build Coastguard Worker int i;
2255*48a54d36SAndroid Build Coastguard Worker for (i = 0; name[i]; i++)
2256*48a54d36SAndroid Build Coastguard Worker {
2257*48a54d36SAndroid Build Coastguard Worker if (name [i] == k_dns_separator)
2258*48a54d36SAndroid Build Coastguard Worker count++;
2259*48a54d36SAndroid Build Coastguard Worker }
2260*48a54d36SAndroid Build Coastguard Worker
2261*48a54d36SAndroid Build Coastguard Worker return count;
2262*48a54d36SAndroid Build Coastguard Worker }
2263*48a54d36SAndroid Build Coastguard Worker
2264*48a54d36SAndroid Build Coastguard Worker
2265*48a54d36SAndroid Build Coastguard Worker int
islocal(const char * name)2266*48a54d36SAndroid Build Coastguard Worker islocal (const char * name)
2267*48a54d36SAndroid Build Coastguard Worker {
2268*48a54d36SAndroid Build Coastguard Worker return cmp_dns_suffix (name, k_local_suffix) > 0;
2269*48a54d36SAndroid Build Coastguard Worker }
2270*48a54d36SAndroid Build Coastguard Worker
2271*48a54d36SAndroid Build Coastguard Worker
2272*48a54d36SAndroid Build Coastguard Worker int
rr_to_af(ns_type_t rrtype)2273*48a54d36SAndroid Build Coastguard Worker rr_to_af (ns_type_t rrtype)
2274*48a54d36SAndroid Build Coastguard Worker {
2275*48a54d36SAndroid Build Coastguard Worker switch (rrtype)
2276*48a54d36SAndroid Build Coastguard Worker {
2277*48a54d36SAndroid Build Coastguard Worker case kDNSServiceType_A:
2278*48a54d36SAndroid Build Coastguard Worker return AF_INET;
2279*48a54d36SAndroid Build Coastguard Worker
2280*48a54d36SAndroid Build Coastguard Worker case kDNSServiceType_AAAA:
2281*48a54d36SAndroid Build Coastguard Worker return AF_INET6;
2282*48a54d36SAndroid Build Coastguard Worker
2283*48a54d36SAndroid Build Coastguard Worker default:
2284*48a54d36SAndroid Build Coastguard Worker return AF_UNSPEC;
2285*48a54d36SAndroid Build Coastguard Worker }
2286*48a54d36SAndroid Build Coastguard Worker }
2287*48a54d36SAndroid Build Coastguard Worker
2288*48a54d36SAndroid Build Coastguard Worker
2289*48a54d36SAndroid Build Coastguard Worker ns_type_t
af_to_rr(int af)2290*48a54d36SAndroid Build Coastguard Worker af_to_rr (int af)
2291*48a54d36SAndroid Build Coastguard Worker {
2292*48a54d36SAndroid Build Coastguard Worker switch (af)
2293*48a54d36SAndroid Build Coastguard Worker {
2294*48a54d36SAndroid Build Coastguard Worker case AF_INET:
2295*48a54d36SAndroid Build Coastguard Worker return kDNSServiceType_A;
2296*48a54d36SAndroid Build Coastguard Worker
2297*48a54d36SAndroid Build Coastguard Worker case AF_INET6:
2298*48a54d36SAndroid Build Coastguard Worker return kDNSServiceType_AAAA;
2299*48a54d36SAndroid Build Coastguard Worker
2300*48a54d36SAndroid Build Coastguard Worker default:
2301*48a54d36SAndroid Build Coastguard Worker //return ns_t_invalid;
2302*48a54d36SAndroid Build Coastguard Worker return 0;
2303*48a54d36SAndroid Build Coastguard Worker }
2304*48a54d36SAndroid Build Coastguard Worker }
2305*48a54d36SAndroid Build Coastguard Worker
2306*48a54d36SAndroid Build Coastguard Worker
2307*48a54d36SAndroid Build Coastguard Worker int
str_to_af(const char * str)2308*48a54d36SAndroid Build Coastguard Worker str_to_af (const char * str)
2309*48a54d36SAndroid Build Coastguard Worker {
2310*48a54d36SAndroid Build Coastguard Worker int result =
2311*48a54d36SAndroid Build Coastguard Worker table_index_name (k_table_af, k_table_af_size, str);
2312*48a54d36SAndroid Build Coastguard Worker if (result < 0)
2313*48a54d36SAndroid Build Coastguard Worker result = 0;
2314*48a54d36SAndroid Build Coastguard Worker
2315*48a54d36SAndroid Build Coastguard Worker return k_table_af [result].value;
2316*48a54d36SAndroid Build Coastguard Worker }
2317*48a54d36SAndroid Build Coastguard Worker
2318*48a54d36SAndroid Build Coastguard Worker
2319*48a54d36SAndroid Build Coastguard Worker ns_class_t
str_to_ns_class(const char * str)2320*48a54d36SAndroid Build Coastguard Worker str_to_ns_class (const char * str)
2321*48a54d36SAndroid Build Coastguard Worker {
2322*48a54d36SAndroid Build Coastguard Worker return (ns_class_t)
2323*48a54d36SAndroid Build Coastguard Worker simple_table_index (k_table_ns_class, k_table_ns_class_size, str);
2324*48a54d36SAndroid Build Coastguard Worker }
2325*48a54d36SAndroid Build Coastguard Worker
2326*48a54d36SAndroid Build Coastguard Worker
2327*48a54d36SAndroid Build Coastguard Worker ns_type_t
str_to_ns_type(const char * str)2328*48a54d36SAndroid Build Coastguard Worker str_to_ns_type (const char * str)
2329*48a54d36SAndroid Build Coastguard Worker {
2330*48a54d36SAndroid Build Coastguard Worker return (ns_type_t)
2331*48a54d36SAndroid Build Coastguard Worker simple_table_index (k_table_ns_type, k_table_ns_type_size, str);
2332*48a54d36SAndroid Build Coastguard Worker }
2333*48a54d36SAndroid Build Coastguard Worker
2334*48a54d36SAndroid Build Coastguard Worker
2335*48a54d36SAndroid Build Coastguard Worker const char *
af_to_str(int in)2336*48a54d36SAndroid Build Coastguard Worker af_to_str (int in)
2337*48a54d36SAndroid Build Coastguard Worker {
2338*48a54d36SAndroid Build Coastguard Worker int result =
2339*48a54d36SAndroid Build Coastguard Worker table_index_value (k_table_af, k_table_af_size, in);
2340*48a54d36SAndroid Build Coastguard Worker if (result < 0)
2341*48a54d36SAndroid Build Coastguard Worker result = 0;
2342*48a54d36SAndroid Build Coastguard Worker
2343*48a54d36SAndroid Build Coastguard Worker return k_table_af [result].name;
2344*48a54d36SAndroid Build Coastguard Worker }
2345*48a54d36SAndroid Build Coastguard Worker
2346*48a54d36SAndroid Build Coastguard Worker
2347*48a54d36SAndroid Build Coastguard Worker const char *
ns_class_to_str(ns_class_t in)2348*48a54d36SAndroid Build Coastguard Worker ns_class_to_str (ns_class_t in)
2349*48a54d36SAndroid Build Coastguard Worker {
2350*48a54d36SAndroid Build Coastguard Worker if (in < k_table_ns_class_size)
2351*48a54d36SAndroid Build Coastguard Worker return k_table_ns_class [in];
2352*48a54d36SAndroid Build Coastguard Worker else
2353*48a54d36SAndroid Build Coastguard Worker return NULL;
2354*48a54d36SAndroid Build Coastguard Worker }
2355*48a54d36SAndroid Build Coastguard Worker
2356*48a54d36SAndroid Build Coastguard Worker
2357*48a54d36SAndroid Build Coastguard Worker const char *
ns_type_to_str(ns_type_t in)2358*48a54d36SAndroid Build Coastguard Worker ns_type_to_str (ns_type_t in)
2359*48a54d36SAndroid Build Coastguard Worker {
2360*48a54d36SAndroid Build Coastguard Worker if (in < k_table_ns_type_size)
2361*48a54d36SAndroid Build Coastguard Worker return k_table_ns_type [in];
2362*48a54d36SAndroid Build Coastguard Worker else
2363*48a54d36SAndroid Build Coastguard Worker return NULL;
2364*48a54d36SAndroid Build Coastguard Worker }
2365*48a54d36SAndroid Build Coastguard Worker
2366*48a54d36SAndroid Build Coastguard Worker
2367*48a54d36SAndroid Build Coastguard Worker char *
format_reverse_addr_in(const struct in_addr * addr,int prefixlen,char * buf)2368*48a54d36SAndroid Build Coastguard Worker format_reverse_addr_in (
2369*48a54d36SAndroid Build Coastguard Worker const struct in_addr * addr,
2370*48a54d36SAndroid Build Coastguard Worker int prefixlen,
2371*48a54d36SAndroid Build Coastguard Worker char * buf
2372*48a54d36SAndroid Build Coastguard Worker )
2373*48a54d36SAndroid Build Coastguard Worker {
2374*48a54d36SAndroid Build Coastguard Worker char * curr = buf;
2375*48a54d36SAndroid Build Coastguard Worker int i;
2376*48a54d36SAndroid Build Coastguard Worker
2377*48a54d36SAndroid Build Coastguard Worker const uint8_t * in_addr_a = (uint8_t *) addr;
2378*48a54d36SAndroid Build Coastguard Worker
2379*48a54d36SAndroid Build Coastguard Worker if (prefixlen > 32)
2380*48a54d36SAndroid Build Coastguard Worker return NULL;
2381*48a54d36SAndroid Build Coastguard Worker if (prefixlen < 0)
2382*48a54d36SAndroid Build Coastguard Worker prefixlen = 32;
2383*48a54d36SAndroid Build Coastguard Worker
2384*48a54d36SAndroid Build Coastguard Worker i = (prefixlen + 7) / 8;
2385*48a54d36SAndroid Build Coastguard Worker // divide prefixlen into bytes, rounding up
2386*48a54d36SAndroid Build Coastguard Worker
2387*48a54d36SAndroid Build Coastguard Worker while (i > 0)
2388*48a54d36SAndroid Build Coastguard Worker {
2389*48a54d36SAndroid Build Coastguard Worker i--;
2390*48a54d36SAndroid Build Coastguard Worker curr += sprintf (curr, "%d.", in_addr_a [i]);
2391*48a54d36SAndroid Build Coastguard Worker }
2392*48a54d36SAndroid Build Coastguard Worker sprintf (curr, "in-addr.arpa");
2393*48a54d36SAndroid Build Coastguard Worker
2394*48a54d36SAndroid Build Coastguard Worker return buf;
2395*48a54d36SAndroid Build Coastguard Worker }
2396*48a54d36SAndroid Build Coastguard Worker
2397*48a54d36SAndroid Build Coastguard Worker
2398*48a54d36SAndroid Build Coastguard Worker char *
format_reverse_addr_in6(const struct in6_addr * addr,int prefixlen,char * buf)2399*48a54d36SAndroid Build Coastguard Worker format_reverse_addr_in6 (
2400*48a54d36SAndroid Build Coastguard Worker const struct in6_addr * addr,
2401*48a54d36SAndroid Build Coastguard Worker int prefixlen,
2402*48a54d36SAndroid Build Coastguard Worker char * buf
2403*48a54d36SAndroid Build Coastguard Worker )
2404*48a54d36SAndroid Build Coastguard Worker {
2405*48a54d36SAndroid Build Coastguard Worker char * curr = buf;
2406*48a54d36SAndroid Build Coastguard Worker int i;
2407*48a54d36SAndroid Build Coastguard Worker
2408*48a54d36SAndroid Build Coastguard Worker const uint8_t * in_addr_a = (uint8_t *) addr;
2409*48a54d36SAndroid Build Coastguard Worker
2410*48a54d36SAndroid Build Coastguard Worker if (prefixlen > 128)
2411*48a54d36SAndroid Build Coastguard Worker return NULL;
2412*48a54d36SAndroid Build Coastguard Worker if (prefixlen < 0)
2413*48a54d36SAndroid Build Coastguard Worker prefixlen = 128;
2414*48a54d36SAndroid Build Coastguard Worker
2415*48a54d36SAndroid Build Coastguard Worker i = (prefixlen + 3) / 4;
2416*48a54d36SAndroid Build Coastguard Worker // divide prefixlen into nibbles, rounding up
2417*48a54d36SAndroid Build Coastguard Worker
2418*48a54d36SAndroid Build Coastguard Worker // Special handling for first
2419*48a54d36SAndroid Build Coastguard Worker if (i % 2)
2420*48a54d36SAndroid Build Coastguard Worker {
2421*48a54d36SAndroid Build Coastguard Worker curr += sprintf (curr, "%d.", (in_addr_a [i/2] >> 4) & 0x0F);
2422*48a54d36SAndroid Build Coastguard Worker }
2423*48a54d36SAndroid Build Coastguard Worker i >>= 1;
2424*48a54d36SAndroid Build Coastguard Worker // Convert i to bytes (divide by 2)
2425*48a54d36SAndroid Build Coastguard Worker
2426*48a54d36SAndroid Build Coastguard Worker while (i > 0)
2427*48a54d36SAndroid Build Coastguard Worker {
2428*48a54d36SAndroid Build Coastguard Worker uint8_t val;
2429*48a54d36SAndroid Build Coastguard Worker
2430*48a54d36SAndroid Build Coastguard Worker i--;
2431*48a54d36SAndroid Build Coastguard Worker val = in_addr_a [i];
2432*48a54d36SAndroid Build Coastguard Worker curr += sprintf (curr, "%x.%x.", val & 0x0F, (val >> 4) & 0x0F);
2433*48a54d36SAndroid Build Coastguard Worker }
2434*48a54d36SAndroid Build Coastguard Worker sprintf (curr, "ip6.arpa");
2435*48a54d36SAndroid Build Coastguard Worker
2436*48a54d36SAndroid Build Coastguard Worker return buf;
2437*48a54d36SAndroid Build Coastguard Worker }
2438*48a54d36SAndroid Build Coastguard Worker
2439*48a54d36SAndroid Build Coastguard Worker
2440*48a54d36SAndroid Build Coastguard Worker char *
format_reverse_addr(int af,const void * addr,int prefixlen,char * buf)2441*48a54d36SAndroid Build Coastguard Worker format_reverse_addr (
2442*48a54d36SAndroid Build Coastguard Worker int af,
2443*48a54d36SAndroid Build Coastguard Worker const void * addr,
2444*48a54d36SAndroid Build Coastguard Worker int prefixlen,
2445*48a54d36SAndroid Build Coastguard Worker char * buf
2446*48a54d36SAndroid Build Coastguard Worker )
2447*48a54d36SAndroid Build Coastguard Worker {
2448*48a54d36SAndroid Build Coastguard Worker switch (af)
2449*48a54d36SAndroid Build Coastguard Worker {
2450*48a54d36SAndroid Build Coastguard Worker case AF_INET:
2451*48a54d36SAndroid Build Coastguard Worker return
2452*48a54d36SAndroid Build Coastguard Worker format_reverse_addr_in (
2453*48a54d36SAndroid Build Coastguard Worker (struct in_addr *) addr, prefixlen, buf
2454*48a54d36SAndroid Build Coastguard Worker );
2455*48a54d36SAndroid Build Coastguard Worker break;
2456*48a54d36SAndroid Build Coastguard Worker
2457*48a54d36SAndroid Build Coastguard Worker case AF_INET6:
2458*48a54d36SAndroid Build Coastguard Worker return
2459*48a54d36SAndroid Build Coastguard Worker format_reverse_addr_in6 (
2460*48a54d36SAndroid Build Coastguard Worker (struct in6_addr *) addr, prefixlen, buf
2461*48a54d36SAndroid Build Coastguard Worker );
2462*48a54d36SAndroid Build Coastguard Worker break;
2463*48a54d36SAndroid Build Coastguard Worker
2464*48a54d36SAndroid Build Coastguard Worker default:
2465*48a54d36SAndroid Build Coastguard Worker return NULL;
2466*48a54d36SAndroid Build Coastguard Worker }
2467*48a54d36SAndroid Build Coastguard Worker }
2468*48a54d36SAndroid Build Coastguard Worker
2469*48a54d36SAndroid Build Coastguard Worker
2470*48a54d36SAndroid Build Coastguard Worker int
cmp_dns_suffix(const char * name,const char * domain)2471*48a54d36SAndroid Build Coastguard Worker cmp_dns_suffix (const char * name, const char * domain)
2472*48a54d36SAndroid Build Coastguard Worker {
2473*48a54d36SAndroid Build Coastguard Worker const char * nametail;
2474*48a54d36SAndroid Build Coastguard Worker const char * domaintail;
2475*48a54d36SAndroid Build Coastguard Worker
2476*48a54d36SAndroid Build Coastguard Worker // Idiot checks
2477*48a54d36SAndroid Build Coastguard Worker if (*name == 0 || *name == k_dns_separator)
2478*48a54d36SAndroid Build Coastguard Worker {
2479*48a54d36SAndroid Build Coastguard Worker // Name can't be empty or start with separator
2480*48a54d36SAndroid Build Coastguard Worker return CMP_DNS_SUFFIX_BAD_NAME;
2481*48a54d36SAndroid Build Coastguard Worker }
2482*48a54d36SAndroid Build Coastguard Worker
2483*48a54d36SAndroid Build Coastguard Worker if (*domain == 0)
2484*48a54d36SAndroid Build Coastguard Worker {
2485*48a54d36SAndroid Build Coastguard Worker return CMP_DNS_SUFFIX_SUCCESS;
2486*48a54d36SAndroid Build Coastguard Worker // trivially true
2487*48a54d36SAndroid Build Coastguard Worker }
2488*48a54d36SAndroid Build Coastguard Worker
2489*48a54d36SAndroid Build Coastguard Worker if (*domain == k_dns_separator)
2490*48a54d36SAndroid Build Coastguard Worker {
2491*48a54d36SAndroid Build Coastguard Worker // drop leading separator from domain
2492*48a54d36SAndroid Build Coastguard Worker domain++;
2493*48a54d36SAndroid Build Coastguard Worker if (*domain == k_dns_separator)
2494*48a54d36SAndroid Build Coastguard Worker {
2495*48a54d36SAndroid Build Coastguard Worker return CMP_DNS_SUFFIX_BAD_DOMAIN;
2496*48a54d36SAndroid Build Coastguard Worker }
2497*48a54d36SAndroid Build Coastguard Worker }
2498*48a54d36SAndroid Build Coastguard Worker
2499*48a54d36SAndroid Build Coastguard Worker // Find ends of strings
2500*48a54d36SAndroid Build Coastguard Worker for (nametail = name; *nametail; nametail++)
2501*48a54d36SAndroid Build Coastguard Worker ;
2502*48a54d36SAndroid Build Coastguard Worker for (domaintail = domain; *domaintail; domaintail++)
2503*48a54d36SAndroid Build Coastguard Worker ;
2504*48a54d36SAndroid Build Coastguard Worker
2505*48a54d36SAndroid Build Coastguard Worker // Shuffle back to last real character, and drop any trailing '.'
2506*48a54d36SAndroid Build Coastguard Worker // while we're at it.
2507*48a54d36SAndroid Build Coastguard Worker nametail --;
2508*48a54d36SAndroid Build Coastguard Worker if (*nametail == k_dns_separator)
2509*48a54d36SAndroid Build Coastguard Worker {
2510*48a54d36SAndroid Build Coastguard Worker nametail --;
2511*48a54d36SAndroid Build Coastguard Worker if (*nametail == k_dns_separator)
2512*48a54d36SAndroid Build Coastguard Worker {
2513*48a54d36SAndroid Build Coastguard Worker return CMP_DNS_SUFFIX_BAD_NAME;
2514*48a54d36SAndroid Build Coastguard Worker }
2515*48a54d36SAndroid Build Coastguard Worker }
2516*48a54d36SAndroid Build Coastguard Worker domaintail --;
2517*48a54d36SAndroid Build Coastguard Worker if (*domaintail == k_dns_separator)
2518*48a54d36SAndroid Build Coastguard Worker {
2519*48a54d36SAndroid Build Coastguard Worker domaintail --;
2520*48a54d36SAndroid Build Coastguard Worker if (*domaintail == k_dns_separator)
2521*48a54d36SAndroid Build Coastguard Worker {
2522*48a54d36SAndroid Build Coastguard Worker return CMP_DNS_SUFFIX_BAD_DOMAIN;
2523*48a54d36SAndroid Build Coastguard Worker }
2524*48a54d36SAndroid Build Coastguard Worker }
2525*48a54d36SAndroid Build Coastguard Worker
2526*48a54d36SAndroid Build Coastguard Worker // Compare.
2527*48a54d36SAndroid Build Coastguard Worker while (
2528*48a54d36SAndroid Build Coastguard Worker nametail >= name
2529*48a54d36SAndroid Build Coastguard Worker && domaintail >= domain
2530*48a54d36SAndroid Build Coastguard Worker && tolower(*nametail) == tolower(*domaintail))
2531*48a54d36SAndroid Build Coastguard Worker {
2532*48a54d36SAndroid Build Coastguard Worker nametail--;
2533*48a54d36SAndroid Build Coastguard Worker domaintail--;
2534*48a54d36SAndroid Build Coastguard Worker }
2535*48a54d36SAndroid Build Coastguard Worker
2536*48a54d36SAndroid Build Coastguard Worker /* A successful finish will be one of the following:
2537*48a54d36SAndroid Build Coastguard Worker (leading and trailing . ignored)
2538*48a54d36SAndroid Build Coastguard Worker
2539*48a54d36SAndroid Build Coastguard Worker name : domain2.domain1
2540*48a54d36SAndroid Build Coastguard Worker domain: domain2.domain1
2541*48a54d36SAndroid Build Coastguard Worker ^
2542*48a54d36SAndroid Build Coastguard Worker
2543*48a54d36SAndroid Build Coastguard Worker name : domain3.domain2.domain1
2544*48a54d36SAndroid Build Coastguard Worker domain: domain2.domain1
2545*48a54d36SAndroid Build Coastguard Worker ^
2546*48a54d36SAndroid Build Coastguard Worker */
2547*48a54d36SAndroid Build Coastguard Worker if (
2548*48a54d36SAndroid Build Coastguard Worker domaintail < domain
2549*48a54d36SAndroid Build Coastguard Worker && (nametail < name || *nametail == k_dns_separator)
2550*48a54d36SAndroid Build Coastguard Worker )
2551*48a54d36SAndroid Build Coastguard Worker {
2552*48a54d36SAndroid Build Coastguard Worker return CMP_DNS_SUFFIX_SUCCESS;
2553*48a54d36SAndroid Build Coastguard Worker }
2554*48a54d36SAndroid Build Coastguard Worker else
2555*48a54d36SAndroid Build Coastguard Worker {
2556*48a54d36SAndroid Build Coastguard Worker return CMP_DNS_SUFFIX_FAILURE;
2557*48a54d36SAndroid Build Coastguard Worker }
2558*48a54d36SAndroid Build Coastguard Worker }
2559*48a54d36SAndroid Build Coastguard Worker
2560*48a54d36SAndroid Build Coastguard Worker
2561*48a54d36SAndroid Build Coastguard Worker int
dns_rdata_to_name(const char * rdata,int rdlen,char * name,int name_len)2562*48a54d36SAndroid Build Coastguard Worker dns_rdata_to_name (const char * rdata, int rdlen, char * name, int name_len)
2563*48a54d36SAndroid Build Coastguard Worker {
2564*48a54d36SAndroid Build Coastguard Worker int i = 0;
2565*48a54d36SAndroid Build Coastguard Worker // Index into 'name'
2566*48a54d36SAndroid Build Coastguard Worker const char * rdata_curr = rdata;
2567*48a54d36SAndroid Build Coastguard Worker
2568*48a54d36SAndroid Build Coastguard Worker if (rdlen == 0) return DNS_RDATA_TO_NAME_BAD_FORMAT;
2569*48a54d36SAndroid Build Coastguard Worker
2570*48a54d36SAndroid Build Coastguard Worker /*
2571*48a54d36SAndroid Build Coastguard Worker In RDATA, a DNS name is stored as a series of labels.
2572*48a54d36SAndroid Build Coastguard Worker Each label consists of a length octet (max value 63)
2573*48a54d36SAndroid Build Coastguard Worker followed by the data for that label.
2574*48a54d36SAndroid Build Coastguard Worker The series is terminated with a length 0 octet.
2575*48a54d36SAndroid Build Coastguard Worker A length octet beginning with bits 11 is a pointer to
2576*48a54d36SAndroid Build Coastguard Worker somewhere else in the payload, but we don't support these
2577*48a54d36SAndroid Build Coastguard Worker since we don't have access to the entire payload.
2578*48a54d36SAndroid Build Coastguard Worker
2579*48a54d36SAndroid Build Coastguard Worker See RFC1034 section 3.1 and RFC1035 section 3.1.
2580*48a54d36SAndroid Build Coastguard Worker */
2581*48a54d36SAndroid Build Coastguard Worker while (1)
2582*48a54d36SAndroid Build Coastguard Worker {
2583*48a54d36SAndroid Build Coastguard Worker int term_len = *rdata_curr;
2584*48a54d36SAndroid Build Coastguard Worker rdata_curr++;
2585*48a54d36SAndroid Build Coastguard Worker
2586*48a54d36SAndroid Build Coastguard Worker if (term_len == 0)
2587*48a54d36SAndroid Build Coastguard Worker {
2588*48a54d36SAndroid Build Coastguard Worker break;
2589*48a54d36SAndroid Build Coastguard Worker // 0 length record terminates label
2590*48a54d36SAndroid Build Coastguard Worker }
2591*48a54d36SAndroid Build Coastguard Worker else if (term_len > k_label_maxlen)
2592*48a54d36SAndroid Build Coastguard Worker {
2593*48a54d36SAndroid Build Coastguard Worker name [i] = 0;
2594*48a54d36SAndroid Build Coastguard Worker return DNS_RDATA_TO_NAME_PTR;
2595*48a54d36SAndroid Build Coastguard Worker }
2596*48a54d36SAndroid Build Coastguard Worker else if (rdata_curr + term_len > rdata + rdlen)
2597*48a54d36SAndroid Build Coastguard Worker {
2598*48a54d36SAndroid Build Coastguard Worker name [i] = 0;
2599*48a54d36SAndroid Build Coastguard Worker return DNS_RDATA_TO_NAME_BAD_FORMAT;
2600*48a54d36SAndroid Build Coastguard Worker }
2601*48a54d36SAndroid Build Coastguard Worker
2602*48a54d36SAndroid Build Coastguard Worker if (name_len < i + term_len + 1)
2603*48a54d36SAndroid Build Coastguard Worker // +1 is separator
2604*48a54d36SAndroid Build Coastguard Worker {
2605*48a54d36SAndroid Build Coastguard Worker name [i] = 0;
2606*48a54d36SAndroid Build Coastguard Worker return DNS_RDATA_TO_NAME_TOO_LONG;
2607*48a54d36SAndroid Build Coastguard Worker }
2608*48a54d36SAndroid Build Coastguard Worker
2609*48a54d36SAndroid Build Coastguard Worker memcpy (name + i, rdata_curr, term_len);
2610*48a54d36SAndroid Build Coastguard Worker
2611*48a54d36SAndroid Build Coastguard Worker i += term_len;
2612*48a54d36SAndroid Build Coastguard Worker rdata_curr += term_len;
2613*48a54d36SAndroid Build Coastguard Worker
2614*48a54d36SAndroid Build Coastguard Worker name [i] = k_dns_separator;
2615*48a54d36SAndroid Build Coastguard Worker i++;
2616*48a54d36SAndroid Build Coastguard Worker }
2617*48a54d36SAndroid Build Coastguard Worker
2618*48a54d36SAndroid Build Coastguard Worker name [i] = 0;
2619*48a54d36SAndroid Build Coastguard Worker return i;
2620*48a54d36SAndroid Build Coastguard Worker }
2621*48a54d36SAndroid Build Coastguard Worker
2622*48a54d36SAndroid Build Coastguard Worker
2623*48a54d36SAndroid Build Coastguard Worker //----------
2624*48a54d36SAndroid Build Coastguard Worker // Local functions
2625*48a54d36SAndroid Build Coastguard Worker
2626*48a54d36SAndroid Build Coastguard Worker /*
2627*48a54d36SAndroid Build Coastguard Worker Find the index of an string entry in a table. A case insenitive match
2628*48a54d36SAndroid Build Coastguard Worker is performed. If no entry is found, 0 is returned.
2629*48a54d36SAndroid Build Coastguard Worker
2630*48a54d36SAndroid Build Coastguard Worker Parameters
2631*48a54d36SAndroid Build Coastguard Worker table
2632*48a54d36SAndroid Build Coastguard Worker Lookup table
2633*48a54d36SAndroid Build Coastguard Worker Table entries may be NULL. NULL entries will never match.
2634*48a54d36SAndroid Build Coastguard Worker size
2635*48a54d36SAndroid Build Coastguard Worker number of entries in table
2636*48a54d36SAndroid Build Coastguard Worker str
2637*48a54d36SAndroid Build Coastguard Worker lookup string
2638*48a54d36SAndroid Build Coastguard Worker
2639*48a54d36SAndroid Build Coastguard Worker Result
2640*48a54d36SAndroid Build Coastguard Worker index of first matching entry, or 0 if no matches
2641*48a54d36SAndroid Build Coastguard Worker */
2642*48a54d36SAndroid Build Coastguard Worker static int
simple_table_index(const char * table[],int size,const char * str)2643*48a54d36SAndroid Build Coastguard Worker simple_table_index (const char * table [], int size, const char * str)
2644*48a54d36SAndroid Build Coastguard Worker {
2645*48a54d36SAndroid Build Coastguard Worker int i;
2646*48a54d36SAndroid Build Coastguard Worker for (i = 0; i < size; i++)
2647*48a54d36SAndroid Build Coastguard Worker {
2648*48a54d36SAndroid Build Coastguard Worker if (
2649*48a54d36SAndroid Build Coastguard Worker table [i]
2650*48a54d36SAndroid Build Coastguard Worker && (strcasecmp (table [i], str) == 0)
2651*48a54d36SAndroid Build Coastguard Worker )
2652*48a54d36SAndroid Build Coastguard Worker {
2653*48a54d36SAndroid Build Coastguard Worker return i;
2654*48a54d36SAndroid Build Coastguard Worker }
2655*48a54d36SAndroid Build Coastguard Worker }
2656*48a54d36SAndroid Build Coastguard Worker
2657*48a54d36SAndroid Build Coastguard Worker return 0;
2658*48a54d36SAndroid Build Coastguard Worker }
2659*48a54d36SAndroid Build Coastguard Worker
2660*48a54d36SAndroid Build Coastguard Worker
2661*48a54d36SAndroid Build Coastguard Worker /*
2662*48a54d36SAndroid Build Coastguard Worker Find the index of a name in a table.
2663*48a54d36SAndroid Build Coastguard Worker
2664*48a54d36SAndroid Build Coastguard Worker Parameters
2665*48a54d36SAndroid Build Coastguard Worker table
2666*48a54d36SAndroid Build Coastguard Worker array of table_entry_t records. The name field is compared
2667*48a54d36SAndroid Build Coastguard Worker (ignoring case) to the input string.
2668*48a54d36SAndroid Build Coastguard Worker size
2669*48a54d36SAndroid Build Coastguard Worker number of entries in table
2670*48a54d36SAndroid Build Coastguard Worker str
2671*48a54d36SAndroid Build Coastguard Worker lookup string
2672*48a54d36SAndroid Build Coastguard Worker
2673*48a54d36SAndroid Build Coastguard Worker Result
2674*48a54d36SAndroid Build Coastguard Worker index of first matching entry, or -1 if no matches
2675*48a54d36SAndroid Build Coastguard Worker */
2676*48a54d36SAndroid Build Coastguard Worker static int
table_index_name(const table_entry_t table[],int size,const char * str)2677*48a54d36SAndroid Build Coastguard Worker table_index_name (const table_entry_t table [], int size, const char * str)
2678*48a54d36SAndroid Build Coastguard Worker {
2679*48a54d36SAndroid Build Coastguard Worker int i;
2680*48a54d36SAndroid Build Coastguard Worker for (i = 0; i < size; i++)
2681*48a54d36SAndroid Build Coastguard Worker {
2682*48a54d36SAndroid Build Coastguard Worker if (
2683*48a54d36SAndroid Build Coastguard Worker table [i].name
2684*48a54d36SAndroid Build Coastguard Worker && (strcasecmp (table [i].name, str) == 0)
2685*48a54d36SAndroid Build Coastguard Worker )
2686*48a54d36SAndroid Build Coastguard Worker {
2687*48a54d36SAndroid Build Coastguard Worker return i;
2688*48a54d36SAndroid Build Coastguard Worker }
2689*48a54d36SAndroid Build Coastguard Worker }
2690*48a54d36SAndroid Build Coastguard Worker
2691*48a54d36SAndroid Build Coastguard Worker return -1;
2692*48a54d36SAndroid Build Coastguard Worker }
2693*48a54d36SAndroid Build Coastguard Worker
2694*48a54d36SAndroid Build Coastguard Worker
2695*48a54d36SAndroid Build Coastguard Worker /*
2696*48a54d36SAndroid Build Coastguard Worker Find the index of a value a table.
2697*48a54d36SAndroid Build Coastguard Worker
2698*48a54d36SAndroid Build Coastguard Worker Parameters
2699*48a54d36SAndroid Build Coastguard Worker table
2700*48a54d36SAndroid Build Coastguard Worker array of table_entry_t records. The value field is compared to
2701*48a54d36SAndroid Build Coastguard Worker the input value
2702*48a54d36SAndroid Build Coastguard Worker size
2703*48a54d36SAndroid Build Coastguard Worker number of entries in table
2704*48a54d36SAndroid Build Coastguard Worker n
2705*48a54d36SAndroid Build Coastguard Worker lookup value
2706*48a54d36SAndroid Build Coastguard Worker
2707*48a54d36SAndroid Build Coastguard Worker Result
2708*48a54d36SAndroid Build Coastguard Worker index of first matching entry, or -1 if no matches
2709*48a54d36SAndroid Build Coastguard Worker */
2710*48a54d36SAndroid Build Coastguard Worker static int
table_index_value(const table_entry_t table[],int size,int n)2711*48a54d36SAndroid Build Coastguard Worker table_index_value (const table_entry_t table [], int size, int n)
2712*48a54d36SAndroid Build Coastguard Worker {
2713*48a54d36SAndroid Build Coastguard Worker int i;
2714*48a54d36SAndroid Build Coastguard Worker for (i = 0; i < size; i++)
2715*48a54d36SAndroid Build Coastguard Worker {
2716*48a54d36SAndroid Build Coastguard Worker if (table [i].value == n)
2717*48a54d36SAndroid Build Coastguard Worker {
2718*48a54d36SAndroid Build Coastguard Worker return i;
2719*48a54d36SAndroid Build Coastguard Worker }
2720*48a54d36SAndroid Build Coastguard Worker }
2721*48a54d36SAndroid Build Coastguard Worker
2722*48a54d36SAndroid Build Coastguard Worker return -1;
2723*48a54d36SAndroid Build Coastguard Worker }
2724