Incorporated from BIND-4.9.3-BETA9.
authorroland <roland>
Thu, 28 Jul 1994 21:50:33 +0000 (21:50 +0000)
committerroland <roland>
Thu, 28 Jul 1994 21:50:33 +0000 (21:50 +0000)
resolv/gethnamaddr.c
resolv/getnetbyaddr.c
resolv/getnetbyname.c
resolv/getnetent.c
resolv/getnetnamadr.c [new file with mode: 0644]

index 96248bc..35e9007 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * ++Copyright++ 1985, 1988
+ * ++Copyright++ 1985, 1988, 1993
  * -
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1985, 1988, 1993
+ *    The 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
@@ -54,7 +54,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)gethostnamadr.c    6.47 (Berkeley) 6/18/92";
+static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";
 static char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
@@ -63,27 +63,47 @@ static char rcsid[] = "$Id$";
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
+
+#include <stdio.h>
 #include <netdb.h>
 #include <resolv.h>
-#include <stdio.h>
 #include <ctype.h>
 #include <errno.h>
-#include "../conf/portability.h"
+#include <syslog.h>
+
+#ifndef LOG_AUTH
+# define LOG_AUTH 0
+#endif
+
+#define MULTI_PTRS_ARE_ALIASES 1       /* XXX - experimental */
+
+#if defined(BSD) && (BSD >= 199103)
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+#if defined(USE_OPTIONS_H)
+# include <../conf/options.h>
+#endif
 
 #define        MAXALIASES      35
 #define        MAXADDRS        35
 
+static const char AskedForGot[] =
+                         "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
+
 static char *h_addr_ptrs[MAXADDRS + 1];
 
 static struct hostent host;
 static char *host_aliases[MAXALIASES];
-static char hostbuf[BUFSIZ+1];
+static char hostbuf[8*1024];
 static struct in_addr host_addr;
 static FILE *hostf = NULL;
-static char hostaddr[MAXADDRS];
-static char *host_addrs[2];
 static int stayopen = 0;
-char *strpbrk();
+
+#ifdef RESOLVSORT
+static void addrsort __P((char **, int));
+#endif
 
 #if PACKETSZ > 1024
 #define        MAXPACKET       PACKETSZ
