settings: drop unmaintained ifnet settings plugin of Gentoo

Even Gentoo disables this plugin since before 0.9.8 release
of NetworkManager. Time to say goodbye.

If somebody happens to show up to maintain it, we may resurrect it
later.

If "$distro_plugins=ifnet" was set, configure.ac would use that
to autodetect --with-hostname-persist=gentoo. Replace that autodetect
part by checking for /etc/gentoo-release file.
This commit is contained in:
Thomas Haller 2017-12-20 10:42:41 +01:00
parent 298d156e36
commit 0474441e22
32 changed files with 8 additions and 7835 deletions

3
.gitignore vendored
View file

@ -256,7 +256,6 @@ test-*.trs
/src/settings/plugins/ibft/tests/test-ibft
/src/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.[ch]
/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh
/src/settings/plugins/ifnet/tests/test-ifnet
/src/settings/plugins/ifupdown/tests/test-ifupdown
/src/settings/plugins/keyfile/tests/test-keyfile
/src/settings/plugins/ifcfg-rh/tests/network-scripts/tmp/
@ -300,7 +299,6 @@ test-*.trs
/src/dnsmasq-manager/tests/test-dnsmasq-utils
/src/rdisc/
/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils
/src/settings/plugins/ifnet/tests/check_ifnet
/src/supplicant-manager/tests/test-supplicant-config
/introspection/nmdbus-*.c
/introspection/nmdbus-*.h
@ -313,3 +311,4 @@ test-*.trs
/libnm-core/tests/test-setting-8021x
/libnm-core/tests/test-setting-bond
/libnm-core/tests/test-setting-dcb
/src/settings/plugins/ifnet

View file

@ -18,7 +18,7 @@ before_install:
- sudo apt-get install libnl-3-dev libndp-dev automake libcurl4-gnutls-dev
script: |
sh autogen.sh --with-systemd-logind=no --enable-more-warnings=no --enable-ifcfg-rh --enable-ifupdown --enable-ifnet --enable-tests &&
sh autogen.sh --with-systemd-logind=no --enable-more-warnings=no --enable-ifcfg-rh --enable-ifupdown --enable-tests &&
make -j4 &&
./contrib/travis/travis-check.sh

View file

@ -123,7 +123,6 @@ DISTCHECK_CONFIGURE_FLAGS = \
--with-wext=no \
--enable-ifcfg-rh \
--enable-ifupdown \
--enable-ifnet \
--disable-dependency-tracking
dist-configure-check:
@ -2409,96 +2408,6 @@ EXTRA_DIST += \
src/settings/plugins/ifupdown/tests/test21-source-dir-stanza \
src/settings/plugins/ifupdown/tests/test21-source-dir-stanza.d
###############################################################################
# src/settings/plugins/ifnet
###############################################################################
if CONFIG_PLUGIN_IFNET
core_plugins += src/settings/plugins/ifnet/libnm-settings-plugin-ifnet.la
noinst_LTLIBRARIES += src/settings/plugins/ifnet/libnms-ifnet-core.la
src_settings_plugins_ifnet_cppflags = \
-I$(srcdir)/src \
-I$(srcdir)/shared \
-I$(builddir)/shared \
-I$(srcdir)/libnm-core \
-I$(builddir)/libnm-core \
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
$(GLIB_CFLAGS) \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DSBINDIR=\"$(sbindir)\"
src_settings_plugins_ifnet_libnms_ifnet_core_la_SOURCES = \
src/settings/plugins/ifnet/nms-ifnet-net-parser.c\
src/settings/plugins/ifnet/nms-ifnet-net-parser.h\
src/settings/plugins/ifnet/nms-ifnet-connection-parser.c \
src/settings/plugins/ifnet/nms-ifnet-connection-parser.h \
src/settings/plugins/ifnet/nms-ifnet-net-utils.h\
src/settings/plugins/ifnet/nms-ifnet-net-utils.c\
src/settings/plugins/ifnet/nms-ifnet-wpa-parser.h\
src/settings/plugins/ifnet/nms-ifnet-wpa-parser.c
src_settings_plugins_ifnet_libnms_ifnet_core_la_CPPFLAGS = $(src_settings_plugins_ifnet_cppflags)
src_settings_plugins_ifnet_libnm_settings_plugin_ifnet_la_SOURCES = \
src/settings/plugins/ifnet/nms-ifnet-connection.c \
src/settings/plugins/ifnet/nms-ifnet-connection.h \
src/settings/plugins/ifnet/nms-ifnet-plugin.c \
src/settings/plugins/ifnet/nms-ifnet-plugin.h
src_settings_plugins_ifnet_libnm_settings_plugin_ifnet_la_CPPFLAGS = $(src_settings_plugins_ifnet_cppflags)
src_settings_plugins_ifnet_libnm_settings_plugin_ifnet_la_LDFLAGS = \
-module -avoid-version \
-Wl,--version-script="$(srcdir)/linker-script-settings.ver"
src_settings_plugins_ifnet_libnm_settings_plugin_ifnet_la_LIBADD = \
src/settings/plugins/ifnet/libnms-ifnet-core.la
check-local-symbols-settings-ifnet: src/settings/plugins/ifnet/libnm-settings-plugin-ifnet.la
$(call check_so_symbols,$(builddir)/src/settings/plugins/ifnet/.libs/libnm-settings-plugin-ifnet.so)
check_local += check-local-symbols-settings-ifnet
###############################################################################
check_programs += src/settings/plugins/ifnet/tests/test-ifnet
src_settings_plugins_ifnet_tests_test_ifnet_CPPFLAGS = \
-I$(srcdir)/shared \
-I$(builddir)/shared \
-I$(srcdir)/libnm-core \
-I$(builddir)/libnm-core \
-I$(srcdir)/src \
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
$(GLIB_CFLAGS) \
$(CODE_COVERAGE_CFLAGS) \
-DTEST_IFNET_DIR=\"$(abs_srcdir)/src/settings/plugins/ifnet/tests\" \
-DTEST_SCRATCH_DIR=\"$(abs_builddir)/src/settings/plugins/ifnet/tests/\" \
-DTEST_WPA_SUPPLICANT_CONF='"$(srcdir)/src/settings/plugins/ifnet/tests/wpa_supplicant.conf"' \
-DSYSCONFDIR=\"nonexistent\"
src_settings_plugins_ifnet_tests_test_ifnet_LDFLAGS = \
$(GLIB_LDFLAGS)
$(CODE_COVERAGE_LDFLAGS)
src_settings_plugins_ifnet_tests_test_ifnet_LDADD = \
src/settings/plugins/ifnet/libnms-ifnet-core.la \
src/libNetworkManagerTest.la
endif
EXTRA_DIST += \
src/settings/plugins/ifnet/tests/net \
src/settings/plugins/ifnet/tests/net.all \
src/settings/plugins/ifnet/tests/nm-system-settings.conf \
src/settings/plugins/ifnet/tests/wpa_supplicant.conf \
src/settings/plugins/ifnet/tests/test_ca_cert.pem
###############################################################################
# src/devices/adsl
###############################################################################

View file

