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

📄 arlib.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
	return (ar_query_name(hname, C_IN, T_A, rptr));}/* * ar_gethostbyaddr * * Generates a query for a given IP address. */int	ar_gethostbyaddr(addr, info, size)char	*addr;char	*info;int	size;{	struct	resinfo	resi;	register struct resinfo *rp = &resi;	if (size && info)	    {		rp->ri_ptr = (char *)malloc(size);		bcopy(info, rp->ri_ptr, size);		rp->ri_size = size;	    }	else		bzero((char *)rp, sizeof(resi));	ar_reinfo.re_nu_look++;	return (do_query_number(rp, addr, NULL));}/* * do_query_number * * Use this to do reverse IP# lookups. */static	int	do_query_number(resi, numb, rptr)struct	resinfo	*resi;char	*numb;register struct	reslist	*rptr;{	register unsigned char	*cp;	static	char	ipbuf[32];	/*	 * Generate name in the "in-addr.arpa" domain.  No addings bits to this	 * name to get more names to query!.	 */	cp = (unsigned char *)numb;	(void)sprintf(ipbuf,"%u.%u.%u.%u.in-addr.arpa.",			(unsigned int)(cp[3]), (unsigned int)(cp[2]),			(unsigned int)(cp[1]), (unsigned int)(cp[0]));	if (!rptr)	    {		rptr = ar_make_request(resi);		rptr->re_type = T_PTR;		rptr->re_he.h_length = sizeof(struct in_addr);		bcopy(numb, (char *)&rptr->re_addr, rptr->re_he.h_length);		bcopy(numb, (char *)&rptr->re_he.h_addr_list[0].s_addr,			rptr->re_he.h_length);	    }	return (ar_query_name(ipbuf, C_IN, T_PTR, rptr));}/* * ar_resent_query * * resends a query. */static	int	ar_resend_query(rptr)struct	reslist	*rptr;{	if (!rptr->re_resend)		return -1;	switch(rptr->re_type)	{	case T_PTR:		ar_reinfo.re_resends++;		return do_query_number(NULL, &rptr->re_addr, rptr);	case T_A:		ar_reinfo.re_resends++;		return do_query_name(NULL, rptr->re_name, rptr);	default:		break;	}	return -1;}/* * ar_procanswer * * process an answer received from a nameserver. */static	int	ar_procanswer(rptr, hptr, buf, eob)struct	reslist	*rptr;char	*buf, *eob;HEADER	*hptr;{	char	*cp, **alias, *s;	int	class, type, dlen, len, ans = 0, n, i;	u_int32_t ttl, dr, *adr;	struct	hent	*hp;	cp = buf + sizeof(HEADER);	adr = (u_int32_t *)rptr->re_he.h_addr_list;	while (*adr)		adr++;	alias = rptr->re_he.h_aliases;	while (*alias)		alias++;	hp = &rptr->re_he;	/*	 * Skip over the original question.	 */	while (hptr->qdcount-- > 0)		cp += dn_skipname(cp, eob) + QFIXEDSZ;	/*	 * proccess each answer sent to us. blech.	 */	while (hptr->ancount-- > 0 && cp < eob) {		n = dn_expand(buf, eob, cp, ar_hostbuf, sizeof(ar_hostbuf));		cp += n;		if (n <= 0)			return ans;		ans++;		/*		 * 'skip' past the general dns crap (ttl, class, etc) to get		 * the pointer to the right spot.  Some of thse are actually		 * useful so its not a good idea to skip past in one big jump.		 */		type = (int)_getshort(cp);		cp += sizeof(short);		class = (int)_getshort(cp);		cp += sizeof(short);		ttl = (u_int32_t)_getlong(cp);		cp += sizeof(u_int32_t);		dlen =  (int)_getshort(cp);		cp += sizeof(short);		rptr->re_type = type;		switch(type)		{		case T_A :			rptr->re_he.h_length = dlen;			if (ans == 1)				rptr->re_he.h_addrtype=(class == C_IN) ?							AF_INET : AF_UNSPEC;			if (dlen != sizeof(dr))			    {				h_errno = TRY_AGAIN;				continue;			    }			bcopy(cp, &dr, dlen);			*adr++ = dr;			*adr = 0;			cp += dlen;			len = strlen(ar_hostbuf);			if (!rptr->re_he.h_name)			    {				rptr->re_he.h_name = (char *)malloc(len+1);				if (!rptr->re_he.h_name)					break;				(void)strcpy(rptr->re_he.h_name, ar_hostbuf);			    } 			break;		case T_PTR :			if ((n = dn_expand(buf, eob, cp, ar_hostbuf,					   sizeof(ar_hostbuf) )) < 0)			    {				cp += n;				continue;			    }			cp += n;			len = strlen(ar_hostbuf)+1;			/*			 * copy the returned hostname into the host name			 * or alias field if there is a known hostname			 * already.			 */			if (!rptr->re_he.h_name)			    {				rptr->re_he.h_name = (char *)malloc(len);				if (!rptr->re_he.h_name)					break;				(void)strcpy(rptr->re_he.h_name, ar_hostbuf);			    }			else			    {				*alias = (char *)malloc(len);				if (!*alias)					return -1;				(void)strcpy(*alias++, ar_hostbuf);				*alias = NULL;			    }			break;		case T_CNAME :			cp += dlen;			if (alias >= &(rptr->re_he.h_aliases[MAXALIASES-1]))				continue;			n = strlen(ar_hostbuf)+1;			*alias = (char *)malloc(n);			if (!*alias)				return -1;			(void)strcpy(*alias++, ar_hostbuf);			*alias = NULL;			break;		default :			break;		}	}	return ans;}/* * ar_answer * * Get an answer from a DNS server and process it.  If a query is found to * which no answer has been given to yet, copy its 'info' structure back * to where "reip" points and return a pointer to the hostent structure. */struct	hostent	*ar_answer(reip, size)char	*reip;int	size;{	static	char	ar_rcvbuf[sizeof(HEADER) + MAXPACKET];	static	struct	hostent	ar_host;	register HEADER	*hptr;	register struct	reslist	*rptr = NULL;	register struct hostent *hp;	register char **s;	unsigned long	*adr;	int	rc, i, n, a;	rc = recv(ar_resfd, ar_rcvbuf, sizeof(ar_rcvbuf), 0);	if (rc <= 0)		goto getres_err;	ar_reinfo.re_replies++;	hptr = (HEADER *)ar_rcvbuf;	/*	 * convert things to be in the right order.	 */	hptr->id = ntohs(hptr->id);	hptr->ancount = ntohs(hptr->ancount);	hptr->arcount = ntohs(hptr->arcount);	hptr->nscount = ntohs(hptr->nscount);	hptr->qdcount = ntohs(hptr->qdcount);	/*	 * response for an id which we have already received an answer for	 * just ignore this response.	 */	rptr = ar_find_id(hptr->id);	if (!rptr)		goto getres_err;	if ((hptr->rcode != NOERROR) || (hptr->ancount == 0))	    {		switch (hptr->rcode)		{		case NXDOMAIN:			h_errno = HOST_NOT_FOUND;			break;		case SERVFAIL:			h_errno = TRY_AGAIN;			break;		case NOERROR:			h_errno = NO_DATA;			break;		case FORMERR:		case NOTIMP:		case REFUSED:		default:			h_errno = NO_RECOVERY;			break;		}		ar_reinfo.re_errors++;		/*		** If a bad error was returned, we stop here and dont send		** send any more (no retries granted).		*/		if (h_errno != TRY_AGAIN)		    {			rptr->re_resend = 0;			rptr->re_retries = 0;		    }		goto getres_err;	    }	a = ar_procanswer(rptr, hptr, ar_rcvbuf, ar_rcvbuf+rc);	if ((rptr->re_type == T_PTR) && (_res.options & RES_CHECKPTR))	    {		/*		 * For reverse lookups on IP#'s, lookup the name that is given		 * for the ip# and return with that as the official result.		 * -avalon		 */		rptr->re_type = T_A;		/*		 * Clean out the list of addresses already set, even though		 * there should only be one :)		 */		adr = (unsigned long *)rptr->re_he.h_addr_list;		while (*adr)			*adr++ = 0L;		/*		 * Lookup the name that we were given for the ip#		 */		ar_reinfo.re_na_look++;		(void)strncpy(rptr->re_name, rptr->re_he.h_name,			sizeof(rptr->re_name)-1);		rptr->re_he.h_name = NULL;		rptr->re_retries = _res.retry;		rptr->re_sends = 1;		rptr->re_resend = 1;		rptr->re_he.h_name = NULL;		ar_reinfo.re_na_look++;		(void)ar_query_name(rptr->re_name, C_IN, T_A, rptr);		return NULL;	    }	if (reip && rptr->re_rinfo.ri_ptr && size)		bcopy(rptr->re_rinfo.ri_ptr, reip,			MIN(rptr->re_rinfo.ri_size, size));	/*	 * Clean up structure from previous usage.	 */	hp = &ar_host;#ifdef	ARLIB_DEBUG	ar_dump_hostent("ar_answer: previous usage", hp);#endif	if (hp->h_name)		(void)free(hp->h_name);	if (s = hp->h_aliases)	    {		while (*s)			(void)free(*s++);		(void)free(hp->h_aliases);	    }	if (s = hp->h_addr_list)	    {		/*		 * Only free once since we allocated space for		 * address in one big chunk.		 */		(void)free(*s);		(void)free(hp->h_addr_list);	    }	bzero((char *)hp, sizeof(*hp));	/*	 * Setup and copy details for the structure we return a pointer to.	 */	hp->h_addrtype = AF_INET;	hp->h_length = sizeof(struct in_addr);	if(rptr->re_he.h_name)	    {		hp->h_name = (char *)malloc(strlen(rptr->re_he.h_name)+1);		if(!hp->h_name)		    {#ifdef	ARLIB_DEBUG			fprintf(stderr, "no memory for hostname\n");#endif			h_errno = TRY_AGAIN;			goto getres_err;		    }		(void)strcpy(hp->h_name, rptr->re_he.h_name);	    }#ifdef	ARLIB_DEBUG	ar_dump_hostent("ar_answer: (snap) store name", hp);#endif	/*	 * Count IP#'s.	 */	for (i = 0, n = 0; i < MAXADDRS; i++, n++)		if (!rptr->re_he.h_addr_list[i].s_addr)			break;	s = hp->h_addr_list = (char **)malloc((n + 1) * sizeof(char *));	if (n)	    {		*s = (char *)malloc(n * sizeof(struct in_addr));		if(!*s)		    {#ifdef	ARLIB_DEBUG			fprintf(stderr, "no memory for IP#'s (%d)\n", n);#endif			h_errno = TRY_AGAIN;			goto getres_err;		    }		bcopy((char *)&rptr->re_he.h_addr_list[0].s_addr, *s,			sizeof(struct in_addr));		s++;		for (i = 1; i < n; i++, s++)		    {			*s = hp->h_addr + i * sizeof(struct in_addr);			bcopy((char *)&rptr->re_he.h_addr_list[i].s_addr, *s,				sizeof(struct in_addr));		    }	    }	*s = NULL;#ifdef	ARLIB_DEBUG	ar_dump_hostent("ar_answer: (snap) store IP#'s", hp);#endif	/*	 * Count CNAMEs	 */	for (i = 0, n = 0; i < MAXADDRS; i++, n++)		if (!rptr->re_he.h_aliases[i])			break;	s = hp->h_aliases = (char **)malloc((n + 1) * sizeof(char *));	if (!s)	    {#ifdef	ARLIB_DEBUG		fprintf(stderr, "no memory for aliases (%d)\n", n);#endif		h_errno = TRY_AGAIN;		goto getres_err;	    }	for (i = 0; i < n; i++)	    {		*s++ = rptr->re_he.h_aliases[i];		rptr->re_he.h_aliases[i] = NULL;	    }	*s = NULL;#ifdef	ARLIB_DEBUG	ar_dump_hostent("ar_answer: (snap) store CNAMEs", hp);	ar_dump_hostent("ar_answer: new one", hp);#endif	if (a > 0)		(void)ar_remrequest(rptr);	else		if (!rptr->re_sent)			(void)ar_remrequest(rptr);	return hp;getres_err:	if (rptr)	    {		if (reip && rptr->re_rinfo.ri_ptr && size)			bcopy(rptr->re_rinfo.ri_ptr, reip,				MIN(rptr->re_rinfo.ri_size, size));		if ((h_errno != TRY_AGAIN) &&		    (_res.options & (RES_DNSRCH|RES_DEFNAMES) ==		     (RES_DNSRCH|RES_DEFNAMES) ))			if (_res.dnsrch[rptr->re_srch])			    {				rptr->re_retries = _res.retry;				rptr->re_sends = 1;				rptr->re_resend = 1;				(void)ar_resend_query(rptr);				rptr->re_srch++;			    }		return NULL;	    }	return NULL;}#ifdef	ARLIB_DEBUGvoid ar_dump_hostent(prefix, hp)char *prefix;struct hostent *hp;{	register char **s;	fflush(stdout);	fprintf(stderr, "%s\n", prefix);	fprintf(stderr, "  hp %p\n", hp);	fprintf(stderr, "    h_name %p '%s'\n",	hp->h_name, hp->h_name);	if (s = hp->h_aliases)	    {		fprintf(stderr, "    h_aliases %p\n",		hp->h_aliases);		while (*s)		    {			fprintf(stderr, "      element %p\n", *s);			s++;		    }	    }	if (s = hp->h_addr_list)	    {		fprintf(stderr, "    h_addr_list %p\n",		hp->h_addr_list);		while (*s)		    {			fprintf(stderr, "      element %p\n", *s);			s++;		    }	    }	fflush(stderr);}void ar_dump_reslist(FILE* fp){	register struct reslist *rptr;	int c;	c = 0;	for (rptr = ar_first; rptr; rptr = rptr->re_next)	    {		fprintf(fp, "%4d [%p] %4d [%p]: %s\n", rptr->re_id, rptr,			*(rptr->re_rinfo.ri_ptr), rptr->re_rinfo.ri_ptr,			rptr->re_name);	    }}#endif

⌨️ 快捷键说明

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