2 * Copyright (c) 1996-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Author: Hartmut Brandt <harti@freebsd.org>
29 * $Begemot: libunimsg/libngatm/unimsg.c,v 1.4 2004/07/08 08:21:41 brandt Exp $
31 * User space message structure.
39 #include <arpa/inet.h>
40 #include <netnatm/unimsg.h>
42 /* the amount of extra bytes to allocate */
46 * Allocate a message that can hold at least 's' bytes. Return NULL if
50 uni_msg_alloc(size_t s)
56 if ((m = malloc(sizeof(struct uni_msg))) == NULL)
58 if ((m->b_buf = malloc(s)) == NULL) {
62 m->b_rptr = m->b_wptr = m->b_buf;
63 m->b_lim = m->b_buf + s;
68 * Destroy the message and free memory
71 uni_msg_destroy(struct uni_msg *m)
78 * Extend message by at least 's' additional bytes.
79 * May reallocate the message buffer. Return -1 on errors, 0 if ok.
80 * If an error occurs the message is destroyed.
83 uni_msg_extend(struct uni_msg *m, size_t s)
86 size_t len, leading, newsize;
89 newsize = m->b_wptr - m->b_buf + s + EXTRA;
90 leading = m->b_rptr - m->b_buf;
91 if ((b = realloc(m->b_buf, newsize)) == NULL) {
97 m->b_rptr = m->b_buf + leading;
98 m->b_wptr = m->b_rptr + len;
99 m->b_lim = m->b_buf + newsize;
105 * Append the given buffer to the message. May reallocate the message
106 * buffer. Return 0 if ok, -1 on errors.
109 uni_msg_append(struct uni_msg *m, void *buf, size_t size)
113 if ((error = uni_msg_ensure(m, size)))
115 memcpy(m->b_wptr, buf, size);
122 * Construct a message from a number of pieces. The list of pieces must end
123 * with a NULL pointer.
126 uni_msg_build(void *ptr, ...)
137 n = va_arg(ap, size_t);
139 p1 = va_arg(ap, void *);
143 if ((m = uni_msg_alloc(len)) == NULL)
149 n = va_arg(ap, size_t);
150 memcpy(m->b_wptr, p1, n);
152 p1 = va_arg(ap, void *);
160 * Strip the last 32 bit word from the buffer.
161 * Barf if there is no word left.
164 uni_msg_strip32(struct uni_msg *msg)
169 bcopy(msg->b_wptr, &w, 4);
174 * Strip the first four bytes of the buffer.
177 uni_msg_get32(struct uni_msg *msg)
181 bcopy(msg->b_rptr, &w, 4);
187 * Append a 32 bit word to the buffer.
190 uni_msg_append32(struct uni_msg *msg, u_int u)
192 if (uni_msg_ensure(msg, 4) == -1)
195 bcopy(&u, msg->b_wptr, 4);
201 * Append a byte to the buffer.
204 uni_msg_append8(struct uni_msg *msg, u_int u)
206 if (uni_msg_ensure(msg, 1) == -1)
213 * Return the i-th word counted from the end of the buffer.
214 * i=-1 will return the last 32bit word, i=-2 the 2nd last.
215 * Assumes that the word is in the buffer.
218 uni_msg_trail32(const struct uni_msg *msg, int i)
222 bcopy(msg->b_wptr + 4 * i, &w, 4);
231 uni_msg_dup(const struct uni_msg *inp)
236 len = inp->b_wptr - inp->b_rptr;
237 off = inp->b_rptr - inp->b_buf;
238 if ((msg = uni_msg_alloc(inp->b_lim - inp->b_buf)) == NULL)
240 msg->b_rptr = msg->b_buf + off;
241 msg->b_wptr = msg->b_rptr + len;
242 (void)memcpy(msg->b_rptr, inp->b_rptr, len);