#include "ares_private.h"#include "ares_dns.h"Include dependency graph for ares_parse_ptr_reply.c:
Go to the source code of this file.
Functions | |
| int | ares_parse_ptr_reply (const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host) |
|
||||||||||||||||||||||||||||
|
Definition at line 26 of file ares_parse_ptr_reply.c. References ARES_EBADRESP, ARES_ENODATA, ARES_ENOMEM, ares_expand_name(), ARES_SUCCESS, C_IN, DNS_HEADER_ANCOUNT, DNS_HEADER_QDCOUNT, DNS_RR_CLASS, DNS_RR_LEN, DNS_RR_TYPE, free, HFIXEDSZ, len, malloc, NULL, QFIXEDSZ, RRFIXEDSZ, status, strcasecmp, T_CNAME, and T_PTR. Referenced by addr_callback().
00028 {
00029 unsigned int qdcount, ancount;
00030 int status, i, len, rr_type, rr_class, rr_len;
00031 const unsigned char *aptr;
00032 char *ptrname, *hostname, *rr_name, *rr_data;
00033 struct hostent *hostent;
00034
00035 /* Set *host to NULL for all failure cases. */
00036 *host = NULL;
00037
00038 /* Give up if abuf doesn't have room for a header. */
00039 if (alen < HFIXEDSZ)
00040 return ARES_EBADRESP;
00041
00042 /* Fetch the question and answer count from the header. */
00043 qdcount = DNS_HEADER_QDCOUNT(abuf);
00044 ancount = DNS_HEADER_ANCOUNT(abuf);
00045 if (qdcount != 1)
00046 return ARES_EBADRESP;
00047
00048 /* Expand the name from the question, and skip past the question. */
00049 aptr = abuf + HFIXEDSZ;
00050 status = ares_expand_name(aptr, abuf, alen, &ptrname, &len);
00051 if (status != ARES_SUCCESS)
00052 return status;
00053 if (aptr + len + QFIXEDSZ > abuf + alen)
00054 {
00055 free(ptrname);
00056 return ARES_EBADRESP;
00057 }
00058 aptr += len + QFIXEDSZ;
00059
00060 /* Examine each answer resource record (RR) in turn. */
00061 hostname = NULL;
00062 for (i = 0; i < ancount; i++)
00063 {
00064 /* Decode the RR up to the data field. */
00065 status = ares_expand_name(aptr, abuf, alen, &rr_name, &len);
00066 if (status != ARES_SUCCESS)
00067 break;
00068 aptr += len;
00069 if (aptr + RRFIXEDSZ > abuf + alen)
00070 {
00071 status = ARES_EBADRESP;
00072 break;
00073 }
00074 rr_type = DNS_RR_TYPE(aptr);
00075 rr_class = DNS_RR_CLASS(aptr);
00076 rr_len = DNS_RR_LEN(aptr);
00077 aptr += RRFIXEDSZ;
00078
00079 if (rr_class == C_IN && rr_type == T_PTR
00080 && strcasecmp(rr_name, ptrname) == 0)
00081 {
00082 /* Decode the RR data and set hostname to it. */
00083 status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
00084 if (status != ARES_SUCCESS)
00085 break;
00086 if (hostname)
00087 free(hostname);
00088 hostname = rr_data;
00089 }
00090
00091 if (rr_class == C_IN && rr_type == T_CNAME)
00092 {
00093 /* Decode the RR data and replace ptrname with it. */
00094 status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);
00095 if (status != ARES_SUCCESS)
00096 break;
00097 free(ptrname);
00098 ptrname = rr_data;
00099 }
00100
00101 free(rr_name);
00102 aptr += rr_len;
00103 if (aptr > abuf + alen)
00104 {
00105 status = ARES_EBADRESP;
00106 break;
00107 }
00108 }
00109
00110 if (status == ARES_SUCCESS && !hostname)
00111 status = ARES_ENODATA;
00112 if (status == ARES_SUCCESS)
00113 {
00114 /* We got our answer. Allocate memory to build the host entry. */
00115 hostent = malloc(sizeof(struct hostent));
00116 if (hostent)
00117 {
00118 hostent->h_addr_list = malloc(2 * sizeof(char *));
00119 if (hostent->h_addr_list)
00120 {
00121 hostent->h_addr_list[0] = malloc(addrlen);
00122 if (hostent->h_addr_list[0])
00123 {
00124 hostent->h_aliases = malloc(sizeof (char *));
00125 if (hostent->h_aliases)
00126 {
00127 /* Fill in the hostent and return successfully. */
00128 hostent->h_name = hostname;
00129 hostent->h_aliases[0] = NULL;
00130 hostent->h_addrtype = family;
00131 hostent->h_length = addrlen;
00132 memcpy(hostent->h_addr_list[0], addr, addrlen);
00133 hostent->h_addr_list[1] = NULL;
00134 *host = hostent;
00135 free(ptrname);
00136 return ARES_SUCCESS;
00137 }
00138 free(hostent->h_addr_list[0]);
00139 }
00140 free(hostent->h_addr_list);
00141 }
00142 free(hostent);
00143 }
00144 status = ARES_ENOMEM;
00145 }
00146 if (hostname)
00147 free(hostname);
00148 free(ptrname);
00149 return status;
00150 }
|
Here is the call graph for this function:
1.3.4