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
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
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"
27 #define NP(x) (x?x:"NULL")
29 static GList
*new_addrs
= NULL
;
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) {
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, ...
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
;
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
));
66 scan_for_devices_using_snmp(LibHalContext
*ctx
, char *parent
, char *community
,
69 struct snmp_session session
, *ss
;
70 struct snmp_pdu
*request
= NULL
, *response
= NULL
;
72 unsigned int oid_len
= MAX_OID_LEN
;
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");
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
)
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 */
103 int fds
= 0, block
= 0;
105 struct timeval timeout
;
108 snmp_select_info(&fds
, &fdset
, &timeout
, &block
);
109 fds
= select(fds
, &fdset
, NULL
, NULL
, block
? NULL
: &timeout
);
111 perror("select failed");
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
);
127 g_list_free(new_addrs
);