@@ -104,20 +124,23 @@ typedef union {
 extern int h_errno;
 
 static struct hostent *
-getanswer(answer, anslen, iquery)
-       querybuf *answer;
+getanswer(answer, anslen, qname, qclass, qtype)
+       const querybuf *answer;
        int anslen;
-       int iquery;
+       const char *qname;
+       int qclass, qtype;
 {
-       register HEADER *hp;
-       register u_char *cp;
+       register const HEADER *hp;
+       register const u_char *cp;
        register int n;
-       u_char *eom;
-       char *bp, **ap;
+       const u_char *eom;
+       char *bp, **ap, **hap;
        int type, class, buflen, ancount, qdcount;
-       int haveanswer, getclass = C_ANY;
-       char **hap;
+       int haveanswer, had_error;
+       int toobig = 0;
+       char tbuf[MAXDNAME+1];
 
+       host.h_name = NULL;
        eom = answer->buf + anslen;
        /*
         * find first satisfactory answer
@@ -126,31 +149,28 @@ getanswer(answer, anslen, iquery)
        ancount = ntohs(hp->ancount);
        qdcount = ntohs(hp->qdcount);
        bp = hostbuf;
-       buflen = sizeof(hostbuf);
-       cp = answer->buf + sizeof(HEADER);
-       if (qdcount) {
-               if (iquery) {
-                       if ((n = dn_expand((u_char *)answer->buf,
-                           (u_char *)eom, (u_char *)cp, (u_char *)bp,
-                           buflen)) < 0) {
-                               h_errno = NO_RECOVERY;
-                               return ((struct hostent *) NULL);
-                       }
-                       cp += n + QFIXEDSZ;
-                       host.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)
-                       h_errno = HOST_NOT_FOUND;
-               else
-                       h_errno = TRY_AGAIN;
-               return ((struct hostent *) NULL);
+       buflen = sizeof hostbuf;
+       cp = answer->buf + HFIXEDSZ;
+       if (qdcount != 1) {
+               h_errno = NO_RECOVERY;
+               return (NULL);
+       }
+       if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
+               h_errno = NO_RECOVERY;
+               return (NULL);
+       }
+       cp += n + QFIXEDSZ;
+       if (qtype == T_A) {
+               /* res_send() has already verified that the query name is the
+                * same as the one we sent; this just gets the expanded name
+                * (i.e., with the succeeding search-domain tacked on).
+                */
+               n = strlen(bp) + 1;             /* for the \0 */
+               host.h_name = bp;
+               bp += n;
+               buflen -= n;
+               /* The qname can be abbreviated, but h_name is now absolute. */
+               qname = host.h_name;
        }
        ap = host_aliases;
        *ap = NULL;
@@ -161,91 +181,174 @@ getanswer(answer, anslen, iquery)
        host.h_addr_list = h_addr_ptrs;
 #endif
        haveanswer = 0;
-       while (--ancount >= 0 && cp < eom) {
-               if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom,
-                   (u_char *)cp, (u_char *)bp, buflen)) < 0)
-                       break;
-               cp += n;
+       had_error = 0;
+       while (ancount-- > 0 && cp < eom && !had_error) {
+               n = dn_expand(answer->buf, eom, cp, bp, buflen);
+               if (n < 0) {
+                       had_error++;
+                       continue;
+               }
+               cp += n;                        /* name */
                type = _getshort(cp);
-               cp += sizeof(u_short);
+               cp += INT16SZ;                  /* type */
                class = _getshort(cp);
-               cp += sizeof(u_short) + sizeof(u_int32_t);
+               cp += INT16SZ + INT32SZ;        /* class, TTL */
                n = _getshort(cp);
-               cp += sizeof(u_short);
-               if (type == T_CNAME) {
+               cp += INT16SZ;                  /* len */
+               if (class != qclass) {
+                       /* XXX - debug? syslog? */
                        cp += n;
+                       continue;               /* XXX - had_error++ ? */
+               }
+               if (qtype == T_A && type == T_CNAME) {
                        if (ap >= &host_aliases[MAXALIASES-1])
                                continue;
+                       n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+                       if (n < 0) {
+                               had_error++;
+                               continue;
+                       }
+                       cp += n;
+                       if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
+                               syslog(LOG_NOTICE|LOG_AUTH,
+               "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
+                                      host.h_name, bp);
+                               continue;       /* XXX - had_error++ ? */
+                       }
+                       /* Store alias. */
                        *ap++ = bp;
-                       n = strlen(bp) + 1;
+                       n = strlen(bp) + 1;     /* for the \0 */
                        bp += n;
                        buflen -= n;
-                       continue;
-               }
-               if (iquery && type == T_PTR) {
-                       if ((n = dn_expand((u_char *)answer->buf,
-                           (u_char *)eom, (u_char *)cp, (u_char *)bp,
-                           buflen)) < 0) {
-                               cp += n;
+                       /* Get canonical name. */
+                       n = strlen(tbuf) + 1;   /* for the \0 */
+                       if (n > buflen) {
+                               had_error++;
                                continue;
                        }
-                       cp += n;
+                       strcpy(bp, tbuf);
                        host.h_name = bp;
-                       return(&host);
+                       bp += n;
+                       buflen -= n;
+                       continue;
                }
-               if (iquery || type != T_A)  {
-#ifdef DEBUG
-                       if (_res.options & RES_DEBUG)
-                               printf("unexpected answer type %d, size %d\n",
-                                       type, n);
-#endif
+               if (type != qtype) {
+                       syslog(LOG_NOTICE|LOG_AUTH,
+                    "gethostby*.getanswer: asked for type %d(%s), got %d(%s)",
+                              qtype, qname, type, bp);
                        cp += n;
-                       continue;
+                       continue;               /* XXX - had_error++ ? */
                }
-               if (haveanswer) {
-                       if (n != host.h_length) {
+               switch (type) {
+               case T_PTR:
+                       if (strcasecmp(qname, bp) != 0) {
+                               syslog(LOG_NOTICE|LOG_AUTH,
+                                      AskedForGot, qname, bp);
                                cp += n;
-                               continue;
+                               continue;       /* XXX - had_error++ ? */
+                       }
+                       n = dn_expand(answer->buf, eom, cp, bp, buflen);
+                       if (n < 0) {
+                               had_error++;
+                               break;
+                       }
+#if MULTI_PTRS_ARE_ALIASES
+                       cp += n;
+                       if (!haveanswer)
+                               host.h_name = bp;
+                       else if (ap < &host_aliases[MAXALIASES-1])
+                               *ap++ = bp;
+                       else
+                               n = -1;
+                       if (n != -1) {
+                               n = strlen(bp) + 1;     /* for the \0 */
+                               bp += n;
+                               buflen -= n;
                        }
-                       if (class != getclass) {
+                       break;
+#else
+                       host.h_name = bp;
+                       return (&host);
+#endif
+               case T_A:
+                       if (strcasecmp(host.h_name, bp) != 0) {
+                               syslog(LOG_NOTICE|LOG_AUTH,
+                                      AskedForGot, host.h_name, bp);
                                cp += n;
-                               continue;
+                               continue;       /* XXX - had_error++ ? */
                        }
-               } else {
-                       host.h_length = n;
-                       getclass = class;
-                       host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
-                       if (!iquery) {
+                       if (haveanswer) {
+                               if (n != host.h_length) {
+                                       cp += n;
+                                       continue;
+                               }
+                       } else {
+                               register int nn;
+
+                               host.h_length = n;
+                               host.h_addrtype = (class == C_IN)
+                                                 ? AF_INET
+                                                 : AF_UNSPEC;
                                host.h_name = bp;
-                               bp += strlen(bp) + 1;
+                               nn = strlen(bp) + 1;    /* for the \0 */
+                               bp += nn;
+                               buflen -= nn;
                        }
-               }
 
-               bp += sizeof(align) - ((u_int32_t)bp % sizeof(align));
+                       bp += sizeof(align) - ((u_long)bp % sizeof(align));
 
-               if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
+                       if (bp + n >= &hostbuf[sizeof hostbuf]) {
 #ifdef DEBUG
-                       if (_res.options & RES_DEBUG)
-                               printf("size (%d) too big\n", n);
+                               if (_res.options & RES_DEBUG)
+                                       printf("size (%d) too big\n", n);
 #endif
+                               had_error++;
+                               continue;
+                       }
+                       if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
+                               if (_res.options & RES_DEBUG && !toobig++)
+                                       printf("Too many addresses (%d)\n",
+                                              MAXADDRS);
+                               cp += n;
+                               continue;
+                       }
+                       bcopy(cp, *hap++ = bp, n);
+                       bp += n;
+                       cp += n;
                        break;
-               }
-               bcopy(cp, *hap++ = bp, n);
-               bp +=n;
-               cp += n;
-               haveanswer++;
-       }
+               default:
+                       abort();
+               } /*switch*/
+               if (!had_error)
+                       haveanswer++;
+       } /*while*/
        if (haveanswer) {
                *ap = NULL;
-#if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
                *hap = NULL;
+# if defined(RESOLVSORT)
+               /*
+                * Note: we sort even if host can take only one address
+                * in its return structures - should give it the "best"
+                * address in that case, not some random one
+                */
+               if (_res.nsort && haveanswer > 1 &&
+                   qclass == C_IN && qtype == T_A)
+                       addrsort(h_addr_ptrs, haveanswer);
+# endif /*RESOLVSORT*/
+#if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
+               /* nothing */
 #else
                host.h_addr = h_addr_ptrs[0];
-#endif
+#endif /*BSD*/
+               if (!host.h_name) {
+                       n = strlen(qname) + 1;  /* for the \0 */
+                       strcpy(bp, qname);
+                       host.h_name = bp;
+               }
                return (&host);
        } else {
                h_errno = TRY_AGAIN;
-               return ((struct hostent *) NULL);
+               return (NULL);
        }
 }
 
@@ -274,15 +377,15 @@ gethostbyname(name)
                                 */
                                if (!inet_aton(name, &host_addr)) {
                                        h_errno = HOST_NOT_FOUND;
-                                       return((struct hostent *) NULL);
+                                       return (NULL);
                                }
                                host.h_name = (char *)name;
                                host.h_aliases = host_aliases;
                                host_aliases[0] = NULL;
                                host.h_addrtype = AF_INET;
-                               host.h_length = sizeof(u_int32_t);
+                               host.h_length = INT32SZ;
                                h_addr_ptrs[0] = (char *)&host_addr;
-                               h_addr_ptrs[1] = (char *)0;
+                               h_addr_ptrs[1] = NULL;
 #if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
                                host.h_addr_list = h_addr_ptrs;
 #else
@@ -302,9 +405,9 @@ gethostbyname(name)
                if (errno == ECONNREFUSED)
                        return (_gethtbyname(name));
                else
-                       return ((struct hostent *) NULL);
+                       return (NULL);
        }
