2005-02-13 Dan Williams <dcbw@redhat.com>
Patch from Dan Reed: DHCP options D-BUS API Exposes the DHCP options that a device receives to clients over D-BUS. * configure.in - A few cleanups * dhcpcd/client.h - Correct names, option length, and types for DHCP options * dhcpcd/dhcpcd.[ch] - Clarify function names that access DHCP options & data * src/NetworkManagerDHCP.c - Use new DHCP data access functions * src/NetworkManagerDbus.c - Message handler for DHCP functions * src/nm-dbus-dhcp.[ch] (new) - DHCP dbus methods * test/nm-dhcp-opt-test.c - Test DHCP D-BUS API and return all present DHCP options git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@444 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
26
ChangeLog
26
ChangeLog
@@ -1,3 +1,29 @@
|
||||
2005-02-13 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
Patch from Dan Reed: DHCP options D-BUS API
|
||||
Exposes the DHCP options that a device receives to clients over D-BUS.
|
||||
|
||||
* configure.in
|
||||
- A few cleanups
|
||||
|
||||
* dhcpcd/client.h
|
||||
- Correct names, option length, and types for DHCP options
|
||||
|
||||
* dhcpcd/dhcpcd.[ch]
|
||||
- Clarify function names that access DHCP options & data
|
||||
|
||||
* src/NetworkManagerDHCP.c
|
||||
- Use new DHCP data access functions
|
||||
|
||||
* src/NetworkManagerDbus.c
|
||||
- Message handler for DHCP functions
|
||||
|
||||
* src/nm-dbus-dhcp.[ch] (new)
|
||||
- DHCP dbus methods
|
||||
|
||||
* test/nm-dhcp-opt-test.c
|
||||
- Test DHCP D-BUS API and return all present DHCP options
|
||||
|
||||
2005-02-12 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* test/Makefile.am
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
|
||||
#define NM_DBUS_PATH_DEVICES "/org/freedesktop/NetworkManager/Devices"
|
||||
#define NM_DBUS_INTERFACE_DEVICES "org.freedesktop.NetworkManager.Devices"
|
||||
#define NM_DBUS_PATH_DHCP "/org/freedesktop/NetworkManager/DhcpOptions"
|
||||
#define NM_DBUS_INTERFACE_DHCP "org.freedesktop.NetworkManager.DhcpOptions"
|
||||
|
||||
#define NMI_DBUS_SERVICE "org.freedesktop.NetworkManagerInfo"
|
||||
#define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo"
|
||||
|
35
configure.in
35
configure.in
@@ -39,17 +39,7 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])
|
||||
ALL_LINGUAS="bs cs da de el en_CA es gu ja nb nl no pa pt_BR sk sq sv wa zh_CN"
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
AC_ARG_WITH(distro,
|
||||
[
|
||||
--with-distro: Specify the Linux distribution to target with distro-specific
|
||||
parts of NetworkManager
|
||||
--with-distro=redhat
|
||||
--with-distro=gentoo
|
||||
--with-distro=debian
|
||||
--with-distro=mandrake
|
||||
--with-distro=slackware
|
||||
],,)
|
||||
|
||||
AC_ARG_WITH(distro, AC_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, gentoo, debian, or slackware]))
|
||||
if test "z$with_distro" = "z"; then
|
||||
AC_CHECK_FILE(/etc/mandrake-release,with_distro="mandrake")
|
||||
AC_CHECK_FILE(/etc/redhat-release,with_distro="redhat")
|
||||
@@ -61,13 +51,13 @@ fi
|
||||
with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' `
|
||||
|
||||
if test "z$with_distro" = "z"; then
|
||||
echo "Linux distribution autodetection failed, you must specify the distribution to target using --with-distro=<distro>"
|
||||
echo "Linux distribution autodetection failed, you must specify the distribution to target using --with-distro=DISTRO"
|
||||
exit 1
|
||||
else
|
||||
case $with_distro in
|
||||
redhat|gentoo|debian|slackware) ;;
|
||||
*)
|
||||
echo "Your distribution(${with_distro}) is not yet supported! (patches welcome)"
|
||||
echo "Your distribution (${with_distro}) is not yet supported! (patches welcome)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -148,7 +138,7 @@ PKG_CHECK_MODULES(GNOME_KEYRING, gnome-keyring-1)
|
||||
AC_SUBST(GNOME_KEYRING_CFLAGS)
|
||||
AC_SUBST(GNOME_KEYRING_LIBS)
|
||||
|
||||
AC_ARG_WITH(gcrypt, [--with-gcrypt Use gcrypt library], ac_gcrypt=$withval, ac_gcrypt=auto)
|
||||
AC_ARG_WITH(gcrypt, AC_HELP_STRING([--with-gcrypt], [Use gcrypt library]), ac_gcrypt=$withval, ac_gcrypt=auto)
|
||||
if test x"$ac_gcrypt" != xno; then
|
||||
AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
|
||||
else
|
||||
@@ -175,11 +165,10 @@ AC_SUBST(PANEL_APPLET_CFLAGS)
|
||||
AC_SUBST(PANEL_APPLET_LIBS)
|
||||
|
||||
PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0)
|
||||
AC_SUBST(LIBGNOMEUI_CFLAFS)
|
||||
AC_SUBST(LIBGNOMEUI_CFLAGS) # is this even needed? it was typed incorrectly before
|
||||
AC_SUBST(LIBGNOMEUI_LIBS)
|
||||
|
||||
# taken from hal
|
||||
AC_ARG_WITH(dbus-sys, [ --with-dbus-sys=<dir> where D-BUS system.d directory is])
|
||||
AC_ARG_WITH(dbus-sys, AC_HELP_STRING([--with-dbus-sys=DIR], [where D-BUS system.d directory is]))
|
||||
|
||||
if ! test -z "$with_dbus_sys" ; then
|
||||
DBUS_SYS_DIR="$with_dbus_sys"
|
||||
@@ -189,9 +178,9 @@ fi
|
||||
AC_SUBST(DBUS_SYS_DIR)
|
||||
AC_DEFINE_UNQUOTED(DBUS_SYSTEMD_DIR, "$DBUS_SYS_DIR", [Where system.d dir for DBUS is])
|
||||
|
||||
AC_ARG_WITH(named, AC_HELP_STRING([--with-named=<path>], [path to the named binary]))
|
||||
AC_ARG_WITH(named_dir, AC_HELP_STRING([--with-named-dir=<path>], [path to the named data directory]))
|
||||
AC_ARG_WITH(named_user, AC_HELP_STRING([--with-named-user=username], [named username]))
|
||||
AC_ARG_WITH(named, AC_HELP_STRING([--with-named=PATH], [path to the named binary]))
|
||||
AC_ARG_WITH(named_dir, AC_HELP_STRING([--with-named-dir=PATH], [path to the named data directory]))
|
||||
AC_ARG_WITH(named_user, AC_HELP_STRING([--with-named-user=USERNAME], [named username]))
|
||||
if test "x${with_named}" = x; then
|
||||
AC_DEFINE(NM_NO_NAMED,,[Define if you want to disable named support])
|
||||
fi
|
||||
@@ -199,7 +188,7 @@ AC_DEFINE_UNQUOTED(NM_NAMED_BINARY_PATH, "$with_named", [Define to path of named
|
||||
AC_DEFINE_UNQUOTED(NM_NAMED_DATA_DIR, "$with_named_dir", [Define to path of named data directory])
|
||||
AC_DEFINE_UNQUOTED(NM_NAMED_USER, "$with_named_user", [Define to named username])
|
||||
|
||||
AC_ARG_ENABLE(notification-icon, [ --enable-notification-icon builds the wireless applet as a notification icon], enable_notification_icon=$enableval, enable_notification_icon=yes)
|
||||
AC_ARG_ENABLE(notification-icon, AC_HELP_STRING([--enable-notification-icon], [builds the wireless applet as a notification icon]), enable_notification_icon=$enableval, enable_notification_icon=yes)
|
||||
|
||||
AM_CONDITIONAL(BUILD_NOTIFICATION_ICON, test x$enable_notification_icon = xyes)
|
||||
if test x$enable_notification_icon == xyes ; then
|
||||
@@ -240,7 +229,7 @@ prefix=$old_prefix
|
||||
exec_prefix=$old_exec_prefix
|
||||
|
||||
AC_ARG_ENABLE(more-warnings,
|
||||
[ --enable-more-warnings Maximum compiler warnings],
|
||||
AC_HELP_STRING([--enable-more-warnings], [Maximum compiler warnings]),
|
||||
set_more_warnings="$enableval",[
|
||||
if test -d "$srcdir/{arch}" || test -d "$srcdir/CVS"; then
|
||||
set_more_warnings=yes
|
||||
@@ -295,4 +284,4 @@ libnm_glib/libnm_glib.pc
|
||||
|
||||
echo
|
||||
echo Distribution targeting: ${with_distro}
|
||||
echo 'if this is not correct, please specifiy your distro with --with-distro=<distro>'
|
||||
echo 'if this is not correct, please specifiy your distro with --with-distro=DISTRO'
|
||||
|
198
dhcpcd/client.h
198
dhcpcd/client.h
@@ -83,9 +83,9 @@ typedef struct dhcpMessage
|
||||
|
||||
typedef struct dhcpOptions
|
||||
{
|
||||
u_char num;
|
||||
u_char len[256];
|
||||
void *val[256];
|
||||
u_char num;
|
||||
} __attribute__((packed)) dhcpOptions;
|
||||
|
||||
struct packed_ether_header
|
||||
@@ -132,75 +132,145 @@ typedef struct dhcp_interface
|
||||
|
||||
typedef struct dhcp_option_table
|
||||
{
|
||||
const int option;
|
||||
const char *name;
|
||||
const int len;
|
||||
const int len_hint;
|
||||
dhcp_option_type type;
|
||||
} dhcp_option_table;
|
||||
|
||||
static dhcp_option_table dhcp_opt_table[] =
|
||||
{
|
||||
{ padOption, "padOption", 1 },
|
||||
{ subnetMask, "subnetMask", 4 },
|
||||
{ timerOffset, "timerOffset", -1 },
|
||||
{ routersOnSubnet, "routersOnSubnet", 4 },
|
||||
{ timeServer, "timeServer", 4 },
|
||||
{ nameServer, "nameServer", 4 },
|
||||
{ dns, "dns", 4 },
|
||||
{ logServer, "logServer", 4 },
|
||||
{ cookieServer, "cookieServer", 4 },
|
||||
{ lprServer, "lprServer", 4 },
|
||||
{ impressServer, "impressServer", 4 },
|
||||
{ resourceLocationServer,"resourceLocationServer",4 },
|
||||
{ hostName, "hostName", -1 },
|
||||
{ bootFileSize, "bootFileSize", 4 },
|
||||
{ meritDumpFile, "meritDumpFile", 4 },
|
||||
{ domainName, "domainName", -1 },
|
||||
{ swapServer, "swapServer", 4 },
|
||||
{ rootPath, "rootPath", -1 },
|
||||
{ extentionsPath, "extentionsPath", -1 },
|
||||
{ IPforwarding, "IPforwarding", -1 },
|
||||
{ nonLocalSourceRouting, "nonLocalSourceRouting", -1 },
|
||||
{ policyFilter, "policyFilter", -1 },
|
||||
{ maxDgramReasmSize, "maxDgramReasmSize", -1 },
|
||||
{ defaultIPTTL, "defaultIPTTL", -1 },
|
||||
{ pathMTUagingTimeout, "pathMTUagingTimeout", -1 },
|
||||
{ pathMTUplateauTable, "pathMTUplateauTable", -1 },
|
||||
{ ifMTU, "ifMTU", -1 },
|
||||
{ allSubnetsLocal, "allSubnetsLocal", -1 },
|
||||
{ broadcastAddr, "broadcastAddr", 4 },
|
||||
{ performMaskDiscovery, "performMaskDiscovery", -1 },
|
||||
{ routerSolicitationAddr,"routerSolicitationAddr",-1 },
|
||||
{ staticRoute, "staticRoute", 4 },
|
||||
{ trailerEncapsulation, "trailerEncapsulation", -1 },
|
||||
{ arpCacheTimeout, "arpCacheTimeout", -1 },
|
||||
{ ethernetEncapsulation, "ethernetEncapsulation", -1 },
|
||||
{ tcpDefaultTTL, "tcpDefaultTTL", -1 },
|
||||
{ tcpKeepaliveInterval, "tcpKeepaliveInterval", -1 },
|
||||
{ tcpKeepaliveGarbage, "tcpKeepaliveGarbage", -1 },
|
||||
{ nisDomainName, "nisDomainName", -1 },
|
||||
{ nisServers, "nisServers", 4 },
|
||||
{ ntpServers, "ntpServers", 4 },
|
||||
{ vendorSpecificInfo, "vendorSpecificInfo", -1 },
|
||||
{ netBIOSnameServer, "netBIOSnameServer", -1 },
|
||||
{ netBIOSdgramDistServer,"netBIOSdgramDistServer",-1 },
|
||||
{ netBIOSnodeType, "netBIOSnodeType", -1 },
|
||||
{ netBIOSscope, "netBIOSscope", -1 },
|
||||
{ xFontServer, "xFontServer", -1 },
|
||||
{ xDisplayManager, "xDisplayManager", -1 },
|
||||
{ dhcpRequestedIPaddr, "dhcpRequestedIPaddr", 4 },
|
||||
{ dhcpIPaddrLeaseTime, "dhcpIPaddrLeaseTime", 4 },
|
||||
{ dhcpOptionOverload, "dhcpOptionOverload", -1 },
|
||||
{ dhcpMessageType, "dhcpMessageType", -1 },
|
||||
{ dhcpServerIdentifier, "dhcpServerIdentifier", -1 },
|
||||
{ dhcpParamRequest, "dhcpParamRequest", -1 },
|
||||
{ dhcpMsg, "dhcpMsg", -1 },
|
||||
{ dhcpMaxMsgSize, "dhcpMaxMsgSize", -1 },
|
||||
{ dhcpT1value, "dhcpT1value", 4 },
|
||||
{ dhcpT2value, "dhcpT2value", 4 },
|
||||
{ dhcpClassIdentifier, "dhcpClassIdentifier", -1 },
|
||||
{ dhcpClientIdentifier, "dhcpClientIdentifier", -1 },
|
||||
{ -1, NULL, -1 }
|
||||
/* Names come from http://www.iana.org/assignments/bootp-dhcp-parameters, not to be changed */
|
||||
|
||||
/* 0 */ { "Pad", 0, DHCP_OPT_INVALID },
|
||||
/* 1 */ { "Subnet Mask", 4, DHCP_OPT_ADDRESS },
|
||||
/* 2 */ { "Time Offset", 4, DHCP_OPT_TIME },
|
||||
/* 3 */ { "Router", 4, DHCP_OPT_ADDRESS },
|
||||
/* 4 */ { "Time Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 5 */ { "Name Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 6 */ { "Domain Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 7 */ { "Log Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 8 */ { "Quotes Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 9 */ { "LPR Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 10 */ { "Impress Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 11 */ { "RLP Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 12 */ { "Hostname", 1, DHCP_OPT_STRING },
|
||||
/* 13 */ { "Boot File Size", 2, DHCP_OPT_COUNT },
|
||||
/* 14 */ { "Merit Dump File", 1, DHCP_OPT_STRING },
|
||||
/* 15 */ { "Domain Name", 1, DHCP_OPT_STRING },
|
||||
/* 16 */ { "Swap Server", 1, DHCP_OPT_ADDRESS },
|
||||
/* 17 */ { "Root Path", 1, DHCP_OPT_STRING },
|
||||
/* 18 */ { "Extension Path", 1, DHCP_OPT_STRING },
|
||||
/* 19 */ { "Forward On/Off", 1, DHCP_OPT_TOGGLE },
|
||||
/* 20 */ { "SrcRte On/Off", 1, DHCP_OPT_TOGGLE },
|
||||
/* 21 */ { "Policy Filter", 1, DHCP_OPT_BLOB },
|
||||
/* 22 */ { "Max DG Assembly", 2, DHCP_OPT_COUNT },
|
||||
/* 23 */ { "Default IP TTL", 1, DHCP_OPT_COUNT },
|
||||
/* 24 */ { "MTU Timeout", 4, DHCP_OPT_TIME },
|
||||
/* 25 */ { "MTU Plateau", 1, DHCP_OPT_BLOB },
|
||||
/* 26 */ { "MTU Interface", 2, DHCP_OPT_COUNT },
|
||||
/* 27 */ { "MTU Subnet", 1, DHCP_OPT_TOGGLE },
|
||||
/* 28 */ { "Broadcast Address", 4, DHCP_OPT_ADDRESS },
|
||||
/* 29 */ { "Mask Discovery", 1, DHCP_OPT_TOGGLE },
|
||||
/* 30 */ { "Mask Supplier", 1, DHCP_OPT_TOGGLE },
|
||||
/* 31 */ { "Router Discovery", 1, DHCP_OPT_TOGGLE },
|
||||
/* 32 */ { "Router Request", 4, DHCP_OPT_ADDRESS },
|
||||
/* 33 */ { "Static Route", 1, DHCP_OPT_BLOB },
|
||||
/* 34 */ { "Trailers", 1, DHCP_OPT_TOGGLE },
|
||||
/* 35 */ { "ARP Timeout", 4, DHCP_OPT_TIME },
|
||||
/* 36 */ { "Ethernet", 1, DHCP_OPT_BLOB },
|
||||
/* 37 */ { "Default TCP TTL", 1, DHCP_OPT_COUNT},
|
||||
/* 38 */ { "Keepalive Time", 4, DHCP_OPT_TIME },
|
||||
/* 39 */ { "Keepalive Data", 1, DHCP_OPT_BLOB },
|
||||
/* 40 */ { "NIS Domain", 1, DHCP_OPT_STRING },
|
||||
/* 41 */ { "NIS Servers", 4, DHCP_OPT_ADDRESS },
|
||||
/* 42 */ { "NTP Servers", 4, DHCP_OPT_ADDRESS },
|
||||
/* 43 */ { "Vendor Specific", 1, DHCP_OPT_BLOB },
|
||||
/* 44 */ { "NETBIOS Name Srv", 4, DHCP_OPT_ADDRESS },
|
||||
/* 45 */ { "NETBIOS Dist Srv", 4, DHCP_OPT_ADDRESS },
|
||||
/* 46 */ { "NETBIOS Node Type", 1, DHCP_OPT_NUMBER },
|
||||
/* 47 */ { "NETBIOS Scope", 1, DHCP_OPT_NUMBER },
|
||||
/* 48 */ { "X Window Font", 4, DHCP_OPT_ADDRESS },
|
||||
/* 49 */ { "X Window Manager", 4, DHCP_OPT_ADDRESS },
|
||||
/* 50 */ { "Address Request", 4, DHCP_OPT_ADDRESS },
|
||||
/* 51 */ { "Address Time", 4, DHCP_OPT_TIME },
|
||||
/* 52 */ { "Overload", 1, DHCP_OPT_BLOB },
|
||||
/* 53 */ { "DHCP Msg Type", 1, DHCP_OPT_NUMBER },
|
||||
/* 54 */ { "DHCP Server Id", 4, DHCP_OPT_ADDRESS },
|
||||
/* 55 */ { "Parameter List", 1, DHCP_OPT_BLOB },
|
||||
/* 56 */ { "DHCP Message", 1, DHCP_OPT_BLOB },
|
||||
/* 57 */ { "DHCP Max Msg Size", 2, DHCP_OPT_COUNT },
|
||||
/* 58 */ { "Renewal Time", 4, DHCP_OPT_TIME },
|
||||
/* 59 */ { "Rebinding Time", 4, DHCP_OPT_TIME },
|
||||
/* 60 */ { "Class Id", 1, DHCP_OPT_BLOB },
|
||||
/* 61 */ { "Client Id", 1, DHCP_OPT_BLOB },
|
||||
/* 62 */ { "NetWare/IP Domain", 1, DHCP_OPT_STRING },
|
||||
/* 63 */ { "NetWare/IP Option", 1, DHCP_OPT_BLOB },
|
||||
/* 64 */ { "NIS-Domain-Name", 1, DHCP_OPT_STRING },
|
||||
/* 65 */ { "NIS-Server-Addr", 4, DHCP_OPT_ADDRESS },
|
||||
/* 66 */ { "Server-Name", 1, DHCP_OPT_STRING },
|
||||
/* 67 */ { "Bootfile-Name", 1, DHCP_OPT_STRING },
|
||||
/* 68 */ { "Home-Agent-Addrs", 4, DHCP_OPT_ADDRESS },
|
||||
/* 69 */ { "SMTP-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 70 */ { "POP3-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 71 */ { "NNTP-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 72 */ { "WWW-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 73 */ { "Finger-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 74 */ { "IRC-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 75 */ { "StreetTalk-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 76 */ { "STDA-Server", 4, DHCP_OPT_ADDRESS },
|
||||
/* 77 */ { "User-Class", 1, DHCP_OPT_BLOB },
|
||||
/* 78 */ { "Directory Agent", 1, DHCP_OPT_BLOB },
|
||||
/* 79 */ { "Service Scope", 1, DHCP_OPT_BLOB },
|
||||
/* 80 */ { "Rapid Commit", 0, DHCP_OPT_BLOB },
|
||||
/* 81 */ { "Client FQDN", 1, DHCP_OPT_STRING },
|
||||
/* 82 */ { "Relay Agent Information", 1, DHCP_OPT_BLOB },
|
||||
/* 83 */ { "iSNS", 1, DHCP_OPT_BLOB },
|
||||
/* 84 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 85 */ { "NDS Servers", 4, DHCP_OPT_ADDRESS },
|
||||
/* 86 */ { "NDS Tree Name", 1, DHCP_OPT_BLOB },
|
||||
/* 87 */ { "NDS Context", 1, DHCP_OPT_BLOB },
|
||||
/* 88 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 89 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 90 */ { "Authentication", 1, DHCP_OPT_BLOB },
|
||||
/* 91 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 92 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 93 */ { "Client System", 1, DHCP_OPT_BLOB },
|
||||
/* 94 */ { "Client NDI", 1, DHCP_OPT_BLOB },
|
||||
/* 95 */ { "LDAP", 1, DHCP_OPT_BLOB },
|
||||
/* 96 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 97 */ { "UUID/GUID", 1, DHCP_OPT_BLOB },
|
||||
/* 98 */ { "User-Auth", 1, DHCP_OPT_BLOB },
|
||||
/* 99 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 100 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 101 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 102 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 103 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 104 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 105 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 106 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 107 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 108 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 109 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 110 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 111 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 112 */ { "Netinfo Address", 1, DHCP_OPT_BLOB },
|
||||
/* 113 */ { "Netinfo Tag", 1, DHCP_OPT_BLOB },
|
||||
/* 114 */ { "URL", 1, DHCP_OPT_STRING },
|
||||
/* 115 */ { NULL, 1, DHCP_OPT_BLOB },
|
||||
/* 116 */ { "Auto-Config", 1, DHCP_OPT_BLOB },
|
||||
/* 117 */ { "Name Service Search", 1, DHCP_OPT_BLOB },
|
||||
/* 118 */ { "Subnet Selection Option", 4, DHCP_OPT_BLOB },
|
||||
/* 119 */ { "Domain Search", 1, DHCP_OPT_STRING },
|
||||
/* 120 */ { "SIP Servers DHCP Option", 1, DHCP_OPT_BLOB },
|
||||
/* 121 */ { "Classless Static Route Option", 1, DHCP_OPT_BLOB },
|
||||
/* 122 */ { "CCC", 1, DHCP_OPT_BLOB },
|
||||
/* 123 */ { "GeoConf Option", 16, DHCP_OPT_BLOB },
|
||||
/* 124 */ { "V-I Vendor Class", 1, DHCP_OPT_BLOB },
|
||||
/* 125 */ { "V-I Vendor-Specific Information", 1, DHCP_OPT_BLOB },
|
||||
/* 126 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
/* 127 */ { NULL, 0, DHCP_OPT_INVALID },
|
||||
};
|
||||
static const int dhcp_opt_table_len = sizeof(dhcp_opt_table)/sizeof(*dhcp_opt_table);
|
||||
|
||||
typedef udpipMessage *(*dhcp_msg_build_proc)(dhcp_interface *, int *msg_len);
|
||||
|
||||
|
@@ -260,7 +260,7 @@ void dhcp_interface_cease (dhcp_interface *iface)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int dhcp_interface_dhcp_field_exists (dhcp_interface *iface, int val)
|
||||
int dhcp_interface_option_present (dhcp_interface *iface, int val)
|
||||
{
|
||||
if (!iface) return 0;
|
||||
|
||||
@@ -268,7 +268,7 @@ int dhcp_interface_dhcp_field_exists (dhcp_interface *iface, int val)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void *dhcp_interface_get_dhcp_field (dhcp_interface *iface, int val)
|
||||
void *dhcp_interface_option_payload (dhcp_interface *iface, int val)
|
||||
{
|
||||
if (!iface) return 0;
|
||||
|
||||
@@ -276,7 +276,7 @@ void *dhcp_interface_get_dhcp_field (dhcp_interface *iface, int val)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int dhcp_interface_get_dhcp_field_len (dhcp_interface *iface, int val)
|
||||
int dhcp_interface_option_len (dhcp_interface *iface, int val)
|
||||
{
|
||||
if (!iface) return 0;
|
||||
|
||||
@@ -284,11 +284,61 @@ int dhcp_interface_get_dhcp_field_len (dhcp_interface *iface, int val)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int dhcp_individual_value_len (int val)
|
||||
int dhcp_option_record_len (int val)
|
||||
{
|
||||
if (val <= dhcpClientIdentifier)
|
||||
return (dhcp_opt_table[val].len);
|
||||
if ((val >= 0) && (val < dhcp_opt_table_len))
|
||||
return (dhcp_opt_table[val].len_hint);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
const char *dhcp_option_name (int val)
|
||||
{
|
||||
if ((val >= 0) && (val < dhcp_opt_table_len))
|
||||
return (dhcp_opt_table[val].name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
dhcp_option_type dhcp_option_record_type (int val)
|
||||
{
|
||||
if ((val >= 0) && (val < dhcp_opt_table_len))
|
||||
return (dhcp_opt_table[val].type);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* case-insensitive alpha/num string comparison; skips over white space and punctuation */
|
||||
static int dhcp_strcmp (const unsigned char *s1, const unsigned char *s2)
|
||||
{
|
||||
while (!isalnum(*s1) && (*s1 != 0))
|
||||
s1++;
|
||||
while (!isalnum(*s2) && (*s2 != 0))
|
||||
s2++;
|
||||
while (*s1 != 0) {
|
||||
if (tolower(*s1) != tolower(*s2))
|
||||
return ((tolower(*s1) < tolower(*s2))?-1:1);
|
||||
s1++;
|
||||
s2++;
|
||||
while (!isalnum(*s1) && (*s1 != 0))
|
||||
s1++;
|
||||
while (!isalnum(*s2) && (*s2 != 0))
|
||||
s2++;
|
||||
}
|
||||
if (*s2 != 0)
|
||||
return ((tolower(*s1) < tolower(*s2))?-1:1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int dhcp_option_id_by_name (const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dhcp_opt_table_len; i++)
|
||||
if ((dhcp_opt_table[i].name != NULL) && (dhcp_strcmp (name, dhcp_opt_table[i].name) == 0))
|
||||
return (i);
|
||||
return (-1);
|
||||
}
|
||||
|
@@ -99,6 +99,18 @@ enum
|
||||
endOption = 255
|
||||
};
|
||||
|
||||
typedef enum dhcp_option_type
|
||||
{
|
||||
DHCP_OPT_INVALID,
|
||||
DHCP_OPT_ADDRESS,
|
||||
DHCP_OPT_TIME,
|
||||
DHCP_OPT_STRING,
|
||||
DHCP_OPT_COUNT,
|
||||
DHCP_OPT_TOGGLE,
|
||||
DHCP_OPT_BLOB,
|
||||
DHCP_OPT_NUMBER,
|
||||
} dhcp_option_type;
|
||||
|
||||
/* Return codes */
|
||||
#define RET_DHCP_ERROR 0
|
||||
#define RET_DHCP_ADDRESS_IN_USE 1
|
||||
@@ -126,9 +138,12 @@ struct dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_opt
|
||||
void dhcp_interface_free (struct dhcp_interface *iface);
|
||||
void dhcp_interface_cease (struct dhcp_interface *iface);
|
||||
|
||||
int dhcp_interface_dhcp_field_exists (struct dhcp_interface *iface, int val);
|
||||
int dhcp_interface_get_dhcp_field_len (struct dhcp_interface *iface, int val);
|
||||
void *dhcp_interface_get_dhcp_field (struct dhcp_interface *iface, int val);
|
||||
int dhcp_individual_value_len (int val);
|
||||
int dhcp_interface_option_present (struct dhcp_interface *iface, int val);
|
||||
int dhcp_interface_option_len (struct dhcp_interface *iface, int val);
|
||||
void *dhcp_interface_option_payload (struct dhcp_interface *iface, int val);
|
||||
int dhcp_option_record_len (int val);
|
||||
dhcp_option_type dhcp_option_record_type (int val);
|
||||
int dhcp_option_id_by_name (const char *name);
|
||||
const char * dhcp_option_name (int val);
|
||||
|
||||
#endif
|
||||
|
@@ -13,12 +13,16 @@ NetworkManager_SOURCES = \
|
||||
NetworkManagerDbus.h \
|
||||
NetworkManagerDbusUtils.c \
|
||||
NetworkManagerDbusUtils.h \
|
||||
nm-dbus-nm.h \
|
||||
nm-dbus-nm.c \
|
||||
nm-dbus-device.h \
|
||||
nm-dbus-nm.h \
|
||||
nm-dbus-device.c \
|
||||
nm-dbus-net.h \
|
||||
nm-dbus-device.h \
|
||||
nm-dbus-net.c \
|
||||
nm-dbus-net.h \
|
||||
nm-dbus-dhcp.c \
|
||||
nm-dbus-dhcp.h \
|
||||
nm-dbus-nmi.c \
|
||||
nm-dbus-nmi.h \
|
||||
NetworkManagerDHCP.c \
|
||||
NetworkManagerDHCP.h \
|
||||
NetworkManagerDevice.c \
|
||||
|
@@ -127,31 +127,31 @@ static void nm_device_dhcp_configure (NMDevice *dev)
|
||||
/* Replace basic info */
|
||||
nm_system_device_set_ip4_address (dev, dev->dhcp_iface->ciaddr);
|
||||
|
||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, subnetMask))
|
||||
if (dhcp_interface_option_present (dev->dhcp_iface, subnetMask))
|
||||
{
|
||||
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, subnetMask), dhcp_individual_value_len (subnetMask));
|
||||
memcpy (&temp, dhcp_interface_option_payload (dev->dhcp_iface, subnetMask), dhcp_option_record_len (subnetMask));
|
||||
nm_system_device_set_ip4_netmask (dev, temp);
|
||||
}
|
||||
|
||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, broadcastAddr))
|
||||
if (dhcp_interface_option_present (dev->dhcp_iface, broadcastAddr))
|
||||
{
|
||||
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, broadcastAddr), dhcp_individual_value_len (broadcastAddr));
|
||||
memcpy (&temp, dhcp_interface_option_payload (dev->dhcp_iface, broadcastAddr), dhcp_option_record_len (broadcastAddr));
|
||||
nm_system_device_set_ip4_broadcast (dev, temp);
|
||||
}
|
||||
|
||||
/* Default route */
|
||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, routersOnSubnet))
|
||||
if (dhcp_interface_option_present (dev->dhcp_iface, routersOnSubnet))
|
||||
{
|
||||
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, routersOnSubnet), dhcp_individual_value_len (routersOnSubnet));
|
||||
memcpy (&temp, dhcp_interface_option_payload (dev->dhcp_iface, routersOnSubnet), dhcp_option_record_len (routersOnSubnet));
|
||||
nm_system_device_set_ip4_default_route (dev, temp);
|
||||
}
|
||||
|
||||
/* Update /etc/resolv.conf */
|
||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, dns))
|
||||
set_nameservers (dev, dhcp_interface_get_dhcp_field (dev->dhcp_iface, dns), dhcp_interface_get_dhcp_field_len (dev->dhcp_iface, dns));
|
||||
if (dhcp_interface_option_present (dev->dhcp_iface, dns))
|
||||
set_nameservers (dev, dhcp_interface_option_payload (dev->dhcp_iface, dns), dhcp_interface_option_len (dev->dhcp_iface, dns));
|
||||
|
||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, domainName))
|
||||
set_domain_search (dev, dhcp_interface_get_dhcp_field (dev->dhcp_iface, domainName));
|
||||
if (dhcp_interface_option_present (dev->dhcp_iface, domainName))
|
||||
set_domain_search (dev, dhcp_interface_option_payload (dev->dhcp_iface, domainName));
|
||||
}
|
||||
|
||||
|
||||
@@ -263,14 +263,14 @@ gboolean nm_device_dhcp_setup_timeouts (NMDevice *dev)
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
|
||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, dhcpT1value))
|
||||
if (dhcp_interface_option_present (dev->dhcp_iface, dhcpT1value))
|
||||
{
|
||||
memcpy (&t1, dhcp_interface_get_dhcp_field (dev->dhcp_iface, dhcpT1value), sizeof (int));
|
||||
memcpy (&t1, dhcp_interface_option_payload (dev->dhcp_iface, dhcpT1value), sizeof (int));
|
||||
t1 = ntohl (t1);
|
||||
}
|
||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, dhcpT2value))
|
||||
if (dhcp_interface_option_present (dev->dhcp_iface, dhcpT2value))
|
||||
{
|
||||
memcpy (&t2, dhcp_interface_get_dhcp_field (dev->dhcp_iface, dhcpT2value), sizeof (int));
|
||||
memcpy (&t2, dhcp_interface_option_payload (dev->dhcp_iface, dhcpT2value), sizeof (int));
|
||||
t2 = ntohl (t2);
|
||||
}
|
||||
if (!t1 || !t2)
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "nm-dbus-nm.h"
|
||||
#include "nm-dbus-device.h"
|
||||
#include "nm-dbus-net.h"
|
||||
#include "nm-dbus-dhcp.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -979,6 +980,41 @@ static DBusHandlerResult nm_dbus_devices_message_handler (DBusConnection *connec
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_dbus_dhcp_message_handler
|
||||
*
|
||||
* Dispatch messages against our NetworkManager DHCP object
|
||||
*
|
||||
* All calls are in the form /NM_DBUS_PATH_DHCP->METHOD (STRING attribute)
|
||||
* For example, /org/freedesktop/NetworkManager/DhcpOptions->getType ("Name Server")
|
||||
*
|
||||
*/
|
||||
static DBusHandlerResult nm_dbus_dhcp_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
|
||||
{
|
||||
NMData *data = (NMData *)user_data;
|
||||
gboolean handled = TRUE;
|
||||
DBusMessage *reply = NULL;
|
||||
NMDbusCBData cb_data;
|
||||
|
||||
g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
||||
g_return_val_if_fail (data->dhcp_methods != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
||||
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
||||
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
||||
|
||||
cb_data.data = data;
|
||||
cb_data.dev = NULL;
|
||||
cb_data.opt_id = -1;
|
||||
handled = nm_dbus_method_dispatch (data->dhcp_methods, connection, message, &cb_data, &reply);
|
||||
if (reply)
|
||||
{
|
||||
dbus_connection_send (connection, reply, NULL);
|
||||
dbus_message_unref (reply);
|
||||
}
|
||||
|
||||
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_dbus_is_info_daemon_running
|
||||
*
|
||||
@@ -1008,22 +1044,22 @@ gboolean nm_dbus_is_info_daemon_running (DBusConnection *connection)
|
||||
*/
|
||||
DBusConnection *nm_dbus_init (NMData *data)
|
||||
{
|
||||
DBusError dbus_error;
|
||||
DBusError error;
|
||||
dbus_bool_t success;
|
||||
DBusConnection *connection;
|
||||
DBusObjectPathVTable nm_vtable = {NULL, &nm_dbus_nm_message_handler, NULL, NULL, NULL, NULL};
|
||||
DBusObjectPathVTable devices_vtable = {NULL, &nm_dbus_devices_message_handler, NULL, NULL, NULL, NULL};
|
||||
DBusObjectPathVTable dhcp_vtable = {NULL, &nm_dbus_dhcp_message_handler, NULL, NULL, NULL, NULL};
|
||||
|
||||
dbus_connection_set_change_sigpipe (TRUE);
|
||||
|
||||
dbus_error_init (&dbus_error);
|
||||
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
|
||||
if ((connection == NULL) || dbus_error_is_set (&dbus_error))
|
||||
dbus_error_init (&error);
|
||||
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
|
||||
if ((connection == NULL) || dbus_error_is_set (&error))
|
||||
{
|
||||
syslog (LOG_ERR, "nm_dbus_init() could not get the system bus. Make sure the message bus daemon is running?");
|
||||
if (dbus_error_is_set (&dbus_error))
|
||||
dbus_error_free (&dbus_error);
|
||||
return (NULL);
|
||||
connection = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dbus_connection_set_exit_on_disconnect (connection, FALSE);
|
||||
@@ -1032,25 +1068,22 @@ DBusConnection *nm_dbus_init (NMData *data)
|
||||
data->nm_methods = nm_dbus_nm_methods_setup ();
|
||||
data->device_methods = nm_dbus_device_methods_setup ();
|
||||
data->net_methods = nm_dbus_net_methods_setup ();
|
||||
data->dhcp_methods = nm_dbus_dhcp_methods_setup ();
|
||||
|
||||
success = dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data);
|
||||
if (!success)
|
||||
if ( !dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data)
|
||||
|| !dbus_connection_register_fallback (connection, NM_DBUS_PATH_DEVICES, &devices_vtable, data)
|
||||
|| !dbus_connection_register_object_path (connection, NM_DBUS_PATH_DHCP, &dhcp_vtable, data))
|
||||
{
|
||||
syslog (LOG_CRIT, "nm_dbus_init() could not register a handler for NetworkManager. Not enough memory?");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
success = dbus_connection_register_fallback (connection, NM_DBUS_PATH_DEVICES, &devices_vtable, data);
|
||||
if (!success)
|
||||
{
|
||||
syslog (LOG_CRIT, "nm_dbus_init() could not register a handler for NetworkManager devices. Not enough memory?");
|
||||
return (NULL);
|
||||
syslog (LOG_CRIT, "nm_dbus_init() could not register D-BUS handlers. Cannot continue.");
|
||||
connection = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!dbus_connection_add_filter (connection, nm_dbus_nmi_filter, data, NULL))
|
||||
{
|
||||
syslog (LOG_CRIT, "nm_dbus_init() could not attach a dbus message filter. The NetworkManager dbus security policy may not be loaded. Restart dbus?");
|
||||
return (NULL);
|
||||
connection = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dbus_bus_add_match (connection,
|
||||
@@ -1058,23 +1091,26 @@ DBusConnection *nm_dbus_init (NMData *data)
|
||||
"interface='" NMI_DBUS_INTERFACE "',"
|
||||
"sender='" NMI_DBUS_SERVICE "',"
|
||||
"path='" NMI_DBUS_PATH "'",
|
||||
&dbus_error);
|
||||
dbus_error_free (&dbus_error);
|
||||
NULL);
|
||||
|
||||
dbus_bus_add_match(connection,
|
||||
"type='signal',"
|
||||
"interface='" DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "',"
|
||||
"sender='" DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "'",
|
||||
&dbus_error);
|
||||
dbus_error_free (&dbus_error);
|
||||
NULL);
|
||||
|
||||
dbus_bus_acquire_service (connection, NM_DBUS_SERVICE, 0, &dbus_error);
|
||||
if (dbus_error_is_set (&dbus_error))
|
||||
dbus_error_init (&error);
|
||||
dbus_bus_acquire_service (connection, NM_DBUS_SERVICE, 0, &error);
|
||||
if (dbus_error_is_set (&error))
|
||||
{
|
||||
syslog (LOG_ERR, "nm_dbus_init() could not acquire its service. dbus_bus_acquire_service() says: '%s'", dbus_error.message);
|
||||
dbus_error_free (&dbus_error);
|
||||
return (NULL);
|
||||
syslog (LOG_ERR, "nm_dbus_init() could not acquire its service. dbus_bus_acquire_service() says: '%s'", error.message);
|
||||
connection = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (dbus_error_is_set (&error))
|
||||
dbus_error_free (&error);
|
||||
|
||||
return (connection);
|
||||
}
|
||||
|
@@ -29,12 +29,15 @@
|
||||
|
||||
#include "NetworkManagerMain.h"
|
||||
#include "NetworkManagerDevice.h"
|
||||
#include "dhcpcd/dhcpcd.h"
|
||||
|
||||
typedef struct NMDbusCBData
|
||||
{
|
||||
NMData *data;
|
||||
NMDevice *dev;
|
||||
NMAccessPoint *ap;
|
||||
int opt_id;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
} NMDbusCBData;
|
||||
|
||||
typedef DBusMessage* (*NMDbusMethod) (DBusConnection *, DBusMessage *, NMDbusCBData *);
|
||||
|
@@ -92,6 +92,7 @@ gboolean nm_device_need_ap_switch (NMDevice *dev);
|
||||
void nm_device_freeze_best_ap (NMDevice *dev);
|
||||
void nm_device_unfreeze_best_ap (NMDevice *dev);
|
||||
gboolean nm_device_is_best_ap_frozen (NMDevice *dev);
|
||||
struct dhcp_interface *nm_device_get_dhcp_iface (NMDevice *dev);
|
||||
|
||||
char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap);
|
||||
|
||||
|
@@ -48,6 +48,7 @@ typedef struct NMData
|
||||
NMDbusMethodList *nm_methods;
|
||||
NMDbusMethodList *device_methods;
|
||||
NMDbusMethodList *net_methods;
|
||||
NMDbusMethodList *dhcp_methods;
|
||||
|
||||
GMainContext *main_context;
|
||||
GMainLoop *main_loop;
|
||||
|
431
src/nm-dbus-dhcp.c
Normal file
431
src/nm-dbus-dhcp.c
Normal file
@@ -0,0 +1,431 @@
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Dan Williams <dcbw@redhat.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* (C) Copyright 2005 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "NetworkManagerDevice.h"
|
||||
#include "NetworkManagerDbus.h"
|
||||
#include "NetworkManagerAP.h"
|
||||
#include "NetworkManagerAPList.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-dbus-dhcp.h"
|
||||
#include "dhcpcd/dhcpcd.h"
|
||||
|
||||
static int nm_dbus_dhcp_record_type (int id)
|
||||
{
|
||||
switch (dhcp_option_record_type (id))
|
||||
{
|
||||
case DHCP_OPT_INVALID:
|
||||
return DBUS_TYPE_INVALID;
|
||||
case DHCP_OPT_ADDRESS:
|
||||
case DHCP_OPT_TIME:
|
||||
case DHCP_OPT_COUNT:
|
||||
case DHCP_OPT_NUMBER:
|
||||
return DBUS_TYPE_UINT32;
|
||||
case DHCP_OPT_STRING:
|
||||
return DBUS_TYPE_STRING;
|
||||
case DHCP_OPT_TOGGLE:
|
||||
return DBUS_TYPE_BOOLEAN;
|
||||
case DHCP_OPT_BLOB:
|
||||
return DBUS_TYPE_BYTE;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
#define DBUS_REPLY_BYTYPE(Dtype, Ctype) do { \
|
||||
int __DBUS_REPLY_BYTYPE_len; \
|
||||
\
|
||||
if (dhcp_interface_option_present (dhcp_iface, data->opt_id) \
|
||||
&& (sizeof (Ctype) >= (__DBUS_REPLY_BYTYPE_len = dhcp_option_record_len (data->opt_id))) \
|
||||
&& ((reply = dbus_message_new_method_return (message)) != NULL)) \
|
||||
{ \
|
||||
Ctype __DBUS_REPLY_BYTYPE_val; \
|
||||
void *__DBUS_REPLY_BYTYPE_blob; \
|
||||
\
|
||||
__DBUS_REPLY_BYTYPE_blob = dhcp_interface_option_payload (dhcp_iface, data->opt_id); \
|
||||
if (__DBUS_REPLY_BYTYPE_len == 1) \
|
||||
__DBUS_REPLY_BYTYPE_val = ((unsigned char *)__DBUS_REPLY_BYTYPE_blob)[0]; \
|
||||
else if (__DBUS_REPLY_BYTYPE_len == 2) \
|
||||
__DBUS_REPLY_BYTYPE_val = ((dbus_uint16_t *)__DBUS_REPLY_BYTYPE_blob)[0]; \
|
||||
else \
|
||||
__DBUS_REPLY_BYTYPE_val = ((dbus_uint32_t *)__DBUS_REPLY_BYTYPE_blob)[0]; \
|
||||
dbus_message_append_args (reply, Dtype, __DBUS_REPLY_BYTYPE_val, DBUS_TYPE_INVALID); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DBUS_REPLY_BYTYPEV(Dtype, Ctype, Dappend) do { \
|
||||
int __DBUS_REPLY_BYTYPE_len; \
|
||||
\
|
||||
if (dhcp_interface_option_present (dhcp_iface, data->opt_id) \
|
||||
&& (sizeof (Ctype) >= (__DBUS_REPLY_BYTYPE_len = dhcp_option_record_len (data->opt_id))) \
|
||||
&& ((reply = dbus_message_new_method_return (message)) != NULL)) \
|
||||
{ \
|
||||
DBusMessageIter __DBUS_REPLY_BYTYPE_iter, __DBUS_REPLY_BYTYPE_sub; \
|
||||
void *__DBUS_REPLY_BYTYPE_blob; \
|
||||
int __DBUS_REPLY_BYTYPE_i, __DBUS_REPLY_BYTYPE_count; \
|
||||
\
|
||||
__DBUS_REPLY_BYTYPE_blob = dhcp_interface_option_payload (dhcp_iface, data->opt_id); \
|
||||
__DBUS_REPLY_BYTYPE_count = dhcp_interface_option_len (dhcp_iface, data->opt_id) / __DBUS_REPLY_BYTYPE_len; \
|
||||
dbus_message_iter_init (reply, &__DBUS_REPLY_BYTYPE_iter); \
|
||||
dbus_message_iter_append_array (&__DBUS_REPLY_BYTYPE_iter, &__DBUS_REPLY_BYTYPE_sub, Dtype); \
|
||||
for (__DBUS_REPLY_BYTYPE_i = 0; __DBUS_REPLY_BYTYPE_i < __DBUS_REPLY_BYTYPE_count; __DBUS_REPLY_BYTYPE_i++) \
|
||||
{ \
|
||||
Ctype __DBUS_REPLY_BYTYPE_val; \
|
||||
\
|
||||
if (__DBUS_REPLY_BYTYPE_len == 1) \
|
||||
__DBUS_REPLY_BYTYPE_val = ((unsigned char *)__DBUS_REPLY_BYTYPE_blob)[__DBUS_REPLY_BYTYPE_i]; \
|
||||
else if (__DBUS_REPLY_BYTYPE_len == 2) \
|
||||
__DBUS_REPLY_BYTYPE_val = ((dbus_uint16_t *)__DBUS_REPLY_BYTYPE_blob)[__DBUS_REPLY_BYTYPE_i]; \
|
||||
else \
|
||||
__DBUS_REPLY_BYTYPE_val = ((dbus_uint32_t *)__DBUS_REPLY_BYTYPE_blob)[__DBUS_REPLY_BYTYPE_i]; \
|
||||
/*dbus_message_iter_append_basic (&__DBUS_REPLY_BYTYPE_sub, Dtype, __DBUS_REPLY_BYTYPE_val);*/ \
|
||||
dbus_message_iter_append_ ## Dappend (&__DBUS_REPLY_BYTYPE_sub, __DBUS_REPLY_BYTYPE_val); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define DBUS_REPLY_STRING(Dtype, Ctype) do { \
|
||||
int __DBUS_REPLY_BYTYPE_len; \
|
||||
\
|
||||
if (dhcp_interface_option_present (dhcp_iface, data->opt_id) \
|
||||
&& ((__DBUS_REPLY_BYTYPE_len = dhcp_option_record_len (data->opt_id)) == 1) \
|
||||
&& ((reply = dbus_message_new_method_return (message)) != NULL)) \
|
||||
{ \
|
||||
Ctype __DBUS_REPLY_BYTYPE_val; \
|
||||
\
|
||||
__DBUS_REPLY_BYTYPE_val = (Ctype)dhcp_interface_option_payload (dhcp_iface, data->opt_id); \
|
||||
dbus_message_append_args (reply, Dtype, __DBUS_REPLY_BYTYPE_val, DBUS_TYPE_INVALID); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* nm_dbus_dhcp_get_len
|
||||
*
|
||||
* Gets the total length of the specified DHCP option.
|
||||
*
|
||||
*/
|
||||
static DBusMessage *nm_dbus_dhcp_get_len (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
if ((reply = dbus_message_new_method_return (message)) != NULL)
|
||||
dbus_message_append_args (reply, DBUS_TYPE_UINT32, dhcp_interface_option_len (dhcp_iface, data->opt_id), DBUS_TYPE_INVALID);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_dbus_dhcp_get_type
|
||||
*
|
||||
* Gets the type of the DHCP option.
|
||||
*
|
||||
*/
|
||||
static DBusMessage *nm_dbus_dhcp_get_type (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
if ((reply = dbus_message_new_method_return (message)) != NULL)
|
||||
{
|
||||
if (nm_dbus_dhcp_record_type (data->opt_id) == DBUS_TYPE_STRING)
|
||||
dbus_message_append_args (reply, DBUS_TYPE_UINT32, DBUS_TYPE_STRING, DBUS_TYPE_INVALID);
|
||||
else if (dhcp_interface_option_len (dhcp_iface, data->opt_id) != dhcp_option_record_len (data->opt_id))
|
||||
dbus_message_append_args (reply, DBUS_TYPE_UINT32, DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
|
||||
else
|
||||
dbus_message_append_args (reply, DBUS_TYPE_UINT32, nm_dbus_dhcp_record_type (data->opt_id), DBUS_TYPE_INVALID);
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_dbus_dhcp_get_record_type
|
||||
*
|
||||
* Gets the length of individual records within the specified DHCP option.
|
||||
*
|
||||
*/
|
||||
static DBusMessage *nm_dbus_dhcp_get_record_type (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
if ((reply = dbus_message_new_method_return (message)) != NULL)
|
||||
dbus_message_append_args (reply, DBUS_TYPE_UINT32, nm_dbus_dhcp_record_type (data->opt_id), DBUS_TYPE_INVALID);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_boolean (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
DBUS_REPLY_BYTYPE (DBUS_TYPE_BOOLEAN, dbus_bool_t);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_booleanv (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
DBUS_REPLY_BYTYPEV (DBUS_TYPE_BOOLEAN, dbus_bool_t, boolean);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_byte (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
DBUS_REPLY_BYTYPE (DBUS_TYPE_BYTE, unsigned char);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_bytev (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
DBUS_REPLY_BYTYPEV (DBUS_TYPE_BYTE, unsigned char, byte);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_integer (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
DBUS_REPLY_BYTYPE (DBUS_TYPE_UINT32, dbus_uint32_t);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_integerv (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
DBUS_REPLY_BYTYPEV (DBUS_TYPE_UINT32, dbus_uint32_t, uint32);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_string (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
DBUS_REPLY_STRING (DBUS_TYPE_STRING, const char *);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_generic (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
dhcp_iface = data->dhcp_iface;
|
||||
|
||||
switch (nm_dbus_dhcp_record_type (data->opt_id))
|
||||
{
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
if (dhcp_interface_option_len (dhcp_iface, data->opt_id) == dhcp_option_record_len (data->opt_id))
|
||||
DBUS_REPLY_BYTYPE (DBUS_TYPE_BOOLEAN, dbus_bool_t);
|
||||
else
|
||||
DBUS_REPLY_BYTYPEV (DBUS_TYPE_BOOLEAN, dbus_bool_t, boolean);
|
||||
break;
|
||||
case DBUS_TYPE_BYTE:
|
||||
if (dhcp_interface_option_len (dhcp_iface, data->opt_id) == dhcp_option_record_len (data->opt_id))
|
||||
DBUS_REPLY_BYTYPE (DBUS_TYPE_BYTE, unsigned char);
|
||||
else
|
||||
DBUS_REPLY_BYTYPEV (DBUS_TYPE_BYTE, unsigned char, byte);
|
||||
break;
|
||||
case DBUS_TYPE_UINT32:
|
||||
if (dhcp_interface_option_len (dhcp_iface, data->opt_id) == dhcp_option_record_len (data->opt_id))
|
||||
DBUS_REPLY_BYTYPE(DBUS_TYPE_UINT32, dbus_uint32_t);
|
||||
else
|
||||
DBUS_REPLY_BYTYPEV (DBUS_TYPE_UINT32, dbus_uint32_t, uint32);
|
||||
break;
|
||||
case DBUS_TYPE_STRING:
|
||||
DBUS_REPLY_STRING (DBUS_TYPE_STRING, const char *);
|
||||
break;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
static DBusMessage *nm_dbus_dhcp_get_name (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && (data->opt_id >= 0) && (data->dhcp_iface != NULL) && connection && message, NULL);
|
||||
|
||||
if ((reply = dbus_message_new_method_return (message)) != NULL)
|
||||
dbus_message_append_args (reply, DBUS_TYPE_STRING, dhcp_option_name (data->opt_id), DBUS_TYPE_INVALID);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_dbus_dhcp_validate
|
||||
*
|
||||
* Grab an option name or ID from the message and make sure its valid
|
||||
*
|
||||
*/
|
||||
static DBusMessage *nm_dbus_dhcp_validate (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
|
||||
{
|
||||
DBusMessage *reply = NULL;
|
||||
DBusError error;
|
||||
int id;
|
||||
char *attribute = NULL;
|
||||
gboolean success = FALSE;
|
||||
NMDevice *dev;
|
||||
struct dhcp_interface *dhcp_iface;
|
||||
|
||||
g_return_val_if_fail (data && data->data && connection && message, NULL);
|
||||
|
||||
/* Caller can ask for DHCP option by either name or ID. Try name first, then ID. */
|
||||
dbus_error_init (&error);
|
||||
if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &attribute, DBUS_TYPE_INVALID) || (attribute == NULL))
|
||||
{
|
||||
if (dbus_error_is_set (&error))
|
||||
dbus_error_free (&error);
|
||||
dbus_error_init (&error);
|
||||
if (dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID) && (id >= 0))
|
||||
success = TRUE;
|
||||
}
|
||||
else if (isdigit (*attribute) && ((id = atoi (attribute)) == 0) && (*attribute != '0'))
|
||||
{
|
||||
/* If user passed a DHCP option name, find that option's ID */
|
||||
if ((id = dhcp_option_id_by_name (attribute)) != -1)
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
if (success == TRUE)
|
||||
{
|
||||
if (!data->data->active_device || !(dhcp_iface = nm_device_get_dhcp_iface (data->data->active_device)))
|
||||
{
|
||||
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DhcpOptionsNotAvailable",
|
||||
"DhcpOptions are not available at this time.");
|
||||
success = FALSE;
|
||||
}
|
||||
else if (!dhcp_interface_option_present (dhcp_iface, id))
|
||||
{
|
||||
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DhcpOptionNotPresent",
|
||||
"The DhcpOption requested was not present.");
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
data->opt_id = id;
|
||||
/* We're gonna need some locking here for dhcp_iface, right now we
|
||||
* just hope it never goes away between the validate and the
|
||||
* dispatch functions. ie, device gets deactivated, removed, etc.
|
||||
*/
|
||||
data->dhcp_iface = dhcp_iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "OptionNotFound",
|
||||
"The requested DHCP option does not exist.");
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_dbus_dhcp_methods_setup
|
||||
*
|
||||
* Register handlers for dbus methods on the
|
||||
* org.freedesktop.NetworkManager.DhcpOptions object.
|
||||
*
|
||||
*/
|
||||
NMDbusMethodList *nm_dbus_dhcp_methods_setup (void)
|
||||
{
|
||||
NMDbusMethodList *list = nm_dbus_method_list_new (nm_dbus_dhcp_validate);
|
||||
|
||||
nm_dbus_method_list_add_method (list, "getLen", nm_dbus_dhcp_get_len);
|
||||
nm_dbus_method_list_add_method (list, "getType", nm_dbus_dhcp_get_type);
|
||||
nm_dbus_method_list_add_method (list, "getRecordType", nm_dbus_dhcp_get_record_type);
|
||||
nm_dbus_method_list_add_method (list, "getBoolean", nm_dbus_dhcp_get_boolean);
|
||||
nm_dbus_method_list_add_method (list, "getBooleanv", nm_dbus_dhcp_get_booleanv);
|
||||
nm_dbus_method_list_add_method (list, "getByte", nm_dbus_dhcp_get_byte);
|
||||
nm_dbus_method_list_add_method (list, "getBytev", nm_dbus_dhcp_get_bytev);
|
||||
nm_dbus_method_list_add_method (list, "getBlob", nm_dbus_dhcp_get_bytev); /* getBlob is an alias for getBytev */
|
||||
nm_dbus_method_list_add_method (list, "getInteger", nm_dbus_dhcp_get_integer);
|
||||
nm_dbus_method_list_add_method (list, "getIntegerv", nm_dbus_dhcp_get_integerv);
|
||||
nm_dbus_method_list_add_method (list, "getString", nm_dbus_dhcp_get_string);
|
||||
nm_dbus_method_list_add_method (list, "get", nm_dbus_dhcp_get_generic);
|
||||
nm_dbus_method_list_add_method (list, "getName", nm_dbus_dhcp_get_name);
|
||||
|
||||
return (list);
|
||||
}
|
29
src/nm-dbus-dhcp.h
Normal file
29
src/nm-dbus-dhcp.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Dan Williams <dcbw@redhat.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* (C) Copyright 2005 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_DBUS_DHCP_H
|
||||
#define NM_DBUS_DHCP_H
|
||||
|
||||
#include "NetworkManagerDbusUtils.h"
|
||||
|
||||
NMDbusMethodList *nm_dbus_dhcp_methods_setup (void);
|
||||
|
||||
#endif
|
@@ -4,3 +4,4 @@ nminfotest
|
||||
nmtest
|
||||
nmtestdevices
|
||||
libnm_glib_test
|
||||
nm-dhcp-opt-test
|
||||
|
@@ -8,9 +8,9 @@ AM_CPPFLAGS = \
|
||||
-DBINDIR=\"$(bindir)\" \
|
||||
-DDATADIR=\"$(datadir)\"
|
||||
|
||||
noinst_PROGRAMS = nmtest nminfotest nmtestdevices libnm_glib_test
|
||||
noinst_PROGRAMS = nmtest nminfotest nmtestdevices libnm_glib_test nm-dhcp-opt-test
|
||||
|
||||
nmtest_SOURCES = nmclienttest.c
|
||||
nmtest_SOURCES = nmtest.c
|
||||
nmtest_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS)
|
||||
|
||||
nminfotest_SOURCES = nminfotest.c
|
||||
@@ -21,3 +21,6 @@ nmtestdevices_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS)
|
||||
|
||||
libnm_glib_test_SOURCES = libnm_glib_test.c
|
||||
libnm_glib_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) ../libnm_glib/libnm_glib.la
|
||||
|
||||
nm_dhcp_opt_test_SOURCES = nm-dhcp-opt-test.c
|
||||
nm_dhcp_opt_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS)
|
||||
|
374
test/nm-dhcp-opt-test.c
Normal file
374
test/nm-dhcp-opt-test.c
Normal file
@@ -0,0 +1,374 @@
|
||||
/* nm-dhcp-opt-test - test app for NetworkManager's DHCP Options interface
|
||||
*
|
||||
* Dan Williams <dcbw@redhat.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* (C) Copyright 2005 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
|
||||
/* Return codes for functions that use dbus */
|
||||
enum
|
||||
{
|
||||
RETURN_SUCCESS = 1,
|
||||
RETURN_FAILURE = 0,
|
||||
RETURN_NO_NM = -1
|
||||
};
|
||||
|
||||
|
||||
#define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist"
|
||||
#define NM_DHCP_OPT_NOT_FOUND_ERROR "org.freedesktop.NetworkManager.OptionNotFound"
|
||||
|
||||
static char *dbus_type_to_string (int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DBUS_TYPE_UINT32:
|
||||
return "uint32";
|
||||
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
return "boolean";
|
||||
|
||||
case DBUS_TYPE_BYTE:
|
||||
return "byte";
|
||||
|
||||
case DBUS_TYPE_STRING:
|
||||
return "string";
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
|
||||
gboolean get_one_arg (DBusMessage *message, int arg_type, int arg_type2, void **arg, int *item_count)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (message != NULL, FALSE);
|
||||
g_return_val_if_fail (arg != NULL, FALSE);
|
||||
|
||||
if (arg_type == DBUS_TYPE_ARRAY)
|
||||
{
|
||||
if (!item_count)
|
||||
return FALSE;
|
||||
success = dbus_message_get_args (message, NULL, DBUS_TYPE_ARRAY, arg_type2,
|
||||
arg, item_count, DBUS_TYPE_INVALID);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (arg_type)
|
||||
{
|
||||
case DBUS_TYPE_STRING:
|
||||
success = dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, arg, DBUS_TYPE_INVALID);
|
||||
break;
|
||||
case DBUS_TYPE_BYTE:
|
||||
case DBUS_TYPE_INT32:
|
||||
case DBUS_TYPE_UINT32:
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
success = dbus_message_get_args (message, NULL, arg_type, arg, DBUS_TYPE_INVALID);
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "get_one_arg (): Unknown argument type!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call_nm_method
|
||||
*
|
||||
* Do a method call on NetworkManager.
|
||||
*
|
||||
* Returns: RETURN_SUCCESS on success
|
||||
* RETURN_FAILURE on failure
|
||||
* RETURN_NO_NM if NetworkManager service no longer exists
|
||||
*/
|
||||
static int call_nm_method (DBusConnection *con, const char *method, int opt, int arg_type, int arg_type2, void **arg, int *item_count)
|
||||
{
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
DBusError error;
|
||||
dbus_bool_t ret = TRUE;
|
||||
DBusMessageIter iter;
|
||||
|
||||
g_return_val_if_fail (con != NULL, RETURN_FAILURE);
|
||||
g_return_val_if_fail (method != NULL, RETURN_FAILURE);
|
||||
g_return_val_if_fail (arg != NULL, RETURN_FAILURE);
|
||||
|
||||
if ((arg_type == DBUS_TYPE_STRING) || (arg_type2 == DBUS_TYPE_ARRAY))
|
||||
g_return_val_if_fail (*arg == NULL, RETURN_FAILURE);
|
||||
|
||||
if (arg_type == DBUS_TYPE_ARRAY)
|
||||
{
|
||||
g_return_val_if_fail (item_count != NULL, RETURN_FAILURE);
|
||||
*item_count = 0;
|
||||
}
|
||||
|
||||
if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH_DHCP, NM_DBUS_INTERFACE_DHCP, method)))
|
||||
{
|
||||
fprintf (stderr, "call_nm_method(): Couldn't allocate the dbus message\n");
|
||||
return (RETURN_FAILURE);
|
||||
}
|
||||
dbus_message_append_args (message, DBUS_TYPE_UINT32, opt, DBUS_TYPE_INVALID);
|
||||
|
||||
dbus_error_init (&error);
|
||||
reply = dbus_connection_send_with_reply_and_block (con, message, -1, &error);
|
||||
dbus_message_unref (message);
|
||||
if (dbus_error_is_set (&error))
|
||||
{
|
||||
int ret = RETURN_FAILURE;
|
||||
|
||||
if (!strcmp (error.name, DBUS_NO_SERVICE_ERROR))
|
||||
ret = RETURN_NO_NM;
|
||||
|
||||
if (ret != RETURN_SUCCESS && (strcmp (error.name, NM_DHCP_OPT_NOT_FOUND_ERROR) != 0))
|
||||
fprintf (stderr, "call_nm_method(): %s raised:\n %s\n\n", error.name, error.message);
|
||||
|
||||
dbus_error_free (&error);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
if (reply == NULL)
|
||||
{
|
||||
fprintf (stderr, "call_nm_method(): dbus reply message was NULL\n" );
|
||||
return (RETURN_FAILURE);
|
||||
}
|
||||
|
||||
ret = get_one_arg (reply, arg_type, arg_type2, arg, item_count);
|
||||
dbus_message_unref (reply);
|
||||
if (!ret)
|
||||
{
|
||||
fprintf (stderr, "call_nm_method(): error while getting args: name='%s' message='%s'\n", error.name, error.message);
|
||||
if (dbus_error_is_set (&error))
|
||||
dbus_error_free (&error);
|
||||
return (RETURN_FAILURE);
|
||||
}
|
||||
|
||||
return (RETURN_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
int get_opt_type (DBusConnection *connection, int opt, gboolean record)
|
||||
{
|
||||
int ret;
|
||||
int type = -1;
|
||||
|
||||
ret = call_nm_method (connection, record ? "getRecordType" : "getType", opt, DBUS_TYPE_UINT32, DBUS_TYPE_INVALID, (void *)(&type), NULL);
|
||||
if (ret == RETURN_SUCCESS)
|
||||
return (type);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
void print_array (DBusConnection *connection, int opt, int opt_type)
|
||||
{
|
||||
int num_items;
|
||||
unsigned int *uint32 = NULL;
|
||||
int *int32 = NULL;
|
||||
gboolean *bool = NULL;
|
||||
unsigned char *byte = NULL;
|
||||
void *item;
|
||||
char *method;
|
||||
int ret;
|
||||
const char *name = NULL;
|
||||
|
||||
switch (opt_type)
|
||||
{
|
||||
case DBUS_TYPE_UINT32:
|
||||
item = &uint32;
|
||||
method = "getIntegerv";
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
item = &bool;
|
||||
method = "getBooleanv";
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_BYTE:
|
||||
item = &byte;
|
||||
method = "getBytev";
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "%d: Type %c\n", opt, opt_type);
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
ret = call_nm_method (connection, "getName", opt, DBUS_TYPE_STRING, DBUS_TYPE_INVALID, (void *)(&name), NULL);
|
||||
if (ret != RETURN_SUCCESS)
|
||||
name = NULL;
|
||||
|
||||
ret = call_nm_method (connection, method, opt, DBUS_TYPE_ARRAY, opt_type, item, &num_items);
|
||||
if ((ret == RETURN_SUCCESS) && (num_items > 0))
|
||||
{
|
||||
int i;
|
||||
fprintf (stderr, "%d ('%s'): (%d records of type %s) ", opt, name, num_items, dbus_type_to_string (opt_type));
|
||||
for (i = 0; i < num_items; i++)
|
||||
{
|
||||
switch (opt_type)
|
||||
{
|
||||
case DBUS_TYPE_BYTE:
|
||||
fprintf (stderr, "%d, ", byte[i]);
|
||||
break;
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
fprintf (stderr, "%d, ", bool[i]);
|
||||
break;
|
||||
case DBUS_TYPE_UINT32:
|
||||
fprintf (stderr, "%u, ", uint32[i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void print_one_item (DBusConnection *connection, int opt, int opt_type)
|
||||
{
|
||||
unsigned int uint32;
|
||||
int int32;
|
||||
gboolean bool;
|
||||
unsigned char byte;
|
||||
char *string = NULL;
|
||||
void *item = NULL;
|
||||
char *method;
|
||||
int ret;
|
||||
const char *name = NULL;
|
||||
|
||||
switch (opt_type)
|
||||
{
|
||||
case DBUS_TYPE_UINT32:
|
||||
item = &uint32;
|
||||
method = "getInteger";
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
item = &bool;
|
||||
method = "getBoolean";
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_BYTE:
|
||||
item = &byte;
|
||||
method = "getByte";
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_STRING:
|
||||
item = &string;
|
||||
method = "getString";
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "%d: Type %c\n", opt, opt_type);
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
ret = call_nm_method (connection, "getName", opt, DBUS_TYPE_STRING, DBUS_TYPE_INVALID, (void *)(&name), NULL);
|
||||
if (ret != RETURN_SUCCESS)
|
||||
name = NULL;
|
||||
|
||||
ret = call_nm_method (connection, method, opt, opt_type, DBUS_TYPE_INVALID, item, NULL);
|
||||
if (ret == RETURN_SUCCESS)
|
||||
{
|
||||
fprintf (stderr, "%d ('%s'): (%s) ", opt, name, dbus_type_to_string (opt_type));
|
||||
switch (opt_type)
|
||||
{
|
||||
case DBUS_TYPE_BYTE:
|
||||
fprintf (stderr, "%d\n", byte);
|
||||
break;
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
fprintf (stderr, "%d\n", bool);
|
||||
break;
|
||||
case DBUS_TYPE_UINT32:
|
||||
fprintf (stderr, "%u\n", uint32);
|
||||
break;
|
||||
case DBUS_TYPE_STRING:
|
||||
fprintf (stderr, "'%s'\n", string);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_each_dhcp_option (DBusConnection *connection)
|
||||
{
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusError error;
|
||||
int i;
|
||||
int opt_type;
|
||||
int ret;
|
||||
|
||||
g_return_if_fail (connection != NULL);
|
||||
|
||||
/* Loop through all available DHCP options and print each one. */
|
||||
for (i = 1; i < 62; i++)
|
||||
{
|
||||
int opt_type = get_opt_type (connection, i, FALSE);
|
||||
|
||||
if (opt_type == DBUS_TYPE_ARRAY)
|
||||
{
|
||||
int opt_type2;
|
||||
|
||||
/* get the array item type */
|
||||
opt_type2 = get_opt_type (connection, i, TRUE);
|
||||
print_array (connection, i, opt_type2);
|
||||
}
|
||||
else if (opt_type != -1)
|
||||
print_one_item (connection, i, opt_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
DBusConnection *connection;
|
||||
DBusError error;
|
||||
|
||||
g_type_init ();
|
||||
|
||||
dbus_error_init (&error);
|
||||
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
|
||||
if (connection == NULL)
|
||||
{
|
||||
fprintf (stderr, "Error connecting to system bus: %s\n", error.message);
|
||||
dbus_error_free (&error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_each_dhcp_option (connection);
|
||||
|
||||
exit (0);
|
||||
}
|
Reference in New Issue
Block a user