reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
ares_parse_a_reply.c
Go to the documentation of this file.
1
/* Copyright 1998 by the Massachusetts Institute of Technology.
2
*
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.
14
*/
15
16
17
#include <sys/types.h>
18
#include <stdlib.h>
19
#include <string.h>
20
#include "
ares.h
"
21
#include "
ares_dns.h
"
22
#include "
ares_private.h
"
23
24
#ifndef WIN32
25
#include <sys/socket.h>
26
#include <netinet/in.h>
27
#include <arpa/inet.h>
28
#ifndef __CYGWIN__
29
# include "
ares_nameser.h
"
30
#endif
31
#include <netdb.h>
32
#endif
33
34
int
ares_parse_a_reply
(
const
unsigned
char
* abuf,
int
alen,
35
struct
hostent
** host)
36
{
37
unsigned
int
qdcount
,
ancount
;
38
int
status,
i
,
rr_type
,
rr_class
,
rr_len
,
naddrs
;
39
long
int
len;
40
int
naliases
;
41
const
unsigned
char
*
aptr
;
42
char
* hostname, *
rr_name
, *
rr_data
, **
aliases
;
43
struct
in_addr
*
addrs
;
44
struct
hostent
*
hostent
;
45
46
/* Set *host to NULL for all failure cases. */
47
*host =
NULL
;
48
49
/* Give up if abuf doesn't have room for a header. */
50
if
(alen <
HFIXEDSZ
)
51
return
ARES_EBADRESP
;
52
53
/* Fetch the question and answer count from the header. */
54
qdcount
=
DNS_HEADER_QDCOUNT
(abuf);
55
ancount
=
DNS_HEADER_ANCOUNT
(abuf);
56
if
(
qdcount
!= 1)
57
return
ARES_EBADRESP
;
58
59
/* Expand the name from the question, and skip past the question. */
60
aptr
= abuf +
HFIXEDSZ
;
61
status =
ares_expand_name
(
aptr
, abuf, alen, &hostname, &len);
62
if
(status !=
ARES_SUCCESS
)
63
return
status;
64
if
(
aptr
+ len +
QFIXEDSZ
> abuf + alen)
65
{
66
free
(hostname);
67
return
ARES_EBADRESP
;
68
}
69
aptr
+= len +
QFIXEDSZ
;
70
71
/* Allocate addresses and aliases; ancount gives an upper bound for both. */
72
addrs
=
malloc
(
ancount
*
sizeof
(
struct
in_addr
));
73
if
(!
addrs
)
74
{
75
free
(hostname);
76
return
ARES_ENOMEM
;
77
}
78
aliases
=
malloc
((
ancount
+ 1) *
sizeof
(
char
*));
79
if
(!
aliases
)
80
{
81
free
(hostname);
82
free
(
addrs
);
83
return
ARES_ENOMEM
;
84
}
85
naddrs
= 0;
86
naliases
= 0;
87
88
/* Examine each answer resource record (RR) in turn. */
89
for
(
i
= 0;
i
< (
int
)
ancount
;
i
++)
90
{
91
/* Decode the RR up to the data field. */
92
status =
ares_expand_name
(
aptr
, abuf, alen, &
rr_name
, &len);
93
if
(status !=
ARES_SUCCESS
)
94
break
;
95
aptr
+= len;
96
if
(
aptr
+
RRFIXEDSZ
> abuf + alen)
97
{
98
free
(
rr_name
);
99
status =
ARES_EBADRESP
;
100
break
;
101
}
102
rr_type
=
DNS_RR_TYPE
(
aptr
);
103
rr_class
=
DNS_RR_CLASS
(
aptr
);
104
rr_len
=
DNS_RR_LEN
(
aptr
);
105
aptr
+=
RRFIXEDSZ
;
106
if
(
aptr
+
rr_len
> abuf + alen)
107
{
108
free
(
rr_name
);
109
status =
ARES_EBADRESP
;
110
break
;
111
}
112
113
if
(
rr_class
==
C_IN
&&
rr_type
==
T_A
114
&&
rr_len
==
sizeof
(
struct
in_addr
)
115
&&
strcasecmp
(
rr_name
, hostname) == 0)
116
{
117
memcpy
(&
addrs
[
naddrs
],
aptr
,
sizeof
(
struct
in_addr
));
118
naddrs
++;
119
status =
ARES_SUCCESS
;
120
}
121
122
if
(
rr_class
==
C_IN
&&
rr_type
==
T_CNAME
)
123
{
124
/* Record the RR name as an alias. */
125
aliases
[
naliases
] =
rr_name
;
126
naliases
++;
127
128
/* Decode the RR data and replace the hostname with it. */
129
status =
ares_expand_name
(
aptr
, abuf, alen, &
rr_data
, &len);
130
if
(status !=
ARES_SUCCESS
)
131
break
;
132
free
(hostname);
133
hostname =
rr_data
;
134
}
135
else
136
free
(
rr_name
);
137
138
aptr
+=
rr_len
;
139
if
(
aptr
> abuf + alen)
140
{
141
status =
ARES_EBADRESP
;
142
break
;
143
}
144
}
145
146
if
(status ==
ARES_SUCCESS
&&
naddrs
== 0)
147
status =
ARES_ENODATA
;
148
if
(status ==
ARES_SUCCESS
)
149
{
150
/* We got our answer. Allocate memory to build the host entry. */
151
aliases
[
naliases
] =
NULL
;
152
hostent
=
malloc
(
sizeof
(
struct
hostent
));
153
if
(
hostent
)
154
{
155
hostent
->h_addr_list =
malloc
((
naddrs
+ 1) *
sizeof
(
char
*));
156
if
(
hostent
->h_addr_list)
157
{
158
/* Fill in the hostent and return successfully. */
159
hostent
->h_name = hostname;
160
hostent
->h_aliases =
aliases
;
161
hostent
->h_addrtype =
AF_INET
;
162
hostent
->h_length =
sizeof
(
struct
in_addr
);
163
for
(
i
= 0;
i
<
naddrs
;
i
++)
164
hostent
->h_addr_list[
i
] = (
char
*)&
addrs
[
i
];
165
hostent
->h_addr_list[
naddrs
] =
NULL
;
166
if
(!
naddrs
&&
addrs
)
167
free
(
addrs
);
168
*host =
hostent
;
169
return
ARES_SUCCESS
;
170
}
171
free
(
hostent
);
172
}
173
status =
ARES_ENOMEM
;
174
}
175
for
(
i
= 0;
i
<
naliases
;
i
++)
176
free
(
aliases
[
i
]);
177
free
(
aliases
);
178
free
(
addrs
);
179
free
(hostname);
180
return
status;
181
}
ares.h
ARES_SUCCESS
#define ARES_SUCCESS
Definition
ares.h:79
ARES_ENOMEM
#define ARES_ENOMEM
Definition
ares.h:98
ARES_ENODATA
#define ARES_ENODATA
Definition
ares.h:82
DNS_RR_LEN
#define DNS_RR_LEN(r)
Definition
ares.h:53
DNS_HEADER_QDCOUNT
#define DNS_HEADER_QDCOUNT(h)
Definition
ares.h:48
DNS_HEADER_ANCOUNT
#define DNS_HEADER_ANCOUNT(h)
Definition
ares.h:49
ares_expand_name
int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen)
Definition
ares_expand_name.c:83
ARES_EBADRESP
#define ARES_EBADRESP
Definition
ares.h:93
DNS_RR_TYPE
#define DNS_RR_TYPE(r)
Definition
ares.h:52
ares_dns.h
DNS_RR_CLASS
#define DNS_RR_CLASS(r)
Definition
ares_dns.h:69
ares_nameser.h
QFIXEDSZ
#define QFIXEDSZ
Definition
ares_nameser.h:207
C_IN
#define C_IN
Definition
ares_nameser.h:255
T_CNAME
#define T_CNAME
Definition
ares_nameser.h:283
HFIXEDSZ
#define HFIXEDSZ
Definition
ares_nameser.h:203
RRFIXEDSZ
#define RRFIXEDSZ
Definition
ares_nameser.h:211
ares_parse_a_reply
int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host)
Definition
ares_parse_a_reply.c:34
ares_private.h
T_A
#define T_A
Definition
compat.hxx:152
list
void list()
Definition
userAdmin.cxx:66
rutil
dns
ares
ares_parse_a_reply.c
Generated by
1.9.8