-       return (getanswer(&buf, n, 0));
+       return (getanswer(&buf, n, name, C_IN, T_A));
 }
 
 struct hostent *
@@ -315,17 +418,22 @@ gethostbyaddr(addr, len, type)
        int n;
        querybuf buf;
        register struct hostent *hp;
-       char qbuf[MAXDNAME];
+       char qbuf[MAXDNAME+1];
+#ifdef SUNSECURITY
+       register struct hostent *rhp;
+       char **haddr;
+       u_long old_options;
+#endif /*SUNSECURITY*/
        extern struct hostent *_gethtbyaddr();
        
        if (type != AF_INET)
-               return ((struct hostent *) NULL);
+               return (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));
-       n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
+       n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
        if (n < 0) {
 #ifdef DEBUG
                if (_res.options & RES_DEBUG)
@@ -333,31 +441,57 @@ gethostbyaddr(addr, len, type)
 #endif
                if (errno == ECONNREFUSED)
                        return (_gethtbyaddr(addr, len, type));
-               return ((struct hostent *) NULL);
+               return (NULL);
+       }
+       if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR)))
+               return (NULL);
+#ifdef SUNSECURITY
+       /*
+        * turn off search as the name should be absolute,
+        * 'localhost' should be matched by defnames
+        */
+       old_options = _res.options;
+       _res.options &= ~RES_DNSRCH;
+       _res.options |= RES_DEFNAMES;
+       if (!(rhp = gethostbyname(hp->h_name))) {
+               syslog(LOG_NOTICE|LOG_AUTH,
+                      "gethostbyaddr: No A record for %s (verifying [%s])",
+                      hp->h_name, inet_ntoa(*((struct in_addr *)addr)));
+               _res.options = old_options;
+               return (NULL);
        }
