diff --git a/ChangeLog b/ChangeLog index f9076b1448..bdd9329079 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-03-27 Jürg Billeter + + * configure.in: + * initscript/Makefile.am: + * initscript/paldo/Makefile.am: + * initscript/paldo/NetworkManager.in: + * initscript/paldo/NetworkManagerDispatcher.in: + * src/backends/Makefile.am: + * src/backends/NetworkManagerPaldo.c: + - Add paldo support + 2006-03-27 Dan Williams Patch from Christian Persch diff --git a/configure.in b/configure.in index efbb8ead9b..7aac0b6041 100644 --- a/configure.in +++ b/configure.in @@ -44,7 +44,7 @@ ALL_LINGUAS="bg bs ca cs da de el en_CA es fi fr gu hr hu it ja ko lt nb ne nl p AC_PROG_INTLTOOL([0.27.2]) AM_GLIB_GNU_GETTEXT -AC_ARG_WITH(distro, AC_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, suse, gentoo, debian, arch or slackware])) +AC_ARG_WITH(distro, AC_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, suse, gentoo, debian, arch, slackware or paldo])) if test "z$with_distro" = "z"; then AC_CHECK_FILE(/etc/redhat-release,with_distro="redhat") AC_CHECK_FILE(/etc/SuSE-release,with_distro="suse") @@ -53,6 +53,9 @@ if test "z$with_distro" = "z"; then AC_CHECK_FILE(/etc/debian_version,with_distro="debian") AC_CHECK_FILE(/etc/arch-release,with_distro="arch") AC_CHECK_FILE(/etc/slackware-version,with_distro="slackware") + if test "z$with_distro" = "z"; then + with_distro=`lsb_release -is` + fi fi with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' ` @@ -61,7 +64,7 @@ if test "z$with_distro" = "z"; then exit 1 else case $with_distro in - redhat|suse|gentoo|debian|slackware|arch) ;; + redhat|suse|gentoo|debian|slackware|arch|paldo) ;; *) echo "Your distribution (${with_distro}) is not yet supported! (patches welcome)" exit 1 @@ -74,6 +77,7 @@ AM_CONDITIONAL(TARGET_GENTOO, test x"$with_distro" = xgentoo) AM_CONDITIONAL(TARGET_DEBIAN, test x"$with_distro" = xdebian) AM_CONDITIONAL(TARGET_SLACKWARE, test x"$with_distro" = xslackware) AM_CONDITIONAL(TARGET_ARCH, test x"$with_distro" = xarch) +AM_CONDITIONAL(TARGET_PALDO, test x"$with_distro" = xpaldo) AC_MSG_CHECKING([for wireless-tools >= 28pre9]) AC_TRY_COMPILE([#include ], @@ -343,6 +347,9 @@ initscript/SUSE/networkmanager-dispatcher initscript/Arch/Makefile initscript/Arch/networkmanager initscript/Arch/networkmanager-dispatcher +initscript/paldo/Makefile +initscript/paldo/NetworkManager +initscript/paldo/NetworkManagerDispatcher man/Makefile man/NetworkManager.1 man/NetworkManagerDispatcher.1 diff --git a/initscript/Makefile.am b/initscript/Makefile.am index e5ee9a1198..be662e9d82 100644 --- a/initscript/Makefile.am +++ b/initscript/Makefile.am @@ -17,3 +17,6 @@ endif if TARGET_ARCH SUBDIRS += Arch endif +if TARGET_PALDO +SUBDIRS += paldo +endif diff --git a/initscript/paldo/Makefile.am b/initscript/paldo/Makefile.am new file mode 100644 index 0000000000..2f965bb367 --- /dev/null +++ b/initscript/paldo/Makefile.am @@ -0,0 +1,5 @@ +EXTRA_DIST = NetworkManager NetworkManagerDispatcher + +initddir = $(sysconfdir)/init.d +initd_SCRIPTS = NetworkManager NetworkManagerDispatcher + diff --git a/initscript/paldo/NetworkManager.in b/initscript/paldo/NetworkManager.in new file mode 100644 index 0000000000..8f3cc5c6b5 --- /dev/null +++ b/initscript/paldo/NetworkManager.in @@ -0,0 +1,53 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: NetworkManager +# Required-Start: $network dbus dhcdbd +# Required-Stop: $network dbus dhcdbd +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +### END INIT INFO +. /lib/lsb/init-functions + +prefix=@prefix@ +exec_prefix=@prefix@ +sbindir=@sbindir@ + +case "$1" in + start) + echo -n "Starting NetworkManager..." + if start_daemon $sbindir/NetworkManager + then + log_success_msg + else + log_failure_msg + fi + ;; + stop) + echo -n "Stopping NetworkManager..." + if killproc $sbindir/NetworkManager + then + log_success_msg "." + else + log_failure_msg + fi + ;; + restart|force-reload) + $0 stop + sleep 1 + $0 start + ;; + try-restart) + if pidofproc $sbindir/NetworkManager + then + $0 restart + fi + ;; + status) + pidofproc $sbindir/NetworkManager + exit $? + ;; + *) + echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" + exit 1 + ;; +esac diff --git a/initscript/paldo/NetworkManagerDispatcher.in b/initscript/paldo/NetworkManagerDispatcher.in new file mode 100644 index 0000000000..fa567ea788 --- /dev/null +++ b/initscript/paldo/NetworkManagerDispatcher.in @@ -0,0 +1,53 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: NetworkManagerDispatcher +# Required-Start: $network dbus +# Required-Stop: $network dbus +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +### END INIT INFO +. /lib/lsb/init-functions + +prefix=@prefix@ +exec_prefix=@prefix@ +sbindir=@sbindir@ + +case "$1" in + start) + echo -n "Starting NetworkManagerDispatcher..." + if start_daemon $sbindir/NetworkManagerDispatcher + then + log_success_msg + else + log_failure_msg + fi + ;; + stop) + echo -n "Stopping NetworkManagerDispatcher..." + if killproc $sbindir/NetworkManagerDispatcher + then + log_success_msg "." + else + log_failure_msg + fi + ;; + restart|force-reload) + $0 stop + sleep 1 + $0 start + ;; + try-restart) + if pidofproc $sbindir/NetworkManagerDispatcher + then + $0 restart + fi + ;; + status) + pidofproc $sbindir/NetworkManagerDispatcher + exit $? + ;; + *) + echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" + exit 1 + ;; +esac diff --git a/src/backends/Makefile.am b/src/backends/Makefile.am index da5de20595..67a3e55f58 100644 --- a/src/backends/Makefile.am +++ b/src/backends/Makefile.am @@ -42,6 +42,10 @@ if TARGET_ARCH libnmbackend_la_SOURCES += NetworkManagerArch.c endif +if TARGET_PALDO +libnmbackend_la_SOURCES += NetworkManagerPaldo.c +endif + libnmbackend_la_LIBADD = $(DBUS_LIBS) $(GTHREAD_LIBS) libnmbackend_la_CPPFLAGS = $(DBUS_CFLAGS) \ $(GTHREAD_CFLAGS) \ diff --git a/src/backends/NetworkManagerPaldo.c b/src/backends/NetworkManagerPaldo.c new file mode 100644 index 0000000000..e52ca9f980 --- /dev/null +++ b/src/backends/NetworkManagerPaldo.c @@ -0,0 +1,661 @@ +/* NetworkManager -- Network link manager + * + * Jürg Billeter + * + * Heavily based on NetworkManagerRedhat.c by Dan Williams + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2006 Jürg Billeter + */ + +#include +#include +#include +#include +#include +#include "NetworkManagerSystem.h" +#include "NetworkManagerUtils.h" +#include "nm-device.h" +#include "nm-device-802-3-ethernet.h" +#include "nm-device-802-11-wireless.h" + +/* + * nm_system_init + * + * Initializes the distribution-specific system backend + * + */ +void nm_system_init (void) +{ +} + + +/* + * nm_system_device_flush_routes + * + * Flush all routes associated with a network device + * + */ +void nm_system_device_flush_routes (NMDevice *dev) +{ + g_return_if_fail (dev != NULL); + + /* Not really applicable for test devices */ + if (nm_device_is_test_device (dev)) + return; + + nm_system_device_flush_routes_with_iface (nm_device_get_iface (dev)); +} + + +/* + * nm_system_device_flush_routes_with_iface + * + * Flush all routes associated with a network device + * + */ +void nm_system_device_flush_routes_with_iface (const char *iface) +{ + char *buf; + + g_return_if_fail (iface != NULL); + + /* Remove routing table entries */ + buf = g_strdup_printf ("/sbin/ip route flush dev %s", iface); + nm_spawn_process (buf); + g_free (buf); +} + + +/* + * nm_system_device_add_default_route_via_device + * + * Add default route to the given device + * + */ +void nm_system_device_add_default_route_via_device (NMDevice *dev) +{ + g_return_if_fail (dev != NULL); + + /* Not really applicable for test devices */ + if (nm_device_is_test_device (dev)) + return; + + nm_system_device_add_default_route_via_device_with_iface (nm_device_get_iface (dev)); +} + + +/* + * nm_system_device_add_default_route_via_device_with_iface + * + * Add default route to the given device + * + */ +void nm_system_device_add_default_route_via_device_with_iface (const char *iface) +{ + char *buf; + + g_return_if_fail (iface != NULL); + + /* Add default gateway */ + buf = g_strdup_printf ("/sbin/ip route add default dev %s", iface); + nm_spawn_process (buf); + g_free (buf); +} + + +/* + * nm_system_device_add_route_via_device_with_iface + * + * Add route to the given device + * + */ +void nm_system_device_add_route_via_device_with_iface (const char *iface, const char *route) +{ + char *buf; + + g_return_if_fail (iface != NULL); + + /* Add default gateway */ + buf = g_strdup_printf ("/sbin/ip route add %s dev %s", route, iface); + nm_spawn_process (buf); + g_free (buf); +} + + +/* + * nm_system_device_has_active_routes + * + * Find out whether the specified device has any routes in the routing + * table. + * + */ +gboolean nm_system_device_has_active_routes (NMDevice *dev) +{ + return (FALSE); +} + + +/* + * nm_system_device_flush_addresses + * + * Flush all network addresses associated with a network device + * + */ +void nm_system_device_flush_addresses (NMDevice *dev) +{ + g_return_if_fail (dev != NULL); + + /* Not really applicable for test devices */ + if (nm_device_is_test_device (dev)) + return; + + nm_system_device_flush_addresses_with_iface (nm_device_get_iface (dev)); +} + + +/* + * nm_system_device_flush_addresses_with_iface + * + * Flush all network addresses associated with a network device + * + */ +void nm_system_device_flush_addresses_with_iface (const char *iface) +{ + char *buf; + + g_return_if_fail (iface != NULL); + + /* Remove all IP addresses for a device */ + buf = g_strdup_printf ("/sbin/ip addr flush dev %s", iface); + nm_spawn_process (buf); + g_free (buf); +} + + +/* + * nm_system_enable_loopback + * + * Bring up the loopback interface + * + */ +void nm_system_enable_loopback (void) +{ + nm_spawn_process ("/sbin/ip link set dev lo up"); + nm_spawn_process ("/sbin/ip addr add 127.0.0.1/8 brd 127.255.255.255 dev lo scope host label loopback"); +} + + +/* + * nm_system_flush_loopback_routes + * + * Flush all routes associated with the loopback device, because it + * sometimes gets the first route for ZeroConf/Link-Local traffic. + * + */ +void nm_system_flush_loopback_routes (void) +{ + /* Remove routing table entries for lo */ + nm_spawn_process ("/sbin/ip route flush dev lo"); +} + + +/* + * nm_system_delete_default_route + * + * Remove the old default route in preparation for a new one + * + */ +void nm_system_delete_default_route (void) +{ + nm_spawn_process ("/sbin/ip route del default"); +} + + +/* + * nm_system_flush_arp_cache + * + * Flush all entries in the arp cache. + * + */ +void nm_system_flush_arp_cache (void) +{ + nm_spawn_process ("/sbin/ip neigh flush all"); +} + + +/* + * nm_system_kill_all_dhcp_daemons + * + * Kill all DHCP daemons currently running, done at startup. + * + */ +void nm_system_kill_all_dhcp_daemons (void) +{ +} + + +/* + * nm_system_update_dns + * + * Invalidate the nscd host cache, if it exists, since + * we changed resolv.conf. + * + */ +void nm_system_update_dns (void) +{ +} + + +/* + * nm_system_restart_mdns_responder + * + * Restart the multicast DNS responder so that it knows about new + * network interfaces and IP addresses. + * + */ +void nm_system_restart_mdns_responder (void) +{ + nm_spawn_process("/etc/init.d/avahi-daemon try-restart"); +} + + +/* + * nm_system_device_add_ip6_link_address + * + * Add a default link-local IPv6 address to a device. + * + */ +void nm_system_device_add_ip6_link_address (NMDevice *dev) +{ + char *buf; + struct ether_addr hw_addr; + unsigned char eui[8]; + + if (nm_device_is_802_3_ethernet (dev)) + nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr); + else if (nm_device_is_802_11_wireless (dev)) + nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr); + + memcpy (eui, &(hw_addr.ether_addr_octet), sizeof (hw_addr.ether_addr_octet)); + memmove (eui+5, eui+3, 3); + eui[3] = 0xff; + eui[4] = 0xfe; + eui[0] ^= 2; + + /* Add the default link-local IPv6 address to a device */ + buf = g_strdup_printf ("/sbin/ip -6 addr add fe80::%x%02x:%x%02x:%x%02x:%x%02x/64 dev %s", + eui[0], eui[1], eui[2], eui[3], eui[4], eui[5], + eui[6], eui[7], nm_device_get_iface (dev)); + nm_spawn_process (buf); + g_free (buf); +} + + +typedef struct PaldoSystemConfigData +{ + NMIP4Config * config; + gboolean use_dhcp; + gboolean system_disabled; +} PaldoSystemConfigData; + +#define PALDO_NETDEVICE_CONFIG_DIR SYSCONFDIR "/network/devices" + +static GKeyFile *nm_system_device_get_netdevice_file (NMDevice *dev) +{ + GDir *dir; + GKeyFile *file; + const char *entry; + char *path; + char *file_udi; + + dir = g_dir_open (PALDO_NETDEVICE_CONFIG_DIR, 0, NULL); + if (dir == NULL) + return NULL; + + file = g_key_file_new (); + + for (entry = g_dir_read_name (dir); entry != NULL; entry = g_dir_read_name (dir)) + { + if (!g_str_has_suffix (entry, ".netdevice")) + continue; + + path = g_strdup_printf ("%s/%s", PALDO_NETDEVICE_CONFIG_DIR, entry); + if (!g_key_file_load_from_file (file, path, G_KEY_FILE_NONE, NULL)) + { + g_free (path); + continue; + } + g_free (path); + + file_udi = g_key_file_get_string (file, "Network Device", "UDI", NULL); + if (file_udi == NULL) + continue; + + if (strcmp (file_udi, nm_device_get_udi (dev)) != 0) { + g_free (file_udi); + continue; + } + + g_free (file_udi); + break; + } + + if (entry == NULL) + { + g_key_file_free (file); + file = NULL; + } + + g_dir_close (dir); + + return file; +} + +static NMIP4Config *netdevice_file_get_ip4_config (GKeyFile *file) +{ + NMIP4Config *ip4_config; + char **ipaddress_list; + char **ipaddress; + char *gateway; + char *value; + struct in_addr addr; + + ipaddress_list = g_key_file_get_string_list (file, "Network Device", "IPAddress", NULL, NULL); + if (ipaddress_list == NULL) + return NULL; + + ip4_config = nm_ip4_config_new (); + + for (ipaddress = ipaddress_list; *ipaddress != NULL; ipaddress++) + { + char *mask_slash, *mask_str; + int mask, hostmask; + + mask_slash = strchr (*ipaddress, '/'); + if (mask_slash == NULL) + continue; + + mask_str = mask_slash + 1; + if (*mask_str == '\0') + continue; + *mask_slash = '\0'; + + if (!inet_aton (*ipaddress, &addr)) + continue; + + mask = atoi (mask_str); + if (mask < 0 || mask > 32) + continue; + + hostmask = (1 << (32 - mask)) - 1; + nm_ip4_config_set_address (ip4_config, addr.s_addr); + nm_ip4_config_set_netmask (ip4_config, ~hostmask); + nm_ip4_config_set_broadcast (ip4_config, addr.s_addr | hostmask); + + break; + } + + g_strfreev (ipaddress_list); + + if (ipaddress == NULL) + { + nm_ip4_config_unref (ip4_config); + return NULL; + } + + gateway = g_key_file_get_string (file, "Network Device", "Gateway", NULL); + if (gateway != NULL) + { + if (inet_aton (gateway, &addr)) + nm_ip4_config_set_gateway (ip4_config, addr.s_addr); + + g_free (gateway); + } + + ipaddress_list = g_key_file_get_string_list (file, "Network Device", "Nameserver", NULL, NULL); + if (ipaddress_list != NULL) + { + for (ipaddress = ipaddress_list; *ipaddress != NULL; ipaddress++) + { + if (!inet_aton (*ipaddress, &addr)) + continue; + + nm_ip4_config_add_nameserver (ip4_config, addr.s_addr); + } + + g_strfreev (ipaddress_list); + } + + value = g_key_file_get_string (file, "Network Device", "Domain", NULL); + if (value != NULL) + { + nm_ip4_config_add_domain (ip4_config, value); + g_free (value); + } + + value = g_key_file_get_string (file, "Network Device", "Hostname", NULL); + if (value != NULL) + { + nm_ip4_config_set_hostname (ip4_config, value); + g_free (value); + } + + return ip4_config; +} + +/* + * nm_system_device_get_system_config + * + * Read in the config file for a device. + * + */ +void *nm_system_device_get_system_config (NMDevice *dev, NMData *app_data) +{ + PaldoSystemConfigData *sys_data = NULL; + GKeyFile *file; + char *method; + GError *error = NULL; + gboolean value; + + g_return_val_if_fail (dev != NULL, NULL); + + sys_data = g_malloc0 (sizeof (PaldoSystemConfigData)); + sys_data->use_dhcp = TRUE; + + file = nm_system_device_get_netdevice_file (dev); + if (file == NULL) + return sys_data; + + method = g_key_file_get_string (file, "Network Device", "Method", NULL); + if (method != NULL && strcmp (method, "static") == 0) + { + sys_data->config = netdevice_file_get_ip4_config (file); + + /* only disable dhcp if valid config has been found */ + if (sys_data->config != NULL) + sys_data->use_dhcp = FALSE; + } + g_free (method); + + value = g_key_file_get_boolean (file, "Network Device", "Disabled", &error); + if (error == NULL) + sys_data->system_disabled = value; + g_clear_error (&error); + + g_key_file_free (file); + + /* FIXME: add /etc/network/networks/example.network files */ + + return (void *)sys_data; +} + + +/* + * nm_system_device_free_system_config + * + * Free stored system config data + * + */ +void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) +{ + PaldoSystemConfigData *sys_data = (PaldoSystemConfigData *)system_config_data; + + g_return_if_fail (dev != NULL); + + if (!sys_data) + return; + + if (sys_data->config) + nm_ip4_config_unref (sys_data->config); +} + + +/* + * nm_system_device_get_use_dhcp + * + * Return whether the distro-specific system config tells us to use + * dhcp for this device. + * + */ +gboolean nm_system_device_get_use_dhcp (NMDevice *dev) +{ + PaldoSystemConfigData *sys_data; + + g_return_val_if_fail (dev != NULL, TRUE); + + if ((sys_data = nm_device_get_system_config_data (dev))) + return sys_data->use_dhcp; + + return TRUE; +} + + +/* + * nm_system_device_get_disabled + * + * Return whether the distro-specific system config tells us to + * disable this device. + * + */ +gboolean nm_system_device_get_disabled (NMDevice *dev) +{ + PaldoSystemConfigData *sys_data; + + g_return_val_if_fail (dev != NULL, FALSE); + + if ((sys_data = nm_device_get_system_config_data (dev))) + return sys_data->system_disabled; + + return FALSE; +} + + +NMIP4Config *nm_system_device_new_ip4_system_config (NMDevice *dev) +{ + PaldoSystemConfigData *sys_data; + NMIP4Config *new_config = NULL; + + g_return_val_if_fail (dev != NULL, NULL); + + if ((sys_data = nm_device_get_system_config_data (dev))) + new_config = nm_ip4_config_copy (sys_data->config); + + return new_config; +} + + +void nm_system_deactivate_all_dialup (GSList *list) +{ + /* FIXME: implement for paldo */ +} + + +gboolean nm_system_deactivate_dialup (GSList *list, const char *dialup) +{ + /* FIXME: implement for paldo */ + + return FALSE; +} + + +gboolean nm_system_activate_dialup (GSList *list, const char *dialup) +{ + /* FIXME: implement for paldo */ + + return FALSE; +} + + +GSList * nm_system_get_dialup_config (void) +{ + /* FIXME: implement for paldo */ + + return NULL; +} + +/* + * nm_system_activate_nis + * + * set up the nis domain and write a yp.conf + * + */ +void nm_system_activate_nis (NMIP4Config *config) +{ +} + +/* + * nm_system_shutdown_nis + * + * shutdown ypbind + * + */ +void nm_system_shutdown_nis (void) +{ +} + +/* + * nm_system_set_hostname + * + * set the hostname + * + */ +void nm_system_set_hostname (NMIP4Config *config) +{ +} + + +/* + * nm_system_should_modify_resolv_conf + * + * Can NM update resolv.conf, or is it locked down? + */ +gboolean nm_system_should_modify_resolv_conf (void) +{ + return TRUE; +} + +/* + * nm_system_get_mtu + * + * Return a user-provided or system-mandated MTU for this device or zero if + * no such MTU is provided. + */ +unsigned int nm_system_get_mtu (NMDevice *dev) +{ + return 0; +}