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

📄 gethostnamadr.c

📁 vxworks source code, used for develop vxworks system.
💻 C
字号:
/* gethostnamadr.c - *//* Copyright 1984-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1985, 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//*modification history--------------------01f,16jan03,hsh  fixed buffer overflow in resolver lib (SPR #80386)01e,14jan03,rae  Merged from velocecp branch (SPR #83515)01d,05nov01,vvv  fixed compilation warnings01c,04sep01,vvv  fixed to correctly query multiple servers (SPR #67238);		 fixed compilation warnings01b,11feb96,jag  Fix the formating of the hostent structure in  _gethostbyname                 when invoked with an IP address. Cleaned up warnings.01a,13dec96,jag  Cleaned up and rename user I/F functions with the resolv		 prefix.  Man pages for these functions appear in resolvLib*/#include <vxWorks.h>#include <resolvLib.h>#include <semLib.h>#include <stdio.h>#include <ctype.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <inetLib.h>#define  MAX_RR_TTL  172800         /* Maximum of Two days in seconds */#if PACKETSZ > 1024#define	MAXPACKET	PACKETSZ#else#define	MAXPACKET	1024#endiftypedef union {	HEADER hdr;	u_char buf[MAXPACKET];} querybuf;typedef union {	int32_t	al;	char ac;} align;static int qcomp (struct in_addr **, struct in_addr **);LOCAL struct hostent *getanswer (querybuf *, int, int, struct hostent *, 				 char *, int);LOCAL struct hostent *getanswer(answer, anslen, iquery, pHost, hostbuf, bufLen)	querybuf *answer;	int anslen;	int iquery;	struct hostent   *  pHost;	char *           hostbuf;	int              bufLen;{	register HEADER *hp;	register u_char *cp;	register int n;	u_char *eom;	char *bp, **ap;	int type, class, ancount, qdcount;	int haveanswer, getclass = C_ANY;	char **hap;	char *hostbufEnd;	unsigned int rrttl;		/* RR time to live field */	eom = answer->buf + anslen;	/*	 * find first satisfactory answer	 */	hp = &answer->hdr;	ancount = ntohs(hp->ancount);	qdcount = ntohs(hp->qdcount);	bp = hostbuf;        hostbufEnd = hostbuf + bufLen - 1;	cp = answer->buf + sizeof(HEADER);	/* Process the "questions section" of the DNS response */	if (qdcount) {			    /* Check if this is a Pointer query */		if (iquery) {			if ((n = resolvDNExpand((u_char *)answer->buf,			    (u_char *)eom, (u_char *)cp, (u_char *)bp,			    bufLen)) < 0) {				errno = S_resolvLib_NO_RECOVERY;				return ((struct hostent *) NULL);			}			cp += n + QFIXEDSZ;			pHost->h_name = bp;			n = strlen(bp) + 1;			bp += n;			bufLen -= n;		} else			cp += __dn_skipname(cp, eom) + QFIXEDSZ;		while (--qdcount > 0)			cp += __dn_skipname(cp, eom) + QFIXEDSZ;	} else if (iquery) {		if (hp->aa)			errno = S_resolvLib_HOST_NOT_FOUND;		else			errno = S_resolvLib_TRY_AGAIN;		return ((struct hostent *) NULL);	}	/* Set everything up to process the resource records */	ap = pHost->h_aliases;	*ap = NULL;		hap = pHost->h_addr_list;	*hap = NULL;	pHost->h_ttl = MAX_RR_TTL;  /* Maximum of Two days in seconds */	haveanswer = 0;	while (--ancount >= 0 && cp < eom) {		if ((n = resolvDNExpand((u_char *)answer->buf, (u_char *)eom,		    (u_char *)cp, (u_char *)bp, bufLen)) < 0)			break;		cp += n;		type = _getshort(cp);		/* Get RR type field */ 		cp += sizeof(uint16_t);         /* Skip size of type field */		class = _getshort(cp);		/* Get RR class field */ 		cp += sizeof(uint16_t);         /* Skip size of class field */		rrttl = _getlong(cp);	        /* Get RR TTL field */		cp += sizeof(uint32_t);	        /* Skip size of TTL field */		n = _getshort(cp);		/* Get RR data length field */		cp += sizeof(uint16_t);		/* Skip size of length filed */		if (type == T_CNAME) {			cp += n;			if (ap >= & pHost->h_aliases [MAXALIASES-1])				continue;			*ap++ = bp;			n = strlen(bp) + 1;			bp += n;			bufLen -= n;			if (rrttl < pHost->h_ttl)			    pHost->h_ttl = rrttl;			continue;		}		if (iquery && type == T_PTR) {			if ((n = resolvDNExpand((u_char *)answer->buf,			    (u_char *)eom, (u_char *)cp, (u_char *)bp,			    bufLen)) < 0)				break;			cp += n;			pHost->h_name = bp;			if (rrttl < pHost->h_ttl)			    pHost->h_ttl = rrttl;			return (pHost);		}		if (iquery || type != T_A)  {#ifdef DEBUG			if (_res.options & RES_DEBUG)				printf("unexpected answer type %d, size %d\n",					type, n);#endif			cp += n;			continue;		}		if (haveanswer) {			if (n != pHost->h_length) {				cp += n;				continue;			}			if (class != getclass) {				cp += n;				continue;			}		} else {			pHost->h_length = n;			getclass = class;			pHost->h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;			if (!iquery) {			    pHost->h_name = bp;			    bp += strlen(bp) + 1;			    bufLen -= strlen(bp) + 1;			    if (rrttl < pHost->h_ttl)				pHost->h_ttl = rrttl;			}		}		bufLen -= sizeof(align) - ((u_long)bp % sizeof(align));		bp += sizeof(align) - ((u_long)bp % sizeof(align));		if (bp + n >= hostbufEnd) {#ifdef DEBUG			if (_res.options & RES_DEBUG)				printf("size (%d) too big\n", n);#endif			break;		}		bcopy(cp, *hap++ = bp, n);		bp +=n;		bufLen -=n;		cp += n;		haveanswer++;	}	if (haveanswer) {		*ap = NULL;		*hap = NULL;		if (_res.nsort) {			qsort(pHost->h_addr_list, haveanswer,			    sizeof(struct in_addr),			    (int (*)__P((const void *, const void *)))qcomp);		}		return (pHost);	} else {		errno = S_resolvLib_TRY_AGAIN;		return ((struct hostent *) NULL);	}}struct hostent *_gethostbyname(name, pHost, hostbuf, bufLen)	const char *name;	struct hostent *pHost;        char        *hostbuf;        int         bufLen;{	querybuf buf;	register const char *cp;	int n, i;	register struct hostent *hp;	char lookups[MAXDNSLUS];	/*	 * disallow names consisting only of digits/dots, unless	 * they end in a dot.	 */	if (isdigit((int) name[0]))		for (cp = name;; ++cp) {			if (!*cp) {				if (*--cp == '.')					break;				/*				 * All-numeric, no dot at the end.				 * Fake up a hostent as if we'd actually				 * done a lookup.				 */				pHost->h_addr_list[0] = hostbuf;				hostbuf += sizeof(uint32_t);											if (inet_aton((char *) name, 					      (struct in_addr *) pHost->h_addr_list[0]) 					   == ERROR) 				    {					errno = S_resolvLib_HOST_NOT_FOUND;					return((struct hostent *) NULL);				    }				pHost->h_name = (char *)name;				pHost->h_aliases[0] = NULL;				pHost->h_addrtype = AF_INET;				pHost->h_length = sizeof(uint32_t);				pHost->h_addr_list [1] = NULL;				/* Maximum of Two days in seconds */				pHost->h_ttl = MAX_RR_TTL;				return (pHost);			}			if (!isdigit((int) *cp) && *cp != '.') 				break;		}	bcopy(_res.lookups, lookups, sizeof lookups);	if (lookups[0] == '\0')		strncpy(lookups, "bf", sizeof lookups);	hp = (struct hostent *)NULL;		for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {		/*		 * if resolvSend has already contacted this server, lookup		 * is 'd' indicating 'done'. In this case the server will		 * not be contacted again and lookup is reset.		 */		if (_res.lookups [i] == 'd')		    {		    _res.lookups [i] = 'b';		    continue;		    }		switch (lookups[i]) {		case 'b':			/*		         * Set this server to be the active server - 			 * resolvSend will start its querying from this			 * server, skipping the previous servers			 */			_res.lookups[i] = 'a';			if ((n = resSearch(name, C_IN, T_A, buf.buf,			    sizeof(buf))) < 0) {#ifdef DEBUG				if (_res.options & RES_DEBUG)					printf("resSearch failed\n");#endif				break;			}			hp = getanswer(&buf, n, 0, pHost, hostbuf, bufLen );			/* 			 * Validate the address returned by the server - 			 * should not be a network or broadcast address			 * (SPR #67238)			 */			if (((hp->h_addr [3] & 0xff) == 0) ||			    ((hp->h_addr [3] & 0xff) == 0xff))			    {			    hp = NULL;			    errno = S_resolvLib_INVALID_ADDRESS;			    }			break;		}		if (_res.lookups [i] != 'f')		    _res.lookups [i] = 'b'; 	}	return (hp);}struct hostent *_gethostbyaddr(addr, len, type, pHost, hostbuf, bufLen)	const char *addr;	int len, type;	struct hostent *pHost;	char *           hostbuf;	int             bufLen;{	int n, i;	querybuf buf;	register struct hostent *hp;	char qbuf[MAXDNAME];	char lookups[MAXDNSLUS];		if (type != AF_INET)		return ((struct hostent *) NULL);	(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",		((unsigned)addr[3] & 0xff),		((unsigned)addr[2] & 0xff),		((unsigned)addr[1] & 0xff),		((unsigned)addr[0] & 0xff));	bcopy(_res.lookups, lookups, sizeof lookups);	if (lookups[0] == '\0')		strncpy(lookups, "bf", sizeof lookups);	hp = (struct hostent *)NULL;	for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {		/*		 * if resolvSend has already contacted this server, lookup		 * is 'd' indicating 'done'. In this case the server will		 * not be contacted again and lookup is reset.		 */		if (_res.lookups [i] == 'd')		    {		    _res.lookups [i] = 'b';		    continue;		    }		switch (lookups[i]) {		case 'b':			/*		         * Set this server to be the active server - 			 * resolvSend will start its querying from this			 * server, skipping the previous servers			 */			_res.lookups[i] = 'a';			n = resolvQuery(qbuf, C_IN, T_PTR, (char *)&buf, 					sizeof(buf));			if (n == ERROR) {#ifdef DEBUG				if (_res.options & RES_DEBUG)					printf("resolvQuery failed\n");#endif				break;			}			hp = getanswer(&buf, n, 1, pHost, hostbuf, bufLen);			if (hp == NULL)				break;			hp->h_addrtype = type;			hp->h_length = len;            		pHost->h_addr_list [1] = NULL;            		bcopy (addr, (char *) &pHost->h_addr_list [2], 4);            		pHost->h_addr_list [0] =  (char*) & pHost->h_addr_list [2];			break;		}		if (_res.lookups [i] != 'f')		    _res.lookups [i] = 'b';	}	return (hp);}static intqcomp(a1, a2)	struct in_addr **a1, **a2;{	int pos1, pos2;	for (pos1 = 0; pos1 < _res.nsort; pos1++)		if (_res.sort_list[pos1].addr.s_addr ==		    ((*a1)->s_addr & _res.sort_list[pos1].mask))			break;	for (pos2 = 0; pos2 < _res.nsort; pos2++)		if (_res.sort_list[pos2].addr.s_addr ==		    ((*a2)->s_addr & _res.sort_list[pos2].mask))			break;	return pos1 - pos2;}

⌨️ 快捷键说明

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