-       hp = getanswer(&buf, n, 1);
-       if (hp == NULL)
-               return ((struct hostent *) NULL);
+       _res.options = old_options;
+       for (haddr = rhp->h_addr_list; *haddr; haddr++)
+               if (!memcmp(*haddr, addr, INADDRSZ))
+                       break;
+       if (!*haddr) {
+               syslog(LOG_NOTICE|LOG_AUTH,
+                      "gethostbyaddr: A record of %s != PTR record [%s]",
+                      hp->h_name, inet_ntoa(*((struct in_addr *)addr)));
+               h_errno = HOST_NOT_FOUND;
+               return (NULL);
+       }
+#endif /*SUNSECURITY*/
        hp->h_addrtype = type;
        hp->h_length = len;
        h_addr_ptrs[0] = (char *)&host_addr;
-       h_addr_ptrs[1] = (char *)0;
+       h_addr_ptrs[1] = NULL;
        host_addr = *(struct in_addr *)addr;
 #if BSD < 43 && !defined(h_addr)       /* new-style hostent structure */
        hp->h_addr = h_addr_ptrs[0];
 #endif
-       return(hp);
+       return (hp);
 }
 
 void
 _sethtent(f)
        int f;
 {
-       if (hostf == NULL)
+       if (!hostf)
                hostf = fopen(_PATH_HOSTS, "r" );
        else
                rewind(hostf);
-       stayopen |= f;
+       stayopen = f;
 }
 
 void
@@ -375,35 +509,36 @@ _gethtent()
        char *p;
        register char *cp, **q;
 
-       if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL)
+       if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" )))
                return (NULL);
 again:
