mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-20 00:21:29 +00:00
ifnet: add Gentoo system settings plugin
This commit is contained in:
parent
3f2d741b0d
commit
38f3e5ca61
|
@ -512,6 +512,8 @@ system-settings/Makefile
|
||||||
system-settings/plugins/Makefile
|
system-settings/plugins/Makefile
|
||||||
system-settings/plugins/ifupdown/Makefile
|
system-settings/plugins/ifupdown/Makefile
|
||||||
system-settings/plugins/ifupdown/tests/Makefile
|
system-settings/plugins/ifupdown/tests/Makefile
|
||||||
|
system-settings/plugins/ifnet/Makefile
|
||||||
|
system-settings/plugins/ifnet/tests/Makefile
|
||||||
system-settings/plugins/ifcfg-rh/Makefile
|
system-settings/plugins/ifcfg-rh/Makefile
|
||||||
system-settings/plugins/ifcfg-rh/tests/Makefile
|
system-settings/plugins/ifcfg-rh/tests/Makefile
|
||||||
system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile
|
system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile
|
||||||
|
|
|
@ -21,4 +21,5 @@ src/logging/nm-logging.c
|
||||||
src/named-manager/nm-named-manager.c
|
src/named-manager/nm-named-manager.c
|
||||||
src/system-settings/nm-default-wired-connection.c
|
src/system-settings/nm-default-wired-connection.c
|
||||||
system-settings/plugins/ifcfg-rh/reader.c
|
system-settings/plugins/ifcfg-rh/reader.c
|
||||||
|
system-settings/plugins/ifnet/connection_parser.c
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,7 @@ endif
|
||||||
if TARGET_DEBIAN
|
if TARGET_DEBIAN
|
||||||
SUBDIRS+=ifupdown
|
SUBDIRS+=ifupdown
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if TARGET_GENTOO
|
||||||
|
SUBDIRS+=ifnet
|
||||||
|
endif
|
||||||
|
|
61
system-settings/plugins/ifnet/Makefile.am
Normal file
61
system-settings/plugins/ifnet/Makefile.am
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
SUBDIRS = . tests
|
||||||
|
INCLUDES = \
|
||||||
|
-I$(top_srcdir)/src/system-settings \
|
||||||
|
-I$(top_srcdir)/include \
|
||||||
|
-I$(top_srcdir)/libnm-glib \
|
||||||
|
-I$(top_srcdir)/libnm-util
|
||||||
|
|
||||||
|
pkglib_LTLIBRARIES = libnm-settings-plugin-ifnet.la
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = lib-ifnet-io.la
|
||||||
|
|
||||||
|
libnm_settings_plugin_ifnet_la_SOURCES = \
|
||||||
|
nm-ifnet-connection.c \
|
||||||
|
nm-ifnet-connection.h \
|
||||||
|
plugin.c \
|
||||||
|
plugin.h
|
||||||
|
|
||||||
|
libnm_settings_plugin_ifnet_la_CPPFLAGS = \
|
||||||
|
$(GLIB_CFLAGS) \
|
||||||
|
$(GMODULE_CFLAGS) \
|
||||||
|
$(DBUS_CFLAGS) \
|
||||||
|
$(GUDEV_CFLAGS) \
|
||||||
|
-DG_DISABLE_DEPRECATED \
|
||||||
|
-DSYSCONFDIR=\"$(sysconfdir)\"\
|
||||||
|
-g
|
||||||
|
|
||||||
|
|
||||||
|
libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version
|
||||||
|
libnm_settings_plugin_ifnet_la_LIBADD = \
|
||||||
|
$(top_builddir)/libnm-util/libnm-util.la \
|
||||||
|
$(top_builddir)/libnm-glib/libnm-glib.la \
|
||||||
|
lib-ifnet-io.la\
|
||||||
|
$(GLIB_LIBS) \
|
||||||
|
$(GMODULE_LIBS) \
|
||||||
|
$(GUDEV_LIBS) \
|
||||||
|
$(GIO_LIBS)
|
||||||
|
|
||||||
|
lib_ifnet_io_la_SOURCES = \
|
||||||
|
net_parser.c\
|
||||||
|
net_parser.h\
|
||||||
|
connection_parser.c \
|
||||||
|
connection_parser.h \
|
||||||
|
net_utils.h\
|
||||||
|
net_utils.c\
|
||||||
|
wpa_parser.h\
|
||||||
|
wpa_parser.c
|
||||||
|
|
||||||
|
lib_ifnet_io_la_CPPFLAGS = \
|
||||||
|
$(GLIB_CFLAGS) \
|
||||||
|
$(DBUS_CFLAGS) \
|
||||||
|
-DG_DISABLE_DEPRECATED \
|
||||||
|
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||||
|
-DSBINDIR=\"$(sbindir)\"\
|
||||||
|
-g
|
||||||
|
|
||||||
|
lib_ifnet_io_la_LIBADD = \
|
||||||
|
$(top_builddir)/libnm-util/libnm-util.la \
|
||||||
|
$(GLIB_LIBS)\
|
||||||
|
$(GIO_LIBS)
|
||||||
|
|
||||||
|
|
2997
system-settings/plugins/ifnet/connection_parser.c
Normal file
2997
system-settings/plugins/ifnet/connection_parser.c
Normal file
File diff suppressed because it is too large
Load diff
43
system-settings/plugins/ifnet/connection_parser.h
Normal file
43
system-settings/plugins/ifnet/connection_parser.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* -*- 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 "net_parser.h"
|
||||||
|
|
||||||
|
NMConnection *ifnet_update_connection_from_config_block (gchar * conn_name,
|
||||||
|
GError ** error);
|
||||||
|
|
||||||
|
/* nm_conn_name is used to update nm_ifnet_connection's priv data */
|
||||||
|
gboolean ifnet_update_parsers_by_connection (NMConnection * connection,
|
||||||
|
gchar * conn_name,
|
||||||
|
gchar ** nm_conn_name,
|
||||||
|
gchar * config_file,
|
||||||
|
gchar * wpa_file, GError ** error);
|
||||||
|
|
||||||
|
gboolean ifnet_delete_connection_in_parsers (gchar * conn_name,
|
||||||
|
gchar * config_file,
|
||||||
|
gchar * wpa_file);
|
||||||
|
gboolean ifnet_add_new_connection (NMConnection * connection,
|
||||||
|
gchar * config_file, gchar * wpa_file,
|
||||||
|
GError ** error);
|
||||||
|
#endif
|
635
system-settings/plugins/ifnet/net_parser.c
Normal file
635
system-settings/plugins/ifnet/net_parser.c
Normal file
|
@ -0,0 +1,635 @@
|
||||||
|
/* -*- 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 <string.h>
|
||||||
|
#include <nm-system-config-interface.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "net_parser.h"
|
||||||
|
#include "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 (g_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_connection (gchar * name, gchar * type)
|
||||||
|
{
|
||||||
|
if (add_new_connection_config (type, name)) {
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding network for %s", name);
|
||||||
|
net_parser_data_changed = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
} else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
ifnet_has_connection (gchar * conn_name)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (conn_table, conn_name) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GHashTable *
|
||||||
|
get_connection_config (gchar * 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 (gchar * 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) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "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 */
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "global:%s-%s\n", key_value[0],
|
||||||
|
key_value[1]);
|
||||||
|
g_hash_table_insert (global_settings_table,
|
||||||
|
g_strdup (key_value[0]),
|
||||||
|
g_strdup (key_value[1]));
|
||||||
|
g_strfreev (key_value);
|
||||||
|
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
|
||||||
|
/* wireless connection */
|
||||||
|
conn = add_new_connection_config ("wireless", pos);
|
||||||
|
}
|
||||||
|
data = g_strdup (key_value[1]);
|
||||||
|
tmp = strip_string (data, '(');
|
||||||
|
tmp = strip_string (tmp, ')');
|
||||||
|
strip_string (tmp, '"');
|
||||||
|
strip_string (tmp, '\'');
|
||||||
|
if (conn)
|
||||||
|
g_hash_table_insert (conn, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read settings from /etc/NetworkManager/nm-system-settings.conf
|
||||||
|
gchar *
|
||||||
|
ifnet_get_global_setting (gchar * group, gchar * key)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GKeyFile *keyfile = g_key_file_new ();
|
||||||
|
gchar *result = NULL;
|
||||||
|
|
||||||
|
if (!g_key_file_load_from_file (keyfile,
|
||||||
|
IFNET_SYSTEM_SETTINGS_KEY_FILE,
|
||||||
|
G_KEY_FILE_NONE, &error)) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"loading system config file (%s) caused error: (%d) %s",
|
||||||
|
IFNET_SYSTEM_SETTINGS_KEY_FILE,
|
||||||
|
error ? error->code : -1, error
|
||||||
|
&& error->message ? error->message : "(unknown)");
|
||||||
|
} else {
|
||||||
|
result = g_key_file_get_string (keyfile, group, key, &error);
|
||||||
|
}
|
||||||
|
g_key_file_free (keyfile);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
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])) {
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||||
|
"Ignoring function: %s", func_names[i]);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
ifnet_init (gchar * config_file)
|
||||||
|
{
|
||||||
|
GIOChannel *channel = NULL;
|
||||||
|
gchar *line;
|
||||||
|
|
||||||
|
/* Handle multiple lines with brackets */
|
||||||
|
gboolean complete = TRUE;
|
||||||
|
|
||||||
|
/* line buffer */
|
||||||
|
GString *buf;
|
||||||
|
|
||||||
|
net_parser_data_changed = FALSE;
|
||||||
|
|
||||||
|
conn_table = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
global_settings_table = g_hash_table_new (g_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) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Error: Can't open %s\n", 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;
|
||||||
|
}
|
||||||
|
if (line[0] != '#' && line[0] != '\0') {
|
||||||
|
gchar *pos = NULL;
|
||||||
|
|
||||||
|
if (!complete) {
|
||||||
|
complete =
|
||||||
|
g_strrstr (line,
|
||||||
|
")") == NULL ? FALSE : TRUE;
|
||||||
|
if ((pos = strchr (line, '#')) != NULL)
|
||||||
|
*pos = '\0';
|
||||||
|
g_strstrip (line);
|
||||||
|
if (line[0] != '\0') {
|
||||||
|
g_string_append_printf (buf,
|
||||||
|
" %s", line);
|
||||||
|
}
|
||||||
|
g_free (line);
|
||||||
|
if (!complete)
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
complete =
|
||||||
|
(g_strrstr (line, "(") != NULL
|
||||||
|
&& g_strrstr (line, ")") != NULL)
|
||||||
|
|| g_strrstr (line, "(") == NULL;
|
||||||
|
if ((pos = strchr (line, '#')) != NULL)
|
||||||
|
*pos = '\0';
|
||||||
|
g_strstrip (line);
|
||||||
|
if (line[0] != '\0')
|
||||||
|
g_string_append (buf, line);
|
||||||
|
g_free (line);
|
||||||
|
if (!complete)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
ifnet_get_data (gchar * conn_name, const gchar * key)
|
||||||
|
{
|
||||||
|
GHashTable *conn = g_hash_table_lookup (conn_table, conn_name);
|
||||||
|
|
||||||
|
if (conn)
|
||||||
|
return g_hash_table_lookup (conn, key);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ifnet_set_data (gchar * conn_name, gchar * key, gchar * value)
|
||||||
|
{
|
||||||
|
gpointer orin_key = NULL, orin_value = NULL;
|
||||||
|
GHashTable *conn = g_hash_table_lookup (conn_table, conn_name);
|
||||||
|
|
||||||
|
if (!conn) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"%s does not exsit!", conn_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Remove existing key value pair */
|
||||||
|
if (g_hash_table_lookup_extended (conn, key, &orin_key, &orin_value)) {
|
||||||
|
g_hash_table_remove (conn, orin_key);
|
||||||
|
g_free (orin_key);
|
||||||
|
g_free (orin_value);
|
||||||
|
}
|
||||||
|
if (value)
|
||||||
|
g_hash_table_insert (conn, g_strdup (key),
|
||||||
|
strip_string (g_strdup (value), '"'));
|
||||||
|
net_parser_data_changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember to free return value
|
||||||
|
gchar *
|
||||||
|
ifnet_get_global_data (const gchar * key)
|
||||||
|
{
|
||||||
|
gchar *result = g_hash_table_lookup (global_settings_table, key);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
result = g_strdup (result);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
strip_string (result, '"');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return names of legal connections
|
||||||
|
GList *
|
||||||
|
ifnet_get_connection_names ()
|
||||||
|
{
|
||||||
|
GList *names = g_hash_table_get_keys (conn_table);
|
||||||
|
GList *result = NULL;
|
||||||
|
|
||||||
|
while (names) {
|
||||||
|
if (!ignore_connection_name (names->data))
|
||||||
|
result = g_list_append (result, names->data);
|
||||||
|
names = names->next;
|
||||||
|
}
|
||||||
|
return 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, '"');
|
||||||
|
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++)
|
||||||
|
g_string_append_printf (formated_string,
|
||||||
|
"\t\"%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 (gchar * config_file)
|
||||||
|
{
|
||||||
|
GIOChannel *channel;
|
||||||
|
GError **error = NULL;
|
||||||
|
gpointer key, value, name, network;
|
||||||
|
GHashTableIter iter, iter_network;
|
||||||
|
GList *list_iter;
|
||||||
|
gchar *out_line;
|
||||||
|
gsize bytes_written;
|
||||||
|
gboolean result = FALSE;
|
||||||
|
|
||||||
|
if (!net_parser_data_changed)
|
||||||
|
return FALSE;
|
||||||
|
if (!conn_table || !global_settings_table)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
channel = g_io_channel_new_file (config_file, "w", NULL);
|
||||||
|
if (!channel) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Can't open file %s for writing", config_file);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
g_hash_table_iter_init (&iter, global_settings_table);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Writing to %s", config_file);
|
||||||
|
g_io_channel_write_chars (channel,
|
||||||
|
"#Generated by NetworkManager\n"
|
||||||
|
"###### Global Configuration ######\n",
|
||||||
|
-1, &bytes_written, error);
|
||||||
|
/* 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 && *error))
|
||||||
|
break;
|
||||||
|
g_free (out_line);
|
||||||
|
}
|
||||||
|
if (error && *error) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Found error: %s", (*error)->message);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Writing connection data */
|
||||||
|
g_io_channel_write_chars (channel,
|
||||||
|
"\n###### Connection Configuration ######\n",
|
||||||
|
-1, &bytes_written, error);
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 && *error))
|
||||||
|
break;
|
||||||
|
g_free (out_line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (error && *error) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Found error: %s", (*error)->message);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Writing reserved functions */
|
||||||
|
if (functions_list) {
|
||||||
|
g_io_channel_write_chars (channel,
|
||||||
|
"\n###### Reserved Functions ######\n",
|
||||||
|
-1, &bytes_written, error);
|
||||||
|
/* 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 && *error))
|
||||||
|
break;
|
||||||
|
g_free (out_line);
|
||||||
|
}
|
||||||
|
if (error && *error) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Found error: %s", (*error)->message);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_io_channel_flush (channel, error);
|
||||||
|
if (error && *error) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Found error: %s", (*error)->message);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
result = TRUE;
|
||||||
|
net_parser_data_changed = FALSE;
|
||||||
|
done:
|
||||||
|
g_io_channel_shutdown (channel, FALSE, NULL);
|
||||||
|
g_io_channel_unref (channel);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
ifnet_delete_network (gchar * conn_name)
|
||||||
|
{
|
||||||
|
GHashTable *network = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_table != NULL && conn_name != NULL, FALSE);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "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);
|
||||||
|
}
|
46
system-settings/plugins/ifnet/net_parser.h
Normal file
46
system-settings/plugins/ifnet/net_parser.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/* -*- 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
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#define CONF_NET_FILE "/etc/conf.d/net"
|
||||||
|
#define IFNET_SYSTEM_SETTINGS_KEY_FILE "/etc/NetworkManager/nm-system-settings.conf"
|
||||||
|
#define IFNET_KEY_FILE_GROUP "ifnet"
|
||||||
|
|
||||||
|
gboolean ifnet_init (gchar * config_file);
|
||||||
|
void ifnet_destroy (void);
|
||||||
|
|
||||||
|
/* Reader functions */
|
||||||
|
GList *ifnet_get_connection_names (void);
|
||||||
|
gchar *ifnet_get_data (gchar * conn_name, const gchar * key);
|
||||||
|
gchar *ifnet_get_global_data (const gchar * key);
|
||||||
|
gchar *ifnet_get_global_setting (gchar * group, gchar * key);
|
||||||
|
gboolean ifnet_has_connection (gchar * conn_name);
|
||||||
|
|
||||||
|
/* Writer functions */
|
||||||
|
gboolean ifnet_flush_to_file (gchar * config_file);
|
||||||
|
void ifnet_set_data (gchar * conn_name, gchar * key, gchar * value);
|
||||||
|
gboolean ifnet_add_connection (gchar * name, gchar * type);
|
||||||
|
gboolean ifnet_delete_network (gchar * conn_name);
|
||||||
|
#endif
|
931
system-settings/plugins/ifnet/net_utils.c
Normal file
931
system-settings/plugins/ifnet/net_utils.c
Normal file
|
@ -0,0 +1,931 @@
|
||||||
|
/* -*- 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 <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <nm-utils.h>
|
||||||
|
#include <nm-system-config-interface.h>
|
||||||
|
#include "net_utils.h"
|
||||||
|
#include "wpa_parser.h"
|
||||||
|
#include "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 (gchar * value)
|
||||||
|
{
|
||||||
|
gchar *p;
|
||||||
|
|
||||||
|
if (!value)
|
||||||
|
return FALSE;
|
||||||
|
p = value;
|
||||||
|
while (*p) {
|
||||||
|
if (!isxdigit (*p)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
is_ascii (gchar * value)
|
||||||
|
{
|
||||||
|
gchar *p;
|
||||||
|
|
||||||
|
p = value;
|
||||||
|
while (*p) {
|
||||||
|
if (!isascii (*p)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
is_true (char *str)
|
||||||
|
{
|
||||||
|
if (!g_ascii_strcasecmp (str, "yes")
|
||||||
|
|| !g_ascii_strcasecmp (str, "true"))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hex2num (char c)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
return c - '0';
|
||||||
|
if (c >= 'a' && c <= 'f')
|
||||||
|
return c - 'a' + 10;
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return c - 'A' + 10;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hex2byte (const char *hex)
|
||||||
|
{
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
a = hex2num (*hex++);
|
||||||
|
if (a < 0)
|
||||||
|
return -1;
|
||||||
|
b = hex2num (*hex++);
|
||||||
|
if (b < 0)
|
||||||
|
return -1;
|
||||||
|
return (a << 4) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free return value by caller */
|
||||||
|
gchar *
|
||||||
|
utils_hexstr2bin (const gchar * hex, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int a;
|
||||||
|
const gchar *ipos = hex;
|
||||||
|
gchar *buf = NULL;
|
||||||
|
gchar *opos;
|
||||||
|
|
||||||
|
/* Length must be a multiple of 2 */
|
||||||
|
if ((len % 2) != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
opos = buf = g_malloc0 ((len / 2) + 1);
|
||||||
|
for (i = 0; i < len; i += 2) {
|
||||||
|
a = hex2byte (ipos);
|
||||||
|
if (a < 0) {
|
||||||
|
g_free (buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*opos++ = a;
|
||||||
|
ipos += 2;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free return value by caller */
|
||||||
|
gchar *
|
||||||
|
utils_bin2hexstr (const gchar * bytes, int len, int final_len)
|
||||||
|
{
|
||||||
|
static gchar hex_digits[] = "0123456789abcdef";
|
||||||
|
gchar *result;
|
||||||
|
int i;
|
||||||
|
gsize buflen = (len * 2) + 1;
|
||||||
|
|
||||||
|
g_return_val_if_fail (bytes != NULL, NULL);
|
||||||
|
g_return_val_if_fail (len > 0, NULL);
|
||||||
|
g_return_val_if_fail (len < 4096, NULL); /* Arbitrary limit */
|
||||||
|
if (final_len > -1)
|
||||||
|
g_return_val_if_fail (final_len < buflen, NULL);
|
||||||
|
|
||||||
|
result = g_malloc0 (buflen);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
result[2 * i] = hex_digits[(bytes[i] >> 4) & 0xf];
|
||||||
|
result[2 * i + 1] = hex_digits[bytes[i] & 0xf];
|
||||||
|
}
|
||||||
|
/* Cut converted key off at the correct length for this cipher type */
|
||||||
|
if (final_len > -1)
|
||||||
|
result[final_len] = '\0';
|
||||||
|
else
|
||||||
|
result[buflen - 1] = '\0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GQuark
|
||||||
|
ifnet_plugin_error_quark (void)
|
||||||
|
{
|
||||||
|
static GQuark error_quark = 0;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (error_quark == 0))
|
||||||
|
error_quark =
|
||||||
|
g_quark_from_static_string ("ifnet-plugin-error-quark");
|
||||||
|
return error_quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
reload_parsers ()
|
||||||
|
{
|
||||||
|
ifnet_destroy ();
|
||||||
|
wpa_parser_destroy ();
|
||||||
|
if (!ifnet_init (CONF_NET_FILE))
|
||||||
|
return FALSE;
|
||||||
|
wpa_parser_init (WPA_SUPPLICANT_CONF);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
read_hostname (gchar * path)
|
||||||
|
{
|
||||||
|
gchar *contents = NULL, *result = NULL, *tmp;
|
||||||
|
gchar **all_lines = NULL;
|
||||||
|
guint line_num, i;
|
||||||
|
|
||||||
|
if (!g_file_get_contents (path, &contents, NULL, NULL))
|
||||||
|
return NULL;
|
||||||
|
all_lines = g_strsplit (contents, "\n", 0);
|
||||||
|
line_num = g_strv_length (all_lines);
|
||||||
|
for (i = 0; i < line_num; i++) {
|
||||||
|
g_strstrip (all_lines[i]);
|
||||||
|
if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
|
||||||
|
continue;
|
||||||
|
if (g_str_has_prefix (all_lines[i], "hostname")) {
|
||||||
|
tmp = strstr (all_lines[i], "=");
|
||||||
|
tmp++;
|
||||||
|
tmp = strip_string (tmp, '"');
|
||||||
|
result = g_strdup (tmp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
g_strfreev (all_lines);
|
||||||
|
g_free (contents);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
write_hostname (const gchar * hostname, gchar * path)
|
||||||
|
{
|
||||||
|
gchar *contents = g_strdup_printf ("#Generated by NetworkManager\n"
|
||||||
|
"hostname=\"%s\"\n", hostname);
|
||||||
|
gboolean result = g_file_set_contents (path, contents, -1, NULL);
|
||||||
|
|
||||||
|
g_free (contents);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
is_static_ip4 (gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar *data = ifnet_get_data (conn_name, "config");
|
||||||
|
gchar *dhcp6;
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
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 (gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar *data = ifnet_get_data (conn_name, "config");
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return TRUE;
|
||||||
|
return strstr (data, "dhcp6") == NULL ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
is_ip4_address (gchar * in_address)
|
||||||
|
{
|
||||||
|
gchar *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;
|
||||||
|
|
||||||
|
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 (gchar * in_address)
|
||||||
|
{
|
||||||
|
struct in6_addr tmp_ip6_addr;
|
||||||
|
gchar *tmp;
|
||||||
|
gchar *address = g_strdup (in_address);
|
||||||
|
gboolean result = FALSE;
|
||||||
|
|
||||||
|
if (!address) {
|
||||||
|
g_free (address);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
has_ip6_address (gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar **ipset;
|
||||||
|
guint length;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_name != NULL, FALSE);
|
||||||
|
ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
|
||||||
|
length = g_strv_length (ipset);
|
||||||
|
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 (gchar * conn_name, gboolean (*check_fn) (gchar *))
|
||||||
|
{
|
||||||
|
gchar *routes = NULL, *tmp, *end;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_name != NULL, FALSE);
|
||||||
|
tmp = ifnet_get_data (conn_name, "routes");
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
routes = g_strdup (tmp);
|
||||||
|
tmp = strstr (routes, "default via ");
|
||||||
|
if (!tmp) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
tmp += strlen ("default via ");
|
||||||
|
g_strstrip (tmp);
|
||||||
|
if ((end = strstr (tmp, "\"")) != NULL)
|
||||||
|
*end = '\0';
|
||||||
|
if (check_fn (tmp)) {
|
||||||
|
g_free (routes);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
g_free (routes);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ip_block *
|
||||||
|
create_ip4_block (gchar * ip)
|
||||||
|
{
|
||||||
|
ip_block *iblock = g_slice_new0 (ip_block);
|
||||||
|
struct in_addr 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 (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr))
|
||||||
|
goto error;
|
||||||
|
iblock->ip = tmp_ip4_addr.s_addr;
|
||||||
|
prefix = ip_mask[1];
|
||||||
|
i = 0;
|
||||||
|
while (i < length && isdigit (prefix[i]))
|
||||||
|
i++;
|
||||||
|
prefix[i] = '\0';
|
||||||
|
iblock->netmask = nm_utils_ip4_prefix_to_netmask ((guint32)
|
||||||
|
atoi (ip_mask
|
||||||
|
[1]));
|
||||||
|
} else if (strstr (ip, "netmask")) {
|
||||||
|
ip_mask = g_strsplit (ip, " ", 0);
|
||||||
|
length = g_strv_length (ip_mask);
|
||||||
|
if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr))
|
||||||
|
goto error;
|
||||||
|
iblock->ip = tmp_ip4_addr.s_addr;
|
||||||
|
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->netmask = tmp_ip4_addr.s_addr;
|
||||||
|
} else {
|
||||||
|
g_slice_free (ip_block, iblock);
|
||||||
|
if (!is_ip6_address (ip) && !strstr (ip, "dhcp"))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Can't handle ipv4 address: %s, missing netmask or prefix",
|
||||||
|
ip);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
g_strfreev (ip_mask);
|
||||||
|
return iblock;
|
||||||
|
error:
|
||||||
|
if (!is_ip6_address (ip))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 address: %s",
|
||||||
|
ip);
|
||||||
|
g_strfreev (ip_mask);
|
||||||
|
g_slice_free (ip_block, iblock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ip6_block *
|
||||||
|
create_ip6_block (gchar * ip)
|
||||||
|
{
|
||||||
|
ip6_block *iblock = g_slice_new0 (ip6_block);
|
||||||
|
gchar *dup_ip = g_strdup (ip);
|
||||||
|
struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr);
|
||||||
|
gchar *prefix = NULL;
|
||||||
|
|
||||||
|
if ((prefix = strstr (dup_ip, "/")) != NULL) {
|
||||||
|
*prefix = '\0';
|
||||||
|
prefix++;
|
||||||
|
}
|
||||||
|
if (!inet_pton (AF_INET6, dup_ip, tmp_ip6_addr)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
iblock->ip = tmp_ip6_addr;
|
||||||
|
if (prefix) {
|
||||||
|
errno = 0;
|
||||||
|
iblock->prefix = strtol (prefix, NULL, 10);
|
||||||
|
if (errno || iblock->prefix <= 0 || iblock->prefix > 128) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
iblock->prefix = 64;
|
||||||
|
g_free (dup_ip);
|
||||||
|
return iblock;
|
||||||
|
error:
|
||||||
|
if (!is_ip4_address (ip))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv6 address: %s",
|
||||||
|
ip);
|
||||||
|
g_slice_free (ip6_block, iblock);
|
||||||
|
g_slice_free (struct in6_addr, tmp_ip6_addr);
|
||||||
|
|
||||||
|
g_free (dup_ip);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint32
|
||||||
|
get_ip4_gateway (gchar * gateway)
|
||||||
|
{
|
||||||
|
gchar *tmp, *split;
|
||||||
|
struct in_addr tmp_ip4_addr;
|
||||||
|
|
||||||
|
if (!gateway)
|
||||||
|
return 0;
|
||||||
|
tmp = strstr (gateway, "via ");
|
||||||
|
tmp = g_strdup (tmp + strlen ("via "));
|
||||||
|
strip_string (tmp, ' ');
|
||||||
|
strip_string (tmp, '"');
|
||||||
|
if ((split = strstr (tmp, "\"")) != NULL)
|
||||||
|
*split = '\0';
|
||||||
|
if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr))
|
||||||
|
goto error;
|
||||||
|
g_free (tmp);
|
||||||
|
return tmp_ip4_addr.s_addr;
|
||||||
|
error:
|
||||||
|
if (!is_ip6_address (tmp))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 gateway: %s",
|
||||||
|
tmp);
|
||||||
|
g_free (tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct in6_addr *
|
||||||
|
get_ip6_next_hop (gchar * next_hop)
|
||||||
|
{
|
||||||
|
gchar *tmp;
|
||||||
|
struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr);
|
||||||
|
|
||||||
|
if (!next_hop)
|
||||||
|
return 0;
|
||||||
|
tmp = strstr (next_hop, "via ");
|
||||||
|
tmp = g_strdup (tmp + strlen ("via "));
|
||||||
|
strip_string (tmp, ' ');
|
||||||
|
strip_string (tmp, '"');
|
||||||
|
g_strstrip (tmp);
|
||||||
|
if (!inet_pton (AF_INET6, tmp, tmp_ip6_addr))
|
||||||
|
goto error;
|
||||||
|
g_free (tmp);
|
||||||
|
return tmp_ip6_addr;
|
||||||
|
error:
|
||||||
|
if (!is_ip4_address (tmp))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Can't handle IPv6 next_hop: %s", tmp);
|
||||||
|
g_free (tmp);
|
||||||
|
g_slice_free (struct in6_addr, tmp_ip6_addr);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_block *
|
||||||
|
convert_ip4_config_block (gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar **ipset;
|
||||||
|
guint length;
|
||||||
|
guint i;
|
||||||
|
gchar *ip;
|
||||||
|
guint32 def_gateway;
|
||||||
|
gchar *routes;
|
||||||
|
gchar *pos;
|
||||||
|
ip_block *start = NULL, *current = NULL, *iblock = NULL;
|
||||||
|
gchar *pattern =
|
||||||
|
"((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))";
|
||||||
|
GRegex *regex = g_regex_new (pattern, 0, 0, NULL);
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_name != NULL, NULL);
|
||||||
|
ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
|
||||||
|
length = g_strv_length (ipset);
|
||||||
|
routes = ifnet_get_data (conn_name, "routes");
|
||||||
|
if (routes)
|
||||||
|
def_gateway = get_ip4_gateway (strstr (routes, "default"));
|
||||||
|
else
|
||||||
|
def_gateway = 0;
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
ip = ipset[i];
|
||||||
|
ip = strip_string (ip, '"');
|
||||||
|
//Handle ip like 192.168.4.{1..3}
|
||||||
|
if ((pos = strchr (ip, '{')) != NULL) {
|
||||||
|
gchar *ip_start, *ip_prefix;
|
||||||
|
gchar *begin_str, *end_str;
|
||||||
|
int begin, end, j;
|
||||||
|
GMatchInfo *match_info;
|
||||||
|
|
||||||
|
g_regex_match (regex, ip, 0, &match_info);
|
||||||
|
if (!g_match_info_matches (match_info)) {
|
||||||
|
g_match_info_free (match_info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
begin_str = g_match_info_fetch (match_info, 3);
|
||||||
|
end_str = g_match_info_fetch (match_info, 4);
|
||||||
|
begin = atoi (begin_str);
|
||||||
|
end = atoi (end_str);
|
||||||
|
ip_start = g_match_info_fetch (match_info, 2);
|
||||||
|
ip_prefix = g_match_info_fetch (match_info, 5);
|
||||||
|
if (end < begin || begin < 1 || end > 254) {
|
||||||
|
g_match_info_free (match_info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = begin; j <= end; j++) {
|
||||||
|
char suf[4];
|
||||||
|
gchar *newip;
|
||||||
|
|
||||||
|
sprintf (suf, "%d", j);
|
||||||
|
newip =
|
||||||
|
g_strconcat (ip_start, suf, ip_prefix,
|
||||||
|
NULL);
|
||||||
|
iblock = create_ip4_block (newip);
|
||||||
|
if (iblock == NULL) {
|
||||||
|
g_free (newip);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!iblock->gateway && def_gateway != 0)
|
||||||
|
iblock->gateway = def_gateway;
|
||||||
|
if (start == NULL)
|
||||||
|
start = current = iblock;
|
||||||
|
else {
|
||||||
|
current->next = iblock;
|
||||||
|
current = iblock;
|
||||||
|
}
|
||||||
|
g_free (newip);
|
||||||
|
}
|
||||||
|
g_free (begin_str);
|
||||||
|
g_free (end_str);
|
||||||
|
g_free (ip_start);
|
||||||
|
g_free (ip_prefix);
|
||||||
|
g_match_info_free (match_info);
|
||||||
|
} else {
|
||||||
|
iblock = create_ip4_block (ip);
|
||||||
|
if (iblock == NULL)
|
||||||
|
continue;
|
||||||
|
if (!iblock->gateway && def_gateway != 0)
|
||||||
|
iblock->gateway = def_gateway;
|
||||||
|
if (start == NULL)
|
||||||
|
start = current = iblock;
|
||||||
|
else {
|
||||||
|
current->next = iblock;
|
||||||
|
current = iblock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev (ipset);
|
||||||
|
g_regex_unref (regex);
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip6_block *
|
||||||
|
convert_ip6_config_block (gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar **ipset;
|
||||||
|
guint length;
|
||||||
|
guint i;
|
||||||
|
gchar *ip;
|
||||||
|
ip6_block *start = NULL, *current = NULL, *iblock = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_name != NULL, NULL);
|
||||||
|
ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
|
||||||
|
length = g_strv_length (ipset);
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
ip = ipset[i];
|
||||||
|
ip = strip_string (ip, '"');
|
||||||
|
iblock = create_ip6_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 (gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar **ipset;
|
||||||
|
guint length;
|
||||||
|
guint i;
|
||||||
|
gchar *ip;
|
||||||
|
gchar *routes;
|
||||||
|
ip_block *start = NULL, *current = NULL, *iblock = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_name != NULL, NULL);
|
||||||
|
routes = ifnet_get_data (conn_name, "routes");
|
||||||
|
if (!routes)
|
||||||
|
return NULL;
|
||||||
|
ipset = g_strsplit (routes, "\" \"", 0);
|
||||||
|
length = g_strv_length (ipset);
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
ip = ipset[i];
|
||||||
|
if (strstr (ip, "default via ") || strstr (ip, "::")
|
||||||
|
|| !strstr (ip, "via"))
|
||||||
|
continue;
|
||||||
|
ip = strip_string (ip, '"');
|
||||||
|
iblock = create_ip4_block (ip);
|
||||||
|
if (iblock == NULL)
|
||||||
|
continue;
|
||||||
|
iblock->gateway = get_ip4_gateway (ip);
|
||||||
|
if (start == NULL)
|
||||||
|
start = current = iblock;
|
||||||
|
else {
|
||||||
|
current->next = iblock;
|
||||||
|
current = iblock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev (ipset);
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip6_block *
|
||||||
|
convert_ip6_routes_block (gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar **ipset;
|
||||||
|
guint length;
|
||||||
|
guint i;
|
||||||
|
gchar *ip, *tmp_addr;
|
||||||
|
gchar *routes;
|
||||||
|
ip6_block *start = NULL, *current = NULL, *iblock = NULL;
|
||||||
|
struct in6_addr *tmp_ip6_addr;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_name != NULL, NULL);
|
||||||
|
routes = ifnet_get_data (conn_name, "routes");
|
||||||
|
if (!routes)
|
||||||
|
return NULL;
|
||||||
|
ipset = g_strsplit (routes, "\" \"", 0);
|
||||||
|
length = g_strv_length (ipset);
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
ip = ipset[i];
|
||||||
|
ip = strip_string (ip, '"');
|
||||||
|
if (ip[0] == '\0')
|
||||||
|
continue;
|
||||||
|
printf ("ip:%s\n", ip);
|
||||||
|
if ((tmp_addr = strstr (ip, "default via ")) != NULL) {
|
||||||
|
tmp_addr += strlen ("default via ");
|
||||||
|
if (!is_ip6_address (tmp_addr))
|
||||||
|
continue;
|
||||||
|
else {
|
||||||
|
tmp_ip6_addr = g_slice_new0 (struct in6_addr);
|
||||||
|
|
||||||
|
if (inet_pton (AF_INET6, "::", tmp_ip6_addr)) {
|
||||||
|
iblock = g_slice_new0 (ip6_block);
|
||||||
|
iblock->ip = tmp_ip6_addr;
|
||||||
|
iblock->prefix = 128;
|
||||||
|
} else {
|
||||||
|
g_slice_free (struct in6_addr,
|
||||||
|
tmp_ip6_addr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
iblock = create_ip6_block (ip);
|
||||||
|
if (iblock == NULL)
|
||||||
|
continue;
|
||||||
|
iblock->next_hop = get_ip6_next_hop (ip);
|
||||||
|
if (iblock->next_hop == NULL) {
|
||||||
|
destroy_ip6_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_slice_free (ip_block, iblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
destroy_ip6_block (ip6_block * iblock)
|
||||||
|
{
|
||||||
|
g_slice_free (struct in6_addr, iblock->ip);
|
||||||
|
g_slice_free (struct in6_addr, iblock->next_hop);
|
||||||
|
|
||||||
|
g_slice_free (ip6_block, iblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_ip4_dns_servers (NMSettingIP4Config * s_ip4, gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar *dns_servers = ifnet_get_data (conn_name, "dns_servers");
|
||||||
|
gchar **server_list;
|
||||||
|
guint length, i;
|
||||||
|
struct in_addr tmp_ip4_addr;
|
||||||
|
guint32 new_dns;
|
||||||
|
|
||||||
|
if (!dns_servers)
|
||||||
|
return;
|
||||||
|
strip_string (dns_servers, '"');
|
||||||
|
server_list = g_strsplit (dns_servers, " ", 0);
|
||||||
|
length = g_strv_length (server_list);
|
||||||
|
if (length)
|
||||||
|
g_object_set (s_ip4, NM_SETTING_IP4_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]))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"ignored dns: %s\n",
|
||||||
|
server_list[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_dns = tmp_ip4_addr.s_addr;
|
||||||
|
if (new_dns && !nm_setting_ip4_config_add_dns (s_ip4, new_dns))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"warning: duplicate DNS server %s",
|
||||||
|
server_list[i]);
|
||||||
|
}
|
||||||
|
g_strfreev (server_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_ip6_dns_servers (NMSettingIP6Config * s_ip6, gchar * conn_name)
|
||||||
|
{
|
||||||
|
gchar *dns_servers = ifnet_get_data (conn_name, "dns_servers");
|
||||||
|
gchar **server_list;
|
||||||
|
guint length, i;
|
||||||
|
struct in6_addr tmp_ip6_addr;
|
||||||
|
|
||||||
|
if (!dns_servers)
|
||||||
|
return;
|
||||||
|
strip_string (dns_servers, '"');
|
||||||
|
server_list = g_strsplit (dns_servers, " ", 0);
|
||||||
|
length = g_strv_length (server_list);
|
||||||
|
if (length)
|
||||||
|
g_object_set (s_ip6, NM_SETTING_IP6_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]))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"ignored dns: %s\n",
|
||||||
|
server_list[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_ip6_addr)
|
||||||
|
&& !nm_setting_ip6_config_add_dns (s_ip6, &tmp_ip6_addr))
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"warning: duplicate DNS server %s",
|
||||||
|
server_list[i]);
|
||||||
|
}
|
||||||
|
g_strfreev (server_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
is_managed (gchar * 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
get_dhcp_hostname_and_client_id (char **hostname, char **client_id)
|
||||||
|
{
|
||||||
|
gchar *dhcp_client = ifnet_get_global_setting ("main", "dhcp");
|
||||||
|
const gchar *dhcpcd_conf = "/etc/dhcpcd.conf";
|
||||||
|
const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf";
|
||||||
|
gchar *line = NULL, *tmp = NULL, *contents = NULL;
|
||||||
|
gchar **all_lines;
|
||||||
|
guint line_num, i;
|
||||||
|
|
||||||
|
*hostname = NULL;
|
||||||
|
*client_id = NULL;
|
||||||
|
if (dhcp_client) {
|
||||||
|
if (!strcmp (dhcp_client, "dhclient"))
|
||||||
|
g_file_get_contents (dhclient_conf, &contents, NULL,
|
||||||
|
NULL);
|
||||||
|
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);
|
||||||
|
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];
|
||||||
|
// dhcpcd.conf
|
||||||
|
g_strstrip (line);
|
||||||
|
if (g_str_has_prefix (line, "hostname")) {
|
||||||
|
tmp = line + strlen ("hostname");
|
||||||
|
g_strstrip (tmp);
|
||||||
|
if (tmp[0] != '\0')
|
||||||
|
*hostname = g_strdup (tmp);
|
||||||
|
else
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||||
|
"dhcpcd hostname not defined, ignoring");
|
||||||
|
} else if (g_str_has_prefix (line, "clientid")) {
|
||||||
|
tmp = line + strlen ("clientid");
|
||||||
|
g_strstrip (tmp);
|
||||||
|
if (tmp[0] != '\0')
|
||||||
|
*client_id = g_strdup (tmp);
|
||||||
|
else
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||||
|
"dhcpcd clientid not defined, ignoring");
|
||||||
|
}
|
||||||
|
// dhclient.conf
|
||||||
|
else if ((tmp = strstr (line, "send host-name")) != NULL) {
|
||||||
|
tmp += strlen ("send host-name");
|
||||||
|
g_strstrip (tmp);
|
||||||
|
strip_string (tmp, '"');
|
||||||
|
strip_string (tmp, ';');
|
||||||
|
if (tmp[0] != '\0')
|
||||||
|
*hostname = g_strdup (tmp);
|
||||||
|
else
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||||
|
"dhclient hostname not defined, ignoring");
|
||||||
|
} else if ((tmp = strstr (line, "send dhcp-client-identifier"))
|
||||||
|
!= NULL) {
|
||||||
|
tmp += strlen ("send dhcp-client-identifier");
|
||||||
|
g_strstrip (tmp);
|
||||||
|
strip_string (tmp, ';');
|
||||||
|
if (tmp[0] != '\0')
|
||||||
|
*client_id = g_strdup (tmp);
|
||||||
|
else
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||||
|
"dhclient clientid not defined, ignoring");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev (all_lines);
|
||||||
|
g_free (contents);
|
||||||
|
}
|
80
system-settings/plugins/ifnet/net_utils.h
Normal file
80
system-settings/plugins/ifnet/net_utils.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/* -*- 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 "SCPlugin-Ifnet"
|
||||||
|
#include <glib.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <nm-setting-ip6-config.h>
|
||||||
|
#include <nm-setting-ip4-config.h>
|
||||||
|
#include "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 {
|
||||||
|
guint32 ip;
|
||||||
|
guint32 netmask;
|
||||||
|
guint32 gateway;
|
||||||
|
struct _ip_block *next;
|
||||||
|
} ip_block;
|
||||||
|
|
||||||
|
typedef struct _ip6_block {
|
||||||
|
struct in6_addr *ip;
|
||||||
|
long int prefix;
|
||||||
|
struct in6_addr *next_hop;
|
||||||
|
struct _ip6_block *next;
|
||||||
|
} ip6_block;
|
||||||
|
|
||||||
|
gchar *read_hostname (gchar * path);
|
||||||
|
gboolean write_hostname (const gchar * hostname, gchar * path);
|
||||||
|
gboolean is_static_ip4 (gchar * conn_name);
|
||||||
|
gboolean is_static_ip6 (gchar * conn_name);
|
||||||
|
gboolean is_ip4_address (gchar * in_address);
|
||||||
|
gboolean is_ip6_address (gchar * in_address);
|
||||||
|
gboolean has_ip6_address (gchar * conn_name);
|
||||||
|
gboolean has_default_route (gchar * conn_name, gboolean (*check_fn) (gchar *));
|
||||||
|
gboolean reload_parsers (void);
|
||||||
|
|
||||||
|
ip_block *convert_ip4_config_block (gchar * conn_name);
|
||||||
|
ip6_block *convert_ip6_config_block (gchar * conn_name);
|
||||||
|
ip_block *convert_ip4_routes_block (gchar * conn_name);
|
||||||
|
ip6_block *convert_ip6_routes_block (gchar * conn_name);
|
||||||
|
void destroy_ip_block (ip_block * iblock);
|
||||||
|
void destroy_ip6_block (ip6_block * iblock);
|
||||||
|
|
||||||
|
void set_ip4_dns_servers (NMSettingIP4Config * s_ip4, gchar * conn_name);
|
||||||
|
void set_ip6_dns_servers (NMSettingIP6Config * s_ip6, gchar * conn_name);
|
||||||
|
|
||||||
|
gchar *strip_string (gchar * str, gchar t);
|
||||||
|
gboolean is_managed (gchar * conn_name);
|
||||||
|
|
||||||
|
GQuark ifnet_plugin_error_quark (void);
|
||||||
|
gchar *utils_hexstr2bin (const gchar * hex, size_t len);
|
||||||
|
gchar *utils_bin2hexstr (const gchar * bytes, int len, int final_len);
|
||||||
|
|
||||||
|
gboolean is_hex (gchar * value);
|
||||||
|
gboolean is_ascii (gchar * value);
|
||||||
|
gboolean is_true (gchar * str);
|
||||||
|
|
||||||
|
void get_dhcp_hostname_and_client_id (char **hostname, char **client_id);
|
||||||
|
|
||||||
|
#endif
|
251
system-settings/plugins/ifnet/nm-ifnet-connection.c
Normal file
251
system-settings/plugins/ifnet/nm-ifnet-connection.c
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
/* -*- 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 <string.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
#include <NetworkManager.h>
|
||||||
|
#include <nm-utils.h>
|
||||||
|
#include <nm-setting-wireless-security.h>
|
||||||
|
#include <nm-sysconfig-connection.h>
|
||||||
|
#include <nm-system-config-interface.h>
|
||||||
|
#include <nm-system-config-error.h>
|
||||||
|
#include "nm-ifnet-connection.h"
|
||||||
|
#include "connection_parser.h"
|
||||||
|
#include "net_parser.h"
|
||||||
|
#include "net_utils.h"
|
||||||
|
#include "wpa_parser.h"
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
|
static NMSettingsConnectionInterface *parent_settings_connection_iface;
|
||||||
|
|
||||||
|
static void settings_connection_interface_init (NMSettingsConnectionInterface *
|
||||||
|
klass);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_EXTENDED (NMIfnetConnection, nm_ifnet_connection,
|
||||||
|
NM_TYPE_SYSCONFIG_CONNECTION, 0,
|
||||||
|
G_IMPLEMENT_INTERFACE
|
||||||
|
(NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
|
||||||
|
settings_connection_interface_init))
|
||||||
|
// G_DEFINE_TYPE(NMIfnetConnection, nm_ifnet_connection,
|
||||||
|
// NM_TYPE_SYSCONFIG_CONNECTION)
|
||||||
|
#define NM_IFNET_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionPrivate))
|
||||||
|
enum {
|
||||||
|
PROP_ZERO,
|
||||||
|
PROP_CONN_NAME,
|
||||||
|
_PROP_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IFNET_SETUP_MONITORS,
|
||||||
|
IFNET_CANCEL_MONITORS,
|
||||||
|
IFNET_LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[IFNET_LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gchar *conn_name;
|
||||||
|
NMSystemConfigInterface *config;
|
||||||
|
} NMIfnetConnectionPrivate;
|
||||||
|
|
||||||
|
NMIfnetConnection *
|
||||||
|
nm_ifnet_connection_new (gchar * conn_name)
|
||||||
|
{
|
||||||
|
NMConnection *tmp;
|
||||||
|
GObject *object;
|
||||||
|
GError **error = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn_name != NULL, NULL);
|
||||||
|
tmp = ifnet_update_connection_from_config_block (conn_name, error);
|
||||||
|
if (!tmp)
|
||||||
|
return NULL;
|
||||||
|
object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION,
|
||||||
|
NM_IFNET_CONNECTION_CONN_NAME,
|
||||||
|
conn_name, NULL);
|
||||||
|
if (!object) {
|
||||||
|
g_object_unref (tmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (object), tmp,
|
||||||
|
FALSE, NULL);
|
||||||
|
g_object_unref (tmp);
|
||||||
|
return NM_IFNET_CONNECTION (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_ifnet_connection_init (NMIfnetConnection * connection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
update (NMSettingsConnectionInterface * connection,
|
||||||
|
NMSettingsConnectionInterfaceUpdateFunc callback, gpointer user_data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
gchar *new_conn_name = NULL;
|
||||||
|
gboolean result;
|
||||||
|
NMIfnetConnectionPrivate *priv =
|
||||||
|
NM_IFNET_CONNECTION_GET_PRIVATE (connection);
|
||||||
|
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
|
||||||
|
if (!ifnet_update_parsers_by_connection
|
||||||
|
(NM_CONNECTION (connection), priv->conn_name, &new_conn_name,
|
||||||
|
CONF_NET_FILE, WPA_SUPPLICANT_CONF, &error)) {
|
||||||
|
if (new_conn_name)
|
||||||
|
g_free (new_conn_name);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to update %s",
|
||||||
|
priv->conn_name);
|
||||||
|
reload_parsers ();
|
||||||
|
callback (connection, error, user_data);
|
||||||
|
g_error_free (error);
|
||||||
|
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (priv->conn_name);
|
||||||
|
priv->conn_name = new_conn_name;
|
||||||
|
result =
|
||||||
|
parent_settings_connection_iface->update (connection, callback,
|
||||||
|
user_data);
|
||||||
|
if (result)
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully updated %s",
|
||||||
|
priv->conn_name);
|
||||||
|
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_delete (NMSettingsConnectionInterface * connection,
|
||||||
|
NMSettingsConnectionInterfaceDeleteFunc callback, gpointer user_data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
gboolean result;
|
||||||
|
NMIfnetConnectionPrivate *priv =
|
||||||
|
NM_IFNET_CONNECTION_GET_PRIVATE (connection);
|
||||||
|
g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
|
||||||
|
if (!ifnet_delete_connection_in_parsers
|
||||||
|
(priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF)) {
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to delete %s",
|
||||||
|
priv->conn_name);
|
||||||
|
reload_parsers ();
|
||||||
|
callback (connection, error, user_data);
|
||||||
|
g_error_free (error);
|
||||||
|
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
result =
|
||||||
|
parent_settings_connection_iface->delete (connection, callback,
|
||||||
|
user_data);
|
||||||
|
if (result)
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully deleted %s",
|
||||||
|
priv->conn_name);
|
||||||
|
g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
settings_connection_interface_init (NMSettingsConnectionInterface * iface)
|
||||||
|
{
|
||||||
|
parent_settings_connection_iface = g_type_interface_peek_parent (iface);
|
||||||
|
iface->update = update;
|
||||||
|
iface->delete = do_delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_property (GObject * object, guint prop_id,
|
||||||
|
const GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
NMIfnetConnectionPrivate *priv =
|
||||||
|
NM_IFNET_CONNECTION_GET_PRIVATE (object);
|
||||||
|
g_return_if_fail (priv);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CONN_NAME:
|
||||||
|
if (priv->conn_name)
|
||||||
|
g_free (priv->conn_name);
|
||||||
|
priv->conn_name = g_strdup (g_value_get_pointer (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
NMIfnetConnectionPrivate *priv =
|
||||||
|
NM_IFNET_CONNECTION_GET_PRIVATE (object);
|
||||||
|
g_return_if_fail (priv);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_CONN_NAME:
|
||||||
|
g_value_set_pointer (value, priv->conn_name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
finalize (GObject * object)
|
||||||
|
{
|
||||||
|
NMIfnetConnectionPrivate *priv =
|
||||||
|
NM_IFNET_CONNECTION_GET_PRIVATE (object);
|
||||||
|
g_return_if_fail (priv);
|
||||||
|
|
||||||
|
if (priv->conn_name)
|
||||||
|
g_free (priv->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);
|
||||||
|
|
||||||
|
g_type_class_add_private (ifnet_connection_class,
|
||||||
|
sizeof (NMIfnetConnectionPrivate));
|
||||||
|
|
||||||
|
object_class->set_property = set_property;
|
||||||
|
object_class->get_property = get_property;
|
||||||
|
object_class->finalize = finalize;
|
||||||
|
|
||||||
|
/* Properties */
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_CONN_NAME,
|
||||||
|
g_param_spec_pointer (NM_IFNET_CONNECTION_CONN_NAME,
|
||||||
|
"config_block",
|
||||||
|
"",
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
49
system-settings/plugins/ifnet/nm-ifnet-connection.h
Normal file
49
system-settings/plugins/ifnet/nm-ifnet-connection.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* -*- 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 NM_IFNET_CONNECTION_H
|
||||||
|
#define NM_IFNET_CONNECTION_H
|
||||||
|
|
||||||
|
#include <nm-sysconfig-connection.h>
|
||||||
|
#include "net_parser.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
#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 ((obj), NM_TYPE_IFNET_CONNECTION))
|
||||||
|
#define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass))
|
||||||
|
#define NM_IFNET_CONNECTION_CONN_NAME "connection_name"
|
||||||
|
typedef struct {
|
||||||
|
NMSysconfigConnection parent;
|
||||||
|
} NMIfnetConnection;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NMSysconfigConnectionClass parent;
|
||||||
|
} NMIfnetConnectionClass;
|
||||||
|
|
||||||
|
GType nm_ifnet_connection_get_type (void);
|
||||||
|
|
||||||
|
NMIfnetConnection *nm_ifnet_connection_new (gchar * conn_name);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* NM_IFNET_CONNECTION_H */
|
585
system-settings/plugins/ifnet/plugin.c
Normal file
585
system-settings/plugins/ifnet/plugin.c
Normal file
|
@ -0,0 +1,585 @@
|
||||||
|
/* -*- 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 <string.h>
|
||||||
|
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include <nm-utils.h>
|
||||||
|
#include <nm-setting-connection.h>
|
||||||
|
|
||||||
|
#include "NetworkManager.h"
|
||||||
|
#include "nm-system-config-interface.h"
|
||||||
|
#include "nm-ifnet-connection.h"
|
||||||
|
|
||||||
|
#include "plugin.h"
|
||||||
|
#include "net_utils.h"
|
||||||
|
#include "net_parser.h"
|
||||||
|
#include "wpa_parser.h"
|
||||||
|
#include "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 [dagger] prefix."
|
||||||
|
#define IFNET_SYSTEM_HOSTNAME_FILE "/etc/conf.d/hostname"
|
||||||
|
#define IFNET_MANAGE_WELL_KNOWN_DEFAULT TRUE
|
||||||
|
#define IFNET_KEY_FILE_KEY_MANAGED "managed"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GHashTable *config_connections;
|
||||||
|
gchar *hostname;
|
||||||
|
gboolean unmanaged_well_known;
|
||||||
|
|
||||||
|
GFileMonitor *hostname_monitor;
|
||||||
|
GFileMonitor *net_monitor;
|
||||||
|
GFileMonitor *wpa_monitor;
|
||||||
|
|
||||||
|
} SCPluginIfnetPrivate;
|
||||||
|
|
||||||
|
typedef void (*FileChangedFn) (gpointer user_data);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FileChangedFn callback;
|
||||||
|
gpointer user_data;
|
||||||
|
} FileMonitorInfo;
|
||||||
|
|
||||||
|
static void system_config_interface_init (NMSystemConfigInterface *
|
||||||
|
system_config_interface_class);
|
||||||
|
|
||||||
|
static void
|
||||||
|
reload_connections (gpointer config);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_EXTENDED (SCPluginIfnet, sc_plugin_ifnet, G_TYPE_OBJECT, 0,
|
||||||
|
G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
|
||||||
|
system_config_interface_init))
|
||||||
|
#define SC_PLUGIN_IFNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetPrivate))
|
||||||
|
/*
|
||||||
|
static void
|
||||||
|
ignore_cb(NMSettingsConnectionInterface * connection,
|
||||||
|
GError * error, gpointer user_data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
get_hostname (NMSystemConfigInterface * config)
|
||||||
|
{
|
||||||
|
return SC_PLUGIN_IFNET_GET_PRIVATE (config)->hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_system_hostname (gpointer config)
|
||||||
|
{
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
|
||||||
|
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Updating hostname");
|
||||||
|
|
||||||
|
if (priv->hostname)
|
||||||
|
g_free (priv->hostname);
|
||||||
|
priv->hostname = read_hostname (IFNET_SYSTEM_HOSTNAME_FILE);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (config),
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Hostname updated to: %s",
|
||||||
|
priv->hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_system_hostname (NMSystemConfigInterface * config,
|
||||||
|
const gchar * newhostname)
|
||||||
|
{
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
|
||||||
|
|
||||||
|
g_return_if_fail (newhostname);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Write system hostname: %s",
|
||||||
|
newhostname);
|
||||||
|
if (write_hostname (newhostname, IFNET_SYSTEM_HOSTNAME_FILE)) {
|
||||||
|
if (priv->hostname)
|
||||||
|
g_free (priv->hostname);
|
||||||
|
priv->hostname = g_strdup (newhostname);
|
||||||
|
g_object_notify (G_OBJECT (config),
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
|
||||||
|
} else
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Write system hostname: %s failed", newhostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_managed_plugin ()
|
||||||
|
{
|
||||||
|
gchar *result = NULL;
|
||||||
|
|
||||||
|
result =
|
||||||
|
ifnet_get_global_setting (IFNET_KEY_FILE_GROUP,
|
||||||
|
IFNET_KEY_FILE_KEY_MANAGED);
|
||||||
|
if (result) {
|
||||||
|
if (is_true (result)) {
|
||||||
|
g_free (result);
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
g_free (result);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 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);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Monitoring %s", filename);
|
||||||
|
|
||||||
|
} else
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Monitoring %s failed, error: %s", filename,
|
||||||
|
error == NULL ? "nothing" : (*error)->message);
|
||||||
|
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_old_connection (gchar * conn_name,
|
||||||
|
NMIfnetConnection * old_conn,
|
||||||
|
NMIfnetConnection * new_conn,
|
||||||
|
SCPluginIfnetPrivate * priv)
|
||||||
|
{
|
||||||
|
GError **error = NULL;
|
||||||
|
|
||||||
|
if (!nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (old_conn),
|
||||||
|
NM_CONNECTION (new_conn), TRUE,
|
||||||
|
error)) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "error updating: %s",
|
||||||
|
(error
|
||||||
|
&& (*error)) ? (*error)->message : "(unknown)");
|
||||||
|
} else
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated",
|
||||||
|
conn_name);
|
||||||
|
g_object_unref (new_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_monitors (NMIfnetConnection * connection, gpointer user_data)
|
||||||
|
{
|
||||||
|
SCPluginIfnet *self = SC_PLUGIN_IFNET (user_data);
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
priv->hostname_monitor =
|
||||||
|
monitor_file_changes (IFNET_SYSTEM_HOSTNAME_FILE,
|
||||||
|
update_system_hostname, user_data);
|
||||||
|
priv->net_monitor =
|
||||||
|
monitor_file_changes (CONF_NET_FILE, reload_connections, user_data);
|
||||||
|
priv->wpa_monitor =
|
||||||
|
monitor_file_changes (WPA_SUPPLICANT_CONF, reload_connections,
|
||||||
|
user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cancel_monitors (NMIfnetConnection * connection, gpointer user_data)
|
||||||
|
{
|
||||||
|
SCPluginIfnet *self = SC_PLUGIN_IFNET (user_data);
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
if (priv->hostname_monitor) {
|
||||||
|
g_file_monitor_cancel (priv->hostname_monitor);
|
||||||
|
g_object_unref (priv->hostname_monitor);
|
||||||
|
}
|
||||||
|
if (priv->net_monitor) {
|
||||||
|
g_file_monitor_cancel (priv->net_monitor);
|
||||||
|
g_object_unref (priv->net_monitor);
|
||||||
|
}
|
||||||
|
if (priv->wpa_monitor) {
|
||||||
|
g_file_monitor_cancel (priv->wpa_monitor);
|
||||||
|
g_object_unref (priv->wpa_monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reload_connections (gpointer config)
|
||||||
|
{
|
||||||
|
SCPluginIfnet *self = SC_PLUGIN_IFNET (config);
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
|
||||||
|
GList *conn_names = NULL, *n_iter = NULL;
|
||||||
|
|
||||||
|
/* save names for removing unused connections */
|
||||||
|
GHashTable *new_conn_names = NULL;
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key;
|
||||||
|
gpointer value;
|
||||||
|
|
||||||
|
if (priv->unmanaged_well_known)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!reload_parsers ())
|
||||||
|
return;
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections");
|
||||||
|
conn_names = ifnet_get_connection_names ();
|
||||||
|
new_conn_names =
|
||||||
|
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
|
for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) {
|
||||||
|
NMIfnetConnection *exported;
|
||||||
|
NMIfnetConnection *old;
|
||||||
|
gchar *conn_name = g_strdup (n_iter->data);
|
||||||
|
|
||||||
|
/* add the new connection */
|
||||||
|
exported = nm_ifnet_connection_new (conn_name);
|
||||||
|
if (!exported) {
|
||||||
|
g_free (conn_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
g_signal_connect (G_OBJECT (exported), "ifnet_setup_monitors",
|
||||||
|
G_CALLBACK (setup_monitors), config);
|
||||||
|
g_signal_connect (G_OBJECT (exported), "ifnet_cancel_monitors",
|
||||||
|
G_CALLBACK (cancel_monitors), config);
|
||||||
|
old = g_hash_table_lookup (priv->config_connections, conn_name);
|
||||||
|
if (old && exported) {
|
||||||
|
gchar *auto_refresh =
|
||||||
|
ifnet_get_global_setting (IFNET_KEY_FILE_GROUP,
|
||||||
|
"auto_refresh");
|
||||||
|
|
||||||
|
if (auto_refresh && is_true (auto_refresh)) {
|
||||||
|
if (!nm_connection_compare (NM_CONNECTION (old),
|
||||||
|
NM_CONNECTION
|
||||||
|
(exported),
|
||||||
|
NM_SETTING_COMPARE_FLAG_EXACT))
|
||||||
|
{
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||||
|
"Auto refreshing %s",
|
||||||
|
conn_name);
|
||||||
|
g_signal_emit_by_name (old,
|
||||||
|
NM_SETTINGS_CONNECTION_INTERFACE_REMOVED);
|
||||||
|
g_hash_table_remove
|
||||||
|
(priv->config_connections,
|
||||||
|
conn_name);
|
||||||
|
g_hash_table_insert
|
||||||
|
(priv->config_connections,
|
||||||
|
g_strdup (conn_name), exported);
|
||||||
|
if (is_managed (conn_name))
|
||||||
|
g_signal_emit_by_name (self,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
|
||||||
|
exported);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
update_old_connection (conn_name, old,
|
||||||
|
exported, priv);
|
||||||
|
g_signal_emit_by_name (self,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
|
||||||
|
} else if (exported) {
|
||||||
|
g_hash_table_insert (priv->config_connections,
|
||||||
|
g_strdup (conn_name), exported);
|
||||||
|
if (is_managed (conn_name))
|
||||||
|
g_signal_emit_by_name (self,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
|
||||||
|
exported);
|
||||||
|
}
|
||||||
|
g_hash_table_insert (new_conn_names, conn_name, conn_name);
|
||||||
|
}
|
||||||
|
/* remove unused connections */
|
||||||
|
g_hash_table_iter_init (&iter, priv->config_connections);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
|
if (!g_hash_table_lookup (new_conn_names, key)) {
|
||||||
|
g_signal_emit_by_name (value,
|
||||||
|
NM_SETTINGS_CONNECTION_INTERFACE_REMOVED);
|
||||||
|
g_hash_table_remove (priv->config_connections, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_hash_table_remove_all (new_conn_names);
|
||||||
|
g_hash_table_destroy (new_conn_names);
|
||||||
|
g_list_free (conn_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
add_connection (NMSystemConfigInterface * config,
|
||||||
|
NMConnection * connection, GError ** error)
|
||||||
|
{
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
result = ifnet_add_new_connection (connection, CONF_NET_FILE,
|
||||||
|
WPA_SUPPLICANT_CONF, error);
|
||||||
|
reload_connections (config);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_unmanaged (gpointer key, gpointer data, gpointer user_data)
|
||||||
|
{
|
||||||
|
GSList **list = (GSList **) user_data;
|
||||||
|
gchar *conn_name = (gchar *) key;
|
||||||
|
const char *unmanaged_spec;
|
||||||
|
GSList *iter;
|
||||||
|
|
||||||
|
if (is_managed (conn_name))
|
||||||
|
return;
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Checking unmanaged: %s", conn_name);
|
||||||
|
unmanaged_spec = ifnet_get_data (conn_name, "mac");
|
||||||
|
if (!unmanaged_spec)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Just return if the unmanaged spec is already in the list */
|
||||||
|
for (iter = *list; iter; iter = g_slist_next (iter)) {
|
||||||
|
if (!strcmp ((char *) iter->data, unmanaged_spec))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Add unmanaged: %s", unmanaged_spec);
|
||||||
|
*list =
|
||||||
|
g_slist_prepend (*list, g_strdup_printf ("mac:%s", unmanaged_spec));
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSList *
|
||||||
|
get_unmanaged_specs (NMSystemConfigInterface * config)
|
||||||
|
{
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
|
||||||
|
GSList *list = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv->config_connections != NULL, NULL);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "getting unmanaged specs...");
|
||||||
|
g_hash_table_foreach (priv->config_connections, check_unmanaged, &list);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SCPluginIfnet_init (NMSystemConfigInterface * config)
|
||||||
|
{
|
||||||
|
SCPluginIfnet *self = SC_PLUGIN_IFNET (config);
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Initializing!");
|
||||||
|
if (!priv->config_connections)
|
||||||
|
priv->config_connections =
|
||||||
|
g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||||
|
g_object_unref);
|
||||||
|
priv->unmanaged_well_known = !is_managed_plugin ();
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "management mode: %s",
|
||||||
|
priv->unmanaged_well_known ? "unmanaged" : "managed");
|
||||||
|
// GFileMonitor setup
|
||||||
|
setup_monitors (NULL, config);
|
||||||
|
reload_connections (config);
|
||||||
|
/* Now if we're running in managed mode, let NM know there are new connections */
|
||||||
|
if (!priv->unmanaged_well_known) {
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key;
|
||||||
|
gpointer value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, priv->config_connections);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
|
if (is_managed ((gchar *) key))
|
||||||
|
g_signal_emit_by_name
|
||||||
|
(self,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
|
||||||
|
NM_EXPORTED_CONNECTION (value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Read hostname */
|
||||||
|
update_system_hostname (self);
|
||||||
|
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Initialzation complete!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSList *
|
||||||
|
SCPluginIfnet_get_connections (NMSystemConfigInterface * config)
|
||||||
|
{
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
|
||||||
|
GSList *connections = NULL;
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "(%d) ... get_connections.",
|
||||||
|
GPOINTER_TO_UINT (config));
|
||||||
|
if (priv->unmanaged_well_known) {
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME,
|
||||||
|
"(%d) ... get_connections (managed=false): return empty list.",
|
||||||
|
GPOINTER_TO_UINT (config));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, priv->config_connections);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
if (is_managed ((gchar *) key))
|
||||||
|
connections = g_slist_prepend (connections, value);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "(%d) connections count: %d",
|
||||||
|
GPOINTER_TO_UINT (config), g_slist_length (connections));
|
||||||
|
return connections;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
system_config_interface_init (NMSystemConfigInterface *
|
||||||
|
system_config_interface_class)
|
||||||
|
{
|
||||||
|
system_config_interface_class->init = SCPluginIfnet_init;
|
||||||
|
system_config_interface_class->get_connections =
|
||||||
|
SCPluginIfnet_get_connections;
|
||||||
|
system_config_interface_class->get_unmanaged_specs =
|
||||||
|
get_unmanaged_specs;
|
||||||
|
system_config_interface_class->add_connection = add_connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_plugin_ifnet_init (SCPluginIfnet * plugin)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
NMSystemConfigInterface *self = NM_SYSTEM_CONFIG_INTERFACE (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
|
||||||
|
g_value_set_string (value, IFNET_PLUGIN_NAME_PRINT);
|
||||||
|
break;
|
||||||
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
|
||||||
|
g_value_set_string (value, IFNET_PLUGIN_INFO);
|
||||||
|
break;
|
||||||
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
|
||||||
|
g_value_set_uint (value,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS
|
||||||
|
|
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
|
||||||
|
break;
|
||||||
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
|
||||||
|
g_value_set_string (value, get_hostname (self));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_property (GObject * object, guint prop_id, const GValue * value,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id) {
|
||||||
|
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:{
|
||||||
|
const gchar *hostname = g_value_get_string (value);
|
||||||
|
|
||||||
|
if (hostname && strlen (hostname) < 1)
|
||||||
|
hostname = NULL;
|
||||||
|
write_system_hostname (NM_SYSTEM_CONFIG_INTERFACE
|
||||||
|
(object), hostname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dispose (GObject * object)
|
||||||
|
{
|
||||||
|
SCPluginIfnet *plugin = SC_PLUGIN_IFNET (object);
|
||||||
|
SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (plugin);
|
||||||
|
|
||||||
|
cancel_monitors (NULL, object);
|
||||||
|
if (priv->config_connections) {
|
||||||
|
g_hash_table_remove_all (priv->config_connections);
|
||||||
|
g_hash_table_destroy (priv->config_connections);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->hostname)
|
||||||
|
g_free (priv->hostname);
|
||||||
|
ifnet_destroy ();
|
||||||
|
wpa_parser_destroy ();
|
||||||
|
G_OBJECT_CLASS (sc_plugin_ifnet_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_plugin_ifnet_class_init (SCPluginIfnetClass * req_class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
|
||||||
|
|
||||||
|
g_type_class_add_private (req_class, sizeof (SCPluginIfnetPrivate));
|
||||||
|
|
||||||
|
object_class->dispose = dispose;
|
||||||
|
object_class->get_property = get_property;
|
||||||
|
object_class->set_property = set_property;
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_NAME);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_INFO);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
|
||||||
|
NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_MODULE_EXPORT GObject *
|
||||||
|
nm_system_config_factory (void)
|
||||||
|
{
|
||||||
|
static SCPluginIfnet *singleton = NULL;
|
||||||
|
|
||||||
|
if (!singleton)
|
||||||
|
singleton
|
||||||
|
=
|
||||||
|
SC_PLUGIN_IFNET (g_object_new (SC_TYPE_PLUGIN_IFNET, NULL));
|
||||||
|
else
|
||||||
|
g_object_ref (singleton);
|
||||||
|
return G_OBJECT (singleton);
|
||||||
|
}
|
47
system-settings/plugins/ifnet/plugin.h
Normal file
47
system-settings/plugins/ifnet/plugin.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* -*- 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_
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#define SC_TYPE_PLUGIN_IFNET (sc_plugin_ifnet_get_type ())
|
||||||
|
#define SC_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFNET, SCPluginIfnet))
|
||||||
|
#define SC_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetClass))
|
||||||
|
#define SC_IS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFNET))
|
||||||
|
#define SC_IS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFNET))
|
||||||
|
#define SC_PLUGIN_IFNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetClass))
|
||||||
|
|
||||||
|
typedef struct _SCPluginIfnet SCPluginIfnet;
|
||||||
|
typedef struct _SCPluginIfnetClass SCPluginIfnetClass;
|
||||||
|
|
||||||
|
struct _SCPluginIfnet {
|
||||||
|
GObject parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _SCPluginIfnetClass {
|
||||||
|
GObjectClass parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType sc_plugin_ifnet_get_type (void);
|
||||||
|
#endif
|
14
system-settings/plugins/ifnet/tests/Makefile.am
Normal file
14
system-settings/plugins/ifnet/tests/Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
INCLUDES=-I$(top_srcdir)/system-settings/plugins/ifnet\
|
||||||
|
-I$(top_srcdir)/libnm-glib \
|
||||||
|
-I$(top_srcdir)/libnm-util \
|
||||||
|
-I$(top_srcdir)/include \
|
||||||
|
-I$(top_srcdir)/src/system-settings
|
||||||
|
TESTS = check_ifnet
|
||||||
|
check_PROGRAMS = check_ifnet
|
||||||
|
check_ifnet_SOURCES = test_all.c
|
||||||
|
check_ifnet_LDFLAGS = -g
|
||||||
|
check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS) -g
|
||||||
|
check_ifnet_LDADD = $(top_srcdir)/libnm-util/libnm-util.la\
|
||||||
|
$(top_srcdir)/system-settings/plugins/ifnet/lib-ifnet-io.la\
|
||||||
|
$(CHECK_LIBS)\
|
||||||
|
$(GLIB_LIBS)
|
2
system-settings/plugins/ifnet/tests/hostname
Normal file
2
system-settings/plugins/ifnet/tests/hostname
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#Generated by NetworkManager
|
||||||
|
hostname="gentoo"
|
147
system-settings/plugins/ifnet/tests/net
Normal file
147
system-settings/plugins/ifnet/tests/net
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
# 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 :]!).
|
||||||
|
|
||||||
|
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_eth6=("192.168.4.{1..101}/24")
|
||||||
|
|
||||||
|
config_eth7=( "dhcp" )
|
||||||
|
auto_eth7="true"
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
{}
|
||||||
|
|
864
system-settings/plugins/ifnet/tests/net.all
Normal file
864
system-settings/plugins/ifnet/tests/net.all
Normal file
|
@ -0,0 +1,864 @@
|
||||||
|
##############################################################################
|
||||||
|
# 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 the 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 the 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
|
|
@ -0,0 +1,5 @@
|
||||||
|
[main]
|
||||||
|
plugins=ifnet,keyfile
|
||||||
|
|
||||||
|
[ifnet]
|
||||||
|
managed=false
|
379
system-settings/plugins/ifnet/tests/test_all.c
Normal file
379
system-settings/plugins/ifnet/tests/test_all.c
Normal file
|
@ -0,0 +1,379 @@
|
||||||
|
/* -*- 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <nm-utils.h>
|
||||||
|
|
||||||
|
#include "net_parser.h"
|
||||||
|
#include "nm-test-helpers.h"
|
||||||
|
#include "net_utils.h"
|
||||||
|
#include "wpa_parser.h"
|
||||||
|
#include "connection_parser.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_getdata ()
|
||||||
|
{
|
||||||
|
ASSERT (ifnet_get_data ("eth1", "config")
|
||||||
|
&& strcmp (ifnet_get_data ("eth1", "config"), "dhcp") == 0,
|
||||||
|
"get data", "config_eth1 is not correct");
|
||||||
|
ASSERT (ifnet_get_data ("ppp0", "username")
|
||||||
|
&& strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0,
|
||||||
|
"get data", "config_ppp0 username is not correctly read");
|
||||||
|
ASSERT (ifnet_get_data ("ppp0", "password")
|
||||||
|
&& strcmp (ifnet_get_data ("ppp0", "password"),
|
||||||
|
"password") == 0, "get data",
|
||||||
|
"config_ppp0 password is not correctly read");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_read_hostname ()
|
||||||
|
{
|
||||||
|
gchar *hostname = read_hostname ("hostname");
|
||||||
|
|
||||||
|
ASSERT (hostname != NULL, "get hostname", "hostname is NULL");
|
||||||
|
ASSERT (strcmp ("gentoo", hostname) == 0,
|
||||||
|
"get hostname",
|
||||||
|
"hostname is not correctly read, read:%s, expected: gentoo",
|
||||||
|
hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_write_hostname ()
|
||||||
|
{
|
||||||
|
gchar *hostname = read_hostname ("hostname");
|
||||||
|
|
||||||
|
write_hostname ("gentoo-nm", "hostname");
|
||||||
|
ASSERT (strcmp (read_hostname ("hostname"), "gentoo-nm") == 0,
|
||||||
|
"write hostname", "write hostname error");
|
||||||
|
write_hostname (hostname, "hostname");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_is_static ()
|
||||||
|
{
|
||||||
|
ASSERT (is_static_ip4 ("eth1") == FALSE, "is static",
|
||||||
|
"a dhcp interface is recognized as static");
|
||||||
|
ASSERT (is_static_ip4 ("eth0") == TRUE, "is static",
|
||||||
|
"a static interface is recognized as dhcp");
|
||||||
|
ASSERT (!is_static_ip6 ("eth0") == TRUE, "is static",
|
||||||
|
"a static interface is recognized as dhcp");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_has_default_route ()
|
||||||
|
{
|
||||||
|
ASSERT (has_default_ip4_route ("eth0"), "has default route",
|
||||||
|
"eth0 should have a default ipv4 route");
|
||||||
|
ASSERT (has_default_ip6_route ("eth4"), "has default route",
|
||||||
|
"eth4 should have a default ipv6 route");
|
||||||
|
|
||||||
|
ASSERT (!has_default_ip4_route ("eth5")
|
||||||
|
&& !has_default_ip6_route ("eth5"), "has default route",
|
||||||
|
"eth5 shouldn't have a default route");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_has_ip6_address ()
|
||||||
|
{
|
||||||
|
ASSERT (has_ip6_address ("eth2"), "has ip6 address",
|
||||||
|
"eth2 should have a ipv6 address");
|
||||||
|
ASSERT (!has_ip6_address ("eth0"), "has ip6 address",
|
||||||
|
"eth0 shouldn't have a ipv6 address")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_is_ip4_address ()
|
||||||
|
{
|
||||||
|
gchar *address1 = "192.168.4.232/24";
|
||||||
|
gchar *address2 = "192.168.100.{1..254}/24";
|
||||||
|
gchar *address3 = "192.168.4.2555/24";
|
||||||
|
|
||||||
|
ASSERT (is_ip4_address (address1), "is ip4 address",
|
||||||
|
"%s should be a valid address", address1);
|
||||||
|
ASSERT (is_ip4_address (address2), "is ip4 address",
|
||||||
|
"%s should be a valid address", address2);
|
||||||
|
ASSERT (!is_ip4_address (address3), "is ip4 address",
|
||||||
|
"%s should be an invalid address", address3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_is_ip6_address ()
|
||||||
|
{
|
||||||
|
gchar *address1 = "4321:0:1:2:3:4:567:89ac/24";
|
||||||
|
|
||||||
|
ASSERT (is_ip6_address (address1), "is ip6 address",
|
||||||
|
"%s should be a valid address", address1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_ip_block (ip_block * iblock, gchar * ip, gchar * netmask, gchar * gateway)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
struct in_addr tmp_ip4_addr;
|
||||||
|
|
||||||
|
str = malloc (INET_ADDRSTRLEN);
|
||||||
|
tmp_ip4_addr.s_addr = iblock->ip;
|
||||||
|
inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN);
|
||||||
|
ASSERT (strcmp (ip, str) == 0, "check ip", "ip expected:%s, find:%s",
|
||||||
|
ip, str);
|
||||||
|
tmp_ip4_addr.s_addr = iblock->netmask;
|
||||||
|
inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN);
|
||||||
|
ASSERT (strcmp (netmask, str) == 0, "check netmask",
|
||||||
|
"netmask expected:%s, find:%s", netmask, str);
|
||||||
|
tmp_ip4_addr.s_addr = iblock->gateway;
|
||||||
|
inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN);
|
||||||
|
ASSERT (strcmp (gateway, str) == 0, "check gateway",
|
||||||
|
"gateway expected:%s, find:%s", gateway, str);
|
||||||
|
free (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_convert_ipv4_config_block ()
|
||||||
|
{
|
||||||
|
ip_block *iblock = convert_ip4_config_block ("eth0");
|
||||||
|
ip_block *tmp = iblock;
|
||||||
|
|
||||||
|
ASSERT (iblock != NULL, "convert ipv4 block",
|
||||||
|
"block eth0 should not be NULL");
|
||||||
|
check_ip_block (iblock, "202.117.16.121", "255.255.255.0",
|
||||||
|
"202.117.16.1");
|
||||||
|
iblock = iblock->next;
|
||||||
|
destroy_ip_block (tmp);
|
||||||
|
ASSERT (iblock != NULL, "convert ipv4 block",
|
||||||
|
"block eth0 should have a second IP address");
|
||||||
|
check_ip_block (iblock, "192.168.4.121", "255.255.255.0",
|
||||||
|
"202.117.16.1");
|
||||||
|
destroy_ip_block (iblock);
|
||||||
|
iblock = convert_ip4_config_block ("eth2");
|
||||||
|
ASSERT (iblock != NULL
|
||||||
|
&& iblock->next == NULL, "convert error IPv4 address",
|
||||||
|
"should only get one address");
|
||||||
|
check_ip_block (iblock, "192.168.4.121", "255.255.255.0", "0.0.0.0");
|
||||||
|
destroy_ip_block (iblock);
|
||||||
|
iblock = convert_ip4_config_block ("eth3");
|
||||||
|
ASSERT (iblock == NULL, "convert config_block",
|
||||||
|
"convert error configuration");
|
||||||
|
destroy_ip_block (iblock);
|
||||||
|
iblock = convert_ip4_config_block ("eth6");
|
||||||
|
ASSERT (iblock != NULL, "convert config_block",
|
||||||
|
"convert error configuration");
|
||||||
|
destroy_ip_block (iblock);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_convert_ipv4_routes_block ()
|
||||||
|
{
|
||||||
|
ip_block *iblock = convert_ip4_routes_block ("eth0");
|
||||||
|
ip_block *tmp = iblock;
|
||||||
|
|
||||||
|
ASSERT (iblock != NULL, "convert ip4 routes", "should get one route");
|
||||||
|
check_ip_block (iblock, "192.168.4.0", "255.255.255.0", "192.168.4.1");
|
||||||
|
iblock = iblock->next;
|
||||||
|
destroy_ip_block (tmp);
|
||||||
|
ASSERT (iblock == NULL, "convert ip4 routes",
|
||||||
|
"should only get one route");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_wpa_parser ()
|
||||||
|
{
|
||||||
|
gchar *value;
|
||||||
|
|
||||||
|
ASSERT (exist_ssid ("example"), "get wsec",
|
||||||
|
"ssid myxjtu2 is not found");
|
||||||
|
ASSERT (exist_ssid ("static-wep-test"), "exist_ssid",
|
||||||
|
"ssid static-wep-test is not found");
|
||||||
|
value = wpa_get_value ("static-wep-test", "key_mgmt");
|
||||||
|
ASSERT (value && strcmp (value, "NONE") == 0, "get wpa data",
|
||||||
|
"key_mgmt of static-wep-test should be NONE, find %s", value);
|
||||||
|
value = wpa_get_value ("static-wep-test", "wep_key0");
|
||||||
|
ASSERT (value && strcmp (value, "\"abcde\"") == 0, "get wpa data",
|
||||||
|
"wep_key0 of static-wep-test should be abcde, find %s", value);
|
||||||
|
ASSERT (exist_ssid ("leap-example"), "get wsec",
|
||||||
|
"ssid leap-example is not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_strip_string ()
|
||||||
|
{
|
||||||
|
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, '"');
|
||||||
|
ASSERT (strcmp (result, "default via 202.117.16.1") == 0,
|
||||||
|
"strip_string", "string isn't stripped, result is: %s", result);
|
||||||
|
g_free (result_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_is_unmanaged ()
|
||||||
|
{
|
||||||
|
ASSERT (is_managed ("eth0"), "test_is_unmanaged",
|
||||||
|
"eth0 should be managed");
|
||||||
|
ASSERT (!is_managed ("eth4"), "test_is_unmanaged",
|
||||||
|
"eth4 should be unmanaged");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_new_connection ()
|
||||||
|
{
|
||||||
|
GError **error = NULL;
|
||||||
|
NMConnection *connection;
|
||||||
|
|
||||||
|
connection = ifnet_update_connection_from_config_block ("eth2", error);
|
||||||
|
ASSERT (connection != NULL, "new connection",
|
||||||
|
"new connection failed: %s",
|
||||||
|
error == NULL ? "None" : (*error)->message);
|
||||||
|
g_object_unref (connection);
|
||||||
|
connection =
|
||||||
|
ifnet_update_connection_from_config_block ("qiaomuf", error);
|
||||||
|
ASSERT (connection != NULL, "new connection",
|
||||||
|
"new connection failed: %s", error
|
||||||
|
&& (*error) ? (*error)->message : "NONE");
|
||||||
|
g_object_unref (connection);
|
||||||
|
connection =
|
||||||
|
ifnet_update_connection_from_config_block ("myxjtu2", error);
|
||||||
|
ASSERT (connection != NULL, "new connection",
|
||||||
|
"new connection failed: %s", error
|
||||||
|
&& (*error) ? (*error)->message : "NONE");
|
||||||
|
g_object_unref (connection);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_update_connection ()
|
||||||
|
{
|
||||||
|
GError **error = NULL;
|
||||||
|
NMConnection *connection;
|
||||||
|
|
||||||
|
connection = ifnet_update_connection_from_config_block ("eth0", error);
|
||||||
|
ASSERT (connection != NULL, "get connection",
|
||||||
|
"get connection failed: %s",
|
||||||
|
error == NULL ? "None" : (*error)->message);
|
||||||
|
ASSERT (ifnet_update_parsers_by_connection
|
||||||
|
(connection, "eth0", NULL, "net.generate",
|
||||||
|
"wpa_supplicant.conf.generate", error), "update connection",
|
||||||
|
"update connection failed %s", "eth0");
|
||||||
|
connection =
|
||||||
|
ifnet_update_connection_from_config_block ("0xab3ace", error);
|
||||||
|
ASSERT (connection != NULL, "get connection",
|
||||||
|
"get connection failed: %s",
|
||||||
|
error == NULL ? "None" : (*error)->message);
|
||||||
|
ASSERT (ifnet_update_parsers_by_connection
|
||||||
|
(connection, "0xab3ace", NULL, "net.generate",
|
||||||
|
"wpa_supplicant.conf.generate", error), "update connection",
|
||||||
|
"update connection failed %s", "0xab3ace");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_add_connection ()
|
||||||
|
{
|
||||||
|
GError **error = NULL;
|
||||||
|
NMConnection *connection;
|
||||||
|
|
||||||
|
connection = ifnet_update_connection_from_config_block ("eth0", error);
|
||||||
|
ASSERT (ifnet_add_new_connection
|
||||||
|
(connection, "net.generate", "wpa_supplicant.conf.generate",
|
||||||
|
error), "add connection", "add connection failed: %s", "eth0");
|
||||||
|
connection =
|
||||||
|
ifnet_update_connection_from_config_block ("myxjtu2", error);
|
||||||
|
ASSERT (ifnet_add_new_connection
|
||||||
|
(connection, "net.generate", "wpa_supplicant.conf.generate",
|
||||||
|
error), "add connection", "add connection failed: %s",
|
||||||
|
"myxjtu2");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_delete_connection ()
|
||||||
|
{
|
||||||
|
GError **error = NULL;
|
||||||
|
NMConnection *connection;
|
||||||
|
|
||||||
|
connection = ifnet_update_connection_from_config_block ("eth7", error);
|
||||||
|
ASSERT (connection != NULL, "get connection",
|
||||||
|
"get connection failed: %s",
|
||||||
|
error == NULL ? "None" : (*error)->message);
|
||||||
|
ASSERT (ifnet_delete_connection_in_parsers
|
||||||
|
("eth7", "net.generate", "wpa_supplicant.conf.generate"),
|
||||||
|
"delete connection", "delete connection failed: %s", "eth7");
|
||||||
|
connection =
|
||||||
|
ifnet_update_connection_from_config_block ("qiaomuf", error);
|
||||||
|
ASSERT (connection != NULL, "get connection",
|
||||||
|
"get connection failed: %s",
|
||||||
|
error == NULL ? "None" : (*error)->message);
|
||||||
|
ASSERT (ifnet_delete_connection_in_parsers
|
||||||
|
("qiaomuf", "net.generate", "wpa_supplicant.conf.generate"),
|
||||||
|
"delete connection", "delete connection failed: %s", "qiaomuf");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_all (gboolean run)
|
||||||
|
{
|
||||||
|
if (run) {
|
||||||
|
test_strip_string ();
|
||||||
|
test_is_static ();
|
||||||
|
test_has_ip6_address ();
|
||||||
|
test_has_default_route ();
|
||||||
|
test_getdata ();
|
||||||
|
test_read_hostname ();
|
||||||
|
test_write_hostname ();
|
||||||
|
test_is_ip4_address ();
|
||||||
|
test_is_ip6_address ();
|
||||||
|
test_convert_ipv4_config_block ();
|
||||||
|
test_convert_ipv4_routes_block ();
|
||||||
|
test_is_unmanaged ();
|
||||||
|
test_wpa_parser ();
|
||||||
|
test_convert_ipv4_routes_block ();
|
||||||
|
test_new_connection ();
|
||||||
|
test_update_connection ();
|
||||||
|
test_add_connection ();
|
||||||
|
test_delete_connection ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
// g_mem_set_vtable(glib_mem_profiler_table);
|
||||||
|
// g_atexit(g_mem_profile);
|
||||||
|
g_type_init ();
|
||||||
|
ifnet_destroy ();
|
||||||
|
wpa_parser_destroy ();
|
||||||
|
ifnet_init ("net");
|
||||||
|
wpa_parser_init ("wpa_supplicant.conf");
|
||||||
|
printf("Initialization complete\n");
|
||||||
|
|
||||||
|
run_all (TRUE);
|
||||||
|
|
||||||
|
ifnet_destroy ();
|
||||||
|
wpa_parser_destroy ();
|
||||||
|
return 0;
|
||||||
|
}
|
876
system-settings/plugins/ifnet/tests/wpa_supplicant.conf
Normal file
876
system-settings/plugins/ifnet/tests/wpa_supplicant.conf
Normal file
|
@ -0,0 +1,876 @@
|
||||||
|
##### Example wpa_supplicant configuration file ###############################
|
||||||
|
#
|
||||||
|
# This file describes configuration file format and lists all available option.
|
||||||
|
# Please also take a look at simpler configuration examples in 'examples'
|
||||||
|
# subdirectory.
|
||||||
|
#
|
||||||
|
# Empty lines and lines starting with # are ignored
|
||||||
|
|
||||||
|
# NOTE! This file may contain password information and should probably be made
|
||||||
|
# readable only by root user on multiuser systems.
|
||||||
|
|
||||||
|
# Note: All file paths in this configuration file should use full (absolute,
|
||||||
|
# not relative to working directory) path in order to allow working directory
|
||||||
|
# to be changed. This can happen if wpa_supplicant is run in the background.
|
||||||
|
|
||||||
|
# Whether to allow wpa_supplicant to update (overwrite) configuration
|
||||||
|
#
|
||||||
|
# This option can be used to allow wpa_supplicant to overwrite configuration
|
||||||
|
# file whenever configuration is changed (e.g., new network block is added with
|
||||||
|
# wpa_cli or wpa_gui, or a password is changed). This is required for
|
||||||
|
# wpa_cli/wpa_gui to be able to store the configuration changes permanently.
|
||||||
|
# Please note that overwriting configuration file will remove the comments from
|
||||||
|
# it.
|
||||||
|
#update_config=1
|
||||||
|
|
||||||
|
# global configuration (shared by all network blocks)
|
||||||
|
#
|
||||||
|
# Parameters for the control interface. If this is specified, wpa_supplicant
|
||||||
|
# will open a control interface that is available for external programs to
|
||||||
|
# manage wpa_supplicant. The meaning of this string depends on which control
|
||||||
|
# interface mechanism is used. For all cases, the existance of this parameter
|
||||||
|
# in configuration is used to determine whether the control interface is
|
||||||
|
# enabled.
|
||||||
|
#
|
||||||
|
# For UNIX domain sockets (default on Linux and BSD): This is a directory that
|
||||||
|
# will be created for UNIX domain sockets for listening to requests from
|
||||||
|
# external programs (CLI/GUI, etc.) for status information and configuration.
|
||||||
|
# The socket file will be named based on the interface name, so multiple
|
||||||
|
# wpa_supplicant processes can be run at the same time if more than one
|
||||||
|
# interface is used.
|
||||||
|
# /var/run/wpa_supplicant is the recommended directory for sockets and by
|
||||||
|
# default, wpa_cli will use it when trying to connect with wpa_supplicant.
|
||||||
|
#
|
||||||
|
# Access control for the control interface can be configured by setting the
|
||||||
|
# directory to allow only members of a group to use sockets. This way, it is
|
||||||
|
# possible to run wpa_supplicant as root (since it needs to change network
|
||||||
|
# configuration and open raw sockets) and still allow GUI/CLI components to be
|
||||||
|
# run as non-root users. However, since the control interface can be used to
|
||||||
|
# change the network configuration, this access needs to be protected in many
|
||||||
|
# cases. By default, wpa_supplicant is configured to use gid 0 (root). If you
|
||||||
|
# want to allow non-root users to use the control interface, add a new group
|
||||||
|
# and change this value to match with that group. Add users that should have
|
||||||
|
# control interface access to this group. If this variable is commented out or
|
||||||
|
# not included in the configuration file, group will not be changed from the
|
||||||
|
# value it got by default when the directory or socket was created.
|
||||||
|
#
|
||||||
|
# When configuring both the directory and group, use following format:
|
||||||
|
# DIR=/var/run/wpa_supplicant GROUP=wheel
|
||||||
|
# DIR=/var/run/wpa_supplicant GROUP=0
|
||||||
|
# (group can be either group name or gid)
|
||||||
|
#
|
||||||
|
# For UDP connections (default on Windows): The value will be ignored. This
|
||||||
|
# variable is just used to select that the control interface is to be created.
|
||||||
|
# The value can be set to, e.g., udp (ctrl_interface=udp)
|
||||||
|
#
|
||||||
|
# For Windows Named Pipe: This value can be used to set the security descriptor
|
||||||
|
# for controlling access to the control interface. Security descriptor can be
|
||||||
|
# set using Security Descriptor String Format (see http://msdn.microsoft.com/
|
||||||
|
# library/default.asp?url=/library/en-us/secauthz/security/
|
||||||
|
# security_descriptor_string_format.asp). The descriptor string needs to be
|
||||||
|
# prefixed with SDDL=. For example, ctrl_interface=SDDL=D: would set an empty
|
||||||
|
# DACL (which will reject all connections). See README-Windows.txt for more
|
||||||
|
# information about SDDL string format.
|
||||||
|
#
|
||||||
|
ctrl_interface=/var/run/wpa_supplicant
|
||||||
|
|
||||||
|
# IEEE 802.1X/EAPOL version
|
||||||
|
# wpa_supplicant is implemented based on IEEE Std 802.1X-2004 which defines
|
||||||
|
# EAPOL version 2. However, there are many APs that do not handle the new
|
||||||
|
# version number correctly (they seem to drop the frames completely). In order
|
||||||
|
# to make wpa_supplicant interoperate with these APs, the version number is set
|
||||||
|
# to 1 by default. This configuration value can be used to set it to the new
|
||||||
|
# version (2).
|
||||||
|
eapol_version=1
|
||||||
|
|
||||||
|
# AP scanning/selection
|
||||||
|
# By default, wpa_supplicant requests driver to perform AP scanning and then
|
||||||
|
# uses the scan results to select a suitable AP. Another alternative is to
|
||||||
|
# allow the driver to take care of AP scanning and selection and use
|
||||||
|
# wpa_supplicant just to process EAPOL frames based on IEEE 802.11 association
|
||||||
|
# information from the driver.
|
||||||
|
# 1: wpa_supplicant initiates scanning and AP selection
|
||||||
|
# 0: driver takes care of scanning, AP selection, and IEEE 802.11 association
|
||||||
|
# parameters (e.g., WPA IE generation); this mode can also be used with
|
||||||
|
# non-WPA drivers when using IEEE 802.1X mode; do not try to associate with
|
||||||
|
# APs (i.e., external program needs to control association). This mode must
|
||||||
|
# also be used when using wired Ethernet drivers.
|
||||||
|
# 2: like 0, but associate with APs using security policy and SSID (but not
|
||||||
|
# BSSID); this can be used, e.g., with ndiswrapper and NDIS drivers to
|
||||||
|
# enable operation with hidden SSIDs and optimized roaming; in this mode,
|
||||||
|
# the network blocks in the configuration file are tried one by one until
|
||||||
|
# the driver reports successful association; each network block should have
|
||||||
|
# explicit security policy (i.e., only one option in the lists) for
|
||||||
|
# key_mgmt, pairwise, group, proto variables
|
||||||
|
ap_scan=1
|
||||||
|
|
||||||
|
# EAP fast re-authentication
|
||||||
|
# By default, fast re-authentication is enabled for all EAP methods that
|
||||||
|
# support it. This variable can be used to disable fast re-authentication.
|
||||||
|
# Normally, there is no need to disable this.
|
||||||
|
fast_reauth=1
|
||||||
|
|
||||||
|
# OpenSSL Engine support
|
||||||
|
# These options can be used to load OpenSSL engines.
|
||||||
|
# The two engines that are supported currently are shown below:
|
||||||
|
# They are both from the opensc project (http://www.opensc.org/)
|
||||||
|
# By default no engines are loaded.
|
||||||
|
# make the opensc engine available
|
||||||
|
#opensc_engine_path=/usr/lib64/engine_opensc.so
|
||||||
|
# make the pkcs11 engine available
|
||||||
|
#pkcs11_engine_path=/usr/lib64/engine_pkcs11.so
|
||||||
|
# configure the path to the pkcs11 module required by the pkcs11 engine
|
||||||
|
#pkcs11_module_path=/usr/lib64/opensc-pkcs11.so
|
||||||
|
|
||||||
|
# Dynamic EAP methods
|
||||||
|
# If EAP methods were built dynamically as shared object files, they need to be
|
||||||
|
# loaded here before being used in the network blocks. By default, EAP methods
|
||||||
|
# are included statically in the build, so these lines are not needed
|
||||||
|
#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_tls.so
|
||||||
|
#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_md5.so
|
||||||
|
|
||||||
|
# Driver interface parameters
|
||||||
|
# This field can be used to configure arbitrary driver interace parameters. The
|
||||||
|
# format is specific to the selected driver interface. This field is not used
|
||||||
|
# in most cases.
|
||||||
|
#driver_param="field=value"
|
||||||
|
|
||||||
|
# Country code
|
||||||
|
# The ISO/IEC alpha2 country code for the country in which this device is
|
||||||
|
# currently operating.
|
||||||
|
#country=US
|
||||||
|
|
||||||
|
# Maximum lifetime for PMKSA in seconds; default 43200
|
||||||
|
#dot11RSNAConfigPMKLifetime=43200
|
||||||
|
# Threshold for reauthentication (percentage of PMK lifetime); default 70
|
||||||
|
#dot11RSNAConfigPMKReauthThreshold=70
|
||||||
|
# Timeout for security association negotiation in seconds; default 60
|
||||||
|
#dot11RSNAConfigSATimeout=60
|
||||||
|
|
||||||
|
# Wi-Fi Protected Setup (WPS) parameters
|
||||||
|
|
||||||
|
# Universally Unique IDentifier (UUID; see RFC 4122) of the device
|
||||||
|
# If not configured, UUID will be generated based on the local MAC address.
|
||||||
|
#uuid=12345678-9abc-def0-1234-56789abcdef0
|
||||||
|
|
||||||
|
# Device Name
|
||||||
|
# User-friendly description of device; up to 32 octets encoded in UTF-8
|
||||||
|
#device_name=Wireless Client
|
||||||
|
|
||||||
|
# Manufacturer
|
||||||
|
# The manufacturer of the device (up to 64 ASCII characters)
|
||||||
|
#manufacturer=Company
|
||||||
|
|
||||||
|
# Model Name
|
||||||
|
# Model of the device (up to 32 ASCII characters)
|
||||||
|
#model_name=cmodel
|
||||||
|
|
||||||
|
# Model Number
|
||||||
|
# Additional device description (up to 32 ASCII characters)
|
||||||
|
#model_number=123
|
||||||
|
|
||||||
|
# Serial Number
|
||||||
|
# Serial number of the device (up to 32 characters)
|
||||||
|
#serial_number=12345
|
||||||
|
|
||||||
|
# Primary Device Type
|
||||||
|
# Used format: <categ>-<OUI>-<subcateg>
|
||||||
|
# categ = Category as an integer value
|
||||||
|
# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
|
||||||
|
# default WPS OUI
|
||||||
|
# subcateg = OUI-specific Sub Category as an integer value
|
||||||
|
# Examples:
|
||||||
|
# 1-0050F204-1 (Computer / PC)
|
||||||
|
# 1-0050F204-2 (Computer / Server)
|
||||||
|
# 5-0050F204-1 (Storage / NAS)
|
||||||
|
# 6-0050F204-1 (Network Infrastructure / AP)
|
||||||
|
#device_type=1-0050F204-1
|
||||||
|
|
||||||
|
# OS Version
|
||||||
|
# 4-octet operating system version number (hex string)
|
||||||
|
#os_version=01020300
|
||||||
|
|
||||||
|
# Credential processing
|
||||||
|
# 0 = process received credentials internally (default)
|
||||||
|
# 1 = do not process received credentials; just pass them over ctrl_iface to
|
||||||
|
# external program(s)
|
||||||
|
# 2 = process received credentials internally and pass them over ctrl_iface
|
||||||
|
# to external program(s)
|
||||||
|
#wps_cred_processing=0
|
||||||
|
|
||||||
|
# network block
|
||||||
|
#
|
||||||
|
# Each network (usually AP's sharing the same SSID) is configured as a separate
|
||||||
|
# block in this configuration file. The network blocks are in preference order
|
||||||
|
# (the first match is used).
|
||||||
|
#
|
||||||
|
# network block fields:
|
||||||
|
#
|
||||||
|
# disabled:
|
||||||
|
# 0 = this network can be used (default)
|
||||||
|
# 1 = this network block is disabled (can be enabled through ctrl_iface,
|
||||||
|
# e.g., with wpa_cli or wpa_gui)
|
||||||
|
#
|
||||||
|
# id_str: Network identifier string for external scripts. This value is passed
|
||||||
|
# to external action script through wpa_cli as WPA_ID_STR environment
|
||||||
|
# variable to make it easier to do network specific configuration.
|
||||||
|
#
|
||||||
|
# ssid: SSID (mandatory); either as an ASCII string with double quotation or
|
||||||
|
# as hex string; network name
|
||||||
|
#
|
||||||
|
# scan_ssid:
|
||||||
|
# 0 = do not scan this SSID with specific Probe Request frames (default)
|
||||||
|
# 1 = scan with SSID-specific Probe Request frames (this can be used to
|
||||||
|
# find APs that do not accept broadcast SSID or use multiple SSIDs;
|
||||||
|
# this will add latency to scanning, so enable this only when needed)
|
||||||
|
#
|
||||||
|
# bssid: BSSID (optional); if set, this network block is used only when
|
||||||
|
# associating with the AP using the configured BSSID
|
||||||
|
#
|
||||||
|
# priority: priority group (integer)
|
||||||
|
# By default, all networks will get same priority group (0). If some of the
|
||||||
|
# networks are more desirable, this field can be used to change the order in
|
||||||
|
# which wpa_supplicant goes through the networks when selecting a BSS. The
|
||||||
|
# priority groups will be iterated in decreasing priority (i.e., the larger the
|
||||||
|
# priority value, the sooner the network is matched against the scan results).
|
||||||
|
# Within each priority group, networks will be selected based on security
|
||||||
|
# policy, signal strength, etc.
|
||||||
|
# Please note that AP scanning with scan_ssid=1 and ap_scan=2 mode are not
|
||||||
|
# using this priority to select the order for scanning. Instead, they try the
|
||||||
|
# networks in the order that used in the configuration file.
|
||||||
|
#
|
||||||
|
# mode: IEEE 802.11 operation mode
|
||||||
|
# 0 = infrastructure (Managed) mode, i.e., associate with an AP (default)
|
||||||
|
# 1 = IBSS (ad-hoc, peer-to-peer)
|
||||||
|
# Note: IBSS can only be used with key_mgmt NONE (plaintext and static WEP)
|
||||||
|
# and key_mgmt=WPA-NONE (fixed group key TKIP/CCMP). In addition, ap_scan has
|
||||||
|
# to be set to 2 for IBSS. WPA-None requires following network block options:
|
||||||
|
# proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or CCMP, but not
|
||||||
|
# both), and psk must also be set.
|
||||||
|
#
|
||||||
|
# frequency: Channel frequency in megahertz (MHz) for IBSS, e.g.,
|
||||||
|
# 2412 = IEEE 802.11b/g channel 1. This value is used to configure the initial
|
||||||
|
# channel for IBSS (adhoc) networks. It is ignored in the infrastructure mode.
|
||||||
|
# In addition, this value is only used by the station that creates the IBSS. If
|
||||||
|
# an IBSS network with the configured SSID is already present, the frequency of
|
||||||
|
# the network will be used instead of this configured value.
|
||||||
|
#
|
||||||
|
# proto: list of accepted protocols
|
||||||
|
# WPA = WPA/IEEE 802.11i/D3.0
|
||||||
|
# RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)
|
||||||
|
# If not set, this defaults to: WPA RSN
|
||||||
|
#
|
||||||
|
# key_mgmt: list of accepted authenticated key management protocols
|
||||||
|
# WPA-PSK = WPA pre-shared key (this requires 'psk' field)
|
||||||
|
# WPA-EAP = WPA using EAP authentication
|
||||||
|
# IEEE8021X = IEEE 802.1X using EAP authentication and (optionally) dynamically
|
||||||
|
# generated WEP keys
|
||||||
|
# NONE = WPA is not used; plaintext or static WEP could be used
|
||||||
|
# WPA-PSK-SHA256 = Like WPA-PSK but using stronger SHA256-based algorithms
|
||||||
|
# WPA-EAP-SHA256 = Like WPA-EAP but using stronger SHA256-based algorithms
|
||||||
|
# If not set, this defaults to: WPA-PSK WPA-EAP
|
||||||
|
#
|
||||||
|
# auth_alg: list of allowed IEEE 802.11 authentication algorithms
|
||||||
|
# OPEN = Open System authentication (required for WPA/WPA2)
|
||||||
|
# SHARED = Shared Key authentication (requires static WEP keys)
|
||||||
|
# LEAP = LEAP/Network EAP (only used with LEAP)
|
||||||
|
# If not set, automatic selection is used (Open System with LEAP enabled if
|
||||||
|
# LEAP is allowed as one of the EAP methods).
|
||||||
|
#
|
||||||
|
# pairwise: list of accepted pairwise (unicast) ciphers for WPA
|
||||||
|
# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
|
||||||
|
# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
|
||||||
|
# NONE = Use only Group Keys (deprecated, should not be included if APs support
|
||||||
|
# pairwise keys)
|
||||||
|
# If not set, this defaults to: CCMP TKIP
|
||||||
|
#
|
||||||
|
# group: list of accepted group (broadcast/multicast) ciphers for WPA
|
||||||
|
# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
|
||||||
|
# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
|
||||||
|
# WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
|
||||||
|
# WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key [IEEE 802.11]
|
||||||
|
# If not set, this defaults to: CCMP TKIP WEP104 WEP40
|
||||||
|
#
|
||||||
|
# psk: WPA preshared key; 256-bit pre-shared key
|
||||||
|
# The key used in WPA-PSK mode can be entered either as 64 hex-digits, i.e.,
|
||||||
|
# 32 bytes or as an ASCII passphrase (in which case, the real PSK will be
|
||||||
|
# generated using the passphrase and SSID). ASCII passphrase must be between
|
||||||
|
# 8 and 63 characters (inclusive).
|
||||||
|
# This field is not needed, if WPA-EAP is used.
|
||||||
|
# Note: Separate tool, wpa_passphrase, can be used to generate 256-bit keys
|
||||||
|
# from ASCII passphrase. This process uses lot of CPU and wpa_supplicant
|
||||||
|
# startup and reconfiguration time can be optimized by generating the PSK only
|
||||||
|
# only when the passphrase or SSID has actually changed.
|
||||||
|
#
|
||||||
|
# eapol_flags: IEEE 802.1X/EAPOL options (bit field)
|
||||||
|
# Dynamic WEP key required for non-WPA mode
|
||||||
|
# bit0 (1): require dynamically generated unicast WEP key
|
||||||
|
# bit1 (2): require dynamically generated broadcast WEP key
|
||||||
|
# (3 = require both keys; default)
|
||||||
|
# Note: When using wired authentication, eapol_flags must be set to 0 for the
|
||||||
|
# authentication to be completed successfully.
|
||||||
|
#
|
||||||
|
# mixed_cell: This option can be used to configure whether so called mixed
|
||||||
|
# cells, i.e., networks that use both plaintext and encryption in the same
|
||||||
|
# SSID, are allowed when selecting a BSS form scan results.
|
||||||
|
# 0 = disabled (default)
|
||||||
|
# 1 = enabled
|
||||||
|
#
|
||||||
|
# proactive_key_caching:
|
||||||
|
# Enable/disable opportunistic PMKSA caching for WPA2.
|
||||||
|
# 0 = disabled (default)
|
||||||
|
# 1 = enabled
|
||||||
|
#
|
||||||
|
# wep_key0..3: Static WEP key (ASCII in double quotation, e.g. "abcde" or
|
||||||
|
# hex without quotation, e.g., 0102030405)
|
||||||
|
# wep_tx_keyidx: Default WEP key index (TX) (0..3)
|
||||||
|
#
|
||||||
|
# peerkey: Whether PeerKey negotiation for direct links (IEEE 802.11e DLS) is
|
||||||
|
# allowed. This is only used with RSN/WPA2.
|
||||||
|
# 0 = disabled (default)
|
||||||
|
# 1 = enabled
|
||||||
|
#peerkey=1
|
||||||
|
#
|
||||||
|
# wpa_ptk_rekey: Maximum lifetime for PTK in seconds. This can be used to
|
||||||
|
# enforce rekeying of PTK to mitigate some attacks against TKIP deficiencies.
|
||||||
|
#
|
||||||
|
# Following fields are only used with internal EAP implementation.
|
||||||
|
# eap: space-separated list of accepted EAP methods
|
||||||
|
# MD5 = EAP-MD5 (unsecure and does not generate keying material ->
|
||||||
|
# cannot be used with WPA; to be used as a Phase 2 method
|
||||||
|
# with EAP-PEAP or EAP-TTLS)
|
||||||
|
# MSCHAPV2 = EAP-MSCHAPv2 (cannot be used separately with WPA; to be used
|
||||||
|
# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
|
||||||
|
# OTP = EAP-OTP (cannot be used separately with WPA; to be used
|
||||||
|
# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
|
||||||
|
# GTC = EAP-GTC (cannot be used separately with WPA; to be used
|
||||||
|
# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
|
||||||
|
# TLS = EAP-TLS (client and server certificate)
|
||||||
|
# PEAP = EAP-PEAP (with tunnelled EAP authentication)
|
||||||
|
# TTLS = EAP-TTLS (with tunnelled EAP or PAP/CHAP/MSCHAP/MSCHAPV2
|
||||||
|
# authentication)
|
||||||
|
# If not set, all compiled in methods are allowed.
|
||||||
|
#
|
||||||
|
# identity: Identity string for EAP
|
||||||
|
# This field is also used to configure user NAI for
|
||||||
|
# EAP-PSK/PAX/SAKE/GPSK.
|
||||||
|
# anonymous_identity: Anonymous identity string for EAP (to be used as the
|
||||||
|
# unencrypted identity with EAP types that support different tunnelled
|
||||||
|
# identity, e.g., EAP-TTLS)
|
||||||
|
# password: Password string for EAP. This field can include either the
|
||||||
|
# plaintext password (using ASCII or hex string) or a NtPasswordHash
|
||||||
|
# (16-byte MD4 hash of password) in hash:<32 hex digits> format.
|
||||||
|
# NtPasswordHash can only be used when the password is for MSCHAPv2 or
|
||||||
|
# MSCHAP (EAP-MSCHAPv2, EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP).
|
||||||
|
# EAP-PSK (128-bit PSK), EAP-PAX (128-bit PSK), and EAP-SAKE (256-bit
|
||||||
|
# PSK) is also configured using this field. For EAP-GPSK, this is a
|
||||||
|
# variable length PSK.
|
||||||
|
# ca_cert: File path to CA certificate file (PEM/DER). This file can have one
|
||||||
|
# or more trusted CA certificates. If ca_cert and ca_path are not
|
||||||
|
# included, server certificate will not be verified. This is insecure and
|
||||||
|
# a trusted CA certificate should always be configured when using
|
||||||
|
# EAP-TLS/TTLS/PEAP. Full path should be used since working directory may
|
||||||
|
# change when wpa_supplicant is run in the background.
|
||||||
|
# On Windows, trusted CA certificates can be loaded from the system
|
||||||
|
# certificate store by setting this to cert_store://<name>, e.g.,
|
||||||
|
# ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT".
|
||||||
|
# Note that when running wpa_supplicant as an application, the user
|
||||||
|
# certificate store (My user account) is used, whereas computer store
|
||||||
|
# (Computer account) is used when running wpasvc as a service.
|
||||||
|
# ca_path: Directory path for CA certificate files (PEM). This path may
|
||||||
|
# contain multiple CA certificates in OpenSSL format. Common use for this
|
||||||
|
# is to point to system trusted CA list which is often installed into
|
||||||
|
# directory like /etc/ssl/certs. If configured, these certificates are
|
||||||
|
# added to the list of trusted CAs. ca_cert may also be included in that
|
||||||
|
# case, but it is not required.
|
||||||
|
# client_cert: File path to client certificate file (PEM/DER)
|
||||||
|
# Full path should be used since working directory may change when
|
||||||
|
# wpa_supplicant is run in the background.
|
||||||
|
# Alternatively, a named configuration blob can be used by setting this
|
||||||
|
# to blob://<blob name>.
|
||||||
|
# private_key: File path to client private key file (PEM/DER/PFX)
|
||||||
|
# When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be
|
||||||
|
# commented out. Both the private key and certificate will be read from
|
||||||
|
# the PKCS#12 file in this case. Full path should be used since working
|
||||||
|
# directory may change when wpa_supplicant is run in the background.
|
||||||
|
# Windows certificate store can be used by leaving client_cert out and
|
||||||
|
# configuring private_key in one of the following formats:
|
||||||
|
# cert://substring_to_match
|
||||||
|
# hash://certificate_thumbprint_in_hex
|
||||||
|
# for example: private_key="hash://63093aa9c47f56ae88334c7b65a4"
|
||||||
|
# Note that when running wpa_supplicant as an application, the user
|
||||||
|
# certificate store (My user account) is used, whereas computer store
|
||||||
|
# (Computer account) is used when running wpasvc as a service.
|
||||||
|
# Alternatively, a named configuration blob can be used by setting this
|
||||||
|
# to blob://<blob name>.
|
||||||
|
# private_key_passwd: Password for private key file (if left out, this will be
|
||||||
|
# asked through control interface)
|
||||||
|
# dh_file: File path to DH/DSA parameters file (in PEM format)
|
||||||
|
# This is an optional configuration file for setting parameters for an
|
||||||
|
# ephemeral DH key exchange. In most cases, the default RSA
|
||||||
|
# authentication does not use this configuration. However, it is possible
|
||||||
|
# setup RSA to use ephemeral DH key exchange. In addition, ciphers with
|
||||||
|
# DSA keys always use ephemeral DH keys. This can be used to achieve
|
||||||
|
# forward secrecy. If the file is in DSA parameters format, it will be
|
||||||
|
# automatically converted into DH params.
|
||||||
|
# subject_match: Substring to be matched against the subject of the
|
||||||
|
# authentication server certificate. If this string is set, the server
|
||||||
|
# sertificate is only accepted if it contains this string in the subject.
|
||||||
|
# The subject string is in following format:
|
||||||
|
# /C=US/ST=CA/L=San Francisco/CN=Test AS/emailAddress=as@example.com
|
||||||
|
# altsubject_match: Semicolon separated string of entries to be matched against
|
||||||
|
# the alternative subject name of the authentication server certificate.
|
||||||
|
# If this string is set, the server sertificate is only accepted if it
|
||||||
|
# contains one of the entries in an alternative subject name extension.
|
||||||
|
# altSubjectName string is in following format: TYPE:VALUE
|
||||||
|
# Example: EMAIL:server@example.com
|
||||||
|
# Example: DNS:server.example.com;DNS:server2.example.com
|
||||||
|
# Following types are supported: EMAIL, DNS, URI
|
||||||
|
# phase1: Phase1 (outer authentication, i.e., TLS tunnel) parameters
|
||||||
|
# (string with field-value pairs, e.g., "peapver=0" or
|
||||||
|
# "peapver=1 peaplabel=1")
|
||||||
|
# 'peapver' can be used to force which PEAP version (0 or 1) is used.
|
||||||
|
# 'peaplabel=1' can be used to force new label, "client PEAP encryption",
|
||||||
|
# to be used during key derivation when PEAPv1 or newer. Most existing
|
||||||
|
# PEAPv1 implementation seem to be using the old label, "client EAP
|
||||||
|
# encryption", and wpa_supplicant is now using that as the default value.
|
||||||
|
# Some servers, e.g., Radiator, may require peaplabel=1 configuration to
|
||||||
|
# interoperate with PEAPv1; see eap_testing.txt for more details.
|
||||||
|
# 'peap_outer_success=0' can be used to terminate PEAP authentication on
|
||||||
|
# tunneled EAP-Success. This is required with some RADIUS servers that
|
||||||
|
# implement draft-josefsson-pppext-eap-tls-eap-05.txt (e.g.,
|
||||||
|
# Lucent NavisRadius v4.4.0 with PEAP in "IETF Draft 5" mode)
|
||||||
|
# include_tls_length=1 can be used to force wpa_supplicant to include
|
||||||
|
# TLS Message Length field in all TLS messages even if they are not
|
||||||
|
# fragmented.
|
||||||
|
# sim_min_num_chal=3 can be used to configure EAP-SIM to require three
|
||||||
|
# challenges (by default, it accepts 2 or 3)
|
||||||
|
# result_ind=1 can be used to enable EAP-SIM and EAP-AKA to use
|
||||||
|
# protected result indication.
|
||||||
|
# 'crypto_binding' option can be used to control PEAPv0 cryptobinding
|
||||||
|
# behavior:
|
||||||
|
# * 0 = do not use cryptobinding (default)
|
||||||
|
# * 1 = use cryptobinding if server supports it
|
||||||
|
# * 2 = require cryptobinding
|
||||||
|
# EAP-WSC (WPS) uses following options: pin=<Device Password> or
|
||||||
|
# pbc=1.
|
||||||
|
# phase2: Phase2 (inner authentication with TLS tunnel) parameters
|
||||||
|
# (string with field-value pairs, e.g., "auth=MSCHAPV2" for EAP-PEAP or
|
||||||
|
# "autheap=MSCHAPV2 autheap=MD5" for EAP-TTLS)
|
||||||
|
# Following certificate/private key fields are used in inner Phase2
|
||||||
|
# authentication when using EAP-TTLS or EAP-PEAP.
|
||||||
|
# ca_cert2: File path to CA certificate file. This file can have one or more
|
||||||
|
# trusted CA certificates. If ca_cert2 and ca_path2 are not included,
|
||||||
|
# server certificate will not be verified. This is insecure and a trusted
|
||||||
|
# CA certificate should always be configured.
|
||||||
|
# ca_path2: Directory path for CA certificate files (PEM)
|
||||||
|
# client_cert2: File path to client certificate file
|
||||||
|
# private_key2: File path to client private key file
|
||||||
|
# private_key2_passwd: Password for private key file
|
||||||
|
# dh_file2: File path to DH/DSA parameters file (in PEM format)
|
||||||
|
# subject_match2: Substring to be matched against the subject of the
|
||||||
|
# authentication server certificate.
|
||||||
|
# altsubject_match2: Substring to be matched against the alternative subject
|
||||||
|
# name of the authentication server certificate.
|
||||||
|
#
|
||||||
|
# fragment_size: Maximum EAP fragment size in bytes (default 1398).
|
||||||
|
# This value limits the fragment size for EAP methods that support
|
||||||
|
# fragmentation (e.g., EAP-TLS and EAP-PEAP). This value should be set
|
||||||
|
# small enough to make the EAP messages fit in MTU of the network
|
||||||
|
# interface used for EAPOL. The default value is suitable for most
|
||||||
|
# cases.
|
||||||
|
#
|
||||||
|
# EAP-FAST variables:
|
||||||
|
# pac_file: File path for the PAC entries. wpa_supplicant will need to be able
|
||||||
|
# to create this file and write updates to it when PAC is being
|
||||||
|
# provisioned or refreshed. Full path to the file should be used since
|
||||||
|
# working directory may change when wpa_supplicant is run in the
|
||||||
|
# background. Alternatively, a named configuration blob can be used by
|
||||||
|
# setting this to blob://<blob name>
|
||||||
|
# phase1: fast_provisioning option can be used to enable in-line provisioning
|
||||||
|
# of EAP-FAST credentials (PAC):
|
||||||
|
# 0 = disabled,
|
||||||
|
# 1 = allow unauthenticated provisioning,
|
||||||
|
# 2 = allow authenticated provisioning,
|
||||||
|
# 3 = allow both unauthenticated and authenticated provisioning
|
||||||
|
# fast_max_pac_list_len=<num> option can be used to set the maximum
|
||||||
|
# number of PAC entries to store in a PAC list (default: 10)
|
||||||
|
# fast_pac_format=binary option can be used to select binary format for
|
||||||
|
# storing PAC entries in order to save some space (the default
|
||||||
|
# text format uses about 2.5 times the size of minimal binary
|
||||||
|
# format)
|
||||||
|
#
|
||||||
|
# wpa_supplicant supports number of "EAP workarounds" to work around
|
||||||
|
# interoperability issues with incorrectly behaving authentication servers.
|
||||||
|
# These are enabled by default because some of the issues are present in large
|
||||||
|
# number of authentication servers. Strict EAP conformance mode can be
|
||||||
|
# configured by disabling workarounds with eap_workaround=0.
|
||||||
|
|
||||||
|
# Example blocks:
|
||||||
|
|
||||||
|
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
|
||||||
|
network={
|
||||||
|
ssid="simple"
|
||||||
|
psk="very secret passphrase"
|
||||||
|
priority=5
|
||||||
|
}
|
||||||
|
|
||||||
|
# Same as previous, but request SSID-specific scanning (for APs that reject
|
||||||
|
# broadcast SSID)
|
||||||
|
network={
|
||||||
|
ssid="second ssid"
|
||||||
|
scan_ssid=1
|
||||||
|
psk="very secret passphrase"
|
||||||
|
priority=2
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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
|
||||||
|
}
|
||||||
|
|
||||||
|
# WPA-Personal(PSK) with TKIP and enforcement for frequent PTK rekeying
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
proto=WPA
|
||||||
|
key_mgmt=WPA-PSK
|
||||||
|
pairwise=TKIP
|
||||||
|
group=TKIP
|
||||||
|
psk="not so secure passphrase"
|
||||||
|
wpa_ptk_rekey=600
|
||||||
|
}
|
||||||
|
|
||||||
|
# Only WPA-EAP is used. Both CCMP and TKIP is accepted. An AP that used WEP104
|
||||||
|
# or WEP40 as the group cipher will not be accepted.
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
proto=RSN
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
pairwise=CCMP TKIP
|
||||||
|
group=CCMP TKIP
|
||||||
|
eap=TLS
|
||||||
|
identity="user@example.com"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
client_cert="/etc/cert/user.pem"
|
||||||
|
private_key="/etc/cert/user.prv"
|
||||||
|
private_key_passwd="password"
|
||||||
|
priority=1
|
||||||
|
}
|
||||||
|
|
||||||
|
# EAP-PEAP/MSCHAPv2 configuration for RADIUS servers that use the new peaplabel
|
||||||
|
# (e.g., Radiator)
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=PEAP
|
||||||
|
identity="user@example.com"
|
||||||
|
password="foobar"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
phase1="peaplabel=1"
|
||||||
|
phase2="auth=MSCHAPV2"
|
||||||
|
priority=10
|
||||||
|
}
|
||||||
|
|
||||||
|
# EAP-TTLS/EAP-MD5-Challenge configuration with anonymous identity for the
|
||||||
|
# unencrypted use. Real identity is sent only within an encrypted TLS tunnel.
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=TTLS
|
||||||
|
identity="user@example.com"
|
||||||
|
anonymous_identity="anonymous@example.com"
|
||||||
|
password="foobar"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
priority=2
|
||||||
|
}
|
||||||
|
|
||||||
|
# EAP-TTLS/MSCHAPv2 configuration with anonymous identity for the unencrypted
|
||||||
|
# use. Real identity is sent only within an encrypted TLS tunnel.
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=TTLS
|
||||||
|
identity="user@example.com"
|
||||||
|
anonymous_identity="anonymous@example.com"
|
||||||
|
password="foobar"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
phase2="auth=MSCHAPV2"
|
||||||
|
}
|
||||||
|
|
||||||
|
# WPA-EAP, EAP-TTLS with different CA certificate used for outer and inner
|
||||||
|
# authentication.
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=TTLS
|
||||||
|
# Phase1 / outer authentication
|
||||||
|
anonymous_identity="anonymous@example.com"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
# Phase 2 / inner authentication
|
||||||
|
phase2="autheap=TLS"
|
||||||
|
ca_cert2="/etc/cert/ca2.pem"
|
||||||
|
client_cert2="/etc/cer/user.pem"
|
||||||
|
private_key2="/etc/cer/user.prv"
|
||||||
|
private_key2_passwd="password"
|
||||||
|
priority=2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Both WPA-PSK and WPA-EAP is accepted. Only CCMP is accepted as pairwise and
|
||||||
|
# group cipher.
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
bssid=00:11:22:33:44:55
|
||||||
|
proto=WPA RSN
|
||||||
|
key_mgmt=WPA-PSK WPA-EAP
|
||||||
|
pairwise=CCMP
|
||||||
|
group=CCMP
|
||||||
|
psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
|
||||||
|
}
|
||||||
|
|
||||||
|
# Special characters in SSID, so use hex string. Default to WPA-PSK, WPA-EAP
|
||||||
|
# and all valid ciphers.
|
||||||
|
network={
|
||||||
|
ssid=00010203
|
||||||
|
psk=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# EAP-SIM with a GSM SIM or USIM
|
||||||
|
network={
|
||||||
|
ssid="eap-sim-test"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=SIM
|
||||||
|
pin="1234"
|
||||||
|
pcsc=""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# EAP-PSK
|
||||||
|
network={
|
||||||
|
ssid="eap-psk-test"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=PSK
|
||||||
|
anonymous_identity="eap_psk_user"
|
||||||
|
password=06b4be19da289f475aa46a33cb793029
|
||||||
|
identity="eap_psk_user@example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# IEEE 802.1X/EAPOL with dynamically generated WEP keys (i.e., no WPA) using
|
||||||
|
# EAP-TLS for authentication and key generation; require both unicast and
|
||||||
|
# broadcast WEP keys.
|
||||||
|
network={
|
||||||
|
ssid="1xtest"
|
||||||
|
key_mgmt=IEEE8021X
|
||||||
|
eap=TLS
|
||||||
|
identity="user@example.com"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
client_cert="/etc/cert/user.pem"
|
||||||
|
private_key="/etc/cert/user.prv"
|
||||||
|
private_key_passwd="password"
|
||||||
|
eapol_flags=3
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# LEAP with dynamic WEP keys
|
||||||
|
network={
|
||||||
|
ssid="leap-example"
|
||||||
|
key_mgmt=IEEE8021X
|
||||||
|
eap=LEAP
|
||||||
|
identity="user"
|
||||||
|
password="foobar"
|
||||||
|
}
|
||||||
|
|
||||||
|
# EAP-IKEv2 using shared secrets for both server and peer authentication
|
||||||
|
network={
|
||||||
|
ssid="ikev2-example"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=IKEV2
|
||||||
|
identity="user"
|
||||||
|
password="foobar"
|
||||||
|
}
|
||||||
|
|
||||||
|
# EAP-FAST with WPA (WPA or WPA2)
|
||||||
|
network={
|
||||||
|
ssid="eap-fast-test"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=FAST
|
||||||
|
anonymous_identity="FAST-000102030405"
|
||||||
|
identity="username"
|
||||||
|
password="password"
|
||||||
|
phase1="fast_provisioning=1"
|
||||||
|
pac_file="/etc/wpa_supplicant.eap-fast-pac"
|
||||||
|
}
|
||||||
|
|
||||||
|
network={
|
||||||
|
ssid="eap-fast-test"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=FAST
|
||||||
|
anonymous_identity="FAST-000102030405"
|
||||||
|
identity="username"
|
||||||
|
password="password"
|
||||||
|
phase1="fast_provisioning=1"
|
||||||
|
pac_file="blob://eap-fast-pac"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Plaintext connection (no WPA, no IEEE 802.1X)
|
||||||
|
network={
|
||||||
|
ssid="plaintext-test"
|
||||||
|
key_mgmt=NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Shared WEP key connection (no WPA, no IEEE 802.1X) using Shared Key
|
||||||
|
# IEEE 802.11 authentication
|
||||||
|
network={
|
||||||
|
ssid="static-wep-test2"
|
||||||
|
key_mgmt=NONE
|
||||||
|
wep_key0="abcde"
|
||||||
|
wep_key1=0102030405
|
||||||
|
wep_key2="1234567890123"
|
||||||
|
wep_tx_keyidx=0
|
||||||
|
priority=5
|
||||||
|
auth_alg=SHARED
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# IBSS/ad-hoc network with WPA-None/TKIP.
|
||||||
|
network={
|
||||||
|
ssid="test adhoc"
|
||||||
|
mode=1
|
||||||
|
frequency=2412
|
||||||
|
proto=WPA
|
||||||
|
key_mgmt=WPA-NONE
|
||||||
|
pairwise=NONE
|
||||||
|
group=TKIP
|
||||||
|
psk="secret passphrase"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Catch all example that allows more or less all configuration modes
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
scan_ssid=1
|
||||||
|
key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
|
||||||
|
pairwise=CCMP TKIP
|
||||||
|
group=CCMP TKIP WEP104 WEP40
|
||||||
|
psk="very secret passphrase"
|
||||||
|
eap=TTLS PEAP TLS
|
||||||
|
identity="user@example.com"
|
||||||
|
password="foobar"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
client_cert="/etc/cert/user.pem"
|
||||||
|
private_key="/etc/cert/user.prv"
|
||||||
|
private_key_passwd="password"
|
||||||
|
phase1="peaplabel=0"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Example of EAP-TLS with smartcard (openssl engine)
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=TLS
|
||||||
|
proto=RSN
|
||||||
|
pairwise=CCMP TKIP
|
||||||
|
group=CCMP TKIP
|
||||||
|
identity="user@example.com"
|
||||||
|
ca_cert="/etc/cert/ca.pem"
|
||||||
|
client_cert="/etc/cert/user.pem"
|
||||||
|
|
||||||
|
engine=1
|
||||||
|
|
||||||
|
# The engine configured here must be available. Look at
|
||||||
|
# OpenSSL engine support in the global section.
|
||||||
|
# The key available through the engine must be the private key
|
||||||
|
# matching the client certificate configured above.
|
||||||
|
|
||||||
|
# use the opensc engine
|
||||||
|
#engine_id="opensc"
|
||||||
|
#key_id="45"
|
||||||
|
|
||||||
|
# use the pkcs11 engine
|
||||||
|
engine_id="pkcs11"
|
||||||
|
key_id="id_45"
|
||||||
|
|
||||||
|
# Optional PIN configuration; this can be left out and PIN will be
|
||||||
|
# asked through the control interface
|
||||||
|
pin="1234"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Example configuration showing how to use an inlined blob as a CA certificate
|
||||||
|
# data instead of using external file
|
||||||
|
network={
|
||||||
|
ssid="example"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=TTLS
|
||||||
|
identity="user@example.com"
|
||||||
|
anonymous_identity="anonymous@example.com"
|
||||||
|
password="foobar"
|
||||||
|
ca_cert="blob://exampleblob"
|
||||||
|
priority=20
|
||||||
|
}
|
||||||
|
|
||||||
|
blob-base64-exampleblob={
|
||||||
|
SGVsbG8gV29ybGQhCg==
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Wildcard match for SSID (plaintext APs only). This example select any
|
||||||
|
# open AP regardless of its SSID.
|
||||||
|
network={
|
||||||
|
key_mgmt=NONE
|
||||||
|
}
|
||||||
|
network={
|
||||||
|
ssid="qiaomuf"
|
||||||
|
key_mgmt=WPA-EAP
|
||||||
|
eap=TLS
|
||||||
|
identity="user@example.com"
|
||||||
|
ca_cert="/home/gentoo/temp/ca.pem"
|
||||||
|
client_cert="/home/gentoo/temp/client.pem"
|
||||||
|
private_key="/home/gentoo/temp/client.p12"
|
||||||
|
private_key_passwd="whatever"
|
||||||
|
# phase2="auth=MSCHAPV2"
|
||||||
|
priority=10
|
||||||
|
}
|
||||||
|
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="blob://exampleblob"
|
||||||
|
priority=20
|
||||||
|
}
|
558
system-settings/plugins/ifnet/wpa_parser.c
Normal file
558
system-settings/plugins/ifnet/wpa_parser.c
Normal file
|
@ -0,0 +1,558 @@
|
||||||
|
/* -*- 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 <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <nm-system-config-interface.h>
|
||||||
|
#include "wpa_parser.h"
|
||||||
|
#include "net_parser.h"
|
||||||
|
#include "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, gchar * 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;
|
||||||
|
gchar *ssid = g_hash_table_lookup (security, "ssid"), *ssid_key;
|
||||||
|
gchar *value;
|
||||||
|
gboolean is_hex_ssid;
|
||||||
|
|
||||||
|
/* Every security information should have a 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)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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], '"');
|
||||||
|
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 futre, use wpa_supplicant instead. */
|
||||||
|
static void
|
||||||
|
add_keys_from_net ()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
gchar *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) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "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 (gchar * wpa_supplicant_conf)
|
||||||
|
{
|
||||||
|
GIOChannel *channel = NULL;
|
||||||
|
gchar *line;
|
||||||
|
gboolean complete = FALSE;
|
||||||
|
|
||||||
|
wpa_parser_data_changed = FALSE;
|
||||||
|
wsec_table = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
wsec_global_table = g_hash_table_new (g_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) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"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 (g_str_hash, g_str_equal);
|
||||||
|
gchar *tmp;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (line[0] == '#' || line[0] == '\0') {
|
||||||
|
g_free (line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* ignore inline comments */
|
||||||
|
if ((tmp = strchr (line, '#')) != NULL)
|
||||||
|
*tmp = '\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 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
wpa_get_value (gchar * ssid, gchar * key)
|
||||||
|
{
|
||||||
|
GHashTable *target = g_hash_table_lookup (wsec_table, ssid);
|
||||||
|
|
||||||
|
if (target)
|
||||||
|
return g_hash_table_lookup (target, key);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
exist_ssid (gchar * ssid)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (wsec_table, ssid) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GHashTable *
|
||||||
|
_get_hash_table (gchar * 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 (gchar * 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 FALSE;
|
||||||
|
if (!wsec_table || !wsec_global_table)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
channel = g_io_channel_new_file (config_file, "w", NULL);
|
||||||
|
if (!channel) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME,
|
||||||
|
"Can't open file %s for writing", config_file);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
g_hash_table_iter_init (&iter, wsec_global_table);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Writing to %s", config_file);
|
||||||
|
g_io_channel_write_chars (channel,
|
||||||
|
"#Generated by NetworkManager\n"
|
||||||
|
"###### Global Configuration ######\n",
|
||||||
|
-1, &bytes_written, error);
|
||||||
|
|
||||||
|
/* 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 && *error))
|
||||||
|
break;
|
||||||
|
g_free (out_line);
|
||||||
|
}
|
||||||
|
if (error && *error) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s",
|
||||||
|
(*error)->message);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
g_io_channel_write_chars (channel,
|
||||||
|
"\n###### Security Configuration ######\n",
|
||||||
|
-1, &bytes_written, error);
|
||||||
|
|
||||||
|
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);
|
||||||
|
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 && *error))
|
||||||
|
break;
|
||||||
|
g_free (out_line);
|
||||||
|
}
|
||||||
|
g_io_channel_write_chars (channel,
|
||||||
|
"}\n\n", -1, &bytes_written, error);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (error && *error) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s",
|
||||||
|
(*error)->message);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
g_io_channel_flush (channel, error);
|
||||||
|
|
||||||
|
if (error && *error) {
|
||||||
|
PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s",
|
||||||
|
(*error)->message);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
wpa_parser_data_changed = FALSE;
|
||||||
|
result = TRUE;
|
||||||
|
done:
|
||||||
|
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 (gchar * ssid, gchar * key, gchar * value)
|
||||||
|
{
|
||||||
|
gpointer orig_key = NULL, orig_value = NULL;
|
||||||
|
GHashTable *security = g_hash_table_lookup (wsec_table, ssid);
|
||||||
|
|
||||||
|
g_return_if_fail (security != NULL);
|
||||||
|
|
||||||
|
/* Remove old key value pairs */
|
||||||
|
if (g_hash_table_lookup_extended
|
||||||
|
(security, key, &orig_key, &orig_value)) {
|
||||||
|
g_hash_table_remove (security, orig_key);
|
||||||
|
g_free (orig_key);
|
||||||
|
g_free (orig_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add new key value */
|
||||||
|
if (value) {
|
||||||
|
gchar *new_value = g_strdup (value);
|
||||||
|
|
||||||
|
if (strcmp (key, "ssid") != 0 && strcmp (key, "psk") != 0
|
||||||
|
&& !g_str_has_prefix (key, "wep_key"))
|
||||||
|
strip_string (new_value, '"');
|
||||||
|
g_hash_table_insert (security, g_strdup (key), new_value);
|
||||||
|
}
|
||||||
|
wpa_parser_data_changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
wpa_has_security (gchar * ssid)
|
||||||
|
{
|
||||||
|
return g_hash_table_lookup (wsec_table, ssid) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
wpa_add_security (gchar * ssid)
|
||||||
|
{
|
||||||
|
if (wpa_has_security (ssid))
|
||||||
|
return FALSE;
|
||||||
|
else {
|
||||||
|
GHashTable *security =
|
||||||
|
g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
gchar *ssid_i;
|
||||||
|
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "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 (gchar * ssid)
|
||||||
|
{
|
||||||
|
gpointer orig_key, orig_value;
|
||||||
|
|
||||||
|
g_return_val_if_fail (wsec_table != NULL && ssid != NULL, FALSE);
|
||||||
|
PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Deleting security for %s", ssid);
|
||||||
|
if (!g_hash_table_lookup_extended
|
||||||
|
(wsec_table, ssid, &orig_key, &orig_value))
|
||||||
|
return FALSE;
|
||||||
|
g_hash_table_remove (wsec_table, orig_key);
|
||||||
|
g_free (orig_key);
|
||||||
|
destroy_security ((GHashTable *) orig_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;
|
||||||
|
}
|
||||||
|
}
|
40
system-settings/plugins/ifnet/wpa_parser.h
Normal file
40
system-settings/plugins/ifnet/wpa_parser.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* -*- 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 "/etc/wpa_supplicant/wpa_supplicant.conf"
|
||||||
|
#include <glib.h>
|
||||||
|
void wpa_parser_init (gchar * wpa_supplicant_conf);
|
||||||
|
void wpa_parser_destroy (void);
|
||||||
|
|
||||||
|
/* reader functions */
|
||||||
|
gchar *wpa_get_value (gchar * ssid, gchar * key);
|
||||||
|
gboolean exist_ssid (gchar * ssid);
|
||||||
|
GHashTable *_get_hash_table (gchar * ssid);
|
||||||
|
gboolean wpa_has_security (gchar * ssid);
|
||||||
|
|
||||||
|
/* writer functions */
|
||||||
|
gboolean wpa_flush_to_file (gchar * config_file);
|
||||||
|
void wpa_set_data (gchar * ssid, gchar * key, gchar * value);
|
||||||
|
gboolean wpa_add_security (gchar * ssid);
|
||||||
|
gboolean wpa_delete_security (gchar * ssid);
|
||||||
|
#endif
|
Loading…
Reference in a new issue