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