-       if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
+       if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
                return (NULL);
        if (*p == '#')
                goto again;
-       cp = strpbrk(p, "#\n");
-       if (cp == NULL)
+       if (!(cp = strpbrk(p, "#\n")))
                goto again;
        *cp = '\0';
-       cp = strpbrk(p, " \t");
-       if (cp == NULL)
+       if (!(cp = strpbrk(p, " \t")))
                goto again;
        *cp++ = '\0';
        /* THIS STUFF IS INTERNET SPECIFIC */
+       if (!inet_aton(p, &host_addr))
+               goto again;
+       h_addr_ptrs[0] = (char *)&host_addr;
+       h_addr_ptrs[1] = NULL;
 #if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
-       host.h_addr_list = host_addrs;
+       host.h_addr_list = h_addr_ptrs;
+#else
+       host.h_addr = h_addr_ptrs[0];
 #endif
-       host.h_addr = hostaddr;
-       *((u_int32_t *)host.h_addr) = inet_addr(p);
-       host.h_length = sizeof (u_int32_t);
+       host.h_length = INT32SZ;
        host.h_addrtype = AF_INET;
        while (*cp == ' ' || *cp == '\t')
                cp++;
        host.h_name = cp;
        q = host.h_aliases = host_aliases;
-       cp = strpbrk(cp, " \t");
-       if (cp != NULL) 
+       if (cp = strpbrk(cp, " \t"))
                *cp++ = '\0';
        while (cp && *cp) {
                if (*cp == ' ' || *cp == '\t') {
@@ -412,8 +547,7 @@ again:
                }
                if (q < &host_aliases[MAXALIASES - 1])
                        *q++ = cp;
-               cp = strpbrk(cp, " \t");
-               if (cp != NULL)
+               if (cp = strpbrk(cp, " \t"))
                        *cp++ = '\0';
        }
        *q = NULL;
@@ -455,6 +589,51 @@ _gethtbyaddr(addr, len, type)
        return (p);
 }
 
