The attached patch removes all our own DNS code from isys and replaces it with the glibc NSS functions. We're already shipping libnss_dns.so so this doesn't add any size (well, it adds 27k to the initrd). I'm hoping this will clear up some weird issues I have been seeing lately involving ks= not working. Any thoughts? I'm especially curious if I have broken IPv6. - Chris commit e053d5f8de51138888ba95b2ac0d9700cb041514 Author: Chris Lumens <clumens@xxxxxxxxxx> Date: Tue Feb 5 10:06:07 2008 -0500 Remove our own DNS functions, since glibc's are available now. diff --git a/isys/Makefile b/isys/Makefile index 7f2d304..2df289e 100644 --- a/isys/Makefile +++ b/isys/Makefile @@ -23,7 +23,7 @@ CFLAGS += -I$(PYTHONINCLUDE) -I.. -DHAVE_NFS OBJECTS = nfsmount.o nfsmount_clnt.o nfsmount_xdr.o devices.o imount.o \ smp.o cpio.o uncpio.o dasd.o \ - lang.o isofs.o dns.o linkdetect.o vio.o \ + lang.o isofs.o linkdetect.o vio.o \ ethtool.o wireless.o eddsupport.o nl.o str.o auditd.o SOBJECTS = $(patsubst %.o,%.lo,$(OBJECTS)) SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) isys.c diff --git a/isys/dns.c b/isys/dns.c deleted file mode 100644 index adcbd5c..0000000 --- a/isys/dns.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * dns.c - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <alloca.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <resolv.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> -#include <stdlib.h> -#include <string.h> - -#include "dns.h" - -/* This is dumb, but glibc doesn't like to do hostname lookups w/o libc.so */ - -/* - * IPv6 DNS extensions documented here: - * http://tools.ietf.org/html/rfc3596 - */ - -union dns_response{ - HEADER hdr; - u_char buf[PACKETSZ]; -}; - -static int doQuery(char * query, int queryType, - char ** domainName, void * ipNum, int family) { - int len, ancount, type; - u_char * data, * end; - char name[MAXDNAME]; - union dns_response static_response, *response = &static_response; - size_t response_len = sizeof(static_response); - - /* Give time to finish ethernet negotiation */ - _res.retry = 3; - - do { - len = res_search(query, C_IN, queryType, (void*)response, response_len); - if (len <= 0) return -1; - if (len < response_len) break; - if (response != &static_response) free(response); - if (len > 0x10000) return -1; - response_len = len + 1024; - response = malloc(response_len); - if (response == NULL) return -1; - } while (1); - - if (len < sizeof(response->hdr)) { - if (response != &static_response) free(response); - return -1; - } - - if (ntohs(response->hdr.rcode) != NOERROR) { - if (response != &static_response) free(response); - return -1; - } - - ancount = ntohs(response->hdr.ancount); - - if (ancount < 1) { - if (response != &static_response) free(response); - return -1; - } - - data = response->buf + sizeof(HEADER); - end = response->buf + len; - - /* skip the question */ - len = dn_skipname(data, end); - if (len <= 0) { - if (response != &static_response) free(response); - return -1; - } - data += len + QFIXEDSZ; - - /* parse the answer(s) */ - while (--ancount >= 0 && data < end) { - /* skip the domain name portion of the RR record */ - data += dn_skipname(data, end); - - /* get RR information */ - if (data + 3 * INT16SZ + INT32SZ > end) { - if (response != &static_response) free(response); - return -1; - } - GETSHORT(type, data); - data += INT16SZ; /* skip class */ - data += INT32SZ; /* skip TTL */ - GETSHORT(len, data); - - if (type == T_PTR) { - /* we got a pointer */ - len = dn_expand(response->buf, end, data, name, sizeof(name)); - if (len <= 0) { - if (response != &static_response) free(response); - return -1; - } - if (queryType == T_PTR && domainName) { - /* we wanted a pointer */ - *domainName = malloc(strlen(name) + 1); - strcpy(*domainName, name); - if (response != &static_response) free(response); - return 0; - } - } else if (type == T_A) { - /* we have an IPv4 address */ - if (queryType == T_A && ipNum) { - memcpy(ipNum, data, sizeof(struct in_addr)); - if (response != &static_response) - free(response); - return 0; - } - } else if (type == T_AAAA) { - /* we have an IPv6 address */ - if (queryType == T_AAAA && ipNum) { - memcpy(ipNum, data, sizeof(struct in6_addr)); - if (response != &static_response) - free(response); - return 0; - } - } - - /* move ahead to next RR */ - data += len; - } - - if (response != &static_response) free(response); - return -1; -} - -char * mygethostbyaddr(char * ipnum, int family) { - int i, j, ret; - char *buf = NULL; - char sbuf[5]; - char *result = NULL; - char *octets[4]; - char *octet = NULL; - char *parts[8]; - char *partptr = NULL; - struct in6_addr addr6; - - _res.retry = 1; - - if (ipnum == NULL || (family != AF_INET && family != AF_INET6)) - return NULL; - - if (family == AF_INET) { - buf = strdup(ipnum); - octet = strtok(buf, "."); - - i = 0; - while (octet != NULL) { - octets[i] = octet; - i++; - octet = strtok(NULL, "."); - } - - if (i == 4) { - if (asprintf(&ipnum, "%s.%s.%s.%s.in-addr.arpa", octets[3], - octets[2], octets[1], octets[0]) == -1) - return NULL; - } else { - return NULL; - } - - free(buf); - buf = NULL; - } else if (family == AF_INET6) { - if (!inet_pton(AF_INET6, ipnum, &addr6)) - return NULL; - - i = 7; - while (i >= 0) { - sprintf(sbuf, "%4x", ntohs(addr6.s6_addr16[i])); - sbuf[4] = '\0'; - - if ((parts[i] = malloc(8)) == NULL) - return NULL; - - partptr = parts[i]; - - for (j = 3; j >= 0; j--) { - if (sbuf[j] == ' ') - *partptr = '0'; - else - *partptr = sbuf[j]; - - partptr++; - - if (j != 0) { - *partptr = '.'; - partptr++; - } - } - - i--; - } - - if (asprintf(&ipnum, "%s.%s.%s.%s.%s.%s.%s.%s.ip6.arpa", parts[7], - parts[6], parts[5], parts[4], parts[3], parts[2], - parts[1], parts[0]) == -1) - return NULL; - - for (j = 0; j < 8; j++) { - free(parts[j]); - parts[j] = NULL; - } - } - - ret = doQuery(ipnum, T_PTR, &result, NULL, family); - if (ret) - ret = doQuery(ipnum, T_PTR, &result, NULL, family); - - if (ret) - return NULL; - else - return result; -} - -int mygethostbyname(char * name, void * addr, int family) { - int type; - - if (family == AF_INET) - type = T_A; - else if (family == AF_INET6) - type = T_AAAA; - else - type = -1; - - return doQuery(name, type, NULL, addr, family); -} - -#if 0 -int main(int argc, char **argv) { - struct in_addr addr; - struct in6_addr addr6; - char *ret = NULL; - - /* IPv4 tests */ - printf("hostname for %s is %s\n", "152.1.2.22", - mygethostbyaddr("152.1.2.22", AF_INET)); - if (mygethostbyname("www.redhat.com", &addr, AF_INET) == 0) { - ret = malloc(48); - inet_ntop(AF_INET, &addr, ret, INET_ADDRSTRLEN); - printf("ip for www.redhat.com is %s\n", ret); - free(ret); - ret = NULL; - } - - /* IPv6 tests */ - printf("hostname for %s is %s\n", "fec0:acdc:1::1", - mygethostbyaddr("fec0:acdc:1::1", AF_INET6)); - if (mygethostbyname("cutlet.ipv6.install.boston.redhat.com", &addr6, AF_INET6) == 0) { - ret = malloc(48); - inet_ntop(AF_INET6, &addr6, ret, INET6_ADDRSTRLEN); - printf("ip for cutlet.ipv6.install.boston.redhat.com is %s\n", ret); - free(ret); - ret = NULL; - } - - return 0; -} -#endif - -/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/isys/dns.h b/isys/dns.h deleted file mode 100644 index aa1136a..0000000 --- a/isys/dns.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * dns.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef H_DNS -#define H_DNS - -#include <netinet/in.h> - -int mygethostbyname(char * name, void * addr, int family); -char * mygethostbyaddr(char * ipnum, int family); - -#endif diff --git a/isys/nfsmount.c b/isys/nfsmount.c index 21ad20d..55ba336 100644 --- a/isys/nfsmount.c +++ b/isys/nfsmount.c @@ -59,8 +59,6 @@ #include "nfs_mount4.h" #undef NFS_NEED_KERNEL_TYPES -#include "dns.h" - static char *nfs_strerror(int stat); #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r)) @@ -310,11 +308,13 @@ int nfsmount(const char *spec, const char *node, int *flags, if (!inet_aton(hostname, &server_addr.sin_addr)) #endif { - if (mygethostbyname(hostname, &server_addr.sin_addr, AF_INET)) { + struct hostent *he = gethostbyname(hostname); + if (he) { + memcpy(&server_addr.sin_addr, he->h_addr_list[0], he->h_length); + server_addr.sin_family = he->h_addrtype; + } else { myerror = ERROR_HOSTNAME; goto fail; - } else { - server_addr.sin_family = AF_INET; } } @@ -548,12 +548,14 @@ int nfsmount(const char *spec, const char *node, int *flags, mount_server_addr.sin_family = AF_INET; mount_server_addr.sin_addr.s_addr = inet_addr(hostname); } else { - if (mygethostbyname(hostname, &mount_server_addr.sin_addr, AF_INET)) { - myerror = ERROR_HOSTNAME; - goto fail; - } else { - mount_server_addr.sin_family = AF_INET; - } + struct hostent *he = gethostbyname(hostname); + if (he) { + memcpy(&server_addr.sin_addr, he->h_addr_list[0], he->h_length); + server_addr.sin_family = he->h_addrtype; + } else { + myerror = ERROR_HOSTNAME; + goto fail; + } } } diff --git a/loader2/ftp.c b/loader2/ftp.c index 242a1ac..940b8df 100644 --- a/loader2/ftp.c +++ b/loader2/ftp.c @@ -26,7 +26,6 @@ #define HAVE_ALLOCA_H 1 #define HAVE_NETINET_IN_SYSTM_H 1 #define HAVE_SYS_SOCKET_H 1 -#define USE_ALT_DNS 1 #if HAVE_ALLOCA_H # include <alloca.h> @@ -70,10 +69,6 @@ extern int h_errno; # define IPPORT_FTP 21 #endif -#if defined(USE_ALT_DNS) && USE_ALT_DNS -#include "../isys/dns.h" -#endif - #include "ftp.h" #include "log.h" #include "net.h" @@ -217,6 +212,7 @@ int ftpCommand(int sock, char * command, ...) { static int getHostAddress(const char * host, void * address, int family) { char *hostname, *port; + struct hostent *hostent; splitHostname((char *) host, &hostname, &port); @@ -228,11 +224,12 @@ static int getHostAddress(const char * host, void * address, int family) { return FTPERR_BAD_HOST_ADDR; } } else { - if (mygethostbyname(hostname, (struct in_addr *)address, AF_INET)) { + if ((hostent = gethostbyname(hostname)) != NULL) { + memcpy((struct in_addr *) address, hostent->h_addr_list[0], hostent->h_length); + return 0; + } else { errno = h_errno; return FTPERR_BAD_HOSTNAME; - } else { - return 0; } } } else if (family == AF_INET6) { @@ -242,9 +239,13 @@ static int getHostAddress(const char * host, void * address, int family) { } else return FTPERR_BAD_HOST_ADDR; } else { - /* FIXME: implement me */ - logMessage(ERROR, "we don't have reverse DNS for IPv6 yet"); - return FTPERR_BAD_HOSTNAME; + if ((hostent = gethostbyname(hostname)) != NULL) { + memcpy((struct in_addr6 *) address, hostent->h_addr_list[0], hostent->h_length); + return 0; + } else { + errno = h_errno; + return FTPERR_BAD_HOSTNAME; + } } } else { return FTPERR_UNSUPPORTED_FAMILY; diff --git a/loader2/net.c b/loader2/net.c index 0be97f6..2bb2c85 100644 --- a/loader2/net.c +++ b/loader2/net.c @@ -20,6 +20,7 @@ * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> */ +#include <netdb.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> @@ -35,7 +36,6 @@ #include <strings.h> #include <unistd.h> -#include "../isys/dns.h" #include "../isys/isys.h" #include "../isys/net.h" #include "../isys/wireless.h" @@ -1539,6 +1539,7 @@ int findHostAndDomain(struct networkDeviceConfig * dev) { char * name, * chptr; char ret[48]; ip_addr_t *tip; + struct hostent *host; if (!FL_TESTING(flags)) { writeResolvConf(dev); @@ -1558,16 +1559,18 @@ int findHostAndDomain(struct networkDeviceConfig * dev) { tip = &(dev->dev.ip); inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - name = mygethostbyaddr(ret, tip->sa_family); + host = gethostbyaddr(ret, IP_STRLEN(tip), tip->sa_family); if (!FL_CMDLINE(flags)) newtPopWindow(); - if (!name) { - logMessage(WARNING, "reverse name lookup failed"); + if (!host) { + logMessage(WARNING, "reverse name lookup of %s failed", ret); return 1; } + name = strdup(host->h_name); + logMessage(INFO, "reverse name lookup worked"); dev->dev.hostname = strdup(name); diff --git a/loader2/urls.c b/loader2/urls.c index 3a47fa7..f730133 100644 --- a/loader2/urls.c +++ b/loader2/urls.c @@ -34,8 +34,6 @@ #include <unistd.h> #include <netdb.h> -#include "../isys/dns.h" - #include "ftp.h" #include "lang.h" #include "loader.h" @@ -172,6 +170,7 @@ int urlinstStartTransfer(struct iurlinfo * ui, char * filename, struct in_addr addr; struct in6_addr addr6; char *hostname, *portstr; + struct hostent *host; if (!strcmp(ui->prefix, "/")) finalPrefix = ""; @@ -201,14 +200,13 @@ int urlinstStartTransfer(struct iurlinfo * ui, char * filename, else if (inet_pton(AF_INET6, hostname, &addr6) >= 1) family = AF_INET6; else { - if (mygethostbyname(hostname, &addr, AF_INET) == 0) { - family = AF_INET; - } else if (mygethostbyname(hostname, &addr6, AF_INET6) == 0) { - family = AF_INET6; - } else { - logMessage(ERROR, "cannot determine address family of %s", - hostname); + if ((host = gethostbyname(hostname)) == NULL) { + logMessage(ERROR, "cannot determine address family of %s: %s", + hostname, hstrerror(h_errno)); + return -1; } + else + family = host->h_addrtype; } if (ui->protocol == URL_METHOD_FTP) { @@ -258,6 +256,7 @@ char * addrToIp(char * hostname) { struct in_addr ad; struct in6_addr ad6; char *ret; + struct hostent *host; if ((ret = malloc(48)) == NULL) return hostname; @@ -266,10 +265,8 @@ char * addrToIp(char * hostname) { return ret; else if (inet_ntop(AF_INET6, &ad6, ret, INET6_ADDRSTRLEN) != NULL) return ret; - else if (mygethostbyname(hostname, &ad, AF_INET) == 0) - return hostname; - else if (mygethostbyname(hostname, &ad6, AF_INET6) == 0) - return hostname; + else if ((host = gethostbyname(hostname)) != NULL) + return host->h_name; else return NULL; } diff --git a/scripts/mk-images b/scripts/mk-images index a08fe21..fd7c340 100755 --- a/scripts/mk-images +++ b/scripts/mk-images @@ -531,6 +531,7 @@ makeinitrd() { install -m 644 $MYLANGTABLE $MBD_DIR/etc/lang-table install -m 644 $IMGPATH/etc/passwd $MBD_DIR/etc/passwd install -m 644 $IMGPATH/etc/group $MBD_DIR/etc/group + install -m 644 $IMGPATH/etc/nsswitch.conf $MBD_DIR/etc/nsswitch.conf instbin $IMGPATH /usr/sbin/udevd $MBD_DIR /sbin/udevd instbin $IMGPATH /usr/sbin/udevadm $MBD_DIR /sbin/udevadm @@ -539,6 +540,7 @@ makeinitrd() { ln -s udevadm $MBD_DIR/sbin/udevsettle # Indirect dependencies + install -m 755 $IMGPATH/$LIBDIR/libnss_dns.so.2 $MBD_DIR/$LIBDIR/ install -m 755 $IMGPATH/$LIBDIR/libnss_files.so.2 $MBD_DIR/$LIBDIR/ install -m 755 $IMGPATH/$LIBDIR/libgcc_s.so.1 $MBD_DIR/$LIBDIR/ _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list