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

📄 host.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Return a mnemonic for class */char *pr_class(class)	int class;{	switch (class) {	case C_IN:		/* internet class */		return(verbose? " IN" : "");	case C_HS:		/* internet class */		return(verbose? " HS" : "");	case C_ANY:		/* matches any class */		return(" ANY");	default:		(void) sprintf(nbuf," %d", class);		return nbuf;	}}char *pr_cdname(cp, msg, name, namelen)	u_char *cp, *msg;        u_char *name;        int namelen;{	int n;	if ((n = dn_expand(msg, msg + 512, cp, name, namelen - 2)) < 0)		return (NULL);	if (name[0] == '\0') {		name[0] = '.';		name[1] = '\0';	}	return (char *)(cp + n);}char *resultcodes[] = {	"NOERROR",	"FORMERR",	"SERVFAIL",	"NXDOMAIN",	"NOTIMP",	"REFUSED",	"6",	"7",	"8",	"9",	"10",	"11",	"12",	"13",	"14",	"NOCHANGE",};/* ****************************************************************************** * *  ListHosts -- * *	Requests the name server to do a zone transfer so we *	find out what hosts it knows about. * *  Results: *	SUCCESS		the listing was successful. *	ERROR		the server could not be contacted because  *			a socket could not be obtained or an error *			occured while receiving, or the output file *			could not be opened. * ****************************************************************************** */intListHosts(namePtr, queryType)    char *namePtr;    int  queryType;  /* e.g. T_A */{	querybuf 		buf, answer;	struct sockaddr_in 	sin;	HEADER 			*headerPtr;	int 			msglen;	int 			amtToRead;	int 			numRead;	int 			i;	int 			numAnswers = 0;	int 			result;	int 			soacnt = 0;	u_short 		len;	int			dlen;	int			type;	int			nscount;	u_char 			*cp, *nmp;	u_char 			name[NAME_LEN];	u_char 			dname[2][NAME_LEN];	u_char 			domain[NAME_LEN];/* names and addresses of name servers to try */#define NUMNS 8	char			nsname[NUMNS][NAME_LEN];	int			nshaveaddr[NUMNS];#define IPADDRSIZE 4#define NUMNSADDR 16	char	 		nsipaddr[NUMNSADDR][IPADDRSIZE];	int			numns;	int			numnsaddr;	int			thisns;	struct hostent		*hp;	enum {	    NO_ERRORS, 	    ERR_READING_LEN, 	    ERR_READING_MSG,	    ERR_PRINTING,	} error = NO_ERRORS;/* * normalize to not have trailing dot.  We do string compares below * of info from name server, and it won't have trailing dots. */	i = strlen(namePtr);	if (namePtr[i-1] == '.')	  namePtr[i-1] = 0;	if (server_specified) {	  bcopy(&_res.nsaddr.sin_addr, nsipaddr[0], IPADDRSIZE);	  numnsaddr = 1;	}	else {/* * First we have to find out where to look.  This needs a NS query, * possibly followed by looking up addresses for some of the names. */	msglen = res_mkquery(QUERY, namePtr, C_IN, T_NS,				(char *)0, 0, (char *)0, 				(char *) &buf, sizeof(buf));	if (msglen < 0) {		printf("res_mkquery failed\n");		return (ERROR);	}	msglen = res_send((char *)&buf,msglen,(char *)&answer, sizeof(answer));		if (msglen < 0) {		printf("Unable to get to nameserver -- try again later\n");		return (ERROR);	}	if (_res.options & RES_DEBUG || verbose)		printf("rcode = %d (%s), ancount=%d\n", 		       answer.qb1.rcode, DecodeError(answer.qb1.rcode),		       ntohs(answer.qb1.ancount));/* * Analyze response to our NS lookup */	nscount = ntohs(answer.qb1.ancount) + ntohs(answer.qb1.nscount) +		  ntohs(answer.qb1.arcount);	if (answer.qb1.rcode != NOERROR || nscount == 0) {		switch (answer.qb1.rcode) {			case NXDOMAIN:				/* Check if it's an authoritive answer */				if (answer.qb1.aa) {					printf("No such domain\n");				} else {					printf("Unable to get information about domain -- try again later.\n");				}				break;			case SERVFAIL:				printf("Unable to get information about that domain -- try again later.\n");				break;			case NOERROR:				printf("That domain exists, but seems to be a leaf node.\n");				break;			case FORMERR:			case NOTIMP:			case REFUSED:				printf("Unrecoverable error looking up domain name.\n");				break;		}		return (0);	}	cp = (u_char *)answer.qb2 + sizeof(HEADER);	if (ntohs(answer.qb1.qdcount) > 0)	  cp += dn_skipname(cp, answer.qb2 + msglen) + QFIXEDSZ;	numns = 0;	numnsaddr = 0;/* * Look at response from NS lookup for NS and A records. */	for (;nscount; nscount--) {	  cp += dn_expand(answer.qb2, answer.qb2 + msglen, cp,			  domain, sizeof(domain));	  type = _getshort(cp);	  cp += sizeof(u_short) + sizeof(u_short) + sizeof(u_int32_t);	  dlen = _getshort(cp);	  cp += sizeof(u_short);	  if (type == T_NS) {	    if (dn_expand(answer.qb2, answer.qb2 + msglen, cp, 			  name, sizeof(name)) >= 0) {	      if (numns < NUMNS && strcasecmp((char *)domain, namePtr) == 0) {		for (i = 0; i < numns; i++)		  if (strcasecmp(nsname[i], (char *)name) == 0)		    break;  /* duplicate */		if (i >= numns) {		  strncpy(nsname[numns], (char *)name, sizeof(name));		  nshaveaddr[numns] = 0;		  numns++;		}	      }	    }	  }	  else if (type == T_A) {	    if (numnsaddr < NUMNSADDR)	      for (i = 0; i < numns; i++) {		if (strcasecmp(nsname[i], (char *)domain) == 0) {		  nshaveaddr[i]++;		  bcopy(cp, nsipaddr[numnsaddr],IPADDRSIZE);		  numnsaddr++;		  break;		}	      }	  }	  cp += dlen;	}/* * Usually we'll get addresses for all the servers in the additional * info section.  But in case we don't, look up their addresses. */	for (i = 0; i < numns; i++) {	  if (! nshaveaddr[i]) {	    register long **hptr;	    int numaddrs = 0;	    hp = gethostbyname(nsname[i]);	    if (hp) {	      for (hptr = (long **)hp->h_addr_list; *hptr; hptr++)		if (numnsaddr < NUMNSADDR) {		  bcopy((char *)*hptr, nsipaddr[numnsaddr],IPADDRSIZE);		  numnsaddr++;		  numaddrs++;		}	    }	    if (_res.options & RES_DEBUG || verbose)	      printf("Found %d addresses for %s by extra query\n",		     numaddrs, nsname[i]);	  }	  else	    if (_res.options & RES_DEBUG || verbose)	      printf("Found %d addresses for %s\n",		     nshaveaddr[i], nsname[i]);	}        }/* * Now nsipaddr has numnsaddr addresses for name servers that * serve the requested domain.  Now try to find one that will * accept a zone transfer. */	thisns = 0;again:	numAnswers = 0;	soacnt = 0;	/*	 *  Create a query packet for the requested domain name.	 *	 */	msglen = res_mkquery(QUERY, namePtr, getclass, T_AXFR,				(char *)0, 0, (char *)0, 				(char *) &buf, sizeof(buf));	if (msglen < 0) {	    if (_res.options & RES_DEBUG) {		fprintf(stderr, "ListHosts: Res_mkquery failed\n");	    }	    return (ERROR);	}	bzero((char *)&sin, sizeof(sin));	sin.sin_family	= AF_INET;	sin.sin_port	=  htons(NAMESERVER_PORT);	/*	 *  Set up a virtual circuit to the server.	 */	for (;thisns < numnsaddr; thisns++) {	  if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {	    perror("ListHosts");	    return(ERROR);	  }	  bcopy(nsipaddr[thisns], &sin.sin_addr, IPADDRSIZE);	  if (_res.options & RES_DEBUG || verbose)	    printf("Trying %s\n", inet_ntoa(sin.sin_addr));	  if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) >= 0)	    break;	  if (verbose)	    perror("Connection failed, trying next server");	  (void) close(sockFD);	  sockFD = -1;	}		if (thisns >= numnsaddr) {	  printf("No server for that domain responded\n");	  if (!verbose)	    perror("Error from the last server was");	  return(ERROR);	}	/*	 * Send length & message for zone transfer 	 */        len = htons(msglen);        if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) ||            write(sockFD, (char *) &buf, msglen) != msglen) {		perror("ListHosts");		(void) close(sockFD);		sockFD = -1;		return(ERROR);	}	filePtr = stdout;	while (1) {	    /*	     * Read the length of the response.	     */	    cp = (u_char *) &buf;	    amtToRead = sizeof(u_short);	    while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){		cp 	  += numRead;		amtToRead -= numRead;	    }	    if (numRead <= 0) {		error = ERR_READING_LEN;		break;	    }		    if ((len = htons(*(u_short *)&buf)) == 0) {		break;	/* nothing left to read */	    }	    /*	     * Read the response.	     */	    amtToRead = len;	    cp = (u_char *) &buf;	    while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){		cp += numRead;		amtToRead -= numRead;	    }	    if (numRead <= 0) {		error = ERR_READING_MSG;		break;	    }	    i = buf.qb1.rcode;	    if (i != NOERROR || ntohs(buf.qb1.ancount) == 0) {	      if ((thisns+1) < numnsaddr &&		  (i == SERVFAIL || i == NOTIMP || i == REFUSED)) {		if (_res.options & RES_DEBUG || verbose)		  printf("Server failed, trying next server: %s\n",			 i != NOERROR ? 			 DecodeError(i) : "Premature end of data");		(void) close(sockFD);		sockFD = -1;		thisns++;		goto again;	      }	      printf("Server failed: %s\n",		     i != NOERROR ? DecodeError(i) : "Premature end of data");	      break;	    }	    result = printinfo(&buf, cp, queryType, 1);	    if (! result) {		error = ERR_PRINTING;		break;	    }	    numAnswers++;	    cp = buf.qb2 + sizeof(HEADER);	    if (ntohs(buf.qb1.qdcount) > 0)		cp += dn_skipname(cp, buf.qb2 + len) + QFIXEDSZ;	    nmp = cp;	    cp += dn_skipname(cp, (u_char *)&buf + len);	    if ((_getshort(cp) == T_SOA)) {		dn_expand(buf.qb2, buf.qb2 + len, nmp, dname[soacnt],			sizeof(dname[0]));	        if (soacnt) {		    if (strcmp((char *)dname[0], (char *)dname[1]) == 0)			break;		} else		    soacnt++;	    }        }	(void) close(sockFD);	sockFD = -1;	switch (error) {	    case NO_ERRORS:		return (SUCCESS);	    case ERR_READING_LEN:		return(ERROR);	    case ERR_PRINTING:		fprintf(stderr,"*** Error during listing of %s: %s\n", 				namePtr, DecodeError(result));		return(result);	    case ERR_READING_MSG:		headerPtr = (HEADER *) &buf;		fprintf(stderr,"ListHosts: error receiving zone transfer:\n");		fprintf(stderr,	       "  result: %s, answers = %d, authority = %d, additional = %d\n", 		    	resultcodes[headerPtr->rcode], 		    	ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), 			ntohs(headerPtr->arcount));		return(ERROR);	    default:		return(ERROR);	}}char *DecodeError(result)    int result;{	switch(result) {	    case NOERROR: 	return("Success"); break;	    case FORMERR:	return("Format error"); break;	    case SERVFAIL:	return("Server failed"); break;	    case NXDOMAIN:	return("Non-existent domain"); break;	    case NOTIMP:	return("Not implemented"); break;	    case REFUSED:	return("Query refused"); break;	    case NOCHANGE:	return("No change"); break;	    case NO_INFO: 	return("No information"); break;	    case ERROR: 	return("Unspecified error"); break;	    case TIME_OUT: 	return("Timed out"); break;	    case NONAUTH: 	return("Non-authoritative answer"); break;	    default: 		break;	}	return("BAD ERROR VALUE"); }

⌨️ 快捷键说明

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