aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorHartmut Brandt <harti@FreeBSD.org>2003-10-22 08:09:00 +0000
committerHartmut Brandt <harti@FreeBSD.org>2003-10-22 08:09:00 +0000
commite869973eeca47c8777b3ffec6f8e5afb1949aed7 (patch)
tree05cdda7a131bc5b0ee00601541f48d0398bf397d /contrib
parent8711ce79a748c8ed9211712effba04c46fc0bfb5 (diff)
downloadsrc-e869973eeca47c8777b3ffec6f8e5afb1949aed7.tar.gz
src-e869973eeca47c8777b3ffec6f8e5afb1949aed7.zip
Virgin import of the NgATM SAAL layer user part v0.9.
Notes
Notes: svn path=/vendor/ngatm/dist/; revision=121330
Diffstat (limited to 'contrib')
-rw-r--r--contrib/ngatm/libngatm/sscfucust.h108
-rw-r--r--contrib/ngatm/libngatm/sscopcust.h255
-rw-r--r--contrib/ngatm/libngatm/unimsg.c245
-rw-r--r--contrib/ngatm/man/unimsg.3234
4 files changed, 842 insertions, 0 deletions
diff --git a/contrib/ngatm/libngatm/sscfucust.h b/contrib/ngatm/libngatm/sscfucust.h
new file mode 100644
index 000000000000..5168ef4a68f1
--- /dev/null
+++ b/contrib/ngatm/libngatm/sscfucust.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2001-2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ *
+ * $Begemot: libunimsg/libunimsg/sscfucust.h,v 1.3 2003/09/19 13:10:35 hbb Exp $
+ *
+ * Customisation of the SSCFU code for the user space library.
+ */
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef SSCFU_DEBUG
+#include <assert.h>
+#endif
+#include <netnatm/unimsg.h>
+
+/*
+ * Allocate zeroed or non-zeroed memory of some size and cast it.
+ * Return NULL on failure.
+ */
+#define MEMINIT()
+
+#define MEMZALLOC(PTR,CAST,SIZE) do { \
+ void *_m = malloc(SIZE); \
+ if (_m != NULL) \
+ bzero(_m, SIZE); \
+ (PTR) = (CAST)_m; \
+} while(0)
+
+#define MEMFREE(PTR) \
+ free(PTR)
+
+#define SIG_ALLOC(PTR) \
+ MEMZALLOC(PTR, struct sscfu_sig *, sizeof(struct sscfu_sig))
+#define SIG_FREE(PTR) \
+ MEMFREE(PTR)
+
+/*
+ * Signal queues
+ */
+typedef TAILQ_ENTRY(sscfu_sig) sscfu_sigq_link_t;
+typedef TAILQ_HEAD(sscfu_sigq, sscfu_sig) sscfu_sigq_head_t;
+#define SIGQ_INIT(Q) TAILQ_INIT(Q)
+#define SIGQ_APPEND(Q,S) TAILQ_INSERT_TAIL(Q, S, link)
+#define SIGQ_GET(Q) \
+ ({ \
+ struct sscfu_sig *_s = NULL; \
+ \
+ if(!TAILQ_EMPTY(Q)) { \
+ _s = TAILQ_FIRST(Q); \
+ TAILQ_REMOVE(Q, _s, link); \
+ } \
+ _s; \
+ })
+
+#define SIGQ_CLEAR(Q) \
+ do { \
+ struct sscfu_sig *_s1, *_s2; \
+ \
+ _s1 = TAILQ_FIRST(Q); \
+ while(_s1 != NULL) { \
+ _s2 = TAILQ_NEXT(_s1, link); \
+ if(_s1->m) \
+ MBUF_FREE(_s1->m); \
+ SIG_FREE(_s1); \
+ _s1 = _s2; \
+ } \
+ TAILQ_INIT(Q); \
+ } while(0)
+
+
+/*
+ * Message buffers
+ */
+#define MBUF_FREE(M) uni_msg_destroy(M)
+
+#ifdef SSCFU_DEBUG
+#define ASSERT(S) assert(S)
+#else
+#define ASSERT(S)
+#endif
diff --git a/contrib/ngatm/libngatm/sscopcust.h b/contrib/ngatm/libngatm/sscopcust.h
new file mode 100644
index 000000000000..37cada672e49
--- /dev/null
+++ b/contrib/ngatm/libngatm/sscopcust.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2001-2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ *
+ * $Begemot: libunimsg/libunimsg/sscopcust.h,v 1.3 2003/09/19 13:10:35 hbb Exp $
+ *
+ * Customisation of the SSCOP code for the user space library.
+ */
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#ifdef SSCOP_DEBUG
+#include <assert.h>
+#endif
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netnatm/unimsg.h>
+
+/*
+ * Allocate zeroed or non-zeroed memory of some size and cast it.
+ * Return NULL on failure.
+ */
+#define MEMINIT()
+
+#define MEMZALLOC(PTR,CAST,SIZE) do { \
+ void *_m = malloc(SIZE); \
+ if (_m != NULL) \
+ bzero(_m, SIZE); \
+ (PTR) = (CAST)_m; \
+} while(0)
+
+#define MEMFREE(PTR) free(PTR);
+
+#define MSG_ALLOC(PTR) \
+ MEMZALLOC(PTR, struct sscop_msg *, sizeof(struct sscop_msg))
+#define MSG_FREE(PTR) \
+ MEMFREE(PTR)
+
+#define SIG_ALLOC(PTR) \
+ MEMZALLOC(PTR, struct sscop_sig *, sizeof(struct sscop_sig))
+#define SIG_FREE(PTR) \
+ MEMFREE(PTR)
+
+/*
+ * Timer support.
+ */
+typedef void *sscop_timer_t;
+#define TIMER_INIT(S,T) (S)->t_##T = NULL
+#define TIMER_STOP(S,T) do { \
+ if ((S)->t_##T != NULL) { \
+ (S)->funcs->stop_timer((S), (S)->aarg, (S)->t_##T); \
+ (S)->t_##T = NULL; \
+ } \
+ } while(0)
+#define TIMER_RESTART(S,T) do { \
+ if ((S)->t_##T != NULL) \
+ (S)->funcs->stop_timer((S), (S)->aarg, (S)->t_##T); \
+ (S)->t_##T = (S)->funcs->start_timer((S), (S)->aarg, \
+ (S)->timer##T, T##_func); \
+ } while(0)
+#define TIMER_ISACT(S,T) ((S)->t_##T != NULL)
+
+#define TIMER_FUNC(T,N) \
+static void \
+T##_func(void *varg) \
+{ \
+ struct sscop *sscop = varg; \
+ VERBOSE(sscop, SSCOP_DBG_TIMER, (sscop, sscop->aarg, \
+ "timer_" #T " expired")); \
+ sscop->t_##T = NULL; \
+ sscop_signal(sscop, SIG_T_##N, NULL); \
+}
+
+
+/*
+ * Message queues
+ */
+typedef TAILQ_ENTRY(sscop_msg) sscop_msgq_link_t;
+typedef TAILQ_HEAD(sscop_msgq, sscop_msg) sscop_msgq_head_t;
+#define MSGQ_EMPTY(Q) TAILQ_EMPTY(Q)
+#define MSGQ_INIT(Q) TAILQ_INIT(Q)
+#define MSGQ_FOREACH(P,Q) TAILQ_FOREACH(P,Q,link)
+#define MSGQ_REMOVE(Q,M) TAILQ_REMOVE(Q,M,link)
+#define MSGQ_INSERT_BEFORE(B,M) TAILQ_INSERT_BEFORE(B,M,link)
+#define MSGQ_APPEND(Q,M) TAILQ_INSERT_TAIL(Q,M,link)
+#define MSGQ_PEEK(Q) (TAILQ_EMPTY((Q)) ? NULL : TAILQ_FIRST((Q)))
+#define MSGQ_GET(Q) \
+ ({ \
+ struct sscop_msg *_m = NULL; \
+ \
+ if(!TAILQ_EMPTY(Q)) { \
+ _m = TAILQ_FIRST(Q); \
+ TAILQ_REMOVE(Q, _m, link); \
+ } \
+ _m; \
+ })
+
+#define MSGQ_CLEAR(Q) \
+ do { \
+ struct sscop_msg *_m1, *_m2; \
+ \
+ _m1 = TAILQ_FIRST(Q); \
+ while(_m1 != NULL) { \
+ _m2 = TAILQ_NEXT(_m1, link); \
+ SSCOP_MSG_FREE(_m1); \
+ _m1 = _m2; \
+ } \
+ TAILQ_INIT((Q)); \
+ } while(0)
+
+/*
+ * Signal queues
+ */
+typedef TAILQ_ENTRY(sscop_sig) sscop_sigq_link_t;
+typedef TAILQ_HEAD(sscop_sigq, sscop_sig) sscop_sigq_head_t;
+#define SIGQ_INIT(Q) TAILQ_INIT(Q)
+#define SIGQ_APPEND(Q,S) TAILQ_INSERT_TAIL(Q, S, link)
+#define SIGQ_EMPTY(Q) TAILQ_EMPTY(Q)
+#define SIGQ_GET(Q) \
+ ({ \
+ struct sscop_sig *_s = NULL; \
+ \
+ if(!TAILQ_EMPTY(Q)) { \
+ _s = TAILQ_FIRST(Q); \
+ TAILQ_REMOVE(Q, _s, link); \
+ } \
+ _s; \
+ })
+
+#define SIGQ_MOVE(F,T) \
+ do { \
+ struct sscop_sig *_s; \
+ \
+ while(!TAILQ_EMPTY(F)) { \
+ _s = TAILQ_FIRST(F); \
+ TAILQ_REMOVE(F, _s, link); \
+ TAILQ_INSERT_TAIL(T, _s, link); \
+ } \
+ } while(0)
+
+#define SIGQ_PREPEND(F,T) \
+ do { \
+ struct sscop_sig *_s; \
+ \
+ while(!TAILQ_EMPTY(F)) { \
+ _s = TAILQ_LAST(F, sscop_sigq); \
+ TAILQ_REMOVE(F, _s, link); \
+ TAILQ_INSERT_HEAD(T, _s, link); \
+ } \
+ } while(0)
+
+#define SIGQ_CLEAR(Q) \
+ do { \
+ struct sscop_sig *_s1, *_s2; \
+ \
+ _s1 = TAILQ_FIRST(Q); \
+ while(_s1 != NULL) { \
+ _s2 = TAILQ_NEXT(_s1, link); \
+ SSCOP_MSG_FREE(_s1->msg); \
+ SIG_FREE(_s1); \
+ _s1 = _s2; \
+ } \
+ TAILQ_INIT(Q); \
+ } while(0)
+
+
+
+/*
+ * Message buffers
+ */
+/* Free a buffer (if there is one) */
+#define MBUF_FREE(M) do { if(M) uni_msg_destroy(M); } while(0)
+
+/* duplicate a buffer */
+#define MBUF_DUP(M) uni_msg_dup(M)
+
+/* compute current length */
+#define MBUF_LEN(M) uni_msg_len((M))
+
+/*
+ * Return the i-th word counted from the end of the buffer.
+ * i=-1 will return the last 32bit word, i=-2 the 2nd last.
+ * Assumes that there is enough space.
+ */
+#define MBUF_TRAIL32(M,I) uni_msg_trail32((M), (I))
+
+/*
+ * Strip 32bit value from the end
+ */
+#define MBUF_STRIP32(M) uni_msg_strip32((M))
+
+/*
+ * Strip 32bit value from head
+ */
+#define MBUF_GET32(M) uni_msg_get32((M))
+
+/*
+ * Append a 32bit value to an mbuf. Failures are ignored.
+ */
+#define MBUF_APPEND32(M,W) uni_msg_append32((M), (W))
+
+/*
+ * Pad a message to a multiple of four byte and return the amount of padding
+ * Failures are ignored.
+ */
+#define MBUF_PAD4(M) \
+ ({ \
+ int _npad = 0; \
+ while (uni_msg_len(M) % 4 != 0) { \
+ uni_msg_append8((M), 0); \
+ _npad++; \
+ } \
+ _npad; \
+ })
+
+#define MBUF_UNPAD(M,P) do { (M)->b_wptr -= (P); } while(0)
+
+/*
+ * Allocate a message that will probably hold N bytes.
+ */
+#define MBUF_ALLOC(N) uni_msg_alloc(N)
+
+#ifdef SSCOP_DEBUG
+#define ASSERT(X) assert(X)
+#else
+#define ASSERT(X)
+#endif
diff --git a/contrib/ngatm/libngatm/unimsg.c b/contrib/ngatm/libngatm/unimsg.c
new file mode 100644
index 000000000000..d0c58765dc9c
--- /dev/null
+++ b/contrib/ngatm/libngatm/unimsg.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 1996-2003
+ * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Hartmut Brandt <harti@freebsd.org>
+ *
+ * $Begemot: libunimsg/libunimsg/unimsg.c,v 1.3 2003/09/19 13:10:35 hbb Exp $
+ *
+ * User space message structure.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <netnatm/unimsg.h>
+
+/* the amount of extra bytes to allocate */
+#define EXTRA 128
+
+/*
+ * Allocate a message that can hold at least 's' bytes. Return NULL if
+ * allocation fails.
+ */
+struct uni_msg *
+uni_msg_alloc(size_t s)
+{
+ struct uni_msg *m;
+
+ s += EXTRA;
+
+ if ((m = malloc(sizeof(struct uni_msg))) == NULL)
+ return NULL;
+ if ((m->b_buf = malloc(s)) == NULL) {
+ free(m);
+ return (NULL);
+ }
+ m->b_rptr = m->b_wptr = m->b_buf;
+ m->b_lim = m->b_buf + s;
+ return (m);
+}
+
+/*
+ * Destroy the message and free memory
+ */
+void
+uni_msg_destroy(struct uni_msg *m)
+{
+ free(m->b_buf);
+ free(m);
+}
+
+/*
+ * Extend message by at least 's' additional bytes.
+ * May reallocate the message buffer. Return -1 on errors, 0 if ok.
+ * If an error occurs the message is destroyed.
+ */
+int
+uni_msg_extend(struct uni_msg *m, size_t s)
+{
+ u_char *b;
+ size_t len, leading, newsize;
+
+ len = uni_msg_len(m);
+ newsize = m->b_wptr - m->b_buf + s + EXTRA;
+ leading = m->b_rptr - m->b_buf;
+ if ((b = realloc(m->b_buf, newsize)) == NULL) {
+ free(m->b_buf);
+ free(m);
+ return (-1);
+ }
+ m->b_buf = b;
+ m->b_rptr = m->b_buf + leading;
+ m->b_wptr = m->b_rptr + len;
+ m->b_lim = m->b_buf + newsize;
+
+ return (0);
+}
+
+/*
+ * Append the given buffer to the message. May reallocate the message
+ * buffer. Return 0 if ok, -1 on errors.
+ */
+int
+uni_msg_append(struct uni_msg *m, void *buf, size_t size)
+{
+ int error;
+
+ if ((error = uni_msg_ensure(m, size)))
+ return (error);
+ memcpy(m->b_wptr, buf, size);
+ m->b_wptr += size;
+
+ return (0);
+}
+
+/*
+ * Construct a message from a number of pieces. The list of pieces must end
+ * with a NULL pointer.
+ */
+struct uni_msg *
+uni_msg_build(void *ptr, ...)
+{
+ va_list ap;
+ struct uni_msg *m;
+ size_t len, n;
+ void *p1;
+
+ len = 0;
+ va_start(ap, ptr);
+ p1 = ptr;
+ while (p1 != NULL) {
+ n = va_arg(ap, size_t);
+ len += n;
+ p1 = va_arg(ap, void *);
+ }
+ va_end(ap);
+
+ if ((m = uni_msg_alloc(len)) == NULL)
+ return (NULL);
+
+ va_start(ap, ptr);
+ p1 = ptr;
+ while (p1 != NULL) {
+ n = va_arg(ap, size_t);
+ memcpy(m->b_wptr, p1, n);
+ m->b_wptr += n;
+ p1 = va_arg(ap, void *);
+ }
+ va_end(ap);
+
+ return (m);
+}
+
+/*
+ * Strip the last 32 bit word from the buffer.
+ * Barf if there is no word left.
+ */
+u_int
+uni_msg_strip32(struct uni_msg *msg)
+{
+ u_int32_t w;
+
+ msg->b_wptr -= 4;
+ bcopy(msg->b_wptr, &w, 4);
+ return (ntohl(w));
+}
+
+/*
+ * Strip the first four bytes of the buffer.
+ */
+u_int
+uni_msg_get32(struct uni_msg *msg)
+{
+ u_int32_t w;
+
+ bcopy(msg->b_rptr, &w, 4);
+ msg->b_rptr += 4;
+ return (ntohl(w));
+}
+
+/*
+ * Append a 32 bit word to the buffer.
+ */
+int
+uni_msg_append32(struct uni_msg *msg, u_int u)
+{
+ if (uni_msg_ensure(msg, 4) == -1)
+ return (-1);
+ u = htonl(u);
+ bcopy(&u, msg->b_wptr, 4);
+ msg->b_wptr += 4;
+ return (0);
+}
+
+/*
+ * Append a byte to the buffer.
+ */
+int
+uni_msg_append8(struct uni_msg *msg, u_int u)
+{
+ if (uni_msg_ensure(msg, 1) == -1)
+ return (-1);
+ *msg->b_wptr++ = u;
+ return (0);
+}
+
+/*
+ * Return the i-th word counted from the end of the buffer.
+ * i=-1 will return the last 32bit word, i=-2 the 2nd last.
+ * Assumes that the word is in the buffer.
+ */
+u_int
+uni_msg_trail32(const struct uni_msg *msg, int i)
+{
+ u_int w;
+
+ bcopy(msg->b_wptr + 4 * i, &w, 4);
+ return (ntohl(w));
+}
+
+
+/*
+ * Make a duplicate.
+ */
+struct uni_msg *
+uni_msg_dup(const struct uni_msg *inp)
+{
+ struct uni_msg *msg;
+ u_int len, off;
+
+ len = inp->b_wptr - inp->b_rptr;
+ off = inp->b_rptr - inp->b_buf;
+ if ((msg = uni_msg_alloc(inp->b_lim - inp->b_buf)) == NULL)
+ return (NULL);
+ msg->b_rptr = msg->b_buf + off;
+ msg->b_wptr = msg->b_rptr + len;
+ (void)memcpy(msg->b_rptr, inp->b_rptr, len);
+
+ return (msg);
+}
diff --git a/contrib/ngatm/man/unimsg.3 b/contrib/ngatm/man/unimsg.3
new file mode 100644
index 000000000000..eafa7b12f17b
--- /dev/null
+++ b/contrib/ngatm/man/unimsg.3
@@ -0,0 +1,234 @@
+.\"
+.\" Copyright (c) 2001-2003
+.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Author: Hartmut Brandt <harti@freebsd.org>
+.\"
+.\" $Begemot: libunimsg/man/unimsg.3,v 1.2 2003/08/21 16:01:08 hbb Exp $
+.\"
+.Dd August 23, 2002
+.Dt unimsg 3
+.Os
+.Sh NAME
+.Nm uni_msg_len ,
+.Nm uni_msg_space ,
+.Nm uni_msg_leading ,
+.Nm uni_msg_size ,
+.Nm uni_msg_ensure ,
+.Nm uni_msg_append ,
+.Nm uni_msg_extend ,
+.Nm uni_msg_alloc ,
+.Nm uni_msg_build ,
+.Nm uni_msg_destroy ,
+.Nm uni_msg_strip32 ,
+.Nm uni_msg_get32 ,
+.Nm uni_msg_append32 ,
+.Nm uni_msg_append8 ,
+.Nm uni_msg_trail32 ,
+.Nm uni_msg_dup
+.Nd "ATM signalling library - message buffers"
+.Sh LIBRARY
+Begemot ATM signalling library
+.Pq libunimsg, -lunimsg
+.Sh SYNOPSIS
+.In uni4/unimsg.h
+.Ft size_t
+.Fn uni_msg_len "const struct uni_msg *msg"
+.Ft size_t
+.Fn uni_msg_space "const struct uni_msg *msg"
+.Ft size_t
+.Fn uni_msg_leading "const struct uni_msg *msg"
+.Ft size_t
+.Fn uni_msg_size "const struct uni_msg *msg"
+.Ft int
+.Fn uni_msg_ensure "struct uni_msg *msg" "size_t bytes"
+.Ft int
+.Fn uni_msg_append "struct uni_msg *msg" "void *buf" "size_t buflen"
+.Ft int
+.Fn uni_msg_extend "struct uni_msg *msg" "size_t bytes"
+.Ft struct uni_msg *
+.Fn uni_msg_alloc "size_t space"
+.Ft struct uni_msg *
+.Fn uni_msg_build "void *buf" "..."
+.Ft void
+.Fn uni_msg_destroy "struct uni_msg *msg"
+.Ft u_int
+.Fn uni_msg_strip32 "struct uni_msg *msg"
+.Ft u_int
+.Fn uni_msg_get32 "struct uni_msg *msg"
+.Ft int
+.Fn uni_msg_append32 "struct uni_msg *msg" "u_int value"
+.Ft int
+.Fn uni_msg_append8 "struct uni_msg *msg" "u_int byte"
+.Ft u_int
+.Fn uni_msg_trail32 "const struct uni_msg *msg" "int n"
+.Ft struct uni_msg *
+.Fn uni_msg_dup "const struct uni_msg *msg"
+.Sh DESCRIPTION
+These functions are used to manipulate variable sized message. They are
+inspired by BSD mbufs and SysV stream buffers, but somewhat simplified because
+signalling generally is a low bandwidth task. All the functions operation on
+a
+.Li uni_msg
+data structure:
+.Bd -literal -offset indent
+struct uni_msg {
+ u_char *b_wptr; /* tail pointer */
+ u_char *b_rptr; /* head pointer */
+ u_char *b_buf; /* data buffer */
+ u_char *b_lim; /* end of data buffer */
+};
+.Ed
+.Pp
+The field
+.Fa b_buf
+points to the begin of a memory block that is used to store the actual message
+and the field
+.Fa b_lim
+points just to the first byte behind that buffer. This buffer is allocated
+separate from the structure itself and the user calling any of the above
+functions with a non const
+.Vt struct uni_msg
+argument should expect the buffer to be reallocated and hence not hold pointers
+into the buffer accross call to these functions.
+The pointer
+.Fa b_rptr
+points to the first used byte in the message and
+.Fa b_wptr
+to the first unused byte behind all used bytes.
+If the message is empty, both pointers point to the same place somewhere in
+the allocated buffer.
+.Pp
+There are several functions and macros that return various sizes and lengths.
+The macro
+.Fn uni_msg_len
+returns the actual size of the message (the number of used bytes). The
+macro
+.Fn uni_msg_space
+returns the number of bytes that are left unused behind the used space.
+The macro
+.Fn uni_msg_leading
+returns the number of bytes that are unused before the used space and the
+macro
+.Fn uni_msg_size
+returns the maximum size of the message (that is the size of the allocated
+buffer).
+.Pp
+Two functions may be used to create new messages: The function
+.Fn uni_msg_alloc
+allocates the message structure and a buffer to hold at least
+.Ar space
+bytes (In fact it allocates a couple of bytes more). If the allocation fails
+NULL is returned. The pointers are setup so that there is no leading space
+in the buffer.
+The function
+.Fn uni_msg_build
+constructs a new message from a variable number of buffers. The arguments
+are pairs of
+.Vt void *
+pointers to buffers and
+.Vt size_t
+buffer sizes, terminated by a NULL pointer. The function computes the total
+resulting message size, allocates a message and copies all the buffers
+into the message. The message is built to have no leading space. If the
+allocation fails, NULL is returned.
+.Pp
+The function
+.Fn uni_msg_destroy
+deallocates the buffer pointed to by the message and the message itself.
+It is save to pass a message with a NULL buffer, but not a NULL message.
+.Pp
+The function
+.Fn uni_msg_dup
+returns a copy of a message with exact the same leading space.
+.Pp
+A number of functions are used to add bytes to an existing message.
+The function
+.Fn uni_msg_extend
+extends the message buffer to have space for at least
+.Ar bytes
+additional byte at the end. The leading space does not change. This function
+may reallocate the message buffer. The function returns 0 on success and ENOMEM
+if the reallocation fails. In this case the message buffer is not changed.
+The macro
+.Fn uni_msg_ensure
+checks whether the message has space for additional
+.Ar bytes
+bytes. If not it calls
+.Fn uni_msg_extend
+to make the message buffer larger. The macro returns 0 on success or ENOMEM
+if there is not enough space and the reallocation fails.
+In this case the message buffer is not changed.
+The function
+.Fn uni_msg_append
+appends
+.Ar buflen
+bytes from the buffer pointed to by
+.Ar buf
+to the message.
+The function
+.Fn uni_msg_append8
+appends one byte to the message and the function
+.Fn uni_msg_append32
+appends a 32-bit value in network byte order to the message (
+.Fa b_wptr
+needs not to be aligned). All three functions call
+.Fn uni_msg_ensure
+to make sure, that the buffer contents fit into the message. They
+return 0 on success and ENOMEM if the buffer is too small and the reallocation
+fails. In this case the message buffer is not changed.
+.Pp
+A number of functions can be used to retrieve parts of the message.
+The function
+.Fn uni_msg_strip32
+returns the last four bytes of the message as a 32-bit integer assumed to
+be in network byte order. It adjusts
+.Fa b_wptr
+to remove these four bytes from the message.
+.Fa b_wptr
+does not need to be aligned.
+The function
+.Fn uni_msg_get32
+returns the first four bytes of the message as a 32-bit integer assumed to
+be in network byte order. It adjusts
+.Fa b_rptr
+to remove these four bytes from the message.
+.Fa b_rptr
+does not need to be aligned.
+The function
+.Fn uni_msg_trail32
+returns the
+.Fa n 'th
+32-bit integer from the buffer counted from the end of the buffer. The
+integer is assumed to be in network byte order. A value of -1 for
+.Fa n
+returns the last four bytes of the buffer, a value of -2 the four bytes
+just before the last four bytes and so on. All three functions do not check
+that the message is large enough.
+.Sh SEE ALSO
+.Xr libunimsg 3 ,
+.Xr mbuf 9
+.Sh AUTHORS
+.An Hartmut Brandt Aq harti@freebsd.org