⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ares_parse_a_reply.c

📁 最新rtlinux内核源码
💻 C
字号:
/* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose.  It is provided "as is" * without express or implied warranty. * * CHANGELOG: this file has been modified by Sergio Perez Alca駃z <serpeal@upvnet.upv.es>  *            Departamento de Inform醫ica de Sistemas y Computadores           *            Universidad Polit閏nica de Valencia                              *            Valencia (Spain)     *            Date: April 2003                                           * */#include "ares_private.h"#include "ares_dns.h"int ares_parse_a_reply(const unsigned char *abuf, int alen,		       struct hostent **host){  unsigned int qdcount, ancount;  int status, i, len, rr_type, rr_class, rr_len, naddrs;  int naliases;  const unsigned char *aptr;  char *hostname, *rr_name, *rr_data, **aliases;  struct in_addr *addrs;  struct hostent *hostent;  /* Set *host to NULL for all failure cases. */  *host = NULL;  /* Give up if abuf doesn't have room for a header. */  if (alen < HFIXEDSZ)    return ARES_EBADRESP;  /* Fetch the question and answer count from the header. */  qdcount = DNS_HEADER_QDCOUNT(abuf);  ancount = DNS_HEADER_ANCOUNT(abuf);  if (qdcount != 1)    return ARES_EBADRESP;  /* Expand the name from the question, and skip past the question. */  aptr = abuf + HFIXEDSZ;  status = ares_expand_name(aptr, abuf, alen, &hostname, &len);  if (status != ARES_SUCCESS)    return status;  if (aptr + len + QFIXEDSZ > abuf + alen)    {      free(hostname);      return ARES_EBADRESP;    }  aptr += len + QFIXEDSZ;  /* Allocate addresses and aliases; ancount gives an upper bound for both. */  addrs = malloc(ancount * sizeof(struct in_addr));  if (!addrs)    {      free(hostname);      return ARES_ENOMEM;    }  aliases = malloc((ancount + 1) * sizeof(char *));  if (!aliases)    {      free(hostname);      free(addrs);      return ARES_ENOMEM;    }  naddrs = 0;  naliases = 0;  /* Examine each answer resource record (RR) in turn. */  for (i = 0; i < ancount; i++)    {      /* Decode the RR up to the data field. */      status = ares_expand_name(aptr, abuf, alen, &rr_name, &len);      if (status != ARES_SUCCESS)	break;      aptr += len;      if (aptr + RRFIXEDSZ > abuf + alen)	{	  status = ARES_EBADRESP;	  break;	}      rr_type = DNS_RR_TYPE(aptr);      rr_class = DNS_RR_CLASS(aptr);      rr_len = DNS_RR_LEN(aptr);      aptr += RRFIXEDSZ;      if (rr_class == C_IN && rr_type == T_A	  && rr_len == sizeof(struct in_addr)	  && strcasecmp(rr_name, hostname) == 0)	{	  memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr));	  naddrs++;	  status = ARES_SUCCESS;	}      if (rr_class == C_IN && rr_type == T_CNAME)	{	  /* Record the RR name as an alias. */	  aliases[naliases] = rr_name;	  naliases++;	  /* Decode the RR data and replace the hostname with it. */	  status = ares_expand_name(aptr, abuf, alen, &rr_data, &len);	  if (status != ARES_SUCCESS)	    break;	  free(hostname);	  hostname = rr_data;	}      else	free(rr_name);      aptr += rr_len;      if (aptr > abuf + alen)	{	  status = ARES_EBADRESP;	  break;	}    }  if (status == ARES_SUCCESS && naddrs == 0)    status = ARES_ENODATA;  if (status == ARES_SUCCESS)    {      /* We got our answer.  Allocate memory to build the host entry. */      aliases[naliases] = NULL;      hostent = malloc(sizeof(struct hostent));      if (hostent)	{	  hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *));	  if (hostent->h_addr_list)	    {	      /* Fill in the hostent and return successfully. */	      hostent->h_name = hostname;	      hostent->h_aliases = aliases;	      hostent->h_addrtype = AF_INET;	      hostent->h_length = sizeof(struct in_addr);	      for (i = 0; i < naddrs; i++)		hostent->h_addr_list[i] = (char *) &addrs[i];	      hostent->h_addr_list[naddrs] = NULL;	      *host = hostent;	      return ARES_SUCCESS;	    }	  free(hostent);	}      status = ARES_ENOMEM;    }  for (i = 0; i < naliases; i++)    free(aliases[i]);  free(aliases);  free(addrs);  free(hostname);  return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -