Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!bcm!soma!masscomp-request From: sob@cortex.neuro.bcm.tmc.edu (Stan Barber) Newsgroups: comp.sys.masscomp Subject: name server resolver library for MASSCOMP (part 4 of 7) Message-ID: <3472@soma.bcm.tmc.edu> Date: 5 Jul 88 01:01:12 GMT Sender: masscomp@soma.bcm.tmc.edu Lines: 2451 Approved: masscomp@soma.bcm.tmc.edu If you are on the internet and want your Masscomp to understand the Domain Name Service, here is the first step. This is the resolver library. This code is based on BIND 4.8 with all patches to date. Enjoy. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # tools/nslookup/list.c # tools/nslookup/main.c # tools/nslookup/makefile # This archive created: Mon Jul 4 20:28:26 1988 export PATH; PATH=/bin:/usr/bin:$PATH if test ! -d 'tools' then echo shar: "creating directory 'tools'" mkdir 'tools' fi echo shar: "entering directory 'tools'" cd 'tools' if test ! -d 'nslookup' then echo shar: "creating directory 'nslookup'" mkdir 'nslookup' fi echo shar: "entering directory 'nslookup'" cd 'nslookup' echo shar: "extracting 'list.c'" '(20445 characters)' if test -f 'list.c' then echo shar: "will not over-write existing file 'list.c'" else sed 's/^ X//' << \SHAR_EOF > 'list.c' X/* X * Copyright (c) 1985 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#ifndef lint Xstatic char sccsid[] = "@(#)list.c 5.10 (Berkeley) 2/17/88"; X#endif /* not lint */ X X/* X ******************************************************************************* X * X * list.c -- X * X * Routines to obtain info from name and finger servers. X * X * Adapted from 4.3BSD BIND ns_init.c and from /usr/src/ucb/finger.c X * X ******************************************************************************* X */ X X#includeX#ifdef EXOS X#include X#endif X#include X#include X#include X#include X#ifdef SYS5 X#include X#else X#include X#endif X#include X#include X#include X#include "res.h" X X/* X * Imported from res_debug.c X */ Xextern char *_res_resultcodes[]; X Xtypedef union { X HEADER qb1; X char qb2[PACKETSZ]; X} querybuf; X Xextern u_long inet_addr(); Xextern HostInfo *defaultPtr; Xextern HostInfo curHostInfo; Xextern int curHostValid; X X/* X * During a listing to a file, hash marks are printed X * every HASH_SIZE records. X */ X X#define HASH_SIZE 50 X X X/* X ******************************************************************************* X * X * ListHosts -- X * X * Requests the name server to do a zone transfer so we X * find out what hosts it knows about. X * X * There are five types of output: X * - internet addresses (default) X * - cpu type and operating system (-h option) X * - canonical and alias names (-a option) X * - well-known service names (-s option) X * - ALL records (-d option) X * X * To see all three types of information in sorted order, X * do the following: X * ls domain.edu > file X * ls -a domain.edu >> file X * ls -h domain.edu >> file X * ls -s domain.edu >> file X * view file X * X * Results: X * SUCCESS the listing was successful. X * ERROR the server could not be contacted because X * a socket could not be obtained or an error X * occured while receiving, or the output file X * could not be opened. X * X ******************************************************************************* X */ X Xint XListHosts(string, putToFile) X char *string; X int putToFile; X{ X querybuf buf; X struct sockaddr_in sin; X HEADER *headerPtr; X int queryType; X int msglen; X int amtToRead; X int numRead; X int i; X int numAnswers = 0; X int result; X int soacnt = 0; X u_short len; X char *cp, *nmp; X char name[NAME_LEN]; X char dname[2][NAME_LEN]; X char option[NAME_LEN]; X char file[NAME_LEN]; X char *namePtr; X enum { X NO_ERRORS, X ERR_READING_LEN, X ERR_READING_MSG, X ERR_PRINTING, X } error = NO_ERRORS; X X X /* X * X /* X * Parse the command line. It maybe of the form "ls domain", X * "ls -a domain" or "ls -h domain". X */ X i = sscanf(string, " ls %s %s", option, name); X if (putToFile && i == 2 && name[0] == '>') { X i--; X } X if (i == 2) { X if (strcmp("-a", option) == 0) { X queryType = T_CNAME; X } else if (strcmp("-h", option) == 0) { X queryType = T_HINFO; X } else if (strcmp("-m", option) == 0) { X queryType = T_MX; X } else if (strcmp("-s", option) == 0) { X queryType = T_WKS; X } else if (strcmp("-d", option) == 0) { X queryType = T_ANY; X } else { X queryType = T_A; X } X namePtr = name; X } else if (i == 1) { X namePtr = option; X queryType = T_A; X } else { X fprintf(stderr, "ListHosts: invalid request %s\n",string); X return(ERROR); X } X X X /* X * Create a query packet for the requested domain name. X * X */ X msglen = res_mkquery(QUERY, namePtr, C_IN, T_AXFR, X (char *)0, 0, (char *)0, X (char *) &buf, sizeof(buf)); X if (msglen < 0) { X if (_res.options & RES_DEBUG) { X fprintf(stderr, "ListHosts: Res_mkquery failed\n"); X } X return (ERROR); X } X X#ifdef SYS5 X memset((char *)&sin, '\0', sizeof(sin)); X#else X bzero((char *)&sin, sizeof(sin)); X#endif X sin.sin_family = AF_INET; X sin.sin_port = htons(NAMESERVER_PORT); X X /* X * Check to see if we have the address of the server or the X * address of a server who knows about this domain. X * X * For now, just use the first address in the list. X */ X X if (defaultPtr->addrList != NULL) { X sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0]; X } else { X sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0]; X } X X /* X * Set up a virtual circuit to the server. X */ X#ifdef EXOS X if ((sockFD = socket(SOCK_STREAM, 0, 0, 0)) < 0) { X#else X if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) { X#endif X perror("ListHosts"); X return(ERROR); X } X#ifdef EXOS X if (connect(sockFD, &sin) < 0) { X#else X if (connect(sockFD, &sin, sizeof(sin)) < 0) { X#endif X perror("ListHosts"); X (void) close(sockFD); X sockFD = -1; X return(ERROR); X } X X /* X * Send length & message for zone transfer X */ X X len = htons(msglen); X X if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) || X write(sockFD, (char *) &buf, msglen) != msglen) { X perror("ListHosts"); X (void) close(sockFD); X sockFD = -1; X return(ERROR); X } X X fprintf(stdout,"[%s]\n", X (defaultPtr->addrList != NULL) ? defaultPtr->name : X defaultPtr->servers[0]->name); X X if (!putToFile) { X filePtr = stdout; X } else { X filePtr = OpenFile(string, file); X if (filePtr == NULL) { X fprintf(stderr, "*** Can't open %s for writing\n", file); X (void) close(sockFD); X sockFD = -1; X return(ERROR); X } X fprintf(filePtr, "> %s\n", string); X fprintf(filePtr,"[%s]\n", X (defaultPtr->addrList != NULL) ? defaultPtr->name : X defaultPtr->servers[0]->name); X } X X fprintf(filePtr, "%-30s", "Host or domain name"); X switch(queryType) { X case T_ANY: X fprintf(filePtr, " %-30s\n", "Resource record info"); X break; X case T_A: X fprintf(filePtr, " %-30s\n", "Internet address"); X break; X case T_HINFO: X fprintf(filePtr, " %-10s %s\n", "CPU", "OS"); X break; X case T_CNAME: X fprintf(filePtr, " %-30s\n", "Alias"); X break; X case T_MX: X fprintf(filePtr, " %3s %s\n", "Metric", "Host"); X break; X case T_WKS: X fprintf(filePtr, " %-4s %s\n", "Protocol", "Services"); X } X X X while (1) { X X /* X * Read the length of the response. X */ X X cp = (char *) &buf; X amtToRead = sizeof(u_short); X while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){ X cp += numRead; X amtToRead -= numRead; X } X if (numRead <= 0) { X error = ERR_READING_LEN; X break; X } X X if ((len = htons(*(u_short *)&buf)) == 0) { X break; /* nothing left to read */ X } X X /* X * Read the response. X */ X X amtToRead = len; X cp = (char *) &buf; X while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){ X cp += numRead; X amtToRead -= numRead; X } X if (numRead <= 0) { X error = ERR_READING_MSG; X break; X } X X result = PrintListInfo(filePtr, (char *) &buf, cp, queryType); X if (result != SUCCESS) { X error = ERR_PRINTING; X break; X } X X numAnswers++; X if (putToFile && ((numAnswers % HASH_SIZE) == 0)) { X fprintf(stdout, "#"); X fflush(stdout); X } X cp = buf.qb2 + sizeof(HEADER); X if (ntohs(buf.qb1.qdcount) > 0) X cp += dn_skipname(cp, buf.qb2 + len) + QFIXEDSZ; X nmp = cp; X cp += dn_skipname(cp, (u_char *)&buf + len); X if ((_getshort(cp) == T_SOA)) { X dn_expand(buf.qb2, buf.qb2 + len, nmp, dname[soacnt], X sizeof(dname[0])); X if (soacnt) { X if (strcmp(dname[0], dname[1]) == 0) X break; X } else X soacnt++; X } X } X X if (putToFile) { X fprintf(stdout, "%sReceived %d record%s.\n", X (numAnswers >= HASH_SIZE) ? "\n" : "", X numAnswers, X (numAnswers > 1) ? "s" : ""); X } X X (void) close(sockFD); X sockFD = -1; X if (putToFile) { X fclose(filePtr); X filePtr = NULL; X } X X switch ((int)error) { X case NO_ERRORS: X return (SUCCESS); X X case ERR_READING_LEN: X return(ERROR); X X case ERR_PRINTING: X fprintf(stderr,"*** Error during listing of %s: %s\n", X namePtr, DecodeError(result)); X return(result); X X case ERR_READING_MSG: X headerPtr = (HEADER *) &buf; X fprintf(stderr,"ListHosts: error receiving zone transfer:\n"); X fprintf(stderr, X " result: %s, answers = %d, authority = %d, additional = %d\n", X _res_resultcodes[headerPtr->rcode], X ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), X ntohs(headerPtr->arcount)); X return(ERROR); X default: X return(ERROR); X } X} X X X/* X ******************************************************************************* X * X * PrintListInfo -- X * X * Used by the ListInfo routine to print the answer X * received from the name server. Only the desired X * information is printed. X * X * Results: X * SUCCESS the answer was printed without a problem. X * NO_INFO the answer packet did not contain an answer. X * ERROR the answer was malformed. X * Misc. errors returned in the packet header. X * X ******************************************************************************* X */ X X#define NAME_FORMAT " %-30s" X#define STRIP_DOMAIN(string) if((dot = index(string, '.')) != NULL) *dot = '\0' X X XPrintListInfo(file, msg, eom, queryType) X FILE *file; X char *msg, *eom; X int queryType; X{ X register char *cp; X HEADER *headerPtr; X int type, class, dlen, nameLen; X u_long ttl; X int n; X struct in_addr inaddr; X char name[NAME_LEN]; X char name2[NAME_LEN]; X char *dot; X X /* X * Read the header fields. X */ X headerPtr = (HEADER *)msg; X cp = msg + sizeof(HEADER); X if (headerPtr->rcode != NOERROR) { X return(headerPtr->rcode); X } X X /* X * We are looking for info from answer resource records. X * If there aren't any, return with an error. We assume X * there aren't any question records. X */ X X if (ntohs(headerPtr->ancount) == 0) { X return(NO_INFO); X } else { X if (ntohs(headerPtr->qdcount) > 0) { X nameLen = dn_skipname(cp, eom); X if (nameLen < 0) X return (ERROR); X cp += nameLen + QFIXEDSZ; X } X if ((nameLen = dn_expand(msg, eom, cp, name, sizeof(name))) < 0) { X return (ERROR); X } X cp += nameLen; X type = _getshort(cp); X cp += sizeof(u_short); X class = _getshort(cp); X cp += sizeof(u_short); X ttl = _getlong(cp); X cp += sizeof(u_long); X dlen = _getshort(cp); X cp += sizeof(u_short); X if (name[0] == 0) X strcpy(name, "(root)"); X X /* X * QueryType is used to specify the type of desired information. X * T_A - internet address X * T_CNAME - aliases X * T_HINFO - cpu, OS type X * T_MX - mail routing X * T_WKS - well known service X * T_ANY - any X * X */ X switch (type) { X X case T_A: X if (queryType != T_A && queryType != T_ANY) X break; X X if ((_res.options & RES_DEBUG) == 0) X STRIP_DOMAIN(name); X fprintf(file, NAME_FORMAT, name); X if (queryType == T_ANY) X fprintf(file," %-5s", p_type(type)); X if (class == C_IN) { X#ifdef SYS5 X (void)memcpy((char *)&inaddr, cp, sizeof(inaddr)); X#else X bcopy(cp, (char *)&inaddr, sizeof(inaddr)); X#endif X if (dlen == 4) { X fprintf(file," %s", inet_ntoa(inaddr)); X } else if (dlen == 7) { X fprintf(file," %s", inet_ntoa(inaddr)); X fprintf(file," (%d, %d)", cp[4],(cp[5] << 8) + cp[6]); X } else X fprintf(file, " (dlen = %d?)", dlen); X if (_res.options & RES_DEBUG) X fprintf(file,"\t\t\t%lu", ttl); X fprintf(file,"\n"); X } else X goto other; X break; X X case T_CNAME: X if (queryType != T_CNAME && queryType != T_ANY) X break; X X if ((_res.options & RES_DEBUG) == 0) X STRIP_DOMAIN(name); X fprintf(file, NAME_FORMAT, name); X if (queryType == T_ANY) X fprintf(file," %-5s", p_type(type)); X if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { X fprintf(file, " ***\n"); X return (ERROR); X } X /* X * a bug -- cnames need not be in same domain! X * STRIP_DOMAIN(name2); X */ X X fprintf(file, NAME_FORMAT, name2); X if (_res.options & RES_DEBUG) X fprintf(file,"\t%lu", ttl); X fprintf(file,"\n"); X break; X X case T_HINFO: X if (queryType != T_HINFO && queryType != T_ANY) X break; X X if ((_res.options & RES_DEBUG) == 0) X STRIP_DOMAIN(name); X fprintf(file, NAME_FORMAT, name); X if (queryType == T_ANY) X fprintf(file," %-5s", p_type(type)); X if (n = *cp++) { X (void)sprintf(name,"%.*s", n, cp); X fprintf(file," %-10s", name); X cp += n; X } else { X fprintf(file," %-10s", " "); X } X if (n = *cp++) { X fprintf(file," %.*s", n, cp); X cp += n; X } X if (_res.options & RES_DEBUG) X fprintf(file,"\t\t%lu", ttl); X fprintf(file,"\n"); X break; X X case T_MX: X if (queryType != T_MX && queryType != T_ANY) X break; X X if ((_res.options & RES_DEBUG) == 0) X STRIP_DOMAIN(name); X fprintf(file, NAME_FORMAT, name); X if (queryType == T_ANY) X fprintf(file," %-5s", p_type(type)); X X { X short pref; X X pref = _getshort(cp); X cp += sizeof(u_short); X fprintf(file," %-3d ",pref); X } X if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { X fprintf(file, " ***\n"); X return (ERROR); X } X fprintf(file, " %s", name2); X if (_res.options & RES_DEBUG) X fprintf(file,"\t%lu", ttl); X fprintf(file,"\n"); X X break; X X X case T_NS: X case T_PTR: X if (queryType != T_A && queryType != T_ANY) X break; X /* X * Found a name server or pointer record. X */ X if ((_res.options & RES_DEBUG) == 0) X STRIP_DOMAIN(name); X fprintf(file, NAME_FORMAT, name); X if (queryType == T_ANY) X fprintf(file," %-5s", p_type(type)); X fprintf(file," %s = ", type == T_PTR ? "host" : "server"); X cp = Print_cdname2(cp, msg, eom, file); X if (_res.options & RES_DEBUG) X fprintf(file,"\t%lu", ttl); X fprintf(file,"\n"); X break; X X case T_WKS: X if (queryType != T_WKS && queryType != T_ANY) X break; X X if ((_res.options & RES_DEBUG) == 0) X STRIP_DOMAIN(name); X fprintf(file, NAME_FORMAT, name); X if (queryType == T_ANY) X fprintf(file," %-5s", p_type(type)); X if (class == C_IN) { X cp += 4; dlen -= 4; X { X struct protoent *pp; X struct servent *ss; X u_short port; X#ifndef EXOS X X setprotoent(1); X setservent(1); X#endif X n = *cp & 0377; X#ifdef EXOS X pp = 0; X#else X pp = getprotobynumber(n); X#endif X if(pp == 0) X fprintf(file," %-3d ", n); X else X fprintf(file," %-3s ", pp->p_name); X cp++; dlen--; X X port = 0; X while(dlen-- > 0) { X n = *cp++; X do { X if(n & 0200) { X#ifdef EXOS X ss = 0; X#else X ss = getservbyport((int)htons(port), pp->p_name); X#endif X if(ss == 0) X fprintf(file," %d", port); X else X fprintf(file," %s", ss->s_name); X } X n <<= 1; X } while(++port & 07); X } X } X } else X goto other; X if (_res.options & RES_DEBUG) X fprintf(file,"\t%lu", ttl); X fprintf(file,"\n"); X#ifndef EXOS X endprotoent(); X endservent(); X#endif X break; X X case T_SOA: X case T_AXFR: X if (queryType != T_ANY) X break; X fprintf(file, NAME_FORMAT, name); X if (queryType == T_ANY) X fprintf(file," %-5s", p_type(type)); X if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { X fprintf(file, " ***\n"); X return (ERROR); X } X cp += nameLen; X fprintf(file, " %s", name2); X if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) { X fprintf(file, " ***\n"); X return (ERROR); X } X cp += nameLen; X fprintf(file, " %s. (", name2); X for (n = 0; n < 5; n++) { X u_long u; X X u = _getlong(cp); X cp += sizeof(u_long); X fprintf(file,"%s%d", n? " " : "", u); X } X fprintf(file, ")", name2); X if (_res.options & RES_DEBUG) X fprintf(file,"\t%lu", ttl); X fprintf(file,"\n"); X break; X X default: X /* X * Unwanted answer type -- ignore it. X */ X if (queryType != T_ANY) X break; X if ((_res.options & RES_DEBUG) == 0) X STRIP_DOMAIN(name); X fprintf(file, NAME_FORMAT, name); Xother: X fprintf(file," type = %-5s", p_type(type)); X fprintf(file,", class = %-5s", p_class(class)); X if (_res.options & RES_DEBUG) X fprintf(file,"\t%lu\n", ttl); X break; X } X } X return(SUCCESS); X} X X X/* X ******************************************************************************* X * X * ViewList -- X * X * A hack to view the output of the ls command in sorted X * order using more. X * X ******************************************************************************* X */ X XViewList(string) X char *string; X{ X char file[NAME_LEN]; X char command[NAME_LEN]; X X sscanf(string, " view %s", file); X (void)sprintf(command, "grep \"^ \" %s | sort | more", file); X system(command); X} X X/* X ******************************************************************************* X * X * Finger -- X * X * Connects with the finger server for the current host X * to request info on the specified person (long form) X * who is on the system (short form). X * X * Results: X * SUCCESS the finger server was contacted. X * ERROR the server could not be contacted because X * a socket could not be obtained or connected X * to or the service could not be found. X * X ******************************************************************************* X */ X XFinger(string, putToFile) X char *string; X int putToFile; X{ X struct servent *sp; X struct sockaddr_in sin; X register FILE *f; X register int c; X register int lastc; X char name[NAME_LEN]; X char file[NAME_LEN]; X X /* X * We need a valid current host info to get an inet address. X */ X if (!curHostValid) { X fprintf(stderr, "Finger: no current host defined.\n"); X return (ERROR); X } X X if (sscanf(string, " finger %s", name) == 1) { X if (putToFile && (name[0] == '>')) { X name[0] = '\0'; X } X } else { X name[0] = '\0'; X } X X#ifdef SYS5 X memset((char *)&sin, '\0', sizeof(sin)); X#else X bzero((char *)&sin, sizeof(sin)); X#endif X sin.sin_family = curHostInfo.addrType; X#ifdef SYS5 X (void)memcpy((char *)&sin.sin_addr, curHostInfo.addrList[0], X#else X bcopy(curHostInfo.addrList[0], (char *)&sin.sin_addr, X#endif X curHostInfo.addrLen); X#ifdef EXOS X sin.sin_port = IPPORT_FINGER; X sockFD = socket(SOCK_STREAM, 0, (struct sockproto *) 0, 0); X if (sockFD < 0) { X fflush(stdout); X perror("Finger"); X return (ERROR); X } X X if (connect(sockFD, (char *)&sin) < 0) { X fflush(stdout); X perror("Finger"); X close(sockFD); X sockFD = -1; X return (ERROR); X } X#else X sp = getservbyname("finger", "tcp"); X if (sp == 0) { X fprintf(stderr, "Finger: unknown service\n"); X return (ERROR); X } X sin.sin_port = sp->s_port; X /* X * Set up a virtual circuit to the host. X */ X X#ifdef EXOS X sockFD = socket(SOCK_STREAM, 0, 0, 0); X#else X sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0); X#endif X X if (sockFD < 0) { X fflush(stdout); X perror("Finger"); X return (ERROR); X } X X#ifdef EXOS X if (connect(sockFD, (char *)&sin)) < 0) { X#else X if (connect(sockFD, (char *)&sin, sizeof (sin)) < 0) { X#endif X fflush(stdout); X perror("Finger"); X close(sockFD); X sockFD = -1; X return (ERROR); X } X#endif X if (!putToFile) { X filePtr = stdout; X } else { X filePtr = OpenFile(string, file); X if (filePtr == NULL) { X fprintf(stderr, "*** Can't open %s for writing\n", file); X close(sockFD); X sockFD = -1; X return(ERROR); X } X fprintf(filePtr,"> %s\n", string); X } X fprintf(filePtr, "[%s]\n", curHostInfo.name); X X if (name[0] != '\0') { X write(sockFD, "/W ", 3); X } X write(sockFD, name, strlen(name)); X write(sockFD, "\r\n", 2); X f = fdopen(sockFD, "r"); X while ((c = getc(f)) != EOF) { X switch(c) { X case 0210: X case 0211: X case 0212: X case 0214: X c -= 0200; X break; X case 0215: X c = '\n'; X break; X } X putc(lastc = c, filePtr); X } X if (lastc != '\n') { X putc('\n', filePtr); X } X putc('\n', filePtr); X X close(sockFD); X sockFD = -1; X X if (putToFile) { X fclose(filePtr); X filePtr = NULL; X } X return (SUCCESS); X} SHAR_EOF if test 20445 -ne "`wc -c < 'list.c'`" then echo shar: "error transmitting 'list.c'" '(should have been 20445 characters)' fi fi echo shar: "extracting 'main.c'" '(24577 characters)' if test -f 'main.c' then echo shar: "will not over-write existing file 'main.c'" else sed 's/^ X//' << \SHAR_EOF > 'main.c' X/* X * Copyright (c) 1985 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#ifndef lint Xchar copyright[] = X"@(#) Copyright (c) 1985 Regents of the University of California.\n\ X All rights reserved.\n"; X#endif /* not lint */ X X#ifndef lint Xstatic char sccsid[] = "@(#)main.c 5.15 (Berkeley) 3/26/88"; X#endif /* not lint */ X X/* X ******************************************************************************* X * X * main.c -- X * X * Main routine and some action routines for the name server X * lookup program. X * X * Andrew Cherenson CS298-26 Fall 1985 X * X ******************************************************************************* X */ X X#include X#ifdef SYS5 X#include X#else X#include X#endif X#include X#ifdef EXOS X#include X#endif X#include X#include X#include X#include X#include X#include X#include X#include "res.h" X X/* X * Location of the help file. X */ X X#define HELPFILE "/usr1/local/lib/nslookup.help" X X X#if BSD < 43 X/* X * Internet address of the current host. X */ X X#define LOCALHOST "127.0.0.1" X#endif X X X/* X * Name of a top-level name server. Can be changed with X * the "set root" command. X */ X X#define ROOT_SERVER "sri-nic.arpa." Xchar rootServerName[NAME_LEN]; X X X/* X * Import the state information from the resolver library. X */ X Xextern struct state _res; X X X/* X * Info about the most recently queried host. X */ X XHostInfo curHostInfo; Xint curHostValid = FALSE; X X X/* X * Info about the default name server. X */ X XHostInfo *defaultPtr = NULL; Xchar defaultServer[NAME_LEN]; Xstruct in_addr defaultAddr; X X X/* X * Initial name server query type is Address. X */ X Xint queryType = T_A; Xint queryClass = C_IN; X X/* X * Stuff for Interrupt (control-C) signal handler. X * SockFD is the file descriptor for sockets used to X * connect with the name servers. It has to be global to X * allow the interrupt handler can close open sockets. X */ X Xextern int IntrHandler(); Xint sockFD = -1; XFILE *filePtr; Xjmp_buf env; X X X X/* X ******************************************************************************* X * X * main -- X * X * Initializes the resolver library and determines the address X * of the initial name server. The yylex routine is used to X * read and perform commands. X * X ******************************************************************************* X */ X Xmain(argc, argv) X int argc; X char **argv; X{ X int result; X char hostName[NAME_LEN]; X char *wantedHost = NULL; X int useLocalServer; X int i; X struct hostent *hp; X extern int h_errno; X X /* X * Initialize the resolver library routines. X */ X X if (res_init() == -1) { X fprintf(stderr,"*** Can't initialize resolver.\n"); X exit(1); X } X X /* X * Allocate space for the default server's host info and X * find the server's address and name. If the resolver library X * already has some addresses for a potential name server, X * then use them. Otherwise, see if the current host has a server. X * Command line arguments may override the choice of initial server. X */ X X defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo)); X X /* X * Parse the arguments: X * no args = go into interactive mode, use default host as server X * 1 arg = use as host name to be looked up, default host will be server X * non-interactive mode X * 2 args = 1st arg: X * if it is '-', then X * ignore but go into interactive mode X * else X * use as host name to be looked up, X * go into non-interactive mode X * 2nd arg: name or inet address of server X * X */ X X useLocalServer = FALSE; X if (argc > 1) { X if (argc > 3) { X Usage(); X } X argv++; /* skip prog name */ X X if (*argv[0] != '-') { X wantedHost = *argv; /* name of host to be looked up */ X } X if (argc == 3) { X X /* X * Set explicit name server address. X */ X X _res.nscount = 1; X _res.nsaddr.sin_addr.s_addr = inet_addr(*++argv); X if (_res.nsaddr.sin_addr.s_addr == (unsigned)-1) { X hp = gethostbyname(*argv); X if (hp == NULL){ X herror(h_errno); X _res.nscount = 0; X useLocalServer = TRUE; X } else { X#if BSD > 42 X#ifdef SYS5 X (void)memcpy( &_res.nsaddr.sin_addr, hp->h_addr_list[0], X#else X bcopy(hp->h_addr_list[0], &_res.nsaddr.sin_addr, X#endif X hp->h_length); X#else X#ifdef SYS5 X (void)memcpy( &_res.nsaddr.sin_addr,hp->h_addr, X#else X bcopy(hp->h_addr, &_res.nsaddr.sin_addr, X#endif X hp->h_length); X#endif X useLocalServer = FALSE; X } X } X } X } X X X if (_res.nscount > 0 && !useLocalServer) { X for (i = 0; i < _res.nscount; i++) { X if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) { X useLocalServer = TRUE; X break; X } else { X result = FindHostInfo(&(_res.nsaddr_list[i].sin_addr), X &(_res.nsaddr_list[i].sin_addr), X sizeof(struct in_addr), X defaultPtr); X if (result != SUCCESS) { X fprintf(stderr, X "*** Can't find server name for address %s: %s\n", X inet_ntoa(_res.nsaddr_list[i].sin_addr), X DecodeError(result)); X } else { X defaultAddr = _res.nsaddr_list[i].sin_addr; X break; X } X } X } X X /* X * If we have exhausted the list, tell the user about the X * command line argument to specify an address. X */ X X if (i == _res.nscount) { X fprintf(stderr, X "*** Default servers are not available\n"); X exit(1); X } X X } X gethostname(hostName, sizeof(hostName)); X#if BSD >= 43 X strcpy(defaultServer, hostName); X (void) GetHostInfo(&defaultAddr, C_IN, T_A, "0.0.0.0", defaultPtr, 1); X defaultPtr->name = hostName; X#else X if (useLocalServer) { X defaultAddr.s_addr = inet_addr(LOCALHOST); X result = GetHostInfo(&defaultAddr, C_IN, T_A, hostName, defaultPtr, 1); X if (result != SUCCESS) { X fprintf(stderr, X "*** Can't find initialize address for server %s: %s\n", X defaultServer, DecodeError(result)); X exit(1); X } X } X strcpy(defaultServer, defaultPtr->name); X#endif X X strcpy(rootServerName, ROOT_SERVER); X X X#ifdef DEBUG X#ifdef DEBUG2 X _res.options |= RES_DEBUG2; X#endif X _res.options |= RES_DEBUG; X _res.retry = 2; X#endif DEBUG X X /* X * If we're in non-interactive mode, look up the wanted host and quit. X * Otherwise, print the initial server's name and continue with X * the initialization. X */ X X if (wantedHost != (char *) NULL) { X LookupHost(wantedHost, 0); X exit(0); X } else { X PrintHostInfo(stdout, "Default Server:", defaultPtr); X } X X /* X * Setup the environment to allow the interrupt handler to return here. X */ X X (void) setjmp(env); X X /* X * Return here after a longjmp. X */ X X signal(SIGINT, IntrHandler); X X /* X * Read and evaluate commands. The commands are described in commands.l X * Yylex returns 0 when ^D or 'exit' is typed. X */ X X printf("> "); X while(yylex()) { X printf("> "); X } X} X X X/* X ******************************************************************************* X * X * Usage -- X * X * Lists the proper methods to run the program and exits. X * X ******************************************************************************* X */ X XUsage() X{ X fprintf(sised version of the resolver library supplied with BIND 4.8 Xplus patches supplied in the bind mailinglist. This version will work Xunder SYSTEM V on the Unisys 5000 series of computer with the NET-5000 Xproduct. It may work on ATT 3B computers. It will also continue to work Xon BSD-style computers since none of that code has been changed. X XTo install this libarary on Unisys 5000 computers do the following: X XEdit Makefile.resol in both tools and res subdirectories. Make sure Xit looks like the following: X XCFLAGS=-O -DDEBUG -DEXOS -DSYS5 -I../include -I/usr/include/NET-5000 X XEdit Makefile in tools/nslookup subdirectory so that it looks like: X XCFLAGS=-O -DEXOS -DSYS5 -I../../include -I/usr/include/NET-5000 X XWrite the files and type "make library" at the unix prompt. XGo get a snack. This will take about 20 minutes. X XBecome the super user. X XCreate a file called /etc/resolv.conf to contain the following information: XYour domain suffix ("tmc.edu" or "dec.com" or "nsf.net") and up to three Xnameserver addresses. X[An EXAMPLE file is called resolv.conf in this directory. DO NOT use this file. XCreate your own.] X XYou can now use the programs nstest and nsquery in the tools subdirectory Xto test the system. You do not need to be the superuser to do this. X XFor more information, see the bind distribution kit. X X XStan Barber Xsob@tmc.edu X SHAR_EOF if test 1351 -ne "`wc -c < 'README'`" then echo shar: "error transmitting 'README'" '(should have been 1351 characters)' fi fi if test ! -d 'include' then echo shar: "creating directory 'include'" mkdir 'include' fi echo shar: "entering directory 'include'" cd 'include' if test ! -d 'arpa' then echo shar: "creating directory 'arpa'" mkdir 'arpa' fi echo shar: "entering directory 'arpa'" cd 'arpa' echo shar: "extracting 'nameser.h'" '(6838 characters)' if test -f 'nameser.h' then echo shar: "will not over-write existing file 'nameser.h'" else sed 's/^ X//' << \SHAR_EOF > 'nameser.h' X/* X * Copyright (c) 1983 Regents of the University of California. X * All rights reserved. The Berkeley software License Agreement X * specifies the terms and conditions for redistribution. X * X * @(#)nameser.h 5.17 (Berkeley) 11/17/87 X */ X X/* X * Define constants based on rfc883 X */ X#define PACKETSZ 512 /* maximum packet size */ X#define MAXDNAME 256 /* maximum domain name */ X#define MAXCDNAME 255 /* maximum compressed domain name */ X#define MAXLABEL 63 /* maximum length of domain label */ X /* Number of bytes of fixed size data in query structure */ X#define QFIXEDSZ 4 X /* number of bytes of fixed size data in resource record */ X#define RRFIXEDSZ 10 X X/* X * Internet nameserver port number X */ X#define NAMESERVER_PORT 53 X X/* X * Currently defined opcodes X */ X#define QUERY 0x0 /* standard query */ X#define IQUERY 0x1 /* inverse query */ X#define STATUS 0x2 /* nameserver status query */ X/*#define xxx 0x3 /* 0x3 reserved */ X /* non standard */ X#define UPDATEA 0x9 /* add resource record */ X#define UPDATED 0xa /* delete a specific resource record */ X#define UPDATEDA 0xb /* delete all nemed resource record */ X#define UPDATEM 0xc /* modify a specific resource record */ X#define UPDATEMA 0xd /* modify all named resource record */ X X#define ZONEINIT 0xe /* initial zone transfer */ X#define ZONEREF 0xf /* incremental zone referesh */ X X/* X * Currently defined response codes X */ X#define NOERROR 0 /* no error */ X#define FORMERR 1 /* format error */ X#define SERVFAIL 2 /* server failure */ X#define NXDOMAIN 3 /* non existent domain */ X#define NOTIMP 4 /* not implemented */ X#define REFUSED 5 /* query refused */ X /* non standard */ X#define NOCHANGE 0xf /* update failed to change db */ X X/* X * Type values for resources and queries X */ X#define T_A 1 /* host address */ X#define T_NS 2 /* authoritative server */ X#define T_MD 3 /* mail destination */ X#define T_MF 4 /* mail forwarder */ X#define T_CNAME 5 /* connonical name */ X#define T_SOA 6 /* start of authority zone */ X#define T_MB 7 /* mailbox domain name */ X#define T_MG 8 /* mail group member */ X#define T_MR 9 /* mail rename name */ X#define T_NULL 10 /* null resource record */ X#define T_WKS 11 /* well known service */ X#define T_PTR 12 /* domain name pointer */ X#define T_HINFO 13 /* host information */ X#define T_MINFO 14 /* mailbox information */ X#define T_MX 15 /* mail routing information */ X /* non standard */ X#define T_UINFO 100 /* user (finger) information */ X#define T_UID 101 /* user ID */ X#define T_GID 102 /* group ID */ X#define T_UNSPEC 103 /* Unspecified format (binary data) */ X /* Query type values which do not appear in resource records */ X#define T_AXFR 252 /* transfer zone of authority */ X#define T_MAILB 253 /* transfer mailbox records */ X#define T_MAILA 254 /* transfer mail agent records */ X#define T_ANY 255 /* wildcard match */ X X/* X * Values for class field X */ X X#define C_IN 1 /* the arpa internet */ X#define C_CHAOS 3 /* for chaos net at MIT */ X /* Query class values which do not appear in resource records */ X#define C_ANY 255 /* wildcard match */ X X/* X * Status return codes for T_UNSPEC conversion routines X */ X#define CONV_SUCCESS 0 X#define CONV_OVERFLOW -1 X#define CONV_BADFMT -2 X#define CONV_BADCKSUM -3 X#define CONV_BADBUFLEN -4 X X/* X * Structure for query header, the order of the fields is machine and X * compiler dependent, in our case, the bits within a byte are assignd X * least significant first, while the order of transmition is most X * significant first. This requires a somewhat confusing rearrangement. X */ X Xtypedef struct { X u_short id; /* query identification number */ X#if defined (sun) || defined (sel) || defined (pyr) || defined (is68k) \ X|| defined (tahoe) || defined(tower) || defined (BIT_ZERO_ON_LEFT) X /* Bit zero on left: Gould and similar architectures */ X /* fields in third byte */ X u_char qr:1; /* response flag */ X u_char opcode:4; /* purpose of message */ X u_char aa:1; /* authoritive answer */ X u_char tc:1; /* truncated message */ X u_char rd:1; /* recursion desired */ X /* fields in fourth byte */ X u_char ra:1; /* recursion available */ X u_char pr:1; /* primary server required (non standard) */ X u_char unused:2; /* unused bits */ X u_char rcode:4; /* response code */ X#else X#if defined (vax) || defined(ns32000) || defined (BIT_ZERO_ON_RIGHT) X /* Bit zero on right: VAX */ X /* fields in third byte */ X u_char rd:1; /* recursion desired */ X u_char tc:1; /* truncated message */ X u_char aa:1; /* authoritive answer */ X u_char opcode:4; /* purpose of message */ X u_char qr:1; /* response flag */ X /* fields in fourth byte */ X u_char rcode:4; /* response code */ X u_char unused:2; /* unused bits */ X u_char pr:1; /* primary server required (non standard) */ X u_char ra:1; /* recursion available */ X#else X#if defined (pdp11) || defined (BIT_ZERO_ON_RIGHT_BUT_COMPILER_STUPID) X /* Bit zero on right, compiler doesn't like u_char bit fields: PDP */ X /* fields in third byte */ X u_int rd:1; /* recursion desired */ X u_int tc:1; /* truncated message */ X u_int aa:1; /* authoritive answer */ X u_int opcode:4; /* purpose of message */ X u_int qr:1; /* response flag */ X /* fields in fourth byte */ X u_int rcode:4; /* response code */ X u_int unused:2; /* unused bits */ X u_int pr:1; /* primary server required (non standard) */ X u_int ra:1; /* recursion available */ X#else X /* you must determine what the correct bit order is for your compiler */ X UNDEFINED_BIT_ORDER; X#endif X#endif X#endif X /* remaining bytes */ X u_short qdcount; /* number of question entries */ X u_short ancount; /* number of answer entries */ X u_short nscount; /* number of authority entries */ X u_short arcount; /* number of resource entries */ X} HEADER; X X/* X * Defines for handling compressed domain names X */ X#define INDIR_MASK 0xc0 X X/* X * Structure for passing resource records around. X */ Xstruct rrec { X short r_zone; /* zone number */ X short r_class; /* class number */ X short r_type; /* type number */ X u_long r_ttl; /* time to live */ X int r_size; /* size of data area */ X char *r_data; /* pointer to data */ X}; X Xextern u_short _getshort(); Xextern u_long _getlong(); X X/* X * Inline versions of get/put short/long. X * Pointer is advanced; we assume that both arguments X * are lvalues and will already be in registers. X * cp MUST be u_char *. X */ X#define GETSHORT(s, cp) { \ X (s) = *(cp)++ << 8; \ X (s) |= *(cp)++; \ X} X X#define GETLONG(l, cp) { \ X (l) = *(cp)++ << 8; \ X (l) |= *(cp)++; (l) <<= 8; \ X (l) |= *(cp)++; (l) <<= 8; \ X (l) |= *(cp)++; \ X} X X X#define PUTSHORT(s, cp) { \ X *(cp)++ = (s) >> 8; \ X *(cp)++ = (s); \ X} X X/* X * Warning: PUTLONG destroys its first argument. X */ X#define PUTLONG(l, cp) { \ X (cp)[3] = l; \ X (cp)[2] = (l >>= 8); \ X (cp)[1] = (l >>= 8); \ X (cp)[0] = l >> 8; \ X (cp) += sizeof(u_long); \ X} SHAR_EOF if test 6838 -ne "`wc -c < 'nameser.h'`" then echo shar: "error transmitting 'nameser.h'" '(should have been 6838 characters)' fi fi echo shar: "done with directory 'arpa'" cd .. echo shar: "extracting 'netdb.h'" '(2419 characters)' if test -f 'netdb.h' then echo shar: "will not over-write existing file 'netdb.h'" else sed 's/^ X//' << \SHAR_EOF > 'netdb.h' X/* @(#)netdb.h 1.1 86/07/07 SMI; from UCB */ X/* Modified 87.06.20, S. Levy, adding h_addr_list field to hostent X * allowing simultaneous 4.2 and 4.3 compatibility X * (including compatibility with existing 4.2 binary library routines). X * This file combines 4.2, 4.3, SUN and Cray definitions. X * Domain resolver routines set both h_addr and h_addr_list fields. X */ X X/* X * Structures returned by network X * data base library. All addresses X * are supplied in host order, and X * returned in network order (suitable X * for use in system calls). X */ Xstruct hostent { X char *h_name; /* official name of host */ X char **h_aliases; /* alias list */ X int h_addrtype; /* host address type */ X int h_length; /* length of address */ X#define h_addr h_addr_0 /* Dummy to make resolver think we're 4.3 */ X char *h_addr; /* This field for 4.2 binary compatibility. */ X char **h_addr_list; /* list of addresses from name server */ X}; X X/* X * Assumption here is that a network number X * fits in 32 bits -- probably a poor one. X */ Xstruct netent { X char *n_name; /* official name of net */ X char **n_aliases; /* alias list */ X int n_addrtype; /* net address type */ X unsigned long n_net; /* network # */ X}; X Xstruct servent { X char *s_name; /* official service name */ X char **s_aliases; /* alias list */ X int s_port; /* port # */ X char *s_proto; /* protocol to use */ X}; X Xstruct protoent { X char *p_name; /* official protocol name */ X char **p_aliases; /* alias list */ X int p_proto; /* protocol # */ X}; X Xstruct rpcent { X char *r_name; /* name of server for this rpc program */ X char **r_aliases; /* alias list */ X int r_number; /* rpc program number */ X}; X Xstruct hostent *gethostbyname(), *gethostbyaddr(), *gethostent(); Xstruct netent *getnetbyname(), *getnetbyaddr(), *getnetent(); Xstruct servent *getservbyname(), *getservbyport(), *getservent(); Xstruct protoent *getprotobyname(), *getprotobynumber(), *getprotoent(); Xstruct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent(); X X/* X * Error return codes from gethostbyname() and gethostbyaddr() X */ X Xextern int h_errno; X X#define HOST_NOT_FOUND 1 /* Authoritive Answer Host not found */ X#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ X#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ X#define NO_DATA 4 /* Valid name, no data record of requested type */ X#define NO_ADDRESS NO_DATA /* no address, look for MX record */ SHAR_EOF if test 2419 -ne "`wc -c < 'netdb.h'`" then echo shar: "error transmitting 'netdb.h'" '(should have been 2419 characters)' fi fi echo shar: "extracting 'netdb.h.4.2'" '(1920 characters)' if test -f 'netdb.h.4.2' then echo shar: "will not over-write existing file 'netdb.h.4.2'" else sed 's/^ X//' << \SHAR_EOF > 'netdb.h.4.2' X/* X * Copyright (c) 1980 Regents of the University of California. X * All rights reserved. The Berkeley software License Agreement X * specifies the terms and conditions for redistribution. X * X * @(#)netdb.h 5.8 (Berkeley) 11/18/87 X */ X X/* X * Structures returned by network X * data base library. All addresses X * are supplied in host order, and X * returned in network order (suitable X * for use in system calls). X */ Xstruct hostent { X char *h_name; /* official name of host */ X char **h_aliases; /* alias list */ X int h_addrtype; /* host address type */ X int h_length; /* length of address */ X char *h_addr; /* address */ X}; X X/* X * Assumption here is that a network number X * fits in 32 bits -- probably a poor one. X */ Xstruct netent { X char *n_name; /* official name of net */ X char **n_aliases; /* alias list */ X int n_addrtype; /* net address type */ X unsigned long n_net; /* network # */ X}; X Xstruct servent { X char *s_name; /* official service name */ X char **s_aliases; /* alias list */ X int s_port; /* port # */ X char *s_proto; /* protocol to use */ X}; X Xstruct protoent { X char *p_name; /* official protocol name */ X char **p_aliases; /* alias list */ X int p_proto; /* protocol # */ X}; X Xstruct hostent *gethostbyname(), *gethostbyaddr(), *gethostent(); Xstruct netent *getnetbyname(), *getnetbyaddr(), *getnetent(); Xstruct servent *getservbyname(), *getservbyport(), *getservent(); Xstruct protoent *getprotobyname(), *getprotobynumber(), *getprotoent(); X X/* X * Error return codes from gethostbyname() and gethostbyaddr() X * (left in extern int h_errno). X */ X X#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ X#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ X#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ X#define NO_DATA 4 /* Valid name, no data record of requested type */ X#define NO_ADDRESS NO_DATA /* no address, look for MX record */ SHAR_EOF if test 1920 -ne "`wc -c < 'netdb.h.4.2'`" then echo shar: "error transmitting 'netdb.h.4.2'" '(should have been 1920 characters)' fi fi echo shar: "extracting 'resolv.h'" '(1773 characters)' if test -f 'resolv.h' then echo shar: "will not over-write existing file 'resolv.h'" else sed 's/^ X//' << \SHAR_EOF > 'resolv.h' X X/* X * Copyright (c) 1983, 1987 Regents of the University of California. X * All rights reserved. The Berkeley software License Agreement X * specifies the terms and conditions for redistribution. X * X * @(#)resolv.h 5.5 (Berkeley) 5/12/87 X */ X X/* X * Global defines and variables for resolver stub. X */ X X X#define MAXNS 3 /* max # name servers we'll track */ X#define MAXDNSRCH 3 /* max # default domain levels to try */ X#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ X X#define RES_TIMEOUT 4 /* seconds between retries */ X Xstruct state { X int retrans; /* retransmition time interval */ X int retry; /* number of times to retransmit */ X long options; /* option flags - see below. */ X int nscount; /* number of name servers */ X struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */ X#define nsaddr nsaddr_list[0] /* for backward compatibility */ X u_short id; /* current packet id */ X char defdname[MAXDNAME]; /* default domain */ X char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ X}; X X/* X * Resolver options X */ X#define RES_INIT 0x0001 /* address initialized */ X#define RES_DEBUG 0x0002 /* print debug messages */ X#define RES_AAONLY 0x0004 /* authoritative answers only */ X#define RES_USEVC 0x0008 /* use virtual circuit */ X#define RES_PRIMARY 0x0010 /* query primary server only */ X#define RES_IGNTC 0x0020 /* ignore trucation errors */ X#define RES_RECURSE 0x0040 /* recursion desired */ X#define RES_DEFNAMES 0x0080 /* use default domain name */ X#define RES_STAYOPEN 0x0100 /* Keep TCP socket open */ X#define RES_DNSRCH 0x0200 /* search up local domain tree */ X X#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) X Xextern struct state _res; Xextern char *p_cdname(), *p_rr(), *p_type(), *p_class(); SHAR_EOF if test 1773 -ne "`wc -c < 'resolv.h'`" then echo shar: "error transmitting 'resolv.h'" '(should have been 1773 characters)' fi fi echo shar: "done with directory 'include'" cd .. echo shar: "extracting 'Makefile'" '(1767 characters)' if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else sed 's/^ X//' << \SHAR_EOF > 'Makefile' X# X# Copyright (c) 1983 Regents of the University of California. X# All rights reserved. The Berkeley software License Agreement X# specifies the terms and conditions for redistribution. X# X# @(#)Makefile 6.4 (Berkeley) 6/6/87 X# X XOBJS= gethostnamadr.o sethostent.o X XSRCS= gethostnamadr.c sethostent.c X XCFLAGS= -O ${DEFS} -I../../include # Craig Finseth, MSC, April 1988 XTAGSFILE= tags XDESTDIR= X X.c.o: X ${CC} -p -c ${CFLAGS} $*.c X -ld -X -r $*.o X mv a.out profiled/$*.o X ${CC} ${CFLAGS} -c $*.c X -ld -x -r $*.o X mv a.out $*.o X Xhostlib hostlib_p: ${OBJS} X @echo "building profiled hostlib" X @cd profiled; ar cru ../hostlib_p ${OBJS} X @echo "building normal hostlib" X @ar cru hostlib ${OBJS} X Xtags: X cwd=`pwd`; \ X for i in ${SRCS}; do \ X ctags -a -f ${TAGSFILE} $$cwd/$$i; \ X done X Xclean: X rm -f *.o errs a.out core hostlib hostlib_p profiled/*.o tags X Xdepend: X mkdep ${CFLAGS} ${SRCS} X X# DO NOT DELETE THIS LINE -- mkdep uses it. X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. X Xgethostnamadr.c: Xgethostnamadr.o: gethostnamadr.c /usr/include/sys/param.h Xgethostnamadr.o: /usr/include/machine/param.h /usr/include/signal.h Xgethostnamadr.o: /usr/include/sys/types.h /usr/include/sys/sysmacros.h Xgethostnamadr.o: /usr/include/sys/socket.h /usr/include/netinet/in.h Xgethostnamadr.o: /usr/include/ctype.h ../../include/netdb.h Xgethostnamadr.o: /usr/include/stdio.h /usr/include/errno.h Xgethostnamadr.o: /usr/include/sys/errno.h /usr/include/arpa/inet.h Xgethostnamadr.o: ../../include/arpa/nameser.h ../../include/resolv.h Xsethostent.c: Xsethostent.o: sethostent.c /usr/include/sys/types.h Xsethostent.o: /usr/include/sys/sysmacros.h ../../include/arpa/nameser.h Xsethostent.o: /usr/include/netinet/in.h ../../include/resolv.h X X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY SHAR_EOF if test 1767 -ne "`wc -c < 'Makefile'`" then echo shar: "error transmitting 'Makefile'" '(should have been 1767 characters)' fi fi echo shar: "extracting 'gethnamadr.c'" '(8573 characters)' if test -f 'gethnamadr.c' then echo shar: "will not over-write existing file 'gethnamadr.c'" else sed 's/^ X//' << \SHAR_EOF > 'gethnamadr.c' X/* X * Copyright (c) 1985, 1988 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that this notice is preserved and that due credit is given X * to the University of California at Berkeley. The name of the University X * may not be used to endorse or promote products derived from this X * software without specific prior written permission. This software X * is provided ``as is'' without express or implied warranty. X */ X X#if defined(LIBC_SCCS) && !defined(lint) Xstatic char sccsid[] = "@(#)gethostnamadr.c 6.32 (Berkeley) 4/12/88"; X#endif /* LIBC_SCCS and not lint */ X X#include X#ifdef EXOS X#include X#endif X#include X#include X#include X#include X#include X#include X#ifndef EXOS X#include X#endif X#include X#include X X#define MAXALIASES 35 X#define MAXADDRS 35 X Xstatic char *h_addr_ptrs[MAXADDRS + 1]; X Xstatic struct hostent host; Xstatic char *host_aliases[MAXALIASES]; Xstatic char hostbuf[BUFSIZ+1]; Xstatic struct in_addr host_addr; X#ifdef MASSCOMP Xstatic char HOSTDB[] = "/etc/net/hosts"; X#else Xstatic char HOSTDB[] = "/etc/hosts"; X#endif Xstatic FILE *hostf = NULL; Xstatic char hostaddr[MAXADDRS]; Xstatic char *host_addrs[2]; Xstatic int stayopen = 0; Xstatic char *any(); X X#if PACKETSZ > 1024 X#define MAXPACKET PACKETSZ X#else X#define MAXPACKET 1024 X#endif X Xtypedef union { X HEADER hdr; X u_char buf[MAXPACKET]; X} querybuf; X Xstatic union { X long al; X char ac; X} align; X X Xint h_errno; Xextern errno; X Xstatic struct hostent * Xgetanswer(answer, anslen, iquery) X querybuf *answer; X int anslen; X int iquery; X{ X register HEADER *hp; X register u_char *cp; X register int n; X u_char *eom; X char *bp, **ap; X int type, class, buflen, ancount, qdcount; X int haveanswer, getclass = C_ANY; X char **hap; X X eom = answer->buf + anslen; X /* X * find first satisfactory answer X */ X hp = &answer->hdr; X ancount = ntohs(hp->ancount); X qdcount = ntohs(hp->qdcount); X bp = hostbuf; X buflen = sizeof(hostbuf); X cp = answer->buf + sizeof(HEADER); X if (qdcount) { X if (iquery) { X if ((n = dn_expand((char *)answer->buf, eom, X cp, bp, buflen)) < 0) { X h_errno = NO_RECOVERY; X return ((struct hostent *) NULL); X } X cp += n + QFIXEDSZ; X host.h_name = bp; X n = strlen(bp) + 1; X bp += n; X buflen -= n; X } else X cp += dn_skipname(cp, eom) + QFIXEDSZ; X while (--qdcount > 0) X cp += dn_skipname(cp, eom) + QFIXEDSZ; X } else if (iquery) { X if (hp->aa) X h_errno = HOST_NOT_FOUND; X else X h_errno = TRY_AGAIN; X return ((struct hostent *) NULL); X } X ap = host_aliases; X host.h_aliases = host_aliases; X hap = h_addr_ptrs; X#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ X host.h_addr_list = h_addr_ptrs; X#endif X haveanswer = 0; X while (--ancount >= 0 && cp < eom) { X if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0) X break; X cp += n; X type = _getshort(cp); X cp += sizeof(u_short); X class = _getshort(cp); X cp += sizeof(u_short) + sizeof(u_long); X n = _getshort(cp); X cp += sizeof(u_short); X if (type == T_CNAME) { X cp += n; X if (ap >= &host_aliases[MAXALIASES-1]) X continue; X *ap++ = bp; X n = strlen(bp) + 1; X bp += n; X buflen -= n; X continue; X } X if (iquery && type == T_PTR) { X if ((n = dn_expand((char *)answer->buf, eom, X cp, bp, buflen)) < 0) { X cp += n; X continue; X } X cp += n; X host.h_name = bp; X return(&host); X } X if (iquery || type != T_A) { X#ifdef DEBUG X if (_res.options & RES_DEBUG) X printf("unexpected answer type %d, size %d\n", X type, n); X#endif X cp += n; X continue; X } X if (haveanswer) { X if (n != host.h_length) { X cp += n; X continue; X } X if (class != getclass) { X cp += n; X continue; X } X } else { X host.h_length = n; X getclass = class; X host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; X if (!iquery) { X host.h_name = bp; X bp += strlen(bp) + 1; X } X } X X bp += sizeof(align) - ((u_long)bp % sizeof(align)); X X if (bp + n >= &hostbuf[sizeof(hostbuf)]) { X#ifdef DEBUG X if (_res.options & RES_DEBUG) X printf("size (%d) too big\n", n); X#endif X break; X } X#ifdef SYS5 X (void)memcpy(*hap++ = bp, cp, n); X#else X bcopy(cp, *hap++ = bp, n); X#endif X bp +=n; X cp += n; X haveanswer++; X } X if (haveanswer) { X *ap = NULL; X#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ X *hap = NULL; X#endif X host.h_addr = h_addr_ptrs[0]; X return (&host); X } else { X h_errno = TRY_AGAIN; X return ((struct hostent *) NULL); X } X} X Xstruct hostent * Xgethostbyname(name) X char *name; X{ X querybuf buf; X register char *cp; X int n; X struct hostent *hp; X extern struct hostent *_gethtbyname(); X X if (name == NULL || *name == '\0') { X h_errno = HOST_NOT_FOUND; X return ((struct hostent *) NULL); X } X X /* X * disallow names consisting only of digits/dots, unless X * they end in a dot. X */ X if (isdigit(name[0])) X for (cp = name;; ++cp) { X if (!*cp) { X if (*--cp == '.') X break; X h_errno = HOST_NOT_FOUND; X return ((struct hostent *) NULL); X } X if (!isdigit(*cp) && *cp != '.') X break; X } X X if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) { X#ifdef DEBUG X if (_res.options & RES_DEBUG) X printf("res_search failed\n"); X#endif X if (errno == ECONNREFUSED) X return (_gethtbyname(name)); X else X return ((struct hostent *) NULL); X } X return (getanswer(&buf, n, 0)); X} X Xstruct hostent * Xgethostbyaddr(addr, len, type) X char *addr; X int len, type; X{ X int n; X querybuf buf; X register struct hostent *hp; X char qbuf[MAXDNAME]; X extern struct hostent *_gethtbyaddr(); X X if (type != AF_INET) X return ((struct hostent *) NULL); X (void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa", X ((unsigned)addr[3] & 0xff), X ((unsigned)addr[2] & 0xff), X ((unsigned)addr[1] & 0xff), X ((unsigned)addr[0] & 0xff)); X n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf)); X if (n < 0) { X#ifdef DEBUG X if (_res.options & RES_DEBUG) X printf("res_query failed\n"); X#endif X if (errno == ECONNREFUSED) X return (_gethtbyaddr(addr, len, type)); X return ((struct hostent *) NULL); X } X hp = getanswer(&buf, n, 1); X if (hp == NULL) X return ((struct hostent *) NULL); X hp->h_addrtype = type; X hp->h_length = len; X h_addr_ptrs[0] = (char *)&host_addr; X h_addr_ptrs[1] = (char *)0; X host_addr = *(struct in_addr *)addr; X return(hp); X} X X_sethtent(f) X int f; X{ X if (hostf == NULL) X hostf = fopen(HOSTDB, "r" ); X else X rewind(hostf); X stayopen |= f; X} X X_endhtent() X{ X if (hostf && !stayopen) { X (void) fclose(hostf); X hostf = NULL; X } X} X Xstruct hostent * X_gethtent() X{ X char *p; X register char *cp, **q; X X if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL) X return (NULL); Xagain: X if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) X return (NULL); X if (*p == '#') X goto again; X cp = any(p, "#\n"); X if (cp == NULL) X goto again; X *cp = '\0'; X cp = any(p, " \t"); X if (cp == NULL) X goto again; X *cp++ = '\0'; X /* THIS STUFF IS INTERNET SPECIFIC */ X#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ X host.h_addr_list = host_addrs; X#endif X host.h_addr = hostaddr; X *((u_long *)host.h_addr) = inet_addr(p); X host.h_length = sizeof (u_long); X host.h_addrtype = AF_INET; X while (*cp == ' ' || *cp == '\t') X cp++; X host.h_name = cp; X q = host.h_aliases = host_aliases; X cp = any(cp, " \t"); X if (cp != NULL) X *cp++ = '\0'; X while (cp && *cp) { X if (*cp == ' ' || *cp == '\t') { X cp++; X continue; X } X if (q < &host_aliases[MAXALIASES - 1]) X *q++ = cp; X cp = any(cp, " \t"); X if (cp != NULL) X *cp++ = '\0'; X } X *q = NULL; X return (&host); X} X Xstatic char * Xany(cp, match) X register char *cp; X char *match; X{ X register char *mp, c; X X while (c = *cp) { X for (mp = match; *mp; mp++) X if (*mp == c) X return (cp); X cp++; X } X return ((char *)0); X} X Xstruct hostent * X_gethtbyname(name) X char *name; X{ X register struct hostent *p; X register char **cp; X X _sethtent(0); X while (p = _gethtent()) { X if (strcasecmp(p->h_name, name) == 0) X break; X for (cp = p->h_aliases; *cp != 0; cp++) X if (strcasecmp(*cp, name) == 0) X goto found; X } Xfound: X _endhtent(); X return (p); X} X Xstruct hostent * X_gethtbyaddr(addr, len, type) X char *addr; X int len, type; X{ X register struct hostent *p; X X _sethtent(0); X while (p = _gethtent()) X#ifdef SYS5 X if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len)) X#else X if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) X#endif X break; X _endhtent(); X return (p); X} SHAR_EOF if test 8573 -ne "`wc -c < 'gethnamadr.c'`" then echo shar: "error transmitting 'gethnamadr.c'" '(should have been 8573 characters)' fi fi echo shar: "extracting 'sethostent.c'" '(698 characters)' if test -f 'sethostent.c' then echo shar: "will not over-write existing file 'sethostent.c'" else sed 's/^ X//' << \SHAR_EOF > 'sethostent.c' X/* X * Copyright (c) 1985 Regents of the University of California. X * All rights reserved. The Berkeley software License Agreement X * specifies the terms and conditions for redistribution. X */ X X#if defined(LIBC_SCCS) && !defined(lint) Xstatic char sccsid[] = "@(#)sethostent.c 6.3 (Berkeley) 4/10/86"; X#endif LIBC_SCCS and not lint X X#include X#ifdef EXOS X#include X#endif X#include X#include X#include X Xsethostent(stayopen) X{ X if (stayopen) X _res.options |= RES_STAYOPEN | RES_USEVC; X} X Xendhostent() X{ X _res.options &= ~(RES_STAYOPEN | RES_USEVC); X _res_close(); X} X Xsethostfile(name) Xchar *name; X{ X#ifdef lint Xname = name; X#endif X} SHAR_EOF if test 698 -ne "`wc -c < 'sethostent.c'`" then echo shar: "error transmitting 'sethostent.c'" '(should have been 698 characters)' fi fi echo shar: "extracting 'resolv.conf'" '(508 characters)' if test -f 'resolv.conf' then echo shar: "will not over-write existing file 'resolv.conf'" else sed 's/^ X//' << \SHAR_EOF > 'resolv.conf' X# X# Sample resolv.conf file X# X# First, your domain suffix. This suffix will be appended to any X# hostname that does not contain dots. Xdomain snort.edu X# Now, the internet addresses of the name servers you want X# to use. A good rule here is to query servers on your local net first X# and this query those else where. You can have up to three servers here. Xnameserver 55.0.0.1 Xnameserver 135.0.0.2 Xnameserver 195.0.0.3 X# note: these are not real internet addreses. Replace them with the X# real information! X# X SHAR_EOF if test 508 -ne "`wc -c < 'resolv.conf'`" then echo shar: "error transmitting 'resolv.conf'" '(should have been 508 characters)' fi fi exit 0 # End of shell archive DEBUG X if (_res.options & RES_DEBUG) X printf("truncated answer\n"); X#endif DEBUG X (void) close(s); X s = -1; X /* X * retry decremented on continue X * to desired starting value X */ X retry = _res.retry + 1; X v_circuit = 1; X continue; X } X } X#ifdef DEBUG X if (_res.options & RES_DEBUG) { X printf("got answer:\n"); X p_query(answer); X } X#endif DEBUG X /* X * We are going to assume that the first server is preferred X * over the rest (i.e. it is on the local machine) and only X * keep that one open. X */ X if ((_res.options & KEEPOPEN) == KEEPOPEN && ns == 0) { X return (resplen); X } else { X (void) close(s); X s = -1; X return (resplen); X } X } X } X if (s >= 0) { X (void) close(s); X s = -1; X } X if (v_circuit == 0) X if (gotsomewhere == 0) X errno = ECONNREFUSED; X else X errno = ETIMEDOUT; X else X errno = terrno; X return (-1); X} X X/* X * This routine is for closing the socket if a virtual circuit is used and X * the program wants to close it. This provides support for endhostent() X * which expects to close the socket. X * X * This routine is not expected to be user visible. X */ X_res_close() X{ X if (s != -1) { X (void) close(s); X s = -1; X } X} SHAR_EOF if test 9929 -ne "`wc -c < 'res_send.c'`" then echo shar: "error transmitting 'res_send.c'" '(should have been 9929 characters)' fi fi exit 0 # End of shell archive