reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
ares_parse_ptr_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
21#ifndef WIN32
22#include <sys/socket.h>
23#include <netinet/in.h>
24#include <arpa/inet.h>
25#ifndef __CYGWIN__
26# include "ares_nameser.h"
27#endif
28#include <netdb.h>
29#endif
30
31#include "ares.h"
32#include "ares_dns.h"
33#include "ares_private.h"
34
35int ares_parse_ptr_reply(const unsigned char* abuf, int alen, const void* addr,
36 int addrlen, int family, struct hostent** host)
37{
38 unsigned int qdcount, ancount;
39 int status, i, rr_type, rr_class, rr_len;
40 long int len;
41 const unsigned char* aptr;
42 char* ptrname, * hostname, * rr_name, * rr_data;
43 struct hostent* hostent;
44
45 /* Set *host to NULL for all failure cases. */
46 *host = NULL;
47
48 /* Give up if abuf doesn't have room for a header. */
49 if (alen < HFIXEDSZ)
50 return ARES_EBADRESP;
51
52 /* Fetch the question and answer count from the header. */
55 if (qdcount != 1)
56 return ARES_EBADRESP;
57
58 /* Expand the name from the question, and skip past the question. */
59 aptr = abuf + HFIXEDSZ;
60 status = ares_expand_name(aptr, abuf, alen, &ptrname, &len);
61 if (status != ARES_SUCCESS)
62 return status;
63 if (aptr + len + QFIXEDSZ > abuf + alen)
64 {
66 return ARES_EBADRESP;
67 }
68 aptr += len + QFIXEDSZ;
69
70 /* Examine each answer resource record (RR) in turn. */
71 hostname = NULL;
72 for (i = 0; i < (int)ancount; i++)
73 {
74 /* Decode the RR up to the data field. */
75 status = ares_expand_name(aptr, abuf, alen, &rr_name, &len);
76 if (status != ARES_SUCCESS)
77 break;
78 aptr += len;
79 if (aptr + RRFIXEDSZ > abuf + alen)
80 {
82 status = ARES_EBADRESP;
83 break;
84 }
88 aptr += RRFIXEDSZ;
89
90 if (rr_class == C_IN && rr_type == T_PTR
91 && strcasecmp(rr_name, ptrname) == 0)
92 {
93 /* Decode the RR data and set hostname to it. */
94 status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
95 if (status != ARES_SUCCESS)
96 {
98 break;
99 }
100 if (hostname)
101 free(hostname);
102 hostname = rr_data;
103 }
104
105 if (rr_class == C_IN && rr_type == T_CNAME)
106 {
107 /* Decode the RR data and replace ptrname with it. */
108 status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
109 if (status != ARES_SUCCESS)
110 {
111 free(rr_name);
112 break;
113 }
114 free(ptrname);
116 }
117
118 free(rr_name);
119 aptr += rr_len;
120 if (aptr > abuf + alen)
121 {
122 status = ARES_EBADRESP;
123 break;
124 }
125 }
126
127 if (status == ARES_SUCCESS && !hostname)
128 status = ARES_ENODATA;
129 if (status == ARES_SUCCESS)
130 {
131 /* We got our answer. Allocate memory to build the host entry. */
132 hostent = malloc(sizeof(struct hostent));
133 if (hostent)
134 {
135 hostent->h_addr_list = malloc(2 * sizeof(char*));
136 if (hostent->h_addr_list)
137 {
138 hostent->h_addr_list[0] = malloc(addrlen);
139 if (hostent->h_addr_list[0])
140 {
141 hostent->h_aliases = malloc(sizeof(char*));
142 if (hostent->h_aliases)
143 {
144 /* Fill in the hostent and return successfully. */
145 hostent->h_name = hostname;
146 hostent->h_aliases[0] = NULL;
147 hostent->h_addrtype = family;
148 hostent->h_length = addrlen;
149 memcpy(hostent->h_addr_list[0], addr, addrlen);
150 hostent->h_addr_list[1] = NULL;
151 *host = hostent;
152 free(ptrname);
153 return ARES_SUCCESS;
154 }
155 free(hostent->h_addr_list[0]);
156 }
157 free(hostent->h_addr_list);
158 }
159 free(hostent);
160 }
161 status = ARES_ENOMEM;
162 }
163 if (hostname)
164 free(hostname);
165 free(ptrname);
166 return status;
167}
#define ARES_SUCCESS
Definition ares.h:79
#define ARES_ENOMEM
Definition ares.h:98
#define ARES_ENODATA
Definition ares.h:82
#define DNS_RR_LEN(r)
Definition ares.h:53
#define DNS_HEADER_QDCOUNT(h)
Definition ares.h:48
#define DNS_HEADER_ANCOUNT(h)
Definition ares.h:49
int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen)
#define ARES_EBADRESP
Definition ares.h:93
#define DNS_RR_TYPE(r)
Definition ares.h:52
#define DNS_RR_CLASS(r)
Definition ares_dns.h:69
#define QFIXEDSZ
#define T_PTR
#define C_IN
#define T_CNAME
#define HFIXEDSZ
#define RRFIXEDSZ
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host)
void list()
Definition userAdmin.cxx:66