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
[-- Attachment #1 --]
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
--
--- @(#) $Id: dot.signature,v 1.10 2001/05/17 23:38:49 Jim.Pirzyk Exp $
__o jim@pirzyk.org -----------------------------------------------
_'\<,_
(*)/ (*)
[-- Attachment #2 --]
*** 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210092236.06338.jim>
