xref: /illumos-gate/usr/src/cmd/hal/probing/network-printer/probe-snmp.c (revision 7800901e60d340b6af88e94a2149805dcfcaaf56)
1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  *
5  * Licensed under the Academic Free License version 2.1
6  */
7 
8 #pragma ident	"%Z%%M%	%I%	%E% SMI"
9 
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <strings.h>
15 
16 #undef PACKAGE_STRING
17 #undef PACKAGE_VERSION
18 
19 #include <net-snmp/net-snmp-config.h>
20 #include <net-snmp/net-snmp-includes.h>
21 
22 #include "logger.h"
23 #include "printer.h"
24 
25 static int
26 hrDeviceDesc_to_info(char *string, char **manufacturer, char **model,
27 		char **description)
28 {
29 	int rc = -1;
30 	char *s;
31 
32 	if (string == NULL)
33 		return (-1);
34 
35 	/* if it has : and ; in it, it's probably a 1284 device id */
36 	if ((strchr(string, ':') != NULL) && (strchr(string, ';') != NULL)) {
37 		rc = ieee1284_devid_to_printer_info(string, manufacturer, model,
38 				description, NULL, NULL, NULL);
39 	} else {
40 		rc = 0;
41 		*description = strdup(string);
42 		*manufacturer = strdup(string);
43 		if ((s = strchr(*manufacturer, ' ')) != NULL) {
44 			*s++ = NULL;
45 			*model = strdup(s);
46 		}
47 	}
48 
49 	return (rc);
50 }
51 
52 static struct snmp_pdu *
53 snmp_get_item(char *host, char *community, char *mib_item)
54 {
55 	int status;
56 	struct snmp_session session, *ss;
57 	struct snmp_pdu *request = NULL, *result = NULL;
58 	oid Oid[MAX_OID_LEN];
59 	unsigned int oid_len = MAX_OID_LEN;
60 
61 	/* initialize the SNMP session */
62 	snmp_sess_init(&session);
63 	session.peername = host;
64 	session.community = (uchar_t *)community;
65 	session.community_len = strlen((const char *)session.community);
66 	session.version = SNMP_VERSION_1;
67 	session.retries = 0;
68 
69 	if ((ss = snmp_open(&session)) == NULL)
70 		return (NULL);
71 
72 	/* add the requested data */
73 	if (!read_objid(mib_item, Oid, &oid_len))
74 		snmp_perror(mib_item);
75 
76 	/* initialize the request PDU */
77 	request = snmp_pdu_create(SNMP_MSG_GET);
78 	snmp_add_null_var(request, Oid, oid_len);
79 
80 	status = snmp_synch_response(ss, request, &result);
81 
82 	snmp_close(ss);
83 
84 	return (result);
85 }
86 
87 static char *
88 snmp_get_string(char *host, char *community, char *mib_item)
89 {
90 	char *result = NULL;
91 	struct snmp_pdu *response = NULL;
92 
93 	response = snmp_get_item(host, community, mib_item);
94 
95 	if ((response != NULL) && (response->errstat == SNMP_ERR_NOERROR)) {
96 		struct variable_list *v = response->variables;
97 
98 		if (v->type == ASN_OCTET_STR) {
99 			result = calloc(1, v->val_len + 1);
100 			memcpy(result, v->val.string, v->val_len);
101 		}
102 	}
103 
104 	HAL_DEBUG(("snmp_get_string(%s, %s, %s): %s", host, community, mib_item,
105 		(result?result:"NULL")));
106 
107 	if (response != NULL)
108 		snmp_free_pdu(response);
109 
110 	return (result);
111 }
112 
113 static int
114 snmp_brother_printer_info(char *hostname, char *community, char **manufacturer,
115 		char **model, char **description, char **serial_no,
116 		char ***command_set)
117 {
118 	int rc = -1;
119 	char *tmp = NULL;
120 
121 	/*
122 	 * Brother printers appear to store
123 	 *	1284 DevID	SNMPv2-SMI::enterprises.2435.2.3.9.1.1.7.0
124 	 *	Serial Number	SNMPv2-SMI::enterprises.2435.2.3.9.4.2.1.5.5.1.0
125 	 */
126 	tmp = snmp_get_string(hostname, community,
127 			"SNMPv2-SMI::enterprises.2435.2.3.9.1.1.7.0");
128 	if (tmp != NULL) {
129 		rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
130 				description, NULL, serial_no, command_set);
131 		free(tmp);
132 
133 		if (*serial_no == NULL)
134 			*serial_no = snmp_get_string(hostname, community,
135 				"SNMPv2-SMI::enterprises.2435.2.3.9.4.2.1.5.5.1.0");
136 	}
137 
138 	return (rc);
139 }
140 
141 static int
142 snmp_ricoh_printer_info(char *hostname, char *community, char **manufacturer,
143 		char **model, char **description, char **serial_no,
144 		char ***command_set)
145 {
146 	int rc = -1;
147 	char *tmp = NULL;
148 
149 	/*
150 	 * OKI printers appear to store
151 	 *	1284 DevID	SNMPv2-SMI::enterprises.367.3.2.1.1.1.11.0
152 	 *	Serial Number	SNMPv2-SMI::enterprises.367.3.2.1.2.1.4.0
153 	 */
154 	tmp = snmp_get_string(hostname, community,
155 			"SNMPv2-SMI::enterprises.367.3.2.1.1.1.11.0");
156 	if (tmp != NULL) {
157 		rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
158 				description, NULL, serial_no, command_set);
159 		free(tmp);
160 
161 		if (*serial_no == NULL)
162 			*serial_no = snmp_get_string(hostname, community,
163 				"SNMPv2-SMI::enterprises.367.3.2.1.2.1.4.0");
164 	}
165 
166 	return (rc);
167 }
168 
169 static int
170 snmp_lexmark_printer_info(char *hostname, char *community, char **manufacturer,
171 		char **model, char **description, char **serial_no,
172 		char ***command_set)
173 {
174 	int rc = -1;
175 	char *tmp = NULL;
176 
177 	/*
178 	 * Lexmark printers appear to store
179 	 *	1284 DevID	SNMPv2-SMI::enterprises.641.2.1.2.1.3.1
180 	 *	Serial Number	SNMPv2-SMI::enterprises.641.2.1.2.1.6.1
181 	 */
182 	tmp = snmp_get_string(hostname, community,
183 			"SNMPv2-SMI::enterprises.641.2.1.2.1.3.1");
184 	if (tmp != NULL) {
185 		rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
186 				description, NULL, serial_no, command_set);
187 		free(tmp);
188 
189 		if (*serial_no == NULL)
190 			*serial_no = snmp_get_string(hostname, community,
191 				"SNMPv2-SMI::enterprises.641.2.1.2.1.6.1");
192 	}
193 
194 	return (rc);
195 }
196 
197 static int
198 snmp_xerox_phaser_printer_info(char *hostname, char *community,
199 		char **manufacturer, char **model, char **description,
200 		char **serial_no, char ***command_set, char **uri)
201 {
202 	int rc = -1;
203 	char *tmp = NULL;
204 
205 	/*
206 	 * Xerox Phaser XXXX printers store their
207 	 *	1284 DevID	SNMPv2-SMI::enterprises.253.8.51.1.2.1.20.1
208 	 *	Manufacturer:
209 	 *			SNMPv2-SMI::enterprises.128.2.1.3.1.1.0
210 	 *			SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.16
211 	 *			SNMPv2-SMI::enterprises.23.2.32.4.1.0
212 	 *	Model:
213 	 *			SNMPv2-SMI::enterprises.128.2.1.3.1.2.0
214 	 *			SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.17
215 	 *			SNMPv2-SMI::enterprises.23.2.32.4.2.0
216 	 *	Description	SNMPv2-SMI::enterprises.253.8.53.3.2.1.2.1
217 	 *	Serial Number	SNMPv2-SMI::enterprises.253.8.53.3.2.1.3.1
218 	 *	Uri		SNMPv2-SMI::enterprises.128.2.1.3.6.23.1.5.1
219 	 */
220 
221 	tmp = snmp_get_string(hostname, community,
222 			"SNMPv2-SMI::enterprises.253.8.51.1.2.1.20.1");
223 	if (tmp != NULL) {
224 		rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
225 				description, NULL, serial_no, command_set);
226 		free(tmp);
227 	}
228 
229 	if (*manufacturer == NULL)
230 		*manufacturer = snmp_get_string(hostname, community,
231 			"SNMPv2-SMI::enterprises.128.2.1.3.1.1.0");
232 	if (*manufacturer == NULL)
233 		*manufacturer = snmp_get_string(hostname, community,
234 			"SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.16");
235 	if (*manufacturer == NULL)
236 		*manufacturer = snmp_get_string(hostname, community,
237 			"SNMPv2-SMI::enterprises.23.2.32.4.1.0");
238 
239 	if (*model == NULL)
240 		*model = snmp_get_string(hostname, community,
241 			"SNMPv2-SMI::enterprises.128.2.1.3.1.2.0");
242 	if (*model == NULL)
243 		*model = snmp_get_string(hostname, community,
244 			"SNMPv2-SMI::enterprises.23.2.32.3.2.1.10.1.17");
245 	if (*model == NULL)
246 		*model = snmp_get_string(hostname, community,
247 			"SNMPv2-SMI::enterprises.23.2.32.4.2.0");
248 
249 	if (*serial_no == NULL)
250 		*serial_no = snmp_get_string(hostname, community,
251 			"SNMPv2-SMI::enterprises.253.8.53.3.2.1.3.1");
252 
253 	if ((*manufacturer != NULL) && (*model != NULL))
254 		rc = 0;
255 
256 	return (rc);
257 }
258 
259 static int
260 snmp_qms_printer_info(char *hostname, char *community, char **manufacturer,
261 		char **model, char **description, char **serial_no,
262 		char ***command_set, char **uri)
263 {
264 	int rc = -1;
265 	char *tmp = NULL;
266 
267 	/*
268 	 * MINOLTA-QMS printers appear to store
269 	 *	Prouct Name	SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.1.1.16.1
270 	 *	Serial Number	SNMPv2-SMI::enterprises.2590.1.1.1.5.5.1.1.3.2
271 	 *	URI		SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.1
272 	 *			SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.2
273 	 */
274 	tmp = snmp_get_string(hostname, community,
275 		"SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.1.1.16.1");
276 	if (tmp != NULL) {
277 		rc = hrDeviceDesc_to_info(tmp, manufacturer, model,
278 					description);
279 		free(tmp);
280 
281 		if (*serial_no == NULL)
282 			*serial_no = snmp_get_string(hostname, community,
283 				"SNMPv2-SMI::enterprises.2590.1.1.1.5.5.1.1.3.2");
284 		tmp = snmp_get_string(hostname, community,
285 			"SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.2");
286 		if (tmp == NULL)
287 			tmp = snmp_get_string(hostname, community,
288 				"SNMPv2-SMI::enterprises.2590.1.1.2.1.5.7.14.2.2.1.3.1.1");
289 		if (tmp != NULL)
290 			*uri = tmp;
291 	}
292 
293 	return (rc);
294 }
295 
296 static int
297 snmp_oki_printer_info(char *hostname, char *community, char **manufacturer,
298 		char **model, char **description, char **serial_no,
299 		char ***command_set)
300 {
301 	int rc = -1;
302 	char *tmp = NULL;
303 
304 	/*
305 	 * OKI printers appear to store
306 	 *	Prouct Name	SNMPv2-SMI::enterprises.2001.1.2.683.1.3
307 	 *	Serial Number	SNMPv2-SMI::enterprises.2001.1.2.683.1.5
308 	 */
309 	tmp = snmp_get_string(hostname, community,
310 			"SNMPv2-SMI::enterprises.2001.1.2.683.1.3");
311 	if (tmp != NULL) {
312 		rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
313 				description, NULL, serial_no, command_set);
314 		free(tmp);
315 
316 		if (*serial_no == NULL)
317 			*serial_no = snmp_get_string(hostname, community,
318 				"SNMPv2-SMI::enterprises.2001.1.2.683.1.5");
319 	}
320 
321 	return (rc);
322 }
323 
324 static int
325 snmp_hp_printer_info(char *hostname, char *community, char **manufacturer,
326 		char **model, char **description, char **serial_no,
327 		char ***command_set)
328 {
329 	int rc = -1;
330 	char *tmp = NULL;
331 
332 	/*
333 	 * HP printers appear to store
334 	 *	1284 DevID	SNMPv2-SMI::enterprises.11.2.3.9.1.1.7.0
335 	 *	Serial Number	SNMPv2-SMI::enterprises.2.3.9.4.2.2.5.1.1.17
336 	 */
337 	tmp = snmp_get_string(hostname, community,
338 			"SNMPv2-SMI::enterprises.11.2.3.9.1.1.7.0");
339 	if (tmp != NULL) {
340 		rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
341 				description, NULL, serial_no, command_set);
342 		free(tmp);
343 
344 		if (*serial_no == NULL)
345 			*serial_no = snmp_get_string(hostname, community,
346 				"SNMPv2-SMI::enterprises.2.3.9.4.2.2.5.1.1.17");
347 	}
348 
349 	return (rc);
350 }
351 
352 static int
353 snmp_ppm_printer_info(char *hostname, char *community, char **manufacturer,
354 		char **model, char **description, char **serial_no,
355 		char ***command_set)
356 {
357 	int rc = -1;
358 	char *tmp = NULL;
359 
360 	/*
361 	 * The PWG portMon MIB stores
362 	 *	1284 DevID	SNMPv2-SMI::enterprises.2699.1.2.1.1.1.3`
363 	 */
364 	tmp = snmp_get_string(hostname, community,
365 			"SNMPv2-SMI::enterprises.2699.1.2.1.1.1.3");
366 	if (tmp != NULL) {
367 		rc = ieee1284_devid_to_printer_info(tmp, manufacturer, model,
368 				description, NULL, serial_no, command_set);
369 		free(tmp);
370 	}
371 
372 	return (rc);
373 }
374 
375 static int
376 snmp_prt_printer_info(char *hostname, char *community, char **manufacturer,
377 		char **model, char **description, char **serial_no,
378 		char ***command_set)
379 {
380 	int rc = -1;
381 	char *tmp = NULL;
382 
383 	/*
384 	 * The Printer Printer MIB stores
385 	 *	Vendor	 SNMPv2-SMI::mib-2.43.8.2.1.14.1.1
386 	 *	Model	 SNMPv2-SMI::mib-2.43.8.2.1.15.1.1
387 	 *	Serial	 SNMPv2-SMI::mib-2.43.8.2.1.17.1.1
388 	 */
389 
390 	if (*manufacturer == NULL)
391 		*manufacturer = snmp_get_string(hostname, community,
392 				"SNMPv2-SMI::mib-2.43.8.2.1.14.1.1");
393 	if (*model == NULL)
394 		*model = snmp_get_string(hostname, community,
395 				"SNMPv2-SMI::mib-2.43.8.2.1.15.1.1");
396 	if (*serial_no == NULL)
397 		*serial_no = snmp_get_string(hostname, community,
398 				"SNMPv2-SMI::mib-2.43.8.2.1.17.1.1");
399 
400 	if (*manufacturer != NULL)
401 		rc = 0;
402 
403 	return (rc);
404 }
405 
406 static int
407 snmp_host_resource_printer_info(char *hostname, char *community,
408 		char **manufacturer, char **model, char **description,
409 		char **serial_no, char ***command_set)
410 {
411 	int rc = -1;
412 	char *tmp = NULL;
413 
414 	tmp = snmp_get_string(hostname, community,
415 			"HOST-RESOURCES-MIB::hrDeviceDescr.1");
416 	if (tmp != NULL) {
417 		rc = hrDeviceDesc_to_info(tmp, manufacturer, model,
418 					description);
419 		free(tmp);
420 	}
421 
422 	return (rc);
423 }
424 
425 int
426 snmp_printer_info(char *hostname, char *community, char **manufacturer,
427 		char **model, char **description, char **serial_no,
428 		char ***command_set, char **uri)
429 {
430 	char *tmp = NULL;
431 
432 	init_snmp("network-printer-probe");
433 	init_mib();
434 
435 	if (snmp_brother_printer_info(hostname, community, manufacturer, model,
436 			description, serial_no, command_set) == 0) {
437 		return (0);
438 	} else if (snmp_ricoh_printer_info(hostname, community, manufacturer,
439 			model, description, serial_no, command_set) == 0) {
440 		return (0);
441 	} else if (snmp_lexmark_printer_info(hostname, community, manufacturer,
442 			model, description, serial_no, command_set) == 0) {
443 		return (0);
444 	} else if (snmp_xerox_phaser_printer_info(hostname, community,
445 			manufacturer, model, description, serial_no,
446 			command_set, uri) == 0) {
447 		return (0);
448 	} else if (snmp_qms_printer_info(hostname, community, manufacturer,
449 			model, description, serial_no, command_set, uri) == 0) {
450 		return (0);
451 	} else if (snmp_oki_printer_info(hostname, community, manufacturer,
452 			model, description, serial_no, command_set) == 0) {
453 		return (0);
454 	} else if (snmp_hp_printer_info(hostname, community, manufacturer,
455 			model, description, serial_no, command_set) == 0) {
456 		return (0);
457 	} else if (snmp_ppm_printer_info(hostname, community, manufacturer,
458 			model, description, serial_no, command_set) == 0) {
459 		return (0);
460 	} else if (snmp_prt_printer_info(hostname, community, manufacturer,
461 			model, description, serial_no, command_set) == 0) {
462 		return (0);
463 	} else if (snmp_host_resource_printer_info(hostname, community,
464 			manufacturer, model, description, serial_no,
465 			command_set) == 0) {
466 		return (0);
467 	}
468 
469 	return (-1);
470 }
471 
472 #ifdef NOTDEF
473 
474 #define	NP(x)	(x?x:"")
475 
476 int
477 main(int ac, char *av[])
478 {
479 	int i;
480 
481 	for (i = 1; av[i] != NULL; i++) {
482 		char *hostname = av[i], *manufacturer = NULL, *model = NULL,
483 		     *description = NULL, *serial_no = NULL,
484 		     **command_set = NULL, *uri = NULL;
485 		int rc;
486 
487 		rc = snmp_printer_info(hostname, &manufacturer, &model,
488 				&description, &serial_no, &command_set, &uri);
489 		printf("SNMP data for %s...(%d)\n", hostname, rc);
490 		printf("\tvendor = %s\n", NP(manufacturer));
491 		printf("\tproduct = %s\n", NP(model));
492 		printf("\tdescription = %s\n", NP(description));
493 		printf("\tserial = %s\n", NP(serial_no));
494 		printf("\tdevice = %s\n", NP(uri));
495 
496 		if (command_set != NULL) {
497 			int j;
498 
499 			printf("\tcommand set = \n");
500 			for (j = 0; command_set[j] != NULL; j++)
501 				printf("\t\t%s\n", command_set[j]);
502 		}
503 	}
504 
505 	return (0);
506 }
507 #endif
508