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

📄 host.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 *  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. * ****************************************************************************** */static intListHosts(namePtr, queryType)    char *namePtr;    int  queryType;  /* e.g. T_A */{	querybuf_t 		buf, answer;	dns_hdr_t		*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;	u8_t 			*cp, *nmp;	u8_t 			name[NAME_LEN];	char 			dname[2][NAME_LEN];	u8_t 			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;	char *tcp_serv_name;	int tcp_fd;	nwio_tcpconf_t tcpconf;	nwio_tcpcl_t clopt;	int terrno;/* * 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((char *)&_res.nsaddr, 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, (struct rrec *)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.dh_flag2 & DHF_RCODE,		       DecodeError(answer.qb1.dh_flag2 & DHF_RCODE),		       ntohs(answer.qb1.dh_ancount));/* * Analyze response to our NS lookup */	nscount = ntohs(answer.qb1.dh_ancount) + ntohs(answer.qb1.dh_nscount) +		  ntohs(answer.qb1.dh_arcount);	if (answer.qb1.dh_flag2 & DHF_RCODE != NOERROR || nscount == 0) {		switch (answer.qb1.dh_flag2 & DHF_RCODE) {			case NXDOMAIN:				/* Check if it's an authoritive answer */				if (answer.qb1.dh_flag1 & DHF_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 = answer.qb2 + sizeof(dns_hdr_t);	if (ntohs(answer.qb1.dh_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_long);	  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((char *)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, (struct rrec *)0, 				(char *) &buf, sizeof(buf));	if (msglen < 0) {	    if (_res.options & RES_DEBUG) {		fprintf(stderr, "ListHosts: Res_mkquery failed\n");	    }	    return (ERROR);	}	/*	 *  Set up a virtual circuit to the server.	 */	tcp_serv_name= getenv("TCP_DEVICE");	if (!tcp_serv_name)		tcp_serv_name= TCP_DEVICE;	for (;thisns < numnsaddr; thisns++) 	{		tcp_fd= open(tcp_serv_name, O_RDWR);		if (tcp_fd == -1)		{			fprintf(stderr, "unable to open '%s': %s\n", tcp_serv_name,				strerror(errno));			return ERROR;		}		tcpconf.nwtc_flags= NWTC_EXCL | NWTC_LP_SEL | NWTC_SET_RA | 								NWTC_SET_RP;		tcpconf.nwtc_remaddr= *(ipaddr_t *)nsipaddr[thisns];		tcpconf.nwtc_remport= HTONS(NAMESERVER_PORT);		result= ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf);		if (result == -1)		{			fprintf(stderr, "tcp_ioc_setconf failed: %s\n", 				strerror(errno));			close(tcp_fd);			return ERROR;		}		if (_res.options & RES_DEBUG || verbose)			printf("Trying %s\n", inet_ntoa(tcpconf.nwtc_remaddr));		clopt.nwtcl_flags= 0;		result= ioctl(tcp_fd, NWIOTCPCONN, &clopt);		if (result == 0)			break;		terrno= errno;		if (verbose)			fprintf(stderr, 				"Connection failed, trying next server: %s\n",				strerror(errno));		close(tcp_fd);	}		if (thisns >= numnsaddr) {	  printf("No server for that domain responded\n");	  if (!verbose)	    fprintf(stderr, "Error from the last server was: %s\n", 						strerror(terrno));	  return(ERROR);	}	/*	 * Send length & message for zone transfer 	 */        len = htons(msglen);	result= tcpip_writeall(tcp_fd, (char *)&len, sizeof(len));	if (result != sizeof(len))	{		fprintf(stderr, "write failed: %s\n", strerror(errno));		close(tcp_fd);		return ERROR;	}	result= tcpip_writeall(tcp_fd, (char *)&buf, msglen);	if (result != msglen)	{		fprintf(stderr, "write failed: %s\n",			strerror(errno));		close(tcp_fd);		return ERROR;	}	filePtr = stdout;	while (1) {	    /*	     * Read the length of the response.	     */	    cp = (u8_t *) &buf;	    amtToRead = sizeof(u_short);	    while(amtToRead > 0)	    {		result = read(tcp_fd, (char *)cp, amtToRead);		if (result <= 0)			break;		cp 	  += result;		amtToRead -= result;	    }	    if (amtToRead) {		error = ERR_READING_LEN;		break;	    }		    if ((len = htons(*(u_short *)&buf)) == 0) {		break;	/* nothing left to read */	    }	    /*	     * Read the response.	     */	    amtToRead = len;	    cp = (u8_t *) &buf;	    while(amtToRead > 0)	    {		result = read(tcp_fd, (char *)cp, amtToRead);		if (result<= 0)			break;		cp 	  += result;		amtToRead -= result;	    }	    if (amtToRead) {		error = ERR_READING_MSG;		break;	    }	    i = buf.qb1.dh_flag2 & DHF_RCODE;	    if (i != NOERROR || ntohs(buf.qb1.dh_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");		close(tcp_fd);		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(dns_hdr_t);	    if (ntohs(buf.qb1.dh_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, (u8_t *)dname[soacnt],			sizeof(dname[0]));	        if (soacnt) {		    if (strcmp(dname[0], dname[1]) == 0)			break;		} else		    soacnt++;	    }        }	close(tcp_fd);	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 = (dns_hdr_t *) &buf;		fprintf(stderr,"ListHosts: error receiving zone transfer:\n");		fprintf(stderr,	       "  result: %s, answers = %d, authority = %d, additional = %d\n", 		    	resultcodes[headerPtr->dh_flag2 & DHF_RCODE], 		    	ntohs(headerPtr->dh_ancount), 			ntohs(headerPtr->dh_nscount), 			ntohs(headerPtr->dh_arcount));		return(ERROR);	    default:		return(ERROR);	}}static 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"); }static int tcpip_writeall(fd, buf, siz)int fd;char *buf;unsigned siz;{	unsigned siz_org;	int nbytes;	siz_org= siz;	while (siz)	{		nbytes= write(fd, buf, siz);		if (nbytes == -1)			return nbytes;		assert(siz >= nbytes);		buf += nbytes;		siz -= nbytes;	}	return siz_org;}

⌨️ 快捷键说明

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