xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ldap.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2000-2002 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <ctype.h>
31*0Sstevel@tonic-gate #include <string.h>
32*0Sstevel@tonic-gate #include <fcntl.h>
33*0Sstevel@tonic-gate #include <string.h>
34*0Sstevel@tonic-gate #include <sys/types.h>
35*0Sstevel@tonic-gate #include <sys/time.h>
36*0Sstevel@tonic-gate #include <sys/stat.h>
37*0Sstevel@tonic-gate #include <sys/uio.h>
38*0Sstevel@tonic-gate #include <unistd.h>
39*0Sstevel@tonic-gate #include <signal.h>
40*0Sstevel@tonic-gate #include <errno.h>
41*0Sstevel@tonic-gate #include <stdlib.h>
42*0Sstevel@tonic-gate #include <sys/wait.h>
43*0Sstevel@tonic-gate #include <sys/socket.h>
44*0Sstevel@tonic-gate #include <sys/sockio.h>
45*0Sstevel@tonic-gate #include <net/if.h>
46*0Sstevel@tonic-gate #include <netinet/in_systm.h>
47*0Sstevel@tonic-gate #include <netinet/in.h>
48*0Sstevel@tonic-gate #include <netinet/ip.h>
49*0Sstevel@tonic-gate #include <netinet/if_ether.h>
50*0Sstevel@tonic-gate #include <netinet/udp.h>
51*0Sstevel@tonic-gate #include "snoop.h"
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #ifndef MIN
54*0Sstevel@tonic-gate #define	MIN(a, b) ((a) < (b) ? (a) : (b))
55*0Sstevel@tonic-gate #endif
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate extern char *src_name;
58*0Sstevel@tonic-gate extern char *dst_name;
59*0Sstevel@tonic-gate #define	MAX_CTX  (10)
60*0Sstevel@tonic-gate #define	LINE_LEN (255)
61*0Sstevel@tonic-gate #define	BUF_SIZE (16000)
62*0Sstevel@tonic-gate static int ldap = 0;	/* flag to control initialization */
63*0Sstevel@tonic-gate struct ctx {
64*0Sstevel@tonic-gate 	int src;
65*0Sstevel@tonic-gate 	int dst;
66*0Sstevel@tonic-gate 	char *src_name;
67*0Sstevel@tonic-gate 	char *dst_name;
68*0Sstevel@tonic-gate };
69*0Sstevel@tonic-gate char *osibuff = NULL;
70*0Sstevel@tonic-gate int osilen = 0;
71*0Sstevel@tonic-gate char scrbuffer[BUF_SIZE];	/* buffer to accumulate data until a */
72*0Sstevel@tonic-gate 				/* complete LDAPmessage is received  */
73*0Sstevel@tonic-gate char resultcode[LINE_LEN];	/* These are used */
74*0Sstevel@tonic-gate char operation[LINE_LEN];	/* by -V option.  */
75*0Sstevel@tonic-gate char bb[LINE_LEN];
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate int gi_osibuf[MAX_CTX];
78*0Sstevel@tonic-gate int otyp[MAX_CTX];
79*0Sstevel@tonic-gate int olen[MAX_CTX];
80*0Sstevel@tonic-gate int level[MAX_CTX];
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate void decode_ldap(char *buf, int len);
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate #define	X unsigned char
85*0Sstevel@tonic-gate typedef	X * A;
86*0Sstevel@tonic-gate #define	INT(a) ((int)(a))
87*0Sstevel@tonic-gate #define	SCRUB (void) strcat(scrbuffer, bb);
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate static X	hex;	/* input hex octet */
90*0Sstevel@tonic-gate static A	*PTRaclass;	/* application tag table pointer */
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate /*
93*0Sstevel@tonic-gate **----------------------------------------------**
94*0Sstevel@tonic-gate **		ASN.1 Message Printing Macros			**
95*0Sstevel@tonic-gate **----------------------------------------------**
96*0Sstevel@tonic-gate */
97*0Sstevel@tonic-gate 
98*0Sstevel@tonic-gate #define	asnshw1(a)				{(void)sprintf(bb, a); SCRUB }
99*0Sstevel@tonic-gate #define	asnshw2(a, b)			{(void)sprintf(bb, a, b); SCRUB }
100*0Sstevel@tonic-gate #define	asnshw3(a, b, c)		{(void)sprintf(bb, a, b, c); SCRUB }
101*0Sstevel@tonic-gate #define	asnshw4(a, b, c, d)		{(void)sprintf(bb, a, b, c, d); SCRUB }
102*0Sstevel@tonic-gate #define	asnshw5(a, b, c, d, e)	{(void)sprintf(bb, a, b, c, d, e); SCRUB }
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate /*
105*0Sstevel@tonic-gate **--------------------------------------**
106*0Sstevel@tonic-gate **		Local Types And Variables		**
107*0Sstevel@tonic-gate **--------------------------------------**
108*0Sstevel@tonic-gate */
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate /*
111*0Sstevel@tonic-gate ** object identifier oid to name mapping description type
112*0Sstevel@tonic-gate */
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate typedef struct {
115*0Sstevel@tonic-gate 	A	oidname;		/* object identifier string name */
116*0Sstevel@tonic-gate 	X	oidcode[16];	/* object identifier hexa code */
117*0Sstevel@tonic-gate }	oidelmT;
118*0Sstevel@tonic-gate typedef oidelmT *oidelmTp;
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate /*
121*0Sstevel@tonic-gate **------------------------------------------**
122*0Sstevel@tonic-gate **	snoop's entry point to ldap decoding	**
123*0Sstevel@tonic-gate **------------------------------------------**
124*0Sstevel@tonic-gate */
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate void
127*0Sstevel@tonic-gate interpret_ldap(flags, data, fraglen, src, dst)
128*0Sstevel@tonic-gate int flags;
129*0Sstevel@tonic-gate char *data;
130*0Sstevel@tonic-gate int fraglen;
131*0Sstevel@tonic-gate int src;
132*0Sstevel@tonic-gate int dst;
133*0Sstevel@tonic-gate {
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	if (!ldap) {
136*0Sstevel@tonic-gate 		init_ldap();
137*0Sstevel@tonic-gate 		ldap = 1;
138*0Sstevel@tonic-gate 	}
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	(void) decode_ldap(data, fraglen);
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate 	if (flags & F_DTAIL) {
143*0Sstevel@tonic-gate 		/* i.e. when snoop is run with -v (verbose) */
144*0Sstevel@tonic-gate 		show_header("LDAP:  ",
145*0Sstevel@tonic-gate 		"Lightweight Directory Access Protocol Header", fraglen);
146*0Sstevel@tonic-gate 		show_space();
147*0Sstevel@tonic-gate 		printf("%s", scrbuffer);
148*0Sstevel@tonic-gate 	}
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 	if (flags & F_SUM) {
151*0Sstevel@tonic-gate 	/* i.e. when snoop is run with -V (summary) */
152*0Sstevel@tonic-gate 		(void) strcpy(data, "");
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 		if (strlen(operation) != 0) {
155*0Sstevel@tonic-gate 			(void) strcat(data, " ");
156*0Sstevel@tonic-gate 			(void) strncat(data, operation, 30);
157*0Sstevel@tonic-gate 			(void) strcpy(operation, "");
158*0Sstevel@tonic-gate 		}
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 		if (strlen(resultcode) != 0) {
161*0Sstevel@tonic-gate 			(void) strcat(data, " ");
162*0Sstevel@tonic-gate 			(void) strncat(data, resultcode, 30);
163*0Sstevel@tonic-gate 			(void) strcpy(resultcode, "");
164*0Sstevel@tonic-gate 		}
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate 		if (dst == 389) {
167*0Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
168*0Sstevel@tonic-gate 				"LDAP C port=%d%s", src, data);
169*0Sstevel@tonic-gate 		}
170*0Sstevel@tonic-gate 		if (src == 389) {
171*0Sstevel@tonic-gate 			(void) sprintf(get_sum_line(),
172*0Sstevel@tonic-gate 				"LDAP R port=%d%s", dst, data);
173*0Sstevel@tonic-gate 		}
174*0Sstevel@tonic-gate 	}
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate 	(void) strcpy(scrbuffer, "");
177*0Sstevel@tonic-gate }
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate /*
180*0Sstevel@tonic-gate **--------------------------------------------------------------**
181*0Sstevel@tonic-gate **	known object identifiers: customize to add your own oids	**
182*0Sstevel@tonic-gate **--------------------------------------------------------------**
183*0Sstevel@tonic-gate */
184*0Sstevel@tonic-gate 
185*0Sstevel@tonic-gate static oidelmT OidTab[] = {
186*0Sstevel@tonic-gate /*
187*0Sstevel@tonic-gate **	X.500 Standardized Attribute Types
188*0Sstevel@tonic-gate */
189*0Sstevel@tonic-gate {(A)"ObjectClass",				{ 0x03, 0x55, 0x04, 0x00 }},
190*0Sstevel@tonic-gate {(A)"AliasObjectName",			{ 0x03, 0x55, 0x04, 0x01 }},
191*0Sstevel@tonic-gate {(A)"KnowledgeInfo",			{ 0x03, 0x55, 0x04, 0x02 }},
192*0Sstevel@tonic-gate {(A)"CommonName",				{ 0x03, 0x55, 0x04, 0x03 }},
193*0Sstevel@tonic-gate {(A)"Surname",					{ 0x03, 0x55, 0x04, 0x04 }},
194*0Sstevel@tonic-gate {(A)"SerialNumber",				{ 0x03, 0x55, 0x04, 0x05 }},
195*0Sstevel@tonic-gate {(A)"CountryName",				{ 0x03, 0x55, 0x04, 0x06 }},
196*0Sstevel@tonic-gate {(A)"LocalityName",				{ 0x03, 0x55, 0x04, 0x07 }},
197*0Sstevel@tonic-gate {(A)"StateOrProvinceName",		{ 0x03, 0x55, 0x04, 0x08 }},
198*0Sstevel@tonic-gate {(A)"StreetAddress",			{ 0x03, 0x55, 0x04, 0x09 }},
199*0Sstevel@tonic-gate {(A)"OrganizationName",			{ 0x03, 0x55, 0x04, 0x0a }},
200*0Sstevel@tonic-gate {(A)"OrganizationUnitName",		{ 0x03, 0x55, 0x04, 0x0b }},
201*0Sstevel@tonic-gate {(A)"Title",					{ 0x03, 0x55, 0x04, 0x0c }},
202*0Sstevel@tonic-gate {(A)"Description",				{ 0x03, 0x55, 0x04, 0x0d }},
203*0Sstevel@tonic-gate {(A)"SearchGuide",				{ 0x03, 0x55, 0x04, 0x0e }},
204*0Sstevel@tonic-gate {(A)"BusinessCategory",			{ 0x03, 0x55, 0x04, 0x0f }},
205*0Sstevel@tonic-gate {(A)"PostalAddress",			{ 0x03, 0x55, 0x04, 0x10 }},
206*0Sstevel@tonic-gate {(A)"PostalCode",				{ 0x03, 0x55, 0x04, 0x11 }},
207*0Sstevel@tonic-gate {(A)"PostOfficeBox",			{ 0x03, 0x55, 0x04, 0x12 }},
208*0Sstevel@tonic-gate {(A)"PhysicalDeliveryOffice",	{ 0x03, 0x55, 0x04, 0x13 }},
209*0Sstevel@tonic-gate {(A)"TelephoneNUmber",			{ 0x03, 0x55, 0x04, 0x14 }},
210*0Sstevel@tonic-gate {(A)"TelexNumber",				{ 0x03, 0x55, 0x04, 0x15 }},
211*0Sstevel@tonic-gate {(A)"TeletexTerminalId",		{ 0x03, 0x55, 0x04, 0x16 }},
212*0Sstevel@tonic-gate {(A)"FaxTelephoneNumber",		{ 0x03, 0x55, 0x04, 0x17 }},
213*0Sstevel@tonic-gate {(A)"X121Address",				{ 0x03, 0x55, 0x04, 0x18 }},
214*0Sstevel@tonic-gate {(A)"IsdnAddress",				{ 0x03, 0x55, 0x04, 0x19 }},
215*0Sstevel@tonic-gate {(A)"RegisteredAddress",		{ 0x03, 0x55, 0x04, 0x1a }},
216*0Sstevel@tonic-gate {(A)"DestinationIndicator",		{ 0x03, 0x55, 0x04, 0x1b }},
217*0Sstevel@tonic-gate {(A)"PreferDeliveryMethod",		{ 0x03, 0x55, 0x04, 0x1c }},
218*0Sstevel@tonic-gate {(A)"PresentationAddress",		{ 0x03, 0x55, 0x04, 0x1d }},
219*0Sstevel@tonic-gate {(A)"SupportedApplContext",		{ 0x03, 0x55, 0x04, 0x1e }},
220*0Sstevel@tonic-gate {(A)"Member",					{ 0x03, 0x55, 0x04, 0x1f }},
221*0Sstevel@tonic-gate {(A)"Owner",					{ 0x03, 0x55, 0x04, 0x20 }},
222*0Sstevel@tonic-gate {(A)"RoleOccupant",				{ 0x03, 0x55, 0x04, 0x21 }},
223*0Sstevel@tonic-gate {(A)"SeeAlso",					{ 0x03, 0x55, 0x04, 0x22 }},
224*0Sstevel@tonic-gate {(A)"Password",					{ 0x03, 0x55, 0x04, 0x23 }},
225*0Sstevel@tonic-gate {(A)"UserCertificate",			{ 0x03, 0x55, 0x04, 0x24 }},
226*0Sstevel@tonic-gate {(A)"CaCertificate",			{ 0x03, 0x55, 0x04, 0x25 }},
227*0Sstevel@tonic-gate {(A)"AuthorityRevList",			{ 0x03, 0x55, 0x04, 0x26 }},
228*0Sstevel@tonic-gate {(A)"CertificateRevList",		{ 0x03, 0x55, 0x04, 0x27 }},
229*0Sstevel@tonic-gate {(A)"CrossCertificatePair",		{ 0x03, 0x55, 0x04, 0x28 }},
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate /*
232*0Sstevel@tonic-gate **	X.500 Standardized Object Classes
233*0Sstevel@tonic-gate */
234*0Sstevel@tonic-gate {(A)"Top",					{ 0x03, 0x55, 0x06, 0x00 }},
235*0Sstevel@tonic-gate {(A)"Alias",				{ 0x03, 0x55, 0x06, 0x01 }},
236*0Sstevel@tonic-gate {(A)"Country",				{ 0x03, 0x55, 0x06, 0x02 }},
237*0Sstevel@tonic-gate {(A)"Locality",				{ 0x03, 0x55, 0x06, 0x03 }},
238*0Sstevel@tonic-gate {(A)"Organization",			{ 0x03, 0x55, 0x06, 0x04 }},
239*0Sstevel@tonic-gate {(A)"OrganizationUnit",		{ 0x03, 0x55, 0x06, 0x05 }},
240*0Sstevel@tonic-gate {(A)"Person",				{ 0x03, 0x55, 0x06, 0x06 }},
241*0Sstevel@tonic-gate {(A)"OrganizationPersion",	{ 0x03, 0x55, 0x06, 0x07 }},
242*0Sstevel@tonic-gate {(A)"OrganizationRole",		{ 0x03, 0x55, 0x06, 0x08 }},
243*0Sstevel@tonic-gate {(A)"Group",				{ 0x03, 0x55, 0x06, 0x09 }},
244*0Sstevel@tonic-gate {(A)"ResidentialPerson",	{ 0x03, 0x55, 0x06, 0x0A }},
245*0Sstevel@tonic-gate {(A)"ApplicationProcess",	{ 0x03, 0x55, 0x06, 0x0B }},
246*0Sstevel@tonic-gate {(A)"ApplicationEntity",	{ 0x03, 0x55, 0x06, 0x0C }},
247*0Sstevel@tonic-gate {(A)"Dsa",					{ 0x03, 0x55, 0x06, 0x0D }},
248*0Sstevel@tonic-gate {(A)"Device",				{ 0x03, 0x55, 0x06, 0x0E }},
249*0Sstevel@tonic-gate {(A)"StrongAuthenticUser",	{ 0x03, 0x55, 0x06, 0x0F }},
250*0Sstevel@tonic-gate {(A)"CaAuthority",			{ 0x03, 0x55, 0x06, 0x10 }},
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate /*
253*0Sstevel@tonic-gate **	ACSE Protocol Object Identifiers
254*0Sstevel@tonic-gate */
255*0Sstevel@tonic-gate {(A)"Asn1BER-TS",		{ 0x02, 0x51, 0x01 }},
256*0Sstevel@tonic-gate {(A)"Private-TS",		{ 0x06, 0x2b, 0xce, 0x06, 0x01, 0x04, 0x06 }},
257*0Sstevel@tonic-gate {(A)"ACSE-AS",			{ 0x04, 0x52, 0x01, 0x00, 0x01 }},
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate /*
260*0Sstevel@tonic-gate **	Directory Protocol Oids
261*0Sstevel@tonic-gate */
262*0Sstevel@tonic-gate {(A)"DirAccess-AC",			{ 0x03, 0x55, 0x03, 0x01 }},
263*0Sstevel@tonic-gate {(A)"DirSystem-AC",			{ 0x03, 0x55, 0x03, 0x02 }},
264*0Sstevel@tonic-gate 
265*0Sstevel@tonic-gate {(A)"DirAccess-AS",			{ 0x03, 0x55, 0x09, 0x01 }},
266*0Sstevel@tonic-gate {(A)"DirSystem-AS",			{ 0x03, 0x55, 0x09, 0x02 }},
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate /*
269*0Sstevel@tonic-gate **	and add your private object identifiers here ...
270*0Sstevel@tonic-gate */
271*0Sstevel@tonic-gate };
272*0Sstevel@tonic-gate 
273*0Sstevel@tonic-gate #define	OIDNB (sizeof (OidTab) / sizeof (oidelmT))	/* total oid nb */
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate /*
276*0Sstevel@tonic-gate **	asn.1 tag class definition
277*0Sstevel@tonic-gate */
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate static A class[] = {	/* tag class */
280*0Sstevel@tonic-gate 	(A)"UNIV ",
281*0Sstevel@tonic-gate 	(A)"APPL ",
282*0Sstevel@tonic-gate 	(A)"CTXs ",
283*0Sstevel@tonic-gate 	(A)"PRIV "
284*0Sstevel@tonic-gate };
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate /*
287*0Sstevel@tonic-gate **	universal tag definition
288*0Sstevel@tonic-gate */
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate static A uclass[] = {	/* universal tag assignment */
291*0Sstevel@tonic-gate (A)"EndOfContents",			/* 0  */
292*0Sstevel@tonic-gate (A)"Boolean",				/* 1  */
293*0Sstevel@tonic-gate (A)"Integer",				/* 2  */
294*0Sstevel@tonic-gate (A)"BitString",				/* 3  */
295*0Sstevel@tonic-gate (A)"OctetString",			/* 4  */
296*0Sstevel@tonic-gate (A)"Null",					/* 5  */
297*0Sstevel@tonic-gate (A)"Oid",					/* 6  */
298*0Sstevel@tonic-gate (A)"ObjDescriptor",			/* 7  */
299*0Sstevel@tonic-gate (A)"External",				/* 8  */
300*0Sstevel@tonic-gate (A)"Real",					/* 9  */
301*0Sstevel@tonic-gate (A)"Enumerated",			/* 10 */
302*0Sstevel@tonic-gate (A)"Reserved",				/* 11 */
303*0Sstevel@tonic-gate (A)"Reserved",				/* 12 */
304*0Sstevel@tonic-gate (A)"Reserved",				/* 13 */
305*0Sstevel@tonic-gate (A)"Reserved",				/* 14 */
306*0Sstevel@tonic-gate (A)"Reserved",				/* 15 */
307*0Sstevel@tonic-gate (A)"Sequence",				/* 16 */
308*0Sstevel@tonic-gate (A)"Set",					/* 17 */
309*0Sstevel@tonic-gate (A)"NumericString",			/* 18 */
310*0Sstevel@tonic-gate (A)"PrintableString",		/* 19 */
311*0Sstevel@tonic-gate (A)"T.61String",			/* 20 */
312*0Sstevel@tonic-gate (A)"VideotexString",		/* 21 */
313*0Sstevel@tonic-gate (A)"IA5String",				/* 22 */
314*0Sstevel@tonic-gate (A)"UTCTime",				/* 23 */
315*0Sstevel@tonic-gate (A)"GeneralizedTime",		/* 24 */
316*0Sstevel@tonic-gate (A)"GraphicString",			/* 25 */
317*0Sstevel@tonic-gate (A)"VisibleString",			/* 26 */
318*0Sstevel@tonic-gate (A)"GeneralString",			/* 27 */
319*0Sstevel@tonic-gate (A)"Reserved",				/* 28 */
320*0Sstevel@tonic-gate (A)"Reserved",				/* 29 */
321*0Sstevel@tonic-gate (A)"Reserved",				/* 30 */
322*0Sstevel@tonic-gate (A)"Reserved" 				/* 31 */
323*0Sstevel@tonic-gate };
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate static A MHSaclass[] = {	/* mhs application tag assignment */
326*0Sstevel@tonic-gate (A)"Bind Request",		/* 0 */
327*0Sstevel@tonic-gate (A)"Bind Response",
328*0Sstevel@tonic-gate (A)"Unbind Request",
329*0Sstevel@tonic-gate (A)"Search Request",
330*0Sstevel@tonic-gate (A)"Search ResEntry",
331*0Sstevel@tonic-gate (A)"Search ResDone",	/* 5 */
332*0Sstevel@tonic-gate (A)"Modify Request",
333*0Sstevel@tonic-gate (A)"Modify Response",
334*0Sstevel@tonic-gate (A)"Add Request",
335*0Sstevel@tonic-gate (A)"Add Response",		/* 9 */
336*0Sstevel@tonic-gate (A)"Del Request",
337*0Sstevel@tonic-gate (A)"Del Response",
338*0Sstevel@tonic-gate (A)"ModDN Request",
339*0Sstevel@tonic-gate (A)"ModDN Response",
340*0Sstevel@tonic-gate (A)"Compare Request",	/* 14 */
341*0Sstevel@tonic-gate (A)"Compare Response",
342*0Sstevel@tonic-gate (A)"Abandon Request",
343*0Sstevel@tonic-gate (A)"",					/* 17 */
344*0Sstevel@tonic-gate (A)"",					/* 18 */
345*0Sstevel@tonic-gate (A)"Search ResRef",		/* 19 */
346*0Sstevel@tonic-gate (A)"",					/* 20 */
347*0Sstevel@tonic-gate (A)"",					/* 21 */
348*0Sstevel@tonic-gate (A)"",					/* 22 */
349*0Sstevel@tonic-gate (A)"Extended Request",
350*0Sstevel@tonic-gate (A)"Extended Response",
351*0Sstevel@tonic-gate (A)"",					/* 25 */
352*0Sstevel@tonic-gate (A)"",					/* 26 */
353*0Sstevel@tonic-gate (A)"",					/* 27 */
354*0Sstevel@tonic-gate (A)"",					/* 28 */
355*0Sstevel@tonic-gate (A)"",					/* 29 */
356*0Sstevel@tonic-gate (A)"",					/* 30 */
357*0Sstevel@tonic-gate (A)"" 					/* 31 */
358*0Sstevel@tonic-gate };
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate static A DFTaclass[] = {	/* Default Application Tag Assignment */
362*0Sstevel@tonic-gate (A)"",				/* 0  */
363*0Sstevel@tonic-gate (A)"",				/* 1  */
364*0Sstevel@tonic-gate (A)"",				/* 2  */
365*0Sstevel@tonic-gate (A)"",				/* 3  */
366*0Sstevel@tonic-gate (A)"",				/* 4  */
367*0Sstevel@tonic-gate (A)"",				/* 5  */
368*0Sstevel@tonic-gate (A)"",				/* 6  */
369*0Sstevel@tonic-gate (A)"",				/* 7  */
370*0Sstevel@tonic-gate (A)"",				/* 8  */
371*0Sstevel@tonic-gate (A)"",				/* 9  */
372*0Sstevel@tonic-gate (A)"",				/* 10 */
373*0Sstevel@tonic-gate (A)"",				/* 11 */
374*0Sstevel@tonic-gate (A)"",				/* 12 */
375*0Sstevel@tonic-gate (A)"",				/* 13 */
376*0Sstevel@tonic-gate (A)"",				/* 14 */
377*0Sstevel@tonic-gate (A)"",				/* 15 */
378*0Sstevel@tonic-gate (A)"",				/* 16 */
379*0Sstevel@tonic-gate (A)"",				/* 17 */
380*0Sstevel@tonic-gate (A)"",				/* 18 */
381*0Sstevel@tonic-gate (A)"",				/* 19 */
382*0Sstevel@tonic-gate (A)"",				/* 20 */
383*0Sstevel@tonic-gate (A)"",				/* 21 */
384*0Sstevel@tonic-gate (A)"",				/* 22 */
385*0Sstevel@tonic-gate (A)"",				/* 23 */
386*0Sstevel@tonic-gate (A)"",				/* 24 */
387*0Sstevel@tonic-gate (A)"",				/* 25 */
388*0Sstevel@tonic-gate (A)"",				/* 26 */
389*0Sstevel@tonic-gate (A)"",				/* 27 */
390*0Sstevel@tonic-gate (A)"",				/* 28 */
391*0Sstevel@tonic-gate (A)"",				/* 29 */
392*0Sstevel@tonic-gate (A)"",				/* 30 */
393*0Sstevel@tonic-gate (A)"" 				/* 31 */
394*0Sstevel@tonic-gate };
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate typedef struct asndefS {
397*0Sstevel@tonic-gate char *name;
398*0Sstevel@tonic-gate int type;
399*0Sstevel@tonic-gate int application;
400*0Sstevel@tonic-gate int nbson;
401*0Sstevel@tonic-gate struct {
402*0Sstevel@tonic-gate 	char *sonname;
403*0Sstevel@tonic-gate 	struct asndefS *sondef;
404*0Sstevel@tonic-gate 	long tag;
405*0Sstevel@tonic-gate 	} son[50];
406*0Sstevel@tonic-gate } asndefT, * asndefTp;
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate #define	SEQUENCE		0x0002
409*0Sstevel@tonic-gate #define	SEQUENCEOF		0x0003
410*0Sstevel@tonic-gate #define	SET				0x0004
411*0Sstevel@tonic-gate #define	PRINTABLE		0x0008
412*0Sstevel@tonic-gate #define	ENUM			0x0010
413*0Sstevel@tonic-gate #define	BITSTRING		0x0020
414*0Sstevel@tonic-gate #define	EXTENSION		0x0040
415*0Sstevel@tonic-gate #define	CONTENTTYPE		0x0080
416*0Sstevel@tonic-gate #define	CONTENT			0x0100
417*0Sstevel@tonic-gate #define	CHOICE			0x0200
418*0Sstevel@tonic-gate 
419*0Sstevel@tonic-gate static asndefT RTSpasswd = { "RTS Authentification data", SET,  -1, 2, {
420*0Sstevel@tonic-gate 			{"MTA Name", 0, 0},
421*0Sstevel@tonic-gate 			{"MTA Password", 0, 1}}};
422*0Sstevel@tonic-gate static asndefT RTSudata = { "RTS User data", SET,  -1, 1, {
423*0Sstevel@tonic-gate 			{0, &RTSpasswd, 1}}};
424*0Sstevel@tonic-gate 
425*0Sstevel@tonic-gate static asndefT baseObject = {"Base Object", PRINTABLE, -1, 0, {0}};
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate static asndefT scope = {"Scope", ENUM, -1, 3, {
428*0Sstevel@tonic-gate 			{"BaseObject", 0, 0},
429*0Sstevel@tonic-gate 			{"singleLevel", 0, 1},
430*0Sstevel@tonic-gate 			{"wholeSubtree", 0, 2}}};
431*0Sstevel@tonic-gate 
432*0Sstevel@tonic-gate static asndefT derefAliases = {"DerefAliases", ENUM, -1, 4, {
433*0Sstevel@tonic-gate 			{"neverDerefAliases", 0, 0},
434*0Sstevel@tonic-gate 			{"derefInSearching", 0, 1},
435*0Sstevel@tonic-gate 			{"derefFindingBaseObj", 0, 2},
436*0Sstevel@tonic-gate 			{"derefAlways", 0, 3}}};
437*0Sstevel@tonic-gate 
438*0Sstevel@tonic-gate static asndefT filter;
439*0Sstevel@tonic-gate static asndefT and = {"And", SET, -1, 1, {
440*0Sstevel@tonic-gate 			{0, &filter, -1}}};
441*0Sstevel@tonic-gate static asndefT or = {"Or", SET, -1, 1, {
442*0Sstevel@tonic-gate 			{0, &filter, -1}}};
443*0Sstevel@tonic-gate static asndefT not = {"Not", SET, -1, 1, {
444*0Sstevel@tonic-gate 			{0, &filter, -1}}};
445*0Sstevel@tonic-gate static asndefT equalityMatch = {"Equality Match", SEQUENCE, -1, 2, {
446*0Sstevel@tonic-gate 			{"Attr Descr", 0, -1},
447*0Sstevel@tonic-gate 			{"Value", 0, -1}}};
448*0Sstevel@tonic-gate static asndefT substrings = {"Substring", SEQUENCE, -1, 2, {
449*0Sstevel@tonic-gate 			{"Type", 0, -1},
450*0Sstevel@tonic-gate 			{"Substrings (initial)", 0, 0},
451*0Sstevel@tonic-gate 			{"Substrings (any)", 0, 1},
452*0Sstevel@tonic-gate 			{"Substring (final)", 0, 2}}};
453*0Sstevel@tonic-gate static asndefT greaterOrEqual = {"Greater Or Equal", SEQUENCE, -1, 2, {
454*0Sstevel@tonic-gate 			{"Attr Descr", 0, -1},
455*0Sstevel@tonic-gate 			{"Value", 0, -1}}};
456*0Sstevel@tonic-gate static asndefT lessOrEqual = {"Less Or Equal", SEQUENCE, -1, 2, {
457*0Sstevel@tonic-gate 			{"Attr Descr", 0, -1},
458*0Sstevel@tonic-gate 			{"Value", 0, -1}}};
459*0Sstevel@tonic-gate static asndefT approxMatch = {"Approx Match", SEQUENCE, -1, 2, {
460*0Sstevel@tonic-gate 			{"Attr Descr", 0, -1},
461*0Sstevel@tonic-gate 			{"Value", 0, -1}}};
462*0Sstevel@tonic-gate static asndefT extensibleMatch = {"Extensible Match", SEQUENCE, -1, 4, {
463*0Sstevel@tonic-gate 			{"MatchingRule", 0, 1},
464*0Sstevel@tonic-gate 			{"Type", 0, 2},
465*0Sstevel@tonic-gate 			{"MatchValue", 0, 3},
466*0Sstevel@tonic-gate 			{"dnAttributes", 0, 4}}};
467*0Sstevel@tonic-gate 
468*0Sstevel@tonic-gate static asndefT filter = {"Filter", CHOICE, -1, 10, {
469*0Sstevel@tonic-gate 			{0, &and, 0},
470*0Sstevel@tonic-gate 			{0, &or, 1},
471*0Sstevel@tonic-gate 			{0, &not, 2},
472*0Sstevel@tonic-gate 			{0, &equalityMatch, 3},
473*0Sstevel@tonic-gate 			{0, &substrings, 4},
474*0Sstevel@tonic-gate 			{0, &greaterOrEqual, 5},
475*0Sstevel@tonic-gate 			{0, &lessOrEqual, 6},
476*0Sstevel@tonic-gate 			{"Filter: Present", 0, 7},
477*0Sstevel@tonic-gate 			{0, &approxMatch, 8},
478*0Sstevel@tonic-gate 			{0, &extensibleMatch, 9}}};
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate static asndefT attributedescription = \
481*0Sstevel@tonic-gate 			{"Attribute Description", PRINTABLE, -1, 0, {0}};
482*0Sstevel@tonic-gate static asndefT attributes = {"Attribute List", SEQUENCEOF, -1, 1, {
483*0Sstevel@tonic-gate 			{0, &attributedescription, -1}}};
484*0Sstevel@tonic-gate 
485*0Sstevel@tonic-gate static asndefT searchRequest = {"Operation", SEQUENCE, 3, 8, {
486*0Sstevel@tonic-gate 			{0, &baseObject, -1},
487*0Sstevel@tonic-gate 			{0, &scope, -1},
488*0Sstevel@tonic-gate 			{0, &derefAliases, -1},
489*0Sstevel@tonic-gate 			{"SizeLimit", 0, -1},
490*0Sstevel@tonic-gate 			{"TimeLimit", 0, -1},
491*0Sstevel@tonic-gate 			{"TypesOnly", 0, -1},
492*0Sstevel@tonic-gate 			{0, &filter, -1},
493*0Sstevel@tonic-gate 			{0, &attributes, -1}}};
494*0Sstevel@tonic-gate 
495*0Sstevel@tonic-gate static asndefT objectName = {"Object Name", PRINTABLE, -1, 0, {0}};
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate static asndefT ldapEntry = {"Entry", PRINTABLE, -1, 0, {0}};
498*0Sstevel@tonic-gate static asndefT relativeLdapEntry = \
499*0Sstevel@tonic-gate 			{"Relative LDAP Entry", PRINTABLE, -1, 0, {0}};
500*0Sstevel@tonic-gate static asndefT newSuperior = {"New Superior", PRINTABLE, -1, 0, {0}};
501*0Sstevel@tonic-gate 
502*0Sstevel@tonic-gate static asndefT vals = {"Vals", SET, -1, 1, {
503*0Sstevel@tonic-gate 			{"Value", 0, -1}}};
504*0Sstevel@tonic-gate 
505*0Sstevel@tonic-gate static asndefT attribute = {"Attribute", SEQUENCE, -1, 2, {
506*0Sstevel@tonic-gate 			{"Type", 0, -1},
507*0Sstevel@tonic-gate 			{0, &vals, -1}}};
508*0Sstevel@tonic-gate 
509*0Sstevel@tonic-gate static asndefT partialAttributes = {"Partial Attributes", SEQUENCEOF, -1, 1, {
510*0Sstevel@tonic-gate 			{0, &attribute, -1}}};
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate static asndefT searchResEntry = {"Operation", SEQUENCE, 4, 2, {
513*0Sstevel@tonic-gate 			{0, &objectName, -1},
514*0Sstevel@tonic-gate 			{0, &partialAttributes, -1}}};
515*0Sstevel@tonic-gate 
516*0Sstevel@tonic-gate static asndefT authChoice = {"Authentication Choice", CHOICE, -1, 2, {
517*0Sstevel@tonic-gate 			{"Authentication: Simple", 0, 0},
518*0Sstevel@tonic-gate 			{"Authentication: SASL", 0, 3}}};
519*0Sstevel@tonic-gate 
520*0Sstevel@tonic-gate static asndefT bindRequest = {"Operation", SEQUENCE, 0, 3, {
521*0Sstevel@tonic-gate 			{"Version", 0, -1},
522*0Sstevel@tonic-gate 			{0, &objectName, -1},
523*0Sstevel@tonic-gate 			{0, &authChoice, -1}}};
524*0Sstevel@tonic-gate 
525*0Sstevel@tonic-gate static asndefT resultCode = {"Result Code", ENUM, -1, 39, {
526*0Sstevel@tonic-gate 			{"Success", 0, 0},
527*0Sstevel@tonic-gate 			{"Operation Error", 0, 1},
528*0Sstevel@tonic-gate 			{"Protocol Error", 0, 2},
529*0Sstevel@tonic-gate 			{"Time Limit Exceeded", 0, 3},
530*0Sstevel@tonic-gate 			{"Size Limit Exceeded", 0, 4},
531*0Sstevel@tonic-gate 			{"Compare False", 0, 5},
532*0Sstevel@tonic-gate 			{"Compare True", 0, 6},
533*0Sstevel@tonic-gate 			{"Auth Method Not supported", 0, 7},
534*0Sstevel@tonic-gate 			{"Strong Auth Required", 0, 8},
535*0Sstevel@tonic-gate 			{"Referral", 0, 10},
536*0Sstevel@tonic-gate 			{"Admin Limit Exceeded", 0, 11},
537*0Sstevel@tonic-gate 			{"Unavailable Critical Extension", 0, 12},
538*0Sstevel@tonic-gate 			{"Confidentiality required", 0, 13},
539*0Sstevel@tonic-gate 			{"SASL Bind In Progress", 0, 14},
540*0Sstevel@tonic-gate 			{"No Such Attribute", 0, 16},
541*0Sstevel@tonic-gate 			{"Undefined Attribute Type", 0, 17},
542*0Sstevel@tonic-gate 			{"Inappropriate Matching", 0, 18},
543*0Sstevel@tonic-gate 			{"Constraint violation", 0, 19},
544*0Sstevel@tonic-gate 			{"Attribute or Value Exists", 0, 20},
545*0Sstevel@tonic-gate 			{"Invalid Attribute Syntax", 0, 21},
546*0Sstevel@tonic-gate 			{"No Such Object", 0, 32},
547*0Sstevel@tonic-gate 			{"Alias Problem", 0, 33},
548*0Sstevel@tonic-gate 			{"Invalid DN Syntax", 0, 34},
549*0Sstevel@tonic-gate 			{"Alias Dereferencing Problem", 0, 36},
550*0Sstevel@tonic-gate 			{"Inappropriate Authentication", 0, 48},
551*0Sstevel@tonic-gate 			{"Invalid Credentials", 0, 49},
552*0Sstevel@tonic-gate 			{"Insufficient Access Rights", 0, 50},
553*0Sstevel@tonic-gate 			{"Busy", 0, 51},
554*0Sstevel@tonic-gate 			{"Unavailable", 0, 52},
555*0Sstevel@tonic-gate 			{"Unwilling To Perform", 0, 53},
556*0Sstevel@tonic-gate 			{"Loop Detect", 0, 54},
557*0Sstevel@tonic-gate 			{"Naming Violation", 0, 64},
558*0Sstevel@tonic-gate 			{"ObjectClass violation", 0, 65},
559*0Sstevel@tonic-gate 			{"Not Allowed On Non Leaf", 0, 66},
560*0Sstevel@tonic-gate 			{"Not Allowed On RDN", 0, 67},
561*0Sstevel@tonic-gate 			{"Entry Already Exists", 0, 68},
562*0Sstevel@tonic-gate 			{"ObjectClass Mods Prohibited", 0, 69},
563*0Sstevel@tonic-gate 			{"Affects Multiple DSAs", 0, 71},
564*0Sstevel@tonic-gate 			{"Other", 0, 80}}};
565*0Sstevel@tonic-gate 
566*0Sstevel@tonic-gate 
567*0Sstevel@tonic-gate static asndefT referral = {"Referral", SEQUENCEOF, -1, 1, {
568*0Sstevel@tonic-gate 			{"LDAP URL", 0, -1}}};
569*0Sstevel@tonic-gate 
570*0Sstevel@tonic-gate static asndefT ldapResult = {"LDAP Result", SEQUENCE, -1, 4, {
571*0Sstevel@tonic-gate 			{0, &resultCode, -1},
572*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
573*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
574*0Sstevel@tonic-gate 			{0, &referral, 3}}};
575*0Sstevel@tonic-gate 
576*0Sstevel@tonic-gate static asndefT bindResponse = {"Operation", SEQUENCE, 1, 5, {
577*0Sstevel@tonic-gate 			{0, &resultCode, -1},
578*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
579*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
580*0Sstevel@tonic-gate 			{0, &referral, 3},
581*0Sstevel@tonic-gate 			{"SASL Credentials", 0, 7}}};
582*0Sstevel@tonic-gate 
583*0Sstevel@tonic-gate static asndefT unbindRequest = {"Operation", SEQUENCE, 2, 0, {0}};
584*0Sstevel@tonic-gate 
585*0Sstevel@tonic-gate static asndefT searchResDone = {"Operation", SEQUENCE, 5, 4, {
586*0Sstevel@tonic-gate 			{0, &resultCode, -1},
587*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
588*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
589*0Sstevel@tonic-gate 			{0, &referral, 3}}};
590*0Sstevel@tonic-gate 
591*0Sstevel@tonic-gate static asndefT seqModOperation = {"Operation", ENUM, -1, 4, {
592*0Sstevel@tonic-gate 			{"Add", 0, 0},
593*0Sstevel@tonic-gate 			{"Delete", 0, 1},
594*0Sstevel@tonic-gate 			{"Replace", 0, 2}}};
595*0Sstevel@tonic-gate 
596*0Sstevel@tonic-gate static asndefT seqModModification = {"Modification", SEQUENCE, -1, 1, {
597*0Sstevel@tonic-gate 			{0, &attribute, -1}}};
598*0Sstevel@tonic-gate 
599*0Sstevel@tonic-gate static asndefT seqModification = {"", SEQUENCE, -1, 2, {
600*0Sstevel@tonic-gate 		    {0, &seqModOperation, -1},
601*0Sstevel@tonic-gate 			{0, &seqModModification, -1}}};
602*0Sstevel@tonic-gate 
603*0Sstevel@tonic-gate static asndefT modification = {"Modification", SEQUENCEOF, -1, 1, {
604*0Sstevel@tonic-gate 			{0, &seqModification, -1}}};
605*0Sstevel@tonic-gate 
606*0Sstevel@tonic-gate static asndefT modifyRequest = {"Operation", SEQUENCE, 6, 2, {
607*0Sstevel@tonic-gate 			{0, &objectName, -1},
608*0Sstevel@tonic-gate 			{0, &modification, -1}}};
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate static asndefT modifyResponse = {"Operation", SEQUENCE, 7, 4, {
611*0Sstevel@tonic-gate 			{0, &resultCode, -1},
612*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
613*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
614*0Sstevel@tonic-gate 			{0, &referral, 3}}};
615*0Sstevel@tonic-gate 
616*0Sstevel@tonic-gate static asndefT addAttributes = {"Attributes", SEQUENCEOF, -1, 1, {
617*0Sstevel@tonic-gate 			{0, &attribute, -1}}};
618*0Sstevel@tonic-gate 
619*0Sstevel@tonic-gate static asndefT addRequest = {"Operation", SEQUENCE, 8, 2, {
620*0Sstevel@tonic-gate 			{0, &ldapEntry, -1},
621*0Sstevel@tonic-gate 			{0, &addAttributes, -1}}};
622*0Sstevel@tonic-gate 
623*0Sstevel@tonic-gate static asndefT addResponse = {"Operation", SEQUENCE, 9, 4, {
624*0Sstevel@tonic-gate 			{0, &resultCode, -1},
625*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
626*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
627*0Sstevel@tonic-gate 			{0, &referral, 3}}};
628*0Sstevel@tonic-gate 
629*0Sstevel@tonic-gate static asndefT delRequest = {"Operation", SEQUENCE, 10, 1, {
630*0Sstevel@tonic-gate 			{0, &ldapEntry, -1}}};
631*0Sstevel@tonic-gate 
632*0Sstevel@tonic-gate static asndefT delResponse = {"Operation", SEQUENCE, 11, 4, {
633*0Sstevel@tonic-gate 			{0, &resultCode, -1},
634*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
635*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
636*0Sstevel@tonic-gate 			{0, &referral, 3}}};
637*0Sstevel@tonic-gate 
638*0Sstevel@tonic-gate static asndefT modifyDNRequest = {"Operation", SEQUENCE, 12, 4, {
639*0Sstevel@tonic-gate 			{0, &ldapEntry, -1},
640*0Sstevel@tonic-gate 			{0, &relativeLdapEntry, -1},
641*0Sstevel@tonic-gate 			{"Delete Old RDN", 0, -1},
642*0Sstevel@tonic-gate 			{0, &newSuperior, 0}}};
643*0Sstevel@tonic-gate 
644*0Sstevel@tonic-gate static asndefT modifyDNResponse = {"Operation", SEQUENCE, 13, 4, {
645*0Sstevel@tonic-gate 			{0, &resultCode, -1},
646*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
647*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
648*0Sstevel@tonic-gate 			{0, &referral, 3}}};
649*0Sstevel@tonic-gate 
650*0Sstevel@tonic-gate static asndefT ava = {"Ava", SEQUENCE, -1, 2, {
651*0Sstevel@tonic-gate 			{"Attr Descr", 0, -1},
652*0Sstevel@tonic-gate 			{"Value", 0, -1}}};
653*0Sstevel@tonic-gate 
654*0Sstevel@tonic-gate static asndefT compareRequest = {"Operation", SEQUENCE, 14, 2, {
655*0Sstevel@tonic-gate 			{0, &ldapEntry, -1},
656*0Sstevel@tonic-gate 			{0, &ava, 0}}};
657*0Sstevel@tonic-gate 
658*0Sstevel@tonic-gate static asndefT compareResponse = {"Operation", SEQUENCE, 15, 4, {
659*0Sstevel@tonic-gate 			{0, &resultCode, -1},
660*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
661*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
662*0Sstevel@tonic-gate 			{0, &referral, 3}}};
663*0Sstevel@tonic-gate 
664*0Sstevel@tonic-gate static asndefT abandonRequest = {"Operation", SEQUENCE, 16, 1, {
665*0Sstevel@tonic-gate 		    {"Message ID", 0, -1}}};
666*0Sstevel@tonic-gate 
667*0Sstevel@tonic-gate static asndefT searchResRef =  {"Operation", SEQUENCEOF, 19, 1, {
668*0Sstevel@tonic-gate 			{"LDAP URL", 0, -1}}};
669*0Sstevel@tonic-gate 
670*0Sstevel@tonic-gate static asndefT extendedRequest = {"Operation", SEQUENCE, 14, 2, {
671*0Sstevel@tonic-gate 			{"Request Name", 0, 0},
672*0Sstevel@tonic-gate 			{"Request Value", 0, 1}}};
673*0Sstevel@tonic-gate 
674*0Sstevel@tonic-gate static asndefT extendedResponse = {"Operation", SEQUENCE, 24, 6, {
675*0Sstevel@tonic-gate 			{0, &resultCode, -1},
676*0Sstevel@tonic-gate 			{"Matched DN", 0, -1},
677*0Sstevel@tonic-gate 			{"Error Message", 0, -1},
678*0Sstevel@tonic-gate 			{0, &referral, 3},
679*0Sstevel@tonic-gate 			{"Response Name", 0, 10},
680*0Sstevel@tonic-gate 			{"Response", 0, 11}}};
681*0Sstevel@tonic-gate 
682*0Sstevel@tonic-gate static asndefT protocolOp = {"Protocol Op", CHOICE, -1, 20, {
683*0Sstevel@tonic-gate 			{0, &bindRequest, 0},
684*0Sstevel@tonic-gate 			{0, &bindResponse, 1},
685*0Sstevel@tonic-gate 			{0, &unbindRequest, 2},
686*0Sstevel@tonic-gate 			{0, &searchRequest, 3},
687*0Sstevel@tonic-gate 			{0, &searchResEntry, 4},
688*0Sstevel@tonic-gate 			{0, &searchResDone, 5},
689*0Sstevel@tonic-gate 			{0, &modifyRequest, 6},
690*0Sstevel@tonic-gate 			{0, &modifyResponse, 7},
691*0Sstevel@tonic-gate 			{0, &addRequest, 8},
692*0Sstevel@tonic-gate 			{0, &addResponse, 9},
693*0Sstevel@tonic-gate 			{0, &delRequest, 10},
694*0Sstevel@tonic-gate 			{0, &delResponse, 11},
695*0Sstevel@tonic-gate 			{0, &modifyDNRequest, 12},
696*0Sstevel@tonic-gate 			{0, &modifyDNResponse, 13},
697*0Sstevel@tonic-gate 			{0, &compareRequest, 14},
698*0Sstevel@tonic-gate 			{0, &compareResponse, 15},
699*0Sstevel@tonic-gate 			{0, &abandonRequest, 16},
700*0Sstevel@tonic-gate 			{0, &searchResRef, 19},
701*0Sstevel@tonic-gate 			{0, &extendedRequest, 23},
702*0Sstevel@tonic-gate 			{0, &extendedResponse, 24}}};
703*0Sstevel@tonic-gate 
704*0Sstevel@tonic-gate static asndefT control = {"Control", SEQUENCE, -1, 3, {
705*0Sstevel@tonic-gate 			{"LDAP OID", 0, -1},
706*0Sstevel@tonic-gate 			{"Criticality", 0, -1},
707*0Sstevel@tonic-gate 			{"Control value", 0, -1}}};
708*0Sstevel@tonic-gate 
709*0Sstevel@tonic-gate static asndefT controls = {"Controls List", SEQUENCEOF, -1, 1, {
710*0Sstevel@tonic-gate 	{0, &control, -1}}};
711*0Sstevel@tonic-gate 
712*0Sstevel@tonic-gate static asndefT LDAPMessage = { "LDAPMessage", SEQUENCE, -1, 3, {
713*0Sstevel@tonic-gate 			{"Message ID", 0, -1},
714*0Sstevel@tonic-gate 			{0, &protocolOp, -1},
715*0Sstevel@tonic-gate 			{0, &controls, 0}}};
716*0Sstevel@tonic-gate 
717*0Sstevel@tonic-gate static asndefT MPDU = { "MPDU", SET,  -1, 1,
718*0Sstevel@tonic-gate 			{{0, &LDAPMessage, 0}}};
719*0Sstevel@tonic-gate 
720*0Sstevel@tonic-gate static int mytype[] = {
721*0Sstevel@tonic-gate 0,			/* EndOfContents	*/
722*0Sstevel@tonic-gate 0,			/* Boolean			*/
723*0Sstevel@tonic-gate 0,			/* Integer			*/
724*0Sstevel@tonic-gate BITSTRING,	/* BitString		*/
725*0Sstevel@tonic-gate 0,			/* OctetString		*/
726*0Sstevel@tonic-gate 0,			/* Null				*/
727*0Sstevel@tonic-gate 0,			/* Oid				*/
728*0Sstevel@tonic-gate 0,			/* ObjDescriptor	*/
729*0Sstevel@tonic-gate 0,			/* External			*/
730*0Sstevel@tonic-gate 0,			/* Real				*/
731*0Sstevel@tonic-gate ENUM,		/* Enumerated		*/
732*0Sstevel@tonic-gate 0,			/* Reserved			*/
733*0Sstevel@tonic-gate 0,			/* Reserved			*/
734*0Sstevel@tonic-gate 0,			/* Reserved			*/
735*0Sstevel@tonic-gate 0,			/* Reserved			*/
736*0Sstevel@tonic-gate 0,			/* Reserved			*/
737*0Sstevel@tonic-gate SEQUENCE,	/* Sequence			*/
738*0Sstevel@tonic-gate SET,		/* Set				*/
739*0Sstevel@tonic-gate 0,			/* NumericString	*/
740*0Sstevel@tonic-gate 0,			/* PrintableString	*/
741*0Sstevel@tonic-gate 0,			/* T.61String		*/
742*0Sstevel@tonic-gate 0,			/* VideotexString	*/
743*0Sstevel@tonic-gate 0,			/* IA5String		*/
744*0Sstevel@tonic-gate 0,			/* UTCTime			*/
745*0Sstevel@tonic-gate 0,			/* GeneralizedTime	*/
746*0Sstevel@tonic-gate 0,			/* GraphicString	*/
747*0Sstevel@tonic-gate 0,			/* VisibleString	*/
748*0Sstevel@tonic-gate 0,			/* GeneralString	*/
749*0Sstevel@tonic-gate 0,			/* Reserved			*/
750*0Sstevel@tonic-gate 0,			/* Reserved			*/
751*0Sstevel@tonic-gate 0,			/* Reserved			*/
752*0Sstevel@tonic-gate 0,			/* Reserved			*/
753*0Sstevel@tonic-gate };
754*0Sstevel@tonic-gate 
755*0Sstevel@tonic-gate /*
756*0Sstevel@tonic-gate **----------------------------------------------**
757*0Sstevel@tonic-gate **	find object identifier in known oid table	**
758*0Sstevel@tonic-gate **----------------------------------------------**
759*0Sstevel@tonic-gate */
760*0Sstevel@tonic-gate static oidmap(oid, olg)
761*0Sstevel@tonic-gate A	oid;	/* oid hexa string */
762*0Sstevel@tonic-gate int	olg;	/* oid length */
763*0Sstevel@tonic-gate {
764*0Sstevel@tonic-gate 	register int ix, goon;
765*0Sstevel@tonic-gate 	register A oidptr, tabptr, tabend;
766*0Sstevel@tonic-gate 
767*0Sstevel@tonic-gate /* returns (oid table size) if not found */
768*0Sstevel@tonic-gate 
769*0Sstevel@tonic-gate 	for (ix = 0; ix < OIDNB; ix++) {
770*0Sstevel@tonic-gate 		oidptr = oid; tabptr = (&(OidTab[ix].oidcode[0]));
771*0Sstevel@tonic-gate 		if (olg == INT(*tabptr++)) {
772*0Sstevel@tonic-gate 			for (tabend = tabptr + olg, goon = 1;
773*0Sstevel@tonic-gate 				(goon) && (tabptr < tabend); ) {
774*0Sstevel@tonic-gate 				if (*tabptr++ != *oidptr++) goon = 0;
775*0Sstevel@tonic-gate 			}
776*0Sstevel@tonic-gate 			if (goon)
777*0Sstevel@tonic-gate 				return (ix);
778*0Sstevel@tonic-gate 		}
779*0Sstevel@tonic-gate 	}
780*0Sstevel@tonic-gate 	return (OIDNB);
781*0Sstevel@tonic-gate }
782*0Sstevel@tonic-gate 
783*0Sstevel@tonic-gate /*
784*0Sstevel@tonic-gate **------------------------------------------------------**
785*0Sstevel@tonic-gate **read an hexacode and convert it into ascii		**
786*0Sstevel@tonic-gate **------------------------------------------------------**
787*0Sstevel@tonic-gate */
788*0Sstevel@tonic-gate 
789*0Sstevel@tonic-gate static int getnext(int ctxnum)
790*0Sstevel@tonic-gate {
791*0Sstevel@tonic-gate 	static X c[3]; /* c[0-3] will contain ascii values on exit */
792*0Sstevel@tonic-gate 	hex = 0;
793*0Sstevel@tonic-gate 	if (gi_osibuf[ctxnum] == osilen)
794*0Sstevel@tonic-gate 		return (-1);
795*0Sstevel@tonic-gate 	hex = osibuff[gi_osibuf[ctxnum]++];
796*0Sstevel@tonic-gate 	(void) sprintf((char *)c, "%02x", (hex&0x00FF));
797*0Sstevel@tonic-gate 	return (0);
798*0Sstevel@tonic-gate }
799*0Sstevel@tonic-gate 
800*0Sstevel@tonic-gate /*
801*0Sstevel@tonic-gate **------------------------------------------------------**
802*0Sstevel@tonic-gate ** Skip everything that is not an LDAPMessage		**
803*0Sstevel@tonic-gate **------------------------------------------------------**
804*0Sstevel@tonic-gate */
805*0Sstevel@tonic-gate static char *skipjunk(len, pdu)
806*0Sstevel@tonic-gate int len;
807*0Sstevel@tonic-gate char *pdu;
808*0Sstevel@tonic-gate {
809*0Sstevel@tonic-gate 	int tag;
810*0Sstevel@tonic-gate 	char *buf = pdu;
811*0Sstevel@tonic-gate 	int offset = 0;
812*0Sstevel@tonic-gate 	while (len > 0) {
813*0Sstevel@tonic-gate 		/* size minumum for a sequence + integer = 5 */
814*0Sstevel@tonic-gate 		/* LDAPMessage::= SEQUENCE  */
815*0Sstevel@tonic-gate 		if ((len > 5) && (buf[0] == 0x30)) {
816*0Sstevel@tonic-gate 			tag = buf[1]&0x00ff;
817*0Sstevel@tonic-gate 			if (tag < 0x80) {
818*0Sstevel@tonic-gate 				/* length is one one octet */
819*0Sstevel@tonic-gate 				offset = 1;
820*0Sstevel@tonic-gate 			} else {
821*0Sstevel@tonic-gate 				/* length is multiple octet.  */
822*0Sstevel@tonic-gate 				offset = 1+ tag&0x007f;
823*0Sstevel@tonic-gate 			}
824*0Sstevel@tonic-gate 			/* Make sure we don't read past the end */
825*0Sstevel@tonic-gate 			/* of the buffer */
826*0Sstevel@tonic-gate 			if (len - (1+offset) > 0) {
827*0Sstevel@tonic-gate 				/* skip after the length */
828*0Sstevel@tonic-gate 				tag = buf[1+offset]&0x00ff;
829*0Sstevel@tonic-gate 				if (tag == 0x02) { /* INTEGER */
830*0Sstevel@tonic-gate 					/* looks like a valid PDU */
831*0Sstevel@tonic-gate 					return (buf);
832*0Sstevel@tonic-gate 				}
833*0Sstevel@tonic-gate 			}
834*0Sstevel@tonic-gate 		}
835*0Sstevel@tonic-gate 		len --;
836*0Sstevel@tonic-gate 		buf++;
837*0Sstevel@tonic-gate 	}
838*0Sstevel@tonic-gate 	return (buf);
839*0Sstevel@tonic-gate }
840*0Sstevel@tonic-gate /*
841*0Sstevel@tonic-gate **----------------------------------------------------------**
842*0Sstevel@tonic-gate **	main routine: decode a TLV; to be called recursively	**
843*0Sstevel@tonic-gate **----------------------------------------------------------**
844*0Sstevel@tonic-gate */
845*0Sstevel@tonic-gate #define	GETNEXT(a) (void)getnext(a);
846*0Sstevel@tonic-gate static int decpdu(pdulen, ASNDESC, ctxnum)
847*0Sstevel@tonic-gate int	pdulen;	/* current pdu's length */
848*0Sstevel@tonic-gate asndefTp ASNDESC;
849*0Sstevel@tonic-gate int ctxnum;
850*0Sstevel@tonic-gate {
851*0Sstevel@tonic-gate 	X		scrlin[99];	/* screen line */
852*0Sstevel@tonic-gate 	X		oidstr[80];	/* oid hexa string */
853*0Sstevel@tonic-gate 	int		slen;	/* screen line length */
854*0Sstevel@tonic-gate 	int		stlv;	/* sub-tlv length */
855*0Sstevel@tonic-gate 	int		oix;	/* oid table index */
856*0Sstevel@tonic-gate 	int		effnb;	/* effectively traced octet nb */
857*0Sstevel@tonic-gate 	int		i, j;
858*0Sstevel@tonic-gate 	int		ai = -2;
859*0Sstevel@tonic-gate 	asndefTp SASNDESC = 0;
860*0Sstevel@tonic-gate 	asndefTp TMPDESC = 0;
861*0Sstevel@tonic-gate 	asndefTp GR_TMPDESC = 0;
862*0Sstevel@tonic-gate 	int tmpai = 0;
863*0Sstevel@tonic-gate 	int gr_tmpai = 0;
864*0Sstevel@tonic-gate 	int dontprint = 0;
865*0Sstevel@tonic-gate 	int already = 0;
866*0Sstevel@tonic-gate 	static int rlen = 0;	/* tlv's real length */
867*0Sstevel@tonic-gate 
868*0Sstevel@tonic-gate 	++level[ctxnum];	/* level indicator */
869*0Sstevel@tonic-gate 	effnb = 0;
870*0Sstevel@tonic-gate 
871*0Sstevel@tonic-gate 	/*
872*0Sstevel@tonic-gate 	** Decode the current TLV segment
873*0Sstevel@tonic-gate 	*/
874*0Sstevel@tonic-gate 	while (pdulen > 1) {
875*0Sstevel@tonic-gate 
876*0Sstevel@tonic-gate 		if (getnext(ctxnum)) {
877*0Sstevel@tonic-gate 			break;
878*0Sstevel@tonic-gate 		}
879*0Sstevel@tonic-gate 		if (strlen(scrbuffer)) asnshw2("%s  ", "LDAP:");
880*0Sstevel@tonic-gate 		/* screen printing according to level indicator */
881*0Sstevel@tonic-gate 		for (i = 1; i < level[ctxnum]; ++i) asnshw1("   ");
882*0Sstevel@tonic-gate 
883*0Sstevel@tonic-gate 		/* get tag */
884*0Sstevel@tonic-gate 		otyp[ctxnum] = INT(hex); /* single octet type only */
885*0Sstevel@tonic-gate 		--pdulen;
886*0Sstevel@tonic-gate 		++effnb;
887*0Sstevel@tonic-gate 
888*0Sstevel@tonic-gate 		/* get length */
889*0Sstevel@tonic-gate 		GETNEXT(ctxnum);
890*0Sstevel@tonic-gate 		olen[ctxnum] = INT(hex);	/* tlv length */
891*0Sstevel@tonic-gate 		--pdulen;
892*0Sstevel@tonic-gate 		++effnb;
893*0Sstevel@tonic-gate 
894*0Sstevel@tonic-gate 		/* Continuing decoding of current TLV... */
895*0Sstevel@tonic-gate 		/*
896*0Sstevel@tonic-gate 		** Snoop's lower layers do not allow us
897*0Sstevel@tonic-gate 		** to know the true length for
898*0Sstevel@tonic-gate 		** datastream protocols like LDAP.
899*0Sstevel@tonic-gate 		*/
900*0Sstevel@tonic-gate 
901*0Sstevel@tonic-gate 		/* if length is less than 128, we */
902*0Sstevel@tonic-gate 		/* already have the real TLV length. */
903*0Sstevel@tonic-gate 		if (olen[ctxnum] < 128) {	/* short length form */
904*0Sstevel@tonic-gate 			rlen = olen[ctxnum];
905*0Sstevel@tonic-gate 		} else {		/* long and any form length */
906*0Sstevel@tonic-gate 		/* else we do more getnext()'s */
907*0Sstevel@tonic-gate 			for (rlen = 0, olen[ctxnum] &= 0x0F;
908*0Sstevel@tonic-gate 			(olen[ctxnum]) && (pdulen > 0);
909*0Sstevel@tonic-gate 			--olen[ctxnum], --pdulen, ++effnb) {
910*0Sstevel@tonic-gate 				GETNEXT(ctxnum);
911*0Sstevel@tonic-gate 				rlen = (rlen << 8) | INT(hex);
912*0Sstevel@tonic-gate 			}
913*0Sstevel@tonic-gate 			if (!rlen) {
914*0Sstevel@tonic-gate 				pdulen = 0x7fffffff;
915*0Sstevel@tonic-gate 			}
916*0Sstevel@tonic-gate 		}
917*0Sstevel@tonic-gate 
918*0Sstevel@tonic-gate 		/*
919*0Sstevel@tonic-gate 		** print the tag class and number
920*0Sstevel@tonic-gate 		*/
921*0Sstevel@tonic-gate 		i = otyp[ctxnum]&0x1F;
922*0Sstevel@tonic-gate 		switch (otyp[ctxnum] >> 6) {	/* class */
923*0Sstevel@tonic-gate 		case 0:	/* universal */
924*0Sstevel@tonic-gate 			if (ASNDESC && i != 0) {
925*0Sstevel@tonic-gate 				int dobreak = 0;
926*0Sstevel@tonic-gate 				switch (ASNDESC->type) {
927*0Sstevel@tonic-gate 				case CONTENT:
928*0Sstevel@tonic-gate 					SASNDESC = ASNDESC;
929*0Sstevel@tonic-gate 					break;
930*0Sstevel@tonic-gate 				case SET:
931*0Sstevel@tonic-gate 					for (ai = 0;
932*0Sstevel@tonic-gate 						ai < ASNDESC->nbson && i < 32 &&
933*0Sstevel@tonic-gate 						ASNDESC->son[ai].sondef &&
934*0Sstevel@tonic-gate 					/*
935*0Sstevel@tonic-gate 					** For this test SEQUENCE & SEQUENCE OF
936*0Sstevel@tonic-gate 					** are same, so suppress the last bit
937*0Sstevel@tonic-gate 					*/
938*0Sstevel@tonic-gate 						(ASNDESC->son[ai].sondef
939*0Sstevel@tonic-gate 							->type&0xFE)
940*0Sstevel@tonic-gate 						!= mytype[i]; ++ai);
941*0Sstevel@tonic-gate 					if (ai < ASNDESC->nbson) {
942*0Sstevel@tonic-gate 						SASNDESC =
943*0Sstevel@tonic-gate 							ASNDESC->son[ai].sondef;
944*0Sstevel@tonic-gate 						if (ASNDESC->son[ai].sonname) {
945*0Sstevel@tonic-gate 							if (ASNDESC-> \
946*0Sstevel@tonic-gate 				son[ai].sondef && ASNDESC->son[ai].sondef->name)
947*0Sstevel@tonic-gate 							{
948*0Sstevel@tonic-gate 							asnshw2 \
949*0Sstevel@tonic-gate 				("%s	", "LDAP:");
950*0Sstevel@tonic-gate 								asnshw4 \
951*0Sstevel@tonic-gate 				(" %c[%s %s]",
952*0Sstevel@tonic-gate 				((otyp[ctxnum]&0x20)?'*':' '), \
953*0Sstevel@tonic-gate 				ASNDESC->son[ai].sonname, \
954*0Sstevel@tonic-gate 				ASNDESC->son[ai].sondef->name);
955*0Sstevel@tonic-gate 							} else {
956*0Sstevel@tonic-gate 								asnshw2 \
957*0Sstevel@tonic-gate 							("%s	", "");
958*0Sstevel@tonic-gate 								asnshw3 \
959*0Sstevel@tonic-gate 							(" %c[%s]", \
960*0Sstevel@tonic-gate 				((otyp[ctxnum]&0x20)?'*':' '),
961*0Sstevel@tonic-gate 				ASNDESC->son[ai].sonname);
962*0Sstevel@tonic-gate 							} /* end if */
963*0Sstevel@tonic-gate 							dobreak = 1;
964*0Sstevel@tonic-gate 						} else if
965*0Sstevel@tonic-gate 				(ASNDESC->son[ai].sondef &&
966*0Sstevel@tonic-gate 				ASNDESC->son[ai].sondef->name) {
967*0Sstevel@tonic-gate 							asnshw2 \
968*0Sstevel@tonic-gate 					("%s	", "LDAP:");
969*0Sstevel@tonic-gate 							asnshw3 \
970*0Sstevel@tonic-gate 				(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
971*0Sstevel@tonic-gate 				ASNDESC->son[ai].sondef->name);
972*0Sstevel@tonic-gate 							dobreak = 1;
973*0Sstevel@tonic-gate 						} /* end if */
974*0Sstevel@tonic-gate 					} /* end if */
975*0Sstevel@tonic-gate 						break;
976*0Sstevel@tonic-gate 				case CHOICE:
977*0Sstevel@tonic-gate 					if (GR_TMPDESC) {
978*0Sstevel@tonic-gate 						ASNDESC = TMPDESC;
979*0Sstevel@tonic-gate 						TMPDESC = GR_TMPDESC;
980*0Sstevel@tonic-gate 						GR_TMPDESC = 0;
981*0Sstevel@tonic-gate 					} else if (TMPDESC) {
982*0Sstevel@tonic-gate 						ASNDESC = TMPDESC;
983*0Sstevel@tonic-gate 						TMPDESC = 0;
984*0Sstevel@tonic-gate 					}
985*0Sstevel@tonic-gate 					if (gr_tmpai) {
986*0Sstevel@tonic-gate 						ai = tmpai;
987*0Sstevel@tonic-gate 						tmpai = gr_tmpai;
988*0Sstevel@tonic-gate 						gr_tmpai = 0;
989*0Sstevel@tonic-gate 					} else if (tmpai) {
990*0Sstevel@tonic-gate 						ai = tmpai;
991*0Sstevel@tonic-gate 						tmpai = 0;
992*0Sstevel@tonic-gate 					}
993*0Sstevel@tonic-gate 					break;
994*0Sstevel@tonic-gate 
995*0Sstevel@tonic-gate 				case SEQUENCE:
996*0Sstevel@tonic-gate 					if (ai == -2) {
997*0Sstevel@tonic-gate 						ai = 0;
998*0Sstevel@tonic-gate 					} else {
999*0Sstevel@tonic-gate 						do {
1000*0Sstevel@tonic-gate 							ai++;
1001*0Sstevel@tonic-gate 						} while \
1002*0Sstevel@tonic-gate 			(ai < ASNDESC->nbson && i < 32 && mytype[i] && \
1003*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef &&
1004*0Sstevel@tonic-gate 					/*
1005*0Sstevel@tonic-gate 					** For this test SEQUENCE & SEQUENCE OF
1006*0Sstevel@tonic-gate 					** are the same, so suppress last bit
1007*0Sstevel@tonic-gate 					*/
1008*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef->type&0xFE) != mytype[i]);
1009*0Sstevel@tonic-gate 					} /* end if */
1010*0Sstevel@tonic-gate 					if (ai < ASNDESC->nbson) {
1011*0Sstevel@tonic-gate 						SASNDESC = \
1012*0Sstevel@tonic-gate 						ASNDESC->son[ai].sondef;
1013*0Sstevel@tonic-gate 						if (ASNDESC->son[ai].sonname) {
1014*0Sstevel@tonic-gate 							if \
1015*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef &&
1016*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name) {
1017*0Sstevel@tonic-gate 								asnshw4 \
1018*0Sstevel@tonic-gate 			(" %c[%s %s]", ((otyp[ctxnum]&0x20)?'*':' '),
1019*0Sstevel@tonic-gate 			ASNDESC->son[ai].sonname,
1020*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name);
1021*0Sstevel@tonic-gate 							} else {
1022*0Sstevel@tonic-gate 								asnshw3 \
1023*0Sstevel@tonic-gate 			(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
1024*0Sstevel@tonic-gate 			ASNDESC->son[ai].sonname);
1025*0Sstevel@tonic-gate 							} /* end if */
1026*0Sstevel@tonic-gate 							dobreak = 1;
1027*0Sstevel@tonic-gate 						} else if \
1028*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef &&
1029*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name) {
1030*0Sstevel@tonic-gate 								asnshw3 \
1031*0Sstevel@tonic-gate 			(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
1032*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name);
1033*0Sstevel@tonic-gate 							dobreak = 1;
1034*0Sstevel@tonic-gate 						} /* end if */
1035*0Sstevel@tonic-gate 					} /* end if */
1036*0Sstevel@tonic-gate 					break;
1037*0Sstevel@tonic-gate 				case SEQUENCEOF:
1038*0Sstevel@tonic-gate 					ai = 0;
1039*0Sstevel@tonic-gate 					SASNDESC = ASNDESC->son[ai].sondef;
1040*0Sstevel@tonic-gate 					if (ASNDESC->son[ai].sonname) {
1041*0Sstevel@tonic-gate 						if (ASNDESC->son[ai].sondef && \
1042*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name) {
1043*0Sstevel@tonic-gate 								asnshw4 \
1044*0Sstevel@tonic-gate 			(" %c[%s %s]", ((otyp[ctxnum]&0x20)?'*':' '),
1045*0Sstevel@tonic-gate 			ASNDESC->son[ai].sonname,
1046*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name);
1047*0Sstevel@tonic-gate 						} else {
1048*0Sstevel@tonic-gate 							asnshw3 \
1049*0Sstevel@tonic-gate 			(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
1050*0Sstevel@tonic-gate 			ASNDESC->son[ai].sonname);
1051*0Sstevel@tonic-gate 						} /* end if */
1052*0Sstevel@tonic-gate 						dobreak = 1;
1053*0Sstevel@tonic-gate 					} else if \
1054*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef &&
1055*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name) {
1056*0Sstevel@tonic-gate 							asnshw3 \
1057*0Sstevel@tonic-gate 			(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '),
1058*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name);
1059*0Sstevel@tonic-gate 						dobreak = 1;
1060*0Sstevel@tonic-gate 					} /* end if */
1061*0Sstevel@tonic-gate 				} /* end switch */
1062*0Sstevel@tonic-gate 				if (dobreak) {
1063*0Sstevel@tonic-gate 					break;
1064*0Sstevel@tonic-gate 				} /* end if */
1065*0Sstevel@tonic-gate 			} /* end if */
1066*0Sstevel@tonic-gate 			if (uclass[i]) {
1067*0Sstevel@tonic-gate 				asnshw3 \
1068*0Sstevel@tonic-gate 			(" %c[%s]", ((otyp[ctxnum]&0x20)?'*':' '), uclass[i]);
1069*0Sstevel@tonic-gate 			} else {
1070*0Sstevel@tonic-gate 				asnshw4 \
1071*0Sstevel@tonic-gate 			(" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '),
1072*0Sstevel@tonic-gate 			class[0], i);
1073*0Sstevel@tonic-gate 			}
1074*0Sstevel@tonic-gate 			break;
1075*0Sstevel@tonic-gate 		case 1:		/* application */
1076*0Sstevel@tonic-gate 
1077*0Sstevel@tonic-gate 		if (ASNDESC) {
1078*0Sstevel@tonic-gate 
1079*0Sstevel@tonic-gate 				for (ai = 0; ai < ASNDESC->nbson; ++ai) {
1080*0Sstevel@tonic-gate 					int i2 = 0;
1081*0Sstevel@tonic-gate 
1082*0Sstevel@tonic-gate 					if \
1083*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef &&
1084*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->type == CHOICE) {
1085*0Sstevel@tonic-gate 						while \
1086*0Sstevel@tonic-gate 			(i2 < ASNDESC->son[ai].sondef->nbson &&
1087*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->son[i2].sondef && \
1088*0Sstevel@tonic-gate 	ASNDESC->son[ai].sondef->son[i2].sondef->application != i) {
1089*0Sstevel@tonic-gate 							i2++;
1090*0Sstevel@tonic-gate 							continue;
1091*0Sstevel@tonic-gate 						}
1092*0Sstevel@tonic-gate 						if \
1093*0Sstevel@tonic-gate 			(i2 == ASNDESC->son[ai].sondef->nbson) {
1094*0Sstevel@tonic-gate 							ai = ASNDESC->nbson;
1095*0Sstevel@tonic-gate 							break;
1096*0Sstevel@tonic-gate 						}
1097*0Sstevel@tonic-gate 			if (TMPDESC) {
1098*0Sstevel@tonic-gate 				GR_TMPDESC = TMPDESC;
1099*0Sstevel@tonic-gate 				gr_tmpai = tmpai;
1100*0Sstevel@tonic-gate 			}
1101*0Sstevel@tonic-gate 					TMPDESC = ASNDESC;
1102*0Sstevel@tonic-gate 					ASNDESC = ASNDESC->son[ai].sondef;
1103*0Sstevel@tonic-gate 					tmpai = ai;
1104*0Sstevel@tonic-gate 					ai = i2;
1105*0Sstevel@tonic-gate 					}
1106*0Sstevel@tonic-gate 
1107*0Sstevel@tonic-gate 					if (ASNDESC->son[ai].sondef && \
1108*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->application == i) {
1109*0Sstevel@tonic-gate 						SASNDESC = \
1110*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef;
1111*0Sstevel@tonic-gate 						if (ASNDESC->son[ai].sonname) {
1112*0Sstevel@tonic-gate 							if \
1113*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef->name) {
1114*0Sstevel@tonic-gate 								asnshw3 \
1115*0Sstevel@tonic-gate 			(" %s %s", ASNDESC->son[ai].sonname,
1116*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name);
1117*0Sstevel@tonic-gate 							} else {
1118*0Sstevel@tonic-gate 								asnshw2 \
1119*0Sstevel@tonic-gate 			(" %s", ASNDESC->son[ai].sonname);
1120*0Sstevel@tonic-gate 							} /* end if */
1121*0Sstevel@tonic-gate 						} else if \
1122*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef->name) {
1123*0Sstevel@tonic-gate 							asnshw2 \
1124*0Sstevel@tonic-gate 			(" %s", ASNDESC->son[ai].sondef->name);
1125*0Sstevel@tonic-gate 						} /* end if */
1126*0Sstevel@tonic-gate 						break;
1127*0Sstevel@tonic-gate 					} /* end if */
1128*0Sstevel@tonic-gate 				} /* end for */
1129*0Sstevel@tonic-gate 				if (ai >= ASNDESC->nbson) {
1130*0Sstevel@tonic-gate 					ai = -1;	/* not found */
1131*0Sstevel@tonic-gate 				} /* end if */
1132*0Sstevel@tonic-gate 			} /* end if */
1133*0Sstevel@tonic-gate 			if (PTRaclass[i]) {
1134*0Sstevel@tonic-gate 				asnshw5 \
1135*0Sstevel@tonic-gate 			(" %c[%s%d: %s]", ((otyp[ctxnum]&0x20)?'*':' '),
1136*0Sstevel@tonic-gate 			class[1], i, PTRaclass[i]);
1137*0Sstevel@tonic-gate 				(void) strcpy(operation, (char *)PTRaclass[i]);
1138*0Sstevel@tonic-gate 			} else {
1139*0Sstevel@tonic-gate 				asnshw4 \
1140*0Sstevel@tonic-gate 			(" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '), \
1141*0Sstevel@tonic-gate 			class[1], i);
1142*0Sstevel@tonic-gate 			}
1143*0Sstevel@tonic-gate 			break;
1144*0Sstevel@tonic-gate 
1145*0Sstevel@tonic-gate 		case 2:		/* context-specific */
1146*0Sstevel@tonic-gate 
1147*0Sstevel@tonic-gate 			if (TMPDESC) {
1148*0Sstevel@tonic-gate 				ASNDESC = TMPDESC;
1149*0Sstevel@tonic-gate 				TMPDESC = GR_TMPDESC;
1150*0Sstevel@tonic-gate 				already = 1;
1151*0Sstevel@tonic-gate 			}
1152*0Sstevel@tonic-gate 			if (ASNDESC) {
1153*0Sstevel@tonic-gate 
1154*0Sstevel@tonic-gate 				for (ai = 0; ai < ASNDESC->nbson; ++ai) {
1155*0Sstevel@tonic-gate 					if \
1156*0Sstevel@tonic-gate 			(!already && ASNDESC->son[ai].sondef &&
1157*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->type == CHOICE) {
1158*0Sstevel@tonic-gate 						int i2 = 0;
1159*0Sstevel@tonic-gate 						while \
1160*0Sstevel@tonic-gate 			(i2 < ASNDESC->son[ai].sondef->nbson &&
1161*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->son[i2].tag != i) {
1162*0Sstevel@tonic-gate 							i2++;
1163*0Sstevel@tonic-gate 							continue;
1164*0Sstevel@tonic-gate 						}
1165*0Sstevel@tonic-gate 						if (i2 == \
1166*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->nbson) {
1167*0Sstevel@tonic-gate 							ai = ASNDESC->nbson;
1168*0Sstevel@tonic-gate 							break;
1169*0Sstevel@tonic-gate 						}
1170*0Sstevel@tonic-gate 						if (TMPDESC) {
1171*0Sstevel@tonic-gate 							GR_TMPDESC = TMPDESC;
1172*0Sstevel@tonic-gate 							gr_tmpai = tmpai;
1173*0Sstevel@tonic-gate 						}
1174*0Sstevel@tonic-gate 						TMPDESC = ASNDESC;
1175*0Sstevel@tonic-gate 						ASNDESC = \
1176*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef;
1177*0Sstevel@tonic-gate 						tmpai = ai;
1178*0Sstevel@tonic-gate 						ai = i2;
1179*0Sstevel@tonic-gate 					}
1180*0Sstevel@tonic-gate 
1181*0Sstevel@tonic-gate 					if \
1182*0Sstevel@tonic-gate 			(ASNDESC->son[ai].tag == i) {
1183*0Sstevel@tonic-gate 						SASNDESC = \
1184*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef;
1185*0Sstevel@tonic-gate 						if (ASNDESC->son[ai].sonname) {
1186*0Sstevel@tonic-gate 							if \
1187*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef &&
1188*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name) {
1189*0Sstevel@tonic-gate 								asnshw3 \
1190*0Sstevel@tonic-gate 			(" %s %s", ASNDESC->son[ai].sonname,
1191*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name);
1192*0Sstevel@tonic-gate 							} else {
1193*0Sstevel@tonic-gate 								asnshw2 \
1194*0Sstevel@tonic-gate 			(" %s", ASNDESC->son[ai].sonname);
1195*0Sstevel@tonic-gate 							} /* end if */
1196*0Sstevel@tonic-gate 						} else if \
1197*0Sstevel@tonic-gate 			(ASNDESC->son[ai].sondef &&
1198*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef->name) {
1199*0Sstevel@tonic-gate 							asnshw2 \
1200*0Sstevel@tonic-gate 			(" %s", ASNDESC->son[ai].sondef->name);
1201*0Sstevel@tonic-gate 						} /* end if */
1202*0Sstevel@tonic-gate 						break;
1203*0Sstevel@tonic-gate 					} /* end if */
1204*0Sstevel@tonic-gate 				} /* end for */
1205*0Sstevel@tonic-gate 				if (ai >= ASNDESC->nbson) {
1206*0Sstevel@tonic-gate 					ai = -1;	/* not found */
1207*0Sstevel@tonic-gate 				} /* end if */
1208*0Sstevel@tonic-gate 			} /* end if */
1209*0Sstevel@tonic-gate 			asnshw3 \
1210*0Sstevel@tonic-gate 			(" %c[%d]", ((otyp[ctxnum]&0x20)?'*':' '), i);
1211*0Sstevel@tonic-gate 			break;
1212*0Sstevel@tonic-gate 
1213*0Sstevel@tonic-gate 		case 3:		/* private */
1214*0Sstevel@tonic-gate 			asnshw4 \
1215*0Sstevel@tonic-gate 			(" %c[%s%d]", ((otyp[ctxnum]&0x20)?'*':' '), \
1216*0Sstevel@tonic-gate 			class[3], i);
1217*0Sstevel@tonic-gate 		} /* esac: tag */
1218*0Sstevel@tonic-gate 
1219*0Sstevel@tonic-gate 		/*
1220*0Sstevel@tonic-gate 		** print the length - as a debug tool only.
1221*0Sstevel@tonic-gate 		*/
1222*0Sstevel@tonic-gate 		/* asnshw2(" Length=%d ",rlen); */
1223*0Sstevel@tonic-gate 		asnshw1("\n");
1224*0Sstevel@tonic-gate 		if (rlen > pdulen) {
1225*0Sstevel@tonic-gate 			asnshw1("*** Decode length error,");
1226*0Sstevel@tonic-gate 			asnshw2(" PDU length = %d ***\n", pdulen);
1227*0Sstevel@tonic-gate 			rlen = pdulen;
1228*0Sstevel@tonic-gate 		}
1229*0Sstevel@tonic-gate 
1230*0Sstevel@tonic-gate 		/*
1231*0Sstevel@tonic-gate 		** recursive interpretation of the value if constructor
1232*0Sstevel@tonic-gate 		*/
1233*0Sstevel@tonic-gate 		if (otyp[ctxnum]&0x20) {		/* constructor */
1234*0Sstevel@tonic-gate 
1235*0Sstevel@tonic-gate 			stlv = decpdu((rlen?rlen:pdulen), \
1236*0Sstevel@tonic-gate 			ASNDESC && ai != -1 ?(ai == -2 ? ASNDESC:
1237*0Sstevel@tonic-gate 			ASNDESC->son[ai].sondef):0, ctxnum);
1238*0Sstevel@tonic-gate 			/* recursive decoding */
1239*0Sstevel@tonic-gate 			pdulen -= stlv;
1240*0Sstevel@tonic-gate 			effnb += stlv;
1241*0Sstevel@tonic-gate 		} else if (otyp[ctxnum] == 0x06) {
1242*0Sstevel@tonic-gate 			/*
1243*0Sstevel@tonic-gate 			** interpretation of the object identifier
1244*0Sstevel@tonic-gate 			*/
1245*0Sstevel@tonic-gate 			for (j = 0; (rlen) && (pdulen > 0); \
1246*0Sstevel@tonic-gate 			--rlen, --pdulen, ++effnb) {
1247*0Sstevel@tonic-gate 				GETNEXT(ctxnum);
1248*0Sstevel@tonic-gate 				oidstr[j++] = hex;
1249*0Sstevel@tonic-gate 			}
1250*0Sstevel@tonic-gate 
1251*0Sstevel@tonic-gate 			/* interpret the object identifier */
1252*0Sstevel@tonic-gate 			oidstr[j++] = '\0';
1253*0Sstevel@tonic-gate 			oix = oidmap(oidstr, j-1);
1254*0Sstevel@tonic-gate 			asnshw1("\n");
1255*0Sstevel@tonic-gate 			if (oix >= 0 && oix < OIDNB) {	/* recognized obj id */
1256*0Sstevel@tonic-gate 				asnshw2("%s\n", OidTab[oix].oidname);
1257*0Sstevel@tonic-gate 			} else {
1258*0Sstevel@tonic-gate 				asnshw1("Unknown Oid\n");
1259*0Sstevel@tonic-gate 			}
1260*0Sstevel@tonic-gate 		} else {
1261*0Sstevel@tonic-gate 			/*
1262*0Sstevel@tonic-gate 			** interpretation of other primitive tags
1263*0Sstevel@tonic-gate 			*/
1264*0Sstevel@tonic-gate 			if (!otyp[ctxnum] && !rlen) {
1265*0Sstevel@tonic-gate 			/* end of contents: any form length */
1266*0Sstevel@tonic-gate 				pdulen = 0;
1267*0Sstevel@tonic-gate 			} else {
1268*0Sstevel@tonic-gate 				X   hexstr[5];
1269*0Sstevel@tonic-gate 				int k = 0;
1270*0Sstevel@tonic-gate 				int klen = rlen;
1271*0Sstevel@tonic-gate 				if (SASNDESC && SASNDESC->type == CONTENT && \
1272*0Sstevel@tonic-gate 			SASNDESC->nbson && SASNDESC->son[0].sondef) {
1273*0Sstevel@tonic-gate 					(void)
1274*0Sstevel@tonic-gate 			decpdu(rlen, SASNDESC->son[0].sondef, ctxnum);
1275*0Sstevel@tonic-gate 				} else {
1276*0Sstevel@tonic-gate 					if (rlen < 200) {
1277*0Sstevel@tonic-gate 					for (j = 0, slen = 0; \
1278*0Sstevel@tonic-gate 			(rlen) && (pdulen > 0);
1279*0Sstevel@tonic-gate 					--rlen, --pdulen, ++effnb)
1280*0Sstevel@tonic-gate 					{
1281*0Sstevel@tonic-gate 						if (!slen) {
1282*0Sstevel@tonic-gate 						    (void) \
1283*0Sstevel@tonic-gate 			strcpy((char *)scrlin, "LDAP:  "); j += 7;
1284*0Sstevel@tonic-gate 						    for \
1285*0Sstevel@tonic-gate 			(i = 0; i < level[ctxnum]; ++i) {
1286*0Sstevel@tonic-gate 							scrlin[j++] = ' ';
1287*0Sstevel@tonic-gate 							scrlin[j++] = ' ';
1288*0Sstevel@tonic-gate 							scrlin[j++] = ' ';
1289*0Sstevel@tonic-gate 							scrlin[j++] = ' ';
1290*0Sstevel@tonic-gate 						    }
1291*0Sstevel@tonic-gate 						}
1292*0Sstevel@tonic-gate 
1293*0Sstevel@tonic-gate 						GETNEXT(ctxnum);
1294*0Sstevel@tonic-gate 						if (k < 5) {
1295*0Sstevel@tonic-gate 							hexstr[k++] = hex;
1296*0Sstevel@tonic-gate 						} /* end if */
1297*0Sstevel@tonic-gate 						if (!isprint(hex)) {
1298*0Sstevel@tonic-gate 							hex = '_';
1299*0Sstevel@tonic-gate 							dontprint = 1;
1300*0Sstevel@tonic-gate 						}
1301*0Sstevel@tonic-gate 						scrlin[j++] = hex;
1302*0Sstevel@tonic-gate 						if ((slen += 2) >= \
1303*0Sstevel@tonic-gate 			(72 - (level[ctxnum] * 3))) {
1304*0Sstevel@tonic-gate 							slen = 0;
1305*0Sstevel@tonic-gate 							scrlin[j] = 0;
1306*0Sstevel@tonic-gate 							if (!dontprint) {
1307*0Sstevel@tonic-gate 								asnshw2 \
1308*0Sstevel@tonic-gate 			("%s\n", scrlin);
1309*0Sstevel@tonic-gate 							}
1310*0Sstevel@tonic-gate 							j = 0;
1311*0Sstevel@tonic-gate 						}
1312*0Sstevel@tonic-gate 					} /* rof: primitive values */
1313*0Sstevel@tonic-gate 					if (slen) {
1314*0Sstevel@tonic-gate 						scrlin[j] = 0;
1315*0Sstevel@tonic-gate 						if (!dontprint) {
1316*0Sstevel@tonic-gate 							asnshw2("%s\n", scrlin);
1317*0Sstevel@tonic-gate 						}
1318*0Sstevel@tonic-gate 					}
1319*0Sstevel@tonic-gate 					dontprint = 0;
1320*0Sstevel@tonic-gate 				} else {
1321*0Sstevel@tonic-gate 					asnshw2("%s  ", "LDAP:");
1322*0Sstevel@tonic-gate 				    for (i = 0; i < level[ctxnum]; ++i) {
1323*0Sstevel@tonic-gate 						asnshw1("   ");
1324*0Sstevel@tonic-gate 						scrlin[j++] = ' ';
1325*0Sstevel@tonic-gate 						scrlin[j++] = ' ';
1326*0Sstevel@tonic-gate 						scrlin[j++] = ' ';
1327*0Sstevel@tonic-gate 					}
1328*0Sstevel@tonic-gate 
1329*0Sstevel@tonic-gate 				    for (j = 0; (rlen) && (pdulen > 0); \
1330*0Sstevel@tonic-gate 			--rlen, --pdulen, ++effnb) {
1331*0Sstevel@tonic-gate 						GETNEXT(ctxnum);
1332*0Sstevel@tonic-gate 						if (k < 5) {
1333*0Sstevel@tonic-gate 							hexstr[k++] = hex;
1334*0Sstevel@tonic-gate 						}
1335*0Sstevel@tonic-gate 					}
1336*0Sstevel@tonic-gate 				    (void) strcpy \
1337*0Sstevel@tonic-gate 			((char *)scrlin, \
1338*0Sstevel@tonic-gate 			"*** NOT PRINTED - Too long value ***");
1339*0Sstevel@tonic-gate 						asnshw2("%s\n", scrlin);
1340*0Sstevel@tonic-gate 					}
1341*0Sstevel@tonic-gate 
1342*0Sstevel@tonic-gate 					if \
1343*0Sstevel@tonic-gate 			(SASNDESC && SASNDESC->type == BITSTRING &&\
1344*0Sstevel@tonic-gate 			klen <= 5) {
1345*0Sstevel@tonic-gate 						unsigned long bitstr = 0;
1346*0Sstevel@tonic-gate 						for (i = 1; i < 5; ++i) {
1347*0Sstevel@tonic-gate 							bitstr = \
1348*0Sstevel@tonic-gate 			((bitstr) << 8) + ((i < klen)?hexstr[i]:0);
1349*0Sstevel@tonic-gate 						} /* end for */
1350*0Sstevel@tonic-gate 						for \
1351*0Sstevel@tonic-gate 			(i = 0; i < SASNDESC->nbson; ++i) {
1352*0Sstevel@tonic-gate 							if ((bitstr & \
1353*0Sstevel@tonic-gate 			((unsigned long)SASNDESC->son[i].sondef)) ==
1354*0Sstevel@tonic-gate 			((unsigned long)SASNDESC->son[i].tag)) {
1355*0Sstevel@tonic-gate 								if \
1356*0Sstevel@tonic-gate 			(SASNDESC->son[i].sonname) {
1357*0Sstevel@tonic-gate 								int k;
1358*0Sstevel@tonic-gate 								asnshw2 \
1359*0Sstevel@tonic-gate 			("%s  ", "LDAP:");
1360*0Sstevel@tonic-gate 								for \
1361*0Sstevel@tonic-gate 			(k = 0; k < level[ctxnum]; ++k) {
1362*0Sstevel@tonic-gate 								asnshw1("   ");
1363*0Sstevel@tonic-gate 								}
1364*0Sstevel@tonic-gate 								asnshw2 \
1365*0Sstevel@tonic-gate 			("%s", SASNDESC->son[i].sonname);
1366*0Sstevel@tonic-gate 								} /* end if */
1367*0Sstevel@tonic-gate 							} /* end if */
1368*0Sstevel@tonic-gate 						} /* end for */
1369*0Sstevel@tonic-gate 					} /* end if */
1370*0Sstevel@tonic-gate 					if (SASNDESC && \
1371*0Sstevel@tonic-gate 			(SASNDESC->type == ENUM ||
1372*0Sstevel@tonic-gate 			SASNDESC->type == CONTENTTYPE) && klen <= 5) {
1373*0Sstevel@tonic-gate 						unsigned long value = 0;
1374*0Sstevel@tonic-gate 						for (i = 0; i < klen; ++i) {
1375*0Sstevel@tonic-gate 							value = \
1376*0Sstevel@tonic-gate 			((value) << 8) + hexstr[i];
1377*0Sstevel@tonic-gate 						} /* end for */
1378*0Sstevel@tonic-gate 						for \
1379*0Sstevel@tonic-gate 			(i = 0; i < SASNDESC->nbson; ++i) {
1380*0Sstevel@tonic-gate 							if \
1381*0Sstevel@tonic-gate 			(value == ((unsigned long)SASNDESC->son[i].tag)) {
1382*0Sstevel@tonic-gate 								if \
1383*0Sstevel@tonic-gate 			(SASNDESC->son[i].sonname) {
1384*0Sstevel@tonic-gate 									int k;
1385*0Sstevel@tonic-gate 								asnshw2 \
1386*0Sstevel@tonic-gate 			("%s  ", "LDAP:");
1387*0Sstevel@tonic-gate 									for \
1388*0Sstevel@tonic-gate 			(k = 0; k < level[ctxnum]; ++k) {
1389*0Sstevel@tonic-gate 								asnshw1("   ");
1390*0Sstevel@tonic-gate 									}
1391*0Sstevel@tonic-gate 								asnshw2 \
1392*0Sstevel@tonic-gate 			("%s\n", SASNDESC->son[i].sonname);
1393*0Sstevel@tonic-gate 									(void) \
1394*0Sstevel@tonic-gate 			strcpy(resultcode, SASNDESC->son[i].sonname);
1395*0Sstevel@tonic-gate 								} /* end if */
1396*0Sstevel@tonic-gate 								break;
1397*0Sstevel@tonic-gate 							} /* end if */
1398*0Sstevel@tonic-gate 						} /* end for */
1399*0Sstevel@tonic-gate 					} /* end if */
1400*0Sstevel@tonic-gate 
1401*0Sstevel@tonic-gate 				} /* end if */
1402*0Sstevel@tonic-gate 			} /* fi: constructor/obj-id/primitive */
1403*0Sstevel@tonic-gate 		} /* fi: tag analysis */
1404*0Sstevel@tonic-gate 	} /* elihw: len>1 */
1405*0Sstevel@tonic-gate 	--level[ctxnum];
1406*0Sstevel@tonic-gate 	return (effnb);
1407*0Sstevel@tonic-gate }
1408*0Sstevel@tonic-gate 
1409*0Sstevel@tonic-gate 
1410*0Sstevel@tonic-gate /* init_ldap initializes various buffers and variables */
1411*0Sstevel@tonic-gate /* it is called one-time (in snoop_filter.c) only. */
1412*0Sstevel@tonic-gate 
1413*0Sstevel@tonic-gate void
1414*0Sstevel@tonic-gate init_ldap()
1415*0Sstevel@tonic-gate {
1416*0Sstevel@tonic-gate 	int i;
1417*0Sstevel@tonic-gate 
1418*0Sstevel@tonic-gate 	for (i = 0; i < MAX_CTX; i++) {
1419*0Sstevel@tonic-gate 		gi_osibuf[i] = 0;
1420*0Sstevel@tonic-gate 		level[i] = 0;
1421*0Sstevel@tonic-gate 	}
1422*0Sstevel@tonic-gate }
1423*0Sstevel@tonic-gate static void
1424*0Sstevel@tonic-gate ldapdump(char *data, int datalen)
1425*0Sstevel@tonic-gate {
1426*0Sstevel@tonic-gate 	char *p;
1427*0Sstevel@tonic-gate 	ushort_t *p16 = (ushort_t *)data;
1428*0Sstevel@tonic-gate 	char *p8 = data;
1429*0Sstevel@tonic-gate 	int i, left, len;
1430*0Sstevel@tonic-gate 	int chunk = 16;  /* 16 bytes per line */
1431*0Sstevel@tonic-gate 
1432*0Sstevel@tonic-gate 	asnshw1("LDAP: Skipping until next full LDAPMessage\n");
1433*0Sstevel@tonic-gate 
1434*0Sstevel@tonic-gate 	for (p = data; p < data + datalen; p += chunk) {
1435*0Sstevel@tonic-gate 		asnshw2("LDAP:\t%4d: ", p - data);
1436*0Sstevel@tonic-gate 		left = (data + datalen) - p;
1437*0Sstevel@tonic-gate 		len = MIN(chunk, left);
1438*0Sstevel@tonic-gate 		for (i = 0; i < (len / 2); i++)
1439*0Sstevel@tonic-gate 			asnshw2("%04x ", ntohs(*p16++) & 0xffff);
1440*0Sstevel@tonic-gate 		if (len % 2) {
1441*0Sstevel@tonic-gate 			asnshw2("%02x   ", *((unsigned char *)p16));
1442*0Sstevel@tonic-gate 		}
1443*0Sstevel@tonic-gate 		for (i = 0; i < (chunk - left) / 2; i++)
1444*0Sstevel@tonic-gate 			asnshw1("     ");
1445*0Sstevel@tonic-gate 
1446*0Sstevel@tonic-gate 		asnshw1("   ");
1447*0Sstevel@tonic-gate 		for (i = 0; i < len; i++, p8++)
1448*0Sstevel@tonic-gate 			asnshw2("%c", isprint(*p8) ? *p8 : '.');
1449*0Sstevel@tonic-gate 		asnshw1("\n");
1450*0Sstevel@tonic-gate 	}
1451*0Sstevel@tonic-gate 
1452*0Sstevel@tonic-gate 	asnshw1("LDAP:\n");
1453*0Sstevel@tonic-gate }
1454*0Sstevel@tonic-gate 
1455*0Sstevel@tonic-gate /* decode_ldap is the entry point for the main decoding function */
1456*0Sstevel@tonic-gate /* decpdu(). decode_ldap() is only called by interpret_ldap. */
1457*0Sstevel@tonic-gate 
1458*0Sstevel@tonic-gate void
1459*0Sstevel@tonic-gate decode_ldap(char *buf, int len)
1460*0Sstevel@tonic-gate {
1461*0Sstevel@tonic-gate 	asndefTp ASNDESC = 0;
1462*0Sstevel@tonic-gate 	char *newbuf;
1463*0Sstevel@tonic-gate 	int skipped = 0;
1464*0Sstevel@tonic-gate 
1465*0Sstevel@tonic-gate 	PTRaclass = MHSaclass;
1466*0Sstevel@tonic-gate 	ASNDESC = &MPDU;
1467*0Sstevel@tonic-gate 
1468*0Sstevel@tonic-gate 
1469*0Sstevel@tonic-gate 	newbuf =  skipjunk(len, buf);
1470*0Sstevel@tonic-gate 	if (newbuf > buf) {
1471*0Sstevel@tonic-gate 		skipped = newbuf-buf;
1472*0Sstevel@tonic-gate 		ldapdump(buf, newbuf-buf);
1473*0Sstevel@tonic-gate 	}
1474*0Sstevel@tonic-gate 	buf = newbuf;
1475*0Sstevel@tonic-gate 	len = len-skipped;
1476*0Sstevel@tonic-gate 	osibuff = buf;	/* Undecoded buf is passed by interpret_ldap */
1477*0Sstevel@tonic-gate 	osilen = len;	/* length of tcp data is also passed */
1478*0Sstevel@tonic-gate 
1479*0Sstevel@tonic-gate 	(void) decpdu(len, ASNDESC, 0);
1480*0Sstevel@tonic-gate 	gi_osibuf[0] = 0;
1481*0Sstevel@tonic-gate }
1482