@ -121,24 +121,20 @@ AC_CHECK_FUNCS([__secure_getenv secure_getenv])
AC_ARG_ENABLE(config-plugin-ibft, AS_HELP_STRING([--enable-config-plugin-ibft], [enable ibft configuration plugin]))
AC_ARG_ENABLE(ifcfg-rh, AS_HELP_STRING([--enable-ifcfg-rh], [enable ifcfg-rh configuration plugin (Fedora/RHEL)]))
AC_ARG_ENABLE(ifupdown, AS_HELP_STRING([--enable-ifupdown], [enable ifupdown configuration plugin (Debian/Ubuntu)]))
AC_ARG_ENABLE(ifnet, AS_HELP_STRING([--enable-ifnet], [enable ifnet configuration plugin (Gentoo)]))
# Default alternative plugins by distribution
AS_IF([test -z "$enable_ifcfg_rh"], AC_CHECK_FILE(/etc/redhat-release, enable_ifcfg_rh=yes))
AS_IF([test -z "$enable_ifcfg_rh"], AC_CHECK_FILE(/etc/fedora-release, enable_ifcfg_rh=yes))
AS_IF([test -z "$enable_ifcfg_rh"], AC_CHECK_FILE(/etc/mandriva-release, enable_ifcfg_rh=yes))
AS_IF([test -z "$enable_ifupdown"], AC_CHECK_FILE(/etc/debian_version, enable_ifupdown=yes))
AS_IF([test -z "$enable_ifnet"], AC_CHECK_FILE(/etc/gentoo-release, enable_ifnet=yes))
# Otherwise plugins default to "no"
AS_IF([test -z "$enable_ifcfg_rh"], enable_ifcfg_rh=no)
AS_IF([test -z "$enable_ifupdown"], enable_ifupdown=no)
AS_IF([test -z "$enable_ifnet"], enable_ifnet=no)
# Enable ibft by default
AS_IF([test -z "$enable_config_plugin_ibft"], enable_config_plugin_ibft="yes")
# Create automake conditionals
AM_CONDITIONAL(CONFIG_PLUGIN_IBFT, test "$enable_config_plugin_ibft" = "yes")
AM_CONDITIONAL(CONFIG_PLUGIN_IFCFG_RH, test "$enable_ifcfg_rh" = "yes")
AM_CONDITIONAL(CONFIG_PLUGIN_IFUPDOWN, test "$enable_ifupdown" = "yes")
AM_CONDITIONAL(CONFIG_PLUGIN_IFNET, test "$enable_ifnet" = "yes")
AC_ARG_WITH(config-plugins-default,
AS_HELP_STRING([--with-config-plugins-default=PLUGINS],
@ -148,14 +144,12 @@ if test -z "$config_plugins_default" -o "$config_plugins_default" = no; then
config_plugins_default=''
test "$enable_ifcfg_rh" = "yes" && config_plugins_default="$config_plugins_default,ifcfg-rh"
test "$enable_ifupdown" = "yes" && config_plugins_default="$config_plugins_default,ifupdown"
test "$enable_ifnet" = "yes" && config_plugins_default="$config_plugins_default,ifnet"
test "$enable_config_plugin_ibft" = "yes" && config_plugins_default="$config_plugins_default,ibft"
config_plugins_default="${config_plugins_default#,}"
fi
test "$enable_ifcfg_rh" = "yes" && distro_plugins="$distro_plugins,ifcfg-rh"
test "$enable_ifupdown" = "yes" && distro_plugins="$distro_plugins,ifupdown"
test "$enable_ifnet" = "yes" && distro_plugins="$distro_plugins,ifnet"
distro_plugins="${distro_plugins#,}"
AC_DEFINE_UNQUOTED(NM_CONFIG_DEFAULT_MAIN_PLUGINS, "$config_plugins_default", [Default configuration option for main.plugins setting])
@ -409,7 +403,7 @@ AS_IF([test "$with_hostname_persist" = "slackware"], hostname_persist=slackware)
AS_IF([test "$with_hostname_persist" = "default"], hostname_persist=default)
# if the method was not explicitly set, try to guess it from the enabled plugins
AS_IF([test -z "$hostname_persist" -a -f /etc/SuSE-release], hostname_persist=suse)
AS_IF([test -z "$hostname_persist" -a "$distro_plugins" = "ifnet"], hostname_persist=gentoo)
AS_IF([test -z "$hostname_persist" -a -f /etc/gentoo-release], hostname_persist=gentoo)
AS_IF([test -z "$hostname_persist" -a -f /etc/slackware-version], hostname_persist=slackware)
AS_IF([test -z "$hostname_persist"], hostname_persist=default)
@ -1417,7 +1411,6 @@ echo "Configuration plugins (main.plugins=${config_plugins_default})"
echo " ibft: ${enable_config_plugin_ibft}"
echo " ifcfg-rh: ${enable_ifcfg_rh}"
echo " ifupdown: ${enable_ifupdown}"
echo " ifnet: ${enable_ifnet}"
echo
echo "Handlers for /etc/resolv.conf:"

View file

@ -131,7 +131,6 @@ if [[ $NO_DIST != 1 ]]; then
--enable-ifcfg-rh \
--enable-ifupdown \
--enable-ibft \
--enable-ifnet \
--with-config-logging-backend-default=syslog \
--with-libaudit=yes-disabled-by-default \
--enable-polkit=yes \

View file

@ -1235,25 +1235,16 @@ enable=nm-version-min:1.3,nm-version-min:1.2.6,nm-version-min:1.0.16
</varlistentry>
<varlistentry>
<term><varname>ifcfg-suse</varname></term>
<term><varname>ifcfg-suse</varname>, <varname>ifnet</varname></term>
<listitem>
<para>
This plugin is deprecated and its selection has no effect.
These plugins are deprecated and their selection has no effect.
The <literal>keyfile</literal> plugin should be used
instead.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>ifnet</varname></term>
<listitem>
<para>
This plugin was used on Gentoo but is deprecated.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View file

@ -222,7 +222,6 @@ endif
enable_ifcfg_rh = get_option('ifcfg_rh') or (distro == 'redhat')
enable_ifupdown = get_option('ifupdown') or (distro == 'debian')
enable_ifnet = get_option('ifnet') or (distro == 'gentoo')
enable_config_plugin_ibft = get_option('config_plugin_ibft')
config_h.set10('WITH_SETTINGS_PLUGIN_IBFT', enable_config_plugin_ibft)
@ -239,10 +238,6 @@ if config_plugins_default == ''
config_plugins += ['ifupdown']
endif
if enable_ifnet
config_plugins += ['ifnet']
endif
if enable_config_plugin_ibft
config_plugins += ['ibft']
endif
@ -972,7 +967,6 @@ output += '\nConfiguration_plugins (main.plugins=' + config_plugins_default + ')
output += ' ibft: ' + enable_config_plugin_ibft.to_string() + '\n'
output += ' ifcfg-rh: ' + enable_ifcfg_rh.to_string() + '\n'
output += ' ifupdown: ' + enable_ifupdown.to_string() + '\n'
output += ' ifnet: ' + enable_ifnet.to_string() + '\n'
output += '\nHandlers for /etc/resolv.conf:\n'
output += ' resolvconf: ' + enable_resolvconf.to_string()
if enable_resolvconf

View file

@ -47,7 +47,6 @@ option('config_plugins_default', type: 'string', value: '', description: 'Defaul
option('config_plugin_ibft', type: 'boolean', value: true, description: 'enable ibft configuration plugin')
option('ifcfg_rh', type: 'boolean', value: false, description: 'enable ifcfg-rh configuration plugin (Fedora/RHEL)')
option('ifupdown', type: 'boolean', value: false, description: 'enable ifupdown configuration plugin (Debian/Ubuntu)')
option('ifnet', type: 'boolean', value: false, description: 'enable ifnet configuration plugin (Gentoo)')
# handlers for resolv.conf
option('resolvconf', type: 'array', value: ['resolvconf', '/sbin/resolvconf', '/usr/sbin/resolvconf', '/usr/local/sbin/resolvconf'], description: 'Enable resolvconf support')

View file

@ -57,7 +57,6 @@
#define NM_CONFIG_KEYFILE_GROUP_KEYFILE "keyfile"
#define NM_CONFIG_KEYFILE_GROUP_IFUPDOWN "ifupdown"
#define NM_CONFIG_KEYFILE_GROUP_IFNET "ifnet"
#define NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT "auth-polkit"
#define NM_CONFIG_KEYFILE_KEY_MAIN_AUTOCONNECT_RETRIES_DEFAULT "autoconnect-retries-default"

View file

@ -677,8 +677,8 @@ load_plugins (NMSettings *self, const char **plugins, GError **error)
continue;
}
if (!strcmp (pname, "ifcfg-suse")) {
_LOGW ("skipping deprecated plugin ifcfg-suse");
if (NM_IN_STRSET (pname, "ifcfg-suse", "ifnet")) {
_LOGW ("skipping deprecated plugin %s", pname);
continue;
}

View file

@ -1,58 +0,0 @@
sources = files(
'nms-ifnet-connection-parser.c',
'nms-ifnet-net-parser.c',
'nms-ifnet-net-utils.c',
'nms-ifnet-wpa-parser.c'
)
cflags = [
'-DSBINDIR="@0@"'.format(nm_sbindir),
'-DSYSCONFDIR="@0@"'.format(nm_sysconfdir)
]
libnms_ifnet_core = static_library(
'nms-ifnet-core',
sources: sources,
dependencies: core_dep,
c_args: cflags
)
sources = files(
'nms-ifnet-connection.c',
'nms-ifnet-plugin.c'
)
ldflags = []
if have_version_script
ldflags += '-Wl,--version-script,@0@'.format(linker_script_settings)
endif
libnm_settings_plugin_ifnet = shared_module(
'nm-settings-plugin-ifnet',
sources: sources,
dependencies: core_dep,
c_args: cflags,
link_with: libnms_ifnet_core,
link_args: ldflags,
link_depends: linker_script_settings,
install: true,
install_dir: nm_pkglibdir
)
core_plugins += libnm_settings_plugin_ifnet
# FIXME: check_so_symbols replacement
'''
run_target(
'check-local-symbols-settings-ifnet',
command: [check_so_symbols, libnm_settings_plugin_ifnet.full_path()],
depends: libnm_settings_plugin_ifnet
)
check-local-symbols-settings-ifnet: src/settings/plugins/ifnet/libnm-settings-plugin-ifnet.la
$(call check_so_symbols,$(builddir)/src/settings/plugins/ifnet/.libs/libnm-settings-plugin-ifnet.so)
'''
if enable_tests
subdir('tests')
endif

File diff suppressed because it is too large Load diff

View file

@ -1,55 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#ifndef _CONNECTION_PARSER_H
#define _CONNECTION_PARSER_H
#include "nm-connection.h"
#include "nms-ifnet-net-parser.h"
gboolean ifnet_can_write_connection (NMConnection *connection, GError **error);
NMConnection *ifnet_update_connection_from_config_block (const char *conn_name,
const char *basepath,
GError **error);
/* nm_conn_name is used to update nm_ifnet_connection's priv data */
gboolean ifnet_update_parsers_by_connection (NMConnection *connection,
const char *conn_name,
const char *config_file,
const char *wpa_file,
gchar **out_new_name,
gchar **out_backup,
GError **error);
gboolean ifnet_delete_connection_in_parsers (const char *conn_name,
const char *config_file,
const char *wpa_file,
gchar **out_backup);
gboolean ifnet_add_new_connection (NMConnection *connection,
const char *config_file,
const char *wpa_file,
gchar **out_new_name,
gchar **out_backup,
GError ** error);
#endif

View file

@ -1,233 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#include "nm-default.h"
#include "nms-ifnet-connection.h"
#include <string.h>
#include <glib/gstdio.h>
#include "nm-dbus-interface.h"
#include "nm-utils.h"
#include "nm-setting-wireless-security.h"
#include "settings/nm-settings-connection.h"
#include "settings/nm-settings-plugin.h"
#include "nms-ifnet-connection-parser.h"
#include "nms-ifnet-net-parser.h"
#include "nms-ifnet-net-utils.h"
#include "nms-ifnet-wpa-parser.h"
#include "nms-ifnet-plugin.h"
/*****************************************************************************/
enum {
IFNET_SETUP_MONITORS,
IFNET_CANCEL_MONITORS,
IFNET_LAST_SIGNAL
};
static guint signals[IFNET_LAST_SIGNAL] = { 0 };
typedef struct {
gchar *conn_name;
NMSettingsPlugin *config;
} NMIfnetConnectionPrivate;
struct _NMIfnetConnection {
NMSettingsConnection parent;
NMIfnetConnectionPrivate _priv;
};
struct _NMIfnetConnectionClass {
NMSettingsConnectionClass parent;
};
G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SETTINGS_CONNECTION)
#define NM_IFNET_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMIfnetConnection, NM_IS_IFNET_CONNECTION)
/*****************************************************************************/
const char *
nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection)
{
return NM_IFNET_CONNECTION_GET_PRIVATE (connection)->conn_name;
}
static gboolean
commit_changes (NMSettingsConnection *connection,
NMConnection *new_connection,
NMSettingsConnectionCommitReason commit_reason,
NMConnection **out_reread_connection,
char **out_logmsg_change,
GError **error)
{
NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection);
char *new_name = NULL;
gboolean success = FALSE;
gboolean added = FALSE;
nm_assert (out_reread_connection && !*out_reread_connection);
nm_assert (!out_logmsg_change || !*out_logmsg_change);
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
if (priv->conn_name) {
success = ifnet_update_parsers_by_connection (new_connection,
priv->conn_name,
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
&new_name,
NULL,
error);
} else {
added = TRUE;
success = ifnet_add_new_connection (new_connection,
CONF_NET_FILE,
WPA_SUPPLICANT_CONF,
&new_name,
NULL,
error);
}
g_assert (!!success == (new_name != NULL));
if (success) {
g_free (priv->conn_name);
priv->conn_name = new_name;
}
reload_parsers ();
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
if (success) {
NM_SET_OUT (out_logmsg_change,
g_strdup_printf ("ifcfg-rh: %s %s",
added ? "persist" : "updated",
new_name));
}
return success;
}
static gboolean
delete (NMSettingsConnection *connection,
GError **error)
{
NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) connection);
/* Only connections which exist in /etc/conf.d/net will have a conn_name */
if (priv->conn_name) {
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
if (!ifnet_delete_connection_in_parsers (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL)) {
nm_log_warn (LOGD_SETTINGS, "Failed to delete %s", priv->conn_name);
reload_parsers ();
/* let's not return an error. */
}
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
}
return TRUE;
}
/*****************************************************************************/
static void
nm_ifnet_connection_init (NMIfnetConnection * connection)
{
}
NMIfnetConnection *
nm_ifnet_connection_new (NMConnection *source, const char *conn_name)
{
NMConnection *tmp;
GObject *object;
GError *error = NULL;
gboolean update_unsaved = TRUE;
g_return_val_if_fail (source || conn_name, NULL);
if (source)
tmp = g_object_ref (source);
else {
tmp = ifnet_update_connection_from_config_block (conn_name, NULL, &error);
if (!tmp) {
nm_log_warn (LOGD_SETTINGS, "Could not read connection '%s': %s",
conn_name, error->message);
g_error_free (error);
return NULL;
}
/* If we just read the connection from disk, it's clearly not Unsaved */
update_unsaved = FALSE;
}
object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL);
NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) object)->conn_name = g_strdup (conn_name);
if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object),
tmp,
update_unsaved
? NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED
: NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
NULL,
NULL)) {
g_object_unref (object);
return NULL;
}
g_object_unref (tmp);
return NM_IFNET_CONNECTION (object);
}
static void
finalize (GObject * object)
{
g_free (NM_IFNET_CONNECTION_GET_PRIVATE ((NMIfnetConnection *) object)->conn_name);
G_OBJECT_CLASS (nm_ifnet_connection_parent_class)->finalize (object);
}
static void
nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ifnet_connection_class);
NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifnet_connection_class);
object_class->finalize = finalize;
settings_class->delete = delete;
settings_class->commit_changes = commit_changes;
signals[IFNET_SETUP_MONITORS] =
g_signal_new ("ifnet_setup_monitors",
G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST,
0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[IFNET_CANCEL_MONITORS] =
g_signal_new ("ifnet_cancel_monitors",
G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST,
0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}

View file

@ -1,46 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#ifndef __NETWORKMANAGER_IFNET_CONNECTION_H__
#define __NETWORKMANAGER_IFNET_CONNECTION_H__
#include "settings/nm-settings-connection.h"
#include "nms-ifnet-net-parser.h"
#define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ())
#define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection))
#define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass))
#define NM_IS_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFNET_CONNECTION))
#define NM_IS_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IFNET_CONNECTION))
#define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass))
typedef struct _NMIfnetConnection NMIfnetConnection;
typedef struct _NMIfnetConnectionClass NMIfnetConnectionClass;
GType nm_ifnet_connection_get_type (void);
NMIfnetConnection *nm_ifnet_connection_new (NMConnection *source,
const char *conn_name);
const char *nm_ifnet_connection_get_conn_name (NMIfnetConnection *connection);
#endif /* __NETWORKMANAGER_IFNET_CONNECTION_H__ */

View file

@ -1,734 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#include "nm-default.h"
#include "nms-ifnet-net-parser.h"
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "settings/nm-settings-plugin.h"
#include "platform/nm-platform.h"
#include "nms-ifnet-plugin.h"
#include "nms-ifnet-net-utils.h"
/* Save all the connection information */
static GHashTable *conn_table;
/* Save global settings which are used for writing*/
static GHashTable *global_settings_table;
/* Save functions */
static GList *functions_list;
/* Used to decide whether to write changes to file*/
static gboolean net_parser_data_changed = FALSE;
static GHashTable *
add_new_connection_config (const gchar * type, const gchar * name)
{
GHashTable *new_conn;
gchar *new_name;
if (!name)
return NULL;
/* Return existing connection */
if ((new_conn = g_hash_table_lookup (conn_table, name)) != NULL)
return new_conn;
new_conn = g_hash_table_new (nm_str_hash, g_str_equal);
new_name = g_strdup (name);
g_hash_table_insert (new_conn, g_strdup ("name"), new_name);
g_hash_table_insert (new_conn, g_strdup ("type"), g_strdup (type));
g_hash_table_insert (conn_table, new_name, new_conn);
return new_conn;
}
gboolean
ifnet_add_network (const char *name, const char *type)
{
if (ifnet_has_network (name))
return TRUE;
if (add_new_connection_config (type, name)) {
nm_log_info (LOGD_SETTINGS, "Adding network for %s", name);
net_parser_data_changed = TRUE;
return TRUE;
}
return FALSE;
}
gboolean
ifnet_has_network (const char *conn_name)
{
return g_hash_table_lookup (conn_table, conn_name) != NULL;
}
static GHashTable *
get_connection_config (const char *name)
{
return g_hash_table_lookup (conn_table, name);
}
/* Ignored name won't be treated as wireless ssid */
static gchar *ignore_name[] = {
"vlan", "bond", "atm", "ath", "ippp", "vpn", "tap", "tun", "1",
"br", "nas", "6to4", "timeout", "kvm", "force", NULL
};
static gboolean
ignore_connection_name (const char *name)
{
gboolean result = FALSE;
guint i = 0;
/* check ignore_name list */
while (ignore_name[i] != NULL) {
if (g_ascii_strncasecmp
(name, ignore_name[i], strlen (ignore_name[i])) == 0) {
return TRUE;
}
i++;
}
/* Ignore mac address based configuration */
if (strlen (name) == 12 && is_hex (name))
result = TRUE;
return result;
}
static gboolean
is_global_setting (char *key)
{
static gchar *global_settings[] = { "wpa_supplicant_", NULL };
int i;
for (i = 0; global_settings[i] != NULL; i++) {
if (strstr (key, global_settings[i]))
return 1;
}
return 0;
}
/* Parse a complete line */
/* Connection type is determined here */
static void
init_block_by_line (gchar * buf)
{
gchar **key_value;
gchar *pos;
gchar *data;
gchar *tmp;
GHashTable *conn;
key_value = g_strsplit (buf, "=", 2);
if (g_strv_length (key_value) != 2) {
nm_log_warn (LOGD_SETTINGS, "Can't handle this line: %s\n", buf);
g_strfreev (key_value);
return;
}
pos = g_strrstr (key_value[0], "_");
if (pos == NULL || is_global_setting (key_value[0])) {
/* global data */
data = g_strdup (key_value[1]);
tmp = strip_string (data, '"');
strip_string (tmp, '\'');
nm_log_info (LOGD_SETTINGS, "global:%s-%s\n", key_value[0], tmp);
g_hash_table_insert (global_settings_table, g_strdup (key_value[0]), g_strdup (tmp));
g_strfreev (key_value);
g_free (data);
return;
}
*pos++ = '\0';
if ((conn = get_connection_config (pos)) == NULL) {
if (g_ascii_strncasecmp (pos, "eth", 3) == 0
&& strlen (pos) == 4)
/* wired connection */
conn = add_new_connection_config ("wired", pos);
else if (g_ascii_strncasecmp (pos, "ppp", 3) == 0
&& strlen (pos) == 4)
/* pppoe connection */
conn = add_new_connection_config ("ppp", pos);
else if (ignore_connection_name (pos)) {
/* ignored connection */
conn = add_new_connection_config ("ignore", pos);
} else {
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, pos);
if (ifindex && nm_platform_link_get_type (NM_PLATFORM_GET, ifindex) != NM_LINK_TYPE_WIFI)
/* wired connection */
conn = add_new_connection_config ("wired", pos);
else
/* wireless connection */
conn = add_new_connection_config ("wireless", pos);
}
}
data = g_strdup (key_value[1]);
tmp = strip_string (data, '"');
strip_string (tmp, '\'');
if (conn)
g_hash_table_insert (conn, strip_string (g_strdup (key_value[0]), ' '),
g_strdup (tmp));
g_free (data);
g_strfreev (key_value);
}
static void
destroy_connection_config (GHashTable * conn)
{
gpointer key, value;
GHashTableIter iter;
g_hash_table_iter_init (&iter, conn);
while (g_hash_table_iter_next (&iter, &key, &value)) {
g_free (key);
g_free (value);
}
g_hash_table_destroy (conn);
}
static void
strip_function (GIOChannel * channel, gchar * line)
{
int counter = 0;
gchar *p, *tmp;
gboolean begin = FALSE;
GString *function_str = g_string_new (line);
g_string_append (function_str, "\n");
while (1) {
p = line;
while (*p != '\0') {
if (*p == '{') {
counter++;
begin = TRUE;
} else if (*p == '}')
counter--;
p++;
}
if (begin && counter == 0) {
g_free (line);
goto done;
}
while (1) {
g_free (line);
if (g_io_channel_read_line
(channel, &line, NULL, NULL,
NULL) == G_IO_STATUS_EOF)
goto done;
g_string_append (function_str, line);
tmp = g_strdup (line);
g_strstrip (tmp);
if (tmp[0] != '#' && tmp[0] != '\0') {
g_free (tmp);
break;
} else
g_free (tmp);
}
}
done:
functions_list =
g_list_append (functions_list, g_strdup (function_str->str));
g_string_free (function_str, TRUE);
}
static gboolean
is_function (gchar * line)
{
static gchar *func_names[] =
{ "preup", "predown", "postup", "postdown", "failup", "faildown",
NULL,
};
int i;
for (i = 0; func_names[i]; i++) {
if (g_str_has_prefix (line, func_names[i])) {
nm_log_info (LOGD_SETTINGS, "Ignoring function: %s", func_names[i]);
return TRUE;
}
}
return FALSE;
}
static void
append_line (GString *buf, gchar* line)
{
gchar *pos = NULL;
if ((pos = strchr (line, '#')) != NULL)
*pos = '\0';
g_strstrip (line);
if (line[0] != '\0')
g_string_append_printf (buf, " %s", line);
g_free (line);
}
gboolean
ifnet_init (gchar * config_file)
{
GIOChannel *channel = NULL;
gchar *line;
/* Handle multiple lines with brackets */
gboolean complete = TRUE;
gboolean openrc_style = TRUE;
/* line buffer */
GString *buf;
net_parser_data_changed = FALSE;
conn_table = g_hash_table_new (nm_str_hash, g_str_equal);
global_settings_table = g_hash_table_new (nm_str_hash, g_str_equal);
functions_list = NULL;
if (g_file_test (config_file, G_FILE_TEST_IS_REGULAR))
channel = g_io_channel_new_file (config_file, "r", NULL);
if (channel == NULL) {
nm_log_warn (LOGD_SETTINGS, "Can't open %s", config_file);
return FALSE;
}
buf = g_string_new (NULL);
while (g_io_channel_read_line
(channel, &line, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
g_strstrip (line);
/* convert multiple lines to a complete line and
* pass it to init_block_by_line() */
if (is_function (line)) {
strip_function (channel, line);
continue;
}
// New openrc style, bash arrays are not allowed. We only care about '"'
if (openrc_style && line[0] != '#' && line[0] != '\0'
&& !strchr (line, '(') && !strchr (line, ')')) {
gchar *tmp = line;
while ((tmp = strchr (tmp, '"')) != NULL) {
complete = !complete;
++tmp;
}
append_line (buf, line);
// Add "(separator) for routes. It will be easier for later parsing
if (strstr (buf->str, "via"))
g_string_append_printf (buf, "\"");
if (!complete)
continue;
strip_string (buf->str, '"');
init_block_by_line (buf->str);
g_string_free (buf, TRUE);
buf = g_string_new (NULL);
}
// Old bash arrays for baselayout-1, to be deleted
else if (line[0] != '#' && line[0] != '\0') {
if (!complete) {
complete =
g_strrstr (line,
")") == NULL ? FALSE : TRUE;
append_line (buf, line);
if (!complete) {
openrc_style = FALSE;
continue;
}
else {
openrc_style = TRUE;
}
} else {
complete =
(g_strrstr (line, "(") != NULL
&& g_strrstr (line, ")") != NULL)
|| g_strrstr (line, "(") == NULL;
append_line (buf, line);
if (!complete)
{
openrc_style = FALSE;
continue;
} else {
openrc_style = TRUE;
}
}
init_block_by_line (buf->str);
g_string_free (buf, TRUE);
buf = g_string_new (NULL);
} else
/* Blank line or comment line */
g_free (line);
}
g_string_free (buf, TRUE);
g_io_channel_shutdown (channel, FALSE, NULL);
g_io_channel_unref (channel);
return TRUE;
}
const char *
ifnet_get_data (const char *conn_name, const char *key)
{
GHashTable *conn;
g_return_val_if_fail (conn_name && key, NULL);
conn = g_hash_table_lookup (conn_table, conn_name);
if (conn)
return g_hash_table_lookup (conn, key);
return NULL;
}
/* format ip values for comparison */
static gchar*
format_ip_for_comparison (const gchar * value)
{
gchar **ipset;
guint length, i;
GString *formated_string = g_string_new (NULL);
gchar *formatted = NULL;
ipset = g_strsplit (value, "\"", 0);
length = g_strv_length (ipset);
for (i = 0; i < length; i++)
{
strip_string (ipset[i], ' ');
if (ipset[i][0] != '\0')
g_string_append_printf (formated_string,
"%s ", ipset[i]);
}
formatted = g_strdup (formated_string->str);
formatted[formated_string->len - 1] = '\0';
g_string_free (formated_string, TRUE);
g_strfreev (ipset);
return formatted;
}
void
ifnet_set_data (const char *conn_name, const char *key, const char *value)
{
gpointer old_key = NULL, old_value = NULL;
GHashTable *conn = g_hash_table_lookup (conn_table, conn_name);
gchar * stripped = NULL;
if (!conn) {
nm_log_warn (LOGD_SETTINGS, "%s does not exist!", conn_name);
return;
}
if (value){
stripped = g_strdup (value);
strip_string (stripped, '"');
}
/* Remove existing key value pair */
if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) {
/* This ugly hack is due to baselayout compatibility. We have to
* deal with different ip format. So sometimes we have the same ips
* but different strings.
*/
if (stripped &&
(!strcmp (key, "config")
|| !strcmp (key, "routes")
|| !strcmp (key, "pppd")
|| !strcmp (key, "chat")))
{
gchar *old_ips = format_ip_for_comparison (old_value);
gchar *new_ips = format_ip_for_comparison (value);
if(!strcmp (old_ips, new_ips))
{
g_free (stripped);
g_free (old_ips);
g_free (new_ips);
return;
}
g_free (old_ips);
g_free (new_ips);
}
if (stripped && !strcmp (old_value, stripped)) {
g_free (stripped);
return;
}
g_hash_table_remove (conn, old_key);
g_free (old_key);
g_free (old_value);
} else if (!value)
return;
if (stripped)
g_hash_table_insert (conn, g_strdup (key), stripped);
net_parser_data_changed = TRUE;
}
// Remember to free return value
const char *
ifnet_get_global_data (const gchar * key)
{
return g_hash_table_lookup (global_settings_table, key);
}
// Return names of legal connections
GList *
ifnet_get_connection_names (void)
{
GList *names = g_hash_table_get_keys (conn_table);
GList *iter, *result = NULL;
for (iter = names; iter; iter = iter->next) {
if (!ignore_connection_name (iter->data))
result = g_list_prepend (result, iter->data);
}
g_list_free (names);
return g_list_reverse (result);
}
/* format IP and route for writing */
static void
format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name)
{
gchar **ipset;
guint length, i;
GString *formated_string = g_string_new (NULL);
strip_string (value, '(');
strip_string (value, ')');
strip_string (value, '"');
ipset = g_strsplit (value, "\"", 0);
length = g_strv_length (ipset);
//only one line
if (length < 2) {
*out_line =
g_strdup_printf ("%s_%s=\"%s\"\n", key, name, value);
goto done;
}
// Multiple lines
g_string_append_printf (formated_string, "%s_%s=\"\n", key, name);
for (i = 0; i < length; i++)
{
strip_string (ipset[i], ' ');
if (ipset[i][0] != '\0')
g_string_append_printf (formated_string,
"%s\n", ipset[i]);
}
g_string_append (formated_string, "\"\n");
*out_line = g_strdup (formated_string->str);
done:
g_string_free (formated_string, TRUE);
g_strfreev (ipset);
}
gboolean
ifnet_flush_to_file (const char *config_file, gchar **out_backup)
{
GIOChannel *channel;
GError *error = NULL;
gpointer key, value, name, network;
GHashTableIter iter, iter_network;
GList *list_iter;
gchar *out_line = NULL;
gsize bytes_written;
gboolean result = FALSE;
gchar *backup;
if (!net_parser_data_changed)
return TRUE;
if (!conn_table || !global_settings_table)
return FALSE;
backup = backup_file (config_file);
channel = g_io_channel_new_file (config_file, "w", NULL);
if (!channel) {
nm_log_warn (LOGD_SETTINGS, "Can't open file %s for writing", config_file);
g_free (backup);
return FALSE;
}
g_hash_table_iter_init (&iter, global_settings_table);
nm_log_info (LOGD_SETTINGS, "Writing to %s", config_file);
g_io_channel_write_chars (channel,
"#Generated by NetworkManager\n"
"###### Global Configuration ######\n",
-1, &bytes_written, &error);
if (error)
goto done;
/* Writing global data */
while (g_hash_table_iter_next (&iter, &key, &value)) {
out_line =
g_strdup_printf ("%s=\"%s\"\n", (gchar *) key, (gchar *) value);
g_io_channel_write_chars (channel, out_line, -1,
&bytes_written, &error);
if (bytes_written == 0 || error)
goto done;
g_free (out_line);
}
/* Writing connection data */
g_io_channel_write_chars (channel,
"\n###### Connection Configuration ######\n",
-1, &bytes_written, &error);
if (error)
goto done;
g_hash_table_iter_init (&iter, conn_table);
while (g_hash_table_iter_next (&iter, &name, &network)) {
g_hash_table_iter_init (&iter_network, (GHashTable *) network);
g_io_channel_write_chars (channel,
"#----------------------------------\n",
-1, &bytes_written, &error);
if (error)
goto done;
while (g_hash_table_iter_next (&iter_network, &key, &value)) {
if (!g_str_has_prefix ((gchar *) key, "name")
&& !g_str_has_prefix ((gchar *) key, "type")) {
/* These keys contain brackets */
if (strcmp
((gchar *) key,
"config") == 0
|| strcmp ((gchar *) key,
"routes") == 0
|| strcmp ((gchar *) key,
"pppd") == 0
|| strcmp ((gchar *) key, "chat") == 0)
format_ips (value, &out_line, (gchar *)
key, (gchar *)
name);
else
out_line =
g_strdup_printf
("%s_%s=\"%s\"\n",
(gchar *) key,
(gchar *) name, (gchar *) value);
g_io_channel_write_chars (channel, out_line, -1, &bytes_written, &error);
if (bytes_written == 0 || error)
goto done;
g_free (out_line);
}
}
}
/* Writing reserved functions */
if (functions_list) {
g_io_channel_write_chars (channel,
"\n###### Reserved Functions ######\n",
-1, &bytes_written, &error);
if (error)
goto done;
/* Writing functions */
for (list_iter = functions_list; list_iter;
list_iter = g_list_next (list_iter)) {
out_line =
g_strdup_printf ("%s\n", (gchar *) list_iter->data);
g_io_channel_write_chars (channel, out_line, -1,
&bytes_written, &error);
if (bytes_written == 0 || error)
goto done;
g_free (out_line);
}
}
g_io_channel_flush (channel, &error);
if (error)
goto done;
result = TRUE;
net_parser_data_changed = FALSE;
done:
if (error) {
nm_log_warn (LOGD_SETTINGS, "Error writing the configuration file: %s", error->message);
g_error_free (error);
}
if (result && out_backup)
*out_backup = backup;
else
g_free (backup);
g_io_channel_shutdown (channel, FALSE, NULL);
g_io_channel_unref (channel);
return result;
}
gboolean
ifnet_delete_network (const char *conn_name)
{
GHashTable *network = NULL;
g_return_val_if_fail (conn_table != NULL && conn_name != NULL, FALSE);
nm_log_info (LOGD_SETTINGS, "Deleting network for %s", conn_name);
network = g_hash_table_lookup (conn_table, conn_name);
if (!network)
return FALSE;
g_hash_table_remove (conn_table, conn_name);
destroy_connection_config (network);
net_parser_data_changed = TRUE;
return TRUE;
}
void
ifnet_destroy (void)
{
GHashTableIter iter;
gpointer key;
gpointer value;
GList *list_iter;
/* Destroy connection setting */
if (conn_table) {
g_hash_table_iter_init (&iter, conn_table);
while (g_hash_table_iter_next (&iter, &key, &value)) {
destroy_connection_config ((GHashTable *)
value);
}
g_hash_table_destroy (conn_table);
conn_table = NULL;
}
/* Destroy global data */
if (global_settings_table) {
g_hash_table_iter_init (&iter, global_settings_table);
while (g_hash_table_iter_next (&iter, &key, &value)) {
g_free (key);
g_free (value);
}
g_hash_table_destroy (global_settings_table);
global_settings_table = NULL;
}
for (list_iter = functions_list; list_iter;
list_iter = g_list_next (list_iter))
g_free (list_iter->data);
g_list_free (functions_list);
}

