anaconda.spec | 2 - command-stubs/dhcpclient-stub | 116 ---- isys/Makefile | 9 - isys/iface.c | 378 ++++++++++++-- isys/iface.h | 141 +++++- isys/isys.c | 193 ++++---- isys/wireless.c | 208 ------- isys/wireless.h | 4 - loader2/Makefile | 12 +- loader2/linuxrc.s390 | 1 - loader2/loader.c | 57 ++- loader2/net.c | 1194 +++++++++++++++++++---------------------- loader2/net.h | 66 +-- loader2/nfsinstall.c | 34 +- loader2/telnetd.c | 179 +++---- loader2/urlinstall.c | 6 +- loader2/urls.c | 2 +- scripts/mk-images | 11 +- scripts/upd-instroot | 13 +- 19 files changed, 1307 insertions(+), 1319 deletions(-) diff --git a/anaconda.spec b/anaconda.spec index 19dc803..5840cd7 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 @@ -46,7 +45,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 diff --git a/command-stubs/dhcpclient-stub b/command-stubs/dhcpclient-stub deleted file mode 100755 index b5ffdc7..0000000 --- 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 . -# - -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 5935277..690beaf 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 51f923c..65a7c16 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,68 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include #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 struct nl_addr *_iface_in_addr2nl_addr(struct in_addr *, + struct in_addr *); +static struct nl_addr *_iface_in6_addr2nl_addr(struct in6_addr *, int); +static int _iface_have_valid_addr(void *addr, int family, int length); + /* - * 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 +92,133 @@ 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); +} + +/* + * Convert an IPv4 address and accompanying netmask from struct in_addr to + * a struct nl_addr. The netmask is optional. Pass NULL for netmask if you + * just want to convert an arbitrary in_addr to nl_addr. Return NULL on + * failure. + */ +static struct nl_addr *_iface_in_addr2nl_addr(struct in_addr *ipaddr, + struct in_addr *netmask) { + int prefix = -1; + char ipbuf[INET_ADDRSTRLEN+1]; + char *tmpbuf = NULL; + struct nl_addr *addr = NULL; + + if (ipaddr == NULL) { + return NULL; + } + + memset(&ipbuf, '\0', INET_ADDRSTRLEN+1); + + /* convert ip address to dotted-quad representation with prefix */ + if (inet_ntop(AF_INET, ipaddr, ipbuf, INET_ADDRSTRLEN) == NULL) { + return NULL; + } + + if (netmask != NULL) { + if ((prefix = iface_netmask2prefix(netmask)) == -1) { + return NULL; + } + + if (asprintf(&tmpbuf, "%s/%d", ipbuf, prefix) == -1) { + return NULL; + } + } else { + if (asprintf(&tmpbuf, "%s", ipbuf) == -1) { + return NULL; + } + } + + /* build our nl_addr */ + if ((addr = nl_addr_parse(tmpbuf, AF_INET)) == NULL) { + return NULL; + } + + return addr; +} + +/* + * Convert an IPv6 address and accompanying prefix from struct in6_addr to + * an nl_addr. Return NULL on failure. + */ +struct nl_addr *_iface_in6_addr2nl_addr(struct in6_addr *ip6addr, + int ip6prefix) { + struct nl_addr *addr = NULL; + char *tmpbuf = NULL; + char ip6buf[INET6_ADDRSTRLEN+1]; + + if (ip6addr == NULL || (ip6prefix < 0 || ip6prefix > 128)) { + return NULL; + } + + memset(&ip6buf, '\0', INET6_ADDRSTRLEN+1); + + /* convert ip address to hex+colon representation with prefix */ + if (inet_ntop(AF_INET6, ip6addr, ip6buf, INET6_ADDRSTRLEN) == NULL) { + return NULL; + } + + if (asprintf(&tmpbuf, "%s/%d", ip6buf, ip6prefix) == -1) { + return NULL; + } + + /* build our nl_addr */ + if ((addr = nl_addr_parse(tmpbuf, AF_INET6)) == NULL) { + return NULL; + } + + return addr; +} + +/* + * 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; +} + +/* * 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 +235,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 +279,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 +291,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 +329,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 +342,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; } @@ -231,3 +375,169 @@ mac2str_error2: return buf; } + +/* + * 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->dhcp_pid = -1; + iface->dhcpv6_pid = -1; + 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); +} diff --git a/isys/iface.h b/isys/iface.h index cc1f813..43992fa 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,10 +19,141 @@ * Author(s): David Cantrell */ +#ifndef ISYSIFACE_H +#define ISYSIFACE_H + +#include +#include #include #include +/* Enumerated types used in iface.c as well as loader's network code */ +enum { 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) + +/* 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); + +#endif /* ISYSIFACE_H */ diff --git a/isys/isys.c b/isys/isys.c index 32ae1d9..41a4e9d 100644 --- a/isys/isys.c +++ b/isys/isys.c @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include #include #ifdef USESELINUX @@ -65,9 +67,6 @@ #include #include -#include -#include - #include #include "iface.h" @@ -79,6 +78,7 @@ #include "wireless.h" #include "eddsupport.h" #include "auditd.h" +#include "imount.h" #ifndef CDROMEJECT #define CDROMEJECT 0x5309 @@ -517,52 +517,54 @@ 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 (strlen(prefix)) - i = atoi(prefix); - if (i > 0 && i <= 128) - cfg.ipv6_prefixlen = i; + if (inet_pton(AF_INET6, ipv6, &iface.ip6addr) >= 1) { + if (strlen(prefix)) { + i = strtol(prefix, &ep, 10); + if (i > 0 && i <= 128) { + 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; } @@ -571,21 +573,17 @@ static PyObject * doConfigNetDevice(PyObject * s, PyObject * args) { 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 *device = NULL; +// char *r = NULL; char *ipv4method = NULL, *ipv6method = NULL, *dhcpclass = NULL; int useipv4, useipv6; - char buf[47]; - time_t timeout = 45; - struct pumpNetIntf cfg; +// char buf[47]; +// time_t timeout = 45; + iface_t cfg; struct utsname kv; - DHCP_Preference pref = 0; - ip_addr_t *tip; - PyObject * rc; +// DHCP_Preference pref = 0; +// PyObject * rc; if (!PyArg_ParseTuple(args, "sisis|s", &device, &useipv4, &ipv4method, &useipv6, &ipv6method, &dhcpclass)) return NULL; @@ -604,62 +602,67 @@ static PyObject * doDhcpNetDevice(PyObject * s, PyObject * args) { 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; +// /* 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 PyString_FromString(""); + //return rc; } 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; - mask = htonl(~((1 << (32 - prefix)) - 1)); - inet_ntop(AF_INET, (struct in_addr *) &mask, dst, INET_ADDRSTRLEN); + if ((mask = iface_prefix2netmask(prefix)) == NULL) + return NULL; + + 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 aa13b11..6ede034 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 82cb4d4..d7ba8be 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 9e1361b..103709d 100644 --- a/loader2/Makefile +++ b/loader2/Makefile @@ -28,13 +28,13 @@ 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) ifeq (1, $(USESELINUX)) LIBS += -lselinux -lsepol diff --git a/loader2/linuxrc.s390 b/loader2/linuxrc.s390 index f9e1de9..210f83e 100644 --- a/loader2/linuxrc.s390 +++ b/loader2/linuxrc.s390 @@ -370,7 +370,6 @@ if [ "$NETTYPE" = "qeth" ] || [ "$NETTYPE" = "lcs" ]; 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 56b227d..5f944f4 100644 --- a/loader2/loader.c +++ b/loader2/loader.c @@ -45,9 +45,12 @@ #include #include +#include #include #include +#include + #include #include #include @@ -150,7 +153,7 @@ void doShell(void) { void doGdbserver(struct loaderData_s *loaderData) { int child, rc, 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. @@ -158,7 +161,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; } @@ -1077,7 +1080,7 @@ static char *doLoaderMain(char * location, int rhcdfnd = 0; char * devName = NULL; - static struct networkDeviceConfig netDev; + static iface_t iface; char * kbdtype = NULL; @@ -1284,8 +1287,8 @@ static char *doLoaderMain(char * location, logMessage(INFO, "need to set up networking"); initLoopback(); - memset(&netDev, 0, sizeof(netDev)); - netDev.isDynamic = 1; + memset(&iface, 0, sizeof(iface)); + iface.flags |= IFACE_FLAGS_IS_DYNAMIC; /* fall through to interface selection */ case STEP_IFACE: @@ -1312,7 +1315,7 @@ static char *doLoaderMain(char * location, } devName = loaderData->netDev; - strcpy(netDev.dev.device, devName); + strcpy(iface.device, devName); /* continue to ip config */ step = STEP_IP; @@ -1324,7 +1327,7 @@ static char *doLoaderMain(char * location, 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); } @@ -1339,25 +1342,26 @@ static char *doLoaderMain(char * location, /* 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, methodNum); + rc = readNetConfig(devName, &iface, loaderData->netCls, methodNum); 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)) { + if (inet_ntop(AF_INET, &iface.ipaddr, ret, + INET_ADDRSTRLEN) == NULL) { + ret = NULL; + } } 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); @@ -1371,16 +1375,17 @@ static char *doLoaderMain(char * location, 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)) { + if (inet_ntop(AF_INET6, &iface.ip6addr, ret, + INET6_ADDRSTRLEN) == NULL) { + ret = NULL; + } } 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); @@ -1399,8 +1404,10 @@ static char *doLoaderMain(char * location, } } - free(ret); - ret = NULL; + if (ret) { + free(ret); + ret = NULL; + } if ((rc == LOADER_BACK) || (rc == LOADER_ERROR) || ((dir == -1) && (rc == LOADER_NOOP))) { @@ -1409,7 +1416,7 @@ static char *doLoaderMain(char * location, break; } - writeNetInfo("/tmp/netinfo", &netDev); + writeNetInfo("/tmp/netinfo", &iface); step = STEP_URL; dir = 1; break; diff --git a/loader2/net.c b/loader2/net.c index c468b67..e0791db 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 @@ -65,6 +65,7 @@ static void cidrCallback(newtComponent co, void * dptr) { struct intfconfig_s * data = dptr; int cidr, upper = 0; struct in_addr addr; + char *ep = NULL; if (co == data->cidr4Entry) { if (data->cidr4 == NULL && data->ipv4 == NULL) @@ -73,7 +74,7 @@ static void cidrCallback(newtComponent co, void * dptr) { if (inet_pton(AF_INET, data->cidr4, &addr) >= 1) return; - cidr = atoi(data->cidr4); + cidr = strtol(data->cidr4, &ep, 10); if (strcmp(data->ipv4, "")) upper = 32; @@ -81,7 +82,7 @@ static void cidrCallback(newtComponent co, void * dptr) { if (data->cidr6 == NULL && data->ipv6 == NULL) return; - cidr = atoi(data->cidr6); + cidr = strtol(data->cidr6, &ep, 10); if (strcmp(data->ipv6, "")) upper = 128; @@ -99,7 +100,7 @@ static void cidrCallback(newtComponent co, void * dptr) { static void ipCallback(newtComponent co, void * dptr) { int i; - char *buf, *octet; + char *buf, *octet, *ep; struct intfconfig_s * data = dptr; if (co == data->ipv4Entry) { @@ -107,7 +108,7 @@ static void ipCallback(newtComponent co, void * dptr) { if (data->cidr4 == NULL && data->ipv4 != NULL) { buf = strdup(data->ipv4); octet = strtok(buf, "."); - i = atoi(octet); + i = strtol(octet, &ep, 10); free(buf); free(octet); @@ -229,7 +230,7 @@ void initLoopback(void) { strcpy(req.ifr_name, "lo"); if (ioctl(s, SIOCGIFFLAGS, &req)) { - logMessage(LOG_ERR, "ioctl SIOCGIFFLAGS failed: %d %s\n", errno, + logMessage(ERROR, "ioctl SIOCGIFFLAGS failed: %d %s\n", errno, strerror(errno)); close(s); return; @@ -237,7 +238,7 @@ void initLoopback(void) { req.ifr_flags |= (IFF_UP | IFF_RUNNING); if (ioctl(s, SIOCSIFFLAGS, &req)) { - logMessage(LOG_ERR, "ioctl SIOCSIFFLAGS failed: %d %s\n", errno, + logMessage(ERROR, "ioctl SIOCSIFFLAGS failed: %d %s\n", errno, strerror(errno)); close(s); return; @@ -248,19 +249,19 @@ void initLoopback(void) { return; } -static int getWirelessConfig(struct networkDeviceConfig *cfg, char * ifname) { +static int getWirelessConfig(iface_t * iface, char * ifname) { char * wepkey = ""; - char * essid = ""; + char * ssid = ""; int rc = 0; char * buf; - if (cfg->wepkey != NULL) { - wepkey = strdup(cfg->wepkey); + if (iface->wepkey != NULL) { + wepkey = strdup(iface->wepkey); } - if (cfg->essid != NULL) { - essid = strdup(cfg->essid); + if (iface->ssid != NULL) { + ssid = strdup(iface->ssid); } else { - essid = get_essid(ifname); + ssid = get_ssid(ifname); } rc = asprintf(&buf, _("%s is a wireless network adapter. Please " @@ -268,8 +269,14 @@ static int getWirelessConfig(struct networkDeviceConfig *cfg, char * ifname) { "to access your wireless network. If no key " "is needed, leave this field blank and the " "install will continue."), ifname); + + if (rc == -1) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); + abort(); + } + do { - struct newtWinEntry entry[] = { { N_("ESSID"), &essid, 0 }, + struct newtWinEntry entry[] = { { N_("SSID"), &ssid, 0 }, { N_("Encryption Key"), &wepkey, 0 }, { NULL, NULL, 0 } }; @@ -284,26 +291,26 @@ static int getWirelessConfig(struct networkDeviceConfig *cfg, char * ifname) { } while (rc == 2); free(buf); - if (cfg->wepkey != NULL) - free(cfg->wepkey); + if (iface->wepkey != NULL) + free(iface->wepkey); if (wepkey && (strlen(wepkey) > 0)) - cfg->wepkey = strdup(wepkey); + iface->wepkey = strdup(wepkey); else - cfg->wepkey = NULL; + iface->wepkey = NULL; - if (cfg->essid != NULL) - free(cfg->essid); + if (iface->ssid != NULL) + free(iface->ssid); - if (essid && (strlen(essid) > 0)) - cfg->essid = strdup(essid); + if (ssid && (strlen(ssid) > 0)) + iface->ssid = strdup(ssid); else - cfg->essid = NULL; + iface->ssid = NULL; return LOADER_OK; } -static int getDnsServers(struct networkDeviceConfig * cfg) { +static int getDnsServers(iface_t * iface) { int rc; struct in_addr addr; struct in6_addr addr6; @@ -323,23 +330,22 @@ 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); @@ -364,7 +370,7 @@ 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) { struct in_addr addr; struct in6_addr addr6; @@ -380,9 +386,9 @@ 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) { @@ -390,20 +396,20 @@ void setupNetworkDeviceConfig(struct networkDeviceConfig * cfg, if (loaderData->essid) { logMessage(INFO, "setting specified essid of %s", loaderData->essid); - cfg->essid = strdup(loaderData->essid); + iface->ssid = strdup(loaderData->essid); } if (loaderData->wepkey) { logMessage(INFO, "setting specified wepkey"); - cfg->wepkey = strdup(loaderData->wepkey); + iface->wepkey = strdup(loaderData->wepkey); } /* go ahead and set up the wireless interface in case * we're using dhcp */ - setupWireless(cfg); + setupWireless(iface); } /* 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 */ @@ -422,196 +428,174 @@ void setupNetworkDeviceConfig(struct networkDeviceConfig * cfg, if (!FL_TESTING(flags)) { waitForLink(loaderData->netDev); - cfg->noDns = loaderData->noDns; - cfg->dhcpTimeout = loaderData->dhcpTimeout; - ret = doDhcp(cfg); + + if (loaderData->noDns) { + iface->flags |= IFACE_FLAGS_NO_WRITE_RESOLV_CONF; + } + + iface->dhcptimeout = loaderData->dhcpTimeout; + ret = startNetworkManager(iface); } if (!FL_CMDLINE(flags)) newtPopWindow(); - if (ret != NULL) { - logMessage(DEBUGLVL, "dhcp: %s", ret); + if (ret) { + logMessage(DEBUGLVL, "dhcp: %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 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)) { + if (startNetworkManager(iface)) { newtWinMessage(_("Network Error"), _("Retry"), _("There was an error configuring your network " "interface.")); return LOADER_BACK; } - findHostAndDomain(cfg); - - if (!cfg->noDns) - writeResolvConf(cfg); - 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 (getWirelessConfig(iface, device) == LOADER_BACK) { 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); } @@ -619,14 +603,14 @@ int readNetConfig(char * device, struct networkDeviceConfig * cfg, /* 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; @@ -638,87 +622,51 @@ 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)) { + if (startNetworkManager(iface)) { 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; 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 */ @@ -836,39 +784,39 @@ 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)) { winStatus(55, 3, NULL, _("Sending request for IP information for %s..."), device, 0); waitForLink(device); - dret = doDhcp(newCfg); + dret = startNetworkManager(iface); newtPopWindow(); } - if (dret == NULL) { - newCfg->isDynamic = 1; - if (!(newCfg->dev.set & PUMP_NETINFO_HAS_DNS)) { + if (!dret) { + iface->flags |= IFACE_FLAGS_IS_DYNAMIC; + if (iface->numdns == 0) { logMessage(WARNING, "dhcp worked, but did not return a DNS server"); @@ -878,15 +826,15 @@ int configureTCPIP(char * device, struct networkDeviceConfig * cfg, * - 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; @@ -895,7 +843,7 @@ int configureTCPIP(char * device, struct networkDeviceConfig * cfg, i = 1; } } else { - logMessage(DEBUGLVL, "dhcp: %s", dret); + logMessage(DEBUGLVL, "dhcp: %d", dret); i = 0; } } else { @@ -909,22 +857,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, q, have[2], stack[2]; - char *buf = NULL; - char ret[48]; - ip_addr_t *tip; + int i, rows, pos, prefix, cidr, have[2], stack[2]; + char *buf = NULL, *ep; + char ret[INET6_ADDRSTRLEN+1]; struct in_addr addr; struct in6_addr addr6; + struct in_addr *tmpaddr = NULL; newtComponent f, okay, back, answer; newtGrid egrid = NULL; newtGrid qgrid = NULL; @@ -932,16 +879,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; @@ -973,25 +925,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); } @@ -1025,23 +991,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) - q = asprintf(&buf, "%d", cfg->dev.ipv6_prefixlen); - else if (newCfg->dev.set & PUMP_INTFINFO_HAS_IPV6_PREFIX) - q = asprintf(&buf, "%d", newCfg->dev.ipv6_prefixlen); + if (iface->ip6prefix) { + if (asprintf(&buf, "%d", iface->ip6prefix) == -1) { + buf = NULL; + } + } 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); } @@ -1067,26 +1045,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); @@ -1103,6 +1083,12 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, "netmask or the CIDR-style prefix are acceptable. " "The gateway and name server fields must be valid IPv4 " "or IPv6 addresses.")); + + if (i == -1) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); + abort(); + } + text = newtTextboxReflowed(-1, -1, buf, 52, 0, 10, 0); newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, @@ -1126,31 +1112,31 @@ int manualNetConfig(char * device, struct networkDeviceConfig * cfg, if (!stack[i]) have[i] = 2; answer = newtRunForm(f); - /* memset(newCfg, 0, sizeof(*newCfg)); */ /* 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 { - cidr = atoi(ipcomps->cidr4); + cidr = strtol(ipcomps->cidr4, &ep, 10); 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; } } } @@ -1160,18 +1146,18 @@ 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]++; } } if (ipcomps->cidr6) { - prefix = atoi(ipcomps->cidr6); + prefix = strtol(ipcomps->cidr6, &ep, 10); if (prefix > 0 || prefix <= 128) { - newCfg->dev.ipv6_prefixlen = prefix; - newCfg->dev.set |= PUMP_INTFINFO_HAS_IPV6_PREFIX; + iface->ip6prefix = prefix; have[IPV6]++; } } @@ -1179,37 +1165,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; } } @@ -1234,8 +1207,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); @@ -1245,382 +1218,341 @@ 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 = "); + } 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 = "); + } 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 = "); + } 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 = "); + } 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 = "); + } 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 = "); + } 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: %s", strerror(errno)); - } - 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: %s", strerror(errno)); + if (iface->numdns > 0) { + for (i = 0; i < iface->numdns; i++) { + logMessage(DEBUGLVL, "DNS[%d] = %s", i, iface->dns[i]); } + } - } + if (iface->hostname) { + logMessage(DEBUGLVL, "hostname = %s", iface->hostname); } - return 0; -} + if (iface->domain) { + logMessage(DEBUGLVL, "domain = %s", iface->domain); + } -void netlogger(void *arg, int priority, char *fmt, va_list va) { - int p; - char *buf = NULL; - - 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->dhcptimeout) { + logMessage(DEBUGLVL, "DHCP timeout = %d", iface->dhcptimeout); + } - if (vasprintf(&buf, fmt, va) != -1) { - logMessage(p, "%s", buf); - free(buf); - } else { - logMessage(ERROR, "unable to log network message"); + if (iface->vendorclass) { + logMessage(DEBUGLVL, "DHCP vendor class = %s", iface->vendorclass); } - return; -} + if (iface->ssid) { + logMessage(DEBUGLVL, "SSID = %s", iface->ssid); + } -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; + if (iface->wepkey) { + logMessage(DEBUGLVL, "WEP key = %s", iface->wepkey); + } - i = &dev->dev; +#if defined(__s390__) || defined(__s390x__) + if (iface->mtu) { + logMessage(DEBUGLVL, "mtu = %d", iface->mtu); + } - if (dev->dhcpTimeout < 0) - timeout = 45; - else - timeout = dev->dhcpTimeout; + if (iface->subchannels) { + logMessage(DEBUGLVL, "subchannels = %s", iface->subchannels); + } - if (dev->vendor_class != NULL) { - class = dev->vendor_class; - } else { - if (uname(&kv) == -1) { - logMessage(ERROR, "failure running uname() in doDhcp()"); - class = "anaconda"; - } else { - int ret; + if (iface->portname) { + logMessage(DEBUGLVL, "portname = %s", iface->portname); + } - ret = asprintf(&class, "anaconda-%s %s %s", - kv.sysname, kv.release, kv.machine); - logMessage(DEBUGLVL, "sending %s as dhcp vendor-class", class); - } + if (iface->peerid) { + logMessage(DEBUGLVL, "peerid = %s", iface->peerid); } - if (getLogLevel() == DEBUGLVL) - loglevel = LOG_DEBUG; - else - loglevel = LOG_INFO; + if (iface->nettype) { + logMessage(DEBUGLVL, "nettype = %s", iface->nettype); + } - /* dhcp preferences are in /usr/include/libdhcp/dhcp_nic.h */ + if (iface->ctcprot) { + logMessage(DEBUGLVL, "ctcprot = %s", iface->ctcprot); + } +#endif - /* 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; +/* FIXME: print rest of iface structure */ + + return; +} + +/* + * Start NetworkManager to bring up interfaces. We write out sysconfig + * control files here to make it easy. + */ +int startNetworkManager(iface_t * iface) { + int err = 0; + char *fn = NULL; + char tmpaddr[INET6_ADDRSTRLEN+1]; + + memset(tmpaddr, '\0', sizeof(tmpaddr)); + + /* write out /etc/sysconfig/network-scripts/ifcfg-DEVICE */ + if (asprintf(&fn, "/etc/sysconfig/network-scripts/ifcfg-%s", + iface->device) == -1) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); + return 1; } - /* 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; + if (writeNetInfo(fn, iface)) { + logMessage(ERROR, "error writing %s", fn); + return 2; } - /* disable some things for this DHCP call */ - pref |= DHCPv6_DISABLE_RESOLVER | DHCPv4_DISABLE_HOSTNAME_SET; + /* write out /etc/sysconfig/network */ + if (asprintf(&fn, "/etc/sysconfig/network", iface->device) == -1) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); + return 8; + } - /* 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 ((ofile = fopen(fn, "w")) == NULL) { + free(fn); + logMessage(ERROR, "failed to open %s for writing", fn); + return 9; } - /* 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); + fprintf(ofile, "NETWORKING=yes\n"); + + if (iface->hostname != NULL) { + fprintf(ofile, "HOSTNAME=%s\n", iface->hostname); + } + + if (iface_have_in_addr(iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, tmpaddr, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + return 10; } + + fprintf(ofile, "GATEWAY=%s\n", tmpaddr); } - return r; -} + if (iface_have_in6_addr(iface->gateway6)) { + if (inet_ntop(AF_INET6, &iface->gateway6, tmpaddr, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + return 11; + } -int configureNetwork(struct networkDeviceConfig * dev) { - char *rc; + fprintf(ofile, "IPV6_DEFAULTGW=%s\n", tmpaddr); + } - setupWireless(dev); - rc = pumpSetupInterface(&dev->dev); - if (rc != NULL) { - logMessage(INFO, "result of pumpSetupInterface is %s", rc); - return 1; + if (fclose(ofile) == EOF) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); + return 12; } - /* we need to wait for a link after setting up the interface as some - * switches decide to reconfigure themselves after that (#115825) - */ - waitForLink((char *)&dev->dev.device); + /* start NetworkManager */ +/* FIXME: write me */ + return 0; } -int writeNetInfo(const char * fn, struct networkDeviceConfig * dev) { +int writeNetInfo(const char * fn, iface_t * iface) { FILE * f; int i; struct device ** devices; - char ret[48]; - ip_addr_t *tip; + char ret[INET6_ADDRSTRLEN+1]; devices = getDevices(DEVICE_NETWORK); if (!devices) return 0; for (i = 0; devices[i]; i++) - if (!strcmp(devices[i]->device, dev->dev.device)) break; - - if (!(f = fopen(fn, "w"))) return -1; + if (!strcmp(devices[i]->device, iface->device)) + break; - fprintf(f, "DEVICE=%s\n", dev->dev.device); + if (!(f = fopen(fn, "w"))) + return -1; + + fprintf(f, "DEVICE=%s\n", iface->device); fprintf(f, "ONBOOT=yes\n"); - if (dev->isDynamic) { + if (IFACE_IS_DYNAMIC(iface->flags)) { fprintf(f, "BOOTPROTO=dhcp\n"); } else { fprintf(f, "BOOTPROTO=static\n"); - 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->ipaddr)) { + inet_ntop(AF_INET, &iface->ipaddr, ret, INET_ADDRSTRLEN); + if (ret == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + fprintf(f, "IPADDR=%s\n", ret); + } + } - tip = &(dev->dev.netmask); - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - fprintf(f, "NETMASK=%s\n", ret); + if (iface_have_in_addr(&iface->netmask)) { + inet_ntop(AF_INET, &iface->netmask, ret, INET_ADDRSTRLEN); + if (ret == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + fprintf(f, "NETMASK=%s\n", ret); + } + } - 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); + if (iface_have_in_addr(&iface->broadcast)) { + inet_ntop(AF_INET, &iface->broadcast, ret, INET_ADDRSTRLEN); + if (ret == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + fprintf(f, "BROADCAST=%s\n", ret); + } } - 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); + if (iface_have_in_addr(&iface->gateway)) { + inet_ntop(AF_INET, &iface->gateway, ret, INET_ADDRSTRLEN); + if (ret == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + fprintf(f, "GATEWAY=%s\n", ret); + } } } if (!FL_NOIPV6(flags)) { - if (dev->ipv6method == IPV6_AUTO_METHOD) { + if (iface->ipv6method == IPV6_AUTO_METHOD) { fprintf(f, "IPV6_AUTOCONF=yes\n"); - } else if (dev->ipv6method == IPV6_DHCP_METHOD) { + } else if (iface->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); - - return 0; -} - -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 (!(net->dev.set & PUMP_NETINFO_HAS_DOMAIN) && !net->dev.numDns) - return LOADER_ERROR; - - f = fopen(filename, "w"); - if (!f) { - logMessage(ERROR, "Cannot create %s: %s\n", filename, strerror(errno)); - return LOADER_ERROR; - } - - if (net->dev.set & PUMP_NETINFO_HAS_DOMAIN) - fprintf(f, "search %s\n", net->dev.domain); - - 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); - } - - fclose(f); - - res_init(); /* reinit the resolver so DNS changes take affect */ - - return 0; -} - -int findHostAndDomain(struct networkDeviceConfig * dev) { - char * name, * chptr; - char ret[48]; - ip_addr_t *tip; - struct hostent *host; - - if (!FL_TESTING(flags)) { - writeResolvConf(dev); - } - - if (dev->dev.numDns == 0) { - logMessage(ERROR, "no DNS servers, can't look up hostname"); - return 1; - } - - 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"); - - 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_CMDLINE(flags)) - newtPopWindow(); - - if (!host) { - logMessage(WARNING, "reverse name lookup of %s failed", ret); - return 1; + if (inet_ntop(AF_INET6, &iface->ip6addr, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + fprintf(f, "IPV6ADDR=%s/%d\n", ret, iface->ip6prefix); + } } - name = strdup(host->h_name); - - logMessage(INFO, "reverse name lookup worked (hostname is %s)", name); - - dev->dev.hostname = strdup(name); - dev->dev.set |= PUMP_NETINFO_HAS_HOSTNAME; - } else { - name = dev->dev.hostname; + 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 { + fprintf(f, "IPV6_DEFAULTGW=%s\n", ret); + } + } } - 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 (iface->numdns > 0) { + for (i = 0; i < iface->numdns; i++) { + fprintf(f, "DNS%d=%s\n", i+1, iface->dns[i]); } } + if (iface->hostname) + fprintf(f, "HOSTNAME=%s\n", iface->hostname); + if (iface->domain) + fprintf(f, "DOMAIN=%s\n", iface->domain); + if (iface->mtu) + fprintf(f, "MTU=%d\n", iface->mtu); + if (iface->peerid) + fprintf(f, "PEERID=%s\n", iface->peerid); + if (iface->subchannels) + fprintf(f, "SUBCHANNELS=%s\n", iface->subchannels); + if (iface->portname) + fprintf(f, "PORTNAME=%s\n", iface->portname); + if (iface->nettype) + fprintf(f, "NETTYPE=%s\n", iface->nettype); + if (iface->ctcprot) + fprintf(f, "CTCPROT=%s\n", iface->ctcprot); + + if (iface->ssid) + fprintf(f, "ESSID=%s\n", iface->ssid); + if (iface->wepkey) + fprintf(f, "KEY=%s\n", iface->wepkey); + + fclose(f); + return 0; } -void setKickstartNetwork(struct loaderData_s * loaderData, int argc, +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; + char *arg, *bootProto = NULL; + char *device = NULL, *ethtool = NULL, *class = NULL; + char *essid = NULL, *wepkey = NULL, *onboot = NULL; + int noDns = 0, noksdev = 0, rc, mtu = 0; + int noipv4 = 0, noipv6 = 0, dhcpTimeout = -1; poptContext optCon; - struct networkDeviceConfig cfg; + iface_t iface; struct poptOption ksOptions[] = { { "bootproto", '\0', POPT_ARG_STRING, &bootProto, 0, NULL, NULL }, @@ -1643,7 +1575,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) { @@ -1669,7 +1603,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"), @@ -1697,7 +1631,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) { @@ -1751,7 +1685,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"); } } @@ -1884,10 +1818,10 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) { /* JKFIXME: should display link status */ deviceNum = 0; rc = newtWinMenu(_("Networking Device"), - _("You have multiple network devices on this system. " - "Which would you like to install through?"), max, 10, 10, - deviceNums < 6 ? deviceNums : 6, deviceNames, - &deviceNum, _("OK"), _("Back"), NULL); + _("You have multiple network devices on this system. " + "Which would you like to install through?"), max, 10, 10, + deviceNums < 6 ? deviceNums : 6, deviceNames, + &deviceNum, _("OK"), _("Back"), NULL); if (rc == 2) return LOADER_BACK; @@ -1899,7 +1833,7 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) { for (i = 0; devs[i]; i++) { if (strcmp(loaderData->netDev, devices[i])) if (!FL_TESTING(flags)) - pumpDisableInterface(devs[i]->device); + iface_down(devs[i]->device); } return LOADER_OK; @@ -1908,8 +1842,7 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) { /* 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 */ @@ -1918,7 +1851,7 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, initLoopback(); - memset(netCfgPtr, 0, sizeof(*netCfgPtr)); + memset(iface, 0, sizeof(*iface)); do { do { @@ -1934,8 +1867,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); @@ -1952,9 +1885,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) { @@ -1976,41 +1909,4 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, return 0; } -void splitHostname (char *str, char **host, char **port) -{ - char *rightbrack = strchr(str, ']'); - - *host = NULL; - *port = NULL; - - if (*str == '[' && rightbrack) { - /* An IPv6 address surrounded by brackets, optionally with a colon and - * port number. - */ - char *colon = strrchr(rightbrack, ':'); - - if (colon) { - *host = strndup(str+1, rightbrack-1-str); - *port = strdup(colon+1); - } - else - *host = strndup(str+1, rightbrack-1-str); - } else if (strcount(str, ':') > 1) { - /* An IPv6 address without brackets. Don't make the user surround the - * address with brackets if there's no port number. - */ - *host = strdup(str); - } else { - /* An IPv4 address, optionally with a colon and port number. */ - char *colon = strrchr(str, ':'); - - if (colon) { - *host = strndup(str, colon-str); - *port = strdup(colon+1); - } - else - *host = strdup(str); - } -} - /* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/loader2/net.h b/loader2/net.h index 82a5bf4..4fb8a79 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 -#include #include -#include +#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,34 +45,24 @@ 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 writeNetInfo(const char * fn, iface_t * iface); int nfsGetSetup(char ** hostptr, char ** dirptr); 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); -void splitHostname (char *str, char **host, char **port); + iface_t * iface); +int startNetworkManager(iface_t * iface); #endif diff --git a/loader2/nfsinstall.c b/loader2/nfsinstall.c index 75d5548..166eecf 100644 --- a/loader2/nfsinstall.c +++ b/loader2/nfsinstall.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include "loader.h" #include "lang.h" @@ -390,9 +393,11 @@ int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { char * chk = NULL, *ip = NULL; int failed = 0; int i; - struct networkDeviceConfig netCfg; + iface_t iface; - if (kickstartNetworkUp(loaderData, &netCfg)) { + iface_init_iface_t(&iface); + + if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "unable to bring up network"); return 1; } @@ -401,23 +406,26 @@ int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { * the dhcp/bootp information */ if (url == NULL) { - char ret[47]; - ip_addr_t *tip; - - if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) { + if (iface.nextserver == NULL) { logMessage(ERROR, "no bootserver was found"); return 1; } - tip = &(netCfg.dev.nextServer); - if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) { - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - i = asprintf(&url, "%s:%s", ret, "/kickstart/"); + if (iface.bootfile == NULL) { + if (asprintf(&url, "%s:/kickstart/", iface.nextserver) == -1) { + logMessage(ERROR, "bootp: error generating url"); + return 1; + } + logMessage(ERROR, "bootp: no bootfile received"); } else { - inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); - i = asprintf(&url, "%s:%s", ret, netCfg.dev.bootFile); - logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile); + if (asprintf(&url, "%s:%s", iface.nextserver, + iface.bootfile) == -1) { + logMessage(ERROR, "bootp: error generating url with bootfile"); + return 1; + } + + logMessage(INFO, "bootp: bootfile is %s", iface.bootfile); } } diff --git a/loader2/telnetd.c b/loader2/telnetd.c index d5850f4..99c6feb 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: %s", strerror(errno)); - return -1; + logMessage(ERROR, "socket: %s", strerror(errno)); + return -1; } address.sin_family = AF_INET; @@ -88,18 +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: %s", - strerror(errno)); - 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 @@ -108,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); } @@ -127,87 +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: %s", strerror(errno)); - } + /* 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); @@ -220,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); @@ -235,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 55b7c3d..0b87b8b 100644 --- a/loader2/urlinstall.c +++ b/loader2/urlinstall.c @@ -312,10 +312,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 43006ac..12e56c9 100644 --- a/loader2/urls.c +++ b/loader2/urls.c @@ -245,7 +245,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 719a5b3..24b90a0 100755 --- a/scripts/mk-images +++ b/scripts/mk-images @@ -432,7 +432,6 @@ EOF 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 @@ -513,6 +512,7 @@ makeinitrd() { mkdir -p $MBD_DIR/etc/modprobe.d mkdir -p $MBD_DIR/var/run mkdir -p $MBD_DIR/var/lock/rpm + mkdir -p $MBD_DIR/var/lib/dhclient if [ "$BUILDARCH" = "ppc" -o "$BUILDARCH" = "ppc64" ]; then mkdir -p $MBD_DIR/dev/iseries @@ -569,6 +569,14 @@ makeinitrd() { ln -s udevadm $MBD_DIR/sbin/udevtrigger ln -s udevadm $MBD_DIR/sbin/udevsettle + # DHCP and DHCPv6 client daemons and support programs + instbin $IMGPATH /sbin/dhclient $MBD_DIR /sbin/dhclient + instbin $IMGPATH /sbin/dhclient-script $MBD_DIR /sbin/dhclient-script + instbin $IMGPATH /sbin/dhcp6c $MBD_DIR /sbin/dhcp6c + instbin $IMGPATH /sbin/arping $MBD_DIR /sbin/arping + instbin $IMGPATH /sbin/ifconfig $MBD_DIR /sbin/ifconfig + instbin $IMGPATH /sbin/ip $MBD_DIR /sbin/ip + # 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/ @@ -593,7 +601,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/upd-instroot b/scripts/upd-instroot index 1645aad..5baea32 100755 --- a/scripts/upd-instroot +++ b/scripts/upd-instroot @@ -188,7 +188,7 @@ fi if [ $ARCH = s390 -o $ARCH = s390x ]; then PACKAGES="$PACKAGES s390utils binutils libgcc tcp_wrappers - sed net-tools openssh openssh-server coreutils + sed openssh openssh-server coreutils login initscripts bash portmap pam login mount grep modutils gawk strace xorg-x11-xauth xorg-x11-libs" @@ -235,7 +235,8 @@ PACKAGESGR="anaconda libpng gtk2 libglade2 fonts-ISO8859-2 fonts-ISO8859-9 fonts-malayalam fonts-or