diff options
-rw-r--r-- | anaconda.spec | 9 | ||||
-rw-r--r-- | command-stubs/Makefile | 2 | ||||
-rwxr-xr-x | command-stubs/dhcpclient-stub | 116 | ||||
-rw-r--r-- | isys/Makefile | 9 | ||||
-rw-r--r-- | isys/iface.c | 366 | ||||
-rw-r--r-- | isys/iface.h | 154 | ||||
-rw-r--r-- | isys/isys.c | 171 | ||||
-rw-r--r-- | isys/wireless.c | 208 | ||||
-rw-r--r-- | isys/wireless.h | 4 | ||||
-rw-r--r-- | loader2/Makefile | 19 | ||||
-rw-r--r-- | loader2/init.c | 21 | ||||
-rw-r--r-- | loader2/linuxrc.s390 | 1 | ||||
-rw-r--r-- | loader2/loader.c | 77 | ||||
-rw-r--r-- | loader2/net.c | 1391 | ||||
-rw-r--r-- | loader2/net.h | 66 | ||||
-rw-r--r-- | loader2/nfsinstall.c | 10 | ||||
-rw-r--r-- | loader2/telnetd.c | 177 | ||||
-rw-r--r-- | loader2/urlinstall.c | 6 | ||||
-rw-r--r-- | loader2/urls.c | 2 | ||||
-rwxr-xr-x | scripts/mk-images | 130 | ||||
-rwxr-xr-x | scripts/mk-images.efi | 6 | ||||
-rwxr-xr-x | scripts/upd-instroot | 70 |
22 files changed, 1577 insertions, 1438 deletions
diff --git a/anaconda.spec b/anaconda.spec index ab2659b34..83d9f690a 100644 --- a/anaconda.spec +++ b/anaconda.spec @@ -17,7 +17,6 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %define dmver 1.02.17-6 %define gettextver 0.11 %define intltoolver 0.31.2-3 -%define libdhcpver 1.99.8-1 %define libnlver 1.0 %define libselinuxver 1.6 %define mkinitrdver 5.1.2-1 @@ -33,6 +32,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %define rhpxlver 0.25 %define desktopfileutilsver 0.8 %define e2fsver 1.41.0 +%define nmver 0.7.0 +%define dbusver 1.2.3 BuildRequires: audit-libs-devel BuildRequires: booty @@ -47,7 +48,6 @@ BuildRequires: isomd5sum-devel BuildRequires: libX11-devel BuildRequires: libXt-devel BuildRequires: libXxf86misc-devel -BuildRequires: libdhcp-devel >= %{libdhcpver} BuildRequires: libnl-devel >= %{libnlver} BuildRequires: libselinux-devel >= %{libselinuxver} BuildRequires: libsepol-devel @@ -65,6 +65,8 @@ BuildRequires: slang-devel >= %{slangver} BuildRequires: xmlto BuildRequires: yum >= %{yumver} BuildRequires: zlib-devel +BuildRequires: NetworkManager-devel >= %{nmver} +BuildRequires: dbus-devel >= %{dbusver} %ifarch %livearches BuildRequires: desktop-file-utils %endif @@ -128,6 +130,9 @@ Requires: openssh Requires: busybox-anaconda Requires: isomd5sum Requires: yum-utils >= 1.1.11-3 +Requires: NetworkManager >= %{nmver} +Requires: dhclient +Requires: dhcpv6-client Obsoletes: anaconda-images <= 10 Obsoletes: anaconda-runtime < %{version}-%{release} Provides: anaconda-runtime = %{version}-%{release} diff --git a/command-stubs/Makefile b/command-stubs/Makefile index e9db03916..1a0b5dea5 100644 --- a/command-stubs/Makefile +++ b/command-stubs/Makefile @@ -20,7 +20,7 @@ include ../Makefile.inc STUBS = raidstart-stub raidstop-stub list-harddrives-stub \ - loadkeys-stub losetup-stub dhcpclient-stub mknod-stub syslogd-stub + loadkeys-stub losetup-stub mknod-stub syslogd-stub all: @echo "Nothing to do" diff --git a/command-stubs/dhcpclient-stub b/command-stubs/dhcpclient-stub deleted file mode 100755 index b5ffdc78d..000000000 --- a/command-stubs/dhcpclient-stub +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/python -# -# dhcpclient-stub -# -# 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/>. -# - -import os -import sys -import getopt - -# for testing -if (os.path.exists('isys')): - sys.path.append('isys') - -sys.path.append('/usr/lib/anaconda') - -import isys -from sys import argv - -import network -from network import NetworkDevice - -def showusage(): - print "Usage: dhcpclient [-4] [-6] [-a] [-i device] [-c class]" - -def showhelp(): - showusage() - print "Options:" - print " -4 Configure IPv4 stack via DHCP" - print " -6 Configure IPv6 stack (DHCPv6 unless -a given)" - print " -a Use IPv6 auto neighbor discovery" - print " -i device Device to configure (e.g., eth0)" - print " -c class Optional DHCP class name" - print "Defaults:" - print " dhcpclient -4 -6 -a -i eth0" - -if __name__ == "__main__": - dev = NetworkDevice('eth0') - dev.set(('bootproto', 'dhcp')) - - auto = False - stacks = 0 - - help = False - unknown = False - - try: - opts, args = getopt.getopt(sys.argv[1:], '46ai:c:', - ['ipv4', 'ipv6', 'auto', 'interface', - 'class', 'help']) - except getopt.GetoptError: - help = True - - for o, a in opts: - if o in ('-4', '--ipv4'): - stacks += 4 - elif o in ('-6', '--ipv6'): - stacks += 6 - elif o in ('-a', '--auto'): - auto = True - elif o in ('-i', '--interface'): - dev.set(('device', a)) - elif o in ('-c', '--class'): - dev.set(('dhcpclass', a)) - elif o in ('--help'): - help = True - else: - unknown = True - - if help: - showhelp() - sys.exit(0) - - if unknown: - showusage() - sys.exit(1) - - if auto: - dev.set(('ipv6_autoconf', 'yes')) - else: - dev.set(('ipv6_autoconf', 'no')) - - if stacks == 10: - dev.set(('useipv4', True)) - dev.set(('useipv6', True)) - elif stacks == 6: - dev.set(('useipv4', False)) - dev.set(('useipv6', True)) - elif stacks == 4: - dev.set(('useipv4', True)) - dev.set(('useipv6', False)) - - try: - ns = isys.dhcpNetDevice(dev) - if ns: - f = open('/etc/resolv.conf', 'w') - f.write("nameserver %s\n" % ns) - f.close() - except: - print "Error configuring device %s." % (dev.get('device'),) - - sys.exit(0) diff --git a/isys/Makefile b/isys/Makefile index e4d1de435..e9418573a 100644 --- a/isys/Makefile +++ b/isys/Makefile @@ -38,10 +38,6 @@ SUBDIRS = LOADLIBES += $(shell pkg-config --libs libnl-1) CFLAGS += $(shell pkg-config --cflags libnl-1) -# libdhcp -LOADLIBES += $(shell pkg-config --libs libdhcp) -CFLAGS += $(shell pkg-config --cflags libdhcp) - ifeq ($(ARCH),sparc) PYMODULES += _silo.so SOURCES += silo.c @@ -79,7 +75,6 @@ clean: rm -f *.o *.so *.lo *.a *.pyc $(TARGET) $(SOBJECTS) rm -f $(OBJECTS) rm -f .depend - rm -f nl for d in $(SUBDIRS); do make -C $$d clean; done install: all @@ -89,10 +84,6 @@ install: all subdirs: for d in $(SUBDIRS); do make -C $$d; done -nltest: str.o nl.c nl.h - $(CC) -c $(CFLAGS) -DTESTING nl.c -o nl.o - $(CC) -DTESTING nl.o -o nl $(LOADLIBES) str.o - depend: $(CPP) -M $(CFLAGS) $(SOURCES) > .depend diff --git a/isys/iface.c b/isys/iface.c index 6f274bc76..93cef022f 100644 --- a/isys/iface.c +++ b/isys/iface.c @@ -1,7 +1,7 @@ /* - * iface.c - Network interface control functions + * iface.c - Network interface configuration API * - * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. * * 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 @@ -21,34 +21,66 @@ #include <stdio.h> #include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/utsname.h> +#include <arpa/inet.h> +#include <dirent.h> +#include <fcntl.h> +#include <netdb.h> +#include <signal.h> #include <netinet/in.h> #include <netlink/netlink.h> #include <netlink/socket.h> +#include <netlink/route/rtnl.h> +#include <netlink/route/route.h> #include <netlink/route/addr.h> #include <netlink/route/link.h> #include "iface.h" #include "str.h" +/* Internal-only function prototypes. */ +static struct nl_handle *_iface_get_handle(void); +static struct nl_cache *_iface_get_link_cache(struct nl_handle **); +static int _iface_name_to_index(char *); +static int _iface_have_valid_addr(void *addr, int family, int length); +static int _iface_redirect_io(char *device, int fd, int mode); + /* - * Return an NETLINK_ROUTE cache. + * Return a libnl handle for NETLINK_ROUTE. */ -struct nl_cache *iface_get_link_cache(struct nl_handle **handle) { - struct nl_cache *cache = NULL; +static struct nl_handle *_iface_get_handle(void) { + struct nl_handle *handle = NULL; - if ((*handle = nl_handle_alloc()) == NULL) { - perror("nl_handle_alloc() failure in iface_get_link_cache()"); + if ((handle = nl_handle_alloc()) == NULL) { return NULL; } - if (nl_connect(*handle, NETLINK_ROUTE)) { - perror("nl_connect() failure in iface_get_link_cache()"); - nl_handle_destroy(*handle); + if (nl_connect(handle, NETLINK_ROUTE)) { + nl_handle_destroy(handle); + return NULL; + } + + return handle; +} + +/* + * Return an NETLINK_ROUTE cache. + */ +static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) { + struct nl_cache *cache = NULL; + + if ((*handle = _iface_get_handle()) == NULL) { return NULL; } if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { - perror("rtnl_link_alloc_cache() failure in iface_get_link_cache()"); nl_close(*handle); nl_handle_destroy(*handle); return NULL; @@ -58,6 +90,79 @@ struct nl_cache *iface_get_link_cache(struct nl_handle **handle) { } /* + * Convert an interface name to index number. + */ +static int _iface_name_to_index(char *ifname) { + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + + if (ifname == NULL) { + return -1; + } + + if ((cache = _iface_get_link_cache(&handle)) == NULL) { + return -1; + } + + return rtnl_link_name2i(cache, ifname); +} + +/* + * Determine if a struct in_addr or struct in6_addr contains a valid address. + */ +static int _iface_have_valid_addr(void *addr, int family, int length) { + char buf[length+1]; + + if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) { + return 0; + } + + memset(buf, '\0', sizeof(buf)); + + if (inet_ntop(family, addr, buf, length) == NULL) { + return 0; + } else { + /* check for unknown addresses */ + if (family == AF_INET) { + if (!strncmp(buf, "0.0.0.0", 7)) { + return 0; + } + } else if (family == AF_INET6) { + if (!strncmp(buf, "::", 2)) { + return 0; + } + } + } + + return 1; +} + +/* + * Redirect I/O to another device (e.g., stdout to /dev/tty5) + */ +int _iface_redirect_io(char *device, int fd, int mode) { + int io = -1; + + if ((io = open(device, mode)) == -1) { + return 1; + } + + if (close(fd) == -1) { + return 2; + } + + if (dup2(io, fd) == -1) { + return 3; + } + + if (close(io) == -1) { + return 4; + } + + return 0; +} + +/* * Given an interface name (e.g., eth0), return the IP address in human * readable format (i.e., the output from inet_ntop()). Return NULL for * no match. NOTE: This function will check for IPv6 and IPv4 @@ -74,26 +179,16 @@ char *iface_ip2str(char *ifname) { struct rtnl_addr *raddr = NULL; struct nl_addr *addr = NULL; - if (ifname == NULL) { - perror("Missing ifname in iface_ip2str()"); - return NULL; - } - - if ((cache = iface_get_link_cache(&handle)) == NULL) { - perror("iface_get_link_cache() failure in iface_ip2str()"); - return NULL; + if ((ifindex = _iface_name_to_index(ifname)) == -1) { + goto ip2str_error; } - ifindex = rtnl_link_name2i(cache, ifname); - if ((cache = rtnl_addr_alloc_cache(handle)) == NULL) { - perror("rtnl_addr_alloc_cache() failure in iface_ip2str()"); goto ip2str_error; } /* find the IPv4 and IPv6 addresses for this interface */ if ((obj = nl_cache_get_first(cache)) == NULL) { - perror("nl_cache_get_first() failure in iface_ip2str()"); goto ip2str_error; } @@ -128,8 +223,7 @@ char *iface_ip2str(char *ifname) { buflen += 1; - if ((buf = malloc(buflen)) == NULL) { - perror("malloc() failure on buf in iface_ip2str()"); + if ((buf = calloc(sizeof(char *), buflen)) == NULL) { nl_addr_destroy(addr); goto ip2str_error; } @@ -141,7 +235,6 @@ char *iface_ip2str(char *ifname) { if ((pos = index(buf, '/')) != NULL) { *pos = '\0'; if ((buf = realloc(buf, strlen(buf) + 1)) == NULL) { - perror("realloc() failure on buf in iface_ip2str()"); nl_addr_destroy(addr); goto ip2str_error; } @@ -180,7 +273,7 @@ ip2str_error: } } -/** +/* * Given an interface name (e.g., eth0), return the MAC address in human * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. */ @@ -193,27 +286,22 @@ char *iface_mac2str(char *ifname) { struct nl_addr *addr = NULL; if (ifname == NULL) { - perror("Missing ifname in iface_mac2str()"); return NULL; } - if ((cache = iface_get_link_cache(&handle)) == NULL) { - perror("iface_get_link_cache() failure in iface_mac2str()"); + if ((cache = _iface_get_link_cache(&handle)) == NULL) { return NULL; } if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { - perror("rtnl_link_get_by_name() failure in iface_mac2str()"); goto mac2str_error2; } if ((addr = rtnl_link_get_addr(link)) == NULL) { - perror("rtnl_link_get_addr() failure in iface_mac2str()"); goto mac2str_error3; } - if ((buf = malloc(buflen)) == NULL) { - perror("malloc() failure on buf in iface_mac2str()"); + if ((buf = calloc(sizeof(char *), buflen)) == NULL) { goto mac2str_error4; } @@ -233,6 +321,209 @@ mac2str_error2: } /* + * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on + * failure. + */ +struct in_addr *iface_prefix2netmask(int prefix) { + int mask = 0; + char *buf = NULL; + struct in_addr *ret; + + if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) { + return NULL; + } + + mask = htonl(~((1 << (32 - prefix)) - 1)); + + if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf, + INET_ADDRSTRLEN) == NULL) { + return NULL; + } + + if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) { + return NULL; + } + + memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr)); + return ret; +} + +/* + * Convert an IPv4 netmask to an IPv4 CIDR prefix. Return -1 on failure. + */ +int iface_netmask2prefix(struct in_addr *netmask) { + int ret = -1; + struct in_addr mask; + + if (netmask == NULL) { + return -1; + } + + memcpy(&mask, netmask, sizeof(struct in_addr)); + + while (mask.s_addr != 0) { + mask.s_addr = mask.s_addr >> 1; + ret++; + } + + return ret; +} + +/* + * Look up the hostname and domain for our assigned IP address. Tries IPv4 + * first, then IPv6. Returns 0 on success, non-negative on failure. + */ +int iface_dns_lookup(iface_t *iface) { + char *ch = NULL; + struct sockaddr_in sa; + struct sockaddr_in6 sa6; + + if ((iface->hostname != NULL) && (iface->domain != NULL)) { + return 0; + } + + /* make sure our hostname buffer is large enough */ + if ((iface->hostname = calloc('\0', NI_MAXHOST+1)) == NULL) { + return 1; + } + + /* try an IPv4 lookup first */ + if (iface_have_in_addr(&iface->ipaddr)) { + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = iface->ipaddr.s_addr; + + if (getnameinfo((struct sockaddr *) &sa, sizeof(sa), iface->hostname, + NI_MAXHOST, NULL, 0, NI_NAMEREQD)) { + free(iface->hostname); + iface->hostname = NULL; + } + } + + /* try IPv6 lookup if IPv4 failed */ + if ((iface->hostname == NULL) && iface_have_in6_addr(&iface->ip6addr)) { + memset(&sa6, 0, sizeof(sa6)); + sa6.sin6_family = AF_INET6; + memcpy(&sa6.sin6_addr, &iface->ip6addr, sizeof(iface->ip6addr)); + + if (getnameinfo((struct sockaddr *) &sa6, sizeof(sa6), iface->hostname, + NI_MAXHOST, NULL, 0, NI_NAMEREQD)) { + free(iface->hostname); + iface->hostname = NULL; + } + } + + /* fill in the domain */ + if ((iface->domain == NULL) && (iface->hostname != NULL)) { + for (ch = iface->hostname; *ch && (*ch != '.'); ch++); + + if (*ch == '.') { + iface->domain = strdup(ch + 1); + } + } + + return 0; +} + +/* + * Initialize a new iface_t structure to default values. + */ +void iface_init_iface_t(iface_t *iface) { + int i; + + memset(&iface->device, '\0', sizeof(iface->device)); + memset(&iface->ipaddr, 0, sizeof(iface->ipaddr)); + memset(&iface->netmask, 0, sizeof(iface->netmask)); + memset(&iface->broadcast, 0, sizeof(iface->broadcast)); + memset(&iface->ip6addr, 0, sizeof(iface->ip6addr)); + memset(&iface->gateway, 0, sizeof(iface->gateway)); + memset(&iface->gateway6, 0, sizeof(iface->gateway6)); + + for (i = 0; i < MAXNS; i++) { + iface->dns[i] = NULL; + } + + iface->macaddr = NULL; + iface->ip6prefix = 0; + iface->nextserver = NULL; + iface->bootfile = NULL; + iface->numdns = 0; + iface->hostname = NULL; + iface->domain = NULL; + iface->search = NULL; + iface->dhcptimeout = 0; + iface->vendorclass = NULL; + iface->ssid = NULL; + iface->wepkey = NULL; + iface->mtu = 0; + iface->subchannels = NULL; + iface->portname = NULL; + iface->peerid = NULL; + iface->nettype = NULL; + iface->ctcprot = NULL; + iface->flags = 0; + iface->ipv4method = IPV4_UNUSED_METHOD; + iface->ipv6method = IPV6_UNUSED_METHOD; + + return; +} + +/* + * Given a pointer to a struct in_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in_addr(struct in_addr *addr) { + return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN); +} + +/* + * Given a pointer to a struct in6_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in6_addr(struct in6_addr *addr6) { + return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN); +} + +/* + * Start NetworkManager -- requires that you have already written out the + * control files in /etc/sysconfig for the interface. + */ +int iface_start_NetworkManager(iface_t *iface) { + int status; + pid_t pid; + + /* Start NetworkManager */ + pid = fork(); + if (pid == 0) { + if (setpgrp() == -1) { + exit(1); + } + + if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) || + _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) || + _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, O_WRONLY)) { + exit(2); + } + + if (execl(NETWORKMANAGER, NETWORKMANAGER, + "--pid-file=/var/run/NetworkManager/NetworkManager.pid", + NULL) == -1) { + exit(3); + } else { + exit(0); + } + } else if (pid == -1) { + return 1; + } else { + if (waitpid(pid, &status, 0) == -1) { + return 2; + } + } + + return 0; +} + +/* * Set the MTU on the specified device. */ int iface_set_interface_mtu(char *ifname, int mtu) { @@ -243,22 +534,18 @@ int iface_set_interface_mtu(char *ifname, int mtu) { struct rtnl_link *request = NULL; if (ifname == NULL) { - perror("Missing ifname in iface_set_interface_mtu()"); return -1; } if (mtu <= 0) { - perror("MTU cannot be <= 0 in iface_set_interface_mtu()"); return -2; } - if ((cache = iface_get_link_cache(&handle)) == NULL) { - perror("iface_get_link_cache() failure in iface_set_interface_mtu()"); + if ((cache = _iface_get_link_cache(&handle)) == NULL) { return -3; } if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { - perror("rtnl_link_get_by_name() failure in iface_set_interface_mtu()"); ret = -4; goto ifacemtu_error1; } @@ -267,7 +554,6 @@ int iface_set_interface_mtu(char *ifname, int mtu) { rtnl_link_set_mtu(request, mtu); if (rtnl_link_change(handle, link, request, 0)) { - perror("rtnl_link_change() failure in iface_set_interface_mtu()"); ret = -5; goto ifacemtu_error2; } diff --git a/isys/iface.h b/isys/iface.h index 4b0e50f2d..03cffee4e 100644 --- a/isys/iface.h +++ b/isys/iface.h @@ -1,7 +1,7 @@ /* - * iface.h + * iface.h - Network interface configuration API * - * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. * * 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 @@ -19,11 +19,155 @@ * Author(s): David Cantrell <dcantrell@redhat.com> */ +#ifndef ISYSIFACE_H +#define ISYSIFACE_H + +#include <resolv.h> +#include <net/if.h> #include <netlink/cache.h> #include <netlink/socket.h> +/* Enumerated types used in iface.c as well as loader's network code */ +enum { IPUNUSED, IPV4, IPV6 }; + +enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD }; +enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD, + IPV6_MANUAL_METHOD }; + +#define IPV4_FIRST_METHOD IPV4_DHCP_METHOD +#define IPV4_LAST_METHOD IPV4_MANUAL_METHOD + +#define IPV6_FIRST_METHOD IPV6_AUTO_METHOD +#define IPV6_LAST_METHOD IPV6_MANUAL_METHOD + +/* Flags for the iface_t */ +#define IFACE_FLAGS_NO_WRITE_RESOLV_CONF (((uint64_t) 1) << 0) +/* FIXME: do we need these? */ +#define IFACE_FLAGS_IS_PRESET (((uint64_t) 1) << 1) +#define IFACE_FLAGS_IS_DYNAMIC (((uint64_t) 1) << 2) + +#define IFACE_NO_WRITE_RESOLV_CONF(a) ((a) & IFACE_FLAGS_NO_WRITE_RESOLV_CONF) +#define IFACE_IS_PRESET(a) ((a) & IFACE_FLAGS_IS_PRESET) +#define IFACE_IS_DYNAMIC(a) ((a) & IFACE_FLAGS_IS_DYNAMIC) + +/* Macros for starting NetworkManager */ +#define NETWORKMANAGER "/usr/sbin/NetworkManager" +#define OUTPUT_TERMINAL "/dev/tty5" + +/* Per-interface configuration information */ +typedef struct _iface_t { + /* device name (e.g., eth0) */ + char device[IF_NAMESIZE]; + + /* MAC address as xx:xx:xx:xx:xx:xx */ + char *macaddr; + + /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */ + struct in_addr ipaddr; + struct in_addr netmask; + struct in_addr broadcast; + + /* IPv6 (store addresses in in6_addr format, prefix is just an int) */ + struct in6_addr ip6addr; + int ip6prefix; + + /* Gateway settings */ + struct in_addr gateway; + struct in6_addr gateway6; + + /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */ + char *nextserver; + char *bootfile; + + /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */ + char *dns[MAXNS]; + int numdns; + char *hostname; + char *domain; + char *search; + + /* Misc DHCP settings */ + int dhcptimeout; + char *vendorclass; + + /* Wireless settings */ + char *ssid; + char *wepkey; + + /* s390 specifics */ + int mtu; + char *subchannels; + char *portname; + char *peerid; + char *nettype; + char *ctcprot; + + /* flags */ + uint64_t flags; + int ipv4method; + int ipv6method; +} iface_t; + /* Function prototypes */ -struct nl_cache *iface_get_link_cache(struct nl_handle **handle); -char *iface_mac2str(char *ifname); -char *iface_ip2str(char *ifname); + +/* + * Given an interface name (e.g., eth0), return the IP address in human + * readable format (i.e., the output from inet_ntop()). Return NULL for + * no match. NOTE: This function will check for IPv6 and IPv4 + * addresses. In the case where the interface has both, the IPv4 address + * is returned. The only way you will get an IPv6 address from this function + * is if that's the only address configured for the interface. + */ +char *iface_ip2str(char *); + +/* + * Given an interface name (e.g., eth0), return the MAC address in human + * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. + */ +char *iface_mac2str(char *); + +/* + * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on + * failure. + */ +struct in_addr *iface_prefix2netmask(int); + +/* + * Convert an IPv4 netmask to an IPv4 CIDR prefix. Return -1 on failure. + */ +int iface_netmask2prefix(struct in_addr *); + +/* + * Look up the hostname and domain for our assigned IP address. Tries IPv4 + * first, then IPv6. Returns 0 on success, non-negative on failure. + */ +int iface_dns_lookup(iface_t *); + +/* + * Initialize a new iface_t structure to default values. + */ +void iface_init_iface_t(iface_t *); + +/* + * Given a pointer to a struct in_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in_addr(struct in_addr *addr); + +/* + * Given a pointer to a struct in6_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in6_addr(struct in6_addr *addr6); + +/* + * Start NetworkManager + */ +int iface_start_NetworkManager(iface_t *iface); + +/* + * Set Maximum Transfer Unit (MTU) on specified interface + */ int iface_set_interface_mtu(char *ifname, int mtu); + +#endif /* ISYSIFACE_H */ diff --git a/isys/isys.c b/isys/isys.c index 298049711..32b7ef162 100644 --- a/isys/isys.c +++ b/isys/isys.c @@ -53,6 +53,8 @@ #include <scsi/scsi_ioctl.h> #include <sys/vt.h> #include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> #include <linux/fb.h> #include <libintl.h> #ifdef USESELINUX @@ -65,9 +67,6 @@ #include <signal.h> #include <execinfo.h> -#include <libdhcp/ip_addr.h> -#include <libdhcp/pump.h> - #include <blkid/blkid.h> #include <X11/Xlib.h> @@ -83,6 +82,7 @@ #include "wireless.h" #include "eddsupport.h" #include "auditd.h" +#include "imount.h" #ifndef CDROMEJECT #define CDROMEJECT 0x5309 @@ -523,162 +523,83 @@ void init_isys(void) { static PyObject * doConfigNetDevice(PyObject * s, PyObject * args) { int i = 0; - char *dev, *ipv4, *netmask, *ipv6, *prefix, *gateway; - struct pumpNetIntf cfg; - struct in_addr addr, nm, nw; - struct in6_addr addr6; + char *dev, *ipv4, *netmask, *ipv6, *prefix, *gateway, *gateway6, *ep; + iface_t iface; + struct in_addr tmpaddr; if (!PyArg_ParseTuple(args, "ssssss", &dev, &ipv4, &netmask, - &ipv6, &prefix, &gateway)) + &ipv6, &prefix, &gateway, &gateway6)) return NULL; - memset(&cfg, '\0', sizeof(struct pumpNetIntf)); - strncpy(cfg.device, dev, sizeof(cfg.device) - 1); + memset(&iface, '\0', sizeof(iface_t)); + strncpy(iface.device, dev, sizeof(iface.device) - 1); /* IPv4 */ - if (inet_pton(AF_INET, ipv4, &addr) >= 1) { - cfg.ipv4 = ip_addr_in(&addr); - - if (inet_pton(AF_INET, netmask, &nm) >= 1) { - cfg.netmask = ip_addr_in(&nm); - - /* we have IP and netmask, calculate network and broadcast */ - cfg.network = ip_addr_v4(ntohl((addr.s_addr) & nm.s_addr)); - nw = ip_in_addr(&cfg.network); - cfg.broadcast = ip_addr_v4(ntohl(nw.s_addr | ~nm.s_addr)); + if (inet_pton(AF_INET, ipv4, &iface.ipaddr) >= 1) { + if (inet_pton(AF_INET, netmask, &iface.netmask) >= 1) { + /* we have IP and netmask, calculate broadcast */ + memset(&tmpaddr, 0, sizeof(tmpaddr)); + tmpaddr.s_addr = iface.ipaddr.s_addr & iface.netmask.s_addr; + iface.broadcast.s_addr = tmpaddr.s_addr | ~iface.netmask.s_addr; } } /* IPv6 */ - if (inet_pton(AF_INET6, ipv6, &addr6) >= 1) { - cfg.ipv6 = ip_addr_in6(&addr6); - + if (inet_pton(AF_INET6, ipv6, &iface.ip6addr) >= 1) { if (strlen(prefix)) { - errno = 0; - i = strtol(prefix, NULL, 10); - - if ((errno == ERANGE && (i == LONG_MIN || i == LONG_MAX)) || - (errno != 0 && i == 0)) { - return NULL; - } - + i = strtol(prefix, &ep, 10); if (i > 0 && i <= 128) { - cfg.ipv6_prefixlen = i; + iface.ip6prefix = i; } } } - /* Global */ + /* Gateways */ if (strlen(gateway)) { - if (inet_pton(AF_INET, gateway, &addr) >= 1) { - cfg.gateway = ip_addr_in(&addr); - } else if (inet_pton(AF_INET6, gateway, &addr6) >= 1) { - cfg.gateway = ip_addr_in6(&addr6); + if (inet_pton(AF_INET, gateway, &iface.gateway) <= 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; } } - if (pumpSetupInterface(&cfg)) { + if (strlen(gateway6)) { + if (inet_pton(AF_INET6, gateway6, &iface.gateway6) <= 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + } + + /* Bring up the interface */ +/* + if (iface_config(&iface)) { PyErr_SetFromErrno(PyExc_SystemError); return NULL; } +*/ Py_INCREF(Py_None); return Py_None; } -void pumplogger(void *arg, int priority, char *fmt, va_list va) { - libdhcp_syslogger(0, priority, fmt, va); -} - static PyObject * doDhcpNetDevice(PyObject * s, PyObject * args) { - char *device = NULL, *r = NULL; - char *ipv4method = NULL, *ipv6method = NULL, *dhcpclass = NULL; - int useipv4, useipv6; - char buf[47]; - time_t timeout = 45; - struct pumpNetIntf cfg; - struct utsname kv; - DHCP_Preference pref = 0; - ip_addr_t *tip; - PyObject * rc; - - if (!PyArg_ParseTuple(args, "sisis|s", &device, &useipv4, &ipv4method, &useipv6, &ipv6method, &dhcpclass)) - return NULL; - - /* if we lack a user-provided dhcpclass, construct the default */ - if ((dhcpclass == NULL) || (strlen(dhcpclass) == 0)) { - if (uname(&kv) == -1) { - dhcpclass = "anaconda"; - } else { - if (asprintf(&dhcpclass, "anaconda-%s %s %s", - kv.sysname, kv.release, kv.machine) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } - } - - memset(&cfg, '\0', sizeof(cfg)); - strcpy(cfg.device, device); - - /* disable DHCPv4 is user selected manual IPv4 or didn't select IPv4 */ - if (useipv4 && strlen(ipv4method) > 0) { - if (!strncmp(ipv4method, "manual", 6)) { - /* IPv4 disabled entirely -or- manual IPv4 config selected */ - pref |= DHCPv4_DISABLE; - } - } else if (!useipv4 && strlen(ipv4method) == 0) { - pref |= DHCPv4_DISABLE; - } - - /* set appropriate IPv6 configuration method */ - if (strlen(ipv6method) > 0) { - if ((!useipv6 && !strncmp(ipv6method, "auto", 4)) || - (useipv6 && !strncmp(ipv6method, "manual", 6))) { - pref |= DHCPv6_DISABLE | DHCPv6_DISABLE_ADDRESSES; - } - } else if (strlen(ipv6method) == 0 && !useipv6) { - pref |= DHCPv6_DISABLE | DHCPv6_DISABLE_ADDRESSES; - } - - pref |= DHCPv6_DISABLE_RESOLVER | DHCPv4_DISABLE_HOSTNAME_SET; - - if (!(pref & DHCPv4_DISABLE) || !(pref & DHCPv6_DISABLE)) { - r = pumpDhcpClassRun(&cfg, NULL, dhcpclass, pref, 0, timeout, - pumplogger, LOG_ERR); - if (r) { - Py_INCREF(Py_None); - return Py_None; - } else { - if (pumpSetupInterface(&cfg)) { - Py_INCREF(Py_None); - return Py_None; - } - } - } - - if (cfg.numDns) { - tip = &(cfg.dnsServers[0]); - inet_ntop(tip->sa_family, IP_ADDR(tip), buf, IP_STRLEN(tip)); - rc = PyString_FromString(buf); - } else { - rc = PyString_FromString(""); - } - - return rc; + /* function returns a nameserver address to the caller */ + /* FIXME: needs to use NetworkManager --dcantrell */ + return PyString_FromString(""); } static PyObject * doPrefixToNetmask (PyObject * s, PyObject * args) { - int prefix = 0; - int mask = 0; - char dst[INET_ADDRSTRLEN]; + int prefix = 0; + struct in_addr *mask = NULL; + char dst[INET_ADDRSTRLEN+1]; - if (!PyArg_ParseTuple(args, "i", &prefix)) return NULL; + if (!PyArg_ParseTuple(args, "i", &prefix)) + return NULL; + + if ((mask = iface_prefix2netmask(prefix)) == NULL) + return NULL; - mask = htonl(~((1 << (32 - prefix)) - 1)); - inet_ntop(AF_INET, (struct in_addr *) &mask, dst, INET_ADDRSTRLEN); + if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL) + return NULL; return Py_BuildValue("s", dst); } diff --git a/isys/wireless.c b/isys/wireless.c index aa13b1198..6ede034b2 100644 --- a/isys/wireless.c +++ b/isys/wireless.c @@ -69,211 +69,3 @@ int is_wireless_interface(char * ifname) { return 1; } - -/* set the essid for ifname to essid. if essid is NULL, do automatically */ -int set_essid(char * ifname, char * essid) { - int sock; - struct iwreq wreq; - - memset(&wreq, 0, sizeof (wreq)); - - if (strlen(essid) > IW_ESSID_MAX_SIZE) { - fprintf(stderr, "essid too long\n"); - return -1; - } - - sock = get_socket(); - wreq = get_wreq(ifname); - - if (essid) { - wreq.u.essid.flags = 1; - wreq.u.essid.pointer = (caddr_t) essid; - wreq.u.essid.length = strlen(essid) + 1; - } else { - wreq.u.essid.flags = 0; - wreq.u.essid.pointer = (caddr_t) NULL; - wreq.u.essid.length = 0; - } - - int rc = ioctl(sock, SIOCSIWESSID, &wreq); - close(sock); - - if (rc < 0) { - fprintf(stderr, "failed to set essid: %s\n", strerror(errno)); - return -1; - } - - return 0; -} - -char * get_essid(char * ifname) { - int sock; - struct iwreq wreq; - - memset(&wreq, 0, sizeof (wreq)); - - sock = get_socket(); - wreq = get_wreq(ifname); - - wreq.u.essid.pointer = (caddr_t) malloc(IW_ESSID_MAX_SIZE + 1); - wreq.u.essid.length = IW_ESSID_MAX_SIZE + 1; - wreq.u.essid.flags = 0; - int rc = ioctl(sock, SIOCGIWESSID, &wreq); - close(sock); - - if (rc < 0) { - fprintf(stderr, "failed to get essid for %s: %s\n", ifname, - strerror(errno)); - return NULL; - } - - return wreq.u.essid.pointer; -} - -/* based off iw_in_key from wireless-tools/iwlib.c */ -static int parse_wep_key(char * in, unsigned char * key) { - int len = 0; - - if (!strncmp(in, "s:", 2)) { - /* the key is a string */ - len = strlen(in + 2); - memmove(key, in + 2, len); - } else { - char *buff, *hex, *out, *p; - - /* hexadecimal digits, straight from iwlib.c */ - buff = malloc(IW_ENCODING_TOKEN_MAX + strlen(in) + 1); - if(buff == NULL) { - fprintf(stderr, "Malloc failed (string too long ?)\n"); - return(-1); - } - /* Preserve original buffers (both in & out) */ - hex = buff + IW_ENCODING_TOKEN_MAX; - strcpy(hex, in); - out = buff; - /* Parse */ - p = strtok(hex, "-:;.,"); - while((p != (char *) NULL) && (len < IW_ENCODING_TOKEN_MAX)) { - int temph, templ, count, l; - - /* Get each char separatly (and not by two) so that we don't - * get confused by 'enc' (=> '0E'+'0C') and similar */ - count = sscanf(p, "%1X%1X", &temph, &templ); - if(count < 1) - return(-1); /* Error -> non-hex char */ - /* Fixup odd strings such as '123' is '01'+'23' and not '12'+'03'*/ - l = strlen(p); - if(l % 2) - count = 1; - /* Put back two chars as one byte */ - if(count == 2) - templ |= temph << 4; - else - templ = temph; - out[len++] = (unsigned char) (templ & 0xFF); - /* Check where to get next char from */ - if(l > count) /* Token not finished yet */ - p += count; - else - p = strtok((char *) NULL, "-:;.,"); - } - memcpy(key, out, len); - free(buff); - } - - return len; -} - -int set_wep_key(char * ifname, char * key) { - int sock; - struct iwreq wreq; - unsigned char thekey[IW_ENCODING_TOKEN_MAX]; - - if (strlen(key) > IW_ENCODING_TOKEN_MAX) { - fprintf(stderr, "wep key too long\n"); - return -1; - } - - sock = get_socket(); - wreq = get_wreq(ifname); - - if (key) { - int len = parse_wep_key(key, thekey); - if (len > 0) { - wreq.u.data.flags = IW_ENCODE_ENABLED; - wreq.u.data.length = len; - wreq.u.data.pointer = (caddr_t) thekey; - } - } else { - wreq.u.data.flags = IW_ENCODE_DISABLED; - wreq.u.data.pointer = (caddr_t) NULL; - wreq.u.data.length = 0; - } - - int rc = ioctl(sock, SIOCSIWENCODE, &wreq); - close(sock); - - if (rc < 0) { - fprintf(stderr, "failed to set wep key: %s\n", strerror(errno)); - return -1; - } - - return 0; -} - -enum { MODE_AUTO, MODE_ADHOC, MODE_MANAGED, MODE_MASTER, MODE_REPEATER, - MODE_SECONDARY, MODE_MONITOR }; - -int set_managed(char * ifname) { - int sock = get_socket(); - struct iwreq wreq = get_wreq(ifname); - - wreq.u.mode = MODE_MANAGED; - int rc = ioctl(sock, SIOCSIWMODE, &wreq); - close(sock); - - if (rc < 0) { - fprintf(stderr, "failed to set managed mode: %s\n", strerror(errno)); - return -1; - } - - return 0; -} - -#ifdef STANDALONE -int main(int argc, char **argv) { - if (argc < 4) { - fprintf(stderr, "Usage: %s [interface] [essid] [key]\n", argv[0]); - exit(1); - } - - if (!is_wireless_interface(argv[1])) { - fprintf(stderr, "%s isn't a wireless interface!\n", argv[1]); - exit(2); - } - - /* if (set_essid(argv[1], NULL) < 0) { - fprintf(stderr, "Unable to set essid to %s\n", argv[2]); - exit(3); - } - exit(0);*/ - - if (set_essid(argv[1], argv[2]) < 0) { - fprintf(stderr, "Unable to set essid to %s\n", argv[2]); - exit(3); - } - - /* if (set_wep_key(argv[1], NULL) < 0) { - fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]); - exit(4); - } - exit(0);*/ - - if (set_wep_key(argv[1], argv[3]) < 0) { - fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]); - exit(4); - } - - return 0; -} -#endif diff --git a/isys/wireless.h b/isys/wireless.h index 82cb4d4ce..d7ba8be03 100644 --- a/isys/wireless.h +++ b/isys/wireless.h @@ -21,9 +21,5 @@ #define WIRELESS_H int is_wireless_interface(char * ifname); -int set_essid(char * ifname, char * essid); -char * get_essid(char * ifname); -int set_wep_key(char * ifname, char * key); -int set_managed(char * ifname); #endif diff --git a/loader2/Makefile b/loader2/Makefile index 57c022552..ff56e501a 100644 --- a/loader2/Makefile +++ b/loader2/Makefile @@ -28,13 +28,20 @@ endif LIBS = -lnewt -lslang -lz -lpopt ../isys/libisys.a -lcheckisomd5 -# dhcp library flags -LIBS += $(shell pkg-config --libs libdhcp) -CFLAGS += $(shell pkg-config --cflags libdhcp) - # devmapper -LIBS += $(shell pkg-config --libs devmapper) -CFLAGS += $(shell pkg-config --cflags devmapper) +LIBS += $(shell pkg-config --libs devmapper) +CFLAGS += $(shell pkg-config --cflags devmapper) + +# libnl +LIBS += $(shell pkg-config --libs libnl-1) +CFLAGS += $(shell pkg-config --cflags libnl-1) + +# NetworkManager +CFLAGS += $(shell pkg-config --cflags NetworkManager) + +# D-Bus +LIBS += $(shell pkg-config --libs dbus-1) +CFLAGS += $(shell pkg-config --cflags dbus-1) ifeq (1, $(USESELINUX)) LIBS += -lselinux -lsepol diff --git a/loader2/init.c b/loader2/init.c index 52e9beecd..403789383 100644 --- a/loader2/init.c +++ b/loader2/init.c @@ -696,6 +696,27 @@ int main(int argc, char **argv) { sleep(2); } + /* D-Bus */ + if (!testing) { + if (fork() == 0) { + execl("/sbin/dbus-uuidgen", "/sbin/dbus-uuidgen", "--ensure", NULL); + exit(1); + } + + if (fork() == 0) { + execl("/sbin/dbus-daemon", "/sbin/dbus-daemon", "--system", NULL); + exit(1); + } + } + + /* HAL daemon */ + if (!testing) { + if (fork() == 0) { + execl("/sbin/hald", "/sbin/hald", NULL); + exit(1); + } + } + /* Go into normal init mode - keep going, and then do a orderly shutdown when: diff --git a/loader2/linuxrc.s390 b/loader2/linuxrc.s390 index 8e7d6ae7e..7facd3b19 100644 --- a/loader2/linuxrc.s390 +++ b/loader2/linuxrc.s390 @@ -414,7 +414,6 @@ if [ "$do_net_install" = "yes" ]; then else # ctc0, iucv0 if [ -z "$NETMASK" ]; then # If the user did not supply netmask, we add the right one. - # Netmask MUST be present, or pumpSetupInterface() blows routes. NETMASK="255.255.255.255" fi while [ -z "$GATEWAY" ]; do diff --git a/loader2/loader.c b/loader2/loader.c index becacb2c4..6ecc21873 100644 --- a/loader2/loader.c +++ b/loader2/loader.c @@ -42,9 +42,11 @@ #include <syslog.h> #include <unistd.h> #include <stdint.h> +#include <arpa/inet.h> #include <sys/ioctl.h> #include <sys/types.h> +#include <sys/socket.h> #include <sys/stat.h> #include <sys/wait.h> @@ -132,23 +134,33 @@ void doSuspend(void) { } void doShell(void) { - /* this lets us debug the loader just by having a second initramfs - * containing /sbin/busybox */ - int child, status; + pid_t child; + int status; newtSuspend(); - if (!(child = fork())) { - execl("/sbin/busybox", "msh", NULL); - _exit(1); + child = fork(); + + if (child == 0) { + if (execl("/sbin/bash", "/sbin/bash", "-i", NULL) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + _exit(1); + } + } else if (child == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + newtResume(); + } else { + if (waitpid(child, &status, 0) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + } + + newtResume(); } - waitpid(child, &status, 0); - newtResume(); } void doGdbserver(struct loaderData_s *loaderData) { int child, fd; char *pid; - struct networkDeviceConfig netCfg; + iface_t iface; /* If gdbserver is found, go ahead and run it on the loader process now * before anything bad happens. @@ -156,7 +168,7 @@ void doGdbserver(struct loaderData_s *loaderData) { if (loaderData->gdbServer && !access("/usr/bin/gdbserver", X_OK)) { pid_t loaderPid = getpid(); - if (kickstartNetworkUp(loaderData, &netCfg)) { + if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "can't run gdbserver due to no network"); return; } @@ -1130,7 +1142,7 @@ static char *doLoaderMain(struct loaderData_s *loaderData, STEP_IP, STEP_STAGE2, STEP_DONE } step; char *url = NULL, *ret = NULL, *devName = NULL, *kbdtype = NULL; - static struct networkDeviceConfig netDev; + static iface_t iface; int i, rc, dir = 1; int needsNetwork = 0, class = -1; int skipMethodDialog = 0, skipLangKbd = 0; @@ -1194,6 +1206,12 @@ static char *doLoaderMain(struct loaderData_s *loaderData, } } + /* Disable all network interfaces in NetworkManager by default */ + if ((i = writeDisabledNetInfo()) != 0) { + logMessage(ERROR, "writeDisabledNetInfo failure: %d", i); + } + + i = 0; step = STEP_LANG; while (step != STEP_DONE) { @@ -1376,8 +1394,7 @@ static char *doLoaderMain(struct loaderData_s *loaderData, logMessage(INFO, "need to set up networking"); initLoopback(); - memset(&netDev, 0, sizeof(netDev)); - netDev.isDynamic = 1; + memset(&iface, 0, sizeof(iface)); /* fall through to interface selection */ } @@ -1406,7 +1423,7 @@ static char *doLoaderMain(struct loaderData_s *loaderData, } devName = loaderData->netDev; - strcpy(netDev.dev.device, devName); + strcpy(iface.device, devName); /* continue to ip config */ step = STEP_IP; @@ -1420,7 +1437,7 @@ static char *doLoaderMain(struct loaderData_s *loaderData, break; } - if ((ret = malloc(48)) == NULL) { + if ((ret = malloc(INET6_ADDRSTRLEN+1)) == NULL) { logMessage(ERROR, "malloc failure for ret in STEP_IP"); exit(EXIT_FAILURE); } @@ -1435,25 +1452,24 @@ static char *doLoaderMain(struct loaderData_s *loaderData, /* populate netDev based on any kickstart data */ if (loaderData->ipinfo_set) { - netDev.preset = 1; + iface.flags |= IFACE_FLAGS_IS_PRESET; } - setupNetworkDeviceConfig(&netDev, loaderData); + setupNetworkDeviceConfig(&iface, loaderData); - rc = readNetConfig(devName, &netDev, loaderData->netCls, loaderData->method); + rc = readNetConfig(devName, &iface, loaderData->netCls, loaderData->method); if (FL_NOIPV4(flags)) { loaderData->ipinfo_set = 0; } else { if (loaderData->ipv4 == NULL) { - if (strcmp((char *) &(netDev.dev.ip), "")) { - ret = (char *) inet_ntop(AF_INET, - IP_ADDR(&(netDev.dev.ip)), ret, - IP_STRLEN(&(netDev.dev.ip))); + if (iface_have_in_addr(&iface.ipaddr)) { + ret = (char *) inet_ntop(AF_INET, &iface.ipaddr, + ret, INET_ADDRSTRLEN); } else { ret = NULL; - netDev.isDynamic = 1; + iface.flags |= IFACE_FLAGS_IS_DYNAMIC; } - if (netDev.isDynamic || ret == NULL) { + if (IFACE_IS_DYNAMIC(iface.flags) || ret == NULL) { loaderData->ipv4 = strdup("dhcp"); } else { loaderData->ipv4 = strdup(ret); @@ -1467,16 +1483,15 @@ static char *doLoaderMain(struct loaderData_s *loaderData, loaderData->ipv6info_set = 0; } else { if (loaderData->ipv6 == NULL) { - if (strcmp((char *) &(netDev.dev.ip), "")) { - ret = (char *) inet_ntop(AF_INET6, - IP_ADDR(&(netDev.dev.ip)), ret, - IP_STRLEN(&(netDev.dev.ip))); + if (iface_have_in6_addr(&iface.ip6addr)) { + ret = (char *) inet_ntop(AF_INET6, &iface.ip6addr, + ret, INET6_ADDRSTRLEN); } else { ret = NULL; - netDev.isDynamic = 1; + iface.flags |= IFACE_FLAGS_IS_DYNAMIC; } - if (netDev.isDynamic || ret == NULL) { + if (IFACE_IS_DYNAMIC(iface.flags) || ret == NULL) { loaderData->ipv6 = strdup("dhcpv6"); } else { loaderData->ipv6 = strdup(ret); @@ -1505,7 +1520,7 @@ static char *doLoaderMain(struct loaderData_s *loaderData, break; } - writeNetInfo("/tmp/netinfo", &netDev); + writeEnabledNetInfo(&iface); step = STEP_STAGE2; dir = 1; break; diff --git a/loader2/net.c b/loader2/net.c index 4cdb6c29c..1e57bf508 100644 --- a/loader2/net.c +++ b/loader2/net.c @@ -1,8 +1,8 @@ /* * net.c * - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. - * All rights reserved. + * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc. + * 2006, 2007, 2008 * * 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 @@ -35,6 +35,8 @@ #include <string.h> #include <strings.h> #include <unistd.h> +#include <dbus/dbus.h> +#include <NetworkManager.h> #include "../isys/isys.h" #include "../isys/net.h" @@ -248,14 +250,14 @@ void initLoopback(void) { strcpy(req.ifr_name, "lo"); if (ioctl(s, SIOCGIFFLAGS, &req)) { - logMessage(LOG_ERR, "ioctl SIOCGIFFLAGS failed: %m\n"); + logMessage(ERROR, "ioctl SIOCGIFFLAGS failed: %m\n"); close(s); return; } req.ifr_flags |= (IFF_UP | IFF_RUNNING); if (ioctl(s, SIOCSIFFLAGS, &req)) { - logMessage(LOG_ERR, "ioctl SIOCSIFFLAGS failed: %m\n"); + logMessage(ERROR, "ioctl SIOCSIFFLAGS failed: %m\n"); close(s); return; } @@ -265,66 +267,8 @@ void initLoopback(void) { return; } -static int getWirelessConfig(struct networkDeviceConfig *cfg, char * ifname) { - char * wepkey = ""; - char * essid = ""; - int rc = 0; - char * buf; - - if (cfg->wepkey != NULL) { - wepkey = strdup(cfg->wepkey); - } - if (cfg->essid != NULL) { - essid = strdup(cfg->essid); - } else { - essid = get_essid(ifname); - } - - if (asprintf(&buf, _("%s is a wireless network adapter. Please " - "provide the ESSID and encryption key needed " - "to access your wireless network. If no key " - "is needed, leave this field blank and the " - "install will continue."), ifname) == -1) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - do { - struct newtWinEntry entry[] = { { N_("ESSID"), &essid, 0 }, - { N_("Encryption Key"), &wepkey, 0 }, - { NULL, NULL, 0 } }; - - rc = newtWinEntries(_("Wireless Settings"), buf, - 40, 5, 10, 30, entry, _("OK"), _("Back"), NULL); - if (rc == 2) { - free(buf); - return LOADER_BACK; - } - - /* set stuff up */ - } while (rc == 2); - free(buf); - - if (cfg->wepkey != NULL) - free(cfg->wepkey); - - if (wepkey && (strlen(wepkey) > 0)) - cfg->wepkey = strdup(wepkey); - else - cfg->wepkey = NULL; - - if (cfg->essid != NULL) - free(cfg->essid); - - if (essid && (strlen(essid) > 0)) - cfg->essid = strdup(essid); - else - cfg->essid = NULL; - - return LOADER_OK; -} - -static int getDnsServers(struct networkDeviceConfig * cfg) { +/* XXX: make this get DNS servers via NM +static int getDnsServers(iface_t * iface) { int rc; struct in_addr addr; struct in6_addr addr6; @@ -344,28 +288,28 @@ static int getDnsServers(struct networkDeviceConfig * cfg) { rc = 0; if (!ns || !*ns) { - cfg->dev.numDns = 0; + iface->numdns = 0; break; } else { - if (inet_pton(AF_INET, ns, &addr) >= 1) - cfg->dev.dnsServers[0] = ip_addr_in(&addr); - else if (inet_pton(AF_INET6, ns, &addr6) >= 1) - cfg->dev.dnsServers[0] = ip_addr_in6(&addr6); - else + if ((inet_pton(AF_INET, ns, &addr) >= 1) || + (inet_pton(AF_INET6, ns, &addr6) >= 1)) { + iface->dns[0] = strdup(ns); + } else { rc = 2; + } } if (rc) { newtWinMessage(_("Invalid IP Information"), _("Retry"), _("You entered an invalid IP address.")); } else { - cfg->dev.set |= PUMP_NETINFO_HAS_DNS; - cfg->dev.numDns = 1; + iface->numdns = 1; } } while (rc == 2); return LOADER_OK; } +*/ void printLoaderDataIPINFO(struct loaderData_s *loaderData) { logMessage(DEBUGLVL, "loaderData->ipinfo_set = |%d|", loaderData->ipinfo_set); @@ -385,8 +329,9 @@ void printLoaderDataIPINFO(struct loaderData_s *loaderData) { } /* given loader data from kickstart, populate network configuration struct */ -void setupNetworkDeviceConfig(struct networkDeviceConfig * cfg, +void setupNetworkDeviceConfig(iface_t * iface, struct loaderData_s * loaderData) { + int err; struct in_addr addr; struct in6_addr addr6; char * c; @@ -401,253 +346,217 @@ void setupNetworkDeviceConfig(struct networkDeviceConfig * cfg, } if (loaderData->netCls_set) { - cfg->vendor_class = loaderData->netCls; + iface->vendorclass = loaderData->netCls; } else { - cfg->vendor_class = NULL; + iface->vendorclass = NULL; } if (loaderData->ipinfo_set) { - if (is_wireless_interface(loaderData->netDev)) { - if (loaderData->essid) { - logMessage(INFO, "setting specified essid of %s", - loaderData->essid); - cfg->essid = strdup(loaderData->essid); - } - if (loaderData->wepkey) { - logMessage(INFO, "setting specified wepkey"); - cfg->wepkey = strdup(loaderData->wepkey); - } - /* go ahead and set up the wireless interface in case - * we're using dhcp */ - setupWireless(cfg); - } - /* this is how we specify dhcp */ if (!strncmp(loaderData->ipv4, "dhcp", 4)) { - char *ret = NULL; + int ret = 0; /* JKFIXME: this soooo doesn't belong here. and it needs to * be broken out into a function too */ logMessage(INFO, "sending dhcp request through device %s", loaderData->netDev); - if (!FL_CMDLINE(flags)) { - startNewt(); - winStatus(55, 3, NULL, - _("Sending request for IP information for %s..."), - loaderData->netDev, 0); - } else { - printf("Sending request for IP information for %s...\n", - loaderData->netDev); - } - if (!FL_TESTING(flags)) { waitForLink(loaderData->netDev); - cfg->noDns = loaderData->noDns; - cfg->dhcpTimeout = loaderData->dhcpTimeout; - ret = doDhcp(cfg); - } - if (!FL_CMDLINE(flags)) + if (loaderData->noDns) { + iface->flags |= IFACE_FLAGS_NO_WRITE_RESOLV_CONF; + } + + iface->dhcptimeout = loaderData->dhcpTimeout; + + err = writeEnabledNetInfo(iface); + if (err) { + logMessage(ERROR, + "failed to write /etc/sysconfig data for %s (%d)", + iface->device, err); + return; + } + + ret = get_connection(iface); newtPopWindow(); + } - if (ret != NULL) { - logMessage(DEBUGLVL, "dhcp: %s", ret); + if (ret) { + logMessage(ERROR, "failed to start NetworkManager (%d)", ret); return; } - cfg->isDynamic = 1; - cfg->preset = 1; + iface->flags |= IFACE_FLAGS_IS_DYNAMIC | IFACE_FLAGS_IS_PRESET; } else if (loaderData->ipv4) { if (inet_pton(AF_INET, loaderData->ipv4, &addr) >= 1) { - cfg->dev.ip = ip_addr_in(&addr); - cfg->dev.ipv4 = ip_addr_in(&addr); - cfg->dev.set |= PUMP_INTFINFO_HAS_IP|PUMP_INTFINFO_HAS_IPV4_IP; - cfg->isDynamic = 0; - cfg->preset = 1; + iface->ipaddr = addr; + iface->flags &= ~IFACE_FLAGS_IS_DYNAMIC; + iface->flags |= IFACE_FLAGS_IS_PRESET; } } else if (loaderData->ipv6) { if (inet_pton(AF_INET6, loaderData->ipv6, &addr6) >= 1) { - cfg->dev.ip = ip_addr_in6(&addr6); - cfg->dev.ipv6 = ip_addr_in6(&addr6); - cfg->dev.set |= PUMP_INTFINFO_HAS_IP|PUMP_INTFINFO_HAS_IPV6_IP; - cfg->isDynamic = 0; - cfg->preset = 1; + memcpy(&iface->ip6addr, &addr6, sizeof(struct in6_addr)); + iface->flags &= ~IFACE_FLAGS_IS_DYNAMIC; + iface->flags |= IFACE_FLAGS_IS_PRESET; } } else { /* invalid ip information, disable the setting of ip info */ loaderData->ipinfo_set = 0; - cfg->isDynamic = 0; + iface->flags &= ~IFACE_FLAGS_IS_DYNAMIC; loaderData->ipv4 = NULL; loaderData->ipv6 = NULL; } } - if (loaderData->netmask && (inet_pton(AF_INET, loaderData->netmask, &addr) >= 1)) { - cfg->dev.netmask = ip_addr_in(&addr); - cfg->dev.set |= PUMP_INTFINFO_HAS_NETMASK; + if (loaderData->netmask) { + if (inet_pton(AF_INET, loaderData->netmask, &iface->netmask) <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } } - if (loaderData->gateway && (inet_pton(AF_INET, loaderData->gateway, &addr) >= 1)) { - cfg->dev.gateway = ip_addr_in(&addr); - cfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY; + if (loaderData->gateway) { + if (inet_pton(AF_INET, loaderData->gateway, &iface->gateway) <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } } - if (loaderData->gateway && (inet_pton(AF_INET6, loaderData->gateway, &addr6) >= 1)) { - cfg->dev.gateway = ip_addr_in6(&addr6); - cfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY; - } + /* FIXME: add support for loaderData->gateway6 */ if (loaderData->dns) { char * buf; - char ret[48]; + char ret[INET6_ADDRSTRLEN+1]; buf = strdup(loaderData->dns); /* Scan the dns parameter for multiple comma-separated IP addresses */ - c = strtok(buf, ","); - while ((cfg->dev.numDns < MAXNS) && (c != NULL)) { + c = strtok(buf, ","); + while ((iface->numdns < MAXNS) && (c != NULL)) { if (inet_pton(AF_INET, c, &addr) >= 1) { - cfg->dev.dnsServers[cfg->dev.numDns] = ip_addr_in(&addr); - cfg->dev.numDns++; - inet_ntop(AF_INET, &addr, ret, INET_ADDRSTRLEN); - logMessage(DEBUGLVL, "adding dns4 %s", ret); - c = strtok(NULL, ","); + iface->dns[iface->numdns] = strdup(c); + iface->numdns++; + + if (inet_ntop(AF_INET, &addr, ret, INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); + } else { + logMessage(DEBUGLVL, "adding dns4 %s", ret); + c = strtok(NULL, ","); + } } else if (inet_pton(AF_INET6, c, &addr6) >= 1) { - cfg->dev.dnsServers[cfg->dev.numDns] = ip_addr_in6(&addr6); - cfg->dev.numDns++; - inet_ntop(AF_INET6, &addr6, ret, INET6_ADDRSTRLEN); - logMessage(DEBUGLVL, "adding dns6 %s", ret); - c = strtok(NULL, ","); + iface->dns[iface->numdns] = strdup(c); + iface->numdns++; + + if (inet_ntop(AF_INET6, &addr6, ret, INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); + } else { + logMessage(DEBUGLVL, "adding dns6 %s", ret); + c = strtok(NULL, ","); + } } } + logMessage(INFO, "dnsservers is %s", loaderData->dns); - if (cfg->dev.numDns) - cfg->dev.set |= PUMP_NETINFO_HAS_DNS; } if (loaderData->hostname) { logMessage(INFO, "setting specified hostname of %s", loaderData->hostname); - cfg->dev.hostname = strdup(loaderData->hostname); - cfg->dev.set |= PUMP_NETINFO_HAS_HOSTNAME; + iface->hostname = strdup(loaderData->hostname); } if (loaderData->mtu) { - cfg->mtu = loaderData->mtu; - cfg->dev.mtu = loaderData->mtu; - cfg->dev.set |= PUMP_INTFINFO_HAS_MTU; + iface->mtu = loaderData->mtu; } if (loaderData->peerid) { - cfg->peerid = strdup(loaderData->peerid); + iface->peerid = strdup(loaderData->peerid); } if (loaderData->subchannels) { - cfg->subchannels = strdup(loaderData->subchannels); + iface->subchannels = strdup(loaderData->subchannels); } if (loaderData->ctcprot) { - cfg->ctcprot = strdup(loaderData->ctcprot); + iface->ctcprot = strdup(loaderData->ctcprot); } if (loaderData->portname) { - cfg->portname = strdup(loaderData->portname); + iface->portname = strdup(loaderData->portname); } if (loaderData->nettype) { - cfg->nettype = strdup(loaderData->nettype); + iface->nettype = strdup(loaderData->nettype); } if (loaderData->ethtool) { parseEthtoolSettings(loaderData); } - cfg->noDns = loaderData->noDns; - cfg->dhcpTimeout = loaderData->dhcpTimeout; + if (loaderData->noDns) { + iface->flags |= IFACE_FLAGS_NO_WRITE_RESOLV_CONF; + } + + iface->dhcptimeout = loaderData->dhcpTimeout; } -int readNetConfig(char * device, struct networkDeviceConfig * cfg, +int readNetConfig(char * device, iface_t * iface, char * dhcpclass, int methodNum) { - struct networkDeviceConfig newCfg; + int err; int ret; int i = 0; struct netconfopts opts; - struct in_addr addr, nm, nw; - struct in6_addr addr6; + struct in_addr addr; struct intfconfig_s ipcomps; - memset(&ipcomps, '\0', sizeof(ipcomps)); + /* ipcomps contains the user interface components */ ipcomps.ipv4 = NULL; ipcomps.ipv6 = NULL; ipcomps.cidr4 = NULL; ipcomps.cidr6 = NULL; ipcomps.gw = NULL; + ipcomps.gw6 = NULL; ipcomps.ns = NULL; /* init opts */ opts.ipv4Choice = 0; opts.ipv6Choice = 0; - /* init newCfg */ - memset(&newCfg, '\0', sizeof(newCfg)); - strcpy(newCfg.dev.device, device); - newCfg.essid = NULL; - newCfg.wepkey = NULL; - newCfg.isDynamic = cfg->isDynamic; - newCfg.noDns = cfg->noDns; - newCfg.dhcpTimeout = cfg->dhcpTimeout; - newCfg.preset = cfg->preset; - if (dhcpclass) { - newCfg.vendor_class = strdup(dhcpclass); - } else { - newCfg.vendor_class = NULL; - } - /* JKFIXME: we really need a way to override this and be able to change * our network config */ - if (!FL_TESTING(flags) && cfg->preset) { + if (!FL_TESTING(flags) && IFACE_IS_PRESET(iface->flags)) { logMessage(INFO, "doing kickstart... setting it up"); - if (configureNetwork(cfg)) { - newtWinMessage(_("Network Error"), _("Retry"), - _("There was an error configuring your network " - "interface.")); + + err = writeEnabledNetInfo(iface); + if (err) { + logMessage(ERROR, "failed to write /etc/sysconfig data for %s (%d)", + iface->device, err); return LOADER_BACK; } - findHostAndDomain(cfg); - - if (!cfg->noDns) - writeResolvConf(cfg); + i = get_connection(iface); + newtPopWindow(); - return LOADER_NOOP; - } - - /* handle wireless device configuration */ - if (is_wireless_interface(device)) { - logMessage(INFO, "%s is a wireless adapter", device); - if (getWirelessConfig(cfg, device) == LOADER_BACK) { + if (i > 0) { + newtWinMessage(_("Network Error"), _("Retry"), + _("There was an error configuring your network " + "interface.")); return LOADER_BACK; } - if (cfg->essid != NULL) - newCfg.essid = strdup(cfg->essid); - - if (cfg->wepkey != NULL) - newCfg.wepkey = strdup(cfg->wepkey); - } else { - logMessage(INFO, "%s is not a wireless adapter", device); + return LOADER_NOOP; } /* dhcp/manual network configuration loop */ i = 1; while (i == 1) { - ret = configureTCPIP(device, cfg, &newCfg, &opts, methodNum); + ret = configureTCPIP(device, iface, &opts, methodNum); if (ret == LOADER_NOOP) { /* dhcp selected, proceed */ i = 0; } else if (ret == LOADER_OK) { /* do manual configuration */ - ret = manualNetConfig(device, cfg, &newCfg, &ipcomps, &opts); + ret = manualNetConfig(device, iface, &ipcomps, &opts); if (ret == LOADER_BACK) { continue; @@ -659,87 +568,61 @@ int readNetConfig(char * device, struct networkDeviceConfig * cfg, } } - cfg->ipv4method = newCfg.ipv4method; - cfg->ipv6method = newCfg.ipv6method; - - /* preserve extra dns servers for the sake of being nice */ - if (cfg->dev.numDns > newCfg.dev.numDns) { - for (i = newCfg.dev.numDns; i < cfg->dev.numDns; i++) { - memcpy(&newCfg.dev.dnsServers[i], &cfg->dev.dnsServers[i], - sizeof (newCfg.dev.dnsServers[i])); - } - newCfg.dev.numDns = cfg->dev.numDns; - } - - cfg->isDynamic = newCfg.isDynamic; - memcpy(&cfg->dev, &newCfg.dev, sizeof(newCfg.dev)); - - if (!(cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY)) { - if (ipcomps.gw != NULL) { - if (inet_pton(AF_INET, ipcomps.gw, &addr) >= 1) { - cfg->dev.gateway = ip_addr_in(&addr); - cfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY; - } else if (inet_pton(AF_INET6, ipcomps.gw, &addr6) >= 1) { - cfg->dev.gateway = ip_addr_in6(&addr6); - cfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY; - } +/* + if (ipcomps.gw && *ipcomps.gw) { + if (inet_pton(AF_INET, ipcomps.gw, &iface->gateway) <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else if (inet_pton(AF_INET6, ipcomps.gw, &iface->gateway6) <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); } } +*/ /* calculate any missing IPv4 pieces */ if (opts.ipv4Choice == '*') { - addr = ip_in_addr(&cfg->dev.ipv4); - nm = ip_in_addr(&cfg->dev.netmask); - - if (!(cfg->dev.set & PUMP_INTFINFO_HAS_NETWORK)) { - cfg->dev.network = ip_addr_v4(ntohl((addr.s_addr) & nm.s_addr)); - cfg->dev.set |= PUMP_INTFINFO_HAS_NETWORK; - } + memset(&addr, 0, sizeof(addr)); + addr.s_addr = (iface->ipaddr.s_addr) & (iface->netmask.s_addr); - if (!(cfg->dev.set & PUMP_INTFINFO_HAS_BROADCAST)) { - nw = ip_in_addr(&cfg->dev.network); - cfg->dev.broadcast = ip_addr_v4(ntohl(nw.s_addr | ~nm.s_addr)); - cfg->dev.set |= PUMP_INTFINFO_HAS_BROADCAST; + if (iface->broadcast.s_addr == 0) { + iface->broadcast.s_addr = addr.s_addr | ~(iface->netmask.s_addr); } } - /* make sure we don't have a dhcp_nic handle for static */ - if ((cfg->isDynamic == 0) && (cfg->dev.dhcp_nic != NULL)) { - dhcp_nic_free(cfg->dev.dhcp_nic); - cfg->dev.dhcp_nic = NULL; - } - /* dump some network debugging info */ - debugNetworkInfo(cfg); + debugNetworkInfo(iface); /* bring up the interface */ if (!FL_TESTING(flags)) { - if (configureNetwork(cfg)) { + err = writeEnabledNetInfo(iface); + if (err) { + logMessage(ERROR, "failed to write /etc/sysconfig data for %s (%d)", + iface->device, err); + return LOADER_BACK; + } + + i = get_connection(iface); + newtPopWindow(); + + if (i > 0) { newtWinMessage(_("Network Error"), _("Retry"), _("There was an error configuring your network " "interface.")); return LOADER_BACK; } - - findHostAndDomain(cfg); - writeResolvConf(cfg); } return LOADER_OK; } -int configureTCPIP(char * device, struct networkDeviceConfig * cfg, - struct networkDeviceConfig * newCfg, +int configureTCPIP(char * device, iface_t * iface, struct netconfopts * opts, int methodNum) { - int i = 0, z = 0, skipForm = 0; - char *dret = NULL; + int i = 0, z = 0, skipForm = 0, dret = 0, err; newtComponent f, okay, back, answer; newtComponent ipv4Checkbox, ipv6Checkbox, v4Method[2], v6Method[3]; newtGrid grid, checkgrid, buttons; - newCfg->ipv4method = -1; - newCfg->ipv6method = -1; - /* UI WINDOW 1: ask for ipv4 choice, ipv6 choice, and conf methods */ /* IPv4 checkbox */ @@ -824,9 +707,7 @@ int configureTCPIP(char * device, struct networkDeviceConfig * cfg, (FL_NOIPV4(flags) && FL_NOIPV6(flags)) || (FL_IS_KICKSTART(flags))) { skipForm = 1; - } else if (FL_CMDLINE(flags)) { - fprintf(stderr, "Required network configuration not given for cmdline mode, aborting\n"); - exit(EXIT_FAILURE); + newtPopWindow(); } /* run the form */ @@ -859,62 +740,70 @@ int configureTCPIP(char * device, struct networkDeviceConfig * cfg, /* what TCP/IP stacks do we use? what conf methods? */ if (opts->ipv4Choice == '*') { flags &= ~LOADER_FLAGS_NOIPV4; - for (z = 0; z < 2; z++) - if (newtRadioGetCurrent(v4Method[0]) == v4Method[z]) - newCfg->ipv4method = z; + for (z = IPV4_FIRST_METHOD; z <= IPV4_LAST_METHOD; z++) + if (newtRadioGetCurrent(v4Method[0]) == v4Method[z-1]) + iface->ipv4method = z; } else { flags |= LOADER_FLAGS_NOIPV4; } if (opts->ipv6Choice == '*') { flags &= ~LOADER_FLAGS_NOIPV6; - for (z = 0; z < 3; z++) - if (newtRadioGetCurrent(v6Method[0]) == v6Method[z]) - newCfg->ipv6method = z; + for (z = IPV6_FIRST_METHOD; z <= IPV6_LAST_METHOD; z++) + if (newtRadioGetCurrent(v6Method[0]) == v6Method[z-1]) + iface->ipv6method = z; } else { flags |= LOADER_FLAGS_NOIPV6; } /* do interface configuration (call DHCP here, or return for manual) */ - if ((!FL_NOIPV4(flags) && newCfg->ipv4method == IPV4_DHCP_METHOD) || - (!FL_NOIPV6(flags) && (newCfg->ipv6method == IPV6_AUTO_METHOD || - newCfg->ipv6method == IPV6_DHCP_METHOD))) { + if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) || + (!FL_NOIPV6(flags) && (iface->ipv6method == IPV6_AUTO_METHOD || + iface->ipv6method == IPV6_DHCP_METHOD))) { /* do DHCP if selected */ if (!FL_TESTING(flags)) { - if (FL_CMDLINE(flags)) { - printf(_("Sending request for IP information for %s...\n"), device); - } else { - winStatus(55, 3, NULL, - _("Sending request for IP information for %s..."), - device, 0); + waitForLink(device); + + err = writeEnabledNetInfo(iface); + if (err) { + logMessage(ERROR, + "failed to write /etc/sysconfig data for %s (%d)", + iface->device, err); + return LOADER_BACK; } - waitForLink(device); - dret = doDhcp(newCfg); + dret = get_connection(iface); newtPopWindow(); } - if (dret == NULL) { - newCfg->isDynamic = 1; - if (!(newCfg->dev.set & PUMP_NETINFO_HAS_DNS)) { + if (!dret) { + iface->flags |= IFACE_FLAGS_IS_DYNAMIC; + +/* XXX: if we don't have working DNS lookups, ask for a nameserver, + * but be friendly to NM. we should ask NM if it knows about a + * nameserver and then ask the user for one if NM isn't in the know. + */ +/* + if (iface->numdns == 0) { logMessage(WARNING, "dhcp worked, but did not return a DNS server"); - +*/ /* * prompt for a nameserver IP address when: * - DHCP for IPv4, DHCP/AUTO for IPv6 and both enabled * - IPv4 disabled and DHCP/AUTO for IPv6 * - IPv6 disabled and DHCP for IPv4 */ - if ((newCfg->ipv4method == IPV4_DHCP_METHOD - && (newCfg->ipv6method == IPV6_AUTO_METHOD || - newCfg->ipv6method == IPV6_DHCP_METHOD)) - || (newCfg->ipv4method == IPV4_DHCP_METHOD +/* + if ((iface->ipv4method == IPV4_DHCP_METHOD + && (iface->ipv6method == IPV6_AUTO_METHOD || + iface->ipv6method == IPV6_DHCP_METHOD)) + || (iface->ipv4method == IPV4_DHCP_METHOD && FL_NOIPV6(flags)) || (FL_NOIPV4(flags) - && (newCfg->ipv6method == IPV6_AUTO_METHOD || - newCfg->ipv6method == IPV6_DHCP_METHOD))) { - i = getDnsServers(newCfg); + && (iface->ipv6method == IPV6_AUTO_METHOD || + iface->ipv6method == IPV6_DHCP_METHOD))) { + i = getDnsServers(iface); i = i ? 0 : 1; } else { i = 1; @@ -922,8 +811,10 @@ int configureTCPIP(char * device, struct networkDeviceConfig * cfg, } else { i = 1; } +*/ + i = 1; } else { - logMessage(DEBUGLVL, "dhcp: %s", dret); + logMessage(DEBUGLVL, "get_connection() failed, returned %d", dret); i = 0; } } else { @@ -937,22 +828,21 @@ int configureTCPIP(char * device, struct networkDeviceConfig * cfg, newtFormDestroy(f); newtPopWindow(); - if ((!FL_NOIPV4(flags) && newCfg->ipv4method == IPV4_MANUAL_METHOD) || - (!FL_NOIPV6(flags) && newCfg->ipv6method == IPV6_MANUAL_METHOD)) + if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_MANUAL_METHOD) || + (!FL_NOIPV6(flags) && iface->ipv6method == IPV6_MANUAL_METHOD)) return LOADER_OK; else return LOADER_NOOP; } -int manualNetConfig(char * device, struct networkDeviceConfig * cfg, - struct networkDeviceConfig * newCfg, +int manualNetConfig(char * device, iface_t * iface, struct intfconfig_s * ipcomps, struct netconfopts * opts) { int i, rows, pos, prefix, cidr, have[2], stack[2]; char *buf = NULL; char ret[48]; - ip_addr_t *tip; struct in_addr addr; struct in6_addr addr6; + struct in_addr *tmpaddr = NULL; newtComponent f, okay, back, answer; newtGrid egrid = NULL; newtGrid qgrid = NULL; @@ -960,16 +850,21 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, newtGrid buttons, grid; newtComponent text = NULL; + memset(ret, '\0', INET6_ADDRSTRLEN+1); + /* so we don't perform this test over and over */ - stack[IPV4] = opts->ipv4Choice == '*' - && newCfg->ipv4method == IPV4_MANUAL_METHOD; - stack[IPV6] = opts->ipv6Choice == '*' - && newCfg->ipv6method == IPV6_MANUAL_METHOD; + stack[IPV4] = opts->ipv4Choice == '*' && + iface->ipv4method == IPV4_MANUAL_METHOD; + stack[IPV6] = opts->ipv6Choice == '*' && + iface->ipv6method == IPV6_MANUAL_METHOD; /* UI WINDOW 2 (optional): manual IP config for non-DHCP installs */ rows = 2; - for (i = 0; i < 2; i++) - if (stack[i]) rows++; + for (i = 0; i < 2; i++) { + if (stack[i]) { + rows++; + } + } egrid = newtCreateGrid(4, rows); pos = 0; @@ -1001,25 +896,39 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, newtComponentAddCallback(ipcomps->cidr4Entry, cidrCallback, ipcomps); /* populate fields if we have data already */ - tip = NULL; - if (cfg->dev.set & PUMP_INTFINFO_HAS_IPV4_IP) - tip = &(cfg->dev.ipv4); - else if (newCfg->dev.set & PUMP_INTFINFO_HAS_IPV4_IP) - tip = &(newCfg->dev.ipv4); - - if (tip) { - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); + if (iface_have_in_addr(&iface->ipaddr)) { + if (inet_ntop(AF_INET, &iface->ipaddr, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } else if (iface_have_in_addr(&iface->ipaddr)) { + if (inet_ntop(AF_INET, &iface->ipaddr, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } + + if (*ret) { newtEntrySet(ipcomps->ipv4Entry, ret, 1); } - tip = NULL; - if (cfg->dev.set & PUMP_INTFINFO_HAS_NETMASK) - tip = &(cfg->dev.netmask); - else if (newCfg->dev.set & PUMP_INTFINFO_HAS_NETMASK) - tip = &(newCfg->dev.netmask); + if (iface_have_in_addr(&iface->netmask)) { + if (inet_ntop(AF_INET, &iface->netmask, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } else if (iface_have_in_addr(&iface->netmask)) { + if (inet_ntop(AF_INET, &iface->netmask, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } - if (tip) { - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); + if (*ret) { newtEntrySet(ipcomps->cidr4Entry, ret, 1); } @@ -1053,30 +962,35 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, newtComponentAddCallback(ipcomps->cidr6Entry, cidrCallback, ipcomps); /* populate fields if we have data already */ - tip = NULL; - if (cfg->dev.set & PUMP_INTFINFO_HAS_IPV6_IP) - tip = &(cfg->dev.ipv6); - else if (newCfg->dev.set & PUMP_INTFINFO_HAS_IPV6_IP) - tip = &(newCfg->dev.ipv6); - - if (tip) { - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); + if (iface_have_in6_addr(&iface->ip6addr)) { + if (inet_ntop(AF_INET6, &iface->ip6addr, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } else if (iface_have_in6_addr(&iface->ip6addr)) { + if (inet_ntop(AF_INET6, &iface->ip6addr, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } + + if (*ret) { newtEntrySet(ipcomps->ipv6Entry, ret, 1); } - if (cfg->dev.set & PUMP_INTFINFO_HAS_IPV6_PREFIX) { - if (asprintf(&buf, "%d", cfg->dev.ipv6_prefixlen) == -1) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); + if (iface->ip6prefix) { + if (asprintf(&buf, "%d", iface->ip6prefix) == -1) { + buf = NULL; } - } else if (newCfg->dev.set & PUMP_INTFINFO_HAS_IPV6_PREFIX) { - if (asprintf(&buf, "%d", newCfg->dev.ipv6_prefixlen) == -1) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); + } else if (iface->ip6prefix) { + if (asprintf(&buf, "%d", iface->ip6prefix) == -1) { + buf = NULL; } } - if (buf) { + if (buf != NULL) { newtEntrySet(ipcomps->cidr6Entry, buf, 1); free(buf); } @@ -1102,26 +1016,28 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT, ipcomps->nsEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - tip = NULL; - if (cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY) - tip = &(cfg->dev.gateway); - else if (newCfg->dev.set & PUMP_NETINFO_HAS_GATEWAY) - tip = &(newCfg->dev.gateway); - - if (tip) { - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - newtEntrySet(ipcomps->gwEntry, ret, 1); + if (iface_have_in_addr(&iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + newtEntrySet(ipcomps->gwEntry, ret, 1); + } + } else if (iface_have_in6_addr(&iface->gateway6)) { + if (inet_ntop(AF_INET6, &iface->gateway6, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + newtEntrySet(ipcomps->gwEntry, ret, 1); + } } - tip = NULL; - if (cfg->dev.numDns) - tip = &(cfg->dev.dnsServers[0]); - else if (newCfg->dev.numDns) - tip = &(newCfg->dev.dnsServers[0]); - - if (tip) { - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - newtEntrySet(ipcomps->nsEntry, ret, 1); + if (iface->numdns) { + newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1); + } else if (iface->numdns) { + newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1); } newtComponentAddCallback(ipcomps->gwEntry, ipCallback, ipcomps); @@ -1171,17 +1087,16 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, /* collect IPv4 data */ if (stack[IPV4]) { if (ipcomps->ipv4) { - if (inet_pton(AF_INET, ipcomps->ipv4, &addr) >= 1) { - newCfg->dev.ipv4 = ip_addr_in(&addr); - newCfg->dev.set |= PUMP_INTFINFO_HAS_IPV4_IP; + if (inet_pton(AF_INET, ipcomps->ipv4, &iface->ipaddr) <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { have[IPV4]++; } } if (ipcomps->cidr4) { - if (inet_pton(AF_INET, ipcomps->cidr4, &addr) >= 1) { - newCfg->dev.netmask = ip_addr_in(&addr); - newCfg->dev.set |= PUMP_INTFINFO_HAS_NETMASK; + if (inet_pton(AF_INET, ipcomps->cidr4, &iface->netmask)>=1) { have[IPV4]++; } else { errno = 0; @@ -1195,11 +1110,13 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, } if (cidr >= 1 && cidr <= 32) { - if (inet_pton(AF_INET, "255.255.255.255", &addr) >= 1) { - addr.s_addr = htonl(ntohl(addr.s_addr) << (32 - cidr)); - newCfg->dev.netmask = ip_addr_in(&addr); - newCfg->dev.set |= PUMP_INTFINFO_HAS_NETMASK; + tmpaddr = iface_prefix2netmask(cidr); + if (tmpaddr != NULL) { + memcpy(&iface->netmask, tmpaddr, + sizeof(struct in_addr)); have[IPV4]++; + } else { + iface->netmask.s_addr = 0; } } } @@ -1209,9 +1126,10 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, /* collect IPv6 data */ if (stack[IPV6]) { if (ipcomps->ipv6) { - if (inet_pton(AF_INET6, ipcomps->ipv6, &addr6) >= 1) { - newCfg->dev.ipv6 = ip_addr_in6(&addr6); - newCfg->dev.set |= PUMP_INTFINFO_HAS_IPV6_IP; + if (inet_pton(AF_INET6, ipcomps->ipv6, &iface->ip6addr) <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { have[IPV6]++; } } @@ -1228,8 +1146,7 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, } if (prefix > 0 || prefix <= 128) { - newCfg->dev.ipv6_prefixlen = prefix; - newCfg->dev.set |= PUMP_INTFINFO_HAS_IPV6_PREFIX; + iface->ip6prefix = prefix; have[IPV6]++; } } @@ -1237,37 +1154,24 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, /* collect common network settings */ if (ipcomps->gw) { - if (inet_pton(AF_INET, ipcomps->gw, &addr) >= 1) { - newCfg->dev.gateway = ip_addr_in(&addr); - newCfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY; - } else if (inet_pton(AF_INET6, ipcomps->gw, &addr6) >= 1) { - newCfg->dev.gateway = ip_addr_in6(&addr6); - newCfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY; - } - } - - /* The cfg->dev.ip field needs to store the IPv4 address if - * there is one. - */ - if (ipcomps->ipv4) { - if (inet_pton(AF_INET, ipcomps->ipv4, &addr) >= 1) { - newCfg->dev.ip = ip_addr_in(&addr); - newCfg->dev.set |= PUMP_INTFINFO_HAS_IP; + if (inet_pton(AF_INET, ipcomps->gw, &iface->gateway) <= 0) { + memset(&iface->gateway, 0, sizeof(iface->gateway)); + + if (inet_pton(AF_INET6, ipcomps->gw, &iface->gateway6) <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + memset(&iface->gateway6, 0, sizeof(iface->gateway6)); + } } } /* gather nameservers */ if (ipcomps->ns) { - if (inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) { - cfg->dev.dnsServers[0] = ip_addr_in(&addr); - cfg->dev.set |= PUMP_NETINFO_HAS_DNS; - if (cfg->dev.numDns < 1) - cfg->dev.numDns = 1; - } else if (inet_pton(AF_INET6, ipcomps->ns, &addr6) >= 1) { - cfg->dev.dnsServers[0] = ip_addr_in6(&addr6); - cfg->dev.set |= PUMP_NETINFO_HAS_DNS; - if (cfg->dev.numDns < 1) - cfg->dev.numDns = 1; + if ((inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) || + (inet_pton(AF_INET6, ipcomps->ns, &addr6) >= 1)) { + iface->dns[0] = strdup(ipcomps->ns); + if (iface->numdns < 1) + iface->numdns = 1; } } @@ -1292,8 +1196,8 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, "CIDR prefix.")); } - strcpy(newCfg->dev.device, device); - newCfg->isDynamic = 0; + strcpy(iface->device, device); + iface->flags &= ~IFACE_FLAGS_IS_DYNAMIC; } free(buf); @@ -1303,398 +1207,368 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, return LOADER_OK; } -void debugNetworkInfo(struct networkDeviceConfig *cfg) { +void debugNetworkInfo(iface_t * iface) { int i; - char *buf = NULL; + char buf[INET6_ADDRSTRLEN]; - logMessage(DEBUGLVL, "device = %s", cfg->dev.device); + logMessage(DEBUGLVL, "device = %s", iface->device); - if (cfg->dev.set & PUMP_INTFINFO_HAS_IPV4_IP) { - logMessage(DEBUGLVL, "ipv4 = %s", ip_text(cfg->dev.ipv4, buf, 0)); - free(buf); - buf = NULL; + if (iface->macaddr != NULL) { + logMessage(DEBUGLVL, "MAC address = %s", iface->macaddr); } - if (cfg->dev.set & PUMP_INTFINFO_HAS_BROADCAST) { - logMessage(DEBUGLVL,"broadcast = %s",ip_text(cfg->dev.broadcast,buf,0)); - free(buf); - buf = NULL; + if (iface_have_in_addr(&iface->ipaddr)) { + if (inet_ntop(AF_INET, &iface->ipaddr, buf, INET_ADDRSTRLEN) == NULL) { + logMessage(DEBUGLVL, "IPv4 address = <unable to convert>"); + } else { + logMessage(DEBUGLVL, "IPv4 address = %s", buf); + } } - if (cfg->dev.set & PUMP_INTFINFO_HAS_NETMASK) { - logMessage(DEBUGLVL, "netmask = %s", ip_text(cfg->dev.netmask, buf, 0)); - free(buf); - buf = NULL; + if (iface_have_in_addr(&iface->netmask)) { + if (inet_ntop(AF_INET, &iface->netmask, buf, INET_ADDRSTRLEN) == NULL) { + logMessage(DEBUGLVL, "IPv4 netmask = <unable to convert>"); + } else { + logMessage(DEBUGLVL, "IPv4 netmask = %s", buf); + } } - if (cfg->dev.set & PUMP_INTFINFO_HAS_NETWORK) { - logMessage(DEBUGLVL, "network = %s", ip_text(cfg->dev.network, buf, 0)); - free(buf); - buf = NULL; + if (iface_have_in_addr(&iface->broadcast)) { + if (inet_ntop(AF_INET, &iface->broadcast, buf, + INET_ADDRSTRLEN) == NULL ) { + logMessage(DEBUGLVL, "IPv4 broadcast = <unable to convert>"); + } else { + logMessage(DEBUGLVL, "IPv4 broadcast = %s", buf); + } } - if (cfg->dev.set & PUMP_INTFINFO_HAS_IPV6_IP) { - logMessage(DEBUGLVL, "ipv6 = %s", ip_text(cfg->dev.ipv6, buf, 0)); - free(buf); - buf = NULL; + if (iface_have_in_addr(&iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, buf, INET_ADDRSTRLEN) == NULL) { + logMessage(DEBUGLVL, "Gateway = <unable to convert>"); + } else { + logMessage(DEBUGLVL, "Gateway = %s", buf); + } } - if (cfg->dev.set & PUMP_INTFINFO_HAS_IPV6_PREFIX) { - logMessage(DEBUGLVL, "ipv6_prefixlen = %d", cfg->dev.ipv6_prefixlen); - free(buf); - buf = NULL; + if (iface_have_in6_addr(&iface->ip6addr)) { + if (inet_ntop(AF_INET6, &iface->ip6addr, buf, + INET6_ADDRSTRLEN) == NULL) { + logMessage(DEBUGLVL, "IPv6 address = <unable to convert>"); + } else { + logMessage(DEBUGLVL, "IPv6 address = %s", buf); + } } - if (cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY) { - logMessage(DEBUGLVL, "gateway = %s", ip_text(cfg->dev.gateway, buf, 0)); - free(buf); - buf = NULL; + if (iface->ip6prefix) { + logMessage(DEBUGLVL, "IPv6 prefix = %d", iface->ip6prefix); } - if (cfg->dev.set & PUMP_NETINFO_HAS_DNS) { - for (i=0; i < cfg->dev.numDns; i++) { - logMessage(DEBUGLVL, "dns[%d] = %s", i, - ip_text(cfg->dev.dnsServers[i], buf, 0)); - free(buf); - buf = NULL; + if (iface_have_in6_addr(&iface->gateway6)) { + if (inet_ntop(AF_INET6, &iface->gateway6, buf, + INET6_ADDRSTRLEN) == NULL) { + logMessage(DEBUGLVL, "IPv6 Gateway = <unable to convert>"); + } else { + logMessage(DEBUGLVL, "IPv6 Gateway = %s", buf); } } -} - -int setupWireless(struct networkDeviceConfig *dev) { - /* wireless config needs to be set up before we can bring the interface - * up */ - if (!is_wireless_interface(dev->dev.device)) - return 0; - - if (dev->essid) { - logMessage(INFO, "setting essid for %s to %s", dev->dev.device, - dev->essid); - if (set_essid(dev->dev.device, dev->essid) < 0) { - logMessage(ERROR, "failed to set essid: %m"); - } - if (dev->wepkey) { - logMessage(INFO, "setting encryption key for %s", dev->dev.device); - if (set_wep_key(dev->dev.device, dev->wepkey) < 0) { - logMessage(ERROR, "failed to set wep key: %m"); - } + if (iface->numdns > 0) { + for (i = 0; i < iface->numdns; i++) { + logMessage(DEBUGLVL, "DNS[%d] = %s", i, iface->dns[i]); } } - return 0; -} - -void netlogger(void *arg, int priority, char *fmt, va_list va) { - int p; - char *buf = NULL; + if (iface->hostname) { + logMessage(DEBUGLVL, "hostname = %s", iface->hostname); + } - if (priority == LOG_ERR) - p = ERROR; - else if (priority == LOG_INFO) - p = INFO; - else if (priority == LOG_DEBUG) - p = DEBUGLVL; - else if (priority == LOG_FATAL) - p = CRITICAL; - else - p = INFO; + if (iface->domain) { + logMessage(DEBUGLVL, "domain = %s", iface->domain); + } - if (vasprintf(&buf, fmt, va) != -1) { - logMessage(p, "%s", buf); - free(buf); - } else { - logMessage(ERROR, "unable to log network message"); + if (iface->dhcptimeout) { + logMessage(DEBUGLVL, "DHCP timeout = %d", iface->dhcptimeout); } - return; -} + if (iface->vendorclass) { + logMessage(DEBUGLVL, "DHCP vendor class = %s", iface->vendorclass); + } -char *doDhcp(struct networkDeviceConfig *dev) { - struct pumpNetIntf *i; - char *r = NULL, *class = NULL; - time_t timeout; - int loglevel; - DHCP_Preference pref = 0; - struct utsname kv; - int mturet; + if (iface->ssid) { + logMessage(DEBUGLVL, "SSID = %s", iface->ssid); + } - i = &dev->dev; + if (iface->wepkey) { + logMessage(DEBUGLVL, "WEP key = %s", iface->wepkey); + } - if (dev->dhcpTimeout < 0) { - timeout = 45; - } else { - timeout = dev->dhcpTimeout; +#if defined(__s390__) || defined(__s390x__) + if (iface->mtu) { + logMessage(DEBUGLVL, "mtu = %d", iface->mtu); } - if (dev->vendor_class != NULL) { - class = dev->vendor_class; - } else { - if (uname(&kv) == -1) { - logMessage(ERROR, "failure running uname() in doDhcp()"); - class = "anaconda"; - } else { - if (asprintf(&class, "anaconda-%s %s %s", - kv.sysname, kv.release, kv.machine) == -1) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); - } + if (iface->subchannels) { + logMessage(DEBUGLVL, "subchannels = %s", iface->subchannels); + } - logMessage(DEBUGLVL, "sending %s as dhcp vendor-class", class); - } + if (iface->portname) { + logMessage(DEBUGLVL, "portname = %s", iface->portname); } - if (getLogLevel() == DEBUGLVL) { - loglevel = LOG_DEBUG; - } else { - loglevel = LOG_INFO; + if (iface->peerid) { + logMessage(DEBUGLVL, "peerid = %s", iface->peerid); } - /* set interface MTU */ - if (i->set & PUMP_INTFINFO_HAS_MTU) { - mturet = iface_set_interface_mtu((char *) i->device, i->mtu); + if (iface->nettype) { + logMessage(DEBUGLVL, "nettype = %s", iface->nettype); + } - if (mturet) { - logMessage(ERROR, "unable to set %s mtu to %d (code %d)", - (char *) i->device, i->mtu, mturet); - } + if (iface->ctcprot) { + logMessage(DEBUGLVL, "ctcprot = %s", iface->ctcprot); } +#endif - /* dhcp preferences are in /usr/include/libdhcp/dhcp_nic.h */ +/* FIXME: print rest of iface structure */ - /* calling function should catch ipv4Choice & ipv6Choice both being ' ' */ - if (FL_NOIPV4(flags) || dev->ipv4method == IPV4_MANUAL_METHOD) { - /* IPv4 disabled entirely -or- manual IPv4 config selected */ - pref |= DHCPv4_DISABLE; - } + return; +} - /* IPv6 enabled -and- auto neighbor discovery selected */ - /* IPv6 disabled entirely -or- manual IPv6 config selected */ - if ((!FL_NOIPV6(flags) && dev->ipv6method == IPV6_AUTO_METHOD) || - (FL_NOIPV6(flags) || dev->ipv6method == IPV6_MANUAL_METHOD)) { - pref |= DHCPv6_DISABLE | DHCPv6_DISABLE_ADDRESSES; - } +/* + * By default, we disable all network interfaces and then only + * bring up the ones the user wants. + */ +int writeDisabledNetInfo(void) { + int i = 0; + char *ofile = NULL; + FILE *fp = NULL; + struct device **devs = NULL; - /* disable some things for this DHCP call */ - pref |= DHCPv6_DISABLE_RESOLVER | DHCPv4_DISABLE_HOSTNAME_SET; + devs = getDevices(DEVICE_NETWORK); - /* don't try to run the client if DHCPv4 and DHCPv6 are disabled */ - if (!(pref & DHCPv4_DISABLE) || !(pref & DHCPv6_DISABLE)){ - logMessage(loglevel, "requesting dhcp timeout %ld", (long)timeout); - r = pumpDhcpClassRun(i,0L,class,pref,0,timeout,netlogger,loglevel); + if (devs == NULL) { + return 1; } - /* set hostname if we have that */ - if (dev->dev.hostname) { - if (sethostname(dev->dev.hostname, strlen(dev->dev.hostname))) { - logMessage(ERROR,"error setting hostname to %s",dev->dev.hostname); + for (i = 0; devs[i]; i++) { + if (asprintf(&ofile, "/etc/sysconfig/network-scripts/ifcfg-%s", + devs[i]->device) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + abort(); } - } - - return r; -} -int configureNetwork(struct networkDeviceConfig * dev) { - char *rc; - int mturet; - struct pumpNetIntf *i = &dev->dev; + if ((fp = fopen(ofile, "w")) == NULL) { + free(ofile); + return 2; + } - setupWireless(dev); + fprintf(fp, "DEVICE=%s\n", devs[i]->device); + fprintf(fp, "HWADDR=%s\n", iface_mac2str(devs[i]->device)); + fprintf(fp, "ONBOOT=no\n"); + fprintf(fp, "NM_CONTROLLED=no\n"); - /* set interface MTU */ - if (i->set & PUMP_INTFINFO_HAS_MTU) { - mturet = iface_set_interface_mtu((char *) i->device, i->mtu); + if (ofile) { + free(ofile); + } - if (mturet) { - logMessage(ERROR, "unable to set %s mtu to %d (code %d)", - (char *) i->device, i->mtu, mturet); + if (fclose(fp) == EOF) { + return 3; } } - rc = pumpSetupInterface(i); - if (rc != NULL) { - logMessage(INFO, "result of pumpSetupInterface is %s", rc); + return 0; +} + +/* + * Write out network interface control files: + * /etc/sysconfig/network-scripts/ifcfg-DEVICE + * /etc/sysconfig/network + */ +int writeEnabledNetInfo(iface_t *iface) { + int i = 0; + FILE *fp = NULL; + char buf[INET6_ADDRSTRLEN+1]; + char *ofile = NULL; + + memset(&buf, '\0', sizeof(buf)); + + if (asprintf(&ofile, "/etc/sysconfig/network-scripts/ifcfg-%s", + iface->device) == -1) { return 1; } - /* we need to wait for a link after setting up the interface as some - * switches decide to reconfigure themselves after that (#115825) - */ - waitForLink((char *) i->device); - return 0; -} + if ((fp = fopen(ofile, "w")) == NULL) { + free(ofile); + return 2; + } -int writeNetInfo(const char * fn, struct networkDeviceConfig * dev) { - FILE * f; - int i; - struct device ** devices; - char ret[48]; - ip_addr_t *tip; + fprintf(fp, "DEVICE=%s\n", iface->device); + fprintf(fp, "HWADDR=%s\n", iface_mac2str(iface->device)); + fprintf(fp, "ONBOOT=yes\n"); + fprintf(fp, "NM_CONTROLLED=yes\n"); - devices = getDevices(DEVICE_NETWORK); - if (!devices) - return 0; + if (!FL_NOIPV4(flags)) { + if (iface->ipv4method == IPV4_DHCP_METHOD) { + fprintf(fp, "BOOTPROTO=dhcp\n"); + } else if (iface->ipv4method == IPV4_MANUAL_METHOD) { + fprintf(fp, "BOOTPROTO=static\n"); - for (i = 0; devices[i]; i++) - if (!strcmp(devices[i]->device, dev->dev.device)) break; - - if (!(f = fopen(fn, "w"))) return -1; + if (iface_have_in_addr(&iface->ipaddr)) { + if (inet_ntop(AF_INET, &iface->ipaddr, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + return 3; + } - fprintf(f, "DEVICE=%s\n", dev->dev.device); + fprintf(fp, "IPADDR=%s\n", buf); + } - fprintf(f, "ONBOOT=yes\n"); + if (iface_have_in_addr(&iface->netmask)) { + if (inet_ntop(AF_INET, &iface->ipaddr, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + return 4; + } - if (dev->isDynamic) { - fprintf(f, "BOOTPROTO=dhcp\n"); - } else { - fprintf(f, "BOOTPROTO=static\n"); + fprintf(fp, "NETMASK=%s\n", buf); + } - tip = &(dev->dev.ipv4); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - fprintf(f, "IPADDR=%s\n", ret); + if (iface_have_in_addr(&iface->broadcast)) { + if (inet_ntop(AF_INET, &iface->ipaddr, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + return 5; + } - tip = &(dev->dev.netmask); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - fprintf(f, "NETMASK=%s\n", ret); + fprintf(fp, "BROADCAST=%s\n", buf); + } - if (dev->dev.set & PUMP_NETINFO_HAS_GATEWAY) { - tip = &(dev->dev.gateway); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - fprintf(f, "GATEWAY=%s\n", ret); - } + /* XXX: this should not be here, but ifcfg-fedora + * in NM does not currently read the global + * /etc/sysconfig/network file. + */ + if (iface_have_in_addr(&iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + return 6; + } - if (dev->dev.set & PUMP_INTFINFO_HAS_BROADCAST) { - tip = &(dev->dev.broadcast); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - fprintf(f, "BROADCAST=%s\n", ret); + fprintf(fp, "GATEWAY=%s\n", buf); + } } } if (!FL_NOIPV6(flags)) { - if (dev->ipv6method == IPV6_AUTO_METHOD) { - fprintf(f, "IPV6_AUTOCONF=yes\n"); - } else if (dev->ipv6method == IPV6_DHCP_METHOD) { - fprintf(f, "IPV6ADDR=dhcp\n"); - } else { - tip = &(dev->dev.ipv6); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - fprintf(f, "IPV6ADDR=%s/%d\n", ret, dev->dev.ipv6_prefixlen); - } - } - - if (dev->dev.set & PUMP_NETINFO_HAS_HOSTNAME) - fprintf(f, "HOSTNAME=%s\n", dev->dev.hostname); - if (dev->dev.set & PUMP_NETINFO_HAS_DOMAIN) - fprintf(f, "DOMAIN=%s\n", dev->dev.domain); - if (dev->mtu) - fprintf(f, "MTU=%d\n", dev->mtu); - if (dev->peerid) - fprintf(f, "PEERID=%s\n", dev->peerid); - if (dev->subchannels) - fprintf(f, "SUBCHANNELS=%s\n", dev->subchannels); - if (dev->portname) - fprintf(f, "PORTNAME=%s\n", dev->portname); - if (dev->nettype) - fprintf(f, "NETTYPE=%s\n", dev->nettype); - if (dev->ctcprot) - fprintf(f, "CTCPROT=%s\n", dev->ctcprot); - - if (dev->essid) - fprintf(f, "ESSID=%s\n", dev->essid); - if (dev->wepkey) - fprintf(f, "KEY=%s\n", dev->wepkey); - - fclose(f); + if (iface->ipv6method == IPV6_AUTO_METHOD || + iface->ipv6method == IPV6_DHCP_METHOD || + iface->ipv6method == IPV6_MANUAL_METHOD) { + fprintf(fp, "IPV6INIT=yes\n"); + + if (iface->ipv6method == IPV6_AUTO_METHOD) { + fprintf(fp, "IPV6_AUTOCONF=yes\n"); + } else if (iface->ipv6method == IPV6_DHCP_METHOD) { + fprintf(fp, "DHCPV6C=yes\n"); + } else if (iface->ipv6method == IPV6_MANUAL_METHOD) { + if (iface_have_in6_addr(&iface->ip6addr)) { + if (inet_ntop(AF_INET6, &iface->ip6addr, buf, + INET6_ADDRSTRLEN) == NULL) { + free(ofile); + return 7; + } - return 0; -} + if (iface->ip6prefix) { + fprintf(fp, "IPV6ADDR=%s/%d\n", buf, iface->ip6prefix); + } else { + fprintf(fp, "IPV6ADDR=%s\n", buf); + } + } + } + } + } -int writeResolvConf(struct networkDeviceConfig * net) { - char * filename = "/etc/resolv.conf"; - FILE * f; - int i; - char ret[48]; - ip_addr_t *tip; -#if defined(__s390__) || defined(__s390x__) - return 0; -#endif + if (iface->numdns > 0) { + for (i = 0; i < iface->numdns; i++) { + fprintf(fp, "DNS%d=%s\n", i+1, iface->dns[i]); + } + } - if (!(net->dev.set & PUMP_NETINFO_HAS_DOMAIN) && !net->dev.numDns) - return LOADER_ERROR; + if (iface->hostname) { + fprintf(fp, "HOSTNAME=%s\n", iface->hostname); + } - f = fopen(filename, "w"); - if (!f) { - logMessage(ERROR, "Cannot create %s: %m\n", filename); - return LOADER_ERROR; + if (iface->domain) { + fprintf(fp, "DOMAIN=%s\n", iface->domain); } - if (net->dev.set & PUMP_NETINFO_HAS_DOMAIN) - fprintf(f, "search %s\n", net->dev.domain); + if (iface->mtu) { + fprintf(fp, "MTU=%d\n", iface->mtu); + } - for (i = 0; i < net->dev.numDns; i++) { - tip = &(net->dev.dnsServers[i]); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - fprintf(f, "nameserver %s\n", ret); + if (iface->peerid) { + fprintf(fp, "PEERID=%s\n", iface->peerid); } - fclose(f); + if (iface->subchannels) { + fprintf(fp, "SUBCHANNELS=%s\n", iface->subchannels); + } - res_init(); /* reinit the resolver so DNS changes take affect */ + if (iface->portname) { + fprintf(fp, "PORTNAME=%s\n", iface->portname); + } - return 0; -} + if (iface->nettype) { + fprintf(fp, "NETTYPE=%s\n", iface->nettype); + } -int findHostAndDomain(struct networkDeviceConfig * dev) { - char * name, * chptr; - char ret[48]; - ip_addr_t *tip; - struct hostent *host; + if (iface->ctcprot) { + fprintf(fp, "CTCPROT=%s\n", iface->ctcprot); + } - if (!FL_TESTING(flags)) { - writeResolvConf(dev); + if (ofile) { + free(ofile); } - if (dev->dev.numDns == 0) { - logMessage(ERROR, "no DNS servers, can't look up hostname"); - return 1; + if (fclose(fp) == EOF) { + return 8; } - if (!(dev->dev.set & PUMP_NETINFO_HAS_HOSTNAME)) { - if (!FL_CMDLINE(flags)) - winStatus(50, 3, NULL, - _("Determining host name and domain...")); - else - printf("Determining host name and domain...\n"); + /* Global settings */ + if ((fp = fopen("/etc/sysconfig/network", "w")) == NULL) { + return 9; + } - tip = &(dev->dev.ip); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - host = gethostbyaddr(IP_ADDR(tip), IP_STRLEN(tip), tip->sa_family); + if (!FL_NOIPV4(flags)) { + fprintf(fp, "NETWORKING=yes\n"); + } - if (!FL_CMDLINE(flags)) - newtPopWindow(); + if (!FL_NOIPV6(flags)) { + fprintf(fp, "NETWORKING_IPV6=yes\n"); + } - if (!host) { - logMessage(WARNING, "reverse name lookup of %s failed", ret); - return 1; + if (iface->hostname != NULL) { + fprintf(fp, "HOSTNAME=%s\n", iface->hostname); + } + + if (iface_have_in_addr(&iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, buf, + INET_ADDRSTRLEN) == NULL) { + return 10; } - name = strdup(host->h_name); + fprintf(fp, "GATEWAY=%s\n", buf); + } - logMessage(INFO, "reverse name lookup worked (hostname is %s)", name); + if (iface_have_in6_addr(&iface->gateway6)) { + if (inet_ntop(AF_INET6, &iface->gateway6, buf, + INET6_ADDRSTRLEN) == NULL) { + return 11; + } - dev->dev.hostname = strdup(name); - dev->dev.set |= PUMP_NETINFO_HAS_HOSTNAME; - } else { - name = dev->dev.hostname; + fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf); } - if (!(dev->dev.set & PUMP_NETINFO_HAS_DOMAIN)) { - for (chptr = name; *chptr && (*chptr != '.'); chptr++) ; - if (*chptr == '.') { - if (dev->dev.domain) free(dev->dev.domain); - dev->dev.domain = strdup(chptr + 1); - dev->dev.set |= PUMP_NETINFO_HAS_DOMAIN; - } + if (fclose(fp) == EOF) { + return 12; } return 0; @@ -1704,9 +1578,10 @@ void setKickstartNetwork(struct loaderData_s * loaderData, int argc, char ** argv) { char * arg, * bootProto = NULL, * device = NULL, *ethtool = NULL, * class = NULL; char * essid = NULL, * wepkey = NULL, * onboot = NULL; - int noDns = 0, noksdev = 0, rc, mtu = 0, noipv4 = 0, noipv6 = 0, dhcpTimeout = -1; + int mtu = 1500, noipv4 = 0, noipv6 = 0, dhcpTimeout = -1, noDns = 0, noksdev = 0; + int rc; poptContext optCon; - struct networkDeviceConfig cfg; + iface_t iface; struct poptOption ksOptions[] = { { "bootproto", '\0', POPT_ARG_STRING, &bootProto, 0, NULL, NULL }, @@ -1729,7 +1604,9 @@ void setKickstartNetwork(struct loaderData_s * loaderData, int argc, { "dhcptimeout", '\0', POPT_ARG_INT, &dhcpTimeout, 0, NULL, NULL }, { 0, 0, 0, 0, 0, 0, 0 } }; - + + iface_init_iface_t(&iface); + optCon = poptGetContext(NULL, argc, (const char **) argv, ksOptions, 0); while ((rc = poptGetNextOpt(optCon)) >= 0) { @@ -1755,7 +1632,7 @@ void setKickstartNetwork(struct loaderData_s * loaderData, int argc, break; } } - + if (rc < -1) { newtWinMessage(_("Kickstart Error"), _("OK"), _("Bad argument to kickstart network command %s: %s"), @@ -1783,7 +1660,7 @@ void setKickstartNetwork(struct loaderData_s * loaderData, int argc, newtWinMessage(_("Kickstart Error"), _("OK"), _("Bad bootproto %s specified in network command"), bootProto); - } + } if (!noksdev) { if (device) { @@ -1837,7 +1714,7 @@ void setKickstartNetwork(struct loaderData_s * loaderData, int argc, */ if (loaderData->method != METHOD_NFS && loaderData->method != METHOD_URL) { initLoopback(); - if (kickstartNetworkUp(loaderData, &cfg)) + if (kickstartNetworkUp(loaderData, &iface)) logMessage(ERROR, "unable to bring up network"); } } @@ -2045,24 +1922,13 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) { } loaderData->netDev = devices[deviceNum]; - - /* turn off the non-active interface. this should keep things from - * breaking when we need the interface to do the install as long as - * you keep using that device */ - for (i = 0; devs[i]; i++) { - if (strcmp(loaderData->netDev, devices[i])) - if (!FL_TESTING(flags)) - pumpDisableInterface(devs[i]->device); - } - return LOADER_OK; } /* JKFIXME: bad name. this function brings up networking early on a * kickstart install so that we can do things like grab the ks.cfg from * the network */ -int kickstartNetworkUp(struct loaderData_s * loaderData, - struct networkDeviceConfig *netCfgPtr) { +int kickstartNetworkUp(struct loaderData_s * loaderData, iface_t * iface) { int rc; /* we may have networking already, so return to the caller */ @@ -2071,7 +1937,7 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, initLoopback(); - memset(netCfgPtr, 0, sizeof(*netCfgPtr)); + memset(iface, 0, sizeof(*iface)); do { do { @@ -2087,8 +1953,8 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, return -1; } - /* insert device into pump structure */ - strcpy(netCfgPtr->dev.device, loaderData->netDev); + /* insert device into iface structure */ + strcpy(iface->device, loaderData->netDev); break; } while (1); @@ -2105,9 +1971,9 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, } loaderData->ipinfo_set = 1; - setupNetworkDeviceConfig(netCfgPtr, loaderData); + setupNetworkDeviceConfig(iface, loaderData); - rc = readNetConfig(loaderData->netDev, netCfgPtr, loaderData->netCls, + rc = readNetConfig(loaderData->netDev, iface, loaderData->netCls, loaderData->method); if (rc == LOADER_ERROR) { @@ -2166,4 +2032,109 @@ void splitHostname (char *str, char **host, char **port) } } +/* + * Start NetworkManager and wait for a valid link, return non-zero on error. + */ +int get_connection(iface_t *iface) { + int ret; + int count = 0; + DBusConnection *connection = NULL; + DBusMessage *message = NULL; + DBusMessage *reply = NULL; + DBusError error; + dbus_uint32_t state = NM_STATE_UNKNOWN; + + if (iface == NULL) { + return 1; + } + + /* display status */ + if (FL_CMDLINE(flags)) { + printf(_("Waiting for NetworkManager to configure %s...\n"), + iface->device); + } else { + winStatus(55, 3, NULL, + _("Waiting for NetworkManager to configure %s...\n"), + iface->device, 0); + } + + /* start NetworkManager for configured interface */ + logMessage(INFO, "starting NetworkManager (%d) for %s", __LINE__, + iface->device); + ret = iface_start_NetworkManager(iface); + if (ret > 0) { + return 2; + } + + dbus_error_init(&error); + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + logMessage(DEBUGLVL, "%s (%d): %s: %s", __func__, + __LINE__, error.name, error.message); + dbus_error_free(&error); + return 3; + } + + dbus_bus_add_match(connection, + "type='signal'," + "interface='" NM_DBUS_INTERFACE "'," + "sender='" NM_DBUS_SERVICE "'," + "path='" NM_DBUS_PATH "'", &error); + if (dbus_error_is_set(&error)) { + logMessage(DEBUGLVL, "%s (%d): %s: %s", __func__, + __LINE__, error.name, error.message); + dbus_error_free(&error); + return 4; + } + + /* wait for a network connection to appear, calling for sleep(1) + * at most 30 times */ + while (count <= 30) { + message = dbus_message_new_method_call(NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "state"); + if (!message) { + logMessage(DEBUGLVL, "%s (%d): %s: %s", __func__, + __LINE__, error.name, error.message); + dbus_error_free(&error); + return 5; + } + + reply = dbus_connection_send_with_reply_and_block(connection, + message, + -1, &error); + dbus_message_unref(message); + + if (!reply) { + logMessage(DEBUGLVL, "%s (%d): %s: %s", __func__, + __LINE__, error.name, error.message); + dbus_error_free(&error); + return 6; + } + + if (!dbus_message_get_args(reply, &error, DBUS_TYPE_UINT32, + &state, DBUS_TYPE_INVALID)) { + logMessage(DEBUGLVL, "%s (%d): %s: %s", __func__, + __LINE__, error.name, error.message); + dbus_error_free(&error); + return 7; + } + + dbus_message_unref(reply); + + /* if we are connected, break the loop */ + if (state == NM_STATE_CONNECTED) { + logMessage(DEBUGLVL, "%s: NetworkManager is connected", + __func__); + return 0; + } + + sleep(1); + count++; + } + + return 8; +} + /* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/loader2/net.h b/loader2/net.h index 6bccb2871..173fc83ef 100644 --- a/loader2/net.h +++ b/loader2/net.h @@ -20,52 +20,22 @@ #ifndef H_LOADER_NET #define H_LOADER_NET -#include "loader.h" -#include <ip_addr.h> -#include <libdhcp.h> #include <newt.h> -#include <pump.h> +#include "../isys/iface.h" +#include "loader.h" #define DHCP_METHOD_STR _("Dynamic IP configuration (DHCP)") #define DHCPV6_METHOD_STR _("Dynamic IP configuration (DHCPv6)") #define MANUAL_METHOD_STR _("Manual configuration") #define AUTO_METHOD_STR _("Automatic neighbor discovery") -/* generic names for array index positions in net.c */ -enum { IPV4, IPV6 }; - -/* these match up to the radio button array index order in configureTCPIP() */ -enum { IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD }; -enum { IPV6_AUTO_METHOD, IPV6_DHCP_METHOD, IPV6_MANUAL_METHOD }; - -struct networkDeviceConfig { - struct pumpNetIntf dev; - - /* wireless settings */ - /* side effect: if this is non-NULL, then assume wireless */ - char * essid; - char * wepkey; - - /* misc settings */ - int isDynamic; - int noDns; - int dhcpTimeout; - int preset; - int ipv4method, ipv6method; - char * vendor_class; - - /* s390 settings */ - int mtu; - char *subchannels, *portname, *peerid, *nettype, *ctcprot; -}; - struct intfconfig_s { newtComponent ipv4Entry, cidr4Entry; newtComponent ipv6Entry, cidr6Entry; newtComponent gwEntry, nsEntry; const char *ipv4, *cidr4; const char *ipv6, *cidr6; - const char *gw, *ns; + const char *gw, *gw6, *ns; }; struct netconfopts { @@ -75,33 +45,25 @@ struct netconfopts { typedef int int32; -int readNetConfig(char * device, struct networkDeviceConfig * dev, +int readNetConfig(char * device, iface_t * iface, char * dhcpclass, int methodNum); -int configureTCPIP(char * device, struct networkDeviceConfig * cfg, - struct networkDeviceConfig * newCfg, - struct netconfopts * opts, int methodNum); -int manualNetConfig(char * device, struct networkDeviceConfig * cfg, - struct networkDeviceConfig * newCfg, +int configureTCPIP(char * device, iface_t * iface, struct netconfopts * opts, + int methodNum); +int manualNetConfig(char * device, iface_t * iface, struct intfconfig_s * ipcomps, struct netconfopts * opts); -void debugNetworkInfo(struct networkDeviceConfig *cfg); -int configureNetwork(struct networkDeviceConfig * dev); -int writeNetInfo(const char * fn, struct networkDeviceConfig * dev); -int findHostAndDomain(struct networkDeviceConfig * dev); -int writeResolvConf(struct networkDeviceConfig * net); +void debugNetworkInfo(iface_t * iface); +int writeDisabledNetInfo(void); +int writeEnabledNetInfo(iface_t * iface); void initLoopback(void); int chooseNetworkInterface(struct loaderData_s * loaderData); -void setupNetworkDeviceConfig(struct networkDeviceConfig * cfg, +void setupNetworkDeviceConfig(iface_t * iface, struct loaderData_s * loaderData); -int setupWireless(struct networkDeviceConfig *dev); - +int setupWireless(iface_t * iface); void setKickstartNetwork(struct loaderData_s * loaderData, int argc, char ** argv); - int kickstartNetworkUp(struct loaderData_s * loaderData, - struct networkDeviceConfig *netCfgPtr); - -char *doDhcp(struct networkDeviceConfig *dev); -void netlogger(void *arg, int priority, char *fmt, va_list va); + iface_t * iface); void splitHostname (char *str, char **host, char **port); +int get_connection(iface_t * iface); #endif diff --git a/loader2/nfsinstall.c b/loader2/nfsinstall.c index b1c6e394e..60dec649e 100644 --- a/loader2/nfsinstall.c +++ b/loader2/nfsinstall.c @@ -31,6 +31,9 @@ #include <unistd.h> #include <errno.h> #include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> #include "copy.h" #include "loader.h" @@ -380,9 +383,9 @@ int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { char * host = NULL, *path = NULL, * file = NULL, * opts = NULL; char * chk = NULL, *ip = NULL; int failed = 0; - struct networkDeviceConfig netCfg; + iface_t iface; - if (kickstartNetworkUp(loaderData, &netCfg)) { + if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "unable to bring up network"); return 1; } @@ -390,6 +393,8 @@ int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { /* if they just did 'linux ks', they want us to figure it out from * the dhcp/bootp information */ +/* XXX: fixme NetworkManager integration */ +/* if (url == NULL) { char ret[47]; ip_addr_t *tip; @@ -420,6 +425,7 @@ int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile); } } +*/ /* get the IP of the target system */ if ((ip = iface_ip2str(loaderData->netDev)) == NULL) { diff --git a/loader2/telnetd.c b/loader2/telnetd.c index f262362e8..99c6feb24 100644 --- a/loader2/telnetd.c +++ b/loader2/telnetd.c @@ -68,8 +68,8 @@ int beTelnet(void) { struct winsize ws; if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - logMessage(ERROR, "socket: %m"); - return -1; + logMessage(ERROR, "socket: %s", strerror(errno)); + return -1; } address.sin_family = AF_INET; @@ -88,17 +88,15 @@ int beTelnet(void) { winStatus(45, 3, _("Telnet"), _("Waiting for telnet connection...")); - if ((conn = accept(sock, (struct sockaddr *) &address, - &addrLength)) < 0) { - newtWinMessage(_("Error"), _("OK"), "accept failed: %m"); - close(sock); - return -1; + if ((conn = accept(sock, (struct sockaddr *) &address, &addrLength)) < 0) { + newtWinMessage(_("Error"), _("OK"), "accept failed: %s", + strerror(errno)); + close(sock); + return -1; } stopNewt(); - close(sock); - telnet_negotiate(conn, &termType, &height, &width); #ifdef DEBUG_TELNET @@ -107,18 +105,18 @@ int beTelnet(void) { masterFd = open("/dev/ptmx", O_RDWR); if (masterFd < 0) { - logMessage(CRITICAL, "cannot open /dev/ptmx"); - close(conn); - return -1; + logMessage(CRITICAL, "cannot open /dev/ptmx"); + close(conn); + return -1; } if (height != -1 && width != -1) { #ifdef DEBUG_TELNET - printf("setting window size to %d x %d\n", width, height); + printf("setting window size to %d x %d\n", width, height); #endif - ws.ws_row = height; - ws.ws_col = width; - ioctl(masterFd, TIOCSWINSZ, &ws); + ws.ws_row = height; + ws.ws_col = width; + ioctl(masterFd, TIOCSWINSZ, &ws); } @@ -126,86 +124,84 @@ int beTelnet(void) { if (child) { #ifndef DEBUG_TELNET - startNewt(); - winStatus(45, 3, _("Telnet"), _("Running anaconda via telnet...")); + startNewt(); + winStatus(45, 3, _("Telnet"), _("Running anaconda via telnet...")); #endif - fds[0].events = POLLIN; - fds[0].fd = masterFd; + fds[0].events = POLLIN; + fds[0].fd = masterFd; - fds[1].events = POLLIN; - fds[1].fd = conn; - - while ((i = poll(fds, 2, -1)) > 0) { - if (fds[0].revents) { - i = read(masterFd, buf, sizeof(buf)); + fds[1].events = POLLIN; + fds[1].fd = conn; + while ((i = poll(fds, 2, -1)) > 0) { + if (fds[0].revents) { + i = read(masterFd, buf, sizeof(buf)); #ifdef DEBUG_TELNET - { - int j; - int row; - - for (row = 0; row < (i / 12) + 1; row++) { - printf("wrote:"); - for (j = (row * 12); j < i && j < ((row + 1) * 12); j++) - printf(" 0x%2x", (unsigned char) buf[j]); - printf("\n"); - printf("wrote:"); - for (j = (row * 12); j < i && j < ((row + 1) * 12); j++) - { - if (isprint(buf[j])) - printf(" %c ", buf[j]); - else - printf(" "); - } - printf("\n"); - } - } -#endif - /* child died */ - if (i < 0) - break; + { + int j; + int row; - telnet_send_output(conn, buf, i); - } + for (row = 0; row < (i / 12) + 1; row++) { + printf("wrote:"); - if (fds[1].revents) { - int ret; - i = read(conn, buf, sizeof(buf)); + for (j = (row * 12); j < i && j < ((row + 1) * 12); j++) + printf(" 0x%2x", (unsigned char) buf[j]); - /* connection went away */ - if (!i) - break; + printf("\nwrote:"); - i = telnet_process_input(&ts, buf, i); - ret = write(masterFd, buf, i); + for (j = (row*12); j < i && j < ((row+1)*12); j++) { + if (isprint(buf[j])) + printf(" %c ", buf[j]); + else + printf(" "); + } -#ifdef DEBUG_TELNET - { - int j; - - printf("got:"); - for (j = 0; j < i; j++) - printf(" 0x%x", (unsigned char) buf[j]); - printf("\n"); - } + printf("\n"); + } + } #endif + /* child died */ + if (i < 0) + break; - } - } + telnet_send_output(conn, buf, i); + } + if (fds[1].revents) { + int ret; + i = read(conn, buf, sizeof(buf)); - if (i < 0) - logMessage(ERROR, "poll: %m"); + /* connection went away */ + if (!i) + break; -#ifndef DEBUG_TELNET - stopNewt(); + i = telnet_process_input(&ts, buf, i); + ret = write(masterFd, buf, i); +#ifdef DEBUG_TELNET + { + int j; + + printf("got:"); + for (j = 0; j < i; j++) + printf(" 0x%x", (unsigned char) buf[j]); + printf("\n"); + } #endif + } + } - kill(child, SIGTERM); - close(conn); + if (i < 0) { + logMessage(ERROR, "poll: %s", strerror(errno)); + } - exit(0); +#ifndef DEBUG_TELNET + stopNewt(); +#endif + + kill(child, SIGTERM); + close(conn); + exit(0); } unlockpt(masterFd); @@ -218,9 +214,10 @@ int beTelnet(void) { close(2); if (ttyFd != 0) { - dup2(ttyFd, 0); - close(ttyFd); + dup2(ttyFd, 0); + close(ttyFd); } + dup2(0, 1); dup2(0, 2); @@ -233,20 +230,22 @@ int beTelnet(void) { } void startTelnetd(struct loaderData_s * loaderData) { - char ret[47]; - struct networkDeviceConfig netCfg; - ip_addr_t *tip; + char ret[INET_ADDRSTRLEN+1]; + iface_t iface; + + iface_init_iface_t(&iface); - if (kickstartNetworkUp(loaderData, &netCfg)) { + if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "unable to bring up network"); return; } - tip = &(netCfg.dev.ip); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - logMessage(INFO, "going to beTelnet for %s", ret); - if (!beTelnet()) - flags |= LOADER_FLAGS_TEXT | LOADER_FLAGS_NOSHELL; + if (iface.ipaddr.s_addr) { + inet_ntop(AF_INET, &iface.ipaddr, ret, INET_ADDRSTRLEN); + logMessage(INFO, "going to beTelnet for %s", ret); + if (!beTelnet()) + flags |= LOADER_FLAGS_TEXT | LOADER_FLAGS_NOSHELL; + } return; } diff --git a/loader2/urlinstall.c b/loader2/urlinstall.c index 7a565e4bc..177716612 100644 --- a/loader2/urlinstall.c +++ b/loader2/urlinstall.c @@ -281,10 +281,12 @@ int getFileFromUrl(char * url, char * dest, !strncmp(url, "ftp://", 6) ? URL_METHOD_FTP : URL_METHOD_HTTP; char * host = NULL, * file = NULL, * chptr = NULL, *login = NULL, *password = NULL; int fd, rc; - struct networkDeviceConfig netCfg; + iface_t iface; char *ehdrs = NULL, *ip = NULL; - if (kickstartNetworkUp(loaderData, &netCfg)) { + iface_init_iface_t(&iface); + + if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "unable to bring up network"); return 1; } diff --git a/loader2/urls.c b/loader2/urls.c index 72ee5240f..3cd9a712b 100644 --- a/loader2/urls.c +++ b/loader2/urls.c @@ -257,7 +257,7 @@ char * addrToIp(char * hostname) { char *ret; struct hostent *host; - if ((ret = malloc(48)) == NULL) + if ((ret = malloc(INET6_ADDRSTRLEN+1)) == NULL) return hostname; if (inet_ntop(AF_INET, &ad, ret, INET_ADDRSTRLEN) != NULL) diff --git a/scripts/mk-images b/scripts/mk-images index 60e48e6ab..5e072f416 100755 --- a/scripts/mk-images +++ b/scripts/mk-images @@ -302,7 +302,6 @@ makemoduletree() { cp $KERNELROOT/lib/firmware/ipw2100* $MBD_DIR/firmware ;; ipw2200) - cp $KERNELROOT/lib/firmware/ipw-2.4* $MBD_DIR/firmware cp $KERNELROOT/lib/firmware/ipw2200* $MBD_DIR/firmware ;; iwl3945) @@ -449,11 +448,9 @@ EOF # copy in the binaries instbin $IMGPATH /usr/bin/login $MBD_DIR /sbin/login instbin $IMGPATH /usr/sbin/sshd $MBD_DIR /sbin/sshd - instbin $IMGPATH /usr/bin/bash $MBD_DIR /sbin/bash instbin $IMGPATH /usr/bin/busybox $MBD_DIR /sbin/busybox # make some symlinks - ln -sf bash $MBD_DIR/sbin/sh (cd $MBD_DIR/sbin; set $(./busybox 2>&1| awk '/^\t([[:alnum:]_\.\[]+,)+/' | sed 's/,//g' | sed 's/ +//'); while [ -n "$1" ]; do @@ -530,11 +527,34 @@ makeinitrd() { mkdir -p $MBD_DIR/proc mkdir -p $MBD_DIR/selinux mkdir -p $MBD_DIR/sys - mkdir -p $MBD_DIR/tmp mkdir -p $MBD_DIR/etc/terminfo/{a,b,d,l,s,v,x} - mkdir -p $MBD_DIR/etc/modprobe.d - mkdir -p $MBD_DIR/var/run + mkdir -p $MBD_DIR/tmp + mkdir -p $MBD_DIR/usr/libexec + mkdir -p $MBD_DIR/usr/lib/NetworkManager + mkdir -p $MBD_DIR/usr/share/dbus-1/system-services + mkdir -p $MBD_DIR/var/cache/hald + mkdir -p $MBD_DIR/var/lib/dbus + mkdir -p $MBD_DIR/var/lib/dhclient mkdir -p $MBD_DIR/var/lock/rpm + mkdir -p $MBD_DIR/var/run + mkdir -p $MBD_DIR/var/run/dbus + mkdir -p $MBD_DIR/var/run/hald + mkdir -p $MBD_DIR/var/run/NetworkManager + mkdir -p $MBD_DIR/etc/dbus-1/system.d + mkdir -p $MBD_DIR/etc/modprobe.d + mkdir -p $MBD_DIR/etc/NetworkManager + mkdir -p $MBD_DIR/lib/dbus-1 + mkdir -p $MBD_DIR/etc/sysconfig/network-scripts + mkdir -p $MBD_DIR/usr/share/PolicyKit/policy + mkdir -p $MBD_DIR/etc/PolicyKit + mkdir -p $MBD_DIR/var/lib/misc + mkdir -p $MBD_DIR/etc/hal/fdi + mkdir -p $MBD_DIR/usr/share/hal/fdi + mkdir -p $MBD_DIR/usr/share/hwdata + mkdir -p $MBD_DIR/etc/rc.d/init.d + mkdir -p $MBD_DIR/usr/sbin + mkdir -p $MBD_DIR/var/run/wpa_supplicant + mkdir -p $MBD_DIR/usr/lib/gconv if [ "$BUILDARCH" = "s390" -o "$BUILDARCH" = "s390x" ]; then mkdir -m 111 -p $MBD_DIR/var/empty/sshd @@ -583,8 +603,102 @@ makeinitrd() { instbin $IMGPATH /usr/sbin/udevd $MBD_DIR /sbin/udevd instbin $IMGPATH /usr/sbin/udevadm $MBD_DIR /sbin/udevadm + instbin $IMGPATH /usr/bin/udevinfo $MBD_DIR /sbin/udevinfo ln -s udevadm $MBD_DIR/sbin/udevsettle + instbin $IMGPATH /usr/bin/bash $MBD_DIR /sbin/bash + instbin $IMGPATH /usr/sbin/consoletype $MBD_DIR /sbin/consoletype + instbin $IMGPATH /usr/bin/logger $MBD_DIR /sbin/logger + + ( cd $IMGPATH/etc/rc.d/init.d + cp -a functions $MBD_DIR/etc/rc.d/init.d + ) + + ( cd $IMGPATH/etc/sysconfig/network-scripts + cp -a network-functions $MBD_DIR/etc/sysconfig/network-scripts + cp -a network-functions-ipv6 $MBD_DIR/etc/sysconfig/network-scripts + ) + + ( cd $MBD_DIR/etc ; ln -sf /etc/rc.d/init.d init.d ) + + # DHCP and DHCPv6 client daemons and support programs + instbin $IMGPATH /usr/sbin/dhclient $MBD_DIR /sbin/dhclient + cp -a $IMGPATH/usr/sbin/dhclient-script $MBD_DIR/sbin/dhclient-script + chmod 0755 $MBD_DIR/sbin/dhclient-script + instbin $IMGPATH /usr/sbin/dhcp6c $MBD_DIR /sbin/dhcp6c + instbin $IMGPATH /usr/sbin/arping $MBD_DIR /sbin/arping + instbin $IMGPATH /usr/sbin/ifconfig $MBD_DIR /sbin/ifconfig + instbin $IMGPATH /usr/sbin/ip $MBD_DIR /sbin/ip + touch $MBD_DIR/etc/resolv.conf + + # hwdata + cp -a $IMGPATH/usr/share/hwdata/pci.ids $MBD_DIR/usr/share/hwdata/pci.ids + cp -a $IMGPATH/usr/share/hwdata/usb.ids $MBD_DIR/usr/share/hwdata/usb.ids + + # hal + instbin $IMGPATH /usr/sbin/hald $MBD_DIR /sbin/hald + ( cd $IMGPATH/usr/libexec + for f in hald-runner hald-generate-fdi-cache hal*storage* ; do + instbin $IMGPATH /usr/libexec/$f $MBD_DIR /usr/libexec/$f + done + ) + touch $MBD_DIR/var/run/hald.acl-list + cp -a $IMGPATH/usr/share/hal/fdi/* $MBD_DIR/usr/share/hal/fdi + cp -a $IMGPATH/etc/hal/fdi/* $MBD_DIR/etc/hal/fdi + cp -a $IMGPATH/etc/dbus-1/system.d/hal.conf $MBD_DIR/etc/dbus-1/system.d + + # PolicyKit + ( cd $IMGPATH/etc/PolicyKit + cp -a PolicyKit.conf $MBD_DIR/etc/PolicyKit + ) + ( cd $IMGPATH/usr/share/dbus-1/system-services + cp -a org.freedesktop.PolicyKit.service $MBD_DIR/usr/share/dbus-1/system-services + ) + ( cd $IMGPATH/usr/share/PolicyKit/policy + cp -a org.freedesktop.policykit.policy $MBD_DIR/usr/share/PolicyKit/policy + ) + ( cd $IMGPATH/var/lib/misc + cp -a PolicyKit.reload $MBD_DIR/var/lib/misc + ) + + # dbus + instbin $IMGPATH /usr/bin/dbus-uuidgen $MBD_DIR /sbin/dbus-uuidgen + instbin $IMGPATH /usr/bin/dbus-daemon $MBD_DIR /sbin/dbus-daemon + cp -a $IMGPATH/etc/dbus-1/system.conf $MBD_DIR/etc/dbus-1/system.conf + cp -a $IMGPATH/lib/dbus-1/dbus-daemon-launch-helper $MBD_DIR/lib/dbus-1 + chown root:dbus $MBD_DIR/lib/dbus-1/dbus-daemon-launch-helper + chmod 04750 $MBD_DIR/lib/dbus-1/dbus-daemon-launch-helper + + # wpa_supplicant + instbin $IMGPATH /usr/sbin/wpa_passphrase $MBD_DIR /usr/sbin/wpa_passphrase + instbin $IMGPATH /usr/sbin/wpa_supplicant $MBD_DIR /usr/sbin/wpa_supplicant + cp -a $IMGPATH/etc/dbus-1/system.d/wpa_supplicant.conf $MBD_DIR/etc/dbus-1/system.d + cp -a $IMGPATH/etc/wpa_supplicant/wpa_supplicant.conf $MBD_DIR/etc/wpa_supplicant + ( cd $IMGPATH/usr/share/dbus-1/system-services + cp -a fi.epitest.hostap.WPASupplicant.service $MBD_DIR/usr/share/dbus-1/system-services + ) + + # NetworkManager + instbin $IMGPATH /usr/sbin/NetworkManager $MBD_DIR /usr/sbin/NetworkManager + instbin $IMGPATH /usr/sbin/nm-system-settings $MBD_DIR /usr/sbin/nm-system-settings + cp -a $IMGPATH/etc/dbus-1/system.d/nm-*.conf $MBD_DIR/etc/dbus-1/system.d + cp -a $IMGPATH/etc/dbus-1/system.d/NetworkManager.conf $MBD_DIR/etc/dbus-1/system.d + cp -a $IMGPATH/etc/NetworkManager/nm-system-settings.conf $MBD_DIR/etc/NetworkManager + instbin $IMGPATH /usr/lib/NetworkManager/libnm-settings-plugin-ifcfg-fedora.so \ + $MBD_DIR /usr/lib/NetworkManager/libnm-settings-plugin-ifcfg-fedora.so + ( cd $IMGPATH/usr/libexec + for f in nm-* ; do + instbin $IMGPATH /usr/libexec/$f $MBD_DIR /usr/libexec/$f + done + ) + ( cd $IMGPATH/usr/share/dbus-1/system-services + cp -a org.freedesktop.NetworkManagerSystemSettings.service $MBD_DIR/usr/share/dbus-1/system-services + cp -a org.freedesktop.nm_dispatcher.service $MBD_DIR/usr/share/dbus-1/system-services + ) + + # gconv + cp -a $IMGPATH/usr/lib/gconv/* $MBD_DIR/usr/lib/gconv + # 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/ @@ -594,6 +708,9 @@ makeinitrd() { for i in $IMGPATH/lib/udev/rules.d/*.rules ; do install -m 644 $i $MBD_DIR/lib/udev/rules.d/${i##*/} done + for i in $IMGPATH/etc/udev/rules.d/*.rules ; do + install -m 644 $i $MBD_DIR/etc/udev/rules.d/${i##*/} + done for i in $IMGPATH/lib/udev/*; do if [ -f $i ]; then install -m 755 $i $MBD_DIR/lib/udev/${i##*/}; fi done @@ -612,7 +729,6 @@ makeinitrd() { instbin $IMGPATH /usr/sbin/$n $MBD_DIR /sbin/$n done - ln -s /usr/bin/sh $MBD_DIR/sbin/sh ln -s /sbin/init $MBD_DIR/init ln -s /proc/mounts $MBD_DIR/etc/mtab ln -s sbin $MBD_DIR/bin diff --git a/scripts/mk-images.efi b/scripts/mk-images.efi index 23038eb35..f39a051a1 100755 --- a/scripts/mk-images.efi +++ b/scripts/mk-images.efi @@ -23,7 +23,11 @@ makeefibootdisk() partimg=$1 target=$2 - local partsize=$(ls -l $1 | awk '{ print $5 }') + if [ ! -f $1 ]; then + return + fi + + local partsize=$(ls -l $1 | awk '{ print $5; }') local disksize=$((17408 + $partsize + 17408)) disksize=$(($disksize + $(($disksize % 512)))) local diskimg=$(mktemp /tmp/efidisk.img.XXXXXX) diff --git a/scripts/upd-instroot b/scripts/upd-instroot index bad9bf8a8..08e07734e 100755 --- a/scripts/upd-instroot +++ b/scripts/upd-instroot @@ -151,22 +151,24 @@ die () { PACKAGES="acl anaconda anaconda-runtime attr audit-libs bash beecrypt beecrypt booty busybox-anaconda bzip2 bzip2-libs convertdb1 cracklib-dicts cracklib-python cryptsetup-luks db4 dbus dbus-python device-mapper - device-mapper-libs dmapi dmraid dmraid-libs dosfstools e2fsprogs - e2fsprogs-libs elfutils-libelf expat gfs2-utils glib2 glibc-common - hal hdparm hwdata iscsi-initiator-utils jfsutils keyutils-libs - krb5-libs kudzu libacl libattr libbdevid libbdevid-python libdhcp - libdhcp4client libdhcp6client libgcc libgcrypt libgpg-error - libnl libselinux libselinux-python libsemanage libsemanage-python - libsepol libstdc++ libtermcap libuser libuser-python libvolume_id - libxml2 lvm2 mdadm mkinitrd module-init-tools nash ncurses neon - newt newt-python nfs-utils nspr nss pam parted pciutils pcre - policy policycoreutils popt procps pykickstart pyparted python python-bugzilla + device-mapper-libs dhclient dhcpv6-client dmapi dmraid dmraid-libs + dosfstools e2fsprogs e2fsprogs-libs elfutils-libelf expat gfs2-utils + glib2 glibc-common hal hdparm hwdata iproute iscsi-initiator-utils + jfsutils keyutils-libs krb5-libs kudzu libacl libattr libbdevid + libbdevid-python libdhcp libdhcp4client libdhcp6client + libgcc libgcrypt libgpg-error libnl libselinux libselinux-python + libsemanage libsemanage-python libsepol libstdc++ libtermcap libuser + libuser-python libvolume_id libxml2 lvm2 mdadm mkinitrd + module-init-tools nash ncurses neon net-tools newt newt-python + nfs-utils nspr nss pam parted pciutils pcre policy policycoreutils + popt procps pykickstart pyparted python python-bugzilla python-elementtree python-libs python-pyblock python-sqlite - python-urlgrabber pyxf86config raidtools readline reiserfs-utils - rhpl rhpxl rpm rpm-libs rpm-python sed selinux-policy-targeted setup - slang sqlite system-config-date system-release tzdata util-linux-ng + python-urlgrabber pyxf86config raidtools readline reiserfs-utils rhpl + rhpxl rpm rpm-libs rpm-python sed selinux-policy-targeted setup slang + sqlite system-config-date system-release tzdata util-linux-ng Xconfigurator xfsdump xfsprogs xorg-x11 xorg-x11-server-Xorg yum - yum-fedorakmod yum-metadata-parser zlib anaconda-yum-plugins" + yum-fedorakmod yum-metadata-parser zlib NetworkManager + anaconda-yum-plugins dbus iputils PolicyKit initscripts wpa_supplicant" if [ $ARCH = i386 ]; then PACKAGES="$PACKAGES glibc.i386 openssl.i386" @@ -219,7 +221,7 @@ PACKAGES="$PACKAGES acl anaconda anaconda-help anaconda-images atk attr bash fonts-xorg-ISO8859-2-75dpi fonts-xorg-ISO8859-9-75dpi fonts-xorg-KOI8-R fonts-xorg-KOI8-R-75dpi freetype gail gdk-pixbuf glibc-common gnome-python2-canvas gnome-python2-gtkhtml2 - gnome-themes gpm gtk2 gtk2-engines gtkhtml2 hal libacl libart_lgpl + gnome-themes gpm gtk2 gtk2-engines gtkhtml2 libacl libart_lgpl libattr libbdevid libbdevid-python libgcc libglade2 libgnomecanvas libjpeg libpixman libpng libstdc++ libthai libxcb mesa-dri-drivers pango pirut policy policycoreutils popt prelink procps pycairo @@ -316,6 +318,7 @@ bin/chmod bin/cp bin/cpio bin/dbus-daemon +bin/dbus-uuidgen bin/dd bin/df bin/du @@ -337,8 +340,10 @@ boot/efi/EFI/redhat/elilo.efi boot/efi/EFI/redhat/grub.efi boot/efika.forth boot/memtest86* -etc/PolicyKit -etc/dbus-1 +etc/NetworkManager/nm-system-settings.conf +etc/PolicyKit/* +etc/dbus-1/* +etc/dbus-1/system.d/* etc/fb.modes etc/fonts etc/group @@ -355,11 +360,14 @@ etc/passwd etc/pcmcia etc/prelink.conf etc/protocols +etc/rc.d/init.d/functions etc/rpm/macros.prelink etc/selinux/targeted etc/services etc/shells +etc/sysconfig/network-scripts/network-functions* etc/udev +etc/wpa_supplicant/wpa_supplicant.conf etc/yum.repos.d/* etc/yum/pluginconf.d/blacklist.conf etc/yum/pluginconf.d/fedorakmod.conf @@ -367,11 +375,16 @@ etc/yum/pluginconf.d/whiteout.conf lib/terminfo lib/udev sbin/*gfs* +sbin/arping sbin/badblocks sbin/busybox.anaconda sbin/clock +sbin/consoletype sbin/cryptsetup sbin/debugfs +sbin/dhclient +sbin/dhclient-script +sbin/dhcp6c sbin/dosfslabel sbin/dumpe2fs sbin/e2fsadm @@ -386,6 +399,8 @@ sbin/fsck.reiserfs sbin/fsck.xfs sbin/hdparm sbin/hwclock +sbin/ifconfig +sbin/ip sbin/iscsiadm sbin/iscsid sbin/iscsistart @@ -423,6 +438,7 @@ sbin/umount.nfs* sbin/xfs_repair sbin/xfsdump sbin/xfsrestore +usr/$LIBDIR/NetworkManager usr/$LIBDIR/dri usr/$LIBDIR/gconv usr/$LIBDIR/gdk-pixbuf/loaders/*la* @@ -473,6 +489,7 @@ usr/bin/head usr/bin/hformat usr/bin/hmount usr/bin/humount +usr/bin/logger usr/bin/lsattr* usr/bin/lshal usr/bin/maketilo @@ -524,7 +541,12 @@ usr/lib/yum-plugins/fedorakmod.py* usr/lib/yum-plugins/whiteout.py* usr/libexec/convertdb1 usr/libexec/hal* +usr/libexec/nm-crash-logger +usr/libexec/nm-dhcp-client.action +usr/libexec/nm-dispatcher.action usr/libexec/polkit* +usr/sbin/NetworkManager +usr/sbin/nm-system-settings usr/sbin/addRamDisk usr/sbin/anaconda usr/sbin/chroot @@ -543,13 +565,15 @@ usr/sbin/prelink usr/sbin/semodule usr/sbin/showpart usr/sbin/smartctl +usr/sbin/wpa_passphrase +usr/sbin/wpa_supplicant usr/sbin/wrapper usr/sbin/xfs_admin usr/sbin/xfs_check usr/sbin/xfs_copy usr/sbin/xfs_db usr/sbin/ybin -usr/share/PolicyKit +usr/share/PolicyKit/policy/* usr/share/X11/XKeysymDB usr/share/X11/fonts/TTF/GohaTibebZemen.ttf usr/share/X11/fonts/misc/6x13* @@ -584,6 +608,7 @@ usr/share/fonts/kacst/KacstQura.ttf usr/share/hal usr/share/hwdata/MonitorsDB usr/share/hwdata/pci.ids +usr/share/hwdata/usb.ids usr/share/hwdata/videoaliases usr/share/hwdata/videodrivers usr/share/locale/*/LC_MESSAGES/anaconda.mo @@ -903,7 +928,6 @@ if [ -e $DEST/etc/selinux/targeted ]; then SELINUX=permissive SELINUXTYPE=targeted EOF - cp $DEST/etc/selinux/config fi echo "Creating libuser.conf" @@ -920,8 +944,6 @@ directory = /mnt/sysimage/etc directory = /mnt/sysimage/etc EOF -cp $DEST/etc/libuser.conf - sed -i 's|\(installforallkernels\) = 0|\1 = 1|' $DEST/etc/yum/pluginconf.d/fedorakmod.conf # @@ -941,8 +963,6 @@ sed -i "s,^MANPATH[^_MAP][ \t]*,&/mnt/sysimage," $DEST/etc/man.config # sed -i "s,^MANPATH_MAP[ \t]*[a-zA-Z0-9/]*[ \t]*,&/mnt/sysimage," $DEST/etc/man.config -rm -f $KEEPFILE $KEEPFILERESCUE - echo "Scrubbing tree..." "$DEST" mkdir -p $DEST/lib mkdir -p $DEST/firmware @@ -951,14 +971,12 @@ ln -snf /firmware $DEST/lib/firmware cp $DEST/usr/lib/anaconda/raidstart-stub $DEST/usr/bin/raidstart cp $DEST/usr/lib/anaconda/raidstop-stub $DEST/usr/bin/raidstop cp $DEST/usr/lib/anaconda/losetup-stub $DEST/usr/bin/losetup -cp $DEST/usr/lib/anaconda/dhcpclient-stub $DEST/usr/bin/dhcpclient -( cd $DEST/usr/bin && rm -f pump && ln -sf dhcpclient pump ) cp $DEST/usr/lib/anaconda/list-harddrives-stub $DEST/usr/bin/list-harddrives cp $DEST/usr/lib/anaconda/loadkeys-stub $DEST/usr/bin/loadkeys cp $DEST/usr/lib/anaconda/mknod-stub $DEST/usr/bin/mknod cp $DEST/usr/lib/anaconda/syslogd-stub $DEST/usr/bin/syslogd mv $DEST/usr/sbin/anaconda $DEST/usr/bin/anaconda -mv $DEST/usr/lib/anaconda-runtime/lib* $DEST/usr/$LIBDIR +mv $DEST/usr/lib/anaconda-runtime/lib* $DEST/usr/$LIBDIR 2>/dev/null mv $DEST/etc/yum.repos.d $DEST/etc/anaconda.repos.d |