View file

@ -1,42 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#ifndef _NET_PARSER_H
#define _NET_PARSER_H
#define CONF_NET_FILE SYSCONFDIR "/conf.d/net"
gboolean ifnet_init (gchar * config_file);
void ifnet_destroy (void);
/* Reader functions */
GList *ifnet_get_connection_names (void);
const char *ifnet_get_data (const char *conn_name, const char *key);
const char *ifnet_get_global_data (const char *key);
gboolean ifnet_has_network (const char *conn_name);
/* Writer functions */
gboolean ifnet_flush_to_file (const char *config_file, gchar **out_backup);
void ifnet_set_data (const char *conn_name, const char *key, const char *value);
gboolean ifnet_add_network (const char *name, const char *type);
gboolean ifnet_delete_network (const char *conn_name);
#endif

View file

@ -1,830 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#include "nm-default.h"
#include "nms-ifnet-net-utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "settings/nm-settings-plugin.h"
#include "nm-config.h"
#include "dhcp/nm-dhcp-manager.h"
#include "nms-ifnet-wpa-parser.h"
#include "nms-ifnet-net-parser.h"
/* emit heading and tailing blank space, tab, character t */
gchar *
strip_string (gchar * str, gchar t)
{
gchar *ret = str;
gint length = 0;
guint i = 0;
while (ret[i] != '\0'
&& (ret[i] == '\t' || ret[i] == ' ' || ret[i] == t)) {
length++;
i++;
}
i = 0;
while (ret[i + length] != '\0') {
ret[i] = ret[i + length];
i++;
}
ret[i] = '\0';
length = strlen (ret);
while ((length - 1) >= 0
&& (ret[length - 1] == ' ' || ret[length - 1] == '\n'
|| ret[length - 1] == '\t' || ret[length - 1] == t))
length--;
ret[length] = '\0';
return ret;
}
gboolean
is_hex (const char *value)
{
const char *p = value;
if (!p)
return FALSE;
while (*p) {
if (!g_ascii_isxdigit (*p++))
return FALSE;
}
return TRUE;
}
gboolean
is_ascii (const char *value)
{
const char *p = value;
while (*p) {
if (!g_ascii_isprint (*p++))
return FALSE;
}
return TRUE;
}
gboolean
is_true (const char *str)
{
if (!g_ascii_strcasecmp (str, "yes")
|| !g_ascii_strcasecmp (str, "true"))
return TRUE;
return FALSE;
}
static char *
find_default_gateway_str (char *str)
{
char *tmp;
if ((tmp = strstr (str, "default via ")) != NULL) {
return tmp + strlen ("default via ");
} else if ((tmp = strstr (str, "default gw ")) != NULL) {
return tmp + strlen ("default gw ");
}
return NULL;
}
static char *
find_gateway_str (char *str)
{
char *tmp;
if ((tmp = strstr (str, "via ")) != NULL) {
return tmp + strlen ("via ");
} else if ((tmp = strstr (str, "gw ")) != NULL) {
return tmp + strlen ("gw ");
}
return NULL;
}
gboolean
reload_parsers (void)
{
ifnet_destroy ();
wpa_parser_destroy ();
if (!ifnet_init (CONF_NET_FILE))
return FALSE;
wpa_parser_init (WPA_SUPPLICANT_CONF);
return TRUE;
}
gboolean
is_static_ip4 (const char *conn_name)
{
const char *data = ifnet_get_data (conn_name, "config");
const char *dhcp6;
if (!data)
return FALSE;
if (!strcmp (data, "shared"))
return FALSE;
if (!strcmp (data, "autoip"))
return FALSE;
dhcp6 = strstr (data, "dhcp6");
if (dhcp6) {
gchar *dhcp4;
if (strstr (data, "dhcp "))
return FALSE;
dhcp4 = strstr (data, "dhcp");
if (!dhcp4)
return TRUE;
if (dhcp4[4] == '\0')
return FALSE;
return TRUE;
}
return strstr (data, "dhcp") == NULL ? TRUE : FALSE;
}
gboolean
is_static_ip6 (const char *conn_name)
{
const char *data = ifnet_get_data (conn_name, "config");
if (!data)
return TRUE;
return strstr (data, "dhcp6") == NULL ? TRUE : FALSE;
}
gboolean
is_ip4_address (const char *in_address)
{
const char *pattern =
"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.((\\{\\d{1,3}\\.\\.\\d{1,3}\\})|\\d{1,3})$";
gchar *address = g_strdup (in_address);
gboolean result = FALSE;
gchar *tmp;
GRegex *regex = g_regex_new (pattern, 0, 0, NULL);
GMatchInfo *match_info = NULL;
if (!address)
goto done;
g_strstrip (address);
if ((tmp = strstr (address, "/")) != NULL)
*tmp = '\0';
if ((tmp = strstr (address, " ")) != NULL)
*tmp = '\0';
g_regex_match (regex, address, 0, &match_info);
result = g_match_info_matches (match_info);
done:
if (match_info)
g_match_info_free (match_info);
g_regex_unref (regex);
g_free (address);
return result;
}
gboolean
is_ip6_address (const char *in_address)
{
struct in6_addr tmp_ip6_addr;
gchar *tmp, *address;
gboolean result = FALSE;
if (!in_address)
return FALSE;
address = g_strdup (in_address);
g_strstrip (address);
if ((tmp = strchr (address, '/')) != NULL)
*tmp = '\0';
if (inet_pton (AF_INET6, address, &tmp_ip6_addr))
result = TRUE;
g_free (address);
return result;
}
// 'c' is only used for openrc style
static gchar **
split_addresses_by_char (const gchar *addresses, const gchar *c)
{
gchar **ipset;
if (addresses == NULL)
return NULL;
if (strchr (addresses, '(') != NULL) { // old baselayout style
gchar *tmp = g_strdup (addresses);
strip_string (tmp, '(');
strip_string (tmp, ')');
strip_string (tmp, '"');
strip_string (tmp, '\'');
ipset = g_strsplit (tmp, "\" \"", 0);
g_free(tmp);
} else { // openrc style
if (strstr (addresses, "netmask"))
// There is only one ip address if "netmask" is specified.
// '\n' is not used in config so there will be only one split.
ipset = g_strsplit (addresses, "\n", 0);
else
ipset = g_strsplit (addresses, c, 0);
}
return ipset;
}
static gchar **
split_addresses (const gchar* addresses)
{
// " " is only used by openrc style
return split_addresses_by_char (addresses, " ");
}
static gchar **
split_routes (const gchar* routes)
{
// "\"" is only used by openrc style
return split_addresses_by_char (routes, "\"");
}
gboolean
has_ip6_address (const char *conn_name)
{
gchar **ipset;
guint length;
guint i;
g_return_val_if_fail (conn_name != NULL, FALSE);
ipset = split_addresses (ifnet_get_data (conn_name, "config"));
length = ipset ? g_strv_length (ipset) : 0;
for (i = 0; i < length; i++) {
if (!is_ip6_address (ipset[i]))
continue;
else {
g_strfreev (ipset);
return TRUE;
}
}
g_strfreev (ipset);
return FALSE;
}
gboolean
has_default_route (const char *conn_name, gboolean (*check_fn) (const char *))
{
char *routes = NULL, *end, *tmp;
gboolean success = FALSE;
g_return_val_if_fail (conn_name != NULL, FALSE);
routes = g_strdup (ifnet_get_data (conn_name, "routes"));
if (!routes)
return FALSE;
tmp = find_default_gateway_str (routes);
if (tmp) {
g_strstrip (tmp);
if ((end = strstr (tmp, "\"")) != NULL)
*end = '\0';
if (check_fn (tmp))
success = TRUE;
}
g_free (routes);
return success;
}
static ip_block *
create_ip4_block (gchar * ip)
{
ip_block *iblock = g_slice_new0 (ip_block);
guint32 tmp_ip4_addr;
int i;
guint length;
gchar **ip_mask;
/* prefix format */
if (strstr (ip, "/")) {
gchar *prefix;
ip_mask = g_strsplit (ip, "/", 0);
length = g_strv_length (ip_mask);
if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0]))
goto error;
iblock->ip = g_strdup (ip_mask[0]);
prefix = ip_mask[1];
i = 0;
while (i < length && g_ascii_isdigit (prefix[i]))
i++;
prefix[i] = '\0';
iblock->prefix = (guint32) atoi (ip_mask[1]);
} else if (strstr (ip, "netmask")) {
ip_mask = g_strsplit (ip, " ", 0);
length = g_strv_length (ip_mask);
if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0]))
goto error;
iblock->ip = g_strdup (ip_mask[0]);
i = 0;
while (i < length && !strstr (ip_mask[++i], "netmask")) ;
while (i < length && ip_mask[++i][0] == '\0') ;
if (i >= length)
goto error;
if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr))
goto error;
iblock->prefix = nm_utils_ip4_netmask_to_prefix (tmp_ip4_addr);
} else {
g_slice_free (ip_block, iblock);
if (!is_ip6_address (ip) && !strstr (ip, "dhcp"))
nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, missing netmask or prefix", ip);
return NULL;
}
if (iblock->prefix == 0 || iblock->prefix > 32) {
nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, invalid prefix", ip);
goto error;
}
g_strfreev (ip_mask);
return iblock;
error:
if (!is_ip6_address (ip))
nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 address: %s", ip);
g_strfreev (ip_mask);
g_free (iblock->ip);
g_slice_free (ip_block, iblock);
return NULL;
}
static ip_block *
create_ip_block (gchar * ip)
{
ip_block *iblock = g_slice_new0 (ip_block);
gchar *dup_ip = g_strdup (ip);
gchar *prefix = NULL;
if ((prefix = strstr (dup_ip, "/")) != NULL) {
*prefix = '\0';
prefix++;
}
if (!nm_utils_ipaddr_valid (AF_INET6, dup_ip))
goto error;
iblock->ip = dup_ip;
if (prefix) {
errno = 0;
iblock->prefix = strtol (prefix, NULL, 10);
if (errno || iblock->prefix <= 0 || iblock->prefix > 128) {
goto error;
}
} else
iblock->prefix = 64;
return iblock;
error:
if (!is_ip4_address (ip))
nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 address: %s", ip);
g_slice_free (ip_block, iblock);
g_free (dup_ip);
return NULL;
}
static char *
get_ip4_gateway (gchar * gateway)
{
gchar *tmp, *split;
if (!gateway)
return NULL;
tmp = find_gateway_str (gateway);
if (!tmp) {
nm_log_warn (LOGD_SETTINGS, "Couldn't obtain gateway in \"%s\"", gateway);
return NULL;
}
tmp = g_strdup (tmp);
strip_string (tmp, ' ');
strip_string (tmp, '"');
// Only one gateway is selected
if ((split = strstr (tmp, "\"")) != NULL)
*split = '\0';
if (!nm_utils_ipaddr_valid (AF_INET, tmp))
goto error;
return tmp;
error:
if (!is_ip6_address (tmp))
nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 gateway: %s", tmp);
g_free (tmp);
return NULL;
}
static char *
get_ip6_next_hop (gchar * next_hop)
{
gchar *tmp;
if (!next_hop)
return NULL;
tmp = find_gateway_str (next_hop);
if (!tmp) {
nm_log_warn (LOGD_SETTINGS, "Couldn't obtain next_hop in \"%s\"", next_hop);
return NULL;
}
tmp = g_strdup (tmp);
strip_string (tmp, ' ');
strip_string (tmp, '"');
g_strstrip (tmp);
if (!nm_utils_ipaddr_valid (AF_INET6, tmp))
goto error;
return tmp;
error:
if (!is_ip4_address (tmp))
nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 next_hop: %s", tmp);
g_free (tmp);
return NULL;
}
ip_block *
convert_ip4_config_block (const char *conn_name)
{
gchar **ipset;
guint length;
guint i;
gchar *ip;
char *def_gateway = NULL;
const char *routes;
ip_block *start = NULL, *current = NULL, *iblock = NULL;
g_return_val_if_fail (conn_name != NULL, NULL);
ipset = split_addresses (ifnet_get_data (conn_name, "config"));
length = ipset ? g_strv_length (ipset) : 0;
routes = ifnet_get_data (conn_name, "routes");
if (routes)
def_gateway = get_ip4_gateway (strstr (routes, "default"));
for (i = 0; i < length; i++) {
ip = ipset[i];
ip = strip_string (ip, '"');
iblock = create_ip4_block (ip);
if (iblock == NULL)
continue;
if (!iblock->next_hop && def_gateway != NULL)
iblock->next_hop = g_strdup (def_gateway);
if (start == NULL)
start = current = iblock;
else {
current->next = iblock;
current = iblock;
}
}
g_strfreev (ipset);
g_free (def_gateway);
return start;
}
ip_block *
convert_ip6_config_block (const char *conn_name)
{
gchar **ipset;
guint length;
guint i;
gchar *ip;
ip_block *start = NULL, *current = NULL, *iblock = NULL;
g_return_val_if_fail (conn_name != NULL, NULL);
ipset = split_addresses (ifnet_get_data (conn_name, "config"));
length = ipset ? g_strv_length (ipset) : 0;
for (i = 0; i < length; i++) {
ip = ipset[i];
ip = strip_string (ip, '"');
iblock = create_ip_block (ip);
if (iblock == NULL)
continue;
if (start == NULL)
start = current = iblock;
else {
current->next = iblock;
current = iblock;
}
}
g_strfreev (ipset);
return start;
}
ip_block *
convert_ip4_routes_block (const char *conn_name)
{
gchar **ipset;
guint length;
guint i;
gchar *ip;
ip_block *start = NULL, *current = NULL, *iblock = NULL;
g_return_val_if_fail (conn_name != NULL, NULL);
ipset = split_routes (ifnet_get_data (conn_name, "routes"));
length = ipset ? g_strv_length (ipset) : 0;
for (i = 0; i < length; i++) {
ip = ipset[i];
if (find_default_gateway_str (ip) || strstr (ip, "::")
|| !find_gateway_str (ip))
continue;
ip = strip_string (ip, '"');
iblock = create_ip4_block (ip);
if (iblock == NULL)
continue;
iblock->next_hop = get_ip4_gateway (ip);
if (start == NULL)
start = current = iblock;
else {
current->next = iblock;
current = iblock;
}
}
g_strfreev (ipset);
return start;
}
ip_block *
convert_ip6_routes_block (const char *conn_name)
{
gchar **ipset;
guint length;
guint i;
gchar *ip, *tmp_addr;
ip_block *start = NULL, *current = NULL, *iblock = NULL;
g_return_val_if_fail (conn_name != NULL, NULL);
ipset = split_routes (ifnet_get_data (conn_name, "routes"));
length = ipset ? g_strv_length (ipset) : 0;
for (i = 0; i < length; i++) {
ip = ipset[i];
ip = strip_string (ip, '"');
if (ip[0] == '\0')
continue;
if ((tmp_addr = find_default_gateway_str (ip)) != NULL) {
if (!is_ip6_address (tmp_addr))
continue;
else {
iblock = g_slice_new0 (ip_block);
iblock->ip = g_strdup ("::");
iblock->prefix = 128;
}
} else
iblock = create_ip_block (ip);
if (iblock == NULL)
continue;
iblock->next_hop = get_ip6_next_hop (ip);
if (iblock->next_hop == NULL) {
destroy_ip_block (iblock);
continue;
}
if (start == NULL)
start = current = iblock;
else {
current->next = iblock;
current = iblock;
}
}
g_strfreev (ipset);
return start;
}
void
destroy_ip_block (ip_block * iblock)
{
g_free (iblock->ip);
g_free (iblock->next_hop);
g_slice_free (ip_block, iblock);
}
void
set_ip4_dns_servers (NMSettingIPConfig *s_ip4, const char *conn_name)
{
const char *dns_servers;
gchar **server_list, *stripped;
guint length, i;
guint32 tmp_ip4_addr;
dns_servers = ifnet_get_data (conn_name, "dns_servers");
if (!dns_servers)
return;
stripped = g_strdup (dns_servers);
strip_string (stripped, '"');
server_list = g_strsplit (stripped, " ", 0);
g_free (stripped);
length = g_strv_length (server_list);
if (length)
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS,
TRUE, NULL);
for (i = 0; i < length; i++) {
g_strstrip (server_list[i]);
if (server_list[i][0] == '\0')
continue;
if (!inet_pton (AF_INET, server_list[i], &tmp_ip4_addr)) {
if (!is_ip6_address (server_list[i]))
nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]);
continue;
}
if (!nm_setting_ip_config_add_dns (s_ip4, server_list[i]))
nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]);
}
g_strfreev (server_list);
}
void
set_ip6_dns_servers (NMSettingIPConfig *s_ip6, const char *conn_name)
{
const char *dns_servers;
gchar **server_list, *stripped;
guint length, i;
struct in6_addr tmp_ip6_addr;
dns_servers = ifnet_get_data (conn_name, "dns_servers");
if (!dns_servers)
return;
stripped = g_strdup (dns_servers);
strip_string (stripped, '"');
server_list = g_strsplit (stripped, " ", 0);
g_free (stripped);
length = g_strv_length (server_list);
if (length)
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS,
TRUE, NULL);
for (i = 0; i < length; i++) {
g_strstrip (server_list[i]);
if (server_list[i][0] == '\0')
continue;
if (!inet_pton (AF_INET6, server_list[i], &tmp_ip6_addr)) {
if (is_ip6_address (server_list[i]))
nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]);
continue;
}
if (!nm_setting_ip_config_add_dns (s_ip6, server_list[i]))
nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]);
}
g_strfreev (server_list);
}
gboolean
is_managed (const char *conn_name)
{
gchar *config;
g_return_val_if_fail (conn_name != NULL, FALSE);
config = (gchar *) ifnet_get_data (conn_name, "managed");
if (!config)
return TRUE;
if (strcmp (config, "false") == 0)
return FALSE;
return TRUE;
}
static char *
_has_prefix_impl (char *str, const char *prefix, gsize prefix_len)
{
if (!g_str_has_prefix (str, prefix))
return NULL;
str += prefix_len;
if (!g_ascii_isspace (str[0]))
return NULL;
do {
str++;
} while (g_ascii_isspace (str[0]));
return str;
}
#define _has_prefix(STR, PREFIX) _has_prefix_impl (STR, PREFIX, NM_STRLEN (PREFIX))
void
get_dhcp_hostname_and_client_id (char **hostname, char **client_id)
{
const char *dhcp_client;
const gchar *dhcpcd_conf = SYSCONFDIR "/dhcpcd.conf";
const gchar *dhclient_conf = SYSCONFDIR "/dhcp/dhclient.conf";
gchar *line = NULL, *tmp = NULL, *contents = NULL, *tmp1;
gchar **all_lines;
guint line_num, i;
gboolean use_dhclient = FALSE;
*hostname = NULL;
*client_id = NULL;
dhcp_client = nm_dhcp_manager_get_config (nm_dhcp_manager_get ());
if (dhcp_client) {
if (!strcmp (dhcp_client, "dhclient")) {
g_file_get_contents (dhclient_conf, &contents, NULL,
NULL);
use_dhclient = TRUE;
} else if (!strcmp (dhcp_client, "dhcpcd")) {
g_file_get_contents (dhcpcd_conf, &contents, NULL,
NULL);
}
} else {
if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) {
g_file_get_contents (dhclient_conf, &contents, NULL,
NULL);
use_dhclient = TRUE;
} else if (g_file_test (dhcpcd_conf, G_FILE_TEST_IS_REGULAR)) {
g_file_get_contents (dhcpcd_conf, &contents, NULL,
NULL);
}
}
if (!contents)
return;
all_lines = g_strsplit (contents, "\n", 0);
line_num = g_strv_length (all_lines);
for (i = 0; i < line_num; i++) {
line = all_lines[i];
g_strstrip (line);
if (line[0] == '#' || line[0] == '\0')
continue;
if (!use_dhclient) {
// dhcpcd.conf
if ((tmp = _has_prefix (line, "hostname"))) {
if (tmp[0] != '\0') {
g_free (*hostname);
*hostname = g_strdup (tmp);
} else
nm_log_info (LOGD_SETTINGS, "dhcpcd hostname not defined, ignoring");
} else if ((tmp = _has_prefix (line, "clientid"))) {
if (tmp[0] != '\0') {
g_free (*client_id);
*client_id = g_strdup (tmp);
} else
nm_log_info (LOGD_SETTINGS, "dhcpcd clientid not defined, ignoring");
}
} else {
// dhclient.conf
if ((tmp1 = _has_prefix (line, "send"))) {
if ((tmp = _has_prefix (tmp1, "host-name"))) {
strip_string (tmp, ';');
strip_string (tmp, '"');
if (tmp[0] != '\0') {
g_free (*hostname);
*hostname = g_strdup (tmp);
} else
nm_log_info (LOGD_SETTINGS, "dhclient hostname not defined, ignoring");
} else if ((tmp = _has_prefix (tmp1, "dhcp-client-identifier"))) {
strip_string (tmp, ';');
if (tmp[0] != '\0') {
g_free (*client_id);
*client_id = g_strdup (tmp);
} else
nm_log_info (LOGD_SETTINGS, "dhclient clientid not defined, ignoring");
}
}
}
}
g_strfreev (all_lines);
g_free (contents);
}
gchar *backup_file (const gchar* target)
{
GFile *source, *backup;
gchar* backup_path;
GError *error = NULL;
source = g_file_new_for_path (target);
if (!g_file_query_exists (source, NULL)) {
g_object_unref (source);
return NULL;
}
backup_path = g_strdup_printf ("%s.bak", target);
backup = g_file_new_for_path (backup_path);
if (!g_file_copy (source, backup, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) {
nm_log_warn (LOGD_SETTINGS, "Backup failed: %s", error->message);
g_free (backup_path);
backup_path = NULL;
g_error_free (error);
}
g_object_unref (source);
g_object_unref (backup);
return backup_path;
}

View file

@ -1,71 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#ifndef _IFNET_UTILS_H
#define _IFNET_UTILS_H
#define IFNET_PLUGIN_NAME "SettingsPlugin-Ifnet"
#include <arpa/inet.h>
#include "nm-setting-ip6-config.h"
#include "nm-setting-ip4-config.h"
#include "nms-ifnet-net-parser.h"
#define has_default_ip4_route(conn_name) has_default_route((conn_name), &is_ip4_address)
#define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address)
typedef struct _ip_block {
char *ip;
guint32 prefix;
char *next_hop;
struct _ip_block *next;
} ip_block;
gboolean is_static_ip4 (const char *conn_name);
gboolean is_static_ip6 (const char *conn_name);
gboolean is_ip4_address (const char *in_address);
gboolean is_ip6_address (const char *in_address);
gboolean has_ip6_address (const char *conn_name);
gboolean has_default_route (const char *conn_name, gboolean (*check_fn) (const char *));
gboolean reload_parsers (void);
ip_block *convert_ip4_config_block (const char *conn_name);
ip_block *convert_ip6_config_block (const char *conn_name);
ip_block *convert_ip4_routes_block (const char *conn_name);
ip_block *convert_ip6_routes_block (const char *conn_name);
void destroy_ip_block (ip_block * iblock);
void set_ip4_dns_servers (NMSettingIPConfig * s_ip4, const char *conn_name);
void set_ip6_dns_servers (NMSettingIPConfig * s_ip6, const char *conn_name);
gchar *strip_string (gchar *str, gchar t);
gboolean is_managed (const char *conn_name);
gboolean is_hex (const char *value);
gboolean is_ascii (const char *value);
gboolean is_true (const char *str);
void get_dhcp_hostname_and_client_id (char **hostname, char **client_id);
gchar *backup_file (const gchar* target);
#endif

View file

@ -1,524 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service (ifnet)
*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#include "nm-default.h"
#include "nms-ifnet-plugin.h"
#include <string.h>
#include <gmodule.h>
#include "nm-utils.h"
#include "nm-setting-connection.h"
#include "nm-dbus-interface.h"
#include "settings/nm-settings-plugin.h"
#include "nm-config.h"
#include "NetworkManagerUtils.h"
#include "nms-ifnet-connection.h"
#include "nms-ifnet-net-utils.h"
#include "nms-ifnet-net-parser.h"
#include "nms-ifnet-wpa-parser.h"
#include "nms-ifnet-connection-parser.h"
#define IFNET_PLUGIN_NAME_PRINT "ifnet"
#define IFNET_PLUGIN_INFO "(C) 1999-2010 Gentoo Foundation, Inc. To report bugs please use bugs.gentoo.org with [networkmanager] or [qiaomuf] prefix."
#define IFNET_MANAGE_WELL_KNOWN_DEFAULT TRUE
/*****************************************************************************/
typedef void (*FileChangedFn) (gpointer user_data);
typedef struct {
FileChangedFn callback;
gpointer user_data;
} FileMonitorInfo;
/*****************************************************************************/
typedef struct {
GHashTable *connections; /* uuid::connection */
gboolean unmanaged_well_known;
GFileMonitor *net_monitor;
GFileMonitor *wpa_monitor;
} SettingsPluginIfnetPrivate;
struct _SettingsPluginIfnet {
GObject parent;
SettingsPluginIfnetPrivate _priv;
};
struct _SettingsPluginIfnetClass {
GObjectClass parent;
};
static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface);
G_DEFINE_TYPE_EXTENDED (SettingsPluginIfnet, settings_plugin_ifnet, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN,
settings_plugin_interface_init))
#define SETTINGS_PLUGIN_IFNET_GET_PRIVATE(self) _NM_GET_PRIVATE (self, SettingsPluginIfnet, SETTINGS_IS_PLUGIN_IFNET)
/*****************************************************************************/
static SettingsPluginIfnet *settings_plugin_ifnet_get (void);
NM_DEFINE_SINGLETON_GETTER (SettingsPluginIfnet, settings_plugin_ifnet_get, SETTINGS_TYPE_PLUGIN_IFNET);
/*****************************************************************************/
static void reload_connections (NMSettingsPlugin *config);
/*****************************************************************************/
static gboolean
is_managed_plugin (void)
{
return nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG,
NM_CONFIG_KEYFILE_GROUP_IFNET, NM_CONFIG_KEYFILE_KEY_IFNET_MANAGED,
IFNET_MANAGE_WELL_KNOWN_DEFAULT);
}
static void
file_changed (GFileMonitor * monitor,
GFile * file,
GFile * other_file,
GFileMonitorEvent event_type, gpointer user_data)
{
FileMonitorInfo *info;
switch (event_type) {
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
info = (FileMonitorInfo *) user_data;
info->callback (info->user_data);
break;
default:
break;
}
}
static GFileMonitor *
monitor_file_changes (const char *filename,
FileChangedFn callback, gpointer user_data)
{
GFile *file;
GFileMonitor *monitor;
FileMonitorInfo *info;
GError **error = NULL;
if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR))
return NULL;
file = g_file_new_for_path (filename);
monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, error);
g_object_unref (file);
if (monitor) {
info = g_new0 (FileMonitorInfo, 1);
info->callback = callback;
info->user_data = user_data;
g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free,
info);
g_signal_connect (monitor, "changed", G_CALLBACK (file_changed),
info);
} else {
nm_log_warn (LOGD_SETTINGS, "Monitoring %s failed, error: %s", filename,
error == NULL ? "nothing" : (*error)->message);
}
return monitor;
}
static void
setup_monitors (NMIfnetConnection *connection, gpointer user_data)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
if (!nm_config_get_monitor_connection_files (nm_config_get ()))
return;
if (priv->net_monitor || priv->wpa_monitor)
return;
priv->net_monitor = monitor_file_changes (CONF_NET_FILE,
(FileChangedFn) reload_connections,
user_data);
priv->wpa_monitor = monitor_file_changes (WPA_SUPPLICANT_CONF,
(FileChangedFn) reload_connections,
user_data);
}
static void
cancel_monitors (NMIfnetConnection *connection, gpointer user_data)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (user_data);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
if (priv->net_monitor) {
g_file_monitor_cancel (priv->net_monitor);
g_clear_object (&priv->net_monitor);
}
if (priv->wpa_monitor) {
g_file_monitor_cancel (priv->wpa_monitor);
g_clear_object (&priv->wpa_monitor);
}
}
static void
connection_removed_cb (NMSettingsConnection *obj, gpointer user_data)
{
g_hash_table_remove (SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) user_data)->connections,
nm_connection_get_uuid (NM_CONNECTION (obj)));
}
static void
track_new_connection (SettingsPluginIfnet *self, NMIfnetConnection *connection)
{
g_hash_table_insert (SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self)->connections,
g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))),
g_object_ref (connection));
g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED,
G_CALLBACK (connection_removed_cb),
self);
}
static void
reload_connections (NMSettingsPlugin *config)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (config);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
GList *conn_names = NULL, *n_iter = NULL;
gboolean auto_refresh;
GError *error = NULL;
/* save names for removing unused connections */
GHashTable *new_connections = NULL;
GHashTableIter iter;
const char *uuid;
NMSettingsConnection *candidate;
if (priv->unmanaged_well_known)
return;
if (!reload_parsers ())
return;
nm_log_info (LOGD_SETTINGS, "Loading connections");
auto_refresh = nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG,
NM_CONFIG_KEYFILE_GROUP_IFNET, NM_CONFIG_KEYFILE_KEY_IFNET_AUTO_REFRESH,
FALSE);
new_connections = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref);
/* Reread on-disk data and refresh in-memory connections from it */
conn_names = ifnet_get_connection_names ();
for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) {
NMIfnetConnection *new;
NMIfnetConnection *old;
const char *conn_name = n_iter->data;
/* read the new connection */
new = nm_ifnet_connection_new (NULL, conn_name);
if (!new)
continue;
g_signal_connect (G_OBJECT (new), "ifnet_setup_monitors",
G_CALLBACK (setup_monitors), config);
g_signal_connect (G_OBJECT (new), "ifnet_cancel_monitors",
G_CALLBACK (cancel_monitors), config);
old = g_hash_table_lookup (priv->connections,
nm_connection_get_uuid (NM_CONNECTION (new)));
if (old && new) {
if (auto_refresh) {
/* If connection has changed, remove the old one and add the
* new one to force a disconnect/reconnect with new settings
*/
if (!nm_connection_compare (NM_CONNECTION (old),
NM_CONNECTION (new),
NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS |
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) {
nm_log_info (LOGD_SETTINGS, "Auto refreshing %s", conn_name);
nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (old));
track_new_connection (self, new);
if (is_managed_plugin () && is_managed (conn_name))
g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, new);
}
} else {
/* Update existing connection with new settings */
if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (old),
NM_CONNECTION (new),
NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED,
NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE,
"ifnet-update",
&error)) {
/* Shouldn't ever get here as 'new' was verified by the reader already
* and the UUID did not change. */
g_assert_not_reached ();
}
g_assert_no_error (error);
nm_log_info (LOGD_SETTINGS, "Connection %s updated",
nm_connection_get_id (NM_CONNECTION (new)));
}
g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED);
} else if (new) {
track_new_connection (self, new);
if (is_managed_plugin () && is_managed (conn_name))
g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, new);
}
/* Track all valid connections so we can remove deleted ones later */
g_hash_table_insert (new_connections,
(gpointer) nm_connection_get_uuid (NM_CONNECTION (new)),
new);
}
/* remove deleted/unused connections */
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, (gpointer) &uuid, (gpointer) &candidate)) {
/* only saved connections (which have a conn_name) get removed; unsaved
* ones obviously don't exist in /etc/conf.d/net yet and shouldn't get
* blown away by net file changes.
*/
if ( nm_ifnet_connection_get_conn_name (NM_IFNET_CONNECTION (candidate))
&& !g_hash_table_lookup (new_connections, uuid)) {
nm_settings_connection_signal_remove (candidate);
g_hash_table_iter_remove (&iter);
}
}
g_hash_table_destroy (new_connections);
g_list_free (conn_names);
}
static NMSettingsConnection *
add_connection (NMSettingsPlugin *config,
NMConnection *source,
gboolean save_to_disk,
GError **error)
{
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config);
NMIfnetConnection *new = NULL;
/* Ensure we reject attempts to add the connection long before we're
* asked to write it to disk.
*/
if (!ifnet_can_write_connection (source, error))
goto out;
if (save_to_disk) {
if (!ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, NULL, NULL, error))
goto out;
reload_connections (config);
new = g_hash_table_lookup (priv->connections, nm_connection_get_uuid (source));
} else {
new = nm_ifnet_connection_new (source, NULL);
if (new) {
track_new_connection (SETTINGS_PLUGIN_IFNET (config), new);
/* track_new_connection refs 'new' */
g_object_unref (new);
}
}
out:
if (!new && error && !*error) {
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
"The ifnet plugin cannot add the connection (unknown error).");
}
return (NMSettingsConnection *) new;
}
static void
check_unmanaged (gpointer key, gpointer data, gpointer user_data)
{
NMIfnetConnection *connection = NM_IFNET_CONNECTION (data);
GSList **list = (GSList **) user_data;
const char *mac, *conn_name;
char *unmanaged_spec;
GSList *iter;
conn_name = nm_ifnet_connection_get_conn_name (connection);
if (!conn_name || is_managed (conn_name))
return;
nm_log_info (LOGD_SETTINGS, "Checking unmanaged: %s", conn_name);
mac = ifnet_get_data (conn_name, "mac");
if (mac)
unmanaged_spec = g_strdup_printf ("mac:%s", mac);
else
unmanaged_spec = g_strdup_printf ("interface-name:%s", conn_name);
/* Just return if the unmanaged spec is already in the list */
for (iter = *list; iter; iter = g_slist_next (iter)) {
if (g_str_equal (iter->data, unmanaged_spec)) {
g_free (unmanaged_spec);
return;
}
}
nm_log_info (LOGD_SETTINGS, "Add unmanaged: %s", unmanaged_spec);
*list = g_slist_prepend (*list, unmanaged_spec);
}
static GSList *
get_unmanaged_specs (NMSettingsPlugin * config)
{
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config);
GSList *list = NULL;
nm_log_info (LOGD_SETTINGS, "getting unmanaged specs...");
g_hash_table_foreach (priv->connections, check_unmanaged, &list);
return list;
}
static GSList *
get_connections (NMSettingsPlugin *config)
{
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) config);
GSList *connections = NULL;
GHashTableIter iter;
NMIfnetConnection *connection;
nm_log_info (LOGD_SETTINGS, "(%p) ... get_connections.", config);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) {
const char *conn_name = nm_ifnet_connection_get_conn_name (connection);
if (!conn_name || (!priv->unmanaged_well_known && is_managed (conn_name)))
connections = g_slist_prepend (connections, connection);
}
nm_log_info (LOGD_SETTINGS, "(%p) connections count: %d",
config, g_slist_length (connections));
return connections;
}
/*****************************************************************************/
static void
get_property (GObject * object, guint prop_id, GValue * value,
GParamSpec * pspec)
{
switch (prop_id) {
case NM_SETTINGS_PLUGIN_PROP_NAME:
g_value_set_string (value, IFNET_PLUGIN_NAME_PRINT);
break;
case NM_SETTINGS_PLUGIN_PROP_INFO:
g_value_set_string (value, IFNET_PLUGIN_INFO);
break;
case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES:
g_value_set_uint (value,
NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
init (NMSettingsPlugin *config)
{
SettingsPluginIfnet *self = SETTINGS_PLUGIN_IFNET (config);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE (self);
nm_log_info (LOGD_SETTINGS, "Initializing!");
priv->connections = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref);
priv->unmanaged_well_known = !is_managed_plugin ();
nm_log_info (LOGD_SETTINGS, "management mode: %s",
priv->unmanaged_well_known ? "unmanaged" : "managed");
setup_monitors (NULL, config);
reload_connections (config);
nm_log_info (LOGD_SETTINGS, "Initialzation complete!");
}
/*****************************************************************************/
static void
settings_plugin_ifnet_init (SettingsPluginIfnet * plugin)
{
}
static void
dispose (GObject * object)
{
SettingsPluginIfnet *plugin = SETTINGS_PLUGIN_IFNET (object);
SettingsPluginIfnetPrivate *priv = SETTINGS_PLUGIN_IFNET_GET_PRIVATE ((SettingsPluginIfnet *) plugin);
cancel_monitors (NULL, object);
if (priv->connections) {
g_hash_table_destroy (priv->connections);
priv->connections = NULL;
}
ifnet_destroy ();
wpa_parser_destroy ();
G_OBJECT_CLASS (settings_plugin_ifnet_parent_class)->dispose (object);
}
static void
settings_plugin_ifnet_class_init (SettingsPluginIfnetClass * req_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
object_class->dispose = dispose;
object_class->get_property = get_property;
g_object_class_override_property (object_class,
NM_SETTINGS_PLUGIN_PROP_NAME,
NM_SETTINGS_PLUGIN_NAME);
g_object_class_override_property (object_class,
NM_SETTINGS_PLUGIN_PROP_INFO,
NM_SETTINGS_PLUGIN_INFO);
g_object_class_override_property (object_class,
NM_SETTINGS_PLUGIN_PROP_CAPABILITIES,
NM_SETTINGS_PLUGIN_CAPABILITIES);
}
static void
settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface)
{
plugin_iface->init = init;
plugin_iface->get_connections = get_connections;
plugin_iface->get_unmanaged_specs = get_unmanaged_specs;
plugin_iface->add_connection = add_connection;
plugin_iface->reload_connections = reload_connections;
}
/*****************************************************************************/
G_MODULE_EXPORT GObject *
nm_settings_plugin_factory (void)
{
return G_OBJECT (g_object_ref (settings_plugin_ifnet_get ()));
}

View file

@ -1,38 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service (ifnet)
*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#ifndef _PLUGIN_H_
#define _PLUGIN_H_
#define SETTINGS_TYPE_PLUGIN_IFNET (settings_plugin_ifnet_get_type ())
#define SETTINGS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnet))
#define SETTINGS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnetClass))
#define SETTINGS_IS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SETTINGS_TYPE_PLUGIN_IFNET))
#define SETTINGS_IS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SETTINGS_TYPE_PLUGIN_IFNET))
#define SETTINGS_PLUGIN_IFNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SETTINGS_TYPE_PLUGIN_IFNET, SettingsPluginIfnetClass))
typedef struct _SettingsPluginIfnet SettingsPluginIfnet;
typedef struct _SettingsPluginIfnetClass SettingsPluginIfnetClass;
GType settings_plugin_ifnet_get_type (void);
#endif

View file

@ -1,583 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#include "nm-default.h"
#include "nms-ifnet-wpa-parser.h"
#include <string.h>
#include <stdlib.h>
#include "settings/nm-settings-plugin.h"
#include "nms-ifnet-net-parser.h"
#include "nms-ifnet-net-utils.h"
/* Security information */
static GHashTable *wsec_table = NULL;
/* Global information used for writing */
static GHashTable *wsec_global_table = NULL;
static gboolean wpa_parser_data_changed = FALSE;
static long
wpa_get_long (GHashTable *table, const char *key)
{
return atol (g_hash_table_lookup (table, key));
}
static void
destroy_security (GHashTable * network)
{
gpointer key, value;
GHashTableIter iter;
g_return_if_fail (network);
g_hash_table_iter_init (&iter, network);
while (g_hash_table_iter_next (&iter, &key, &value)) {
g_free (key);
g_free (value);
}
g_hash_table_destroy (network);
}
static GHashTable *
add_security (GHashTable *security)
{
GHashTable *oldsecurity;
const char *ssid, *value;
char *ssid_key;
gboolean is_hex_ssid;
/* Every security information should have a ssid */
ssid = g_hash_table_lookup (security, "ssid");
if (!ssid) {
destroy_security (security);
return NULL;
}
/* Hex format begins with " */
is_hex_ssid = (ssid[0] != '"');
if ((value = g_hash_table_lookup (security, "disabled")) != NULL) {
if (strcmp (value, "1") == 0) {
destroy_security (security);
return NULL;
}
}
/* Default priority is 1 */
if (g_hash_table_lookup (security, "priority") == NULL)
g_hash_table_insert (security, g_strdup ("priority"),
g_strdup ("1"));
oldsecurity = g_hash_table_lookup (wsec_table, ssid);
/* Security with lower priority will be ignored */
if (oldsecurity != NULL) {
if (wpa_get_long (oldsecurity, "priority") >=
wpa_get_long (security, "priority")) {
destroy_security (security);
return NULL;
} else {
g_hash_table_remove (wsec_table, ssid);
destroy_security (oldsecurity);
}
}
/* format ssid */
ssid_key =
is_hex_ssid ? g_strdup_printf ("0x%s",
ssid) :
strip_string (g_strdup (ssid), '"');
g_hash_table_insert (wsec_table, ssid_key, security);
return security;
}
static void
add_key_value (GHashTable * network, gchar * line)
{
gpointer orig_key, orig_value;
gchar **key_value;
if (g_str_has_prefix (line, "network={"))
line += 9;
strip_string (line, '{');
strip_string (line, '}');
if (line[0] == '\0')
return;
key_value = g_strsplit (line, "=", 2);
if (g_strv_length (key_value) != 2) {
g_strfreev (key_value);
return;
}
g_strstrip (key_value[0]);
g_strstrip (key_value[1]);
/* Reserve quotes for psk, wep_key, ssid
* Quotes will determine whether they are hex format */
if (strcmp (key_value[0], "psk") != 0
&& !g_str_has_prefix (key_value[0], "wep_key")
&& strcmp (key_value[0], "ssid") != 0)
strip_string (key_value[1], '"');
/* This sucks */
if (g_hash_table_lookup_extended (network, key_value[0], &orig_key, &orig_value)) {
g_hash_table_remove (network, orig_key);
g_free (orig_key);
g_free (orig_value);
}
g_hash_table_insert (network, g_strdup (key_value[0]),
g_strdup (key_value[1]));
g_strfreev (key_value);
}
static void
add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key)
{
if (one_wep_key[0] == 's') {
//asc key
g_hash_table_insert (table,
g_strdup_printf ("wep_key%d", key_num - 1),
g_strdup_printf ("\"%s\"",
one_wep_key + 2));
} else {
gchar buf[30];
int i = 0, j = 0;
//hex key
while (one_wep_key[i] != '\0') {
if (one_wep_key[i] != '-')
buf[j++] = one_wep_key[i];
i++;
}
buf[j] = '\0';
g_hash_table_insert (table,
g_strdup_printf ("wep_key%d", key_num - 1),
g_strdup (buf));
}
}
/* Reading wep security information from /etc/conf.d/net.
* This should not be used in future, use wpa_supplicant instead. */
static void
add_keys_from_net (void)
{
GList *names = ifnet_get_connection_names ();
GList *iter = names;
gchar *wep_keys = "(\\[([1-4])\\]\\s+(s:\\w{5}|s:\\w{13}|"
"([\\da-fA-F]{4}\\-){2}[\\da-fA-F]{2}|"
"([\\da-fA-F]{4}\\-){6}[\\da-fA-F]{2})\\s+)";
gchar *key_method =
"\\s+key\\s+\\[([1-4])\\]\\s+enc\\s+(open|restricted)";
GRegex *regex_keys = g_regex_new (wep_keys, 0, 0, NULL);
GRegex *regex_method = g_regex_new (key_method, 0, 0, NULL);
GMatchInfo *keys_info;
GMatchInfo *method_info;
while (iter) {
gchar *conn_name = iter->data;
GHashTable *table;
const char *key_str;
if ((key_str = ifnet_get_data (conn_name, "key")) == NULL) {
iter = g_list_next (iter);
continue;
}
wpa_add_security (conn_name);
table = _get_hash_table (conn_name);
/* Give lowest priority */
wpa_set_data (conn_name, "priority", "0");
g_regex_match (regex_keys, key_str, 0, &keys_info);
/* add wep keys */
while (g_match_info_matches (keys_info)) {
gchar *key_num = g_match_info_fetch (keys_info, 2);
gchar *one_wep_key = g_match_info_fetch (keys_info, 3);
add_one_wep_key (table, atoi (key_num), one_wep_key);
g_free (key_num);
g_free (one_wep_key);
g_match_info_next (keys_info, NULL);
}
g_match_info_free (keys_info);
g_regex_match (regex_method, key_str, 0, &method_info);
/* set default key index and auth alg */
if (g_match_info_matches (method_info)) {
gchar *default_idx =
g_match_info_fetch (method_info, 1);
gchar *method = g_match_info_fetch (method_info, 2);
default_idx[0]--;
g_hash_table_insert (table, g_strdup ("wep_tx_keyidx"),
default_idx);
g_hash_table_insert (table, g_strdup ("auth_alg"),
g_ascii_strup (method, -1));
}
g_match_info_free (method_info);
add_security (table);
iter = g_list_next (iter);
}
g_list_free (names);
g_regex_unref (regex_keys);
g_regex_unref (regex_method);
}
static void
add_global_data (gchar * line)
{
gchar **key_value;
g_strstrip (line);
key_value = g_strsplit (line, "=", 2);
if (g_strv_length (key_value) != 2) {
nm_log_warn (LOGD_SETTINGS, "Can't handle this line: %s\n", line);
g_strfreev (key_value);
return;
}
g_hash_table_insert (wsec_global_table,
g_strdup (g_strstrip (key_value[0])),
g_strdup (g_strstrip (key_value[1])));
g_strfreev (key_value);
}
void
wpa_parser_init (const char *wpa_supplicant_conf)
{
GIOChannel *channel = NULL;
gchar *line;
gboolean complete = FALSE;
wpa_parser_data_changed = FALSE;
wsec_table = g_hash_table_new (nm_str_hash, g_str_equal);
wsec_global_table = g_hash_table_new (nm_str_hash, g_str_equal);
if (g_file_test (wpa_supplicant_conf, G_FILE_TEST_IS_REGULAR))
channel =
g_io_channel_new_file (wpa_supplicant_conf, "r", NULL);
if (channel == NULL) {
nm_log_warn (LOGD_SETTINGS, "Can't open %s for wireless security",
wpa_supplicant_conf);
return;
}
while (g_io_channel_read_line (channel, &line, NULL, NULL, NULL)
!= G_IO_STATUS_EOF) {
g_strstrip (line);
if (line[0] != '#' && line[0] != '\0') {
if (strstr (line, "network={") == NULL) {
add_global_data (line);
g_free (line);
continue;
} else {
GHashTable *network =
g_hash_table_new (nm_str_hash, g_str_equal);
do {
gchar *quote_start, *quote_end = NULL, *comment;
if (line[0] == '#' || line[0] == '\0') {
g_free (line);
continue;
}
/* ignore inline comments unless inside
a double-quoted string */
if ((quote_start = strchr (line, '"')) != NULL)
quote_end = strrchr (quote_start + 1, '"');
if ((comment = strchr ((quote_end != NULL) ?
quote_end : line, '#')) != NULL)
*comment = '\0';
if (strstr (line, "}") != NULL)
complete = TRUE;
add_key_value (network, line);
g_free (line);
} while (complete == FALSE
&&
g_io_channel_read_line
(channel, &line, NULL,
NULL, NULL) != G_IO_STATUS_EOF);
add_security (network);
//EOF in inner loop
if (complete == FALSE) {
g_free (line);
break;
}
complete = FALSE;
}
} else
g_free (line);
}
g_io_channel_shutdown (channel, FALSE, NULL);
g_io_channel_unref (channel);
add_keys_from_net ();
}
const char *
wpa_get_value (const char *ssid, const char *key)
{
GHashTable *target = g_hash_table_lookup (wsec_table, ssid);
if (target)
return g_hash_table_lookup (target, key);
return NULL;
}
gboolean
exist_ssid (const char *ssid)
{
return g_hash_table_lookup (wsec_table, ssid) != NULL;
}
GHashTable *
_get_hash_table (const char *ssid)
{
return g_hash_table_lookup (wsec_table, ssid);
}
static gchar *quoted_keys[] =
{ "identity", "cert", "private", "phase", "password", NULL };
/* tell whether the key needs quotes when writing is performed */
static gboolean
need_quote (gchar * key)
{
int i = 0;
while (quoted_keys[i] != NULL) {
if (strstr (key, quoted_keys[i]))
return TRUE;
i++;
}
return FALSE;
}
gboolean
wpa_flush_to_file (const char *config_file)
{
GIOChannel *channel;
GError *error = NULL;
gpointer key, value, ssid, security;
GHashTableIter iter, iter_security;
gchar *out_line;
gsize bytes_written;
gboolean result = FALSE;
if (!wpa_parser_data_changed)
return TRUE;
if (!wsec_table || !wsec_global_table)
return FALSE;
backup_file (config_file);
channel = g_io_channel_new_file (config_file, "w", NULL);
if (!channel) {
nm_log_warn (LOGD_SETTINGS, "Can't open file %s for writing", config_file);
return FALSE;
}
g_hash_table_iter_init (&iter, wsec_global_table);
nm_log_info (LOGD_SETTINGS, "Writing to %s", config_file);
g_io_channel_write_chars (channel,
"#Generated by NetworkManager\n"
"###### Global Configuration ######\n",
-1, &bytes_written, &error);
if (error)
goto done;
/* Writing global information */
while (g_hash_table_iter_next (&iter, &key, &value)) {
out_line =
g_strdup_printf ("%s=%s\n", (gchar *) key, (gchar *) value);
g_io_channel_write_chars (channel, out_line, -1, &bytes_written,
&error);
if (bytes_written == 0 || error)
break;
g_free (out_line);
}
if (error)
goto done;
g_io_channel_write_chars (channel,
"\n###### Security Configuration ######\n",
-1, &bytes_written, &error);
if (error)
goto done;
g_hash_table_iter_init (&iter, wsec_table);
/* Writing security */
while (g_hash_table_iter_next (&iter, &ssid, &security)) {
g_hash_table_iter_init (&iter_security,
(GHashTable *) security);
g_io_channel_write_chars (channel, "network={\n", -1,
&bytes_written, &error);
if (error)
goto done;
while (g_hash_table_iter_next (&iter_security, &key, &value)) {
out_line =
g_strdup_printf (need_quote ((gchar *) key) ?
"\t%s=\"%s\"\n" : "\t%s=%s\n",
(gchar *) key, (gchar *) value);
g_io_channel_write_chars (channel, out_line, -1,
&bytes_written, &error);
if (bytes_written == 0 || error)
goto done;
g_free (out_line);
}
g_io_channel_write_chars (channel, "}\n\n", -1, &bytes_written, &error);
}
g_io_channel_flush (channel, &error);
if (error)
goto done;
wpa_parser_data_changed = FALSE;
result = TRUE;
done:
if (error) {
nm_log_warn (LOGD_SETTINGS, "Error writing WPA configuration: %s", error->message);
g_error_free (error);
}
g_io_channel_shutdown (channel, FALSE, NULL);
g_io_channel_unref (channel);
return result;
}
/* If value is NULL, this method will delete old key value pair */
void
wpa_set_data (const char *ssid, const char *key, const char *value)
{
gpointer old_key = NULL, old_value = NULL;
GHashTable *security = g_hash_table_lookup (wsec_table, ssid);
gchar * stripped = NULL;
g_return_if_fail (security != NULL);
if (value){
stripped = g_strdup(value);
if (strcmp (key, "ssid") != 0 && strcmp (key, "psk") != 0
&& !g_str_has_prefix (key, "wep_key"))
strip_string (stripped, '"');
}
/* Remove old key value pairs */
if (g_hash_table_lookup_extended
(security, key, &old_key, &old_value)) {
if (stripped && !strcmp(old_value, stripped)){
g_free (stripped);
return;
}
g_hash_table_remove (security, old_key);
g_free (old_key);
g_free (old_value);
} else if (!value)
return;
/* Add new key value */
if (stripped)
g_hash_table_insert (security, g_strdup (key), stripped);
wpa_parser_data_changed = TRUE;
}
gboolean
wpa_has_security (const char *ssid)
{
return g_hash_table_lookup (wsec_table, ssid) != NULL;
}
gboolean
wpa_add_security (const char *ssid)
{
if (wpa_has_security (ssid))
return TRUE;
else {
GHashTable *security =
g_hash_table_new (nm_str_hash, g_str_equal);
gchar *ssid_i;
nm_log_info (LOGD_SETTINGS, "Adding security for %s", ssid);
if (g_str_has_prefix (ssid, "0x")) {
/* hex ssid */
ssid_i = g_strdup (ssid + 2);
} else {
/* ascii ssid requires quotes */
ssid_i = g_strdup_printf ("\"%s\"", ssid);
}
g_hash_table_insert (security, strdup ("ssid"), ssid_i);
g_hash_table_insert (security, strdup ("priority"),
strdup ("1"));
g_hash_table_insert (wsec_table, g_strdup (ssid), security);
wpa_parser_data_changed = TRUE;
return TRUE;
}
}
gboolean
wpa_delete_security (const char *ssid)
{
gpointer old_key, old_value;
g_return_val_if_fail (wsec_table != NULL && ssid != NULL, FALSE);
nm_log_info (LOGD_SETTINGS, "Deleting security for %s", ssid);
if (!g_hash_table_lookup_extended
(wsec_table, ssid, &old_key, &old_value))
return FALSE;
g_hash_table_remove (wsec_table, old_key);
g_free (old_key);
destroy_security ((GHashTable *) old_value);
wpa_parser_data_changed = TRUE;
return TRUE;
}
void
wpa_parser_destroy (void)
{
GHashTableIter iter;
gpointer key;
gpointer value;
/* Destroy security */
if (wsec_table) {
g_hash_table_iter_init (&iter, wsec_table);
while (g_hash_table_iter_next (&iter, &key, &value)) {
destroy_security ((GHashTable *) value);
g_free (key);
}
g_hash_table_destroy (wsec_table);
wsec_table = NULL;
}
/* Destroy global data */
if (wsec_global_table) {
g_hash_table_iter_init (&iter, wsec_global_table);
while (g_hash_table_iter_next (&iter, &key, &value)) {
g_free (key);
g_free (value);
}
g_hash_table_destroy (wsec_global_table);
wsec_global_table = NULL;
}
}

