* all of the PDU
* all of the PDU (but no error occurred; we just need more data).
ber_get_next_buffer_ext( void *buffer, size_t buffer_size, unsigned long *len,    BerElement *ber, unsigned long *Bytes_Scanned, Sockbuf *sock ){	unsigned long	tag = 0, netlen, toread;	unsigned char	lc;	long		rc;	int		noctets, diff;	byte_buffer sb = {0};	int rcnt = 0;	/*	 * Any ber element looks like this: tag length contents.	 * Assuming everything's ok, we return the tag byte (we	 * can assume a single byte), return the length in len,	 * and the rest of the undecoded element in buf.	 *	 * Assumptions:	 *	1) small tags (less than 128)	 *	2) definite lengths	 *	3) primitive encodings used whenever possible	 */	/*	 * first time through - malloc the buffer, set up ptrs, and	 * read the tag and the length and as much of the rest as we can	 */	sb.p = buffer;	sb.length = buffer_size;	*len = netlen = 0;	if ( ber->ber_rwptr == NULL || ber->ber_tag == LBER_DEFAULT ) {		/*		 * First, we read the tag.		 */		/* if we have been called before with a fragment not		 * containing a complete length, we have no rwptr but	 	 * a tag already		*/		if ( ber->ber_tag == LBER_DEFAULT ) {			if ( (tag = get_buffer_tag( &sb )) == LBER_DEFAULT ) {				goto premature_exit;			}			ber->ber_tag = tag;		}		if((sock->sb_options & LBER_SOCKBUF_OPT_VALID_TAG) &&		  (tag != sock->sb_valid_tag)) {			*Bytes_Scanned=0;			return( LBER_DEFAULT);		}		/*		 * Next, read the length.  The first byte contains the length		 * of the length.  If bit 8 is set, the length is the long		 * form, otherwise it's the short form.  We don't allow a		 * length that's greater than what we can hold in an unsigned		 * long.		 */		if ( read_bytes( &sb, &lc, 1 ) != 1 ) {			goto premature_exit;		}		if ( lc & 0x80 ) {			noctets = (lc & 0x7f);			if ( noctets > sizeof(unsigned long) )				goto premature_exit;			diff = sizeof(unsigned long) - noctets;			rcnt = read_bytes( &sb, (unsigned char *)&netlen + diff, noctets );			if ( rcnt != noctets ) {				/* keep the read bytes in buffer for the next round */				if ( ber->ber_end - ber->ber_buf < rcnt + 1 ) {					if ( nslberi_ber_realloc( ber, rcnt + 1 ) != 0 )						goto premature_exit;					ber->ber_end = ber->ber_buf + rcnt + 1;				}				ber->ber_ptr = ber->ber_buf;				ber->ber_buf[0] = lc;				if ( rcnt > 0 ) {					SAFEMEMCPY( &ber->ber_buf[1],								(const char *)&netlen + diff, rcnt );				}				/* The way how ber_rwptr is used here is exceptional.				 * Here, ber_rwptr is set after the buffer contents,				 * not to the next byte to be read.				 * This is b/c we need the number of bytes that were read (rcnt)				 * in the next process [ in "else if (0 == ber->ber_len)" ]				 */				ber->ber_rwptr = ber->ber_buf + rcnt + 1;				goto premature_exit;			}			*len = LBER_NTOHL( netlen );		} else {			*len = lc;		}		if ( LBER_DEFAULT == get_and_check_length(ber, *len, sock)) {			goto premature_exit;		}	} else if (0 == ber->ber_len) {		/* Still waiting to receive the length */		lc = ber->ber_buf[0];		if ( lc & 0x80 ) {			int prevcnt = ber->ber_rwptr - ber->ber_buf - 1/* lc */;			if ( prevcnt < 0 ) { /* This is unexpected */				ber_reset( ber, 0 );				ber->ber_tag = LBER_DEFAULT;				goto premature_exit;			}			noctets = (lc & 0x7f);			diff = sizeof(unsigned long) - noctets;			SAFEMEMCPY( (char *)&netlen + diff, &ber->ber_buf[1], prevcnt );			rcnt = read_bytes( &sb, (unsigned char *)&netlen + diff + prevcnt,				noctets - prevcnt );			if ( rcnt != noctets - prevcnt) {				/* keep the read bytes in buffer for the next round */				if ( ber->ber_end - ber->ber_rwptr < rcnt ) {					if ( nslberi_ber_realloc( ber, prevcnt + rcnt + 1 ) != 0 )						goto premature_exit;					ber->ber_end = ber->ber_rwptr + rcnt;				}				SAFEMEMCPY( ber->ber_rwptr,					(const char *)&netlen + diff + prevcnt, rcnt );				/* ditto */				ber->ber_rwptr += rcnt;				goto premature_exit;			}			*len = LBER_NTOHL( netlen );		} else {			*len = lc;	/* should not come here */		}		if ( LBER_DEFAULT == get_and_check_length(ber, *len, sock)) {			goto premature_exit;		}	}	toread = (unsigned long)ber->ber_end - (unsigned long)ber->ber_rwptr;	do {		if ( (rc = read_bytes( &sb, (unsigned char *)ber->ber_rwptr,		    (long)toread )) <= 0 ) {			goto premature_exit;		}		toread -= rc;		ber->ber_rwptr += rc;	} while ( toread > 0 );	*len = ber->ber_len;	*Bytes_Scanned = sb.offset;	return( ber->ber_tag );premature_exit:	/*	 * we're here because we hit the end of the buffer before seeing	 * all of the PDU	 */	*Bytes_Scanned = sb.offset;	return(LBER_DEFAULT);}