#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; char dn, 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.