From owner-freebsd-arch Wed Oct 9 22:35:40 2002 Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7EDEB37B401 for ; Wed, 9 Oct 2002 22:35:31 -0700 (PDT) Received: from pirzyk.org (dsl-65-184-181-29.telocity.com [65.184.181.29]) by mx1.FreeBSD.org (Postfix) with ESMTP id 87D6B43E4A for ; Wed, 9 Oct 2002 22:35:30 -0700 (PDT) (envelope-from jim@pirzyk.org) Received: from snoopy (snoopy.pirzyk.org [10.26.0.4]) by pirzyk.org (8.12.3/8.12.3) with ESMTP id g9A5X0Fb000389 for ; Wed, 9 Oct 2002 22:33:02 -0700 (PDT) (envelope-from jim@pirzyk.org) From: Jim Pirzyk To: freebsd-arch@freebsd.org Subject: getnetby* functions Date: Wed, 9 Oct 2002 22:36:06 -0700 User-Agent: KMail/1.4.3 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="------------Boundary-00=_6K3RC8Q3XF1UIKP2VYDR" Message-Id: <200210092236.06338.jim@pirzyk.org> Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --------------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