dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / hal / addons / network-devices / snmp.c
blob80c793cc8ab9bff7cf6352357c938fc89c268580
1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
5 * Licensed under the Academic Free License version 2.1
6 */
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
13 #include <glib.h>
15 #include <libhal.h>
16 #include <logger.h>
18 #undef PACKAGE_STRING
19 #undef PACKAGE_VERSION
21 #include <net-snmp/net-snmp-config.h>
22 #include <net-snmp/net-snmp-includes.h>
24 #include "network-discovery.h"
25 #include "printer.h"
27 #define NP(x) (x?x:"NULL")
29 static GList *new_addrs = NULL;
31 static void
32 add_snmp_device(LibHalContext *ctx, char *parent, char *name, char *community)
34 /* most printers listen on the appsocket port (9100) */
35 if (is_listening(name, 9100) == 0) {
36 char device[128];
38 snprintf(device, sizeof (device), "socket://%s:9100", name);
40 add_network_printer(ctx, parent, name, device, community);
44 * This would be a good place to detect other types of devices or other
45 * device capabilities. scanners, removable media, storage, ...
49 static int
50 snmp_response_cb(int operation, struct snmp_session *sp, int reqid,
51 struct snmp_pdu *pdu, void *data)
53 struct sockaddr_in *addr = pdu->transport_data;
54 char *name;
56 name = inet_ntoa(addr->sin_addr);
58 /* have we already seen this network device */
59 if (device_seen(name) == FALSE)
60 new_addrs = g_list_append(new_addrs, strdup(name));
62 return (0);
65 gboolean
66 scan_for_devices_using_snmp(LibHalContext *ctx, char *parent, char *community,
67 char *network)
69 struct snmp_session session, *ss;
70 struct snmp_pdu *request = NULL, *response = NULL;
71 oid Oid[MAX_OID_LEN];
72 unsigned int oid_len = MAX_OID_LEN;
73 GList *elem;
75 HAL_DEBUG(("scan_for_devices_using_snmp(0x%8.8x, %s, %s, %s)",
76 ctx, NP(parent), NP(community), NP(network)));
78 init_snmp("snmp-scan");
79 init_mib();
81 /* initialize the SNMP session */
82 snmp_sess_init(&session);
83 session.peername = network;
84 session.community = (uchar_t *)community;
85 session.community_len = strlen((const char *)session.community);
86 session.version = SNMP_VERSION_1;
88 if ((ss = snmp_open(&session)) == NULL)
89 return (FALSE);
91 /* initialize the request PDU */
92 request = snmp_pdu_create(SNMP_MSG_GET);
94 /* add the requested data (everyone should have a sysDescr.0) */
95 if (!read_objid("SNMPv2-MIB::sysDescr.0", Oid, &oid_len))
96 snmp_perror("sysDescr.0");
97 snmp_add_null_var(request, Oid, oid_len);
99 snmp_async_send(ss, request, snmp_response_cb, NULL);
101 /* detect any new devices */
102 while (1) {
103 int fds = 0, block = 0;
104 fd_set fdset;
105 struct timeval timeout;
107 FD_ZERO(&fdset);
108 snmp_select_info(&fds, &fdset, &timeout, &block);
109 fds = select(fds, &fdset, NULL, NULL, block ? NULL : &timeout);
110 if (fds < 0) {
111 perror("select failed");
112 break;
113 } if (fds == 0) {
114 break;
115 } else {
116 snmp_read(&fdset);
120 snmp_close(ss);
122 /* add the newly detected devices */
123 for (elem = new_addrs; elem != NULL; elem = g_list_next(elem)) {
124 add_snmp_device(ctx, parent, (char *)elem->data, community);
125 free(elem->data);
127 g_list_free(new_addrs);
128 new_addrs = NULL;
130 return (TRUE);