summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacobs <none@none>2007-10-23 07:51:21 -0700
committerjacobs <none@none>2007-10-23 07:51:21 -0700
commit4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3 (patch)
tree7637fe253bcc25006346dd639303fbd5ad5adb3c
parenta93a1f58a8763fa69172980b98e3d24720c1136e (diff)
downloadillumos-gate-4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3.tar.gz
PSARC/2007/499 Automatic discovery of network attached printers
6607736 Solaris should detect network attached printers
-rw-r--r--usr/src/cmd/hal/addons/Makefile2
-rw-r--r--usr/src/cmd/hal/addons/network-devices/Makefile81
-rw-r--r--usr/src/cmd/hal/addons/network-devices/addon-network-discovery.c339
-rw-r--r--usr/src/cmd/hal/addons/network-devices/cache.c106
-rw-r--r--usr/src/cmd/hal/addons/network-devices/common.c351
-rw-r--r--usr/src/cmd/hal/addons/network-devices/network-discovery.h28
-rw-r--r--usr/src/cmd/hal/addons/network-devices/network-discovery.xml111
-rw-r--r--usr/src/cmd/hal/addons/network-devices/snmp.c133
-rw-r--r--usr/src/cmd/hal/addons/network-devices/svc-network-discovery117
-rw-r--r--usr/src/cmd/hal/fdi/Makefile6
-rw-r--r--usr/src/cmd/hal/fdi/policy/10osvendor/10-network-attached.fdi42
-rw-r--r--usr/src/cmd/hal/fdi/preprobe/10osvendor/20-printers.fdi38
-rw-r--r--usr/src/cmd/hal/probing/Makefile2
-rw-r--r--usr/src/cmd/hal/probing/network-printer/Makefile68
-rw-r--r--usr/src/cmd/hal/probing/network-printer/probe-network-printer.c118
-rw-r--r--usr/src/cmd/hal/probing/network-printer/probe-snmp.c507
-rw-r--r--usr/src/cmd/hal/probing/printer/Makefile6
-rw-r--r--usr/src/cmd/hal/probing/printer/probe-printer.c176
-rw-r--r--usr/src/cmd/hal/utils/printer.c148
-rw-r--r--usr/src/cmd/hal/utils/printer.h23
-rw-r--r--usr/src/lib/libsecdb/auth_attr.txt2
-rw-r--r--usr/src/lib/libsecdb/help/auths/Makefile2
-rw-r--r--usr/src/lib/libsecdb/help/auths/SmfNADDStates.html40
-rw-r--r--usr/src/lib/libsecdb/help/auths/SmfValueNADD.html40
-rw-r--r--usr/src/lib/libsecdb/prof_attr.txt2
-rw-r--r--usr/src/pkgdefs/SUNW0on/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWhal/prototype_com2
-rw-r--r--usr/src/pkgdefs/SUNWhalr/prototype_com7
-rw-r--r--usr/src/tools/scripts/check_rtime.pl1
30 files changed, 2402 insertions, 100 deletions
diff --git a/usr/src/cmd/hal/addons/Makefile b/usr/src/cmd/hal/addons/Makefile
index b27a0f7295..9afe789d5c 100644
--- a/usr/src/cmd/hal/addons/Makefile
+++ b/usr/src/cmd/hal/addons/Makefile
@@ -25,7 +25,7 @@
# ident "%Z%%M% %I% %E% SMI"
#
-SUBDIRS = storage acpi
+SUBDIRS = storage acpi network-devices
all := TARGET= all
install := TARGET= install
diff --git a/usr/src/cmd/hal/addons/network-devices/Makefile b/usr/src/cmd/hal/addons/network-devices/Makefile
new file mode 100644
index 0000000000..580c5e674c
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/Makefile
@@ -0,0 +1,81 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = hald-addon-network-discovery
+OBJS = addon-network-discovery.o probe-snmp.o snmp.o logger.o cache.o common.o printer.o
+
+MANIFEST = network-discovery.xml
+SVCMETHOD = svc-network-discovery
+
+include ../../../Makefile.cmd
+include ../../Makefile.hal
+
+ROOTMANIFESTDIR = $(ROOTSVCNETWORK)
+$(ROOTMANIFEST) := FILEMODE = 444
+$(ROOTLIBSVCMETHOD)/$(SVCMETHOD):= FILEMODE = 555
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+
+LDLIBS += -lc -ldbus-1 -lhal -lglib-2.0 -ldbus-glib-1
+LDLIBS += -lnsl -lsocket
+LDLIBS += -L$(SFWLIBDIR) -R$(SFWLIBDIR) $(ZIGNORE) -lnetsnmp
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_GLIB_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal -I../../hald -I../../utils
+CPPFLAGS += -I$(SFWINCDIR)
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+probe-snmp.o: ../../probing/network-printer/probe-snmp.c
+ $(COMPILE.c) -o $@ ../../probing/network-printer/probe-snmp.c
+ $(POST_PROCESS_O)
+
+logger.o: ../../hald/logger.c
+ $(COMPILE.c) -o $@ ../../hald/logger.c
+ $(POST_PROCESS_O)
+
+printer.o: ../../utils/printer.c
+ $(COMPILE.c) -o $@ ../../utils/printer.c
+ $(POST_PROCESS_O)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD) $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+check: $(CHKMANIFEST)
+
+clean:
+ $(RM) $(OBJS) $(PROG)
+
+FRC:
+
+include ../../../Makefile.targ
diff --git a/usr/src/cmd/hal/addons/network-devices/addon-network-discovery.c b/usr/src/cmd/hal/addons/network-devices/addon-network-discovery.c
new file mode 100644
index 0000000000..c685a494e9
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/addon-network-discovery.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/dkio.h>
+#include <sys/stat.h>
+#include <priv.h>
+#include <glib.h>
+
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libhal.h>
+
+#include "../../hald/logger.h"
+
+#include "network-discovery.h"
+#include "printer.h"
+
+#define DBUS_INTERFACE "org.freedesktop.Hal.Device.NetworkDiscovery"
+#define NP(x) (x?x:"NULL")
+#define STRDUP(x) (x?strdup(x):NULL)
+
+typedef struct {
+ LibHalContext *ctx;
+ gboolean enabled;
+ char *parent;
+ char *community;
+ char *network;
+} nds_snmp_cbdata_t;
+
+static nds_snmp_cbdata_t *snmp_cb_data = NULL;
+
+static int
+nds_snmp_scan(LibHalContext *ctx, char *parent, char *community, char *network)
+{
+ time_t start;
+
+ HAL_DEBUG(("nds_snmp_scan(0x%8.8x, %s, %s, %s)",
+ ctx, NP(parent), NP(community), NP(network)));
+ HAL_DEBUG(("NetworkDiscovery snmp scan initated"));
+
+ /* scan for devices */
+ time(&start);
+ if (network == NULL) {
+ GList *elem, *list = broadcast_addresses();
+
+ for (elem = list; elem != NULL; elem = g_list_next(elem)) {
+ scan_for_devices_using_snmp(ctx, parent, community,
+ (char *)elem->data);
+ free(elem->data);
+ }
+ g_list_free(list);
+ } else
+ scan_for_devices_using_snmp(ctx, parent, community, network);
+
+ /* remove devices that haven't been seen since before this scan */
+ scan_for_stale_devices(ctx, start);
+
+ HAL_DEBUG(("NetworkDiscovery snmp scan completed"));
+
+ return (0);
+}
+
+static gboolean
+nds_snmp_scan_cb(gpointer data)
+{
+ nds_snmp_cbdata_t *args = data;
+
+ if (args->enabled == FALSE) {
+ if (args->parent) free(args->parent);
+ if (args->community) free(args->community);
+ if (args->network) free(args->network);
+ free(args);
+ return (FALSE);
+ }
+
+ nds_snmp_scan(args->ctx, args->parent, args->community, args->network);
+
+ return (TRUE);
+}
+
+static int
+nds_EnablePrinterScanningViaSNMP(LibHalContext *ctx, char *parent, int interval,
+ char *community, char *network)
+{
+ HAL_DEBUG(("NetworkDiscovery.EnablePrinterScanningViaSNMP(0x%8.8x, %s, %d, %s, %s)",
+ ctx, NP(parent), interval, NP(community), NP(network)));
+
+ /* are we already discoverying network devices ? */
+ if (snmp_cb_data != NULL) {
+ snmp_cb_data->enabled = FALSE; /* cancel it */
+ }
+
+ /* setup for network device discovery */
+ if ((snmp_cb_data = calloc(1, sizeof (*snmp_cb_data))) != NULL) {
+ snmp_cb_data->ctx = ctx;
+ snmp_cb_data->enabled = TRUE;
+ snmp_cb_data->parent = STRDUP(parent);
+ snmp_cb_data->community = STRDUP(community);
+ snmp_cb_data->network = STRDUP(network);
+
+ /* prime the pump with an initial scan */
+ nds_snmp_scan(ctx, parent, community, network);
+
+ /* add a regular network scan */
+ g_timeout_add(interval * 1000, nds_snmp_scan_cb, snmp_cb_data);
+ }
+
+ return (0);
+}
+
+static int
+nds_DisablePrinterScanningViaSNMP(LibHalContext *ctx)
+{
+ HAL_DEBUG(("NetworkDiscovery.DisablePrinterScanningViaSNMP(0x%8.8x)", ctx));
+
+ if (snmp_cb_data != NULL)
+ snmp_cb_data->enabled = FALSE;
+ snmp_cb_data = NULL;
+
+ return (0);
+}
+
+static int
+nds_ScanForPrintersViaSNMP(LibHalContext *ctx, char *parent, char *community,
+ char *network)
+{
+ time_t start, stop;
+
+ HAL_DEBUG(("NetworkDiscovery.ScanForPrintersViaSNMP(0x%8.8x, %s, %s, %s)",
+ ctx, NP(parent), NP(community), NP(network)));
+
+ return (nds_snmp_scan(ctx, parent, community, network));
+}
+
+static DBusHandlerResult
+nds_filter_function(DBusConnection *connection, DBusMessage *message,
+ void *user_data)
+{
+ LibHalContext *ctx = user_data;
+ DBusMessage *reply;
+ DBusError error;
+ const char *member = dbus_message_get_member(message);
+ const char *path = dbus_message_get_path(message);
+ int rc = -1;
+
+ dbus_error_init(&error);
+
+ HAL_DEBUG(("DBus message: %s, %s ", member, path));
+
+ if (dbus_message_is_method_call(message,
+ DBUS_INTERFACE, "EnablePrinterScanningViaSNMP")) {
+ int interval = -1;
+ char *udi = getenv("UDI");
+ char *community = "public";
+ char *network = "0.0.0.0";
+
+ dbus_message_get_args(message, &error,
+ DBUS_TYPE_INT32, &interval,
+ DBUS_TYPE_STRING, &community,
+ DBUS_TYPE_STRING, &network,
+ DBUS_TYPE_INVALID);
+
+ if (strcmp(network, "0.0.0.0") == 0)
+ network = NULL;
+
+ rc = nds_EnablePrinterScanningViaSNMP(ctx, udi, interval,
+ community, network);
+ } else if (dbus_message_is_method_call(message,
+ DBUS_INTERFACE, "ScanForPrintersViaSNMP")) {
+ int interval = -1;
+ char *udi = getenv("UDI");
+ char *community = "public";
+ char *network = "0.0.0.0";
+
+ dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &community,
+ DBUS_TYPE_STRING, &network,
+ DBUS_TYPE_INVALID);
+
+ if (strcmp(network, "0.0.0.0") == 0)
+ network = NULL;
+
+ rc = nds_ScanForPrintersViaSNMP(ctx, udi, community, network);
+ } else if (dbus_message_is_method_call(message,
+ DBUS_INTERFACE, "DisablePrinterScanningViaSNMP")) {
+ rc = nds_DisablePrinterScanningViaSNMP(ctx);
+ } else
+ HAL_WARNING(("Unknown DBus message: %s, %s ", member, path));
+
+ if (dbus_error_is_set(&error))
+ dbus_error_free(&error);
+
+ if ((reply = dbus_message_new_method_return(message)) == NULL) {
+ HAL_WARNING(("Could not allocate memory for the DBus reply"));
+ return (FALSE);
+ }
+
+ dbus_message_append_args(reply, DBUS_TYPE_INT32, &rc,
+ DBUS_TYPE_INVALID);
+
+ if (!dbus_connection_send(connection, reply, NULL)) {
+ HAL_WARNING(("Could not sent reply"));
+ }
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return (DBUS_HANDLER_RESULT_HANDLED);
+}
+
+static int
+nds_claim_interface(LibHalContext *ctx, char *udi, DBusError *error)
+{
+ DBusConnection *connection;
+ char *interface_xml =
+ "<method name=\"EnablePrinterScanningViaSNMP\">\n"
+ " <arg name=\"interval\" direction=\"in\" type=\"i\"/>\n"
+ " <arg name=\"community\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"network\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
+ "</method>\n"
+ "<method name=\"DisablePrinterScanningViaSNMP\">\n"
+ " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
+ "</method>\n"
+ "<method name=\"ScanForPrintersViaSNMP\">\n"
+ " <arg name=\"community\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"network\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
+ "</method>\n";
+
+ HAL_DEBUG(("nds_claim_interface(0x%8.8x, %s, 0x%8.8x): %s",
+ ctx, udi, error, DBUS_INTERFACE));
+
+ if ((connection = libhal_ctx_get_dbus_connection(ctx)) == NULL) {
+ HAL_WARNING(("Could not get DBus connection"));
+ return (-1);
+ }
+
+ if (libhal_device_claim_interface(ctx, udi,
+ DBUS_INTERFACE, interface_xml, error) == 0) {
+ HAL_WARNING(("Could not claim interface: %s", error->message));
+ return (-1);
+ }
+
+ dbus_connection_setup_with_g_main(connection, NULL);
+ dbus_connection_add_filter(connection, nds_filter_function, ctx, NULL);
+ dbus_connection_set_exit_on_disconnect(connection, 0);
+
+ return (0);
+}
+
+static void
+drop_privileges()
+{
+ priv_set_t *pPrivSet = NULL;
+ priv_set_t *lPrivSet = NULL;
+
+ /*
+ * Start with the 'basic' privilege set and then remove any
+ * of the 'basic' privileges that will not be needed.
+ */
+ if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ return;
+ }
+
+ /* Clear privileges we will not need from the 'basic' set */
+ (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
+ (void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
+ (void) priv_delset(pPrivSet, PRIV_PROC_FORK);
+ (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
+ (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
+
+ /* Set the permitted privilege set. */
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
+ return;
+ }
+
+ /* Clear the limit set. */
+ if ((lPrivSet = priv_allocset()) == NULL) {
+ return;
+ }
+
+ priv_emptyset(lPrivSet);
+
+ if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
+ return;
+ }
+
+ priv_freeset(lPrivSet);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ LibHalContext *ctx = NULL;
+ DBusError error;
+ GMainLoop *loop = g_main_loop_new(NULL, FALSE);
+ char *udi;
+
+ if ((udi = getenv("UDI")) == NULL) {
+ return (0);
+ }
+
+ drop_privileges();
+
+ setup_logger();
+
+ dbus_error_init(&error);
+
+ if ((ctx = libhal_ctx_init_direct(&error)) == NULL) {
+ return (0);
+ }
+
+ if (!libhal_device_addon_is_ready(ctx, udi, &error)) {
+ return (0);
+ }
+
+ if (nds_claim_interface(ctx, udi, &error) != 0) {
+ return (0);
+ }
+
+ g_main_loop_run(loop);
+
+ /* NOTREACHED */
+}
diff --git a/usr/src/cmd/hal/addons/network-devices/cache.c b/usr/src/cmd/hal/addons/network-devices/cache.c
new file mode 100644
index 0000000000..27849cf3bd
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/cache.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <libhal.h>
+#include <logger.h>
+
+#include <glib.h>
+
+#include "network-discovery.h"
+
+/*
+ * The interfaces in this file comprise a means of keeping track of devices
+ * that we have already seen and those that have gone missing. This allows
+ * us to quickly determine if we need to probe the device and quickly search
+ * for devices that are no longer available.
+ */
+
+typedef struct {
+ LibHalContext *ctx;
+ time_t timestamp;
+} removal_args_t;
+
+static GHashTable *seen = NULL;
+
+static gboolean
+device_remove_if_stale(gpointer key, gpointer value, gpointer user_data)
+{
+ gboolean result = FALSE;
+ removal_args_t *args = user_data;
+ char *name = key;
+ time_t *val = value;
+
+ HAL_DEBUG(("test stale: %s (%d > %d)", name, args->timestamp, *val));
+ if (args->timestamp > *val) {
+ DBusError error;
+ char **udi = NULL;
+ int num = 0;
+
+ dbus_error_init(&error);
+ udi = libhal_manager_find_device_string_match(args->ctx,
+ "network_device.address", name,
+ &num, &error);
+
+ if (udi != NULL) {
+ int i;
+
+ for (i = 0; i < num; i++) {
+ libhal_remove_device(args->ctx, udi[i], &error);
+ HAL_DEBUG(("remove: %s (%s)", name, udi[i]));
+ }
+ libhal_free_string_array(udi);
+ result = TRUE;
+ }
+ if (dbus_error_is_set(&error))
+ dbus_error_free(&error);
+ }
+
+ return (result);
+}
+
+void
+scan_for_stale_devices(LibHalContext *ctx, time_t timestamp)
+{
+ if (seen != NULL) {
+ removal_args_t args[1];
+
+ args->ctx = ctx;
+ args->timestamp = timestamp;
+
+ g_hash_table_foreach_remove(seen, device_remove_if_stale, args);
+ }
+}
+
+gboolean
+device_seen(char *name)
+{
+ gboolean result;
+ char *key;
+ time_t *val;
+
+ if (seen == NULL)
+ seen = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, free);
+
+ result = g_hash_table_lookup_extended(seen, name,
+ (gpointer)&key, (gpointer)&val);
+
+ if ((result == FALSE) && ((val = calloc(1, sizeof (*val))) != NULL)) {
+ g_hash_table_insert(seen, strdup(name), val);
+ }
+ (void) time(val);
+ HAL_DEBUG(("seen: %s (%d)", name, *val));
+
+ return (result);
+}
diff --git a/usr/src/cmd/hal/addons/network-devices/common.c b/usr/src/cmd/hal/addons/network-devices/common.c
new file mode 100644
index 0000000000..720671236f
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/common.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <libhal.h>
+#include <logger.h>
+
+#include <glib.h>
+
+#include "network-discovery.h"
+#define NP(x) (x?x:"NULL")
+
+extern int snmp_printer_info(char *hostname, char *community,
+ char **manufacturer, char **model, char **description,
+ char **serial_no, char ***command_set, char **uri);
+
+void
+network_device_name_to_udi(char *udi, size_t size, ...)
+{
+ va_list ap;
+ char *element;
+ int i;
+
+ udi[0] = '\0';
+ va_start(ap, size);
+ while ((element = va_arg(ap, char *)) != NULL) {
+ if (element[0] != '/')
+ strlcat(udi, "/", size);
+ strlcat(udi, element, size);
+ }
+ va_end(ap);
+
+ for (i = 0; udi[i] != NULL; i++)
+ if (udi[i] == '.')
+ udi[i] = '_';
+}
+
+static void nop(int sig) {}
+
+static int
+test_socket_access(struct in6_addr *addr, int port)
+{
+ int sd, rc;
+ struct sockaddr_in6 sin6;
+ void (*hndlr)(int);
+
+ memset(&sin6, 0, sizeof (sin6));
+ sin6.sin6_family = AF_INET6;
+ memcpy(&sin6.sin6_addr, addr, sizeof (*addr));
+ sin6.sin6_port = htons(port);
+
+ sd = socket(AF_INET6, SOCK_STREAM, 0);
+ hndlr = signal(SIGALRM, nop);
+ alarm(1);
+ rc = connect(sd, (struct sockaddr *)&sin6, sizeof (sin6));
+ alarm(0);
+ if (hndlr != NULL)
+ signal(SIGALRM, hndlr);
+ close(sd);
+
+ return ((rc < 0) ? 1 : 0);
+}
+
+int
+is_listening(char *hostname, int port)
+{
+ char *uri = NULL, addr_string[INET6_ADDRSTRLEN];
+ struct in6_addr ipv6addr[1];
+ int errnum;
+ struct hostent *hp;
+
+ hp = getipnodebyname(hostname, AF_INET6,
+ AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &errnum);
+ if (hp != NULL) {
+ (void) memcpy(&ipv6addr, hp->h_addr_list[0], hp->h_length);
+ } else
+ return (-1);
+
+ return (test_socket_access(ipv6addr, port));
+}
+
+static char *
+addr_to_string(char *prefix, uchar_t *mac, int mac_len, char *buf, int buf_len)
+{
+ int i, n = 0;
+
+ buf[0] = '\0';
+ if (prefix != NULL)
+ n = sprintf(buf, prefix);
+ for (i = 0; ((i < (mac_len)) && (n < buf_len)); i++)
+ n += sprintf(buf + n, "%2.2X", *mac++);
+
+ return (buf);
+}
+
+static char *
+pseudo_serialno_from_addr(char *name)
+{
+ int sd, rc, errnum;
+ char buf[128];
+ struct hostent *hp;
+ struct xarpreq ar;
+
+ if (name == NULL)
+ return (NULL);
+
+ memset(&ar, 0, sizeof (ar));
+
+ hp = getipnodebyname(name, AF_INET6, AI_ADDRCONFIG, &errnum);
+ if (hp != NULL) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ar.xarp_pa;
+
+ sin6->sin6_family = AF_INET6;
+ (void) memcpy(&sin6->sin6_addr, hp->h_addr_list[0],
+ hp->h_length);
+ } else {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&ar.xarp_pa;
+
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = inet_addr(name);
+ }
+
+ sd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ ar.xarp_ha.sdl_family = AF_LINK;
+ rc = ioctl(sd, SIOCGXARP, (caddr_t)&ar);
+
+ close(sd);
+
+ if (ar.xarp_flags & ATF_COM) { /* use the MAC address */
+ uchar_t *ea = (uchar_t *)LLADDR(&ar.xarp_ha);
+
+ addr_to_string("LLADDR-", ea, ar.xarp_ha.sdl_alen,
+ buf, sizeof (buf));
+
+ } else if (hp != NULL) { /* use the IPv6 address */
+ addr_to_string("IPV6ADDR-", (uchar_t *)&hp->h_addr_list[0],
+ hp->h_length, buf, sizeof (buf));
+ } else { /* use the IPv4 address */
+ struct sockaddr_in *sin = (struct sockaddr_in *)&ar.xarp_pa;
+
+ addr_to_string("IPV4ADDR-", (uchar_t *)&sin->sin_addr.s_addr, 4,
+ buf, sizeof (buf));
+ }
+
+ return (strdup(buf));
+}
+
+int
+add_network_printer(LibHalContext *ctx, char *base, char *hostaddr,
+ char *device, char *community)
+{
+ DBusError error;
+ int rc = -1;
+ char udi[128];
+ char *tmp_udi = NULL;
+ static char *parent = NULL;
+ char *manufacturer = NULL, *model = NULL, *description = NULL,
+ *uri = NULL, *sn, *serial;
+
+ sn = serial = pseudo_serialno_from_addr(hostaddr);
+
+ if (parent == NULL)
+ parent = getenv("UDI");
+
+ dbus_error_init(&error);
+
+ network_device_name_to_udi(udi, sizeof (udi), base, serial, NULL);
+
+ if (libhal_device_exists(ctx, udi, &error) == TRUE)
+ goto out;
+
+ if ((tmp_udi = libhal_new_device(ctx, &error)) == NULL)
+ goto out;
+
+ snmp_printer_info(hostaddr, community, &manufacturer, &model,
+ &description, &serial, NULL, &uri);
+
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "info.parent", parent, &error);
+
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "info.category", "printer", &error);
+
+ libhal_device_property_strlist_append(ctx, tmp_udi,
+ "info.capabilities", "printer", &error);
+ libhal_device_property_strlist_append(ctx, tmp_udi,
+ "info.capabilities", "network_device", &error);
+
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "network_device.address", hostaddr, &error);
+
+ if ((community != NULL) && (strcasecmp(community, "public") != 0))
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "network_device.snmp_community", community, &error);
+
+ if ((uri != NULL) || (device != NULL))
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "printer.device", (uri ? uri : device), &error);
+
+ if (serial != NULL)
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "printer.serial", serial, &error);
+
+ if (manufacturer != NULL)
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "printer.vendor", manufacturer, &error);
+
+ if (model != NULL)
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "printer.product", model, &error);
+
+ if (description != NULL)
+ libhal_device_set_property_string(ctx, tmp_udi,
+ "printer.description", description, &error);
+
+ /* commit the changes to the new UDI */
+ rc = libhal_device_commit_to_gdl(ctx, tmp_udi, udi, &error);
+
+out:
+ HAL_DEBUG(("result: %s (%s): %s, %s, %s, %s, %s", hostaddr, udi,
+ NP(manufacturer), NP(model), NP(description), NP(serial),
+ NP(uri)));
+
+ if (tmp_udi != NULL)
+ free(tmp_udi);
+ if (manufacturer != NULL)
+ free(manufacturer);
+ if (model != NULL)
+ free(model);
+ if (description != NULL)
+ free(description);
+ if (uri != NULL)
+ free(uri);
+ if (sn != NULL)
+ free(sn);
+
+ if (dbus_error_is_set(&error)) {
+ HAL_WARNING(("%s: %s", error.name, error.message));
+ dbus_error_free(&error);
+ }
+
+ HAL_DEBUG(("add: %s (%s)", hostaddr, udi));
+
+ return (rc);
+}
+
+static int
+number_of_interfaces(int s)
+{
+ int rc = -1;
+ struct lifnum n;
+
+ memset(&n, 0 , sizeof (n));
+ n.lifn_family = AF_UNSPEC;
+ if (ioctl(s, SIOCGLIFNUM, (char *)&n) == 0)
+ rc = n.lifn_count;
+
+ return (rc);
+}
+
+static char *
+broadcast_address(int s, char *ifname)
+{
+ char *result = NULL;
+ struct lifreq r;
+
+ memset(&r, 0, sizeof (r));
+ strncpy((char *)&r.lifr_name, ifname, sizeof (r.lifr_name));
+ if (ioctl(s, SIOCGLIFBRDADDR, (char *)&r) == 0) {
+ char buf[INET6_ADDRSTRLEN];
+
+ switch (r.lifr_broadaddr.ss_family) {
+ case AF_INET: {
+ struct sockaddr_in *s =
+ (struct sockaddr_in *)&r.lifr_broadaddr;
+ result = (char *)inet_ntop(AF_INET, &s->sin_addr,
+ buf, sizeof (buf));
+ }
+ break;
+ case AF_INET6: {
+ struct sockaddr_in6 *s =
+ (struct sockaddr_in6 *)&r.lifr_broadaddr;
+ result = (char *)inet_ntop(AF_INET6, &s->sin6_addr,
+ buf, sizeof (buf));
+ }
+ break;
+ }
+
+ if (result != NULL)
+ result = strdup(result);
+ }
+
+ return (result);
+}
+
+GList *
+broadcast_addresses()
+{
+ GList *result = NULL;
+ int s;
+ struct lifconf c;
+ int count;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return (NULL);
+
+ count = number_of_interfaces(s);
+
+ memset(&c, 0, sizeof (c));
+ c.lifc_family = AF_UNSPEC;
+ c.lifc_flags = IFF_BROADCAST;
+ c.lifc_buf = calloc(count, sizeof (struct lifreq));
+ c.lifc_len = (count * sizeof (struct lifreq));
+
+ if (ioctl(s, SIOCGLIFCONF, (char *)&c) == 0) {
+ struct lifreq *r = c.lifc_req;
+
+ for (count = c.lifc_len / sizeof (struct lifreq);
+ count > 0; count--, r++) {
+ char *address = broadcast_address(s, r->lifr_name);
+
+ if (address != NULL) /* add it to the list */
+ result = g_list_append(result, address);
+ }
+ }
+ free(c.lifc_buf);
+ close(s);
+
+ return (result);
+}
diff --git a/usr/src/cmd/hal/addons/network-devices/network-discovery.h b/usr/src/cmd/hal/addons/network-devices/network-discovery.h
new file mode 100644
index 0000000000..9619a5d9be
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/network-discovery.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef NETWORK_DEVICE_COMMON_H
+#define NETWORK_DEVICE_COMMON_H
+
+#include <libhal.h>
+
+extern void network_device_name_to_udi(char *udi, size_t size, ...);
+extern int add_network_printer(LibHalContext *ctx, char *parent, char *hostaddr,
+ char *device, char *community);
+
+extern gboolean scan_for_devices_using_snmp(LibHalContext *ctx, char *parent,
+ char *community, char *network);
+extern void scan_for_stale_devices(LibHalContext *ctx, time_t timestamp);
+extern gboolean device_seen(char *name);
+
+extern int is_listening(char *hostname, int port);
+
+extern GList *broadcast_addresses();
+
+#endif /* NETWORK_DEVICE_COMMON_H */
diff --git a/usr/src/cmd/hal/addons/network-devices/network-discovery.xml b/usr/src/cmd/hal/addons/network-devices/network-discovery.xml
new file mode 100644
index 0000000000..24307664ef
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/network-discovery.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ Licensed under the Academic Free License version 2.1
+
+ ident "%Z%%M% %I% %E% SMI"
+
+ NOTE: This service manifest is not editable; its contents will
+ be overwritten by package or patch operations, including
+ operating system upgrade. Make customizations in a different
+ file.
+
+ Service manifest for HAL network attached device discovery.
+-->
+
+<service_bundle type='manifest' name='SUNWhalr:device-discovery'>
+
+<service
+ name='network/device-discovery/printers'
+ type='service'
+ version='1'>
+
+ <dependency name='usr'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/local' />
+ </dependency>
+
+ <dependency name='network-service'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/network/service' />
+ </dependency>
+
+ <dependency name='dbus'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/dbus' />
+ </dependency>
+
+ <dependency name='hal'
+ type='service'
+ grouping='require_all'
+ restart_on='refresh'>
+ <service_fmri value='svc:/system/hal' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-network-discovery %m %i'
+ timeout_seconds='30'>
+ </exec_method>
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec='/lib/svc/method/svc-network-discovery %m %i'
+ timeout_seconds='30'>
+ </exec_method>
+
+ <exec_method
+ type='method'
+ name='refresh'
+ exec='/lib/svc/method/svc-network-discovery %m %i'
+ timeout_seconds='30'>
+ </exec_method>
+
+ <property_group name='startd' type='framework'>
+ <propval name='duration' type='astring' value='transient' />
+ </property_group>
+
+ <instance
+ name='snmp'
+ enabled='false'>
+
+ <method_context>
+ <method_credential user='root' group='root' />
+ </method_context>
+
+ <property_group name='general' type='framework'>
+ <!-- to start/stop the discovery service -->
+ <propval name='action_authorization' type='astring'
+ value='solaris.smf.manage.discovery.printers.snmp' />
+ </property_group>
+
+ <property_group name='config' type='framework'>
+ <!-- authorization to modify config properties -->
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.value.discovery.printers.snmp' />
+ </property_group>
+ </instance>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ Hardware Abstraction Layer network attached device discovery
+ </loctext>
+ </common_name>
+ </template>
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/hal/addons/network-devices/snmp.c b/usr/src/cmd/hal/addons/network-devices/snmp.c
new file mode 100644
index 0000000000..2213ba5049
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/snmp.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <glib.h>
+
+#include <libhal.h>
+#include <logger.h>
+
+#undef PACKAGE_STRING
+#undef PACKAGE_VERSION
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+
+#include "network-discovery.h"
+#include "printer.h"
+
+#define NP(x) (x?x:"NULL")
+
+static GList *new_addrs = NULL;
+
+static void
+add_snmp_device(LibHalContext *ctx, char *parent, char *name, char *community)
+{
+ /* most printers listen on the appsocket port (9100) */
+ if (is_listening(name, 9100) == 0) {
+ char device[128];
+
+ snprintf(device, sizeof (device), "socket://%s:9100", name);
+
+ add_network_printer(ctx, parent, name, device, community);
+ }
+
+ /*
+ * This would be a good place to detect other types of devices or other
+ * device capabilities. scanners, removable media, storage, ...
+ */
+}
+
+static int
+snmp_response_cb(int operation, struct snmp_session *sp, int reqid,
+ struct snmp_pdu *pdu, void *data)
+{
+ struct sockaddr_in *addr = pdu->transport_data;
+ char *name;
+
+ name = inet_ntoa(addr->sin_addr);
+
+ /* have we already seen this network device */
+ if (device_seen(name) == FALSE)
+ new_addrs = g_list_append(new_addrs, strdup(name));
+
+ return (0);
+}
+
+gboolean
+scan_for_devices_using_snmp(LibHalContext *ctx, char *parent, char *community,
+ char *network)
+{
+ struct snmp_session session, *ss;
+ struct snmp_pdu *request = NULL, *response = NULL;
+ oid Oid[MAX_OID_LEN];
+ unsigned int oid_len = MAX_OID_LEN;
+ GList *elem;
+
+ HAL_DEBUG(("scan_for_devices_using_snmp(0x%8.8x, %s, %s, %s)",
+ ctx, NP(parent), NP(community), NP(network)));
+
+ init_snmp("snmp-scan");
+ init_mib();
+
+ /* initialize the SNMP session */
+ snmp_sess_init(&session);
+ session.peername = network;
+ session.community = (uchar_t *)community;
+ session.community_len = strlen((const char *)session.community);
+ session.version = SNMP_VERSION_1;
+
+ if ((ss = snmp_open(&session)) == NULL)
+ return (FALSE);
+
+ /* initialize the request PDU */
+ request = snmp_pdu_create(SNMP_MSG_GET);
+
+ /* add the requested data (everyone should have a sysDescr.0) */
+ if (!read_objid("SNMPv2-MIB::sysDescr.0", Oid, &oid_len))
+ snmp_perror("sysDescr.0");
+ snmp_add_null_var(request, Oid, oid_len);
+
+ snmp_async_send(ss, request, snmp_response_cb, NULL);
+
+ /* detect any new devices */
+ while (1) {
+ int fds = 0, block = 0;
+ fd_set fdset;
+ struct timeval timeout;
+
+ FD_ZERO(&fdset);
+ snmp_select_info(&fds, &fdset, &timeout, &block);
+ fds = select(fds, &fdset, NULL, NULL, block ? NULL : &timeout);
+ if (fds < 0) {
+ perror("select failed");
+ continue;
+ } if (fds == 0) {
+ break;
+ } else {
+ snmp_read(&fdset);
+ }
+ }
+
+ snmp_close(ss);
+
+ /* add the newly detected devices */
+ for (elem = new_addrs; elem != NULL; elem = g_list_next(elem)) {
+ add_snmp_device(ctx, parent, (char *)elem->data, community);
+ free(elem->data);
+ }
+ g_list_free(new_addrs);
+ new_addrs = NULL;
+
+ return (TRUE);
+}
diff --git a/usr/src/cmd/hal/addons/network-devices/svc-network-discovery b/usr/src/cmd/hal/addons/network-devices/svc-network-discovery
new file mode 100644
index 0000000000..eec0d13486
--- /dev/null
+++ b/usr/src/cmd/hal/addons/network-devices/svc-network-discovery
@@ -0,0 +1,117 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+
+#
+# ident "%Z%%M% %I% %E% SMI"
+
+. /lib/svc/share/smf_include.sh
+
+METHOD=${1}
+INSTANCE=${2}
+
+DBUS_DESTINATION="org.freedesktop.Hal"
+MESSAGE_PREFIX="org.freedesktop.Hal.Device.NetworkDiscovery"
+OBJECT_PATH="/org/freedesktop/Hal/devices/network_attached"
+SMF_PROPERTY_GROUP="config"
+HAL_PROPERTY_GROUP="network_discovery"
+SVCS=/usr/bin/svcs
+
+usage() {
+ echo "Usage: $0 { start | stop | refresh } { snmp }"
+ exit $SMF_EXIT_ERR_FATAL
+}
+
+execute() {
+ echo "$*"
+ $*
+
+ return $?
+}
+
+start_snmp() {
+ interval=`/bin/svcprop -p config/interval ${SMF_FMRI} 2>/dev/null`
+ community=`/bin/svcprop -p config/community ${SMF_FMRI} 2>/dev/null`
+ network=`/bin/svcprop -p config/network ${SMF_FMRI} 2>/dev/null`
+ MESSAGE="${MESSAGE_PREFIX}.EnablePrinterScanningViaSNMP"
+ MESSAGE="${MESSAGE} int32:${interval:-60}"
+ MESSAGE="${MESSAGE} string:${community:-public}"
+ MESSAGE="${MESSAGE} string:${network:-0.0.0.0}"
+
+ execute /usr/bin/dbus-send --system --print-reply \
+ --dest=${DBUS_DESTINATION} --type=method_call ${OBJECT_PATH} \
+ ${MESSAGE}
+ return $?
+}
+
+stop_snmp() {
+ MESSAGE="${MESSAGE_PREFIX}.DisablePrinterScanningViaSNMP"
+
+ execute /usr/bin/dbus-send --system --print-reply \
+ --dest=${DBUS_DESTINATION} --type=method_call ${OBJECT_PATH} \
+ ${MESSAGE}
+ return $?
+}
+
+refresh_snmp() {
+ community=`/bin/svcprop -p config/community ${SMF_FMRI} 2>/dev/null`
+ network=`/bin/svcprop -p config/network ${SMF_FMRI} 2>/dev/null`
+ MESSAGE="${MESSAGE_PREFIX}.EnablePrinterScanningViaSNMP"
+ MESSAGE="${MESSAGE} string:${community:-public}"
+ MESSAGE="${MESSAGE} string:${network:-0.0.0.0}"
+
+ execute /usr/bin/dbus-send --system --print-reply \
+ --dest=${DBUS_DESTINATION} --type=method_call ${OBJECT_PATH} \
+ ${MESSAGE}
+ return $?
+}
+
+case "${METHOD}" in
+ 'start')
+ ;;
+ 'stop')
+ count=`$SVCS -o STATE hal 2>>/dev/null | grep -c "^online"`
+ if [ $count -eq 0 ] ; then
+ exit 0 # if HAL isn't running, there is nothing to do
+ fi
+ ;;
+ 'refresh')
+ ;;
+ *)
+ usage
+ ;;
+esac
+
+case "${INSTANCE}" in
+ 'snmp')
+ ;;
+ *)
+ usage
+ ;;
+esac
+
+${METHOD}_${INSTANCE}
+exit_code=$?
+
+exit $exit_code
diff --git a/usr/src/cmd/hal/fdi/Makefile b/usr/src/cmd/hal/fdi/Makefile
index ba5565fe94..6724d578bf 100644
--- a/usr/src/cmd/hal/fdi/Makefile
+++ b/usr/src/cmd/hal/fdi/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -44,13 +44,15 @@ FDIS = information/10freedesktop/10-camera-ptp.fdi \
information/10freedesktop/10-wireless-mice.fdi \
policy/10osvendor/10-keyboard-policy.fdi \
policy/10osvendor/10-laptop-panel-mgmt-policy.fdi \
+ policy/10osvendor/10-network-attached.fdi \
policy/10osvendor/10-power-mgmt-policy.fdi \
policy/10osvendor/10-toshiba-buttons.fdi \
policy/10osvendor/20-storage-methods.fdi \
policy/10osvendor/20-zfs-methods.fdi \
preprobe/10osvendor/10-ide-drives.fdi \
preprobe/10osvendor/20-ignore-fixed-storage.fdi \
- preprobe/10osvendor/20-ignore-lofi.fdi
+ preprobe/10osvendor/20-ignore-lofi.fdi \
+ preprobe/10osvendor/20-printers.fdi
FDIDIR = $(ROOT_HAL_FDI)
ROOTFDIS = $(FDIS:%=$(FDIDIR)/%)
diff --git a/usr/src/cmd/hal/fdi/policy/10osvendor/10-network-attached.fdi b/usr/src/cmd/hal/fdi/policy/10osvendor/10-network-attached.fdi
new file mode 100644
index 0000000000..85a5d37bb2
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/policy/10osvendor/10-network-attached.fdi
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ Licensed under the Academic Free License version 2.1
+
+ ident "%Z%%M% %I% %E% SMI"
+-->
+
+<deviceinfo version="0.2">
+
+ <!--
+ Create a place holder in the HAL device tree for the network attached
+ device discovery service to attach.
+ -->
+ <device>
+ <match key="system.kernel.name" string="SunOS">
+ <spawn udi="/org/freedesktop/Hal/devices/network_attached"/>
+ </match>
+ </device>
+
+ <!--
+ Attach an instance of the network attached device discovery service to
+ the new HAL device tree node.
+ -->
+ <device>
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/network_attached">
+
+ <append key="info.product" type="strlist">Network Attached Devices</append>
+ <append key="info.capabilities" type="strlist">network_device_discovery</append>
+ <append key="info.addons" type="strlist">hald-addon-network-discovery</append>
+ <!--
+ The addon implements the 'org.freedesktop.Hal.Device.NetworkDiscovery'
+ interface. This interface controls the operation of the addon module.
+ -->
+
+ </match>
+ </device>
+
+</deviceinfo>
diff --git a/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-printers.fdi b/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-printers.fdi
new file mode 100644
index 0000000000..7159c954cf
--- /dev/null
+++ b/usr/src/cmd/hal/fdi/preprobe/10osvendor/20-printers.fdi
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ Licensed under the Academic Free License version 2.1
+
+ ident "%Z%%M% %I% %E% SMI"
+-->
+
+<deviceinfo version="0.2">
+
+ <!-- probe network attached printers for information -->
+ <device>
+ <match key="network_device.address" exists="true">
+ <match key="info.capabilities" contains="printer">
+ <append key="info.callouts.add" type="strlist">hald-probe-network-printer</append>
+ </match>
+ </match>
+ </device>
+
+ <!-- probe USB printers for information -->
+ <device>
+ <match key="info.solaris.driver" equals="usbprn">
+ <append key="info.callouts.add" type="strlist">hald-probe-printer</append>
+ </match>
+ </device>
+
+ <!-- probe ECPP parallel ports for printer information -->
+ <device>
+ <match key="info.solaris.driver" contains="ecpp">
+ <append key="info.callouts.add" type="strlist">hald-probe-printer</append>
+ </match>
+ </device>
+
+</deviceinfo>
+
diff --git a/usr/src/cmd/hal/probing/Makefile b/usr/src/cmd/hal/probing/Makefile
index 8108cc147f..00244dcbe4 100644
--- a/usr/src/cmd/hal/probing/Makefile
+++ b/usr/src/cmd/hal/probing/Makefile
@@ -25,7 +25,7 @@
# ident "%Z%%M% %I% %E% SMI"
#
-SUBDIRS = storage volume printer battery
+SUBDIRS = storage volume printer network-printer battery
all := TARGET= all
install := TARGET= install
diff --git a/usr/src/cmd/hal/probing/network-printer/Makefile b/usr/src/cmd/hal/probing/network-printer/Makefile
new file mode 100644
index 0000000000..bdf1450a56
--- /dev/null
+++ b/usr/src/cmd/hal/probing/network-printer/Makefile
@@ -0,0 +1,68 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+PROG = hald-probe-network-printer
+OBJS = probe-network-printer.o logger.o probe-snmp.o printer.o
+SRCS = probe-network-printer.c
+
+include ../../../Makefile.cmd
+include ../../Makefile.hal
+
+ROOTCMDDIR = $(ROOTLIB_HAL)
+
+LDLIBS += -lc -ldbus-1 -lhal
+LDLIBS += -L$(SFWLIBDIR) -R$(SFWLIBDIR) $(ZIGNORE) -lnetsnmp
+
+CPPFLAGS += $(HAL_DBUS_CPPFLAGS) $(HAL_CONFIG_CPPFLAGS)
+CPPFLAGS += -I$(ROOT)/usr/include/hal -I../../utils -I../../hald
+CPPFLAGS += -I$(SFWINCDIR)
+C99MODE = $(C99_ENABLE)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+logger.o: ../../hald/logger.c
+ $(COMPILE.c) -o $@ ../../hald/logger.c
+ $(POST_PROCESS_O)
+
+printer.o: ../../utils/printer.c
+ $(COMPILE.c) -o $@ ../../utils/printer.c
+ $(POST_PROCESS_O)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTCMD)
+
+clean:
+ $(RM) $(OBJS)
+
+FRC:
+
+include ../../../Makefile.targ
diff --git a/usr/src/cmd/hal/probing/network-printer/probe-network-printer.c b/usr/src/cmd/hal/probing/network-printer/probe-network-printer.c
new file mode 100644
index 0000000000..fc7296bc9b
--- /dev/null
+++ b/usr/src/cmd/hal/probing/network-printer/probe-network-printer.c
@@ -0,0 +1,118 @@
+/***************************************************************************
+ *
+ * probe-network-printer.c : Probe for snmp printer device information
+ *
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ **************************************************************************/
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/prnio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <libhal.h>
+#include <logger.h>
+
+#include "printer.h"
+
+int
+main(int argc, char *argv[])
+{
+ int ret = 1;
+ char *udi;
+ char *printer_address,
+ *community;
+ DBusError error;
+ LibHalContext *ctx = NULL;
+ LibHalChangeSet *cs = NULL;
+ char *manufacturer = NULL,
+ *model = NULL,
+ *serial_number = NULL,
+ *description = NULL,
+ **command_set = NULL,
+ *device_uri = NULL;
+ extern int snmp_printer_info(char *hostname, char *community,
+ char **manufacturer, char **model, char **description,
+ char **serial_number, char ***command_set,
+ char **device_uri);
+
+ dbus_error_init(&error);
+
+ if ((udi = getenv("UDI")) == NULL)
+ goto out;
+
+ printer_address = getenv("HAL_PROP_NETWORK_DEVICE_ADDRESS");
+ if (printer_address == NULL)
+ goto out;
+
+ community = getenv("HAL_PROP_NETWORK_DEVICE_SNMP_COMMUNITY");
+ if (community == NULL)
+ community = "public";
+
+ setup_logger();
+
+ dbus_error_init(&error);
+
+ if ((ctx = libhal_ctx_init_direct(&error)) == NULL)
+ goto out;
+
+ if ((cs = libhal_device_new_changeset(udi)) == NULL) {
+ HAL_DEBUG(("Cannot allocate changeset"));
+ goto out;
+ }
+
+ /* Probe the printer for characteristics via SNMP */
+ ret = snmp_printer_info(printer_address, community, &manufacturer,
+ &model, &description, &serial_number, &command_set,
+ &device_uri);
+ if (ret < 0) {
+ HAL_DEBUG(("Cannot get snmp data for %s: %s",
+ printer_address, strerror(errno)));
+ goto out;
+ }
+
+ /* Add printer characteristics to the HAL device tree */
+ ret = add_printer_info(cs, udi, manufacturer, model, description,
+ serial_number, command_set, device_uri);
+ if (ret < 0) {
+ HAL_DEBUG(("Cannot add printer data for %s to %s: %s",
+ printer_address, udi, strerror(errno)));
+ goto out;
+ }
+
+ libhal_device_commit_changeset(ctx, cs, &error);
+
+ ret = 0;
+
+out:
+ if (cs != NULL) {
+ libhal_device_free_changeset(cs);
+ }
+
+ if (ctx != NULL) {
+ if (dbus_error_is_set(&error)) {
+ dbus_error_free(&error);
+ }
+ libhal_ctx_shutdown(ctx, &error);
+ libhal_ctx_free(ctx);
+ }
+
+ return (ret);
+}
diff --git a/usr/src/cmd/hal/probing/network-printer/probe-snmp.c b/usr/src/cmd/hal/probing/network-printer/probe-snmp.c
new file mode 100644
index 0000000000..7645ff9977
--- /dev/null
+++ b/usr/src/cmd/hal/probing/network-printer/probe-snmp.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <strings.h>
+
+#undef PACKAGE_STRING
+#undef PACKAGE_VERSION
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+
+#include "logger.h"
+#include "printer.h"
+
+static int
+hrDeviceDesc_to_info(char *string, char **manufacturer, char **model,
+ char **description)
+{
+ int rc = -1;
+ char *s;
+
+ if (string == NULL)
+ return (-1);
+
+ /* if it has : and ; in it, it's probably a 1284 device id */
+ if ((strchr(string, ':') != NULL) && (strchr(string, ';') != NULL)) {
+ rc = ieee1284_devid_to_printer_info(string, manufacturer, model,
+ description, NULL, NULL, NULL);
+ } else {
+ rc = 0;
+ *description = strdup(string);
+ *manufacturer = strdup(string);
+ if ((s = strchr(*manufacturer, ' ')) != NULL) {
+ *s++ = NULL;
+ *model = strdup(s);
+ }
+ }
+
+ return (rc);
+}
+
+static struct snmp_pdu *
+snmp_get_item(char *host, char *community, char *mib_item)
+{
+ int status;
+ struct snmp_session session, *ss;
+ struct snmp_pdu *request = NULL, *result = NULL;
+ oid Oid[MAX_OID_LEN];
+ unsigned int oid_len = MAX_OID_LEN;
+
+ /* initialize the SNMP session */
+ snmp_sess_init(&session);
+ session.peername = host;
+ session.community = (uchar_t *)community;
+ session.community_len = strlen((const char *)session.community);
+ session.version = SNMP_VERSION_1;
+ session.retries = 0;
+
+ if ((ss = snmp_open(&session)) == NULL)
+ return (NULL);
+
+ /* add the requested data */
+ if (!read_objid(mib_item, Oid, &oid_len))
+ snmp_perror(mib_item);
+
+ /* initialize the request PDU */
+ request = snmp_pdu_create(SNMP_MSG_GET);
+ snmp_add_null_var(request, Oid, oid_len);
+
+ status = snmp_synch_response(ss, request, &result);
+
+ snmp_close(ss);
+
+ return (result);
+}
+
+static char *
+snmp_get_string(char *host, char *community, char *mib_item)
+{
+ char *result = NULL;
+ struct snmp_pdu *response = NULL;
+
+ response = snmp_get_item(host, community, mib_item);
+
+ if ((response != NULL) && (response->errstat == SNMP_ERR_NOERROR)) {
+ struct variable_list *v = response->variables;
+
+ if (v->type == ASN_OCTET_STR) {
+ result = calloc(1, v->val_len + 1);
+ memcpy(result, v->val.string, v->val_len);
+ }
+ }
+
+ HAL_DEBUG(("snmp_get_string(%s, %s, %s): %s", host, community, mib_item,
+ (result?result:"NULL")));
+
+ if (response != NULL)
+ snmp_free_pdu(response);
+
+ return (result);
+}
+
+static int
+snmp_brother_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * Brother printers appear to store
+ * 1284 DevID SNMPv2-SMI::enterprises.2435.2.3.9.1.1.7.0
+ * Serial Number SNMPv2-SMI::enterprises.2435.2.3.9.4.2.1.5.5.1.0
+ */
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2435.2.3.9.1.1.7.0");
+ if (tmp != NULL) {
+ rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
+ description, NULL, serial_no, command_set);
+ free(tmp);
+
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2435.2.3.9.4.2.1.5.5.1.0");
+ }
+
+ return (rc);
+}
+
+static int
+snmp_ricoh_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * OKI printers appear to store
+ * 1284 DevID SNMPv2-SMI::enterprises.367.3.2.1.1.1.11.0
+ * Serial Number SNMPv2-SMI::enterprises.367.3.2.1.2.1.4.0
+ */
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.367.3.2.1.1.1.11.0");
+ if (tmp != NULL) {
+ rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
+ description, NULL, serial_no, command_set);
+ free(tmp);
+
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.367.3.2.1.2.1.4.0");
+ }
+
+ return (rc);
+}
+
+static int
+snmp_lexmark_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * Lexmark printers appear to store
+ * 1284 DevID SNMPv2-SMI::enterprises.641.2.1.2.1.3.1
+ * Serial Number SNMPv2-SMI::enterprises.641.2.1.2.1.6.1
+ */
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.641.2.1.2.1.3.1");
+ if (tmp != NULL) {
+ rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
+ description, NULL, serial_no, command_set);
+ free(tmp);
+
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.641.2.1.2.1.6.1");
+ }
+
+ return (rc);
+}
+
+static int
+snmp_xerox_phaser_printer_info(char *hostname, char *community,
+ char **manufacturer, char **model, char **description,
+ char **serial_no, char ***command_set, char **uri)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * Xerox Phaser XXXX printers store their
+ * 1284 DevID SNMPv2-SMI::enterprises.253.8.51.1.2.1.20.1
+ * Manufacturer:
+ * SNMPv2-SMI::enterprises.128.2.1.3.1.1.0
+ * SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.16
+ * SNMPv2-SMI::enterprises.23.2.32.4.1.0
+ * Model:
+ * SNMPv2-SMI::enterprises.128.2.1.3.1.2.0
+ * SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.17
+ * SNMPv2-SMI::enterprises.23.2.32.4.2.0
+ * Description SNMPv2-SMI::enterprises.253.8.53.3.2.1.2.1
+ * Serial Number SNMPv2-SMI::enterprises.253.8.53.3.2.1.3.1
+ * Uri SNMPv2-SMI::enterprises.128.2.1.3.6.23.1.5.1
+ */
+
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.253.8.51.1.2.1.20.1");
+ if (tmp != NULL) {
+ rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
+ description, NULL, serial_no, command_set);
+ free(tmp);
+ }
+
+ if (*manufacturer == NULL)
+ *manufacturer = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.128.2.1.3.1.1.0");
+ if (*manufacturer == NULL)
+ *manufacturer = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.16");
+ if (*manufacturer == NULL)
+ *manufacturer = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.23.2.32.4.1.0");
+
+ if (*model == NULL)
+ *model = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.128.2.1.3.1.2.0");
+ if (*model == NULL)
+ *model = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.17");
+ if (*model == NULL)
+ *model = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.23.2.32.4.2.0");
+
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.253.8.53.3.2.1.3.1");
+
+ if ((*manufacturer != NULL) && (*model != NULL))
+ rc = 0;
+
+ return (rc);
+}
+
+static int
+snmp_qms_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set, char **uri)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * MINOLTA-QMS printers appear to store
+ * Prouct Name SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.1.1.16.1
+ * Serial Number SNMPv2-SMI::enterprises.2590.1.1.1.5.5.1.1.3.2
+ * URI SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.1
+ * SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.2
+ */
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.1.1.16.1");
+ if (tmp != NULL) {
+ rc = hrDeviceDesc_to_info(tmp, manufacturer, model,
+ description);
+ free(tmp);
+
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2590.1.1.1.5.5.1.1.3.2");
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.2");
+ if (tmp == NULL)
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.1");
+ if (tmp != NULL)
+ *uri = tmp;
+ }
+
+ return (rc);
+}
+
+static int
+snmp_oki_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * OKI printers appear to store
+ * Prouct Name SNMPv2-SMI::enterprises.2001.1.2.683.1.3
+ * Serial Number SNMPv2-SMI::enterprises.2001.1.2.683.1.5
+ */
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2001.1.2.683.1.3");
+ if (tmp != NULL) {
+ rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
+ description, NULL, serial_no, command_set);
+ free(tmp);
+
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2001.1.2.683.1.5");
+ }
+
+ return (rc);
+}
+
+static int
+snmp_hp_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * HP printers appear to store
+ * 1284 DevID SNMPv2-SMI::enterprises.11.2.3.9.1.1.7.0
+ * Serial Number SNMPv2-SMI::enterprises.2.3.9.4.2.2.5.1.1.17
+ */
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.11.2.3.9.1.1.7.0");
+ if (tmp != NULL) {
+ rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
+ description, NULL, serial_no, command_set);
+ free(tmp);
+
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2.3.9.4.2.2.5.1.1.17");
+ }
+
+ return (rc);
+}
+
+static int
+snmp_ppm_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * The PWG portMon MIB stores
+ * 1284 DevID SNMPv2-SMI::enterprises.2699.1.2.1.1.1.3`
+ */
+ tmp = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::enterprises.2699.1.2.1.1.1.3");
+ if (tmp != NULL) {
+ rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
+ description, NULL, serial_no, command_set);
+ free(tmp);
+ }
+
+ return (rc);
+}
+
+static int
+snmp_prt_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ /*
+ * The Printer Printer MIB stores
+ * Vendor SNMPv2-SMI::mib-2.43.8.2.1.14.1.1
+ * Model SNMPv2-SMI::mib-2.43.8.2.1.15.1.1
+ * Serial SNMPv2-SMI::mib-2.43.8.2.1.17.1.1
+ */
+
+ if (*manufacturer == NULL)
+ *manufacturer = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::mib-2.43.8.2.1.14.1.1");
+ if (*model == NULL)
+ *model = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::mib-2.43.8.2.1.15.1.1");
+ if (*serial_no == NULL)
+ *serial_no = snmp_get_string(hostname, community,
+ "SNMPv2-SMI::mib-2.43.8.2.1.17.1.1");
+
+ if (*manufacturer != NULL)
+ rc = 0;
+
+ return (rc);
+}
+
+static int
+snmp_host_resource_printer_info(char *hostname, char *community,
+ char **manufacturer, char **model, char **description,
+ char **serial_no, char ***command_set)
+{
+ int rc = -1;
+ char *tmp = NULL;
+
+ tmp = snmp_get_string(hostname, community,
+ "HOST-RESOURCES-MIB::hrDeviceDescr.1");
+ if (tmp != NULL) {
+ rc = hrDeviceDesc_to_info(tmp, manufacturer, model,
+ description);
+ free(tmp);
+ }
+
+ return (rc);
+}
+
+int
+snmp_printer_info(char *hostname, char *community, char **manufacturer,
+ char **model, char **description, char **serial_no,
+ char ***command_set, char **uri)
+{
+ char *tmp = NULL;
+
+ init_snmp("network-printer-probe");
+ init_mib();
+
+ if (snmp_brother_printer_info(hostname, community, manufacturer, model,
+ description, serial_no, command_set) == 0) {
+ return (0);
+ } else if (snmp_ricoh_printer_info(hostname, community, manufacturer,
+ model, description, serial_no, command_set) == 0) {
+ return (0);
+ } else if (snmp_lexmark_printer_info(hostname, community, manufacturer,
+ model, description, serial_no, command_set) == 0) {
+ return (0);
+ } else if (snmp_xerox_phaser_printer_info(hostname, community,
+ manufacturer, model, description, serial_no,
+ command_set, uri) == 0) {
+ return (0);
+ } else if (snmp_qms_printer_info(hostname, community, manufacturer,
+ model, description, serial_no, command_set, uri) == 0) {
+ return (0);
+ } else if (snmp_oki_printer_info(hostname, community, manufacturer,
+ model, description, serial_no, command_set) == 0) {
+ return (0);
+ } else if (snmp_hp_printer_info(hostname, community, manufacturer,
+ model, description, serial_no, command_set) == 0) {
+ return (0);
+ } else if (snmp_ppm_printer_info(hostname, community, manufacturer,
+ model, description, serial_no, command_set) == 0) {
+ return (0);
+ } else if (snmp_prt_printer_info(hostname, community, manufacturer,
+ model, description, serial_no, command_set) == 0) {
+ return (0);
+ } else if (snmp_host_resource_printer_info(hostname, community,
+ manufacturer, model, description, serial_no,
+ command_set) == 0) {
+ return (0);
+ }
+
+ return (-1);
+}
+
+#ifdef NOTDEF
+
+#define NP(x) (x?x:"")
+
+int
+main(int ac, char *av[])
+{
+ int i;
+
+ for (i = 1; av[i] != NULL; i++) {
+ char *hostname = av[i], *manufacturer = NULL, *model = NULL,
+ *description = NULL, *serial_no = NULL,
+ **command_set = NULL, *uri = NULL;
+ int rc;
+
+ rc = snmp_printer_info(hostname, &manufacturer, &model,
+ &description, &serial_no, &command_set, &uri);
+ printf("SNMP data for %s...(%d)\n", hostname, rc);
+ printf("\tvendor = %s\n", NP(manufacturer));
+ printf("\tproduct = %s\n", NP(model));
+ printf("\tdescription = %s\n", NP(description));
+ printf("\tserial = %s\n", NP(serial_no));
+ printf("\tdevice = %s\n", NP(uri));
+
+ if (command_set != NULL) {
+ int j;
+
+ printf("\tcommand set = \n");
+ for (j = 0; command_set[j] != NULL; j++)
+ printf("\t\t%s\n", command_set[j]);
+ }
+ }
+
+ return (0);
+}
+#endif
diff --git a/usr/src/cmd/hal/probing/printer/Makefile b/usr/src/cmd/hal/probing/printer/Makefile
index f35624b09a..26903c5959 100644
--- a/usr/src/cmd/hal/probing/printer/Makefile
+++ b/usr/src/cmd/hal/probing/printer/Makefile
@@ -26,7 +26,7 @@
#
PROG = hald-probe-printer
-OBJS = probe-printer.o logger.o
+OBJS = probe-printer.o logger.o printer.o
SRCS = probe-printer.c
include ../../../Makefile.cmd
@@ -48,6 +48,10 @@ logger.o: ../../hald/logger.c
$(COMPILE.c) -o $@ ../../hald/logger.c
$(POST_PROCESS_O)
+printer.o: ../../utils/printer.c
+ $(COMPILE.c) -o $@ ../../utils/printer.c
+ $(POST_PROCESS_O)
+
$(PROG): $(OBJS)
$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
$(POST_PROCESS)
diff --git a/usr/src/cmd/hal/probing/printer/probe-printer.c b/usr/src/cmd/hal/probing/printer/probe-printer.c
index 484acb3f73..181008e10d 100644
--- a/usr/src/cmd/hal/probing/printer/probe-printer.c
+++ b/usr/src/cmd/hal/probing/printer/probe-printer.c
@@ -12,7 +12,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef HAVE_CONFIG_H
-# include <config.h>
+#include <config.h>
#endif
#include <errno.h>
@@ -21,6 +21,9 @@
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/prnio.h>
#include <fcntl.h>
@@ -30,155 +33,142 @@
#include <libhal.h>
#include <logger.h>
-#define NELEM(a) (sizeof (a) / sizeof (*(a)))
-
-static char *
-strip_ws(char *s)
-{
- if (s != NULL) {
- char *p;
-
- /* skip the leading whitespace */
- for (; ((*s != NULL) && (isspace(*s) != 0)); s++) ;
-
- /* drop the trailing whitespace */
- for (p = s + strlen(s) - 1; ((p > s) && (isspace(*p) != 0));
- p--) ;
- *(++p) = '\0';
- }
-
- return (s);
-}
+#include "printer.h"
static int
-get_prnio_data(int fd, LibHalChangeSet *cs)
+prnio_printer_info(char *device_file, char **manufacturer, char **model,
+ char **description, char **serial_number, char ***command_set)
{
struct prn_1284_device_id id;
char buf[BUFSIZ];
- char *s, *iter = NULL;
+ int fd = -1, rc = -1;
memset(&id, 0, sizeof (id));
memset(&buf, 0, sizeof (buf));
id.id_data = buf;
id.id_len = sizeof (buf);
+ if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
+ goto prnio_out;
+ }
+
if (ioctl(fd, PRNIOC_GET_1284_DEVID, &id) < 0) {
- return (-1);
+ goto prnio_out;
}
- HAL_DEBUG (("IEEE-1284 DeviceId = %s", buf));
+ HAL_DEBUG(("IEEE-1284 DeviceId = %s", buf));
- for (s = strtok_r(buf, ";\n", &iter); s != NULL;
- s = strtok_r(NULL, ";\n", &iter)) {
- char *t, *u, *iter2 = NULL;
+ rc = ieee1284_devid_to_printer_info(buf, manufacturer, model,
+ description, NULL, serial_number, command_set);
- if ((t = strtok_r(s, ":\n", &iter2)) == NULL) {
- continue;
- }
+prnio_out:
+ if (fd != -1)
+ close(fd);
- if ((u = strtok_r(NULL, ":\n", &iter2)) == NULL) {
- continue;
- }
+ return (rc);
+}
- if ((strcasecmp(t, "MFG") == 0) ||
- (strcasecmp(t, "MANUFACTURER") == 0)) {
- libhal_changeset_set_property_string (cs,
- "printer.vendor", strip_ws(u));
- } else if ((strcasecmp(t, "MDL") == 0) ||
- (strcasecmp(t, "MODEL") == 0)) {
- libhal_changeset_set_property_string (cs,
- "printer.product", strip_ws(u));
- } else if ((strcasecmp(t, "SN") == 0) ||
- (strcasecmp(t, "SERN") == 0) ||
- (strcasecmp(t, "SERIALNUMBER") == 0)) {
- libhal_changeset_set_property_string (cs,
- "printer.serial", strip_ws(u));
- } else if ((strcasecmp(t, "DES") == 0) ||
- (strcasecmp(t, "DESCRIPTION") == 0)) {
- libhal_changeset_set_property_string (cs,
- "printer.description", strip_ws(u));
- } else if ((strcasecmp(t, "CMD") == 0) ||
- (strcasecmp(t, "COMMAND SET") == 0) ||
- (strcasecmp(t, "COMMANDSET") == 0)) {
- char *v, *iter3 = NULL;
- const char *cmds[32];
- int i = 0;
-
- memset(&cmds, 0, sizeof (cmds));
- for (v = strtok_r(u, ",\n", &iter3);
- ((v != NULL) && (i < NELEM(cmds)));
- v = strtok_r(NULL, ",\n", &iter3)) {
- cmds[i++] = strip_ws(v);
+/*
+ * It is assumed that all devices that support prnio(7i), also have a link
+ * in /dev/printers.
+ */
+static char *
+prnio_device_name(void)
+{
+ char *result = NULL;
+ char *devfs_path;
+ DIR *dp;
+
+ if (((devfs_path = getenv("HAL_PROP_SOLARIS_DEVFS_PATH")) != NULL) &&
+ ((dp = opendir("/dev/printers")) != NULL)) {
+ struct dirent *ep;
+
+ while ((ep = readdir(dp)) != NULL) {
+ char path[MAXPATHLEN], lpath[MAXPATHLEN];
+
+ snprintf(path, sizeof (path), "/dev/printers/%s",
+ ep->d_name);
+ memset(lpath, 0, sizeof (lpath));
+ if ((readlink(path, lpath, sizeof (lpath)) > 0) &&
+ (strstr(lpath, devfs_path) != NULL)) {
+ result = strdup(path);
+ break;
}
-
- libhal_changeset_set_property_strlist(cs,
- "printer.commandset", cmds);
}
+ closedir(dp);
}
- return (0);
+ return (result);
}
-int
-main (int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
int ret = 1;
- int fd = -1;
char *udi;
char *device_file;
+ char *manufacturer = NULL,
+ *model = NULL,
+ *serial_number = NULL,
+ *description = NULL,
+ **command_set = NULL;
DBusError error;
LibHalContext *ctx = NULL;
LibHalChangeSet *cs = NULL;
- if ((udi = getenv ("UDI")) == NULL)
+ if ((udi = getenv("UDI")) == NULL)
goto out;
- if ((device_file = getenv ("HAL_PROP_PRINTER_DEVICE")) == NULL)
+ if ((device_file = getenv("HAL_PROP_PRINTER_DEVICE")) == NULL)
+ device_file = prnio_device_name();
+
+ if (device_file == NULL)
goto out;
- setup_logger ();
+ setup_logger();
- dbus_error_init (&error);
- if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
+ dbus_error_init(&error);
+ if ((ctx = libhal_ctx_init_direct(&error)) == NULL)
goto out;
- if ((cs = libhal_device_new_changeset (udi)) == NULL) {
- HAL_DEBUG (("Cannot allocate changeset"));
+ if ((cs = libhal_device_new_changeset(udi)) == NULL) {
+ HAL_DEBUG(("Cannot allocate changeset"));
goto out;
}
- HAL_DEBUG (("Doing probe-printer for %s (udi=%s)",
- device_file, udi));
-
- if ((fd = open (device_file, O_RDONLY | O_NONBLOCK)) < 0) {
- HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno)));
+ /* Probe the printer for characteristics via prnio(7i) */
+ ret = prnio_printer_info(device_file, &manufacturer, &model,
+ &description, &serial_number, &command_set);
+ if (ret < 0) {
+ HAL_DEBUG(("Cannot get prnio data for %s: %s",
+ device_file, strerror(errno)));
goto out;
}
- if (get_prnio_data(fd, cs) < 0) {
- HAL_DEBUG (("Cannot get prnio data %s: %s", device_file, strerror (errno)));
+ /* Add printer characteristics to the HAL device tree */
+ ret = add_printer_info(cs, udi, manufacturer, model, description,
+ serial_number, command_set, device_file);
+ if (ret < 0) {
+ HAL_DEBUG(("Cannot add printer data for %s to %s: %s",
+ device_file, udi, strerror(errno)));
goto out;
}
- libhal_device_commit_changeset (ctx, cs, &error);
+ libhal_device_commit_changeset(ctx, cs, &error);
ret = 0;
out:
if (cs != NULL) {
- libhal_device_free_changeset (cs);
- }
-
- if (fd >= 0) {
- close (fd);
+ libhal_device_free_changeset(cs);
}
if (ctx != NULL) {
if (dbus_error_is_set(&error)) {
- dbus_error_free (&error);
+ dbus_error_free(&error);
}
- libhal_ctx_shutdown (ctx, &error);
- libhal_ctx_free (ctx);
+ libhal_ctx_shutdown(ctx, &error);
+ libhal_ctx_free(ctx);
}
- return ret;
+ return (ret);
}
diff --git a/usr/src/cmd/hal/utils/printer.c b/usr/src/cmd/hal/utils/printer.c
new file mode 100644
index 0000000000..0299ea6bb1
--- /dev/null
+++ b/usr/src/cmd/hal/utils/printer.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <strings.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <libhal.h>
+#include <logger.h>
+
+#include "printer.h"
+
+static char *
+strip_ws(char *s)
+{
+ if (s != NULL) {
+ char *p;
+
+ /* skip the leading whitespace */
+ for (; ((*s != NULL) && (isspace(*s) != 0)); s++);
+
+ /* drop the trailing whitespace */
+ for (p = s + strlen(s) - 1; ((p > s) && (isspace(*p) != 0));
+ p--);
+ *(++p) = '\0';
+ }
+
+ return (s);
+}
+
+int
+ieee1284_devid_to_printer_info(char *devid_string, char **manufacturer,
+ char **model, char **description, char **class,
+ char **serial_no, char ***command_set)
+{
+ char *iter = NULL;
+ char *s;
+
+ if (devid_string == NULL)
+ return (-1);
+
+ /* parse the 1284 device id string */
+ for (s = (char *)strtok_r(devid_string, ";\n", &iter); s != NULL;
+ s = (char *)strtok_r(NULL, ";\n", &iter)) {
+ char *t, *u, *iter2 = NULL;
+
+ if ((t = (char *)strtok_r(s, ":\n", &iter2)) == NULL)
+ continue;
+
+ if ((u = (char *)strtok_r(NULL, ":\n", &iter2)) == NULL)
+ continue;
+
+ if (((strcasecmp(t, "MFG") == 0) ||
+ (strcasecmp(t, "MANUFACTURER") == 0)) &&
+ (manufacturer != NULL))
+ *manufacturer = strdup(strip_ws(u));
+ else if (((strcasecmp(t, "MDL") == 0) ||
+ (strcasecmp(t, "MODEL") == 0)) &&
+ (model != NULL))
+ *model = strdup(strip_ws(u));
+ else if (((strcasecmp(t, "DES") == 0) ||
+ (strcasecmp(t, "DESCRIPTION") == 0)) &&
+ (description != NULL))
+ *description = strdup(strip_ws(u));
+ else if (((strcasecmp(t, "CLS") == 0) ||
+ (strcasecmp(t, "CLASS") == 0)) &&
+ (class != NULL))
+ *class = strdup(strip_ws(u));
+ else if (((strcasecmp(t, "SER") == 0) ||
+ (strcasecmp(t, "SERNO") == 0)) &&
+ (serial_no != NULL))
+ *serial_no = strdup(strip_ws(u));
+ else if (((strcasecmp(t, "CMD") == 0) ||
+ (strcasecmp(t, "COMMAND SET") == 0)) &&
+ (command_set != NULL)) {
+ /* this should be more dynamic, I got lazy */
+ char *v, *iter3 = NULL;
+ char *cmds[32];
+ int i = 0;
+
+ memset(&cmds, 0, sizeof (cmds));
+#define NELEM(a) (sizeof (a) / sizeof (*(a)))
+ for (v = strtok_r(u, ",\n", &iter3);
+ ((v != NULL) && (i < NELEM(cmds)));
+ v = strtok_r(NULL, ",\n", &iter3)) {
+ cmds[i++] = strdup(strip_ws(v));
+ }
+#undef NELEM
+ *command_set = calloc(++i, sizeof (char *));
+ for (i = 0; (cmds)[i] != NULL; i++)
+ (*command_set)[i] = cmds[i];
+ }
+ }
+
+ return (0);
+}
+
+
+int
+add_printer_info(LibHalChangeSet *cs, char *udi, char *manufacturer,
+ char *model, char *description, char *serial_number,
+ char **command_set, char *device)
+{
+#define NP(x) (x?x:"")
+ HAL_DEBUG(("udi: %s, snmp data: vendor=%s, product=%s, "
+ "description=%s, serial=%s, device=%s\n",
+ NP(udi), NP(manufacturer), NP(model), NP(description),
+ NP(serial_number), NP(device)));
+#undef NP
+
+ if (model != NULL)
+ libhal_changeset_set_property_string(cs,
+ "info.product", model);
+ if (manufacturer != NULL)
+ libhal_changeset_set_property_string(cs,
+ "printer.vendor", manufacturer);
+ if (model != NULL)
+ libhal_changeset_set_property_string(cs,
+ "printer.product", model);
+ if (serial_number != NULL)
+ libhal_changeset_set_property_string(cs,
+ "printer.serial", serial_number);
+ if (description != NULL)
+ libhal_changeset_set_property_string(cs,
+ "printer.description", description);
+ if (command_set != NULL)
+ libhal_changeset_set_property_strlist(cs, "printer.commandset",
+ (const char **)command_set);
+ if (device != NULL)
+ libhal_changeset_set_property_string(cs,
+ "printer.device", device);
+
+ return (0);
+}
diff --git a/usr/src/cmd/hal/utils/printer.h b/usr/src/cmd/hal/utils/printer.h
new file mode 100644
index 0000000000..4b5eca18c0
--- /dev/null
+++ b/usr/src/cmd/hal/utils/printer.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Licensed under the Academic Free License version 2.1
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifndef _PRINTER_H
+#define _PRINTER_H
+
+#include <libhal.h>
+
+extern int ieee1284_devid_to_printer_info(char *devid_string,
+ char **manufacturer, char **model, char **description,
+ char **class, char **serial_no, char ***command_set);
+
+extern int add_printer_info(LibHalChangeSet *cs, char *udi, char *manufacturer,
+ char *model, char *serial_number, char *description,
+ char **command_set, char *device);
+
+#endif /* _PRINTER_H */
diff --git a/usr/src/lib/libsecdb/auth_attr.txt b/usr/src/lib/libsecdb/auth_attr.txt
index d862e0f547..afb8349e40 100644
--- a/usr/src/lib/libsecdb/auth_attr.txt
+++ b/usr/src/lib/libsecdb/auth_attr.txt
@@ -111,6 +111,7 @@ solaris.smf.manage.:::Manage All SMF Service States::help=SmfManageHeader.html
solaris.smf.manage.autofs:::Manage Automount Service States::help=SmfAutofsStates.html
solaris.smf.manage.bind:::Manage DNS Service States::help=BindStates.html
solaris.smf.manage.cron:::Manage Cron Service States::help=SmfCronStates.html
+solaris.smf.manage.discover.printers.snmp:::Manage Network Attached Device Discovery Service States::help=SmfNADDStates.html
solaris.smf.manage.hal:::Manage HAL Service States::help=SmfHALStates.html
solaris.smf.manage.idmap:::Manage Identity Mapping Service States::help=SmfIdmapStates.html
solaris.smf.manage.inetd:::Manage inetd and inetd managed services States::help=SmfIntedStates.html
@@ -130,6 +131,7 @@ solaris.smf.manage.tnctl:::Manage Refresh of Trusted Network Parameters::help=TN
solaris.smf.manage.tnd:::Manage Trusted Network Daemon::help=TNDaemon.html
solaris.smf.manage.wpa:::Manage WPA Service States::help=SmfWpaStates.html
solaris.smf.value.:::Change Values of SMF Service Properties::help=SmfValueHeader.html
+solaris.smf.value.discover.printers.snmp:::Manage Network Attached Device Discovery Service Properties::help=SmfValueNADD.html
solaris.smf.value.idmap:::Change Values of SMF Identity Mapping Service Properties::help=SmfValueIdmap.html
solaris.smf.value.inetd:::Change values of SMF Inetd configuration paramaters::help=SmfValueInted.html
solaris.smf.value.ipsec:::Change Values of SMF IPsec Properties::help=SmfValueIPsec.html
diff --git a/usr/src/lib/libsecdb/help/auths/Makefile b/usr/src/lib/libsecdb/help/auths/Makefile
index cf290e0900..1bdd12e0ce 100644
--- a/usr/src/lib/libsecdb/help/auths/Makefile
+++ b/usr/src/lib/libsecdb/help/auths/Makefile
@@ -78,6 +78,7 @@ HTMLENTS = \
SmfModifyHeader.html \
SmfModifyMethod.html \
SmfNscdStates.html \
+ SmfNADDStates.html \
SmfNWAMStates.html \
SmfPowerStates.html \
SmfRoutingStates.html \
@@ -89,6 +90,7 @@ HTMLENTS = \
SmfValueIPsec.html \
SmfValueIscsitgt.html \
SmfValueMDNS.html \
+ SmfValueNADD.html \
SmfValueNWAM.html \
SmfValueRouting.html \
SmfWpaStates.html \
diff --git a/usr/src/lib/libsecdb/help/auths/SmfNADDStates.html b/usr/src/lib/libsecdb/help/auths/SmfNADDStates.html
new file mode 100644
index 0000000000..811d216635
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/SmfNADDStates.html
@@ -0,0 +1,40 @@
+<HTML>
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+Use is subject to license terms.
+-->
+<!-- SCCS keyword
+#ident "%Z%%M% %I% %E% SMI"
+-->
+<!--
+ <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+-->
+<BODY>
+When Manage Network Device Discovery Service States is in the Authorizations
+Include column, it grants the authorization to enable, disable, or restart
+the Network Attached Device Discovery services.
+<p>
+If Manage Network DeviceDiscovery Service States is grayed, then you are not entitled
+to Add or Remove this authorization.
+<BR>&nbsp;
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/SmfValueNADD.html b/usr/src/lib/libsecdb/help/auths/SmfValueNADD.html
new file mode 100644
index 0000000000..eb26f2671c
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/SmfValueNADD.html
@@ -0,0 +1,40 @@
+<HTML>
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+Use is subject to license terms.
+-->
+<!-- SCCS keyword
+#ident "%Z%%M% %I% %E% SMI"
+-->
+<!--
+ <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+-->
+<BODY>
+When Value Network Attached Device Discovery Properties is in the Authorizations
+Include column, it grants the the authorization to change Network Attached
+Device Discovery service property values.
+<P>
+If Value Network Attached Device Discovery Properties is grayed, then you are
+not entitled to Add or Remove this authorization.
+<BR>&nbsp;
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/prof_attr.txt b/usr/src/lib/libsecdb/prof_attr.txt
index cfc9890dcb..96107e01f4 100644
--- a/usr/src/lib/libsecdb/prof_attr.txt
+++ b/usr/src/lib/libsecdb/prof_attr.txt
@@ -36,7 +36,7 @@ Audit Control:::Configure BSM auditing:auths=solaris.audit.config,solaris.jobs.a
Audit Review:::Review BSM auditing logs:auths=solaris.audit.read;help=RtAuditReview.html
Contract Observer:::Reliably observe any/all contract events:help=RtContractObserver.html
Device Management:::Control Access to Removable Media:auths=solaris.device.*;help=RtDeviceMngmnt.html
-Printer Management:::Manage printers, daemons, spooling:auths=solaris.print.*,solaris.label.print;help=RtPrntAdmin.html
+Printer Management:::Manage printers, daemons, spooling:auths=solaris.print.*,solaris.label.print,solaris.smf.manage.discovery.printers.*,solaris.smf.value.discovery.printers.*;help=RtPrntAdmin.html
Cron Management:::Manage at and cron jobs:auths=solaris.jobs.*,solaris.smf.manage.cron;help=RtCronMngmnt.html
Log Management:::Manage log files:help=RtLogMngmnt.html
Basic Solaris User:::Automatically assigned rights:auths=solaris.profmgr.read,solaris.jobs.user,solaris.mail.mailq,solaris.device.mount.removable;profiles=All;help=RtDefault.html
diff --git a/usr/src/pkgdefs/SUNW0on/prototype_com b/usr/src/pkgdefs/SUNW0on/prototype_com
index eaea3bad10..87facb2c00 100644
--- a/usr/src/pkgdefs/SUNW0on/prototype_com
+++ b/usr/src/pkgdefs/SUNW0on/prototype_com
@@ -251,6 +251,7 @@ f none usr/lib/help/auths/locale/SmfModifyHeader.html 444 root bin
f none usr/lib/help/auths/locale/SmfModifyMethod.html 444 root bin
f none usr/lib/help/auths/locale/SmfIPsecStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfNscdStates.html 444 root bin
+f none usr/lib/help/auths/locale/SmfNADDStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfNWAMStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfPowerStates.html 444 root bin
f none usr/lib/help/auths/locale/SmfRoutingStates.html 444 root bin
@@ -262,6 +263,7 @@ f none usr/lib/help/auths/locale/SmfValueInetd.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueIPsec.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueIscsitgt.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueMDNS.html 444 root bin
+f none usr/lib/help/auths/locale/SmfValueNADD.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueNWAM.html 444 root bin
f none usr/lib/help/auths/locale/SmfValueRouting.html 444 root bin
f none usr/lib/help/auths/locale/SmfWpaStates.html 444 root bin
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_com b/usr/src/pkgdefs/SUNWcsu/prototype_com
index 40ba8db3d7..4c0a9807a5 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com
@@ -487,6 +487,7 @@ f none usr/lib/help/auths/locale/C/SmfModifyMethod.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfInetdStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfIPsecStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfNscdStates.html 444 root bin
+f none usr/lib/help/auths/locale/C/SmfNADDStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfNWAMStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfPowerStates.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfRoutingStates.html 444 root bin
@@ -498,6 +499,7 @@ f none usr/lib/help/auths/locale/C/SmfValueInetd.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueIPsec.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueIscsitgt.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueMDNS.html 444 root bin
+f none usr/lib/help/auths/locale/C/SmfValueNADD.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueNWAM.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfValueRouting.html 444 root bin
f none usr/lib/help/auths/locale/C/SmfWpaStates.html 444 root bin
diff --git a/usr/src/pkgdefs/SUNWhal/prototype_com b/usr/src/pkgdefs/SUNWhal/prototype_com
index c1261489d0..2cc544a272 100644
--- a/usr/src/pkgdefs/SUNWhal/prototype_com
+++ b/usr/src/pkgdefs/SUNWhal/prototype_com
@@ -48,8 +48,10 @@ d none usr/lib 755 root bin
d none usr/lib/hal 755 root bin
f none usr/lib/hal/hald 555 root bin
f none usr/lib/hal/hald-addon-acpi 555 root bin
+f none usr/lib/hal/hald-addon-network-discovery 555 root bin
f none usr/lib/hal/hald-addon-storage 555 root bin
f none usr/lib/hal/hald-probe-battery 555 root bin
+f none usr/lib/hal/hald-probe-network-printer 555 root bin
f none usr/lib/hal/hald-probe-printer 555 root bin
f none usr/lib/hal/hald-probe-storage 555 root bin
f none usr/lib/hal/hald-probe-volume 555 root bin
diff --git a/usr/src/pkgdefs/SUNWhalr/prototype_com b/usr/src/pkgdefs/SUNWhalr/prototype_com
index b42c35545a..9cbe319b4f 100644
--- a/usr/src/pkgdefs/SUNWhalr/prototype_com
+++ b/usr/src/pkgdefs/SUNWhalr/prototype_com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -68,6 +68,7 @@ d none etc/hal/fdi/policy 755 root bin
d none etc/hal/fdi/policy/10osvendor 755 root bin
f none etc/hal/fdi/policy/10osvendor/10-keyboard-policy.fdi 444 root bin
f none etc/hal/fdi/policy/10osvendor/10-laptop-panel-mgmt-policy.fdi 444 root bin
+f none etc/hal/fdi/policy/10osvendor/10-network-attached.fdi 444 root bin
f none etc/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi 444 root bin
f none etc/hal/fdi/policy/10osvendor/10-toshiba-buttons.fdi 444 root bin
f none etc/hal/fdi/policy/10osvendor/20-storage-methods.fdi 444 root bin
@@ -79,14 +80,18 @@ d none etc/hal/fdi/preprobe/10osvendor 755 root bin
f none etc/hal/fdi/preprobe/10osvendor/10-ide-drives.fdi 444 root bin
f none etc/hal/fdi/preprobe/10osvendor/20-ignore-fixed-storage.fdi 444 root bin
f none etc/hal/fdi/preprobe/10osvendor/20-ignore-lofi.fdi 444 root bin
+f none etc/hal/fdi/preprobe/10osvendor/20-printers.fdi 444 root bin
d none etc/hal/fdi/preprobe/20thirdparty 755 root bin
d none etc/hal/fdi/preprobe/30user 755 root bin
d none lib 755 root bin
d none lib/svc 0755 root bin
d none lib/svc/method 0755 root bin
f none lib/svc/method/svc-hal 555 root bin
+f none lib/svc/method/svc-network-discovery 555 root bin
d none var 755 root sys
d none var/svc 755 root sys
d none var/svc/manifest 755 root sys
+d none var/svc/manifest/network 755 root sys
+f manifest var/svc/manifest/network/network-discovery.xml 444 root sys
d none var/svc/manifest/system 755 root sys
f manifest var/svc/manifest/system/hal.xml 444 root sys
diff --git a/usr/src/tools/scripts/check_rtime.pl b/usr/src/tools/scripts/check_rtime.pl
index 057e8ddaf0..891904e530 100644
--- a/usr/src/tools/scripts/check_rtime.pl
+++ b/usr/src/tools/scripts/check_rtime.pl
@@ -215,6 +215,7 @@ $UnusedNoise = qr{
libmapmalloc\.so\.1;\ unused |
unused\ dependency\ of\ .*libstdc\+\+\.so\.6 |
unreferenced\ object=.*libstdc\+\+\.so\.6 |
+ unused\ dependency\ of\ .*libnetsnmp\.so\.5 |
unused\ dependency\ of\ .*libnetsnmphelpers\.so\.5 |
unused\ dependency\ of\ .*libnetsnmpmibs\.so\.5 |
unused\ dependency\ of\ .*libnetsnmpagent\.so\.5