View file

@ -1,41 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#ifndef _WPA_PARSER_H
#define _WPA_PARSER_H
#define WPA_SUPPLICANT_CONF SYSCONFDIR "/wpa_supplicant/wpa_supplicant.conf"
void wpa_parser_init (const char *wpa_supplicant_conf);
void wpa_parser_destroy (void);
/* reader functions */
const char *wpa_get_value (const char *ssid, const char *key);
gboolean exist_ssid (const char *ssid);
GHashTable *_get_hash_table (const char *ssid);
gboolean wpa_has_security (const char *ssid);
/* writer functions */
gboolean wpa_flush_to_file (const char *config_file);
void wpa_set_data (const char *ssid, const char *key, const char *value);
gboolean wpa_add_security (const char *ssid);
gboolean wpa_delete_security (const char *ssid);
#endif

View file

@ -1,20 +0,0 @@
test_unit = 'test-ifnet'
test_ifnet_dir = meson.current_source_dir()
cflags = [
'-DSYSCONFDIR="nonexistent"',
'-DTEST_IFNET_DIR="@0@"'.format(test_ifnet_dir),
'-DTEST_SCRATCH_DIR="@0@"'.format(test_ifnet_dir),
'-DTEST_WPA_SUPPLICANT_CONF="@0@"'.format(join_paths(test_ifnet_dir, 'wpa_supplicant.conf'))
]
exe = executable(
test_unit,
test_unit + '.c',
dependencies: test_core_dep,
c_args: cflags,
link_with: libnms_ifnet_core
)
test(test_unit, exe)

