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:
Dan Williams
2005-02-13 22:10:03 +00:00
parent 40e1dcb347
commit df9976aef0
17 changed files with 1183 additions and 148 deletions

View File

@@ -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> 2005-02-12 Dan Williams <dcbw@redhat.com>
* test/Makefile.am * test/Makefile.am

View File

@@ -31,6 +31,8 @@
#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" #define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
#define NM_DBUS_PATH_DEVICES "/org/freedesktop/NetworkManager/Devices" #define NM_DBUS_PATH_DEVICES "/org/freedesktop/NetworkManager/Devices"
#define NM_DBUS_INTERFACE_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_SERVICE "org.freedesktop.NetworkManagerInfo"
#define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo" #define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo"

View File

@@ -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" 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 AM_GLIB_GNU_GETTEXT
AC_ARG_WITH(distro, AC_ARG_WITH(distro, AC_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, gentoo, debian, or slackware]))
[
--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
],,)
if test "z$with_distro" = "z"; then if test "z$with_distro" = "z"; then
AC_CHECK_FILE(/etc/mandrake-release,with_distro="mandrake") AC_CHECK_FILE(/etc/mandrake-release,with_distro="mandrake")
AC_CHECK_FILE(/etc/redhat-release,with_distro="redhat") AC_CHECK_FILE(/etc/redhat-release,with_distro="redhat")
@@ -61,13 +51,13 @@ fi
with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' ` with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' `
if test "z$with_distro" = "z"; then 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 exit 1
else else
case $with_distro in case $with_distro in
redhat|gentoo|debian|slackware) ;; 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 exit 1
;; ;;
esac esac
@@ -148,7 +138,7 @@ PKG_CHECK_MODULES(GNOME_KEYRING, gnome-keyring-1)
AC_SUBST(GNOME_KEYRING_CFLAGS) AC_SUBST(GNOME_KEYRING_CFLAGS)
AC_SUBST(GNOME_KEYRING_LIBS) 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 if test x"$ac_gcrypt" != xno; then
AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
else else
@@ -175,11 +165,10 @@ AC_SUBST(PANEL_APPLET_CFLAGS)
AC_SUBST(PANEL_APPLET_LIBS) AC_SUBST(PANEL_APPLET_LIBS)
PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0) 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) AC_SUBST(LIBGNOMEUI_LIBS)
# taken from hal AC_ARG_WITH(dbus-sys, AC_HELP_STRING([--with-dbus-sys=DIR], [where D-BUS system.d directory is]))
AC_ARG_WITH(dbus-sys, [ --with-dbus-sys=<dir> where D-BUS system.d directory is])
if ! test -z "$with_dbus_sys" ; then if ! test -z "$with_dbus_sys" ; then
DBUS_SYS_DIR="$with_dbus_sys" DBUS_SYS_DIR="$with_dbus_sys"
@@ -189,9 +178,9 @@ fi
AC_SUBST(DBUS_SYS_DIR) AC_SUBST(DBUS_SYS_DIR)
AC_DEFINE_UNQUOTED(DBUS_SYSTEMD_DIR, "$DBUS_SYS_DIR", [Where system.d dir for DBUS is]) 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, 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_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_user, AC_HELP_STRING([--with-named-user=USERNAME], [named username]))
if test "x${with_named}" = x; then if test "x${with_named}" = x; then
AC_DEFINE(NM_NO_NAMED,,[Define if you want to disable named support]) AC_DEFINE(NM_NO_NAMED,,[Define if you want to disable named support])
fi 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_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_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) AM_CONDITIONAL(BUILD_NOTIFICATION_ICON, test x$enable_notification_icon = xyes)
if test x$enable_notification_icon == xyes ; then if test x$enable_notification_icon == xyes ; then
@@ -240,7 +229,7 @@ prefix=$old_prefix
exec_prefix=$old_exec_prefix exec_prefix=$old_exec_prefix
AC_ARG_ENABLE(more-warnings, AC_ARG_ENABLE(more-warnings,
[ --enable-more-warnings Maximum compiler warnings], AC_HELP_STRING([--enable-more-warnings], [Maximum compiler warnings]),
set_more_warnings="$enableval",[ set_more_warnings="$enableval",[
if test -d "$srcdir/{arch}" || test -d "$srcdir/CVS"; then if test -d "$srcdir/{arch}" || test -d "$srcdir/CVS"; then
set_more_warnings=yes set_more_warnings=yes
@@ -295,4 +284,4 @@ libnm_glib/libnm_glib.pc
echo echo
echo Distribution targeting: ${with_distro} 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'

View File

@@ -83,9 +83,9 @@ typedef struct dhcpMessage
typedef struct dhcpOptions typedef struct dhcpOptions
{ {
u_char num;
u_char len[256]; u_char len[256];
void *val[256]; void *val[256];
u_char num;
} __attribute__((packed)) dhcpOptions; } __attribute__((packed)) dhcpOptions;
struct packed_ether_header struct packed_ether_header
@@ -132,75 +132,145 @@ typedef struct dhcp_interface
typedef struct dhcp_option_table typedef struct dhcp_option_table
{ {
const int option;
const char *name; const char *name;
const int len; const int len_hint;
dhcp_option_type type;
} dhcp_option_table; } dhcp_option_table;
static dhcp_option_table dhcp_opt_table[] = static dhcp_option_table dhcp_opt_table[] =
{ {
{ padOption, "padOption", 1 }, /* Names come from http://www.iana.org/assignments/bootp-dhcp-parameters, not to be changed */
{ subnetMask, "subnetMask", 4 },
{ timerOffset, "timerOffset", -1 }, /* 0 */ { "Pad", 0, DHCP_OPT_INVALID },
{ routersOnSubnet, "routersOnSubnet", 4 }, /* 1 */ { "Subnet Mask", 4, DHCP_OPT_ADDRESS },
{ timeServer, "timeServer", 4 }, /* 2 */ { "Time Offset", 4, DHCP_OPT_TIME },
{ nameServer, "nameServer", 4 }, /* 3 */ { "Router", 4, DHCP_OPT_ADDRESS },
{ dns, "dns", 4 }, /* 4 */ { "Time Server", 4, DHCP_OPT_ADDRESS },
{ logServer, "logServer", 4 }, /* 5 */ { "Name Server", 4, DHCP_OPT_ADDRESS },
{ cookieServer, "cookieServer", 4 }, /* 6 */ { "Domain Server", 4, DHCP_OPT_ADDRESS },
{ lprServer, "lprServer", 4 }, /* 7 */ { "Log Server", 4, DHCP_OPT_ADDRESS },
{ impressServer, "impressServer", 4 }, /* 8 */ { "Quotes Server", 4, DHCP_OPT_ADDRESS },
{ resourceLocationServer,"resourceLocationServer",4 }, /* 9 */ { "LPR Server", 4, DHCP_OPT_ADDRESS },
{ hostName, "hostName", -1 }, /* 10 */ { "Impress Server", 4, DHCP_OPT_ADDRESS },
{ bootFileSize, "bootFileSize", 4 }, /* 11 */ { "RLP Server", 4, DHCP_OPT_ADDRESS },
{ meritDumpFile, "meritDumpFile", 4 }, /* 12 */ { "Hostname", 1, DHCP_OPT_STRING },
{ domainName, "domainName", -1 }, /* 13 */ { "Boot File Size", 2, DHCP_OPT_COUNT },
{ swapServer, "swapServer", 4 }, /* 14 */ { "Merit Dump File", 1, DHCP_OPT_STRING },
{ rootPath, "rootPath", -1 }, /* 15 */ { "Domain Name", 1, DHCP_OPT_STRING },
{ extentionsPath, "extentionsPath", -1 }, /* 16 */ { "Swap Server", 1, DHCP_OPT_ADDRESS },
{ IPforwarding, "IPforwarding", -1 }, /* 17 */ { "Root Path", 1, DHCP_OPT_STRING },
{ nonLocalSourceRouting, "nonLocalSourceRouting", -1 }, /* 18 */ { "Extension Path", 1, DHCP_OPT_STRING },
{ policyFilter, "policyFilter", -1 }, /* 19 */ { "Forward On/Off", 1, DHCP_OPT_TOGGLE },
{ maxDgramReasmSize, "maxDgramReasmSize", -1 }, /* 20 */ { "SrcRte On/Off", 1, DHCP_OPT_TOGGLE },
{ defaultIPTTL, "defaultIPTTL", -1 }, /* 21 */ { "Policy Filter", 1, DHCP_OPT_BLOB },
{ pathMTUagingTimeout, "pathMTUagingTimeout", -1 }, /* 22 */ { "Max DG Assembly", 2, DHCP_OPT_COUNT },
{ pathMTUplateauTable, "pathMTUplateauTable", -1 }, /* 23 */ { "Default IP TTL", 1, DHCP_OPT_COUNT },
{ ifMTU, "ifMTU", -1 }, /* 24 */ { "MTU Timeout", 4, DHCP_OPT_TIME },
{ allSubnetsLocal, "allSubnetsLocal", -1 }, /* 25 */ { "MTU Plateau", 1, DHCP_OPT_BLOB },
{ broadcastAddr, "broadcastAddr", 4 }, /* 26 */ { "MTU Interface", 2, DHCP_OPT_COUNT },
{ performMaskDiscovery, "performMaskDiscovery", -1 }, /* 27 */ { "MTU Subnet", 1, DHCP_OPT_TOGGLE },
{ routerSolicitationAddr,"routerSolicitationAddr",-1 }, /* 28 */ { "Broadcast Address", 4, DHCP_OPT_ADDRESS },
{ staticRoute, "staticRoute", 4 }, /* 29 */ { "Mask Discovery", 1, DHCP_OPT_TOGGLE },
{ trailerEncapsulation, "trailerEncapsulation", -1 }, /* 30 */ { "Mask Supplier", 1, DHCP_OPT_TOGGLE },
{ arpCacheTimeout, "arpCacheTimeout", -1 }, /* 31 */ { "Router Discovery", 1, DHCP_OPT_TOGGLE },
{ ethernetEncapsulation, "ethernetEncapsulation", -1 }, /* 32 */ { "Router Request", 4, DHCP_OPT_ADDRESS },
{ tcpDefaultTTL, "tcpDefaultTTL", -1 }, /* 33 */ { "Static Route", 1, DHCP_OPT_BLOB },
{ tcpKeepaliveInterval, "tcpKeepaliveInterval", -1 }, /* 34 */ { "Trailers", 1, DHCP_OPT_TOGGLE },
{ tcpKeepaliveGarbage, "tcpKeepaliveGarbage", -1 }, /* 35 */ { "ARP Timeout", 4, DHCP_OPT_TIME },
{ nisDomainName, "nisDomainName", -1 }, /* 36 */ { "Ethernet", 1, DHCP_OPT_BLOB },
{ nisServers, "nisServers", 4 }, /* 37 */ { "Default TCP TTL", 1, DHCP_OPT_COUNT},
{ ntpServers, "ntpServers", 4 }, /* 38 */ { "Keepalive Time", 4, DHCP_OPT_TIME },
{ vendorSpecificInfo, "vendorSpecificInfo", -1 }, /* 39 */ { "Keepalive Data", 1, DHCP_OPT_BLOB },
{ netBIOSnameServer, "netBIOSnameServer", -1 }, /* 40 */ { "NIS Domain", 1, DHCP_OPT_STRING },
{ netBIOSdgramDistServer,"netBIOSdgramDistServer",-1 }, /* 41 */ { "NIS Servers", 4, DHCP_OPT_ADDRESS },
{ netBIOSnodeType, "netBIOSnodeType", -1 }, /* 42 */ { "NTP Servers", 4, DHCP_OPT_ADDRESS },
{ netBIOSscope, "netBIOSscope", -1 }, /* 43 */ { "Vendor Specific", 1, DHCP_OPT_BLOB },
{ xFontServer, "xFontServer", -1 }, /* 44 */ { "NETBIOS Name Srv", 4, DHCP_OPT_ADDRESS },
{ xDisplayManager, "xDisplayManager", -1 }, /* 45 */ { "NETBIOS Dist Srv", 4, DHCP_OPT_ADDRESS },
{ dhcpRequestedIPaddr, "dhcpRequestedIPaddr", 4 }, /* 46 */ { "NETBIOS Node Type", 1, DHCP_OPT_NUMBER },
{ dhcpIPaddrLeaseTime, "dhcpIPaddrLeaseTime", 4 }, /* 47 */ { "NETBIOS Scope", 1, DHCP_OPT_NUMBER },
{ dhcpOptionOverload, "dhcpOptionOverload", -1 }, /* 48 */ { "X Window Font", 4, DHCP_OPT_ADDRESS },
{ dhcpMessageType, "dhcpMessageType", -1 }, /* 49 */ { "X Window Manager", 4, DHCP_OPT_ADDRESS },
{ dhcpServerIdentifier, "dhcpServerIdentifier", -1 }, /* 50 */ { "Address Request", 4, DHCP_OPT_ADDRESS },
{ dhcpParamRequest, "dhcpParamRequest", -1 }, /* 51 */ { "Address Time", 4, DHCP_OPT_TIME },
{ dhcpMsg, "dhcpMsg", -1 }, /* 52 */ { "Overload", 1, DHCP_OPT_BLOB },
{ dhcpMaxMsgSize, "dhcpMaxMsgSize", -1 }, /* 53 */ { "DHCP Msg Type", 1, DHCP_OPT_NUMBER },
{ dhcpT1value, "dhcpT1value", 4 }, /* 54 */ { "DHCP Server Id", 4, DHCP_OPT_ADDRESS },
{ dhcpT2value, "dhcpT2value", 4 }, /* 55 */ { "Parameter List", 1, DHCP_OPT_BLOB },
{ dhcpClassIdentifier, "dhcpClassIdentifier", -1 }, /* 56 */ { "DHCP Message", 1, DHCP_OPT_BLOB },
{ dhcpClientIdentifier, "dhcpClientIdentifier", -1 }, /* 57 */ { "DHCP Max Msg Size", 2, DHCP_OPT_COUNT },
{ -1, NULL, -1 } /* 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); typedef udpipMessage *(*dhcp_msg_build_proc)(dhcp_interface *, int *msg_len);

View File

@@ -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; 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; 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; 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) if ((val >= 0) && (val < dhcp_opt_table_len))
return (dhcp_opt_table[val].len); return (dhcp_opt_table[val].len_hint);
else else
return -1; 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);
}

View File

@@ -99,6 +99,18 @@ enum
endOption = 255 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 */ /* Return codes */
#define RET_DHCP_ERROR 0 #define RET_DHCP_ERROR 0
#define RET_DHCP_ADDRESS_IN_USE 1 #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_free (struct dhcp_interface *iface);
void dhcp_interface_cease (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_option_present (struct dhcp_interface *iface, int val);
int dhcp_interface_get_dhcp_field_len (struct dhcp_interface *iface, int val); int dhcp_interface_option_len (struct dhcp_interface *iface, int val);
void *dhcp_interface_get_dhcp_field (struct dhcp_interface *iface, int val); void *dhcp_interface_option_payload (struct dhcp_interface *iface, int val);
int dhcp_individual_value_len (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 #endif

View File

@@ -13,12 +13,16 @@ NetworkManager_SOURCES = \
NetworkManagerDbus.h \ NetworkManagerDbus.h \
NetworkManagerDbusUtils.c \ NetworkManagerDbusUtils.c \
NetworkManagerDbusUtils.h \ NetworkManagerDbusUtils.h \
nm-dbus-nm.h \
nm-dbus-nm.c \ nm-dbus-nm.c \
nm-dbus-device.h \ nm-dbus-nm.h \
nm-dbus-device.c \ nm-dbus-device.c \
nm-dbus-net.h \ nm-dbus-device.h \
nm-dbus-net.c \ 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.c \
NetworkManagerDHCP.h \ NetworkManagerDHCP.h \
NetworkManagerDevice.c \ NetworkManagerDevice.c \

View File

@@ -127,31 +127,31 @@ static void nm_device_dhcp_configure (NMDevice *dev)
/* Replace basic info */ /* Replace basic info */
nm_system_device_set_ip4_address (dev, dev->dhcp_iface->ciaddr); 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); 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); nm_system_device_set_ip4_broadcast (dev, temp);
} }
/* Default route */ /* 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); nm_system_device_set_ip4_default_route (dev, temp);
} }
/* Update /etc/resolv.conf */ /* Update /etc/resolv.conf */
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, dns)) if (dhcp_interface_option_present (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)); 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)) if (dhcp_interface_option_present (dev->dhcp_iface, domainName))
set_domain_search (dev, dhcp_interface_get_dhcp_field (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); 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); 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); t2 = ntohl (t2);
} }
if (!t1 || !t2) if (!t1 || !t2)

View File

@@ -38,6 +38,7 @@
#include "nm-dbus-nm.h" #include "nm-dbus-nm.h"
#include "nm-dbus-device.h" #include "nm-dbus-device.h"
#include "nm-dbus-net.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 * 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) DBusConnection *nm_dbus_init (NMData *data)
{ {
DBusError dbus_error; DBusError error;
dbus_bool_t success; dbus_bool_t success;
DBusConnection *connection; DBusConnection *connection;
DBusObjectPathVTable nm_vtable = {NULL, &nm_dbus_nm_message_handler, NULL, NULL, NULL, NULL}; 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 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_connection_set_change_sigpipe (TRUE);
dbus_error_init (&dbus_error); dbus_error_init (&error);
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error); connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
if ((connection == NULL) || dbus_error_is_set (&dbus_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?"); 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)) connection = NULL;
dbus_error_free (&dbus_error); goto out;
return (NULL);
} }
dbus_connection_set_exit_on_disconnect (connection, FALSE); 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->nm_methods = nm_dbus_nm_methods_setup ();
data->device_methods = nm_dbus_device_methods_setup (); data->device_methods = nm_dbus_device_methods_setup ();
data->net_methods = nm_dbus_net_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 ( !dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data)
if (!success) || !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?"); syslog (LOG_CRIT, "nm_dbus_init() could not register D-BUS handlers. Cannot continue.");
return (NULL); connection = NULL;
} goto out;
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);
} }
if (!dbus_connection_add_filter (connection, nm_dbus_nmi_filter, data, NULL)) 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?"); 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, dbus_bus_add_match (connection,
@@ -1058,23 +1091,26 @@ DBusConnection *nm_dbus_init (NMData *data)
"interface='" NMI_DBUS_INTERFACE "'," "interface='" NMI_DBUS_INTERFACE "',"
"sender='" NMI_DBUS_SERVICE "'," "sender='" NMI_DBUS_SERVICE "',"
"path='" NMI_DBUS_PATH "'", "path='" NMI_DBUS_PATH "'",
&dbus_error); NULL);
dbus_error_free (&dbus_error);
dbus_bus_add_match(connection, dbus_bus_add_match(connection,
"type='signal'," "type='signal',"
"interface='" DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "'," "interface='" DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "',"
"sender='" DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "'", "sender='" DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "'",
&dbus_error); NULL);
dbus_error_free (&dbus_error);
dbus_bus_acquire_service (connection, NM_DBUS_SERVICE, 0, &dbus_error); dbus_error_init (&error);
if (dbus_error_is_set (&dbus_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); syslog (LOG_ERR, "nm_dbus_init() could not acquire its service. dbus_bus_acquire_service() says: '%s'", error.message);
dbus_error_free (&dbus_error); connection = NULL;
return (NULL); goto out;
} }
out:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
return (connection); return (connection);
} }

View File

@@ -29,12 +29,15 @@
#include "NetworkManagerMain.h" #include "NetworkManagerMain.h"
#include "NetworkManagerDevice.h" #include "NetworkManagerDevice.h"
#include "dhcpcd/dhcpcd.h"
typedef struct NMDbusCBData typedef struct NMDbusCBData
{ {
NMData *data; NMData *data;
NMDevice *dev; NMDevice *dev;
NMAccessPoint *ap; NMAccessPoint *ap;
int opt_id;
struct dhcp_interface *dhcp_iface;
} NMDbusCBData; } NMDbusCBData;
typedef DBusMessage* (*NMDbusMethod) (DBusConnection *, DBusMessage *, NMDbusCBData *); typedef DBusMessage* (*NMDbusMethod) (DBusConnection *, DBusMessage *, NMDbusCBData *);

View File

@@ -92,6 +92,7 @@ gboolean nm_device_need_ap_switch (NMDevice *dev);
void nm_device_freeze_best_ap (NMDevice *dev); void nm_device_freeze_best_ap (NMDevice *dev);
void nm_device_unfreeze_best_ap (NMDevice *dev); void nm_device_unfreeze_best_ap (NMDevice *dev);
gboolean nm_device_is_best_ap_frozen (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); char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap);

View File

@@ -48,6 +48,7 @@ typedef struct NMData
NMDbusMethodList *nm_methods; NMDbusMethodList *nm_methods;
NMDbusMethodList *device_methods; NMDbusMethodList *device_methods;
NMDbusMethodList *net_methods; NMDbusMethodList *net_methods;
NMDbusMethodList *dhcp_methods;
GMainContext *main_context; GMainContext *main_context;
GMainLoop *main_loop; GMainLoop *main_loop;

431
src/nm-dbus-dhcp.c Normal file
View 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
View 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

View File

@@ -4,3 +4,4 @@ nminfotest
nmtest nmtest
nmtestdevices nmtestdevices
libnm_glib_test libnm_glib_test
nm-dhcp-opt-test

View File

@@ -8,9 +8,9 @@ AM_CPPFLAGS = \
-DBINDIR=\"$(bindir)\" \ -DBINDIR=\"$(bindir)\" \
-DDATADIR=\"$(datadir)\" -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) nmtest_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS)
nminfotest_SOURCES = nminfotest.c 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_SOURCES = libnm_glib_test.c
libnm_glib_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) ../libnm_glib/libnm_glib.la 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
View 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);
}