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