View file

@ -1,158 +0,0 @@
# This blank configuration will automatically use DHCP for any net.*
# scripts in /etc/init.d. To create a more complete configuration,
# please review /etc/conf.d/net.example and save your configuration
# in /etc/conf.d/net (this file :]!).
modules="!wpa_supplicant"
config_eth0=(
"202.117.16.121 netmask 255.255.255.0 brd 202.117.16.255"
"192.168.4.121/24"
"dhcp6"
)
routes_eth0=( "default via 202.117.16.1"
"192.168.4.0/24 via 192.168.4.1")
dns_servers_eth0="202.117.0.20 202.117.0.21"
dns_search_eth0="p12.edu.cn p13.edu.cn"
config_eth1=(
"dhcp"
)
enable_ipv6_eth1="true"
routes_eth1=( "default via 202.117.16.1" )
dns_servers_eth1="202.117.0.20 202.117.0.21"
config_eth2=(
"202.117.16.1211 netmask 255.255.255.0 brd 202.117.16.255"
"192.168.4.121/24"
"4321:0:1:2:3:4:567:89ab/64"
)
routes_eth2=("default via 4321:0:1:2:3:4:567:89ab")
enable_ipv6_eth2="true"
config_eth3=("nufjlsjlll")
managed_eth4="false"
routes_eth4=("default via 4321:0:1:2:3:4:567:89ab")
config_eth5=("dhcp")
config_eth7=( "dhcp" )
auto_eth7="true"
# missing config_eth8
auto_eth8="true"
#new openrc style
config_eth9="202.117.16.10/24 202.117.17.10/24"
routes_eth9="default via 202.117.16.1
10.0.0.0/8 via 192.168.0.1
"
config_eth10="202.117.16.2 netmask 255.255.255.0"
routes_eth10="10.0.0.0/8 via 192.168.0.1"
config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255")
routes_myxjtu2=("default via 202.117.16.1")
dns_servers_myxjtu2="202.117.0.20 202.117.0.21"
#key_myxjtu2="[1] s:xjtud key [1] enc restricted"
#key_eth6="[1] aaaa-4444-3d [2] s:xjtudlc key [1] enc open"
username_ppp0='user'
password_ppp0='password'
config_qiaomuf=("dhcp")
config_1xtest=("dhcp")
config_0xab3ace=("dhcp")
modules=( "iproute2" )
config_kvm0=( "null" )
config_kvm1=( "null" )
tuntap_kvm0="tap"
tuntap_kvm1="tap"
tunctl_kvm0="-u user"
tunctl_kvm1="-u user"
bridge_br0="eth0 kvm0 kvm1"
config_br0=( "192.168.1.10/24" )
brctl_br0=( "setfd 0")
dhcp_eth1="nosendhost nontp -I"
predown() {
# The default in the script is to test for NFS root and disallow
# downing interfaces in that case. Note that if you specify a
# predown() function you will override that logic. Here it is, in
# case you still want it...
if is_net_fs /; then
eerror "root filesystem is network mounted -- can't stop ${IFACE}"
return 1
fi
# Remember to return 0 on success
return 0
}
postup() {
# This function could be used, for example, to register with a
# dynamic DNS service. Another possibility would be to
# send/receive mail once the interface is brought up.
# Here is an example that allows the use of iproute rules
# which have been configured using the rules_eth0 variable.
#rules_eth0=" \
# 'from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100' \
# 'from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100' \
#"
eval set -- \$rules_${IFVAR}
if [ $# != 0 ]; then
einfo "Adding IP policy routing rules"
eindent
# Ensure that the kernel supports policy routing
if ! ip rule list | grep -q "^"; then
eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)"
eerror "in your kernel to use ip rules"
else
for x; do
ebegin "${x}"
ip rule add ${x}
eend $?
done
fi
eoutdent
# Flush the cache
ip route flush cache dev "${IFACE}"
fi
}
postdown() {
# Enable Wake-On-LAN for every interface except for lo
# Probably a good idea to set ifdown="no" in /etc/conf.d/net
# as well ;)
[ "${IFACE}" != "lo" ] && ethtool -s "${IFACE}" wol g
Automatically erase any ip rules created in the example postup above
if interface_exists "${IFACE}"; then
# Remove any rules for this interface
local rule
ip rule list | grep " iif ${IFACE}[ ]*" | {
while read rule; do
rule="${rule#*:}"
ip rule del ${rule}
done
}
# Flush the route cache
ip route flush cache dev "${IFACE}"
fi
# Return 0 always
return 0
}
failup() {
# This function is mostly here for completeness... I haven't
# thought of anything nifty to do with it yet ;-)
}
faildown()
{}

