]>
git.proxmox.com Git - ceph.git/blob - ceph/src/c-ares/ares_parse_ns_reply.c
1 /* Copyright 1998 by the Massachusetts Institute of Technology.
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose. It is provided "as is"
13 * without express or implied warranty.
17 * ares_parse_ns_reply created by Vlad Dinulescu <vlad.dinulescu@avira.com>
18 * on behalf of AVIRA Gmbh - http://www.avira.com
21 #include "ares_setup.h"
23 #ifdef HAVE_NETINET_IN_H
24 # include <netinet/in.h>
29 #ifdef HAVE_ARPA_INET_H
30 # include <arpa/inet.h>
32 #ifdef HAVE_ARPA_NAMESER_H
33 # include <arpa/nameser.h>
37 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
38 # include <arpa/nameser_compat.h>
43 #include "ares_private.h"
45 int ares_parse_ns_reply( const unsigned char* abuf
, int alen
,
46 struct hostent
** host
)
48 unsigned int qdcount
, ancount
;
49 int status
, i
, rr_type
, rr_class
, rr_len
;
52 const unsigned char *aptr
;
53 char* hostname
, *rr_name
, *rr_data
, **nameservers
;
54 struct hostent
*hostent
;
56 /* Set *host to NULL for all failure cases. */
59 /* Give up if abuf doesn't have room for a header. */
60 if ( alen
< HFIXEDSZ
)
63 /* Fetch the question and answer count from the header. */
64 qdcount
= DNS_HEADER_QDCOUNT( abuf
);
65 ancount
= DNS_HEADER_ANCOUNT( abuf
);
69 /* Expand the name from the question, and skip past the question. */
70 aptr
= abuf
+ HFIXEDSZ
;
71 status
= ares__expand_name_for_response( aptr
, abuf
, alen
, &hostname
, &len
);
72 if ( status
!= ARES_SUCCESS
)
74 if ( aptr
+ len
+ QFIXEDSZ
> abuf
+ alen
)
76 ares_free( hostname
);
79 aptr
+= len
+ QFIXEDSZ
;
81 /* Allocate nameservers array; ancount gives an upper bound */
82 nameservers
= ares_malloc( ( ancount
+ 1 ) * sizeof( char * ) );
85 ares_free( hostname
);
90 /* Examine each answer resource record (RR) in turn. */
91 for ( i
= 0; i
< ( int ) ancount
; i
++ )
93 /* Decode the RR up to the data field. */
94 status
= ares__expand_name_for_response( aptr
, abuf
, alen
, &rr_name
, &len
);
95 if ( status
!= ARES_SUCCESS
)
98 if ( aptr
+ RRFIXEDSZ
> abuf
+ alen
)
100 status
= ARES_EBADRESP
;
104 rr_type
= DNS_RR_TYPE( aptr
);
105 rr_class
= DNS_RR_CLASS( aptr
);
106 rr_len
= DNS_RR_LEN( aptr
);
108 if (aptr
+ rr_len
> abuf
+ alen
)
111 status
= ARES_EBADRESP
;
115 if ( rr_class
== C_IN
&& rr_type
== T_NS
)
117 /* Decode the RR data and add it to the nameservers list */
118 status
= ares__expand_name_for_response( aptr
, abuf
, alen
, &rr_data
,
120 if ( status
!= ARES_SUCCESS
)
126 nameservers
[nameservers_num
] = ares_malloc(strlen(rr_data
)+1);
128 if (nameservers
[nameservers_num
]==NULL
)
135 strcpy(nameservers
[nameservers_num
],rr_data
);
141 ares_free( rr_name
);
144 if ( aptr
> abuf
+ alen
)
145 { /* LCOV_EXCL_START: already checked above */
146 status
= ARES_EBADRESP
;
148 } /* LCOV_EXCL_STOP */
151 if ( status
== ARES_SUCCESS
&& nameservers_num
== 0 )
153 status
= ARES_ENODATA
;
155 if ( status
== ARES_SUCCESS
)
157 /* We got our answer. Allocate memory to build the host entry. */
158 nameservers
[nameservers_num
] = NULL
;
159 hostent
= ares_malloc( sizeof( struct hostent
) );
162 hostent
->h_addr_list
= ares_malloc( 1 * sizeof( char * ) );
163 if ( hostent
->h_addr_list
)
165 /* Fill in the hostent and return successfully. */
166 hostent
->h_name
= hostname
;
167 hostent
->h_aliases
= nameservers
;
168 hostent
->h_addrtype
= AF_INET
;
169 hostent
->h_length
= sizeof( struct in_addr
);
170 hostent
->h_addr_list
[0] = NULL
;
174 ares_free( hostent
);
176 status
= ARES_ENOMEM
;
178 for ( i
= 0; i
< nameservers_num
; i
++ )
179 ares_free( nameservers
[i
] );
180 ares_free( nameservers
);
181 ares_free( hostname
);