+#ifdef RESOLVSORT
+static void
+addrsort(ap, num)
+       char **ap;
+       int num;
+{
+       int i, j;
+       char **p;
+       short aval[MAXADDRS];
+       int needsort = 0;
+
+       p = ap;
+       for (i = 0; i < num; i++, p++) {
+           for (j = 0 ; j < _res.nsort; j++)
+               if (_res.sort_list[j].addr.s_addr == 
+                   (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
+                       break;
+           aval[i] = j;
+           if (needsort == 0 && i > 0 && j < aval[i-1])
+               needsort = i;
+       }
+       if (!needsort)
+           return;
+
+       while (needsort < num) {
+           for (j = needsort - 1; j >= 0; j--) {
+               if (aval[j] > aval[j+1]) {
+                   char *hp;
+
+                   i = aval[j];
+                   aval[j] = aval[j+1];
+                   aval[j+1] = i;
+
+                   hp = ap[j];
+                   ap[j] = ap[j+1];
+                   ap[j+1] = hp;
+
+               } else
+                   break;
+           }
+           needsort++;
+       }
+}
+#endif
+
 #if defined(BSD43_BSD43_NFS) || defined(sun)
 /* some libc's out there are bound internally to these names (UMIPS) */
 void
@@ -474,7 +653,7 @@ struct hostent *
 ht_gethostbyname(name)
        char *name;
 {
-       return _gethtbyname(name);
+       return (_gethtbyname(name));
 }
 
 struct hostent *
@@ -482,13 +661,13 @@ ht_gethostbyaddr(addr, len, type)
        const char *addr;
        int len, type;
 {
-       return _gethtbyaddr(addr, len, type);
+       return (_gethtbyaddr(addr, len, type));
 }
 
 struct hostent *
 gethostent()
 {
-       return _gethtent();
+       return (_gethtent());
 }
 
 void
@@ -501,6 +680,26 @@ dns_service()
 dn_skipname(comp_dn, eom)
        const u_char *comp_dn, *eom;
 {
-       return __dn_skipname(comp_dn, eom);
+       return (__dn_skipname(comp_dn, eom));
 }
 #endif /*old-style libc with yp junk in it*/
+
+#ifdef ultrix
+/* more icky libc packaging in ultrix */
+int
+local_hostname_length(hostname)
+       const char *hostname;
+{
+       int len_host, len_domain;
+
+       if (!*_res.defdname)
+               res_init();
+       len_host = strlen(hostname);
+       len_domain = strlen(_res.defdname);
+       if (len_host > len_domain &&
+           !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
+           hostname[len_host - len_domain - 1] == '.')
+               return (len_host - len_domain - 1);
+       return (0);
+}
+#endif
index cd6ca20..3bc01ad 100644 (file)
@@ -32,7 +32,8 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getnetbyaddr.c     5.7 (Berkeley) 6/1/90";
+static char sccsid[] = "@(#)getnetbyaddr.c     1.1 (Coimbra) 93/06/02";
+static char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
 #include <netdb.h>
@@ -40,8 +41,8 @@ static char sccsid[] = "@(#)getnetbyaddr.c    5.7 (Berkeley) 6/1/90";
 extern int _net_stayopen;
 
 struct netent *
-getnetbyaddr(net, type)
-       register int32_t net;
+_getnetbyaddr(net, type)
+       register long net;
        register int type;
 {
        register struct netent *p;
index dd4755a..907f583 100644 (file)
@@ -32,7 +32,8 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getnetbyname.c     5.7 (Berkeley) 2/24/91";
+static char sccsid[] = "@(#)getnetbyname.c     1.1 (Coimbra) 93/06/02";
+static char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
 #include <netdb.h>
@@ -41,19 +42,24 @@ static char sccsid[] = "@(#)getnetbyname.c  5.7 (Berkeley) 2/24/91";
 extern int _net_stayopen;
 
 struct netent *
-getnetbyname(name)
+_getnetbyname(name)
+#if (defined(sun) || defined(DGUX))
+       register char *name;
+#else
        register const char *name;
+#endif
 {
        register struct netent *p;
        register char **cp;
 
        setnetent(_net_stayopen);
        while (p = getnetent()) {
-               if (strcmp(p->n_name, name) == 0)
+               if (strcasecmp(p->n_name, name) == 0)
                        break;
-               for (cp = p->n_aliases; *cp != 0; cp++)
-                       if (strcmp(*cp, name) == 0)
+               for (cp = p->n_aliases; *cp != 0; cp++){
+                       if (strcasecmp(*cp, name) == 0)
                                goto found;
+               }
        }
 found:
        if (!_net_stayopen)
index 5a3779d..6d1728b 100644 (file)
  * SUCH DAMAGE.
  */
 
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ *     Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * from getnetent.c    1.1 (Coimbra) 93/06/02
+ */
+
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getnetent.c        5.8 (Berkeley) 2/24/91";
+static char rcsid[] = "$Id$";
 #endif /* LIBC_SCCS and not lint */
 
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <netdb.h>
+#include <arpa/nameser.h>
+
 #include <stdio.h>
+#include <resolv.h>
+#include <netdb.h>
 #include <string.h>
 
+#ifndef _PATH_NETWORKS 
+#define _PATH_NETWORKS  "/etc/networks"
+#endif
+
 #define        MAXALIASES      35
 
 static FILE *netf;
@@ -51,9 +68,26 @@ static struct netent net;
 static char *net_aliases[MAXALIASES];
 int _net_stayopen;
 
+void _setnetent __P((int)), _endnetent __P((void));
+
 void
-setnetent(f)
-       int f;
+setnetent(stayopen)
+int stayopen;
+{
+       sethostent(stayopen);
+       _setnetent(stayopen);
+}
+
+void
+endnetent()
+{
+       endhostent();
+       _endnetent();
+}
+
+void
+_setnetent(f)
+int f;
 {
        if (netf == NULL)
                netf = fopen(_PATH_NETWORKS, "r" );
@@ -63,7 +97,7 @@ setnetent(f)
 }
 
 void
-endnetent()
+_endnetent()
 {
        if (netf) {
                fclose(netf);
diff --git a/resolv/getnetnamadr.c b/resolv/getnetnamadr.c
new file mode 100644 (file)
index 0000000..acb958c
--- /dev/null
@@ -0,0 +1,303 @@
+/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ *     Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ */
+/*
+ * Copyright (c) 1983 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetnamadr.c     1.4 (Coimbra) 93/06/03";
+static char rcsid[] = "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+extern int h_errno;
+
+#if defined(mips) && defined(SYSTYPE_BSD43)
+extern int errno;
+#endif
+
+struct netent *_getnetbyaddr __P((long net, int type));
+#if defined(sun)
+struct netent *_getnetbyname __P((char *name));
+#else
+struct netent *_getnetbyname __P((const char *name));
+#endif
+
+#define BYADDR 0
+#define BYNAME 1
+#define        MAXALIASES      35
+
+#if PACKETSZ > 1024
+#define        MAXPACKET       PACKETSZ
+#else
+#define        MAXPACKET       1024
+#endif
+
+typedef union {
+       HEADER  hdr;
+       u_char  buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+       long    al;
+       char    ac;
+} align;
+
+static struct netent *
+getnetanswer(answer, anslen, net_i)
+       querybuf *answer;
+       int anslen;
+       int net_i;
+{
+
+       register HEADER *hp;
+       register u_char *cp;
+       register int    n;
+       u_char          *eom;
+       int             type, class, buflen, ancount, qdcount,
+                       haveanswer, i, nchar,
+                       getclass = C_ANY,
+                       net_length = 0;
+       char            aux1[30], aux2[30], ans[30],
+                       *in, *st, *pauxt, *bp, **ap,
+                       *paux1 = &aux1[0],
+                       *paux2 = &aux2[0],
+                       flag = 0;
+static struct netent   net_entry;
+static char            *net_aliases[MAXALIASES],
+                       netbuf[BUFSIZ+1];
+
+       /*
+        * find first satisfactory answer
+        *
+        *      answer --> +------------+  ( MESSAGE )
+        *                 |   Header   |
+        *                 +------------+
+        *                 |  Question  | the question for the name server
+        *                 +------------+
+        *                 |   Answer   | RRs answering the question
+        *                 +------------+
+        *                 | Authority  | RRs pointing toward an authority
+        *                 | Additional | RRs holding additional information
+        *                 +------------+
+        */
+       eom = answer->buf + anslen;
+       hp = &answer->hdr;
+       ancount = ntohs(hp->ancount); /* #/records in the answer section */
+       qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
+       bp = netbuf;
+       buflen = sizeof(netbuf);
+       cp = answer->buf + HFIXEDSZ;
+       if (!qdcount) {
+               if (hp->aa)
+                       h_errno = HOST_NOT_FOUND;
+               else
+                       h_errno = TRY_AGAIN;
+
+               return ((struct netent *) NULL);
+       }
+       while (qdcount-- > 0){
+               cp += __dn_skipname(cp, eom) + QFIXEDSZ;
+        }
+       ap = net_aliases;
+       *ap = NULL;
+       net_entry.n_aliases = net_aliases;
+       haveanswer = 0;
+       while (--ancount >= 0 && cp < eom) {
+               n = dn_expand(answer->buf, eom, cp, bp, buflen);
+               if (n < 0)
+                       break;
+               cp += n;
+               ans[0] = '\0';
+               (void)strcpy(&ans[0], bp);
+               GETSHORT(type, cp);
+               GETSHORT(class, cp);
+               cp += INT32SZ;          /* TTL */
+               GETSHORT(n, cp);
+               if (class == C_IN && type == T_PTR) {
+                       n = dn_expand(answer->buf, eom, cp, bp, buflen);
+                       if (n < 0) {
+                               cp += n;
+                               return (NULL);
+                       }
+                       cp += n; 
+                       *ap++ = bp;
+                       bp += (strlen(bp) + 1);
+                       net_entry.n_addrtype = (class == C_IN)
+                                               ? AF_INET
+                                               : AF_UNSPEC;
+                       haveanswer++;
+               }
+       }
+       if (haveanswer) {
+               *ap = NULL;
+               switch (net_i) {
+                  case BYADDR :
+                       net_entry.n_name = *net_entry.n_aliases;
+                       net_entry.n_net = 0L;
+                       break;
+                  case BYNAME :
+                       in = *net_entry.n_aliases;
+                       net_entry.n_name = &ans[0];
+                       aux2[0] = '\0';
+                       for (i = 0;  i < 4;  i++) {
+                               for (st = in, nchar = 0;
+                                    *st != '.';
+                                    st++, nchar++)
+                                       ;
+                               if (nchar != 1 || *in != '0' || flag) {
+                                       flag = 1;
+                                       (void)strncpy(paux1,
+                                                     (i==0) ?in :in-1,
+                                                     (i==0) ?nchar :nchar+1);
+                                       paux1[(i==0) ?nchar :nchar+1] = '\0';
+                                       pauxt = paux2;
+                                       paux2 = strcat(paux1, paux2);
+                                       paux1 = pauxt;
+                               }
+                               in = ++st;
+                       }                 
+                       net_entry.n_net = inet_network(paux2);
+               }
+               net_entry.n_aliases++;
+               return (&net_entry);
+       } else {
+               h_errno = TRY_AGAIN;
+               return ((struct netent *) NULL);
+       }
+}
+
+struct netent *
+getnetbyaddr(net, net_type)
+       register long net;
+       register int net_type;
+{
+       unsigned int    netbr[4];
+       int             nn, anslen;
+       querybuf        buf;
+       char            qbuf[MAXDNAME];
+       unsigned long   net2;
+       struct netent   *net_entry;
+
+       if (net_type != AF_INET)
+               return (_getnetbyaddr(net, net_type));
+
+       for (nn = 4, net2 = net;  net2;  net2 >>= 8) {
+               netbr[--nn] = net2 & 0xff;
+       }
+       switch (nn) {
+               case 3:         /* Class A */
+                       (void)sprintf(qbuf, "0.0.0.%u.in-addr.arpa",
+                                     netbr[3]);
+                       break;
+               case 2:         /* Class B */
+                       (void)sprintf(qbuf, "0.0.%u.%u.in-addr.arpa",
+                                     netbr[3], netbr[2]);
+                       break;
+               case 1:         /* Class C */
+                       (void)sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa",
+                                     netbr[3], netbr[2], netbr[1]);
+                       break;
+               case 0:         /* Class D - E */
+                       (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+                                     netbr[3], netbr[2], netbr[1], netbr[0]);
+                       break;
+       }
+       anslen = res_query(qbuf, C_IN, T_PTR, buf.buf, sizeof buf.buf);
+       if (anslen < 0) {
+#ifdef DEBUG
+               if (_res.options & RES_DEBUG)
+                       printf("res_query failed\n");
+#endif
+               if (errno == ECONNREFUSED)
+                       return (_getnetbyaddr(net, net_type));
+               return (_getnetbyaddr(net, net_type));
+       }
+       net_entry = getnetanswer(&buf, anslen, BYADDR);
+       if (net_entry) {
+               unsigned u_net = net;   /* maybe net should be unsigned ? */
+
+               /* Strip trailing zeros */
+               while ((u_net & 0xff) == 0 && u_net != 0) {
+                       u_net >>= 8;
+               }
+               net_entry->n_net = u_net;
+               return (net_entry);
+       } else {
+               return (_getnetbyaddr(net, net_type));
+       }
+}
+
+struct netent *
+getnetbyname(net)
+#if defined(sun)
+       register char *net;
+#else
+       register const char *net;
+#endif
+{
+       unsigned int    netbr[4];
+       int             anslen;
+       querybuf        buf;
+       char            qbuf[MAXDNAME];
+       struct netent   *net_entry;
+       
+       (void)strcpy(&qbuf[0],net);
+       anslen = res_search(qbuf, C_IN, T_PTR, buf.buf, sizeof buf.buf);
+       if (anslen < 0) {
+#ifdef DEBUG
+               if (_res.options & RES_DEBUG)
+                       printf("res_query failed\n");
+#endif
+               if (errno == ECONNREFUSED)
+                       return (_getnetbyname(net));
+               return (_getnetbyname(net));
+       }
+       net_entry = getnetanswer(&buf, anslen, BYNAME);
+       if (net_entry)
+               return (net_entry);
+       else
+               return (_getnetbyname(net));
+}