View file

@ -1,864 +0,0 @@
##############################################################################
# QUICK-START
#
# The quickest start is if you want to use DHCP.
# In that case, everything should work out of the box, no configuration
# necessary, though the startup script will warn you that you haven't
# specified anything.
# WARNING :- some examples have a mixture of IPv4 (ie 192.168.0.1) and IPv6
# (ie 4321:0:1:2:3:4:567:89ab) internet addresses. They only work if you have
# the relevant kernel option enabled. So if you don't have an IPv6 enabled
# kernel then remove the IPv6 address from your config.
# If you want to use a static address or use DHCP explicitly, jump
# down to the section labelled INTERFACE HANDLERS.
#
# If you want to do anything more fancy, you should take the time to
# read through the rest of this file.
##############################################################################
# MODULES
#
# We now support modular networking scripts which means we can easily
# add support for new interface types and modules while keeping
# compatability with existing ones.
#
# Modules load by default if the package they need is installed. If
# you specify a module here that doesn't have it's package installed
# then you get an error stating which package you need to install.
# Ideally, you only use the modules setting when you have two or more
# packages installed that supply the same service.
#
# In other words, you probably should DO NOTHING HERE...
# Prefer ifconfig over iproute2
modules=( "ifconfig" )
# You can also specify other modules for an interface
# In this case we prefer udhcpc over dhcpcd
modules_eth0=( "udhcpc" )
# You can also specify which modules not to use - for example you may be
# using a supplicant or linux-wlan-ng to control wireless configuration but
# you still want to configure network settings per ESSID associated with.
modules=( "!iwconfig" "!wpa_supplicant" )
# IMPORTANT: If you need the above, please disable modules in that order
##############################################################################
# INTERFACE HANDLERS
#
# We provide two interface handlers presently: ifconfig and iproute2.
# You need one of these to do any kind of network configuration.
# For ifconfig support, emerge sys-apps/net-tools
# For iproute2 support, emerge sys-apps/iproute2
# If you don't specify an interface then we prefer iproute2 if it's installed
# To prefer ifconfig over iproute2
modules=( "ifconfig" )
# For a static configuration, use something like this
# (They all do exactly the same thing btw)
config_eth0=( "192.168.0.2/24" )
config_eth0=( "192.168.0.2 netmask 255.255.255.0" )
# We can also specify a broadcast
config_eth0=( "192.168.0.2/24 brd 192.168.0.255" )
config_eth0=( "192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255" )
# If you need more than one address, you can use something like this
# NOTE: ifconfig creates an aliased device for each extra IPv4 address
# (eth0:1, eth0:2, etc)
# iproute2 does not do this as there is no need to
config_eth0=(
"192.168.0.2/24"
"192.168.0.3/24"
"192.168.0.4/24"
)
# Or you can use sequence expressions
config_eth0=( "192.168.0.{2..4}/24" )
# which does the same as above. Be careful though as if you use this and
# fallbacks, you have to ensure that both end up with the same number of
# values otherwise your fallback won't work correctly.
# You can also use IPv6 addresses
# (you should always specify a prefix length with IPv6 here)
config_eth0=(
"192.168.0.2/24"
"4321:0:1:2:3:4:567:89ab/64"
"4321:0:1:2:3:4:567:89ac/64"
)
# If you wish to keep existing addresses + routing and the interface is up,
# you can specify a noop (no operation). If the interface is down or there
# are no addresses assigned, then we move onto the next step (default dhcp)
# This is useful when configuring your interface with a kernel command line
# or similar
config_eth0=( "noop" "192.168.0.2/24" )
# If you don't want ANY address (only useful when calling for advanced stuff)
config_eth0=( "null" )
# Here's how to do routing if you need it
routes_eth0=(
"default via 192.168.0.1" # IPv4 default route
"10.0.0.0/8 via 192.168.0.1" # IPv4 subnet route
"::/0" # IPv6 unicast
)
# If a specified module fails (like dhcp - see below), you can specify a
# fallback like so
fallback_eth0=( "192.168.0.2 netmask 255.255.255.0" )
fallback_route_eth0=( "default via 192.168.0.1" )
# NOTE: fallback entry must match the entry location in config_eth0
# As such you can only have one fallback route.
# Some users may need to alter the MTU - here's how
mtu_eth0="1500"
# Each module described below can set a default base metric, lower is
# preferred over higher. This is so we can prefer a wired route over a
# wireless route automaticaly. You can override this by setting
metric_eth0="100"
# or on a global basis
metric="100"
# The only downside of the global setting is that you have to ensure that
# there are no conflicting routes yourself. For users with large routing
# tables you may have to set a global metric as the due to a simple read of
# the routing table taking over a minute at a time.
##############################################################################
# OPTIONAL MODULES
# INTERFACE RENAMING
# There is no consistent device renaming scheme for Linux.
# The preferred way of naming devices is via the kernel module directly or
# by using udev (http://www.reactivated.net/udevrules.php)
# If you are unable to write udev rules, then we do provide a way of renaming
# the interface based on it's MAC address, but it is not optimal.
# Here is how to rename an interface whose MAC address is 00:11:22:33:44:55
# to foo1
rename_001122334455="foo1"
# You can also do this based on current device name - although this is not
# recommended. Here we rename eth1 to foo2.
rename_eth1="foo2"
#-----------------------------------------------------------------------------
# WIRELESS (802.11 support)
# Wireless can be provided by iwconfig or wpa_supplicant
# iwconfig
# emerge net-wireless/wireless-tools
# Wireless options are held in /etc/conf.d/wireless - but could be here too
# Consult the sample file /etc/conf.d/wireless.example for instructions
# iwconfig is the default
# wpa_supplicant
# emerge net-wireless/wpa-supplicant
# Wireless options are held in /etc/wpa_supplicant.conf
# Consult the sample file /etc/wpa_supplicant.conf.example for instructions
# To choose wpa_supplicant over iwconfig
modules=( "wpa_supplicant" )
# To configure wpa_supplicant
wpa_supplicant_eth0="-Dwext" # For generic wireless
wpa_supplicant_ath0="-Dmadwifi" # For Atheros based cards
# Consult wpa_supplicant for more drivers
# By default don't wait for wpa_suppliant to associate and authenticate.
# If you would like to, so can specify how long in seconds
associate_timeout_eth0=60
# A value of 0 means wait forever.
# GENERIC WIRELESS OPTIONS
# PLEASE READ THE INSTRUCTIONS IN /etc/conf.d/wireless.example FOR
# HOW TO USE THIS ESSID VARIABLE
# You can also override any settings found here per ESSID - which is very
# handy if you use different networks a lot
config_ESSID=( "dhcp" )
dhcpcd_ESSID="-t 5"
# Setting name/domain server causes /etc/resolv.conf to be overwritten
# Note that if DHCP is used, and you want this to take precedence then
set dhcp_ESSID="nodns"
dns_servers_ESSID=( "192.168.0.1" "192.168.0.2" )
dns_domain_ESSID="some.domain"
dns_search_ESSID="search.this.domain search.that.domain"
# Please check the man page for resolv.conf for more information
# as domain and search are mutually exclusive.
# You can also override any settings found here per MAC address of the AP
# in case you use Access Points with the same ESSID but need different
# networking configs. Below is an example - of course you use the same
# method with other variables
mac_config_001122334455=( "dhcp" )
mac_dhcpcd_001122334455="-t 10"
mac_dns_servers_001122334455=( "192.168.0.1" "192.168.0.2" )
# When an interface has been associated with an Access Point, a global
# variable called ESSID is set to the Access Point's ESSID for use in the
# pre/post user functions below (although it's not available in preup as you
# won't have associated then)
# If you're using anything else to configure wireless on your interface AND
# you have installed any of the above packages, you need to disable them
modules=( "!iwconfig" "!wpa_supplicant" )
#-----------------------------------------------------------------------------
# DHCP
# DHCP can be provided by dhclient, dhcpcd, pump or udhcpc.
#
# dhclient: emerge net-misc/dhcp
# dhcpcd: emerge net-misc/dhcpcd
# pump: emerge net-misc/pump
# udhcpc: emerge net-misc/udhcp
# If you have more than one DHCP client installed, you need to specify which
# one to use - otherwise we default to dhcpcd if available.
modules=( "dhclient" ) # to select dhclient over dhcpcd
#
# Notes:
# - All clients send the current hostname to the DHCP server by default
# - dhcpcd does not daemonize when the lease time is infinite
# - udhcp-0.9.3-r3 and earlier do not support getting NTP servers
# - pump does not support getting NIS servers
# - DHCP tends to erase any existing device information - so add
# static addresses after dhcp if you need them
# - dhclient and udhcpc can set other resolv.conf options such as "option"
# and "sortlist"- see the System module for more details
# Regardless of which DHCP client you prefer, you configure them the
# same way using one of following depending on which interface modules
# you're using.
config_eth0=( "dhcp" )
# For passing custom options to dhcpcd use something like the following. This
# example reduces the timeout for retrieving an address from 60 seconds (the
# default) to 10 seconds.
dhcpcd_eth0="-t 10"
# dhclient, udhcpc and pump don't have many runtime options
# You can pass options to them in a similar manner to dhcpcd though
dhclient_eth0="..."
udhcpc_eth0="..."
pump_eth0="..."
# GENERIC DHCP OPTIONS
# Set generic DHCP options like so
dhcp_eth0="release nodns nontp nonis nogateway nosendhost"
# This tells the dhcp client to release it's lease when it stops, not to
# overwrite dns, ntp and nis settings, not to set a default route and not to
# send the current hostname to the dhcp server and when it starts.
# You can use any combination of the above options - the default is not to
# use any of them.
#-----------------------------------------------------------------------------
# For APIPA support, emerge net-misc/iputils or net-analyzer/arping
# APIPA is a module that tries to find a free address in the range
# 169.254.0.0-169.254.255.255 by arping a random address in that range on the
# interface. If no reply is found then we assign that address to the interface
# This is only useful for LANs where there is no DHCP server and you don't
# connect directly to the internet.
config_eth0=( "dhcp" )
fallback_eth0=( "apipa" )
#-----------------------------------------------------------------------------
# ARPING Gateway configuration
# and
# Automatic Private IP Addressing (APIPA)
# For arpingnet / apipa support, emerge net-misc/iputils or net-analyzer/arping
#
# This is a module that tries to find a gateway IP. If it exists then we use
# that gateways configuration for our own. For the configuration variables
# simply ensure that each octet is zero padded and the dots are removed.
# Below is an example.
#
gateways_eth0="192.168.0.1 10.0.0.1"
config_192168000001=( "192.168.0.2/24" )
routes_192168000001=( "default via 192.168.0.1" )
dns_servers_192168000001=( "192.168.0.1" )
config_010000000001=( "10.0.0.254/8" )
routes_010000000001=( "default via 10.0.0.1" )
dns_servers_010000000001=( "10.0.0.1" )
# We can also specify a specific MAC address for each gateway if different
# networks have the same gateway.
gateways_eth0="192.168.0.1,00:11:22:AA:BB:CC 10.0.0.1,33:44:55:DD:EE:FF"
config_192168000001_001122AABBCC=( "192.168.0.2/24" )
routes_192168000001_001122AABBCC=( "default via 192.168.0.1" )
dns_servers_192168000001_001122AABBCC=( "192.168.0.1" )
config_010000000001_334455DDEEFF=( "10.0.0.254/8" )
routes_010000000001_334455DDEEFF=( "default via 10.0.0.1" )
dns_servers_010000000001_334455DDEEFF=( "10.0.0.1" )
# If we don't find any gateways (or there are none configured) then we try and
# use APIPA to find a free address in the range 169.254.0.0-169.254.255.255
# by arping a random address in that range on the interface. If no reply is
# found then we assign that address to the interface.
# This is only useful for LANs where there is no DHCP server.
config_eth0=( "arping" )
# or if no DHCP server can be found
config_eth0=( "dhcp" )
fallback_eth0=( "arping" )
# NOTE: We default to sleeping for 1 second the first time we attempt an
# arping to give the interface time to settle on the LAN. This appears to
# be a good default for most instances, but if not you can alter it here.
arping_sleep=5
arping_sleep_lan=7
# NOTE: We default to waiting 3 seconds to get an arping response. You can
# change the default wait like so.
arping_wait=3
arping_wait_lan=2
#-----------------------------------------------------------------------------
# VLAN (802.1q support)
# For VLAN support, emerge net-misc/vconfig
# Specify the VLAN numbers for the interface like so
# Please ensure your VLAN IDs are NOT zero-padded
vlans_eth0="1 2"
# You may not want to assign an IP to the physical interface, but we still
# need it up.
config_eth0=( "null" )
# You can also configure the VLAN - see for vconfig man page for more details
vconfig_eth0=( "set_name_type VLAN_PLUS_VID_NO_PAD" )
vconfig_vlan1=( "set_flag 1" "set_egress_map 2 6" )
config_vlan1=( "172.16.3.1 netmask 255.255.254.0" )
config_vlan2=( "172.16.2.1 netmask 255.255.254.0" )
# NOTE: Vlans can be configured with a . in their interface names
# When configuring vlans with this name type, you need to replace . with a _
config_eth0.1=( "dhcp" ) - does not work
config_eth0_1=( "dhcp" ) - does work
# NOTE: Vlans are controlled by their physical interface and not per vlan
# This means you do not need to create init scripts in /etc/init.d for each
# vlan, you must need to create one for the physical interface.
# If you wish to control the configuration of each vlan through a separate
# script, or wish to rename the vlan interface to something that vconfig
# cannot then you need to do this.
vlan_start_eth0="no"
# If you do the above then you may want to depend on eth0 like so
RC_NEED_vlan1="net.eth0"
# NOTE: depend functions only work in /etc/conf.d/net
# and not in profile configs such as /etc/conf.d/net.foo
#-----------------------------------------------------------------------------
# Bonding
# For link bonding/trunking emerge net-misc/ifenslave
# To bond interfaces together
slaves_bond0="eth0 eth1 eth2"
config_bond0=( "null" ) # You may not want to assign an IP to the bond
# If any of the slaves require extra configuration - for example wireless or
# ppp devices - we need to depend function on the bonded interfaces
RC_NEED_bond0="net.eth0 net.eth1"
#-----------------------------------------------------------------------------
# Classical IP over ATM
# For CLIP support emerge net-dialup/linux-atm
# Ensure that you have /etc/atmsigd.conf setup correctly
# Now setup each clip interface like so
clip_atm0=( "peer_ip [if.]vpi.vci [opts]" ... )
# where "peer_ip" is the IP address of a PVC peer (in case of an ATM connection
# with your ISP, your only peer is usually the ISP gateway closest to you),
# "if" is the number of the ATM interface which will carry the PVC, "vpi.vci"
# is the ATM VC address, and "opts" may optionally specify VC parameters like
# qos, pcr, and the like (see "atmarp -s" for further reference). Please also
# note quoting: it is meant to distinguish the VCs you want to create. You may,
# in example, create an atm0 interface to more peers, like this:
clip_atm0=( "1.1.1.254 0.8.35" "1.1.1.253 1.8.35" )
# By default, the PVC will use the LLC/SNAP encapsulation. If you rather need a
# null encapsulation (aka "VC mode"), please add the keyword "null" to opts.
#-----------------------------------------------------------------------------
# PPP
# For PPP support, emerge net-dialup/ppp
# PPP is used for most dialup connections, including ADSL.
# The older ADSL module is documented below, but you are encouraged to try
# this module first.
#
# You need to create the PPP net script yourself. Make it like so
#ln -s net.lo /etc/init.d/net.ppp0
#
# We have to instruct ppp0 to actually use ppp
config_ppp0=( "ppp" )
#
# Each PPP interface requires an interface to use as a "Link"
link_ppp0="/dev/ttyS0" # Most PPP links will use a serial port
link_ppp0="eth0" # PPPoE requires an ethernet interface
link_ppp0="[itf.]vpi.vci" # PPPoA requires the ATM VC's address
link_ppp0="/dev/null" # ISDN links should have this
link_ppp0="pty 'your_link_command'" # PPP links over ssh, rsh, etc
#
# Here you should specify what pppd plugins you want to use
# Available plugins are: pppoe, pppoa, capi, dhcpc, minconn, radius,
# radattr, radrealms and winbind
plugins_ppp0=(
"pppoe" # Required plugin for PPPoE
"pppoa vc-encaps" # Required plugin for PPPoA with an option
"capi" # Required plugin for ISDN
)
#
# PPP requires at least a username. You can optionally set a password here too
# If you don't, then it will use the password specified in /etc/ppp/*-secrets
# against the specified username
username_ppp0='user'
password_ppp0='password'
# NOTE: You can set a blank password like so
password_ppp0=
#
# The PPP daemon has many options you can specify - although there are many
# and may seem daunting, it is recommended that you read the pppd man page
# before enabling any of them
pppd_ppp0=(
"maxfail 0" # WARNING: It's not recommended you use this
# if you don't specify maxfail then we assume 0
"updetach" # If not set, "/etc/init.d/net.ppp0 start" will return
# immediately, without waiting the link to come up
# for the first time.
# Do not use it for dial-on-demand links!
"debug" # Enables syslog debugging
"noauth" # Do not require the peer to authenticate itself
"defaultroute" # Make this PPP interface the default route
"usepeerdns" # Use the DNS settings provided by PPP
# On demand options
"demand" # Enable dial on demand
"idle 30" # Link goes down after 30 seconds of inactivity
"10.112.112.112:10.112.112.113" # Phony IP addresses
"ipcp-accept-remote" # Accept the peers idea of remote address
"ipcp-accept-local" # Accept the peers idea of local address
"holdoff 3" # Wait 3 seconds after link dies before re-starting
# Dead peer detection
"lcp-echo-interval 15" # Send a LCP echo every 15 seconds
"lcp-echo-failure 3" # Make peer dead after 3 consective
# echo-requests
# Compression options - use these to completely disable compression
# noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp
# Dial-up settings
"lock" # Lock serial port
"115200" # Set the serial port baud rate
"modem crtscts" # Enable hardware flow control
"192.168.0.1:192.168.0.2" # Local and remote IP addresses
)
#
# Dial-up PPP users need to specify at least one telephone number
phone_number_ppp0=( "12345689" ) # Maximum 2 phone numbers are supported
# They will also need a chat script - here's a good one
chat_ppp0=(
# 'ABORT' 'BUSY'
# 'ABORT' 'ERROR'
# 'ABORT' 'NO ANSWER'
# 'ABORT' 'NO CARRIER'
# 'ABORT' 'NO DIALTONE'
# 'ABORT' 'Invalid Login'
# 'ABORT' 'Login incorrect'
# 'TIMEOUT' '5'
# '' 'ATZ'
# 'OK' 'AT' # Put your modem initialization string here
# 'OK' 'ATDT\T'
# 'TIMEOUT' '60'
# 'CONNECT' ''
# 'TIMEOUT' '5'
# '~--' ''
)
# If the link require extra configuration - for example wireless or
# RFC 268 bridge - we need to depend on the bridge so they get
# configured correctly.
RC_NEED_ppp0="net.nas0"
#WARNING: if MTU of the PPP interface is less than 1500 and you use this
#machine as a router, you should add the following rule to your firewall
#
#iptables -I FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
#-----------------------------------------------------------------------------
# ADSL
# For ADSL support, emerge net-dialup/rp-pppoe
# WARNING: This ADSL module is being deprecated in favour of the PPP module
# above.
# You should make the following settings and also put your
# username/password information in /etc/ppp/pap-secrets
# Configure the interface to use ADSL
config_eth0=( "adsl" )
# You probably won't need to edit /etc/ppp/pppoe.conf if you set this
adsl_user_eth0="my-adsl-username"
#-----------------------------------------------------------------------------
# ISDN
# For ISDN support, emerge net-dialup/isdn4k-utils
# You should make the following settings and also put your
# username/password information in /etc/ppp/pap-secrets
# Configure the interface to use ISDN
config_ippp0=( "dhcp" )
# It's important to specify dhcp if you need it!
config_ippp0=( "192.168.0.1/24" )
# Otherwise, you can use a static IP
# NOTE: The interface name must be either ippp or isdn followed by a number
# You may need this option to set the default route
ipppd_eth0="defaultroute"
#-----------------------------------------------------------------------------
# MAC changer
# To set a specific MAC address
mac_eth0="00:11:22:33:44:55"
# For changing MAC addresses using the below, emerge net-analyzer/macchanger
# - to randomize the last 3 bytes only
mac_eth0="random-ending"
# - to randomize between the same physical type of connection (e.g. fibre,
# copper, wireless) , all vendors
mac_eth0="random-samekind"
# - to randomize between any physical type of connection (e.g. fibre, copper,
# wireless) , all vendors
mac_eth0="random-anykind"
# - full randomization - WARNING: some MAC addresses generated by this may NOT
# act as expected
mac_eth0="random-full"
# custom - passes all parameters directly to net-analyzer/macchanger
mac_eth0="some custom set of parameters"
# You can also set other options based on the MAC address of your network card
# Handy if you use different docking stations with laptops
config_001122334455=( "dhcp" )
#-----------------------------------------------------------------------------
# TUN/TAP
# For TUN/TAP support emerge net-misc/openvpn or sys-apps/usermode-utilities
#
# You must specify if we're a tun or tap device. Then you can give it any
# name you like - such as vpn
tuntap_vpn="tun"
config_vpn=( "192.168.0.1/24")
# Or stick wit the generic names - like tap0
tuntap_tap0="tap"
config_tap0=( "192.168.0.1/24")
# For passing custom options to tunctl use something like the following. This
# example sets the owner to adm
tunctl_tun1="-u adm"
# When using openvpn, there are no options
#-----------------------------------------------------------------------------
# Bridging (802.1d)
# For bridging support emerge net-misc/bridge-utils
# To add ports to bridge br0
bridge_br0="eth0 eth1"
# or dynamically add them when the interface comes up
bridge_add_eth0="br0"
bridge_add_eth1="br0"
# You need to configure the ports to null values so dhcp does not get started
config_eth0=( "null" )
config_eth1=( "null" )
# Finally give the bridge an address - dhcp or a static IP
config_br0=( "dhcp" ) # may not work when adding ports dynamically
config_br0=( "192.168.0.1/24" )
# If any of the ports require extra configuration - for example wireless or
# ppp devices - we need to depend on them like so.
RC_NEED_br0="net.eth0 net.eth1"
# Below is an example of configuring the bridge
# Consult "man brctl" for more details
brctl_br0=( "setfd 0" "sethello 0" "stp off" )
#-----------------------------------------------------------------------------
# RFC 2684 Bridge Support
# For RFC 2684 bridge support emerge net-misc/br2684ctl
# Interface names have to be of the form nas0, nas1, nas2, etc.
# You have to specify a VPI and VCI for the interface like so
br2684ctl_nas0="-a 0.38" # UK VPI and VCI
# You may want to configure the encapsulation method as well by adding the -e
# option to the command above (may need to be before the -a command)
# -e 0 # LLC (default)
# -e 1 # VC mux
# Then you can configure the interface as normal
config_nas0=( "192.168.0.1/24" )
#-----------------------------------------------------------------------------
# Tunnelling
# WARNING: For tunnelling it is highly recommended that you
# emerge sys-apps/iproute2
#
# For GRE tunnels
iptunnel_vpn0="mode gre remote 207.170.82.1 key 0xffffffff ttl 255"
# For IPIP tunnels
iptunnel_vpn0="mode ipip remote 207.170.82.2 ttl 255"
# To configure the interface
config_vpn0=( "192.168.0.2 pointopoint 192.168.1.2" ) # ifconfig style
config_vpn0=( "192.168.0.2 peer 192.168.1.1" ) # iproute2 style
# 6to4 Tunnels allow IPv6 to work over IPv4 addresses, provided you
# have a non-private address configured on an interface.
link_6to4="eth0" # Interface to base it's addresses on
config_6to4=( "ip6to4" )
# You may want to depend on eth0 like so
RC_NEED_6to4="net.eth0"
# To ensure that eth0 is configured before 6to4. Of course, the tunnel could be
# any name and this also works for any configured interface.
# NOTE: If you're not using iproute2 then your 6to4 tunnel has to be called
# sit0 - otherwise use a different name like 6to4 in the example above.
#-----------------------------------------------------------------------------
# System
# For configuring system specifics such as domain, dns, ntp and nis servers
# It's rare that you would need todo this, but you can anyway.
# This is most benefit to wireless users who don't use DHCP so they can change
# their configs based on ESSID. See wireless.example for more details
# To use dns settings such as these, dns_servers_eth0 must be set!
# If you omit the _eth0 suffix, then it applies to all interfaces unless
# overridden by the interface suffix.
dns_domain_eth0="your.domain"
dns_servers_eth0="192.168.0.2 192.168.0.3"
dns_search_eth0="this.domain that.domain"
dns_options_eth0=( "timeout 1" "rotate" )
dns_sortlist_eth0="130.155.160.0/255.255.240.0 130.155.0.0"
# See the man page for resolv.conf for details about the options and sortlist
# directives
ntp_servers_eth0="192.168.0.2 192.168.0.3"
nis_domain_eth0="domain"
nis_servers_eth0="192.168.0.2 192.168.0.3"
# NOTE: Setting any of these will stamp on the files in question. So if you
# don't specify dns_servers but you do specify dns_domain then no nameservers
# will be listed in /etc/resolv.conf even if there were any there to start
# with.
# If this is an issue for you then maybe you should look into a resolv.conf
# manager like resolvconf-gentoo to manage this file for you. All packages
# that baselayout supports use resolvconf-gentoo if installed.
#-----------------------------------------------------------------------------
# Cable in/out detection
# Sometimes the cable is in, others it's out. Obviously you don't want to
# restart net.eth0 every time when you plug it in either.
#
# netplug is a package that detects this and requires no extra configuration
# on your part.
# emerge sys-apps/netplug
# or
# emerge sys-apps/ifplugd
# and you're done :)
# By default we don't wait for netplug/ifplugd to configure the interface.
# If you would like it to wait so that other services now that network is up
# then you can specify a timeout here.
plug_timeout="10"
# A value of 0 means wait forever.
# If you don't want to use netplug on a specific interface but you have it
# installed, you can disable it for that interface via the modules statement
modules_eth0=( "!netplug" )
# You can do the same for ifplugd
#
# You can disable them both with the generic plug
modules_eth0=( "!plug" )
# To use specific ifplugd options, fex specifying wireless mode
ifplugd_eth0="--api-mode=wlan"
# man ifplugd for more options
##############################################################################
# ADVANCED CONFIGURATION
#
# Four functions can be defined which will be called surrounding the
# start/stop operations. The functions are called with the interface
# name first so that one function can control multiple adapters. An extra two
# functions can be defined when an interface fails to start or stop.
#
# The return values for the preup and predown functions should be 0
# (success) to indicate that configuration or deconfiguration of the
# interface can continue. If preup returns a non-zero value, then
# interface configuration will be aborted. If predown returns a
# non-zero value, then the interface will not be allowed to continue
# deconfiguration.
#
# The return values for the postup, postdown, failup and faildown functions are
# ignored since there's nothing to do if they indicate failure.
#
# ${IFACE} is set to the interface being brought up/down
# ${IFVAR} is ${IFACE} converted to variable name bash allows
#preup() {
# # Test for link on the interface prior to bringing it up. This
# # only works on some network adapters and requires the mii-diag
# # package to be installed.
# if mii-tool "${IFACE}" 2> /dev/null | grep -q 'no link'; then
# ewarn "No link on ${IFACE}, aborting configuration"
# return 1
# fi
#
# # Test for link on the interface prior to bringing it up. This
# # only works on some network adapters and requires the ethtool
# # package to be installed.
# if ethtool "${IFACE}" | grep -q 'Link detected: no'; then
# ewarn "No link on ${IFACE}, aborting configuration"
# return 1
# fi
#
#
# # Remember to return 0 on success
# return 0
#}
#predown() {
# # The default in the script is to test for NFS root and disallow
# # downing interfaces in that case. Note that if you specify a
# # predown() function you will override that logic. Here it is, in
# # case you still want it...
# if is_net_fs /; then
# eerror "root filesystem is network mounted -- can't stop ${IFACE}"
# return 1
# fi
#
# # Remember to return 0 on success
# return 0
#}
#postup() {
# # This function could be used, for example, to register with a
# # dynamic DNS service. Another possibility would be to
# # send/receive mail once the interface is brought up.
# # Here is an example that allows the use of iproute rules
# # which have been configured using the rules_eth0 variable.
# #rules_eth0=(
# # "from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100"
# # "from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100"
# #)
# local x="rules_${IFVAR}[@]"
# local -a rules=( "${!x}" )
# if [[ -n ${rules} ]] ; then
# einfo "Adding IP policy routing rules"
# eindent
# # Ensure that the kernel supports policy routing
# if ! ip rule list | grep -q "^" ; then
# eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)"
# eerror "in your kernel to use ip rules"
# else
# for x in "${rules[@]}" ; do
# ebegin "${x}"
# ip rule add ${x} dev "${IFACE}"
# eend $?
# done
# fi
# eoutdent
# # Flush the cache
# ip route flush cache dev "${IFACE}"
# fi
#}
#postdown() {
# # Enable Wake-On-LAN for every interface except for lo
# # Probably a good idea to set RC_DOWN_INTERFACE="no" in /etc/conf.d/rc
# # as well ;)
# [[ ${IFACE} != "lo" ]] && ethtool -s "${IFACE}" wol g
# Automatically erase any ip rules created in the example postup above
# if interface_exists "${IFACE}" ; then
# # Remove any rules for this interface
# local rule
# ip rule list | grep " iif ${IFACE}[ ]*" | {
# while read rule ; do
# rule="${rule#*:}"
# ip rule del ${rule}
# done
# }
# # Flush the route cache
# ip route flush cache dev "${IFACE}"
# fi
# # Return 0 always
# return 0
#}
#failup() {
# # This function is mostly here for completeness... I haven't
# # thought of anything nifty to do with it yet ;-)
#}
#faildown() {
# # This function is mostly here for completeness... I haven't
# # thought of anything nifty to do with it yet ;-)
#}
##############################################################################
# FORCING MODULES
# The Big Fat Warning :- If you use module forcing do not complain to us or
# file bugs about it not working!
#
# Loading modules is a slow affair - we have to check each one for the following
# 1) Code sanity
# 2) Has the required package been emerged?
# 3) Has it modified anything?
# 4) Have all the dependant modules been loaded?
# Then we have to strip out the conflicting modules based on user preference
# and default configuration and sort them into the correct order.
# Finally we check the end result for dependencies.
# This, of course, takes valuable CPU time so we provide module forcing as a
# means to speed things up. We still do *some* checking but not much.
# It is essential that you force modules in the correct order and supply all
# the modules you need. You must always supply an interface module - we
# supply ifconfig or iproute2.
# The Big Fat Warning :- If you use module forcing do not complain to us or
# file bugs about it not working!
# Now that we've warned you twice, here's how to do it
modules_force=( "ifconfig" )
modules_force=( "iproute2" "dhcpcd" )
# We can also apply this to a specific interface
modules_force_eth1=( "iproute2" )
# The below will not work
modules_force=( "dhcpcd" )
# No interface (ifconfig/iproute2)
modules_force=( "ifconfig" "essidnet" "iwconfig" )
# Although it will not crash, essidnet will not work as it has to come after
# iwconfig
modules_force=( "iproute2" "ifconfig" )
# The interface will be setup twice which will cause problems

