#include <lber.h>typedef struct berelement { char
ber_buf; char
ber_ptr; char
ber_end; struct seqorset
ber_sos; int ber_tag; int ber_usertag; } BerElement;
typedef struct sockbuf { int sb_sd; BerElement sb_ber; } Sockbuf;
typedef struct berval { unsigned long bv_len; char
bv_val; };
ber_get_next(Sockbuf
sb, unsigned long
len, BerElement
ber);
ber_skip_tag(BerElement
ber, unsigned long
len);
ber_peek_tag(BerElement
ber, unsigned long
len);
ber_get_int(BerElement
ber, long
num);
ber_get_stringb(BerElement
ber, char
buf, unsigned long
len);
ber_get_stringa(BerElement
ber, char
buf);
ber_get_stringal(BerElement
ber, struct berval
bv);
ber_get_null(BerElement
ber);
ber_get_boolean(BerElement
ber, int
bool);
ber_get_bitstringa(BerElement
ber, char
buf, unsigned long
blen);
ber_first_element(BerElement
ber, unsigned long
len, char
cookie);
ber_next_element(BerElement
ber, unsigned long
len, char
cookie);
ber_scanf(BerElement
ber, char
fmt [, arg...]);
void ber_free(BerElement
ber, int freebuf);
ber_bvfree(struct berval
bv);
ber_bvecfree(struct berval
bvec);
Normally, the only routines that need be called by an application are ber_get_next to get the next BER element and ber_scanf to do the actual decoding. In some cases, ber_peek_tag may also need to be called in normal usage. The other routines are provided for those applications that need more control than ber_scanf provides. In general, these routines return the tag of the element decoded, or -1 if an error occurred.
The ber_get_next routine is used to read the next BER
element from the given Sockbuf, sb. A Sockbuf
consists of the descriptor (usually socket, but a file descriptor works just
as well) from which to read, and a BerElement structure used
to maintain a buffer. On the first call, sb_ber
should be zeroed.
It strips off and returns the leading tag byte, strips off and returns the
length of the entire element in len, and sets up ber for
subsequent calls to ber_scanf (and others) to decode the element.
The ber_scanf routine is used to decode a BER element in much the same way that scanf works (see the fscanf(3S) manual page for details). It reads from ber, a pointer to a BerElement such as returned by ber_get_next, interprets the bytes according to the format string fmt, and stores the results in its additional arguments. The format string contains conversion specifications which are used to direct the interpretation of the BER element. The format string can contain the following characters:
char 

should be supplied. Memory is
allocated, filled with the contents of the octet string, null-terminated, and
returned in the parameter.
char 
buffer should be supplied, followed by a
pointer to an integer initialized to the size of the buffer. Upon return,
the null-terminated octet string is put into the buffer, and the integer is
set to the actual size of the octet string.
struct ber_val 

should be supplied, which
upon return points to a malloc'd struct berval
containing the octet string and its length. ber_bvfree can be
called to free the malloc'd memory.
char 

should be supplied which will point to
the malloc'd bits, followed by an unsigned long 
,
which will point to the length (in bits) of the bitstring returned.
char 


should be supplied,
which upon return points to a malloc'd null-terminated array of
char 
's containing the octet strings. NULL is
returned if the sequence is empty.
struct berval 


should be supplied, which upon return points to a malloc'd
null-terminated array of struct berval 
's containing the
octet strings and their lengths. NULL is returned if the sequence
is empty. ber_bvecfree can be called to free the
malloc'd memory.
The ber_get_stringb routine is used to read an octet string into a preallocated buffer. The len parameter should be initialized to the size of the buffer, and will contain the length of the octet string read upon return. The buffer should be big enough to take the octet string value plus a terminating NULL byte.
The ber_get_stringa routine is used to malloc space into which an octet string is read.
The ber_get_stringal routine is used to malloc space
into which an octet string and its length are read. It takes a
struct berval
, and returns the result in this parameter.
The ber_get_null routine is used to read a NULL element. It returns the tag of the element it skips over.
The ber_get_boolean routine is used to read a boolean value. It is called the same way that ber_get_int is called.
The ber_get_bitstringa routine is used to read a bitstring value.
It takes a char
which will hold the malloc'd
bits, followed by an unsigned long
, which will point to the
length (in bits) of the bitstring returned.
The ber_first_element routine is used to return the tag and length of the first element in a set or sequence. It also returns in cookie a magic cookie parameter that should be passed to subsequent calls to ber_next_element, which returns similar information.
AlmostASearchRequest := SEQUENCE { baseObject DistinguishedName, scope ENUMERATED { baseObject (0), singleLevel (1), wholeSubtree (2) }, derefAliases ENUMERATED { neverDerefaliases (0), derefInSearching (1), derefFindingBaseObj (2), alwaysDerefAliases 3ldap }, sizelimit INTEGER (0 .. 65535), timelimit INTEGER (0 .. 65535), attrsOnly BOOLEAN, attributes SEQUENCE OF AttributeType }The element can be decoded using ber_scanf as follows.
int scope, ali, size, time, attrsonly; chardn,
attrs;
if ( ber_scanf( ber, "{aiiiib{v}}", &dn, &scope, &ali, &size, &time, &attrsonly, &attrs ) == -1 ) /
error
/ else /
success
/
Yeong, W., Howes, T., and Hardcastle-Kille, S., Lightweight Directory Access Protocol, OSI-DS-26, April 1992.
Information Processing - Open Systems Interconnection - Model and Notation - Service Definition - Specification of Basic Encoding Rules for Abstract Syntax Notation One, International Organization for Standardization, International Standard 8825.