summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ngatm/netnatm/msg/privmsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ngatm/netnatm/msg/privmsg.c')
-rw-r--r--sys/contrib/ngatm/netnatm/msg/privmsg.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/sys/contrib/ngatm/netnatm/msg/privmsg.c b/sys/contrib/ngatm/netnatm/msg/privmsg.c
new file mode 100644
index 0000000..3540efd
--- /dev/null
+++ b/sys/contrib/ngatm/netnatm/msg/privmsg.c
@@ -0,0 +1,275 @@
+/*
+ * 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/netnatm/msg/privmsg.c,v 1.8 2003/10/10 14:50:05 hbb Exp $
+ *
+ * Private definitions for the MSG code file.
+ *
+ * This file is included at the begin of the automatically generated
+ * uni_msg.c.
+ */
+
+/*
+ * Decode a UNI message header.
+ * Return values:
+ * 0 - ok
+ * -1 - ignore message (proto, length, CR error)
+ */
+int
+uni_decode_head(struct uni_msg *msg, struct uni_all *out,
+ struct unicx *cx __unused)
+{
+ u_int mlen;
+
+ cx->errcnt = 0;
+ (void)memset(out, 0, sizeof(struct uni_all));
+
+ if(uni_msg_len(msg) < 9)
+ return -1; /* Q.2931 5.6.2 */
+ if(cx->pnni) {
+ if(*msg->b_rptr++ != PNNI_PROTO)
+ return -1; /* Q.2931 5.6.1 */
+ } else {
+ if(*msg->b_rptr++ != UNI_PROTO)
+ return -1; /* Q.2931 5.6.1 */
+ }
+ if(*msg->b_rptr++ != 3)
+ return -1; /* Q.2931 5.6.3.1 */
+
+ out->u.hdr.cref.flag = (*msg->b_rptr & 0x80) ? 1 : 0;
+ out->u.hdr.cref.cref = (*msg->b_rptr++ & 0x7f) << 16;
+ out->u.hdr.cref.cref |= *msg->b_rptr++ << 8;
+ out->u.hdr.cref.cref |= *msg->b_rptr++;
+
+ out->mtype = *msg->b_rptr++;
+
+ /*
+ * Be not too piggy about this byte
+ */
+ switch(*msg->b_rptr & 0x13) {
+
+ case 0x00: case 0x01: case 0x02: case 0x03:
+ out->u.hdr.act = UNI_MSGACT_DEFAULT;
+ break;
+
+ case 0x10: case 0x11: case 0x12:
+ out->u.hdr.act = *msg->b_rptr & 0x3;
+ break;
+
+ case 0x13: /* Q.2931 5.7.1 */
+ out->u.hdr.act = UNI_MSGACT_REPORT;
+ break;
+ }
+ if(cx->pnni && (*msg->b_rptr & 0x08))
+ out->u.hdr.pass = 1;
+ else
+ out->u.hdr.pass = 0;
+
+ msg->b_rptr++;
+
+ mlen = *msg->b_rptr++ << 8;
+ mlen |= *msg->b_rptr++;
+
+ /*
+ * If the message is longer than the indicated length
+ * shorten it. If it is shorter, probably one of the IE
+ * decoders will break, but we should proceed. 5.5.6.5
+ */
+#if 0
+ if(uni_msg_len(msg) > mlen)
+ msg->b_wptr = msg->b_rptr + mlen;
+#endif
+
+ return 0;
+}
+
+static int
+uni_decode_body_internal(enum uni_msgtype mtype, struct uni_msg *msg,
+ union uni_msgall *out, struct unicx *cx)
+{
+ enum uni_ietype ietype;
+ struct uni_iehdr hdr;
+ u_int ielen;
+ const struct iedecl *iedecl;
+ int err = 0, ret;
+ u_char *end;
+
+ cx->ielast = (enum uni_ietype)0;
+ cx->repeat.h.present = 0;
+
+ while (uni_msg_len(msg) != 0) {
+ if (uni_decode_ie_hdr(&ietype, &hdr, msg, cx, &ielen)) {
+ /*
+ * Short header. Set the ielen to an impossible size.
+ * Then we should bump out in the error handling below.
+ * We should have at least an IE type here.
+ */
+ ielen = 0xffffffff;
+ }
+#ifdef DTRACE
+ printf("IE %x\n", ietype);
+#endif
+
+ if ((iedecl = GET_IEDECL(ietype, hdr.coding)) == NULL ||
+ ietype == UNI_IE_UNREC) {
+ /*
+ * entirly unknown IE. Check the length and skip it.
+ * Q.2931 5.6.8.1
+ */
+ if (ielen > uni_msg_len(msg))
+ msg->b_rptr = msg->b_wptr;
+ else
+ msg->b_rptr += ielen;
+ UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_UNK);
+ err = -1;
+ continue;
+ }
+#ifdef DTRACE
+ printf("IE %x known\n", ietype);
+#endif
+ if (ielen > iedecl->maxlen - 4 || ielen > uni_msg_len(msg)) {
+ /*
+ * Information element too long -> content error.
+ * Let the decoding routine set the error flag and
+ * return DEC_ERR.
+ * Q.2931 5.6.8.2
+ */
+#if 0
+ /*
+ * It is not clear how to best handle this error.
+ */
+ if (ielen > iedecl->maxlen - 4)
+ ielen = iedecl->maxlen - 4;
+#endif
+
+ if (ielen > uni_msg_len(msg))
+ ielen = uni_msg_len(msg);
+
+ hdr.present |= UNI_IE_ERROR;
+
+#ifdef DTRACE
+ printf("IE %x length too large\n", ietype);
+#endif
+ }
+
+#ifdef DTRACE
+ else
+ printf("IE %x length ok\n", ietype);
+#endif
+ end = msg->b_rptr + ielen;
+ ret = uni_msgtable[mtype]->decode(out, msg, ietype,
+ &hdr, ielen, cx);
+ msg->b_rptr = end;
+
+#ifdef DTRACE
+ printf("IE %x ret %d\n", ietype, ret);
+#endif
+
+ switch (ret) {
+
+ case DEC_OK: /* ok */
+ break;
+
+ case DEC_ILL: /* illegal IE */
+ /*
+ * Unexpected but recognized.
+ * Q.2931 5.6.8.3
+ */
+ UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_UNK);
+ err = -1;
+ break;
+
+ case DEC_ERR: /* bad IE */
+ if (iedecl->flags & UNIFL_ACCESS)
+ /* this may be wrong: 5.6.8.2 */
+ UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_ACC);
+ else
+ UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_BAD);
+ err = -1;
+ break;
+
+ default:
+ PANIC(("bad decode return"));
+ }
+ cx->ielast = ietype;
+ if (ietype != UNI_IE_REPEAT)
+ cx->repeat.h.present = 0;
+ }
+ return err;
+}
+
+/*
+ * Decode the body of a message. The header is assumed to be decoded
+ * already and out->hdr is filled in. Only information elements remain.
+ */
+int
+uni_decode_body(struct uni_msg *msg, struct uni_all *out, struct unicx *cx)
+{
+ cx->errcnt = 0;
+ if (out->mtype >= 256)
+ return (-1);
+ if (uni_msgtable[out->mtype] == NULL)
+ return (-1);
+ return (uni_decode_body_internal(out->mtype, msg, &out->u, cx));
+}
+
+
+/*
+ * Decode a uni message
+ */
+int
+uni_decode(struct uni_msg *msg, struct uni_all *out, struct unicx *cx)
+{
+ cx->errcnt = 0;
+ if (uni_decode_head(msg, out, cx))
+ return (-1);
+ if (uni_decode_body(msg, out, cx))
+ return (-2);
+ return (0);
+}
+
+int
+uni_encode(struct uni_msg *msg, struct uni_all *in, struct unicx *cx)
+{
+ if (in->mtype >= 256)
+ return (-1);
+ if (uni_msgtable[in->mtype] == NULL)
+ return (-3);
+
+ return ((uni_msgtable[in->mtype]->encode)(msg, &in->u, cx));
+}
+
+/*
+ * Doesn't belong here
+ */
+void
+uni_initcx(struct unicx *cx)
+{
+ memset(cx, 0, sizeof(struct unicx));
+ cx->tabsiz = 4;
+}
OpenPOWER on IntegriCloud