summaryrefslogtreecommitdiffstats
path: root/isys
diff options
context:
space:
mode:
authorDavid Cantrell <dcantrell@redhat.com>2008-08-25 10:19:19 -1000
committerDavid Cantrell <dcantrell@redhat.com>2008-08-25 10:19:19 -1000
commit57e7079052bec83c6aa0bb327b220d1de908d118 (patch)
tree4a4e0a548e489543cdb6152768e8800d43668ddf /isys
parent2be503dd8da94df9979528594bc2a91db5e0cc96 (diff)
downloadanaconda-57e7079052bec83c6aa0bb327b220d1de908d118.tar.gz
anaconda-57e7079052bec83c6aa0bb327b220d1de908d118.tar.xz
anaconda-57e7079052bec83c6aa0bb327b220d1de908d118.zip
Use NetworkManager instead of libdhcp. (#458183)
Finally, no more libdhcp. This is the first set of changes to take anaconda over to the wonderful world of NetworkManager. We are no longer linking with libdhcp to do interface configuration. NM is started early in the installation and opens the door to things like WPA installation support and things like that.
Diffstat (limited to 'isys')
-rw-r--r--isys/Makefile9
-rw-r--r--isys/iface.c366
-rw-r--r--isys/iface.h154
-rw-r--r--isys/isys.c171
-rw-r--r--isys/wireless.c208
-rw-r--r--isys/wireless.h4
6 files changed, 521 insertions, 391 deletions
diff --git a/isys/Makefile b/isys/Makefile
index e4d1de435..e9418573a 100644
--- a/isys/Makefile
+++ b/isys/Makefile
@@ -38,10 +38,6 @@ SUBDIRS =
LOADLIBES += $(shell pkg-config --libs libnl-1)
CFLAGS += $(shell pkg-config --cflags libnl-1)
-# libdhcp
-LOADLIBES += $(shell pkg-config --libs libdhcp)
-CFLAGS += $(shell pkg-config --cflags libdhcp)
-
ifeq ($(ARCH),sparc)
PYMODULES += _silo.so
SOURCES += silo.c
@@ -79,7 +75,6 @@ clean:
rm -f *.o *.so *.lo *.a *.pyc $(TARGET) $(SOBJECTS)
rm -f $(OBJECTS)
rm -f .depend
- rm -f nl
for d in $(SUBDIRS); do make -C $$d clean; done
install: all
@@ -89,10 +84,6 @@ install: all
subdirs:
for d in $(SUBDIRS); do make -C $$d; done
-nltest: str.o nl.c nl.h
- $(CC) -c $(CFLAGS) -DTESTING nl.c -o nl.o
- $(CC) -DTESTING nl.o -o nl $(LOADLIBES) str.o
-
depend:
$(CPP) -M $(CFLAGS) $(SOURCES) > .depend
diff --git a/isys/iface.c b/isys/iface.c
index 6f274bc76..93cef022f 100644
--- a/isys/iface.c
+++ b/isys/iface.c
@@ -1,7 +1,7 @@
/*
- * iface.c - Network interface control functions
+ * iface.c - Network interface configuration API
*
- * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,34 +21,66 @@
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/utsname.h>
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
#include <netinet/in.h>
#include <netlink/netlink.h>
#include <netlink/socket.h>
+#include <netlink/route/rtnl.h>
+#include <netlink/route/route.h>
#include <netlink/route/addr.h>
#include <netlink/route/link.h>
#include "iface.h"
#include "str.h"
+/* Internal-only function prototypes. */
+static struct nl_handle *_iface_get_handle(void);
+static struct nl_cache *_iface_get_link_cache(struct nl_handle **);
+static int _iface_name_to_index(char *);
+static int _iface_have_valid_addr(void *addr, int family, int length);
+static int _iface_redirect_io(char *device, int fd, int mode);
+
/*
- * Return an NETLINK_ROUTE cache.
+ * Return a libnl handle for NETLINK_ROUTE.
*/
-struct nl_cache *iface_get_link_cache(struct nl_handle **handle) {
- struct nl_cache *cache = NULL;
+static struct nl_handle *_iface_get_handle(void) {
+ struct nl_handle *handle = NULL;
- if ((*handle = nl_handle_alloc()) == NULL) {
- perror("nl_handle_alloc() failure in iface_get_link_cache()");
+ if ((handle = nl_handle_alloc()) == NULL) {
return NULL;
}
- if (nl_connect(*handle, NETLINK_ROUTE)) {
- perror("nl_connect() failure in iface_get_link_cache()");
- nl_handle_destroy(*handle);
+ if (nl_connect(handle, NETLINK_ROUTE)) {
+ nl_handle_destroy(handle);
+ return NULL;
+ }
+
+ return handle;
+}
+
+/*
+ * Return an NETLINK_ROUTE cache.
+ */
+static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) {
+ struct nl_cache *cache = NULL;
+
+ if ((*handle = _iface_get_handle()) == NULL) {
return NULL;
}
if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) {
- perror("rtnl_link_alloc_cache() failure in iface_get_link_cache()");
nl_close(*handle);
nl_handle_destroy(*handle);
return NULL;
@@ -58,6 +90,79 @@ struct nl_cache *iface_get_link_cache(struct nl_handle **handle) {
}
/*
+ * Convert an interface name to index number.
+ */
+static int _iface_name_to_index(char *ifname) {
+ struct nl_handle *handle = NULL;
+ struct nl_cache *cache = NULL;
+
+ if (ifname == NULL) {
+ return -1;
+ }
+
+ if ((cache = _iface_get_link_cache(&handle)) == NULL) {
+ return -1;
+ }
+
+ return rtnl_link_name2i(cache, ifname);
+}
+
+/*
+ * Determine if a struct in_addr or struct in6_addr contains a valid address.
+ */
+static int _iface_have_valid_addr(void *addr, int family, int length) {
+ char buf[length+1];
+
+ if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) {
+ return 0;
+ }
+
+ memset(buf, '\0', sizeof(buf));
+
+ if (inet_ntop(family, addr, buf, length) == NULL) {
+ return 0;
+ } else {
+ /* check for unknown addresses */
+ if (family == AF_INET) {
+ if (!strncmp(buf, "0.0.0.0", 7)) {
+ return 0;
+ }
+ } else if (family == AF_INET6) {
+ if (!strncmp(buf, "::", 2)) {
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Redirect I/O to another device (e.g., stdout to /dev/tty5)
+ */
+int _iface_redirect_io(char *device, int fd, int mode) {
+ int io = -1;
+
+ if ((io = open(device, mode)) == -1) {
+ return 1;
+ }
+
+ if (close(fd) == -1) {
+ return 2;
+ }
+
+ if (dup2(io, fd) == -1) {
+ return 3;
+ }
+
+ if (close(io) == -1) {
+ return 4;
+ }
+
+ return 0;
+}
+
+/*
* Given an interface name (e.g., eth0), return the IP address in human
* readable format (i.e., the output from inet_ntop()). Return NULL for
* no match. NOTE: This function will check for IPv6 and IPv4
@@ -74,26 +179,16 @@ char *iface_ip2str(char *ifname) {
struct rtnl_addr *raddr = NULL;
struct nl_addr *addr = NULL;
- if (ifname == NULL) {
- perror("Missing ifname in iface_ip2str()");
- return NULL;
- }
-
- if ((cache = iface_get_link_cache(&handle)) == NULL) {
- perror("iface_get_link_cache() failure in iface_ip2str()");
- return NULL;
+ if ((ifindex = _iface_name_to_index(ifname)) == -1) {
+ goto ip2str_error;
}
- ifindex = rtnl_link_name2i(cache, ifname);
-
if ((cache = rtnl_addr_alloc_cache(handle)) == NULL) {
- perror("rtnl_addr_alloc_cache() failure in iface_ip2str()");
goto ip2str_error;
}
/* find the IPv4 and IPv6 addresses for this interface */
if ((obj = nl_cache_get_first(cache)) == NULL) {
- perror("nl_cache_get_first() failure in iface_ip2str()");
goto ip2str_error;
}
@@ -128,8 +223,7 @@ char *iface_ip2str(char *ifname) {
buflen += 1;
- if ((buf = malloc(buflen)) == NULL) {
- perror("malloc() failure on buf in iface_ip2str()");
+ if ((buf = calloc(sizeof(char *), buflen)) == NULL) {
nl_addr_destroy(addr);
goto ip2str_error;
}
@@ -141,7 +235,6 @@ char *iface_ip2str(char *ifname) {
if ((pos = index(buf, '/')) != NULL) {
*pos = '\0';
if ((buf = realloc(buf, strlen(buf) + 1)) == NULL) {
- perror("realloc() failure on buf in iface_ip2str()");
nl_addr_destroy(addr);
goto ip2str_error;
}
@@ -180,7 +273,7 @@ ip2str_error:
}
}
-/**
+/*
* Given an interface name (e.g., eth0), return the MAC address in human
* readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match.
*/
@@ -193,27 +286,22 @@ char *iface_mac2str(char *ifname) {
struct nl_addr *addr = NULL;
if (ifname == NULL) {
- perror("Missing ifname in iface_mac2str()");
return NULL;
}
- if ((cache = iface_get_link_cache(&handle)) == NULL) {
- perror("iface_get_link_cache() failure in iface_mac2str()");
+ if ((cache = _iface_get_link_cache(&handle)) == NULL) {
return NULL;
}
if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) {
- perror("rtnl_link_get_by_name() failure in iface_mac2str()");
goto mac2str_error2;
}
if ((addr = rtnl_link_get_addr(link)) == NULL) {
- perror("rtnl_link_get_addr() failure in iface_mac2str()");
goto mac2str_error3;
}
- if ((buf = malloc(buflen)) == NULL) {
- perror("malloc() failure on buf in iface_mac2str()");
+ if ((buf = calloc(sizeof(char *), buflen)) == NULL) {
goto mac2str_error4;
}
@@ -233,6 +321,209 @@ mac2str_error2:
}
/*
+ * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on
+ * failure.
+ */
+struct in_addr *iface_prefix2netmask(int prefix) {
+ int mask = 0;
+ char *buf = NULL;
+ struct in_addr *ret;
+
+ if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) {
+ return NULL;
+ }
+
+ mask = htonl(~((1 << (32 - prefix)) - 1));
+
+ if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf,
+ INET_ADDRSTRLEN) == NULL) {
+ return NULL;
+ }
+
+ if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) {
+ return NULL;
+ }
+
+ memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr));
+ return ret;
+}
+
+/*
+ * Convert an IPv4 netmask to an IPv4 CIDR prefix. Return -1 on failure.
+ */
+int iface_netmask2prefix(struct in_addr *netmask) {
+ int ret = -1;
+ struct in_addr mask;
+
+ if (netmask == NULL) {
+ return -1;
+ }
+
+ memcpy(&mask, netmask, sizeof(struct in_addr));
+
+ while (mask.s_addr != 0) {
+ mask.s_addr = mask.s_addr >> 1;
+ ret++;
+ }
+
+ return ret;
+}
+
+/*
+ * Look up the hostname and domain for our assigned IP address. Tries IPv4
+ * first, then IPv6. Returns 0 on success, non-negative on failure.
+ */
+int iface_dns_lookup(iface_t *iface) {
+ char *ch = NULL;
+ struct sockaddr_in sa;
+ struct sockaddr_in6 sa6;
+
+ if ((iface->hostname != NULL) && (iface->domain != NULL)) {
+ return 0;
+ }
+
+ /* make sure our hostname buffer is large enough */
+ if ((iface->hostname = calloc('\0', NI_MAXHOST+1)) == NULL) {
+ return 1;
+ }
+
+ /* try an IPv4 lookup first */
+ if (iface_have_in_addr(&iface->ipaddr)) {
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = iface->ipaddr.s_addr;
+
+ if (getnameinfo((struct sockaddr *) &sa, sizeof(sa), iface->hostname,
+ NI_MAXHOST, NULL, 0, NI_NAMEREQD)) {
+ free(iface->hostname);
+ iface->hostname = NULL;
+ }
+ }
+
+ /* try IPv6 lookup if IPv4 failed */
+ if ((iface->hostname == NULL) && iface_have_in6_addr(&iface->ip6addr)) {
+ memset(&sa6, 0, sizeof(sa6));
+ sa6.sin6_family = AF_INET6;
+ memcpy(&sa6.sin6_addr, &iface->ip6addr, sizeof(iface->ip6addr));
+
+ if (getnameinfo((struct sockaddr *) &sa6, sizeof(sa6), iface->hostname,
+ NI_MAXHOST, NULL, 0, NI_NAMEREQD)) {
+ free(iface->hostname);
+ iface->hostname = NULL;
+ }
+ }
+
+ /* fill in the domain */
+ if ((iface->domain == NULL) && (iface->hostname != NULL)) {
+ for (ch = iface->hostname; *ch && (*ch != '.'); ch++);
+
+ if (*ch == '.') {
+ iface->domain = strdup(ch + 1);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Initialize a new iface_t structure to default values.
+ */
+void iface_init_iface_t(iface_t *iface) {
+ int i;
+
+ memset(&iface->device, '\0', sizeof(iface->device));
+ memset(&iface->ipaddr, 0, sizeof(iface->ipaddr));
+ memset(&iface->netmask, 0, sizeof(iface->netmask));
+ memset(&iface->broadcast, 0, sizeof(iface->broadcast));
+ memset(&iface->ip6addr, 0, sizeof(iface->ip6addr));
+ memset(&iface->gateway, 0, sizeof(iface->gateway));
+ memset(&iface->gateway6, 0, sizeof(iface->gateway6));
+
+ for (i = 0; i < MAXNS; i++) {
+ iface->dns[i] = NULL;
+ }
+
+ iface->macaddr = NULL;
+ iface->ip6prefix = 0;
+ iface->nextserver = NULL;
+ iface->bootfile = NULL;
+ iface->numdns = 0;
+ iface->hostname = NULL;
+ iface->domain = NULL;
+ iface->search = NULL;
+ iface->dhcptimeout = 0;
+ iface->vendorclass = NULL;
+ iface->ssid = NULL;
+ iface->wepkey = NULL;
+ iface->mtu = 0;
+ iface->subchannels = NULL;
+ iface->portname = NULL;
+ iface->peerid = NULL;
+ iface->nettype = NULL;
+ iface->ctcprot = NULL;
+ iface->flags = 0;
+ iface->ipv4method = IPV4_UNUSED_METHOD;
+ iface->ipv6method = IPV6_UNUSED_METHOD;
+
+ return;
+}
+
+/*
+ * Given a pointer to a struct in_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in_addr(struct in_addr *addr) {
+ return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN);
+}
+
+/*
+ * Given a pointer to a struct in6_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in6_addr(struct in6_addr *addr6) {
+ return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN);
+}
+
+/*
+ * Start NetworkManager -- requires that you have already written out the
+ * control files in /etc/sysconfig for the interface.
+ */
+int iface_start_NetworkManager(iface_t *iface) {
+ int status;
+ pid_t pid;
+
+ /* Start NetworkManager */
+ pid = fork();
+ if (pid == 0) {
+ if (setpgrp() == -1) {
+ exit(1);
+ }
+
+ if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) ||
+ _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) ||
+ _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, O_WRONLY)) {
+ exit(2);
+ }
+
+ if (execl(NETWORKMANAGER, NETWORKMANAGER,
+ "--pid-file=/var/run/NetworkManager/NetworkManager.pid",
+ NULL) == -1) {
+ exit(3);
+ } else {
+ exit(0);
+ }
+ } else if (pid == -1) {
+ return 1;
+ } else {
+ if (waitpid(pid, &status, 0) == -1) {
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+/*
* Set the MTU on the specified device.
*/
int iface_set_interface_mtu(char *ifname, int mtu) {
@@ -243,22 +534,18 @@ int iface_set_interface_mtu(char *ifname, int mtu) {
struct rtnl_link *request = NULL;
if (ifname == NULL) {
- perror("Missing ifname in iface_set_interface_mtu()");
return -1;
}
if (mtu <= 0) {
- perror("MTU cannot be <= 0 in iface_set_interface_mtu()");
return -2;
}
- if ((cache = iface_get_link_cache(&handle)) == NULL) {
- perror("iface_get_link_cache() failure in iface_set_interface_mtu()");
+ if ((cache = _iface_get_link_cache(&handle)) == NULL) {
return -3;
}
if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) {
- perror("rtnl_link_get_by_name() failure in iface_set_interface_mtu()");
ret = -4;
goto ifacemtu_error1;
}
@@ -267,7 +554,6 @@ int iface_set_interface_mtu(char *ifname, int mtu) {
rtnl_link_set_mtu(request, mtu);
if (rtnl_link_change(handle, link, request, 0)) {
- perror("rtnl_link_change() failure in iface_set_interface_mtu()");
ret = -5;
goto ifacemtu_error2;
}
diff --git a/isys/iface.h b/isys/iface.h
index 4b0e50f2d..03cffee4e 100644
--- a/isys/iface.h
+++ b/isys/iface.h
@@ -1,7 +1,7 @@
/*
- * iface.h
+ * iface.h - Network interface configuration API
*
- * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,11 +19,155 @@
* Author(s): David Cantrell <dcantrell@redhat.com>
*/
+#ifndef ISYSIFACE_H
+#define ISYSIFACE_H
+
+#include <resolv.h>
+#include <net/if.h>
#include <netlink/cache.h>
#include <netlink/socket.h>
+/* Enumerated types used in iface.c as well as loader's network code */
+enum { IPUNUSED, IPV4, IPV6 };
+
+enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD };
+enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD,
+ IPV6_MANUAL_METHOD };
+
+#define IPV4_FIRST_METHOD IPV4_DHCP_METHOD
+#define IPV4_LAST_METHOD IPV4_MANUAL_METHOD
+
+#define IPV6_FIRST_METHOD IPV6_AUTO_METHOD
+#define IPV6_LAST_METHOD IPV6_MANUAL_METHOD
+
+/* Flags for the iface_t */
+#define IFACE_FLAGS_NO_WRITE_RESOLV_CONF (((uint64_t) 1) << 0)
+/* FIXME: do we need these? */
+#define IFACE_FLAGS_IS_PRESET (((uint64_t) 1) << 1)
+#define IFACE_FLAGS_IS_DYNAMIC (((uint64_t) 1) << 2)
+
+#define IFACE_NO_WRITE_RESOLV_CONF(a) ((a) & IFACE_FLAGS_NO_WRITE_RESOLV_CONF)
+#define IFACE_IS_PRESET(a) ((a) & IFACE_FLAGS_IS_PRESET)
+#define IFACE_IS_DYNAMIC(a) ((a) & IFACE_FLAGS_IS_DYNAMIC)
+
+/* Macros for starting NetworkManager */
+#define NETWORKMANAGER "/usr/sbin/NetworkManager"
+#define OUTPUT_TERMINAL "/dev/tty5"
+
+/* Per-interface configuration information */
+typedef struct _iface_t {
+ /* device name (e.g., eth0) */
+ char device[IF_NAMESIZE];
+
+ /* MAC address as xx:xx:xx:xx:xx:xx */
+ char *macaddr;
+
+ /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */
+ struct in_addr ipaddr;
+ struct in_addr netmask;
+ struct in_addr broadcast;
+
+ /* IPv6 (store addresses in in6_addr format, prefix is just an int) */
+ struct in6_addr ip6addr;
+ int ip6prefix;
+
+ /* Gateway settings */
+ struct in_addr gateway;
+ struct in6_addr gateway6;
+
+ /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */
+ char *nextserver;
+ char *bootfile;
+
+ /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */
+ char *dns[MAXNS];
+ int numdns;
+ char *hostname;
+ char *domain;
+ char *search;
+
+ /* Misc DHCP settings */
+ int dhcptimeout;
+ char *vendorclass;
+
+ /* Wireless settings */
+ char *ssid;
+ char *wepkey;
+
+ /* s390 specifics */
+ int mtu;
+ char *subchannels;
+ char *portname;
+ char *peerid;
+ char *nettype;
+ char *ctcprot;
+
+ /* flags */
+ uint64_t flags;
+ int ipv4method;
+ int ipv6method;
+} iface_t;
+
/* Function prototypes */
-struct nl_cache *iface_get_link_cache(struct nl_handle **handle);
-char *iface_mac2str(char *ifname);
-char *iface_ip2str(char *ifname);
+
+/*
+ * Given an interface name (e.g., eth0), return the IP address in human
+ * readable format (i.e., the output from inet_ntop()). Return NULL for
+ * no match. NOTE: This function will check for IPv6 and IPv4
+ * addresses. In the case where the interface has both, the IPv4 address
+ * is returned. The only way you will get an IPv6 address from this function
+ * is if that's the only address configured for the interface.
+ */
+char *iface_ip2str(char *);
+
+/*
+ * Given an interface name (e.g., eth0), return the MAC address in human
+ * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match.
+ */
+char *iface_mac2str(char *);
+
+/*
+ * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on
+ * failure.
+ */
+struct in_addr *iface_prefix2netmask(int);
+
+/*
+ * Convert an IPv4 netmask to an IPv4 CIDR prefix. Return -1 on failure.
+ */
+int iface_netmask2prefix(struct in_addr *);
+
+/*
+ * Look up the hostname and domain for our assigned IP address. Tries IPv4
+ * first, then IPv6. Returns 0 on success, non-negative on failure.
+ */
+int iface_dns_lookup(iface_t *);
+
+/*
+ * Initialize a new iface_t structure to default values.
+ */
+void iface_init_iface_t(iface_t *);
+
+/*
+ * Given a pointer to a struct in_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in_addr(struct in_addr *addr);
+
+/*
+ * Given a pointer to a struct in6_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in6_addr(struct in6_addr *addr6);
+
+/*
+ * Start NetworkManager
+ */
+int iface_start_NetworkManager(iface_t *iface);
+
+/*
+ * Set Maximum Transfer Unit (MTU) on specified interface
+ */
int iface_set_interface_mtu(char *ifname, int mtu);
+
+#endif /* ISYSIFACE_H */
diff --git a/isys/isys.c b/isys/isys.c
index 298049711..32b7ef162 100644
--- a/isys/isys.c
+++ b/isys/isys.c
@@ -53,6 +53,8 @@
#include <scsi/scsi_ioctl.h>
#include <sys/vt.h>
#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
#include <linux/fb.h>
#include <libintl.h>
#ifdef USESELINUX
@@ -65,9 +67,6 @@
#include <signal.h>
#include <execinfo.h>
-#include <libdhcp/ip_addr.h>
-#include <libdhcp/pump.h>
-
#include <blkid/blkid.h>
#include <X11/Xlib.h>
@@ -83,6 +82,7 @@
#include "wireless.h"
#include "eddsupport.h"
#include "auditd.h"
+#include "imount.h"
#ifndef CDROMEJECT
#define CDROMEJECT 0x5309
@@ -523,162 +523,83 @@ void init_isys(void) {
static PyObject * doConfigNetDevice(PyObject * s, PyObject * args) {
int i = 0;
- char *dev, *ipv4, *netmask, *ipv6, *prefix, *gateway;
- struct pumpNetIntf cfg;
- struct in_addr addr, nm, nw;
- struct in6_addr addr6;
+ char *dev, *ipv4, *netmask, *ipv6, *prefix, *gateway, *gateway6, *ep;
+ iface_t iface;
+ struct in_addr tmpaddr;
if (!PyArg_ParseTuple(args, "ssssss", &dev, &ipv4, &netmask,
- &ipv6, &prefix, &gateway))
+ &ipv6, &prefix, &gateway, &gateway6))
return NULL;
- memset(&cfg, '\0', sizeof(struct pumpNetIntf));
- strncpy(cfg.device, dev, sizeof(cfg.device) - 1);
+ memset(&iface, '\0', sizeof(iface_t));
+ strncpy(iface.device, dev, sizeof(iface.device) - 1);
/* IPv4 */
- if (inet_pton(AF_INET, ipv4, &addr) >= 1) {
- cfg.ipv4 = ip_addr_in(&addr);
-
- if (inet_pton(AF_INET, netmask, &nm) >= 1) {
- cfg.netmask = ip_addr_in(&nm);
-
- /* we have IP and netmask, calculate network and broadcast */
- cfg.network = ip_addr_v4(ntohl((addr.s_addr) & nm.s_addr));
- nw = ip_in_addr(&cfg.network);
- cfg.broadcast = ip_addr_v4(ntohl(nw.s_addr | ~nm.s_addr));
+ if (inet_pton(AF_INET, ipv4, &iface.ipaddr) >= 1) {
+ if (inet_pton(AF_INET, netmask, &iface.netmask) >= 1) {
+ /* we have IP and netmask, calculate broadcast */
+ memset(&tmpaddr, 0, sizeof(tmpaddr));
+ tmpaddr.s_addr = iface.ipaddr.s_addr & iface.netmask.s_addr;
+ iface.broadcast.s_addr = tmpaddr.s_addr | ~iface.netmask.s_addr;
}
}
/* IPv6 */
- if (inet_pton(AF_INET6, ipv6, &addr6) >= 1) {
- cfg.ipv6 = ip_addr_in6(&addr6);
-
+ if (inet_pton(AF_INET6, ipv6, &iface.ip6addr) >= 1) {
if (strlen(prefix)) {
- errno = 0;
- i = strtol(prefix, NULL, 10);
-
- if ((errno == ERANGE && (i == LONG_MIN || i == LONG_MAX)) ||
- (errno != 0 && i == 0)) {
- return NULL;
- }
-
+ i = strtol(prefix, &ep, 10);
if (i > 0 && i <= 128) {
- cfg.ipv6_prefixlen = i;
+ iface.ip6prefix = i;
}
}
}
- /* Global */
+ /* Gateways */
if (strlen(gateway)) {
- if (inet_pton(AF_INET, gateway, &addr) >= 1) {
- cfg.gateway = ip_addr_in(&addr);
- } else if (inet_pton(AF_INET6, gateway, &addr6) >= 1) {
- cfg.gateway = ip_addr_in6(&addr6);
+ if (inet_pton(AF_INET, gateway, &iface.gateway) <= 0) {
+ PyErr_SetFromErrno(PyExc_SystemError);
+ return NULL;
}
}
- if (pumpSetupInterface(&cfg)) {
+ if (strlen(gateway6)) {
+ if (inet_pton(AF_INET6, gateway6, &iface.gateway6) <= 0) {
+ PyErr_SetFromErrno(PyExc_SystemError);
+ return NULL;
+ }
+ }
+
+ /* Bring up the interface */
+/*
+ if (iface_config(&iface)) {
PyErr_SetFromErrno(PyExc_SystemError);
return NULL;
}
+*/
Py_INCREF(Py_None);
return Py_None;
}
-void pumplogger(void *arg, int priority, char *fmt, va_list va) {
- libdhcp_syslogger(0, priority, fmt, va);
-}
-
static PyObject * doDhcpNetDevice(PyObject * s, PyObject * args) {
- char *device = NULL, *r = NULL;
- char *ipv4method = NULL, *ipv6method = NULL, *dhcpclass = NULL;
- int useipv4, useipv6;
- char buf[47];
- time_t timeout = 45;
- struct pumpNetIntf cfg;
- struct utsname kv;
- DHCP_Preference pref = 0;
- ip_addr_t *tip;
- PyObject * rc;
-
- if (!PyArg_ParseTuple(args, "sisis|s", &device, &useipv4, &ipv4method, &useipv6, &ipv6method, &dhcpclass))
- return NULL;
-
- /* if we lack a user-provided dhcpclass, construct the default */
- if ((dhcpclass == NULL) || (strlen(dhcpclass) == 0)) {
- if (uname(&kv) == -1) {
- dhcpclass = "anaconda";
- } else {
- if (asprintf(&dhcpclass, "anaconda-%s %s %s",
- kv.sysname, kv.release, kv.machine) == -1) {
- fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
- strerror(errno));
- fflush(stderr);
- abort();
- }
- }
- }
-
- memset(&cfg, '\0', sizeof(cfg));
- strcpy(cfg.device, device);
-
- /* disable DHCPv4 is user selected manual IPv4 or didn't select IPv4 */
- if (useipv4 && strlen(ipv4method) > 0) {
- if (!strncmp(ipv4method, "manual", 6)) {
- /* IPv4 disabled entirely -or- manual IPv4 config selected */
- pref |= DHCPv4_DISABLE;
- }
- } else if (!useipv4 && strlen(ipv4method) == 0) {
- pref |= DHCPv4_DISABLE;
- }
-
- /* set appropriate IPv6 configuration method */
- if (strlen(ipv6method) > 0) {
- if ((!useipv6 && !strncmp(ipv6method, "auto", 4)) ||
- (useipv6 && !strncmp(ipv6method, "manual", 6))) {
- pref |= DHCPv6_DISABLE | DHCPv6_DISABLE_ADDRESSES;
- }
- } else if (strlen(ipv6method) == 0 && !useipv6) {
- pref |= DHCPv6_DISABLE | DHCPv6_DISABLE_ADDRESSES;
- }
-
- pref |= DHCPv6_DISABLE_RESOLVER | DHCPv4_DISABLE_HOSTNAME_SET;
-
- if (!(pref & DHCPv4_DISABLE) || !(pref & DHCPv6_DISABLE)) {
- r = pumpDhcpClassRun(&cfg, NULL, dhcpclass, pref, 0, timeout,
- pumplogger, LOG_ERR);
- if (r) {
- Py_INCREF(Py_None);
- return Py_None;
- } else {
- if (pumpSetupInterface(&cfg)) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- }
- }
-
- if (cfg.numDns) {
- tip = &(cfg.dnsServers[0]);
- inet_ntop(tip->sa_family, IP_ADDR(tip), buf, IP_STRLEN(tip));
- rc = PyString_FromString(buf);
- } else {
- rc = PyString_FromString("");
- }
-
- return rc;
+ /* function returns a nameserver address to the caller */
+ /* FIXME: needs to use NetworkManager --dcantrell */
+ return PyString_FromString("");
}
static PyObject * doPrefixToNetmask (PyObject * s, PyObject * args) {
- int prefix = 0;
- int mask = 0;
- char dst[INET_ADDRSTRLEN];
+ int prefix = 0;
+ struct in_addr *mask = NULL;
+ char dst[INET_ADDRSTRLEN+1];
- if (!PyArg_ParseTuple(args, "i", &prefix)) return NULL;
+ if (!PyArg_ParseTuple(args, "i", &prefix))
+ return NULL;
+
+ if ((mask = iface_prefix2netmask(prefix)) == NULL)
+ return NULL;
- mask = htonl(~((1 << (32 - prefix)) - 1));
- inet_ntop(AF_INET, (struct in_addr *) &mask, dst, INET_ADDRSTRLEN);
+ if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL)
+ return NULL;
return Py_BuildValue("s", dst);
}
diff --git a/isys/wireless.c b/isys/wireless.c
index aa13b1198..6ede034b2 100644
--- a/isys/wireless.c
+++ b/isys/wireless.c
@@ -69,211 +69,3 @@ int is_wireless_interface(char * ifname) {
return 1;
}
-
-/* set the essid for ifname to essid. if essid is NULL, do automatically */
-int set_essid(char * ifname, char * essid) {
- int sock;
- struct iwreq wreq;
-
- memset(&wreq, 0, sizeof (wreq));
-
- if (strlen(essid) > IW_ESSID_MAX_SIZE) {
- fprintf(stderr, "essid too long\n");
- return -1;
- }
-
- sock = get_socket();
- wreq = get_wreq(ifname);
-
- if (essid) {
- wreq.u.essid.flags = 1;
- wreq.u.essid.pointer = (caddr_t) essid;
- wreq.u.essid.length = strlen(essid) + 1;
- } else {
- wreq.u.essid.flags = 0;
- wreq.u.essid.pointer = (caddr_t) NULL;
- wreq.u.essid.length = 0;
- }
-
- int rc = ioctl(sock, SIOCSIWESSID, &wreq);
- close(sock);
-
- if (rc < 0) {
- fprintf(stderr, "failed to set essid: %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-char * get_essid(char * ifname) {
- int sock;
- struct iwreq wreq;
-
- memset(&wreq, 0, sizeof (wreq));
-
- sock = get_socket();
- wreq = get_wreq(ifname);
-
- wreq.u.essid.pointer = (caddr_t) malloc(IW_ESSID_MAX_SIZE + 1);
- wreq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
- wreq.u.essid.flags = 0;
- int rc = ioctl(sock, SIOCGIWESSID, &wreq);
- close(sock);
-
- if (rc < 0) {
- fprintf(stderr, "failed to get essid for %s: %s\n", ifname,
- strerror(errno));
- return NULL;
- }
-
- return wreq.u.essid.pointer;
-}
-
-/* based off iw_in_key from wireless-tools/iwlib.c */
-static int parse_wep_key(char * in, unsigned char * key) {
- int len = 0;
-
- if (!strncmp(in, "s:", 2)) {
- /* the key is a string */
- len = strlen(in + 2);
- memmove(key, in + 2, len);
- } else {
- char *buff, *hex, *out, *p;
-
- /* hexadecimal digits, straight from iwlib.c */
- buff = malloc(IW_ENCODING_TOKEN_MAX + strlen(in) + 1);
- if(buff == NULL) {
- fprintf(stderr, "Malloc failed (string too long ?)\n");
- return(-1);
- }
- /* Preserve original buffers (both in & out) */
- hex = buff + IW_ENCODING_TOKEN_MAX;
- strcpy(hex, in);
- out = buff;
- /* Parse */
- p = strtok(hex, "-:;.,");
- while((p != (char *) NULL) && (len < IW_ENCODING_TOKEN_MAX)) {
- int temph, templ, count, l;
-
- /* Get each char separatly (and not by two) so that we don't
- * get confused by 'enc' (=> '0E'+'0C') and similar */
- count = sscanf(p, "%1X%1X", &temph, &templ);
- if(count < 1)
- return(-1); /* Error -> non-hex char */
- /* Fixup odd strings such as '123' is '01'+'23' and not '12'+'03'*/
- l = strlen(p);
- if(l % 2)
- count = 1;
- /* Put back two chars as one byte */
- if(count == 2)
- templ |= temph << 4;
- else
- templ = temph;
- out[len++] = (unsigned char) (templ & 0xFF);
- /* Check where to get next char from */
- if(l > count) /* Token not finished yet */
- p += count;
- else
- p = strtok((char *) NULL, "-:;.,");
- }
- memcpy(key, out, len);
- free(buff);
- }
-
- return len;
-}
-
-int set_wep_key(char * ifname, char * key) {
- int sock;
- struct iwreq wreq;
- unsigned char thekey[IW_ENCODING_TOKEN_MAX];
-
- if (strlen(key) > IW_ENCODING_TOKEN_MAX) {
- fprintf(stderr, "wep key too long\n");
- return -1;
- }
-
- sock = get_socket();
- wreq = get_wreq(ifname);
-
- if (key) {
- int len = parse_wep_key(key, thekey);
- if (len > 0) {
- wreq.u.data.flags = IW_ENCODE_ENABLED;
- wreq.u.data.length = len;
- wreq.u.data.pointer = (caddr_t) thekey;
- }
- } else {
- wreq.u.data.flags = IW_ENCODE_DISABLED;
- wreq.u.data.pointer = (caddr_t) NULL;
- wreq.u.data.length = 0;
- }
-
- int rc = ioctl(sock, SIOCSIWENCODE, &wreq);
- close(sock);
-
- if (rc < 0) {
- fprintf(stderr, "failed to set wep key: %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-enum { MODE_AUTO, MODE_ADHOC, MODE_MANAGED, MODE_MASTER, MODE_REPEATER,
- MODE_SECONDARY, MODE_MONITOR };
-
-int set_managed(char * ifname) {
- int sock = get_socket();
- struct iwreq wreq = get_wreq(ifname);
-
- wreq.u.mode = MODE_MANAGED;
- int rc = ioctl(sock, SIOCSIWMODE, &wreq);
- close(sock);
-
- if (rc < 0) {
- fprintf(stderr, "failed to set managed mode: %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-#ifdef STANDALONE
-int main(int argc, char **argv) {
- if (argc < 4) {
- fprintf(stderr, "Usage: %s [interface] [essid] [key]\n", argv[0]);
- exit(1);
- }
-
- if (!is_wireless_interface(argv[1])) {
- fprintf(stderr, "%s isn't a wireless interface!\n", argv[1]);
- exit(2);
- }
-
- /* if (set_essid(argv[1], NULL) < 0) {
- fprintf(stderr, "Unable to set essid to %s\n", argv[2]);
- exit(3);
- }
- exit(0);*/
-
- if (set_essid(argv[1], argv[2]) < 0) {
- fprintf(stderr, "Unable to set essid to %s\n", argv[2]);
- exit(3);
- }
-
- /* if (set_wep_key(argv[1], NULL) < 0) {
- fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]);
- exit(4);
- }
- exit(0);*/
-
- if (set_wep_key(argv[1], argv[3]) < 0) {
- fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]);
- exit(4);
- }
-
- return 0;
-}
-#endif
diff --git a/isys/wireless.h b/isys/wireless.h
index 82cb4d4ce..d7ba8be03 100644
--- a/isys/wireless.h
+++ b/isys/wireless.h
@@ -21,9 +21,5 @@
#define WIRELESS_H
int is_wireless_interface(char * ifname);
-int set_essid(char * ifname, char * essid);
-char * get_essid(char * ifname);
-int set_wep_key(char * ifname, char * key);
-int set_managed(char * ifname);
#endif