View file

@ -1,5 +0,0 @@
[main]
plugins=ifnet,keyfile
[ifnet]
managed=false

View file

@ -1,396 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service (ifnet)
*
* Mu Qiao <qiaomuf@gmail.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 1999-2010 Gentoo Foundation, Inc.
*/
#include "nm-default.h"
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include "nm-utils.h"
#include "platform/nm-linux-platform.h"
#include "dhcp/nm-dhcp-manager.h"
#include "settings/plugins/ifnet/nms-ifnet-net-parser.h"
#include "settings/plugins/ifnet/nms-ifnet-net-utils.h"
#include "settings/plugins/ifnet/nms-ifnet-wpa-parser.h"
#include "settings/plugins/ifnet/nms-ifnet-connection-parser.h"
#include "nm-test-utils-core.h"
/* Fake config handling; the values it returns don't matter, so this
* is easier than forcing it to read our own config file, etc.
*/
NMDhcpManager *
nm_dhcp_manager_get (void)
{
return NULL;
}
const char *
nm_dhcp_manager_get_config (NMDhcpManager *dhcp_manager)
{
return "dhclient";
}
static void
test_getdata (void)
{
g_assert (ifnet_get_data ("eth1", "config") &&
strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0);
g_assert (ifnet_get_data ("ppp0", "username") &&
strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0);
g_assert (ifnet_get_data ("ppp0", "password") &&
strcmp (ifnet_get_data ("ppp0", "password"), "password") == 0);
g_assert (ifnet_get_global_data ("modules") &&
strcmp ("!wpa_supplicant", ifnet_get_global_data ("modules")) == 0);
}
static void
test_is_static (void)
{
g_assert (!is_static_ip4 ("eth1"));
g_assert (is_static_ip4 ("eth0"));
g_assert (!is_static_ip6 ("eth0"));
}
static void
test_has_default_route (void)
{
g_assert (has_default_ip4_route ("eth0"));
g_assert (has_default_ip6_route ("eth4"));
g_assert (!has_default_ip4_route ("eth5") &&
!has_default_ip6_route ("eth5"));
}
static void
test_has_ip6_address (void)
{
g_assert (has_ip6_address ("eth2"));
g_assert (!has_ip6_address ("eth0"));
}
static void
test_is_ip4_address (void)
{
gchar *address1 = "192.168.4.232/24";
gchar *address2 = "192.168.100.{1..254}/24";
gchar *address3 = "192.168.4.2555/24";
g_assert (is_ip4_address (address1));
g_assert (is_ip4_address (address2));
g_assert (!is_ip4_address (address3));
}
static void
test_is_ip6_address (void)
{
gchar *address1 = "4321:0:1:2:3:4:567:89ac/24";
g_assert (is_ip6_address (address1));
}
static void
check_ip_block (ip_block * iblock, gchar * ip, guint32 prefix, gchar * gateway)
{
g_assert_cmpstr (ip, ==, iblock->ip);
g_assert (prefix == iblock->prefix);
g_assert_cmpstr (gateway, ==, iblock->next_hop);
}
static void
test_convert_ipv4_config_block (void)
{
ip_block *iblock = convert_ip4_config_block ("eth0");
ip_block *tmp = iblock;
g_assert (iblock != NULL);
check_ip_block (iblock, "202.117.16.121", 24, "202.117.16.1");
iblock = iblock->next;
destroy_ip_block (tmp);
g_assert (iblock != NULL);
check_ip_block (iblock, "192.168.4.121", 24, "202.117.16.1");
destroy_ip_block (iblock);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*Can't handle IPv4 address*202.117.16.1211*");
iblock = convert_ip4_config_block ("eth2");
g_test_assert_expected_messages ();
g_assert (iblock != NULL && iblock->next == NULL);
check_ip_block (iblock, "192.168.4.121", 24, NULL);
destroy_ip_block (iblock);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*missing netmask or prefix*");
iblock = convert_ip4_config_block ("eth3");
g_assert (iblock == NULL);
}
static void
test_convert_ipv4_routes_block (void)
{
ip_block *iblock = convert_ip4_routes_block ("eth0");
ip_block *tmp = iblock;
g_assert (iblock != NULL);
check_ip_block (iblock, "192.168.4.0", 24, "192.168.4.1");
iblock = iblock->next;
destroy_ip_block (tmp);
g_assert (iblock == NULL);
iblock = convert_ip4_routes_block ("eth9");
tmp = iblock;
g_assert (iblock != NULL);
check_ip_block (iblock, "10.0.0.0", 8, "192.168.0.1");
iblock = iblock->next;
destroy_ip_block (tmp);
g_assert (iblock == NULL);
}
static void
test_wpa_parser (void)
{
const char *value;
g_assert (exist_ssid ("example"));
g_assert (exist_ssid ("static-wep-test"));
value = wpa_get_value ("static-wep-test", "key_mgmt");
g_assert_cmpstr (value, ==, "NONE");
value = wpa_get_value ("static-wep-test", "wep_key0");
g_assert_cmpstr (value, ==, "\"abcde\"");
g_assert (exist_ssid ("leap-example"));
value = wpa_get_value ("test-with-hash-in-psk", "psk");
g_assert_cmpstr (value, ==, "\"xjtudlc3731###asdfasdfasdf\"");
}
static void
test_strip_string (void)
{
gchar *str = "( \"default via 202.117.16.1\" )";
gchar *result = g_strdup (str);
gchar *result_b = result;
result = strip_string (result, '(');
result = strip_string (result, ')');
result = strip_string (result, '"');
g_assert_cmpstr (result, ==, "default via 202.117.16.1");
g_free (result_b);
}
static void
test_is_unmanaged (void)
{
g_assert (is_managed ("eth0"));
g_assert (!is_managed ("eth4"));
}
static void
test_new_connection (void)
{
GError *error = NULL;
NMConnection *connection;
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*Can't handle IPv4 address*202.117.16.1211*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*Can't handle IPv6 address*202.117.16.1211*");
connection = ifnet_update_connection_from_config_block ("eth2", NULL, &error);
g_test_assert_expected_messages ();
g_assert (connection != NULL);
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error);
g_assert (connection != NULL);
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL, &error);
g_assert (connection != NULL);
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("eth9", NULL, &error);
g_assert (connection != NULL);
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("eth10", NULL, &error);
g_assert (connection != NULL);
g_object_unref (connection);
}
static void
kill_backup (char **path)
{
if (*path) {
unlink (*path);
g_free (*path);
*path = NULL;
}
}
#define NET_GEN_NAME "net.generate"
#define SUP_GEN_NAME "wpa_supplicant.conf.generate"
static void
test_update_connection (void)
{
GError *error = NULL;
NMConnection *connection;
gboolean success;
char *backup = NULL;
char *basepath = TEST_IFNET_DIR;
connection = ifnet_update_connection_from_config_block ("eth0", basepath, &error);
g_assert (connection != NULL);
success = ifnet_update_parsers_by_connection (connection, "eth0",
NET_GEN_NAME,
SUP_GEN_NAME,
NULL,
&backup,
&error);
kill_backup (&backup);
g_assert (success);
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("0xab3ace", basepath, &error);
g_assert (connection != NULL);
success = ifnet_update_parsers_by_connection (connection, "0xab3ace",
NET_GEN_NAME,
SUP_GEN_NAME,
NULL,
&backup,
&error);
kill_backup (&backup);
g_assert (success);
g_object_unref (connection);
unlink (NET_GEN_NAME);
unlink (SUP_GEN_NAME);
}
static void
test_add_connection (void)
{
NMConnection *connection;
char *backup = NULL;
const char *basepath = TEST_IFNET_DIR;
connection = ifnet_update_connection_from_config_block ("eth0", basepath, NULL);
g_assert (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL, &backup, NULL));
kill_backup (&backup);
g_object_unref (connection);
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*Can't handle ipv4 address: brd, missing netmask or prefix*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*Can't handle ipv4 address: 202.117.16.255, missing netmask or prefix*");
connection = ifnet_update_connection_from_config_block ("myxjtu2", basepath, NULL);
g_test_assert_expected_messages ();
g_assert (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL, &backup, NULL));
kill_backup (&backup);
g_object_unref (connection);
unlink (NET_GEN_NAME);
unlink (SUP_GEN_NAME);
}
static void
test_delete_connection (void)
{
GError *error = NULL;
NMConnection *connection;
char *backup = NULL;
connection = ifnet_update_connection_from_config_block ("eth7", NULL, &error);
g_assert (connection != NULL);
g_assert (ifnet_delete_connection_in_parsers ("eth7", NET_GEN_NAME, SUP_GEN_NAME, &backup));
kill_backup (&backup);
g_object_unref (connection);
connection = ifnet_update_connection_from_config_block ("qiaomuf", NULL, &error);
g_assert (connection != NULL);
g_assert (ifnet_delete_connection_in_parsers ("qiaomuf", NET_GEN_NAME, SUP_GEN_NAME, &backup));
kill_backup (&backup);
g_object_unref (connection);
unlink (NET_GEN_NAME);
unlink (SUP_GEN_NAME);
}
static void
test_missing_config (void)
{
gs_free_error GError *error = NULL;
NMConnection *connection;
connection = ifnet_update_connection_from_config_block ("eth8", NULL, &error);
g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION);
g_assert (connection == NULL && error != NULL);
}
NMTST_DEFINE ();
#define TPATH "/settings/plugins/ifnet/"
int
main (int argc, char **argv)
{
int ret;
nm_linux_platform_setup ();
nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT");
ifnet_init (TEST_IFNET_DIR "/net");
wpa_parser_init (TEST_IFNET_DIR "/wpa_supplicant.conf");
g_test_add_func (TPATH "strip-string", test_strip_string);
g_test_add_func (TPATH "is-static", test_is_static);
g_test_add_func (TPATH "has-ip6-address", test_has_ip6_address);
g_test_add_func (TPATH "has-default-route", test_has_default_route);
g_test_add_func (TPATH "get-data", test_getdata);
g_test_add_func (TPATH "is-ip4-address", test_is_ip4_address);
g_test_add_func (TPATH "is-ip6-address", test_is_ip6_address);
g_test_add_func (TPATH "convert-ip4-config", test_convert_ipv4_config_block);
g_test_add_func (TPATH "convert-ip4-routes", test_convert_ipv4_routes_block);
g_test_add_func (TPATH "is-unmanaged", test_is_unmanaged);
g_test_add_func (TPATH "wpa-parser", test_wpa_parser);
g_test_add_func (TPATH "new-connection", test_new_connection);
g_test_add_func (TPATH "update-connection", test_update_connection);
g_test_add_func (TPATH "add-connection", test_add_connection);
g_test_add_func (TPATH "delete-connection", test_delete_connection);
g_test_add_func (TPATH "missing-config", test_missing_config);
ret = g_test_run ();
ifnet_destroy ();
wpa_parser_destroy ();
return ret;
}

