2007-08-15 Tambet Ingo <tambet@gmail.com>
* src/ppp-manager: Implement ppp-manager. It's sort of dead code * for now since nothing is using it at the moment, but it'll be all useful and stuff later on. * libnm-util/nm-setting.h: Define NMSettingPPP. * libnm-util/nm-setting.c: Implement NMSettingPPP. * libnm-util/nm-connection.c (register_default_creators): * Register ppp setting. * src/Makefile.am: Add ppp-manager to SUBDIRS. * configure.in: Require ppp headers. Build Makefile for * ppp-manager. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2695 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
13
ChangeLog
13
ChangeLog
@@ -1,5 +1,18 @@
|
||||
2007-08-15 Tambet Ingo <tambet@gmail.com>
|
||||
|
||||
* src/ppp-manager: Implement ppp-manager. It's sort of dead code for now since
|
||||
nothing is using it at the moment, but it'll be all useful and stuff later on.
|
||||
|
||||
* libnm-util/nm-setting.h: Define NMSettingPPP.
|
||||
|
||||
* libnm-util/nm-setting.c: Implement NMSettingPPP.
|
||||
|
||||
* libnm-util/nm-connection.c (register_default_creators): Register ppp setting.
|
||||
|
||||
* src/Makefile.am: Add ppp-manager to SUBDIRS.
|
||||
|
||||
* configure.in: Require ppp headers. Build Makefile for ppp-manager.
|
||||
|
||||
* introspection/Makefile.am: Add nm-manager-client.xml to EXTRA_DIST.
|
||||
|
||||
2007-08-14 Tambet Ingo <tambet@gmail.com>
|
||||
|
@@ -215,6 +215,11 @@ fi
|
||||
AC_DEFINE_UNQUOTED(IP_BINARY_PATH, "$IP_BINARY_PATH", [Define to path of ip binary])
|
||||
AC_SUBST(IP_BINARY_PATH)
|
||||
|
||||
# PPPD
|
||||
AC_CHECK_HEADERS(pppd/pppd.h,,
|
||||
AC_MSG_ERROR(couldn't find pppd.h. pppd-devel package is required.))
|
||||
|
||||
|
||||
AC_ARG_ENABLE(more-warnings,
|
||||
AC_HELP_STRING([--enable-more-warnings], [Maximum compiler warnings]),
|
||||
set_more_warnings="$enableval",[
|
||||
@@ -259,6 +264,7 @@ src/named-manager/Makefile
|
||||
src/vpn-manager/Makefile
|
||||
src/dhcp-manager/Makefile
|
||||
src/supplicant-manager/Makefile
|
||||
src/ppp-manager/Makefile
|
||||
src/backends/Makefile
|
||||
libnm-util/libnm-util.pc
|
||||
libnm-util/Makefile
|
||||
|
@@ -17,6 +17,7 @@ register_default_creators (void)
|
||||
{ "802-11-wireless", nm_setting_wireless_new_from_hash },
|
||||
{ "ipv4", nm_setting_ip4_config_new_from_hash },
|
||||
{ "802-11-wireless-security", nm_setting_wireless_security_new_from_hash },
|
||||
{ "ppp", nm_setting_ppp_new_from_hash },
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <string.h>
|
||||
@@ -1147,3 +1149,149 @@ nm_setting_wireless_security_new_from_hash (GHashTable *settings)
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
/* PPP */
|
||||
|
||||
static gboolean
|
||||
setting_ppp_verify (NMSetting *setting, GHashTable *all_settings)
|
||||
{
|
||||
/* FIXME: Do we even want this or can we just let pppd evaluate the options? */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
setting_ppp_hash (NMSetting *setting)
|
||||
{
|
||||
NMSettingPPP *self = (NMSettingPPP *) setting;
|
||||
GHashTable *hash;
|
||||
|
||||
hash = setting_hash_new ();
|
||||
|
||||
g_hash_table_insert (hash, "noauth", boolean_to_gvalue (self->noauth));
|
||||
g_hash_table_insert (hash, "refuse-eap", boolean_to_gvalue (self->refuse_eap));
|
||||
g_hash_table_insert (hash, "refuse-chap", boolean_to_gvalue (self->refuse_chap));
|
||||
g_hash_table_insert (hash, "refuse-mschap", boolean_to_gvalue (self->refuse_mschap));
|
||||
g_hash_table_insert (hash, "nobsdcomp", boolean_to_gvalue (self->nobsdcomp));
|
||||
g_hash_table_insert (hash, "nodeflate", boolean_to_gvalue (self->nodeflate));
|
||||
g_hash_table_insert (hash, "require-mppe", boolean_to_gvalue (self->require_mppe));
|
||||
g_hash_table_insert (hash, "require-mppe-128", boolean_to_gvalue (self->require_mppe_128));
|
||||
g_hash_table_insert (hash, "mppe-stateful", boolean_to_gvalue (self->mppe_stateful));
|
||||
g_hash_table_insert (hash, "require-mppc", boolean_to_gvalue (self->require_mppc));
|
||||
g_hash_table_insert (hash, "crtscts", boolean_to_gvalue (self->crtscts));
|
||||
g_hash_table_insert (hash, "usepeerdns", boolean_to_gvalue (self->usepeerdns));
|
||||
|
||||
g_hash_table_insert (hash, "baud", int_to_gvalue (self->baud));
|
||||
g_hash_table_insert (hash, "mru", int_to_gvalue (self->mru));
|
||||
g_hash_table_insert (hash, "mtu", int_to_gvalue (self->mtu));
|
||||
g_hash_table_insert (hash, "lcp-echo-failure", int_to_gvalue (self->lcp_echo_failure));
|
||||
g_hash_table_insert (hash, "lcp-echo-interval", int_to_gvalue (self->lcp_echo_interval));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setting_ppp_destroy (NMSetting *setting)
|
||||
{
|
||||
NMSettingPPP *self = (NMSettingPPP *) setting;
|
||||
|
||||
g_slice_free (NMSettingPPP, self);
|
||||
}
|
||||
|
||||
NMSetting *
|
||||
nm_setting_ppp_new (void)
|
||||
{
|
||||
NMSetting *setting;
|
||||
|
||||
setting = (NMSetting *) g_slice_new0 (NMSettingPPP);
|
||||
|
||||
setting->name = g_strdup ("ppp");
|
||||
setting->verify_fn = setting_ppp_verify;
|
||||
setting->hash_fn = setting_ppp_hash;
|
||||
setting->destroy_fn = setting_ppp_destroy;
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
NMSetting *
|
||||
nm_setting_ppp_new_from_hash (GHashTable *settings)
|
||||
{
|
||||
NMSettingPPP *self;
|
||||
NMSetting *setting;
|
||||
GValue *value;
|
||||
|
||||
g_return_val_if_fail (settings != NULL, NULL);
|
||||
|
||||
setting = nm_setting_ppp_new ();
|
||||
self = (NMSettingPPP *) setting;
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "noauth");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->noauth = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "refuse-eap");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->refuse_eap = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "refuse-chap");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->refuse_chap = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "refuse-mschap");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->refuse_mschap = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "nobsdcomp");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->nobsdcomp = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "nodeflate");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->nodeflate = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "require-mppe");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->require_mppe = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "require-mppe-128");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->require_mppe_128 = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "mppe-stateful");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->mppe_stateful = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "require-mppc");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->require_mppc = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "crtscts");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->crtscts = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "usepeerdns");
|
||||
if (value && G_VALUE_HOLDS_BOOLEAN (value))
|
||||
self->usepeerdns = g_value_get_boolean (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "baud");
|
||||
if (value && G_VALUE_HOLDS_INT (value))
|
||||
self->baud = g_value_get_int (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "mru");
|
||||
if (value && G_VALUE_HOLDS_INT (value))
|
||||
self->mru = g_value_get_int (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "mtu");
|
||||
if (value && G_VALUE_HOLDS_INT (value))
|
||||
self->mtu = g_value_get_int (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "lcp-echo-failure");
|
||||
if (value && G_VALUE_HOLDS_INT (value))
|
||||
self->lcp_echo_failure = g_value_get_int (value);
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (settings, "lcp-echo-interval");
|
||||
if (value && G_VALUE_HOLDS_INT (value))
|
||||
self->lcp_echo_interval = g_value_get_int (value);
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
@@ -1,3 +1,5 @@
|
||||
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
|
||||
|
||||
#ifndef NM_SETTING_H
|
||||
#define NM_SETTING_H
|
||||
|
||||
@@ -136,6 +138,34 @@ typedef struct {
|
||||
NMSetting *nm_setting_wireless_security_new (void);
|
||||
NMSetting *nm_setting_wireless_security_new_from_hash (GHashTable *settings);
|
||||
|
||||
/* PPP */
|
||||
|
||||
typedef struct {
|
||||
NMSetting parent;
|
||||
|
||||
gboolean noauth;
|
||||
gboolean refuse_eap;
|
||||
gboolean refuse_chap;
|
||||
gboolean refuse_mschap;
|
||||
gboolean nobsdcomp;
|
||||
gboolean nodeflate;
|
||||
gboolean require_mppe;
|
||||
gboolean require_mppe_128;
|
||||
gboolean mppe_stateful;
|
||||
gboolean require_mppc;
|
||||
gboolean crtscts;
|
||||
gboolean usepeerdns;
|
||||
|
||||
gint32 baud;
|
||||
gint32 mru;
|
||||
gint32 mtu;
|
||||
gint32 lcp_echo_failure;
|
||||
gint32 lcp_echo_interval;
|
||||
} NMSettingPPP;
|
||||
|
||||
NMSetting *nm_setting_ppp_new (void);
|
||||
NMSetting *nm_setting_ppp_new_from_hash (GHashTable *settings);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_SETTING_H */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
SUBDIRS=named-manager vpn-manager dhcp-manager supplicant-manager backends
|
||||
SUBDIRS=named-manager vpn-manager dhcp-manager supplicant-manager ppp-manager backends
|
||||
|
||||
INCLUDES = -I${top_srcdir} \
|
||||
-I${top_srcdir}/include \
|
||||
|
62
src/ppp-manager/Makefile.am
Normal file
62
src/ppp-manager/Makefile.am
Normal file
@@ -0,0 +1,62 @@
|
||||
INCLUDES = -I${top_srcdir} \
|
||||
-I${top_srcdir}/include \
|
||||
-I${top_srcdir}/utils \
|
||||
-I${top_srcdir}/libnm-util \
|
||||
-I${top_srcdir}/src
|
||||
|
||||
noinst_LTLIBRARIES = libppp-manager.la
|
||||
|
||||
BUILT_SOURCES = \
|
||||
nm-ppp-marshal.h \
|
||||
nm-ppp-marshal.c
|
||||
|
||||
libppp_manager_la_SOURCES = \
|
||||
nm-ppp-manager.c \
|
||||
nm-ppp-manager.h \
|
||||
nm-ppp-status.h \
|
||||
nm-ppp-marshal-main.c
|
||||
|
||||
libppp_manager_la_CPPFLAGS = \
|
||||
$(DBUS_CFLAGS) \
|
||||
$(HAL_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||
-DLIBDIR=\"$(libdir)\"
|
||||
|
||||
libppp_manager_la_LIBADD = $(DBUS_LIBS) $(GLIB_LIBS)
|
||||
|
||||
nm_pppd_plugindir = $(libdir)
|
||||
nm_pppd_plugin_PROGRAMS = nm-pppd-plugin.so
|
||||
|
||||
nm_pppd_plugin_so_SOURCES = \
|
||||
nm-pppd-plugin.c \
|
||||
nm-pppd-plugin.h \
|
||||
nm-ppp-status.h
|
||||
|
||||
nm_pppd_plugin_so_CPPFLAGS = $(DBUS_CFLAGS) $(GLIB_CFLAGS)
|
||||
|
||||
nm_pppd_plugin_so_LDFLAGS = -shared
|
||||
nm_pppd_plugin_so_LDADD = \
|
||||
$(DBUS_LIBS) \
|
||||
$(GLIB_LIBS) \
|
||||
$(top_builddir)/libnm-util/libnm-util.la
|
||||
|
||||
|
||||
|
||||
EXTRA_DIST = nm-ppp-marshal.list
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
nm-ppp-marshal.h: nm-ppp-marshal.list
|
||||
$(GLIB_GENMARSHAL) --prefix=nm_ppp_marshal $(srcdir)/nm-ppp-marshal.list --header > \
|
||||
xgen-gmh \
|
||||
&& (cmp -s xgen-gmh nm-ppp-marshal.h || cp xgen-gmh nm-ppp-marshal.h) \
|
||||
&& rm -f xgen-gmh xgen-gmh~
|
||||
|
||||
nm-ppp-marshal.c: nm-ppp-marshal.list
|
||||
$(GLIB_GENMARSHAL) --prefix=nm_ppp_marshal $(srcdir)/nm-ppp-marshal.list --body > \
|
||||
xgen-gmc \
|
||||
&& cp xgen-gmc nm-ppp-marshal.c \
|
||||
&& rm -f xgen-gmc xgen-gmc~
|
||||
|
||||
nm-ppp-marshal-main.c: nm-ppp-marshal.c nm-ppp-marshal.h
|
||||
|
597
src/ppp-manager/nm-ppp-manager.c
Normal file
597
src/ppp-manager/nm-ppp-manager.c
Normal file
@@ -0,0 +1,597 @@
|
||||
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nm-ppp-manager.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-utils.h"
|
||||
#include "dbus-dict-helpers.h"
|
||||
#include "nm-ppp-marshal.h"
|
||||
|
||||
#define NM_PPPD_PLUGIN LIBDIR "/nm-pppd-plugin.so"
|
||||
#define NM_PPP_WAIT_PPPD 10000 /* 10 seconds */
|
||||
|
||||
typedef struct {
|
||||
GPid pid;
|
||||
NMDBusManager *dbus_manager;
|
||||
|
||||
guint32 signal_handler;
|
||||
guint32 ppp_timeout_handler;
|
||||
guint32 name_owner_changed_handler;
|
||||
} NMPPPManagerPrivate;
|
||||
|
||||
#define NM_PPP_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_PPP_MANAGER, NMPPPManagerPrivate))
|
||||
|
||||
G_DEFINE_TYPE (NMPPPManager, nm_ppp_manager, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
STATE_CHANGED,
|
||||
IP4_CONFIG,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
GQuark
|
||||
nm_ppp_manager_error_quark (void)
|
||||
{
|
||||
static GQuark quark;
|
||||
|
||||
if (!quark)
|
||||
quark = g_quark_from_static_string ("nm_ppp_manager_error");
|
||||
|
||||
return quark;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ppp_manager_init (NMPPPManager *manager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
nm_ppp_manager_stop (NM_PPP_MANAGER (object));
|
||||
|
||||
G_OBJECT_CLASS (nm_ppp_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ppp_manager_class_init (NMPPPManagerClass *manager_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
|
||||
|
||||
g_type_class_add_private (manager_class, sizeof (NMPPPManagerPrivate));
|
||||
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* signals */
|
||||
signals[STATE_CHANGED] =
|
||||
g_signal_new ("state-changed",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMPPPManagerClass, state_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_UINT);
|
||||
|
||||
signals[IP4_CONFIG] =
|
||||
g_signal_new ("ip4-config",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMPPPManagerClass, ip4_config),
|
||||
NULL, NULL,
|
||||
nm_ppp_marshal_VOID__STRING_OBJECT,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
NMPPPManager *
|
||||
nm_ppp_manager_new (void)
|
||||
{
|
||||
return (NMPPPManager *) g_object_new (NM_TYPE_PPP_MANAGER, NULL);
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
|
||||
typedef struct {
|
||||
GPtrArray *array;
|
||||
GStringChunk *chunk;
|
||||
} NMCmdLine;
|
||||
|
||||
static NMCmdLine *
|
||||
nm_cmd_line_new (void)
|
||||
{
|
||||
NMCmdLine *cmd;
|
||||
|
||||
cmd = g_slice_new (NMCmdLine);
|
||||
cmd->array = g_ptr_array_new ();
|
||||
cmd->chunk = g_string_chunk_new (1024);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_cmd_line_destroy (NMCmdLine *cmd)
|
||||
{
|
||||
g_ptr_array_free (cmd->array, TRUE);
|
||||
g_string_chunk_free (cmd->chunk);
|
||||
g_slice_free (NMCmdLine, cmd);
|
||||
}
|
||||
|
||||
static char *
|
||||
nm_cmd_line_to_str (NMCmdLine *cmd)
|
||||
{
|
||||
char *str;
|
||||
|
||||
g_ptr_array_add (cmd->array, NULL);
|
||||
str = g_strjoinv (" ", (gchar **) cmd->array->pdata);
|
||||
g_ptr_array_remove_index (cmd->array, cmd->array->len - 1);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_cmd_line_add_string (NMCmdLine *cmd, const char *str)
|
||||
{
|
||||
g_ptr_array_add (cmd->array, g_string_chunk_insert (cmd->chunk, str));
|
||||
}
|
||||
|
||||
static void
|
||||
nm_cmd_line_add_int (NMCmdLine *cmd, int i)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("%d", i);
|
||||
nm_cmd_line_add_string (cmd, str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
|
||||
static inline const char *nm_find_pppd (void)
|
||||
{
|
||||
static const char *pppd_binary_paths[] =
|
||||
{
|
||||
"/usr/local/sbin/pppd",
|
||||
"/usr/sbin/pppd",
|
||||
"/sbin/pppd",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char **pppd_binary = pppd_binary_paths;
|
||||
|
||||
while (*pppd_binary != NULL) {
|
||||
if (g_file_test (*pppd_binary, G_FILE_TEST_EXISTS))
|
||||
break;
|
||||
pppd_binary++;
|
||||
}
|
||||
|
||||
return *pppd_binary;
|
||||
}
|
||||
|
||||
static void
|
||||
ppp_exit_code (guint pppd_exit_status)
|
||||
{
|
||||
const char *msg;
|
||||
|
||||
switch (pppd_exit_status) {
|
||||
case 1:
|
||||
msg = "Fatal pppd error";
|
||||
break;
|
||||
case 2:
|
||||
msg = "pppd options error";
|
||||
break;
|
||||
case 3:
|
||||
msg = "No root priv error";
|
||||
break;
|
||||
case 4:
|
||||
msg = "No ppp module error";
|
||||
break;
|
||||
case 5:
|
||||
msg = "pppd received a signal";
|
||||
break;
|
||||
case 6:
|
||||
msg = "Serial port lock failed";
|
||||
break;
|
||||
case 7:
|
||||
msg = "Serial port open failed";
|
||||
break;
|
||||
case 8:
|
||||
msg = "Connect script failed";
|
||||
break;
|
||||
case 9:
|
||||
msg = "Pty program error";
|
||||
break;
|
||||
case 10:
|
||||
msg = "PPP negotiation failed";
|
||||
break;
|
||||
case 11:
|
||||
msg = "Peer didn't authenticatie itself";
|
||||
break;
|
||||
case 12:
|
||||
msg = "Link idle: Idle Seconds reached.";
|
||||
break;
|
||||
case 13:
|
||||
msg = "Connect time limit reached.";
|
||||
break;
|
||||
case 14:
|
||||
msg = "Callback negotiated, call should come back.";
|
||||
break;
|
||||
case 15:
|
||||
msg = "Lack of LCP echo responses";
|
||||
break;
|
||||
case 16:
|
||||
msg = "A modem hung up the phone";
|
||||
break;
|
||||
case 17:
|
||||
msg = "Loopback detected";
|
||||
break;
|
||||
case 18:
|
||||
msg = "The init script failed";
|
||||
break;
|
||||
case 19:
|
||||
msg = "Authentication error.\n"
|
||||
"We failed to authenticate ourselves to the peer.\n"
|
||||
"Maybe bad account or password?";
|
||||
break;
|
||||
default:
|
||||
msg = "Unknown error";
|
||||
}
|
||||
|
||||
g_warning ("pppd exited with error: %s", msg);
|
||||
}
|
||||
|
||||
static void
|
||||
ppp_watch_cb (GPid pid, gint status, gpointer user_data)
|
||||
{
|
||||
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (user_data);
|
||||
guint err;
|
||||
|
||||
if (WIFEXITED (status)) {
|
||||
err = WEXITSTATUS (status);
|
||||
if (err != 0)
|
||||
ppp_exit_code (err);
|
||||
} else if (WIFSTOPPED (status))
|
||||
g_warning ("ppp stopped unexpectedly with signal %d", WSTOPSIG (status));
|
||||
else if (WIFSIGNALED (status))
|
||||
g_warning ("ppp died with signal %d", WTERMSIG (status));
|
||||
else
|
||||
g_warning ("ppp died from an unknown cause");
|
||||
|
||||
/* Reap child if needed. */
|
||||
waitpid (pid, NULL, WNOHANG);
|
||||
|
||||
priv->pid = 0;
|
||||
}
|
||||
|
||||
#define HANDLE_DICT_ITEM(in_key, in_type, in_ary_type, op) \
|
||||
if (!strcmp (entry.key, in_key)) { \
|
||||
if (entry.type != in_type) { \
|
||||
nm_warning (in_key "had invalid type in PPP IP Config message."); \
|
||||
} else { \
|
||||
if (in_type == DBUS_TYPE_ARRAY && entry.array_type != in_ary_type) { \
|
||||
nm_warning (in_key "had invalid type in PPP IP Config message."); \
|
||||
} else { \
|
||||
op \
|
||||
} \
|
||||
} \
|
||||
goto next; \
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_ip4_config (DBusMessage *message, char **interface, NMIP4Config **config)
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter iter_dict;
|
||||
NMUDictEntry entry;
|
||||
gboolean success = FALSE;
|
||||
|
||||
dbus_message_iter_init (message, &iter);
|
||||
if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) {
|
||||
nm_warning ("Warning: couldn't get config dictionary from PPP IP Config message.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
*config = nm_ip4_config_new ();
|
||||
|
||||
while (nmu_dbus_dict_has_dict_entry (&iter_dict)) {
|
||||
int i;
|
||||
|
||||
if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) {
|
||||
nm_warning ("Error: couldn't read dict entryfrom PPP IP Config message.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
HANDLE_DICT_ITEM("interface", DBUS_TYPE_STRING, 0,
|
||||
{ if (strlen (entry.str_value)) *interface = g_strdup (entry.str_value); });
|
||||
/* IP specific options */
|
||||
HANDLE_DICT_ITEM("address", DBUS_TYPE_UINT32, 0,
|
||||
{ nm_ip4_config_set_address (*config, entry.uint32_value); });
|
||||
HANDLE_DICT_ITEM("netmask", DBUS_TYPE_UINT32, 0,
|
||||
{ nm_ip4_config_set_netmask (*config, entry.uint32_value ? entry.uint32_value : 0x00FF); });
|
||||
HANDLE_DICT_ITEM("gateway", DBUS_TYPE_UINT32, 0,
|
||||
{ nm_ip4_config_set_gateway (*config, entry.uint32_value); });
|
||||
|
||||
/* Multiple DNS servers are allowed */
|
||||
HANDLE_DICT_ITEM("dns_server", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
|
||||
{
|
||||
for (i = 0; i < entry.array_len; i++)
|
||||
nm_ip4_config_add_nameserver (*config, entry.uint32array_value[i]);
|
||||
});
|
||||
|
||||
/* FIXME: Ignoring WINS servers for now since IP4Config doesn't have a place for it */
|
||||
|
||||
next:
|
||||
nmu_dbus_dict_entry_clear (&entry);
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
if (!success && *config) {
|
||||
g_object_unref (*config);
|
||||
*config = NULL;
|
||||
g_free (*interface);
|
||||
*interface = NULL;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_ppp_manager_dbus_signal_handler (DBusConnection *connection,
|
||||
DBusMessage *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPPPManager *manager = NM_PPP_MANAGER (user_data);
|
||||
gboolean handled = FALSE;
|
||||
|
||||
if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_PPP, "Status")) {
|
||||
guint32 state;
|
||||
|
||||
if (dbus_message_get_args (message, NULL,
|
||||
DBUS_TYPE_UINT32, &state,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
|
||||
g_signal_emit (manager, signals[STATE_CHANGED], 0, state);
|
||||
handled = TRUE;
|
||||
}
|
||||
} else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_PPP, "IP4Config")) {
|
||||
char *iface = NULL;
|
||||
NMIP4Config *config = NULL;
|
||||
|
||||
if (parse_ip4_config (message, &iface, &config)) {
|
||||
g_signal_emit (manager, signals[IP4_CONFIG], 0, iface, config);
|
||||
g_free (iface);
|
||||
g_object_unref (config);
|
||||
handled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pppd_timed_out (gpointer data)
|
||||
{
|
||||
NMPPPManager *manager = NM_PPP_MANAGER (data);
|
||||
|
||||
nm_warning ("Looks like pppd didn't initialize our dbus module");
|
||||
nm_ppp_manager_stop (manager);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
name_owner_changed (NMDBusManager *dbus_manager,
|
||||
const char *name,
|
||||
const char *old,
|
||||
const char *new,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPPPManager *manager = NM_PPP_MANAGER (user_data);
|
||||
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
|
||||
gboolean old_owner_good = (old && (strlen (old) > 0));
|
||||
gboolean new_owner_good = (new && (strlen (new) > 0));
|
||||
|
||||
if (strcmp (name, NM_DBUS_SERVICE_PPP))
|
||||
return;
|
||||
|
||||
if (!old_owner_good && new_owner_good) {
|
||||
if (priv->ppp_timeout_handler) {
|
||||
g_source_remove (priv->ppp_timeout_handler);
|
||||
priv->ppp_timeout_handler = 0;
|
||||
}
|
||||
|
||||
priv->signal_handler = nm_dbus_manager_register_signal_handler (priv->dbus_manager,
|
||||
NM_DBUS_INTERFACE_PPP,
|
||||
NM_DBUS_SERVICE_PPP,
|
||||
nm_ppp_manager_dbus_signal_handler,
|
||||
manager);
|
||||
} else if (old_owner_good && !new_owner_good) {
|
||||
nm_ppp_manager_stop (manager);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
start_dbus_watcher (NMPPPManager *manager)
|
||||
{
|
||||
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
priv->ppp_timeout_handler = g_timeout_add (NM_PPP_WAIT_PPPD, pppd_timed_out, manager);
|
||||
|
||||
priv->dbus_manager = nm_dbus_manager_get ();
|
||||
priv->name_owner_changed_handler = g_signal_connect (priv->dbus_manager, "name-owner-changed",
|
||||
G_CALLBACK (name_owner_changed),
|
||||
manager);
|
||||
}
|
||||
|
||||
static NMCmdLine *
|
||||
create_pppd_cmd_line (NMSettingPPP *setting, const char *device, GError **err)
|
||||
{
|
||||
const char *ppp_binary;
|
||||
NMCmdLine *cmd;
|
||||
|
||||
ppp_binary = nm_find_pppd ();
|
||||
if (!ppp_binary) {
|
||||
g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR,
|
||||
"Could not find ppp binary.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create pppd command line */
|
||||
cmd = nm_cmd_line_new ();
|
||||
nm_cmd_line_add_string (cmd, ppp_binary);
|
||||
|
||||
nm_cmd_line_add_string (cmd, "nodetach");
|
||||
nm_cmd_line_add_string (cmd, "lock");
|
||||
nm_cmd_line_add_string (cmd, device);
|
||||
|
||||
if (setting->baud)
|
||||
nm_cmd_line_add_int (cmd, setting->baud);
|
||||
|
||||
if (setting->noauth)
|
||||
nm_cmd_line_add_string (cmd, "noauth");
|
||||
if (setting->noauth)
|
||||
nm_cmd_line_add_string (cmd, "refuse-eap");
|
||||
if (setting->refuse_eap)
|
||||
nm_cmd_line_add_string (cmd, "refuse-chap");
|
||||
if (setting->refuse_chap)
|
||||
nm_cmd_line_add_string (cmd, "refuse-mschap");
|
||||
if (setting->refuse_mschap)
|
||||
nm_cmd_line_add_string (cmd, "nobsdcomp");
|
||||
if (setting->nobsdcomp)
|
||||
nm_cmd_line_add_string (cmd, "nodeflate");
|
||||
if (setting->nodeflate)
|
||||
nm_cmd_line_add_string (cmd, "require-mppe");
|
||||
if (setting->require_mppe)
|
||||
nm_cmd_line_add_string (cmd, "require-mppe-128");
|
||||
if (setting->require_mppe_128)
|
||||
nm_cmd_line_add_string (cmd, "mppe-stateful");
|
||||
if (setting->mppe_stateful)
|
||||
nm_cmd_line_add_string (cmd, "require-mppc");
|
||||
if (setting->crtscts)
|
||||
nm_cmd_line_add_string (cmd, "crtscts");
|
||||
if (setting->usepeerdns)
|
||||
nm_cmd_line_add_string (cmd, "usepeerdns");
|
||||
|
||||
if (setting->mru) {
|
||||
nm_cmd_line_add_string (cmd, "mru");
|
||||
nm_cmd_line_add_int (cmd, setting->mru);
|
||||
}
|
||||
|
||||
if (setting->mtu) {
|
||||
nm_cmd_line_add_string (cmd, "mtu");
|
||||
nm_cmd_line_add_int (cmd, setting->mtu);
|
||||
}
|
||||
|
||||
if (setting->lcp_echo_failure) {
|
||||
nm_cmd_line_add_string (cmd, "lcp-echo-failure");
|
||||
nm_cmd_line_add_int (cmd, setting->lcp_echo_failure);
|
||||
}
|
||||
|
||||
if (setting->lcp_echo_interval) {
|
||||
nm_cmd_line_add_string (cmd, "lcp-echo-interval");
|
||||
nm_cmd_line_add_int (cmd, setting->lcp_echo_interval);
|
||||
}
|
||||
|
||||
nm_cmd_line_add_string (cmd, "plugin");
|
||||
nm_cmd_line_add_string (cmd, NM_PPPD_PLUGIN);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ppp_manager_start (NMPPPManager *manager,
|
||||
const char *device,
|
||||
NMSettingPPP *setting,
|
||||
GError **err)
|
||||
{
|
||||
NMPPPManagerPrivate *priv;
|
||||
NMCmdLine *ppp_cmd;
|
||||
char *cmd_str;
|
||||
GPid pid;
|
||||
int stdin_fd;
|
||||
int stdout_fd;
|
||||
int stderr_fd;
|
||||
GSource *ppp_watch;
|
||||
|
||||
g_return_val_if_fail (NM_IS_PPP_MANAGER (manager), FALSE);
|
||||
g_return_val_if_fail (device != NULL, FALSE);
|
||||
g_return_val_if_fail (setting != NULL, FALSE);
|
||||
|
||||
ppp_cmd = create_pppd_cmd_line (setting, device, err);
|
||||
if (!ppp_cmd)
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: This should come from NMSettingIP4Config */
|
||||
nm_cmd_line_add_string (ppp_cmd, "defaultroute");
|
||||
g_ptr_array_add (ppp_cmd->array, NULL);
|
||||
|
||||
priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
nm_info ("Starting pppd connection");
|
||||
|
||||
cmd_str = nm_cmd_line_to_str (ppp_cmd);
|
||||
nm_debug ("Command line: %s", cmd_str);
|
||||
g_free (cmd_str);
|
||||
|
||||
if (!g_spawn_async_with_pipes (NULL, (char **) ppp_cmd->array->pdata, NULL,
|
||||
G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &priv->pid,
|
||||
&stdin_fd, &stdout_fd, &stderr_fd, err)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
nm_debug ("ppp started with pid %d", priv->pid);
|
||||
|
||||
ppp_watch = g_child_watch_source_new (pid);
|
||||
g_source_set_callback (ppp_watch, (GSourceFunc) ppp_watch_cb, manager, NULL);
|
||||
g_source_attach (ppp_watch, NULL);
|
||||
g_source_unref (ppp_watch);
|
||||
|
||||
start_dbus_watcher (manager);
|
||||
|
||||
out:
|
||||
if (ppp_cmd)
|
||||
nm_cmd_line_destroy (ppp_cmd);
|
||||
|
||||
return priv->pid > 0;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ppp_manager_stop (NMPPPManager *manager)
|
||||
{
|
||||
NMPPPManagerPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_PPP_MANAGER (manager));
|
||||
|
||||
priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
if (priv->ppp_timeout_handler) {
|
||||
g_source_remove (priv->ppp_timeout_handler);
|
||||
priv->ppp_timeout_handler = 0;
|
||||
}
|
||||
|
||||
if (priv->signal_handler) {
|
||||
nm_dbus_manager_remove_signal_handler (priv->dbus_manager, priv->signal_handler);
|
||||
priv->signal_handler = 0;
|
||||
}
|
||||
|
||||
if (priv->dbus_manager) {
|
||||
g_signal_handler_disconnect (priv->dbus_manager, priv->name_owner_changed_handler);
|
||||
g_object_unref (priv->dbus_manager);
|
||||
priv->dbus_manager = NULL;
|
||||
}
|
||||
|
||||
if (priv->pid) {
|
||||
kill (priv->pid, SIGTERM);
|
||||
priv->pid = 0;
|
||||
}
|
||||
}
|
46
src/ppp-manager/nm-ppp-manager.h
Normal file
46
src/ppp-manager/nm-ppp-manager.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef NM_PPP_MANAGER_H
|
||||
#define NM_PPP_MANAGER_H
|
||||
|
||||
#include <glib/gtypes.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-ppp-status.h"
|
||||
#include "nm-setting.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-pppd-plugin.h"
|
||||
|
||||
#define NM_TYPE_PPP_MANAGER (nm_ppp_manager_get_type ())
|
||||
#define NM_PPP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PPP_MANAGER, NMPPPManager))
|
||||
#define NM_PPP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_PPP_MANAGER, NMPPPManagerClass))
|
||||
#define NM_IS_PPP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_PPP_MANAGER))
|
||||
#define NM_IS_PPP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_PPP_MANAGER))
|
||||
#define NM_PPP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_PPP_MANAGER, NMPPPManagerClass))
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
} NMPPPManager;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
|
||||
/* Signals */
|
||||
void (*state_changed) (NMPPPManager *manager, NMPPPStatus status);
|
||||
void (*ip4_config) (NMPPPManager *manager, const char *iface, NMIP4Config *config);
|
||||
} NMPPPManagerClass;
|
||||
|
||||
GType nm_ppp_manager_get_type (void);
|
||||
|
||||
NMPPPManager *nm_ppp_manager_new (void);
|
||||
|
||||
gboolean nm_ppp_manager_start (NMPPPManager *manager,
|
||||
const char *device,
|
||||
NMSettingPPP *setting,
|
||||
GError **err);
|
||||
|
||||
void nm_ppp_manager_stop (NMPPPManager *manager);
|
||||
|
||||
|
||||
#define NM_PPP_MANAGER_ERROR nm_ppp_manager_error_quark()
|
||||
GQuark nm_ppp_manager_error_quark (void);
|
||||
|
||||
#endif /* NM_PPP_MANAGER_H */
|
3
src/ppp-manager/nm-ppp-marshal-main.c
Normal file
3
src/ppp-manager/nm-ppp-marshal-main.c
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "nm-ppp-marshal.h"
|
||||
#include "nm-ppp-marshal.c"
|
||||
|
1
src/ppp-manager/nm-ppp-marshal.list
Normal file
1
src/ppp-manager/nm-ppp-marshal.list
Normal file
@@ -0,0 +1 @@
|
||||
VOID:STRING,OBJECT
|
22
src/ppp-manager/nm-ppp-status.h
Normal file
22
src/ppp-manager/nm-ppp-status.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef NM_PPP_STATUS_H
|
||||
#define NM_PPP_STATUS_H
|
||||
|
||||
typedef enum {
|
||||
NM_PPP_STATUS_UNKNOWN,
|
||||
|
||||
NM_PPP_STATUS_DEAD,
|
||||
NM_PPP_STATUS_INITIALIZE,
|
||||
NM_PPP_STATUS_SERIALCONN,
|
||||
NM_PPP_STATUS_DORMANT,
|
||||
NM_PPP_STATUS_ESTABLISH,
|
||||
NM_PPP_STATUS_AUTHENTICATE,
|
||||
NM_PPP_STATUS_CALLBACK,
|
||||
NM_PPP_STATUS_NETWORK,
|
||||
NM_PPP_STATUS_RUNNING,
|
||||
NM_PPP_STATUS_TERMINATE,
|
||||
NM_PPP_STATUS_DISCONNECT,
|
||||
NM_PPP_STATUS_HOLDOFF,
|
||||
NM_PPP_STATUS_MASTER
|
||||
} NMPPPStatus;
|
||||
|
||||
#endif /* NM_PPP_STATUS_H */
|
307
src/ppp-manager/nm-pppd-plugin.c
Normal file
307
src/ppp-manager/nm-pppd-plugin.c
Normal file
@@ -0,0 +1,307 @@
|
||||
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
|
||||
|
||||
#include <pppd/pppd.h>
|
||||
#include <pppd/fsm.h>
|
||||
#include <pppd/ipcp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <glib.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "nm-pppd-plugin.h"
|
||||
#include "nm-ppp-status.h"
|
||||
#include "dbus-dict-helpers.h"
|
||||
|
||||
char pppd_version[] = VERSION;
|
||||
|
||||
static void
|
||||
nm_phasechange (void *data, int arg)
|
||||
{
|
||||
NMPPPStatus status = NM_PPP_STATUS_UNKNOWN;
|
||||
char *phase;
|
||||
|
||||
switch (arg) {
|
||||
case PHASE_DEAD:
|
||||
status = NM_PPP_STATUS_DEAD;
|
||||
phase = "dead";
|
||||
break;
|
||||
case PHASE_INITIALIZE:
|
||||
status = NM_PPP_STATUS_INITIALIZE;
|
||||
phase = "initialize";
|
||||
break;
|
||||
case PHASE_SERIALCONN:
|
||||
status = NM_PPP_STATUS_SERIALCONN;
|
||||
phase = "serial connection";
|
||||
break;
|
||||
case PHASE_DORMANT:
|
||||
status = NM_PPP_STATUS_DORMANT;
|
||||
phase = "dormant";
|
||||
break;
|
||||
case PHASE_ESTABLISH:
|
||||
status = NM_PPP_STATUS_ESTABLISH;
|
||||
phase = "establish";
|
||||
break;
|
||||
case PHASE_AUTHENTICATE:
|
||||
status = NM_PPP_STATUS_AUTHENTICATE;
|
||||
phase = "authenticate";
|
||||
break;
|
||||
case PHASE_CALLBACK:
|
||||
status = NM_PPP_STATUS_CALLBACK;
|
||||
phase = "callback";
|
||||
break;
|
||||
case PHASE_NETWORK:
|
||||
status = NM_PPP_STATUS_NETWORK;
|
||||
phase = "network";
|
||||
break;
|
||||
case PHASE_RUNNING:
|
||||
status = NM_PPP_STATUS_RUNNING;
|
||||
phase = "running";
|
||||
break;
|
||||
case PHASE_TERMINATE:
|
||||
status = NM_PPP_STATUS_TERMINATE;
|
||||
phase = "terminate";
|
||||
break;
|
||||
case PHASE_DISCONNECT:
|
||||
status = NM_PPP_STATUS_DISCONNECT;
|
||||
phase = "disconnect";
|
||||
break;
|
||||
case PHASE_HOLDOFF:
|
||||
status = NM_PPP_STATUS_HOLDOFF;
|
||||
phase = "holdoff";
|
||||
break;
|
||||
case PHASE_MASTER:
|
||||
status = NM_PPP_STATUS_MASTER;
|
||||
phase = "master";
|
||||
break;
|
||||
|
||||
default:
|
||||
phase = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
g_message ("pppd reported new phase: %s", phase);
|
||||
|
||||
if (status != NM_PPP_STATUS_UNKNOWN) {
|
||||
DBusConnection *connection = (DBusConnection *) data;
|
||||
DBusMessage *message;
|
||||
|
||||
message = dbus_message_new_signal (NM_DBUS_PATH_PPP,
|
||||
NM_DBUS_INTERFACE_PPP,
|
||||
"Status");
|
||||
if (!message) {
|
||||
g_warning ("Couldn't allocate the dbus message");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dbus_message_append_args (message,
|
||||
DBUS_TYPE_UINT32, &status,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
g_warning ("could not append message args");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!dbus_connection_send (connection, message, NULL)) {
|
||||
g_warning ("could not send dbus message");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
dbus_message_unref (message);
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
ip4_address_as_string (guint32 ip)
|
||||
{
|
||||
struct in_addr tmp_addr;
|
||||
gchar *ip_string;
|
||||
|
||||
tmp_addr.s_addr = ip;
|
||||
ip_string = inet_ntoa (tmp_addr);
|
||||
|
||||
return ip_string;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ip_up (void *data, int arg)
|
||||
{
|
||||
DBusConnection *connection = (DBusConnection *) data;
|
||||
DBusMessage *signal;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter iter_dict;
|
||||
guint32 ip4_address;
|
||||
guint32 ip4_gateway;
|
||||
guint32 ip4_dns_1;
|
||||
guint32 ip4_dns_2;
|
||||
guint32 ip4_wins_1;
|
||||
guint32 ip4_wins_2;
|
||||
guint32 ip4_netmask = 0xFFFFFFFF; /* Default mask of 255.255.255.255 */
|
||||
|
||||
if (!ifname) {
|
||||
g_warning ("Didn't receive a tunnel device name");
|
||||
return;
|
||||
}
|
||||
|
||||
ip4_address = ipcp_gotoptions[ifunit].ouraddr;
|
||||
if (!ip4_address) {
|
||||
g_warning ("Didn't receive an internal IP from pppd");
|
||||
return;
|
||||
}
|
||||
|
||||
ip4_gateway = ipcp_gotoptions[ifunit].hisaddr;
|
||||
|
||||
ip4_dns_1 = ipcp_gotoptions[ifunit].dnsaddr[0];
|
||||
ip4_dns_2 = ipcp_gotoptions[ifunit].dnsaddr[1];
|
||||
ip4_wins_1 = ipcp_gotoptions[ifunit].winsaddr[0];
|
||||
ip4_wins_2 = ipcp_gotoptions[ifunit].winsaddr[1];
|
||||
|
||||
g_message ("Got ip configuration");
|
||||
g_message ("address: %s", ip4_address_as_string (ip4_address));
|
||||
g_message ("gateway: %s", ip4_address_as_string (ip4_gateway));
|
||||
g_message ("netmask: %s", ip4_address_as_string (ip4_netmask));
|
||||
g_message ("DNS1: %s", ip4_address_as_string (ip4_dns_1));
|
||||
g_message ("DNS2: %s", ip4_address_as_string (ip4_dns_2));
|
||||
g_message ("WINS1: %s", ip4_address_as_string (ip4_wins_1));
|
||||
g_message ("WINS2: %s", ip4_address_as_string (ip4_wins_2));
|
||||
|
||||
signal = dbus_message_new_signal (NM_DBUS_PATH_PPP,
|
||||
NM_DBUS_INTERFACE_PPP,
|
||||
"IP4Config");
|
||||
if (!signal)
|
||||
goto out;
|
||||
|
||||
dbus_message_iter_init_append (signal, &iter);
|
||||
if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) {
|
||||
g_warning ("dict open write failed!");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!nmu_dbus_dict_append_string (&iter_dict, "interface", ifname)) {
|
||||
g_warning ("couldn't append interface to dict");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!nmu_dbus_dict_append_uint32 (&iter_dict, "addres", ip4_address)) {
|
||||
g_warning ("couldn't append address to dict");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!nmu_dbus_dict_append_uint32 (&iter_dict, "netmask", ip4_netmask)) {
|
||||
g_warning ("couldn't append netmask to dict");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!nmu_dbus_dict_append_uint32 (&iter_dict, "gateway", ip4_gateway)) {
|
||||
g_warning ("couldn't append gateway to dict");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ip4_dns_1 || ip4_dns_2) {
|
||||
guint32 ip4_dns[2];
|
||||
guint32 ip4_dns_len = 0;
|
||||
|
||||
if (ip4_dns_1)
|
||||
ip4_dns[ip4_dns_len++] = ip4_dns_1;
|
||||
if (ip4_dns_2)
|
||||
ip4_dns[ip4_dns_len++] = ip4_dns_2;
|
||||
|
||||
if (!nmu_dbus_dict_append_uint32_array (&iter_dict,
|
||||
"dns_server",
|
||||
ip4_dns,
|
||||
ip4_dns_len)) {
|
||||
g_warning ("couldn't append dns_servers to dict");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (ip4_wins_1 || ip4_wins_2) {
|
||||
guint32 ip4_wins[2];
|
||||
guint32 ip4_wins_len = 0;
|
||||
|
||||
if (ip4_wins_1)
|
||||
ip4_wins[ip4_wins_len++] = ip4_wins_1;
|
||||
if (ip4_wins_2)
|
||||
ip4_wins[ip4_wins_len++] = ip4_wins_2;
|
||||
|
||||
if (!nmu_dbus_dict_append_uint32_array (&iter_dict,
|
||||
"wins_server",
|
||||
ip4_wins,
|
||||
ip4_wins_len)) {
|
||||
g_warning ("couldn't append wins_servers to dict");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nmu_dbus_dict_close_write (&iter, &iter_dict)) {
|
||||
g_warning ("dict close write failed!");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!dbus_connection_send (connection, signal, NULL)) {
|
||||
g_warning ("could not send dbus message");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (signal)
|
||||
dbus_message_unref (signal);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_exit_notify (void *data, int arg)
|
||||
{
|
||||
DBusConnection *connection = (DBusConnection *) data;
|
||||
|
||||
g_message ("exiting");
|
||||
|
||||
if (connection)
|
||||
dbus_connection_unref (connection);
|
||||
}
|
||||
|
||||
static DBusConnection *
|
||||
nm_dbus_prepare_connection (void)
|
||||
{
|
||||
DBusConnection *connection;
|
||||
DBusError err;
|
||||
|
||||
dbus_error_init (&err);
|
||||
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &err);
|
||||
if (!connection || dbus_error_is_set (&err)) {
|
||||
g_warning ("Could not get the system bus. Make sure the message bus daemon is running.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
dbus_connection_set_exit_on_disconnect (connection, FALSE);
|
||||
|
||||
dbus_error_init (&err);
|
||||
dbus_bus_request_name (connection, NM_DBUS_SERVICE_PPP, 0, &err);
|
||||
if (dbus_error_is_set (&err)) {
|
||||
g_warning ("Could not acquire the dbus service. dbus_bus_request_name() says: '%s'.", err.message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (dbus_error_is_set (&err)) {
|
||||
dbus_error_free (&err);
|
||||
connection = NULL;
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
plugin_init (void)
|
||||
{
|
||||
DBusConnection *connection;
|
||||
|
||||
connection = nm_dbus_prepare_connection ();
|
||||
if (connection) {
|
||||
add_notifier (&phasechange, nm_phasechange, connection);
|
||||
add_notifier (&ip_up_notifier, nm_ip_up, connection);
|
||||
add_notifier (&exitnotify, nm_exit_notify, connection);
|
||||
}
|
||||
|
||||
return connection ? 0 : -1;
|
||||
}
|
3
src/ppp-manager/nm-pppd-plugin.h
Normal file
3
src/ppp-manager/nm-pppd-plugin.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#define NM_DBUS_SERVICE_PPP "org.freedesktop.NetworkManager.PPP"
|
||||
#define NM_DBUS_PATH_PPP "/org/freedesktop/NetworkManager/PPP"
|
||||
#define NM_DBUS_INTERFACE_PPP "org.freedesktop.NetworkManager.PPP"
|
Reference in New Issue
Block a user