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