View file

@ -1,27 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw
FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE
AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx
NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ
QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55
IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3
DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU
xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc
Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3
FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4
HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm
J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P
T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF
ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO
BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL
EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl
c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC
AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc
JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT
p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t
qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn
B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp
3nniskIjbH0xjgZf/nVMyLnjxg==
-----END CERTIFICATE-----

View file

@ -1,70 +0,0 @@
# Only WPA-PSK is used. Any valid cipher combination is accepted.
network={
ssid="example"
proto=WPA
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP WEP104 WEP40
psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
priority=2
}
# LEAP with dynamic WEP keys
network={
ssid="leap-example"
key_mgmt=IEEE8021X
eap=LEAP
identity="user"
password="foobar"
}
# Shared WEP key connection (no WPA, no IEEE 802.1X)
network={
ssid="static-wep-test"
key_mgmt=NONE
wep_key0="abcde"
wep_key1=0102030405
wep_key2="1234567890123"
wep_tx_keyidx=0
priority=5
}
# Wildcard match for SSID (plaintext APs only). This example select any
# open AP regardless of its SSID.
network={
key_mgmt=NONE
}
network={
ssid="myxjtu2"
scan_ssid=1
key_mgmt=WPA-PSK
psk="xjtudlc3731"
disabled=0
key_mgmt=NONE
wep_key0="12345"
wep_key1=1234567890
wep_key2="zxcvb"
wep_tx_keyidx=1
auth_alg=OPEN
mode=1
}
network={
ssid=ab3ace
key_mgmt=WPA-EAP
eap=TTLS
identity="user@example.com"
anonymous_identity="anonymous@example.com"
password="foobar"
ca_cert="test_ca_cert.pem"
phase2="auth=CHAP"
priority=20
}
network={
ssid="test-with-hash-in-psk"
key_mgmt=WPA-PSK
psk="xjtudlc3731###asdfasdfasdf"
}

View file

@ -10,10 +10,6 @@ if enable_ifupdown
subdir('ifupdown')
endif
if enable_ifnet
subdir('ifnet')
endif
if enable_config_plugin_ibft
subdir('ibft')
endif

View file

@ -19,7 +19,7 @@ die() {
_build() {
git clean -fdx
./autogen.sh --enable-ld-gc --enable-ifcfg-rh --enable-ifupdown \
--enable-ifnet --enable-ibft --enable-teamdctl --enable-wifi \
--enable-ibft --enable-teamdctl --enable-wifi \
--with-modem-manager-1 --with-ofono --with-more-asserts \
--with-more-logging
make -j20