Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Oct 2002 22:36:06 -0700
From:      Jim Pirzyk <jim@pirzyk.org>
To:        freebsd-arch@freebsd.org
Subject:   getnetby* functions
Message-ID:  <200210092236.06338.jim@pirzyk.org>

next in thread | raw e-mail | index | archive | help

--------------Boundary-00=_6K3RC8Q3XF1UIKP2VYDR
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

The getnetby* functions seem to be broken for the DNS case.  It
cannot find the .0 address in dns.  I propose that the _getnetbydns*()
functions call the _gethostbydns*() function, reformat the result and
stuff it into the netent struct.  Included is a patch to do such a thing
(it is patched against 4.6.2-RELEASE).

Comments?

- JimP


--=20
--- @(#) $Id: dot.signature,v 1.10 2001/05/17 23:38:49 Jim.Pirzyk Exp $
    __o   jim@pirzyk.org -----------------------------------------------
 _'\<,_   =20
(*)/ (*) =20

--------------Boundary-00=_6K3RC8Q3XF1UIKP2VYDR
Content-Type: text/x-diff;
  charset="us-ascii";
  name="getnetbydns.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="getnetbydns.patch"

*** lib/libc/net/getnetbydns.c.orig	Thu Sep 19 08:58:31 2002
--- lib/libc/net/getnetbydns.c	Sat Sep 21 09:52:14 2002
***************
*** 81,88 ****
  
  extern int h_errno;
  
- #define BYADDR 0
- #define BYNAME 1
  #define	MAXALIASES	35
  
  #if PACKETSZ > 1024
--- 81,86 ----
***************
*** 91,222 ****
  #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;
- 	char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
- 	char *in, *st, *pauxt, *bp, **ap;
- 	char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
  static	struct netent net_entry;
! static	char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
  
! 	/*
! 	 * 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 (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) || !res_dnok(bp))
! 			break;
! 		cp += n;
! 		ans[0] = '\0';
! 		(void)strncpy(&ans[0], bp, sizeof(ans) - 1);
! 		ans[sizeof(ans) - 1] = '\0';
! 		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) || !res_hnok(bp)) {
! 				cp += n;
! 				return (NULL);
! 			}
! 			cp += n; 
! 			*ap++ = bp;
! 			n = strlen(bp) + 1;
! 			bp += n;
! 			buflen -= n;
! 			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);
! 			break;
! 		}
! 		net_entry.n_aliases++;
! 		return (&net_entry);
! 	}
! 	h_errno = TRY_AGAIN;
! 	return (NULL);
  }
  
  struct netent *
--- 89,132 ----
  #define	MAXPACKET	1024
  #endif
  
! struct hostent * _gethostbydnsaddr(const char *, int, int);
! struct hostent * _gethostbydnsname(const char *, int);
  
  static struct netent *
! getnetanswer(answer)
! 	struct hostent *answer;
  {
  
  static	struct netent net_entry;
! static	char *net_aliases[MAXALIASES];
! 	u_long net;
! 	int i;
  
! 	/* Check to make sure we found a hostent */
! 	if ( !answer ) return (NULL);
! 
! 	net_entry.n_name = answer->h_name;
! 
! 	for (i = 0; answer->h_aliases[i] && i < MAXALIASES; i++) {
! 		net_aliases[i] = answer->h_aliases[i];
  	}
  	net_entry.n_aliases = net_aliases;
! 
! 	net_entry.n_addrtype = answer->h_addrtype;
! 
! 	/* One difference between gethostby* and getnetby* is the  */
! 	/* address for the former is in network byte order and the */
! 	/* latter is in machine byte order :(                      */
! 	/* Do the memcpy instead of a cast to make sure we have    */
! 	/* aligned memory for a u_long                             */
! 	memcpy (&net, answer->h_addr, sizeof (net));
! 	net_entry.n_net = ntohl(net);
! 
! 	/* Strip trailing zeros */
! 	while ((net_entry.n_net & 0xff) == 0 && net_entry.n_net != 0)
! 		net_entry.n_net >>= 8;
! 
! 	return (&net_entry);
  }
  
  struct netent *
***************
*** 224,301 ****
  	register unsigned 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 (NULL);
! 
! 	for (nn = 4, net2 = net; net2; net2 >>= 8)
! 		netbr[--nn] = net2 & 0xff;
! 	switch (nn) {
! 	case 3: 	/* Class A */
! 		sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
! 		break;
! 	case 2: 	/* Class B */
! 		sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
! 		break;
! 	case 1: 	/* Class C */
! 		sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
! 		    netbr[1]);
! 		break;
! 	case 0: 	/* Class D - E */
! 		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, (u_char *)&buf, sizeof(buf));
! 	if (anslen < 0) {
! #ifdef DEBUG
! 		if (_res.options & RES_DEBUG)
! 			printf("res_query failed\n");
! #endif
! 		return (NULL);
! 	}
! 	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);
! 	}
! 	return (NULL);
  }
  
  struct netent *
  _getnetbydnsname(net)
  	register const char *net;
  {
! 	int anslen;
! 	querybuf buf;
! 	char qbuf[MAXDNAME];
! 
! 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
! 		h_errno = NETDB_INTERNAL;
! 		return (NULL);
! 	}
! 	strncpy(qbuf, net, sizeof(qbuf) - 1);
! 	qbuf[sizeof(qbuf) - 1] = '\0';
! 	anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
! 	if (anslen < 0) {
! #ifdef DEBUG
! 		if (_res.options & RES_DEBUG)
! 			printf("res_query failed\n");
! #endif
! 		return (NULL);
! 	}
! 	return getnetanswer(&buf, anslen, BYNAME);
  }
  
  void
--- 134,194 ----
  	register unsigned long net;
  	register int net_type;
  {
!      unsigned int netbr[4];
!      int nn, anslen;
!      char qbuf[MAXDNAME];
!      unsigned long net2;
! 	struct hostent *buf;
! 
!      for (nn = 4, net2 = net; net2; net2 >>= 8)
!           netbr[--nn] = net2 & 0xff;
!      switch (nn) {
!      case 3:   /* Class A */
!           sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
!           break;    
!      case 2:   /* Class B */
!           sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
!           break;
!      case 1:   /* Class C */
!           sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
!               netbr[1]);
!           break;
!      case 0:   /* Class D - E */
!           sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
!               netbr[1], netbr[0]);
!           break;
!      }
! 
! 	anslen = strlen(qbuf);
! 
!      if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
!           h_errno = NETDB_INTERNAL;
!           return (NULL);
!      }
!      if (_res.options & RES_USE_INET6) {          /* XXX */
!           buf = _gethostbydnsaddr(qbuf, anslen, AF_INET6);    /* XXX */
!           if (buf)                       /* XXX */
!                return (getnetanswer(buf));             /* XXX */
!      }                             /* XXX */
!      return getnetanswer(_gethostbydnsaddr(qbuf, anslen, AF_INET));
  }
  
  struct netent *
  _getnetbydnsname(net)
  	register const char *net;
  {
! 	struct hostent *hp;
! 
!      if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
!           h_errno = NETDB_INTERNAL;
!           return (NULL);
!      }
!      if (_res.options & RES_USE_INET6) {          /* XXX */
!           hp = _gethostbydnsname(net, AF_INET6);    /* XXX */
!           if (hp)                       /* XXX */
!                return (getnetanswer(hp));             /* XXX */
!      }                             /* XXX */
!      return getnetanswer(_gethostbydnsname(net, AF_INET));
  }
  
  void

--------------Boundary-00=_6K3RC8Q3XF1UIKP2VYDR--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210092236.06338.jim>