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