xref: /titanic_52/usr/src/cmd/picl/plugins/sun4v/lib/snmp/debug.c (revision 0d63ce2b32a9e1cc8ed71d4d92536c44d66a530a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #ifdef SNMP_DEBUG
30 
31 /*
32  * Debug routines
33  */
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <thread.h>
39 #include <synch.h>
40 #include <ctype.h>
41 #include <sys/types.h>
42 #include "asn1.h"
43 #include "pdu.h"
44 #include "snmplib.h"
45 #include "debug.h"
46 
47 /*
48  * Buffer and line limits
49  */
50 #define	SNMP_DBLOCK_SZ		4096
51 #define	SNMP_DMAX_LINE		80
52 #define	SNMP_NCHARS_IN_A_ROW	16
53 
54 /*
55  * Debug flags
56  */
57 #define	SNMP_DEBUG_CMD		0x01
58 #define	SNMP_DEBUG_VAR		0x02
59 #define	SNMP_DEBUG_PDU		0x04
60 #define	SNMP_DEBUG_ASN		0x08
61 #define	SNMP_DEBUG_PKT		0x10
62 #define	SNMP_DEBUG_IO		0x20
63 
64 #define	SNMP_DEBUG_DEFAULT	0x15	/* cmd, pdu, pkt */
65 #define	SNMP_DEBUG_EXTENDED	0x35	/* cmd, pdu, pkt, io */
66 #define	SNMP_DEBUG_ALL		0x3f
67 
68 /*
69  * Formatting aids
70  */
71 #define	SNMP_DCMD_INDENT	2
72 #define	SNMP_DVAR_INDENT	4
73 #define	SNMP_DPDU_INDENT	6
74 #define	SNMP_DASN_INDENT	8
75 #define	SNMP_DPKT_INDENT	10
76 #define	SNMP_DIO_INDENT		12
77 
78 #define	SNMP_DHDR_PREFIX	(const char *)" ___ "
79 #define	SNMP_DHDR_SUFFIX	(const char *)" ___"
80 #define	SNMP_DTEXT_PREFIX	(const char *)"| "
81 
82 /*
83  * All debug vars are protected by a single lock
84  */
85 static mutex_t	snmp_dbuf_lock;				/* debug lock */
86 static uint16_t	snmp_debug_flag = SNMP_DEBUG_EXTENDED;	/* debug flags */
87 static char	*snmp_dbuf = NULL;			/* the debug buffer */
88 static char	*snmp_dbuf_curp = NULL;			/* current dbuf index */
89 static char	*snmp_dbuf_tail = NULL;			/* current dbuf tail */
90 static int	snmp_dbuf_sz = 0;			/* current dbuf size */
91 static int	snmp_dbuf_overflow = 0;			/* no more memory */
92 static char	snmp_lbuf[SNMP_DMAX_LINE];		/* scratch space */
93 
94 /*
95  * Key-to-string
96  */
97 typedef struct {
98 	int	key;
99 	char	*str;
100 } snmp_key_to_str_t;
101 
102 static snmp_key_to_str_t snmp_cmds[] = {
103 	{ SNMP_MSG_GET, "SNMP_MSG_GET" },
104 	{ SNMP_MSG_GETNEXT, "SNMP_MSG_GETNEXT" },
105 	{ SNMP_MSG_RESPONSE, "SNMP_MSG_RESPONSE" },
106 	{ SNMP_MSG_SET, "SNMP_MSG_SET" },
107 	{ SNMP_MSG_TRAP, "SNMP_MSG_TRAP" },
108 	{ SNMP_MSG_GETBULK, "SNMP_MSG_GETBULK" },
109 	{ SNMP_MSG_INFORM, "SNMP_MSG_INFORM" },
110 	{ SNMP_MSG_TRAP2, "SNMP_MSG_TRAP2" },
111 	{ SNMP_MSG_REPORT, "SNMP_MSG_REPORT" }
112 };
113 
114 static snmp_key_to_str_t snmp_vartypes[] = {
115 	{ ASN_BOOLEAN, "ASN_BOOLEAN" },
116 	{ ASN_INTEGER, "ASN_INTEGER" },
117 	{ ASN_BIT_STR, "ASN_BIT_STR" },
118 	{ ASN_OCTET_STR, "ASN_OCTET_STR" },
119 	{ ASN_NULL, "ASN_NULL" },
120 	{ ASN_OBJECT_ID, "ASN_OBJECT_ID" },
121 	{ ASN_SEQUENCE, "ASN_SEQUENCE" }
122 };
123 
124 static snmp_key_to_str_t snmp_asnencodings[] = {
125 	{ SNMP_DASN_SEQUENCE, "ASN SEQUENCE" },
126 	{ SNMP_DASN_LENGTH, "ASN LENGTH" },
127 	{ SNMP_DASN_INT, "ASN INT" },
128 	{ SNMP_DASN_OCTET_STR, "ASN OCTET STR" },
129 	{ SNMP_DASN_OID, "ASN OBJECT ID" },
130 	{ SNMP_DASN_NULL, "ASN NULL" }
131 };
132 
133 static char *debug_tags[] = {
134 	"SNMP Command Request",
135 	"Null Var",
136 	"Response Var",
137 	"Request PDU",
138 	"Response PDU",
139 	"Request Packet",
140 	"Response Packet",
141 	"WRITE",
142 	"IOCTL",
143 	"READ",
144 	"SENDTO",
145 	"RECVFROM"
146 };
147 static const int n_tags = sizeof (debug_tags) / sizeof (char *);
148 
149 /*
150  * Helpers
151  */
152 static char	*snmp_cmdstr_lookup(int cmd);
153 static char	*snmp_vtypestr_lookup(int vtype);
154 static char	*snmp_asnencoding_lookup(int asnkey);
155 static void	snmp_get_dumpchars(uchar_t *abuf, uchar_t *p, int nchars);
156 static void	snmp_log_append(char *bufp);
157 static void	snmp_dbuf_realloc(void);
158 
159 void
160 snmp_debug_init(void)
161 {
162 	(void) mutex_init(&snmp_dbuf_lock, USYNC_THREAD, NULL);
163 
164 	(void) mutex_lock(&snmp_dbuf_lock);
165 	snmp_dbuf_realloc();
166 	if (snmp_dbuf == NULL)
167 		snmp_debug_flag = 0;	/* really tragic */
168 	(void) mutex_unlock(&snmp_dbuf_lock);
169 }
170 
171 void
172 snmp_log_cmd(uint_t tag, int cmd, int n_oids, char *oidstr, int row)
173 {
174 	char	*cmdstr;
175 	int	i;
176 
177 	if (oidstr == NULL)
178 		return;
179 
180 	(void) mutex_lock(&snmp_dbuf_lock);
181 
182 	if ((snmp_debug_flag & SNMP_DEBUG_CMD) == 0) {
183 		(void) mutex_unlock(&snmp_dbuf_lock);
184 		return;
185 	}
186 
187 	snmp_log_append("\n");
188 
189 	if (tag < n_tags) {
190 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s%s%s\n",
191 		    SNMP_DCMD_INDENT, ' ', SNMP_DHDR_PREFIX,
192 		    debug_tags[tag], SNMP_DHDR_SUFFIX);
193 		snmp_log_append(snmp_lbuf);
194 	}
195 
196 	if ((cmdstr = snmp_cmdstr_lookup(cmd)) == NULL) {
197 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sCMD=%#x\n",
198 		    SNMP_DCMD_INDENT, ' ', SNMP_DTEXT_PREFIX, cmd);
199 	} else {
200 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s%s\n",
201 		    SNMP_DCMD_INDENT, ' ', SNMP_DTEXT_PREFIX, cmdstr);
202 	}
203 	snmp_log_append(snmp_lbuf);
204 
205 	for (i = 0; i < n_oids; i++) {
206 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s  %s.%d\n",
207 		    SNMP_DCMD_INDENT, ' ', SNMP_DTEXT_PREFIX,
208 		    oidstr, row);
209 		snmp_log_append(snmp_lbuf);
210 
211 		oidstr += strlen(oidstr) + 1;
212 	}
213 
214 	(void) mutex_unlock(&snmp_dbuf_lock);
215 }
216 
217 void
218 snmp_log_var(uint_t tag, pdu_varlist_t *vp)
219 {
220 	char	*vts;
221 
222 	if (vp == NULL)
223 		return;
224 
225 	(void) mutex_lock(&snmp_dbuf_lock);
226 
227 	if ((snmp_debug_flag & SNMP_DEBUG_VAR) == 0) {
228 		(void) mutex_unlock(&snmp_dbuf_lock);
229 		return;
230 	}
231 
232 	snmp_log_append("\n");
233 
234 	if (tag < n_tags) {
235 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s%s%s\n",
236 		    SNMP_DVAR_INDENT, ' ', SNMP_DHDR_PREFIX,
237 		    debug_tags[tag], SNMP_DHDR_SUFFIX);
238 		snmp_log_append(snmp_lbuf);
239 	}
240 
241 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%snextvar = %#x\n",
242 	    SNMP_DVAR_INDENT, ' ', SNMP_DTEXT_PREFIX, vp->nextvar);
243 	snmp_log_append(snmp_lbuf);
244 
245 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sname = %#x\n",
246 	    SNMP_DVAR_INDENT, ' ', SNMP_DTEXT_PREFIX, vp->name);
247 	snmp_log_append(snmp_lbuf);
248 
249 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sname_len = %u\n",
250 	    SNMP_DVAR_INDENT, ' ', SNMP_DTEXT_PREFIX, vp->name_len);
251 	snmp_log_append(snmp_lbuf);
252 
253 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sval.ptr = %#x\n",
254 	    SNMP_DVAR_INDENT, ' ', SNMP_DTEXT_PREFIX, vp->val.str);
255 	snmp_log_append(snmp_lbuf);
256 
257 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sval_len = %u\n",
258 	    SNMP_DVAR_INDENT, ' ', SNMP_DTEXT_PREFIX, vp->val_len);
259 	snmp_log_append(snmp_lbuf);
260 
261 	if ((vts = snmp_vtypestr_lookup(vp->type)) == NULL) {
262 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%stype = %#x\n",
263 		    SNMP_DVAR_INDENT, ' ', SNMP_DTEXT_PREFIX, vp->type);
264 	} else {
265 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%stype = %s\n",
266 		    SNMP_DVAR_INDENT, ' ', SNMP_DTEXT_PREFIX, vts);
267 	}
268 	snmp_log_append(snmp_lbuf);
269 
270 	(void) mutex_unlock(&snmp_dbuf_lock);
271 }
272 
273 void
274 snmp_log_pdu(uint_t tag, snmp_pdu_t *pdu)
275 {
276 	char	*cmdstr;
277 
278 	if (pdu == NULL)
279 		return;
280 
281 	(void) mutex_lock(&snmp_dbuf_lock);
282 
283 	if ((snmp_debug_flag & SNMP_DEBUG_PDU) == 0) {
284 		(void) mutex_unlock(&snmp_dbuf_lock);
285 		return;
286 	}
287 
288 	snmp_log_append("\n");
289 
290 	if (tag < n_tags) {
291 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s%s%s\n",
292 		    SNMP_DPDU_INDENT, ' ', SNMP_DHDR_PREFIX,
293 		    debug_tags[tag], SNMP_DHDR_SUFFIX);
294 		snmp_log_append(snmp_lbuf);
295 	}
296 
297 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sversion = %d\n",
298 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->version);
299 	snmp_log_append(snmp_lbuf);
300 
301 	if (pdu->community) {
302 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
303 		    "%*c%scommunity = %s\n", SNMP_DPDU_INDENT, ' ',
304 		    SNMP_DTEXT_PREFIX, pdu->community);
305 	} else {
306 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
307 		    "%*c%scommunity = %#x\n", SNMP_DPDU_INDENT, ' ',
308 		    SNMP_DTEXT_PREFIX, pdu->community);
309 	}
310 	snmp_log_append(snmp_lbuf);
311 
312 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%scommunity_len = %u\n",
313 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->community_len);
314 	snmp_log_append(snmp_lbuf);
315 
316 	if ((cmdstr = snmp_cmdstr_lookup(pdu->command)) == NULL) {
317 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
318 		    "%*c%scommand = %#x\n", SNMP_DPDU_INDENT, ' ',
319 		    SNMP_DTEXT_PREFIX, pdu->command);
320 	} else {
321 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
322 		    "%*c%scommand = %s\n", SNMP_DPDU_INDENT, ' ',
323 		    SNMP_DTEXT_PREFIX, cmdstr);
324 	}
325 	snmp_log_append(snmp_lbuf);
326 
327 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sreqid = %d\n",
328 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->reqid);
329 	snmp_log_append(snmp_lbuf);
330 
331 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
332 	    "%*c%serrstat = %#x (non-repeaters)\n", SNMP_DPDU_INDENT, ' ',
333 	    SNMP_DTEXT_PREFIX, pdu->errstat);
334 	snmp_log_append(snmp_lbuf);
335 
336 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
337 	    "%*c%serrindex = %u (max-reps)\n", SNMP_DPDU_INDENT, ' ',
338 	    SNMP_DTEXT_PREFIX, pdu->errindex);
339 	snmp_log_append(snmp_lbuf);
340 
341 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%svars = %#x\n",
342 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->vars);
343 	snmp_log_append(snmp_lbuf);
344 
345 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sreq_pkt = %#x\n",
346 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->req_pkt);
347 	snmp_log_append(snmp_lbuf);
348 
349 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sreq_pktsz = %u\n",
350 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->req_pktsz);
351 	snmp_log_append(snmp_lbuf);
352 
353 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sreply_pkt = %#x\n",
354 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->reply_pkt);
355 	snmp_log_append(snmp_lbuf);
356 
357 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sreply_pktsz = %u\n",
358 	    SNMP_DPDU_INDENT, ' ', SNMP_DTEXT_PREFIX, pdu->reply_pktsz);
359 	snmp_log_append(snmp_lbuf);
360 
361 	snmp_log_append("\n");
362 
363 	(void) mutex_unlock(&snmp_dbuf_lock);
364 }
365 
366 void
367 snmp_log_asn(int key, uchar_t *pkt, size_t pktsz)
368 {
369 	char	*p, *asnstr;
370 	int	i, len;
371 	size_t	nrows, nrem;
372 
373 	if (pkt == NULL)
374 		return;
375 
376 	(void) mutex_lock(&snmp_dbuf_lock);
377 
378 	if ((snmp_debug_flag & SNMP_DEBUG_ASN) == 0) {
379 		(void) mutex_unlock(&snmp_dbuf_lock);
380 		return;
381 	}
382 
383 	if ((asnstr = snmp_asnencoding_lookup(key)) == NULL) {
384 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%sASNKEY=%#x\n",
385 		    SNMP_DASN_INDENT, ' ', SNMP_DTEXT_PREFIX, key);
386 	} else {
387 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s%s\n",
388 		    SNMP_DASN_INDENT, ' ', SNMP_DTEXT_PREFIX, asnstr);
389 	}
390 	snmp_log_append(snmp_lbuf);
391 
392 	nrows = pktsz / 16;
393 	for (i = 0; i < nrows; i++) {
394 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s  "
395 		    "%02x %02x %02x %02x %02x %02x %02x %02x "
396 		    "%02x %02x %02x %02x %02x %02x %02x %02x\n",
397 		    SNMP_DASN_INDENT, ' ', SNMP_DTEXT_PREFIX,
398 		    pkt[0], pkt[1], pkt[2], pkt[3], pkt[4], pkt[5],
399 		    pkt[6], pkt[7], pkt[8], pkt[9], pkt[10], pkt[11],
400 		    pkt[12], pkt[13], pkt[14], pkt[15]);
401 
402 		pkt += 16;
403 		snmp_log_append(snmp_lbuf);
404 	}
405 
406 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s ",
407 	    SNMP_DASN_INDENT, ' ', SNMP_DTEXT_PREFIX);
408 
409 	p = snmp_lbuf + SNMP_DASN_INDENT + strlen(SNMP_DTEXT_PREFIX) + 1;
410 	len = SNMP_DMAX_LINE - SNMP_DASN_INDENT - strlen(SNMP_DTEXT_PREFIX) - 1;
411 
412 	nrem = pktsz % 16;
413 	for (i = 0; i < nrem; i++) {
414 		(void) snprintf(p, len, " %02x", pkt[i]);
415 
416 		p += 3;
417 		len -= 3;
418 	}
419 	(void) snprintf(p, len, "\n");
420 	snmp_log_append(snmp_lbuf);
421 
422 	(void) mutex_unlock(&snmp_dbuf_lock);
423 }
424 
425 void
426 snmp_log_pkt(uint_t tag, uchar_t *pkt, size_t pktsz)
427 {
428 	uchar_t	ascii[SNMP_NCHARS_IN_A_ROW + 1];
429 	uchar_t	*p = pkt;
430 	char	*bufp;
431 	int	nrows, nrem;
432 	int	i, len;
433 
434 	if (pkt == NULL)
435 		return;
436 
437 	(void) mutex_lock(&snmp_dbuf_lock);
438 
439 	if ((snmp_debug_flag & SNMP_DEBUG_PKT) == 0) {
440 		(void) mutex_unlock(&snmp_dbuf_lock);
441 		return;
442 	}
443 
444 	snmp_log_append("\n");
445 
446 	if (tag < n_tags) {
447 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s%s%s\n",
448 		    SNMP_DPKT_INDENT, ' ',
449 		    SNMP_DHDR_PREFIX, debug_tags[tag], SNMP_DHDR_SUFFIX);
450 		snmp_log_append(snmp_lbuf);
451 	}
452 
453 	nrows = pktsz / SNMP_NCHARS_IN_A_ROW;
454 	nrem = pktsz % SNMP_NCHARS_IN_A_ROW;
455 
456 	for (i = 0; i < nrows; i++) {
457 		snmp_get_dumpchars(ascii, p, SNMP_NCHARS_IN_A_ROW);
458 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s"
459 		    "%02x %02x %02x %02x %02x %02x %02x %02x "
460 		    "%02x %02x %02x %02x %02x %02x %02x %02x "
461 		    "%s\n",
462 		    SNMP_DPKT_INDENT, ' ', SNMP_DTEXT_PREFIX,
463 		    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
464 		    p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15],
465 		    ascii);
466 		p += 16;
467 
468 		snmp_log_append(snmp_lbuf);
469 	}
470 
471 	(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE, "%*c%s",
472 	    SNMP_DPKT_INDENT, ' ', SNMP_DTEXT_PREFIX);
473 
474 	snmp_get_dumpchars(ascii, p, nrem);
475 
476 	bufp = snmp_lbuf + SNMP_DPKT_INDENT + strlen(SNMP_DTEXT_PREFIX);
477 	len = SNMP_DMAX_LINE - SNMP_DPKT_INDENT + strlen(SNMP_DTEXT_PREFIX);
478 	for (i = 0; i < 16; i++) {
479 		if (i < nrem)
480 			(void) snprintf(bufp, len, "%02x ", p[i]);
481 		else
482 			(void) snprintf(bufp, len, "   ");
483 
484 		bufp += 3;
485 		len -= 3;
486 	}
487 	(void) snprintf(bufp, len, "%s\n", ascii);
488 	snmp_log_append(snmp_lbuf);
489 
490 	(void) mutex_unlock(&snmp_dbuf_lock);
491 }
492 
493 void
494 snmp_log_io(uint_t tag, int a1, uint_t a2, uint_t a3)
495 {
496 	(void) mutex_lock(&snmp_dbuf_lock);
497 
498 	if ((snmp_debug_flag & SNMP_DEBUG_IO) == 0) {
499 		(void) mutex_unlock(&snmp_dbuf_lock);
500 		return;
501 	}
502 
503 	snmp_log_append("\n");
504 
505 	if (tag < n_tags) {
506 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
507 		    "%*c%s%s(%d, %#x, %#x)\n", SNMP_DIO_INDENT, ' ',
508 		    SNMP_DTEXT_PREFIX, debug_tags[tag], a1, a2, a3);
509 	} else {
510 		(void) snprintf(snmp_lbuf, SNMP_DMAX_LINE,
511 		    "%*c%s%#x(%d, %#x, %#x)\n", SNMP_DIO_INDENT, ' ',
512 		    SNMP_DTEXT_PREFIX, tag, a1, a2, a3);
513 	}
514 
515 	snmp_log_append(snmp_lbuf);
516 
517 	(void) mutex_unlock(&snmp_dbuf_lock);
518 }
519 
520 static char *
521 snmp_cmdstr_lookup(int cmd)
522 {
523 	int	nelem = sizeof (snmp_cmds) / sizeof (snmp_key_to_str_t);
524 	int	i;
525 
526 	for (i = 0; i < nelem; i++) {
527 		if (snmp_cmds[i].key == cmd)
528 			return (snmp_cmds[i].str);
529 	}
530 
531 	return (NULL);
532 }
533 
534 static char *
535 snmp_vtypestr_lookup(int vtype)
536 {
537 	int	nelem = sizeof (snmp_vartypes) / sizeof (snmp_key_to_str_t);
538 	int	i;
539 
540 	for (i = 0; i < nelem; i++) {
541 		if (snmp_vartypes[i].key == vtype)
542 			return (snmp_vartypes[i].str);
543 	}
544 
545 	return (NULL);
546 }
547 
548 static char *
549 snmp_asnencoding_lookup(int asnkey)
550 {
551 	int	nelem = sizeof (snmp_asnencodings) / sizeof (snmp_key_to_str_t);
552 	int	i;
553 
554 	for (i = 0; i < nelem; i++) {
555 		if (snmp_asnencodings[i].key == asnkey)
556 			return (snmp_asnencodings[i].str);
557 	}
558 
559 	return (NULL);
560 }
561 
562 static void
563 snmp_get_dumpchars(uchar_t *abuf, uchar_t *p, int nchars)
564 {
565 	int	i;
566 
567 	if (nchars > SNMP_NCHARS_IN_A_ROW)
568 		nchars = SNMP_NCHARS_IN_A_ROW;
569 
570 	abuf[nchars] = 0;
571 	for (i = 0; i < nchars; i++)
572 		abuf[i] = isprint(p[i]) ? p[i] : '.';
573 }
574 
575 static void
576 snmp_log_append(char *bufp)
577 {
578 	int	len;
579 
580 	len = strlen(bufp);
581 	if ((snmp_dbuf_curp + len) >= snmp_dbuf_tail)
582 		snmp_dbuf_realloc();
583 
584 	(void) strcpy(snmp_dbuf_curp, bufp);
585 
586 	snmp_dbuf_curp += len;
587 }
588 
589 static void
590 snmp_dbuf_realloc(void)
591 {
592 	char	*p;
593 	size_t	offset = 0;
594 	size_t	count;
595 
596 	count = snmp_dbuf_sz + SNMP_DBLOCK_SZ;
597 	if ((p = (char *)calloc(count, 1)) == NULL) {
598 		snmp_dbuf_overflow++;
599 		snmp_dbuf_curp = snmp_dbuf;
600 		return;
601 	}
602 
603 	if (snmp_dbuf) {
604 		offset = snmp_dbuf_curp - snmp_dbuf;
605 		(void) memcpy(p, snmp_dbuf, snmp_dbuf_sz);
606 		free(snmp_dbuf);
607 	}
608 
609 	snmp_dbuf = p;
610 	snmp_dbuf_sz += SNMP_DBLOCK_SZ;
611 
612 	snmp_dbuf_curp = snmp_dbuf + offset;
613 	snmp_dbuf_tail = snmp_dbuf + snmp_dbuf_sz;
614 }
615 
616 #endif
617