2 * Copyright (c) 2001-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/netnatm/msg/uni_ie.c,v 1.16 2005/05/23 12:06:30 brandt_h Exp $
31 * Private definitions for the IE code file.
33 * This file includes the table generated automatically.
36 #include <sys/types.h>
37 #include <sys/param.h>
40 #include <sys/libkern.h>
44 #include <netnatm/unimsg.h>
45 #include <netnatm/msg/unistruct.h>
46 #include <netnatm/msg/unimsglib.h>
47 #include <netnatm/msg/uniprint.h>
48 #include <netnatm/msg/priv.h>
51 * Define internal functions.
53 #define DEF_IE_PRINT(Coding, IE) \
54 void uni_ie_print_##Coding##_##IE(struct uni_ie_##IE *ie, struct unicx *cx)
56 #define DEF_IE_CHECK(Coding, IE) \
57 int uni_ie_check_##Coding##_##IE(struct uni_ie_##IE *ie, struct unicx *cx)
59 #define DEF_IE_ENCODE(Coding, IE) \
60 int uni_ie_encode_##Coding##_##IE(struct uni_msg *msg, struct uni_ie_##IE *ie, struct unicx *cx)
62 #define DEF_IE_DECODE(Coding, IE) \
63 int uni_ie_decode_##Coding##_##IE(struct uni_ie_##IE *ie, struct uni_msg *msg, u_int ielen, struct unicx *cx)
66 * This structure is used to define value->string mappings. MKT() is used
67 * to generate a table entry. EOT() to end the table.
69 #define MKT(V,N) { #N, V }
70 #define EOT() { NULL, 0 }
72 /* library internal functions */
73 static void uni_entry(const char *, struct unicx *);
74 static int uni_print_iehdr(const char *, struct uni_iehdr *h, struct unicx *);
75 static void uni_print_ieend(struct unicx *);
76 static void uni_putc(int, struct unicx *);
82 #define APP_BYTE(M, B) do { \
83 *(M)->b_wptr++ = (B); \
85 #define APP_16BIT(M, B) do { \
87 *(M)->b_wptr++ = _v >> 8; \
88 *(M)->b_wptr++ = _v; \
90 #define APP_24BIT(M, B) do { \
92 *(M)->b_wptr++ = _v >> 16; \
93 *(M)->b_wptr++ = _v >> 8; \
94 *(M)->b_wptr++ = _v; \
96 #define APP_32BIT(M, B) do { \
98 *(M)->b_wptr++ = _v >> 24; \
99 *(M)->b_wptr++ = _v >> 16; \
100 *(M)->b_wptr++ = _v >> 8; \
101 *(M)->b_wptr++ = _v; \
103 #define APP_BUF(M, B, L) do { \
104 (void)memcpy((M)->b_wptr, (B), (L)); \
105 (M)->b_wptr += (L); \
108 #define APP_SUB_BYTE(M, T, B) do { APP_BYTE(M, T); APP_BYTE(M, B); } while (0)
109 #define APP_SUB_16BIT(M, T, B) do { APP_BYTE(M, T); APP_16BIT(M, B); } while (0)
110 #define APP_SUB_24BIT(M, T, B) do { APP_BYTE(M, T); APP_24BIT(M, B); } while (0)
111 #define APP_SUB_32BIT(M, T, B) do { APP_BYTE(M, T); APP_32BIT(M, B); } while (0)
113 #define APP_OPT(M, F, P, T) do { \
115 APP_BYTE((M), (T)); \
117 #define APP_OPT_BYTE(M, F, P, T, B) do { \
119 APP_SUB_BYTE((M), (T), (B)); \
121 #define APP_OPT_16BIT(M, F, P, T, B) do { \
123 APP_SUB_16BIT((M), (T), (B)); \
125 #define APP_OPT_24BIT(M, F, P, T, B) do { \
127 APP_SUB_24BIT((M), (T), (B)); \
130 #define START_IE(TYPE,CODE,LEN) \
133 if (uni_check_ie(CODE, (union uni_ieall *)ie, cx)) \
135 if (uni_encode_ie_hdr(msg, CODE, &ie->h, (LEN), cx)) \
138 ielen = msg->b_wptr - msg->b_rptr - 2;
140 #define START_IE2(TYPE,CODE,LEN,REALCODE) \
143 if (uni_check_ie(CODE, (union uni_ieall *)ie, cx)) \
145 if (uni_encode_ie_hdr(msg, REALCODE, &ie->h, (LEN), cx)) \
148 ielen = msg->b_wptr - msg->b_rptr - 2;
150 #define SET_IE_LEN(M) do { \
151 (M)->b_buf[ielen + 0] = \
152 (((M)->b_wptr - (M)->b_rptr) - ielen - 2) >> 8; \
153 (M)->b_buf[ielen + 1] = \
154 (((M)->b_wptr - (M)->b_rptr) - ielen - 2) >> 0; \
158 /***********************************************************************/
162 #define IE_START(ERR) \
163 if (IE_ISPRESENT(*ie)) \
171 IE_SETPRESENT(*ie); \
172 if (uni_check_ie(UNI_IE_##IE, (union uni_ieall *)ie, cx) == 0) \
175 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT; \
178 #define DEC_GETF3(ID, F, P) \
179 case UNI_##ID##_ID: \
183 if (!(P & UNI_##ID##_P)) { \
185 ie->F = *msg->b_rptr++ << 16; \
186 ie->F |= *msg->b_rptr++ << 8; \
187 ie->F |= *msg->b_rptr++; \
192 #define DEC_GETF1(ID, F, P) \
193 case UNI_##ID##_ID: \
197 if (!(P & UNI_##ID##_P)) { \
199 ie->F = *msg->b_rptr++; \
205 #define PRINT_NPREFIX (sizeof(((struct unicx *)0)->prefix) / \
206 sizeof(((struct unicx *)0)->prefix[0]))
209 * This is rather here than in privmsg.c because we need the APP macros.
212 uni_encode_msg_hdr(struct uni_msg *msg, struct uni_msghdr *h,
213 enum uni_msgtype type, struct unicx *cx, int *mlen)
217 uni_msg_ensure(msg, 9);
219 APP_BYTE(msg, cx->pnni ? PNNI_PROTO : UNI_PROTO);
221 if(h->cref.cref >= 1<<23)
223 APP_24BIT(msg, h->cref.cref | (h->cref.flag ? 0x800000 : 0));
227 if(h->act != UNI_MSGACT_DEFAULT)
228 byte |= 0x10 | (h->act & 3);
229 if(cx->pnni && h->pass)
233 *mlen = msg->b_wptr - msg->b_rptr;
240 * Initialize printing. This must be called by all printing routines
241 * that are exported to the user.
244 uni_print_init(char *buf, size_t bufsiz, struct unicx *cx)
259 * Append a character to the buffer if there is still space
262 uni_putc(int c, struct unicx *cx)
272 uni_printf(struct unicx *cx, const char *fmt, ...)
279 n = vsnprintf(cx->buf, cx->bufsiz, fmt, ap);
286 cx->buf += cx->bufsiz - 1;
296 * 0 - print all into one line, fully prefixed
297 * 1 - print on multiple lines, full prefixed, but equal level
298 * entries on one line
299 * 2 - like 2, but only partial prefixed
300 * 3 - like 1, but each entry onto a new line
305 * If we are in multiline mode, end the current line and set the
306 * flag, that we need indentation. But prevent double new lines.
309 uni_print_eol(struct unicx *cx)
320 * New entry. Do the prefixing, indentation and spacing.
323 doprefix(struct unicx *cx, const char *s)
327 if(cx->multiline == 0) {
329 for(i = 0; i < cx->nprefix; i++)
331 uni_printf(cx, "%s.", cx->prefix[i]);
332 } else if(cx->multiline == 1) {
334 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
338 for(i = 0; i < cx->nprefix; i++)
340 uni_printf(cx, "%s.", cx->prefix[i]);
341 } else if(cx->multiline == 2) {
343 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
347 } else if(cx->multiline == 3) {
352 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
353 for(i = 0; i < cx->nprefix; i++)
355 uni_printf(cx, "%s.", cx->prefix[i]);
356 } else if(cx->multiline == 4) {
361 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
363 uni_printf(cx, "%s", s);
366 uni_entry(const char *s, struct unicx *cx)
372 uni_print_flag(const char *s, struct unicx *cx)
379 * Start a deeper level of indendation. If multiline is in effect,
380 * we end the current line.
383 uni_print_push_prefix(const char *prefix, struct unicx *cx)
385 if (cx->nprefix < PRINT_NPREFIX)
386 cx->prefix[cx->nprefix++] = prefix;
389 uni_print_pop_prefix(struct unicx *cx)
396 uni_print_tbl(const char *entry, u_int val, const struct uni_print_tbl *tbl,
400 uni_entry(entry, cx);
402 if (tbl->val == val) {
403 uni_printf(cx, "%s", tbl->name);
408 uni_printf(cx, "ERROR(0x%x)", val);
412 uni_print_entry(struct unicx *cx, const char *e, const char *fmt, ...)
419 if (cx->bufsiz > 1) {
421 n = vsnprintf(cx->buf, cx->bufsiz, fmt, ap);
424 if (n < cx->bufsiz) {
428 cx->buf += cx->bufsiz - 1;
436 /**********************************************************************/
438 * Printing information elements.
441 uni_print_iehdr(const char *name, struct uni_iehdr *h, struct unicx *cx)
443 static const struct uni_print_tbl act_tab[] = {
444 MKT(UNI_IEACT_CLEAR, clear),
445 MKT(UNI_IEACT_IGNORE, ignore),
446 MKT(UNI_IEACT_REPORT, report),
447 MKT(UNI_IEACT_MSG_IGNORE, ignore-msg),
448 MKT(UNI_IEACT_MSG_REPORT, report-msg),
449 MKT(UNI_IEACT_DEFAULT, default),
452 static const struct uni_print_tbl cod_tab[] = {
453 MKT(UNI_CODING_ITU, itut),
454 MKT(UNI_CODING_NET, atmf),
458 uni_print_entry(cx, name, "(");
459 uni_print_tbl(NULL, h->act, act_tab, cx);
461 uni_print_tbl(NULL, h->coding, cod_tab, cx);
462 if(cx->pnni && h->pass)
463 uni_printf(cx, ",pass");
464 if(IE_ISEMPTY(*(struct uni_ie_aal *)h)) {
465 uni_printf(cx, ",empty)");
469 if(IE_ISERROR(*(struct uni_ie_aal *)h)) {
470 uni_printf(cx, ",error)");
477 uni_print_push_prefix(name, cx);
485 uni_print_ieend(struct unicx *cx)
487 uni_print_pop_prefix(cx);
493 uni_print_ie_internal(enum uni_ietype code, const union uni_ieall *ie,
496 const struct iedecl *iedecl;
498 if((iedecl = GET_IEDECL(code, ie->h.coding)) != NULL)
499 (*iedecl->print)(ie, cx);
503 uni_print_ie(char *buf, size_t size, enum uni_ietype code,
504 const union uni_ieall *ie, struct unicx *cx)
506 uni_print_init(buf, size, cx);
507 uni_print_ie_internal(code, ie, cx);
511 uni_check_ie(enum uni_ietype code, union uni_ieall *ie, struct unicx *cx)
513 const struct iedecl *iedecl = GET_IEDECL(code, ie->h.coding);
516 return (iedecl->check(ie, cx));
522 * Decode a information element header.
523 * Returns -1 if the message is too short.
524 * Strip the header from the message.
525 * The header is stripped, even if it is too short.
528 uni_decode_ie_hdr(enum uni_ietype *ietype, struct uni_iehdr *hdr,
529 struct uni_msg *msg, struct unicx *cx, u_int *ielen)
533 *ietype = (enum uni_ietype)0;
536 hdr->coding = UNI_CODING_ITU;
537 hdr->act = UNI_IEACT_DEFAULT;
539 if ((len = uni_msg_len(msg)) == 0)
542 *ietype = *msg->b_rptr++;
547 hdr->coding = (*msg->b_rptr >> 5) & 3;
550 switch (*msg->b_rptr & 0x17) {
552 case 0x10: case 0x11: case 0x12:
553 case 0x15: case 0x16:
554 hdr->act = *msg->b_rptr & 0x7;
557 case 0x00: case 0x01: case 0x02: case 0x03:
558 case 0x04: case 0x05: case 0x06: case 0x07:
559 hdr->act = UNI_IEACT_DEFAULT;
563 /* Q.2931 5.7.2 last sentence */
564 hdr->act = UNI_IEACT_REPORT;
567 if (cx->pnni && (*msg->b_rptr & 0x08))
574 hdr->present = UNI_IE_ERROR | UNI_IE_PRESENT;
580 hdr->present = UNI_IE_ERROR | UNI_IE_PRESENT;
584 *ielen = *msg->b_rptr++ << 8;
585 *ielen |= *msg->b_rptr++;
591 * Decode the body of an information element.
594 uni_decode_ie_body(enum uni_ietype ietype, union uni_ieall *ie,
595 struct uni_msg *msg, u_int ielen, struct unicx *cx)
597 const struct iedecl *iedecl;
601 if (ielen > uni_msg_len(msg)) {
603 * Information element too long -> content error.
606 msg->b_rptr = msg->b_wptr;
607 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
611 if ((iedecl = GET_IEDECL(ietype, ie->h.coding)) == NULL) {
613 * entirly unknown IE.
616 msg->b_rptr += ielen;
617 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
621 if (ielen > iedecl->maxlen) {
623 * Information element too long -> content error.
626 msg->b_rptr += iedecl->maxlen;
627 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
631 end = msg->b_rptr + ielen;
632 ret = (*iedecl->decode)(ie, msg, ielen, cx);
639 uni_encode_ie(enum uni_ietype code, struct uni_msg *msg, union uni_ieall *ie,
642 const struct iedecl *iedecl = GET_IEDECL(code, ie->h.coding);
646 return (iedecl->encode(msg, ie, cx));
650 uni_encode_ie_hdr(struct uni_msg *msg, enum uni_ietype type,
651 struct uni_iehdr *h, u_int len, struct unicx *cx)
655 uni_msg_ensure(msg, 4 + len);
656 *msg->b_wptr++ = type;
658 byte = 0x80 | (h->coding << 5);
659 if(h->act != UNI_IEACT_DEFAULT)
660 byte |= 0x10 | (h->act & 7);
662 byte |= h->pass << 3;
663 *msg->b_wptr++ = byte;
665 if(h->present & UNI_IE_EMPTY) {
680 uni_print_cref_internal(const struct uni_cref *cref, struct unicx *cx)
682 uni_print_entry(cx, "cref", "%d.", cref->flag);
683 if (cref->cref == CREF_GLOBAL)
684 uni_printf(cx, "GLOBAL");
685 else if (cref->cref == CREF_DUMMY)
686 uni_printf(cx, "DUMMY");
688 uni_printf(cx, "%d", cref->cref);
691 uni_print_cref(char *str, size_t len, const struct uni_cref *cref,
694 uni_print_init(str, len, cx);
695 uni_print_cref_internal(cref, cx);
699 uni_print_msghdr_internal(const struct uni_msghdr *hdr, struct unicx *cx)
701 static const struct uni_print_tbl tab[] = {
702 MKT(UNI_MSGACT_CLEAR, clear),
703 MKT(UNI_MSGACT_IGNORE, ignore),
704 MKT(UNI_MSGACT_REPORT, report),
705 MKT(UNI_MSGACT_DEFAULT, default),
709 uni_print_cref_internal(&hdr->cref, cx);
710 uni_print_tbl("act", hdr->act, tab, cx);
712 uni_print_entry(cx, "pass", "%s", hdr->pass ? "yes" : "no");
716 uni_print_msghdr(char *str, size_t len, const struct uni_msghdr *hdr,
719 uni_print_init(str, len, cx);
720 uni_print_msghdr_internal(hdr, cx);
725 uni_print_internal(const struct uni_all *msg, struct unicx *cx)
727 uni_entry("mtype", cx);
728 if(msg->mtype >= 256 || uni_msgtable[msg->mtype] == NULL) {
729 uni_printf(cx, "0x%02x(ERROR)", msg->mtype);
731 uni_printf(cx, "%s", uni_msgtable[msg->mtype]->name);
732 uni_print_msghdr_internal(&msg->u.hdr, cx);
735 (*uni_msgtable[msg->mtype]->print)(&msg->u, cx);
739 if(cx->multiline == 0)
740 uni_printf(cx, "\n");
744 uni_print(char *buf, size_t size, const struct uni_all *all, struct unicx *cx)
746 uni_print_init(buf, size, cx);
747 uni_print_internal(all, cx);
751 uni_print_msg_internal(u_int mtype, const union uni_msgall *msg,
755 uni_entry("mtype", cx);
756 if (mtype >= 256 || uni_msgtable[mtype] == NULL) {
757 uni_printf(cx, "0x%02x(ERROR)", mtype);
759 uni_printf(cx, "%s", uni_msgtable[mtype]->name);
760 uni_print_msghdr_internal(&msg->hdr, cx);
763 (*uni_msgtable[mtype]->print)(msg, cx);
767 if(cx->multiline == 0)
768 uni_printf(cx, "\n");
772 uni_print_msg(char *buf, size_t size, u_int mtype, const union uni_msgall *all,
775 uni_print_init(buf, size, cx);
776 uni_print_msg_internal(mtype, all, cx);
780 uni_print_cx(char *buf, size_t size, struct unicx *cx)
782 static const char *acttab[] = {
794 static const char *errtab[] = {
795 [UNI_IERR_UNK] = "unk", /* unknown IE */
796 [UNI_IERR_LEN] = "len", /* length error */
797 [UNI_IERR_BAD] = "bad", /* content error */
798 [UNI_IERR_ACC] = "acc", /* access element discarded */
799 [UNI_IERR_MIS] = "mis", /* missing IE */
804 uni_print_init(buf, size, cx);
806 uni_printf(cx, "q2932 %d\n", cx->q2932);
807 uni_printf(cx, "pnni %d\n", cx->pnni);
808 uni_printf(cx, "git_hard %d\n", cx->git_hard);
809 uni_printf(cx, "bearer_hard %d\n", cx->bearer_hard);
810 uni_printf(cx, "cause_hard %d\n", cx->cause_hard);
812 uni_printf(cx, "multiline %d\n", cx->multiline);
813 uni_printf(cx, "tabsiz %d\n", cx->tabsiz);
815 uni_printf(cx, "errcnt %d (", cx->errcnt);
816 for(i = 0; i < cx->errcnt; i++) {
817 uni_printf(cx, "%02x[%s,%s%s]", cx->err[i].ie,
818 errtab[cx->err[i].err], acttab[cx->err[i].act],
819 cx->err[i].man ? ",M" : "");
820 if(i != cx->errcnt - 1)
823 uni_printf(cx, ")\n");
826 #include <netnatm/msg/uni_ietab.h>
828 /*********************************************************************
832 * References for this IE are:
834 * Q.2931 pp. 69 (just a pointer to Q.2610)
835 * Q.2610 (this is a small diff to Q.850)
840 * ITU-T and NET coding for different values.
842 static const struct causetab {
845 } itu_causes[128] = {
847 #define D(NAME,VAL,DIAG,STD,STR) [UNI_CAUSE_##NAME] = { STR, UNI_DIAG_##DIAG },
848 #define N(NAME,VAL,DIAG,STD,STR)
850 UNI_DECLARE_CAUSE_VALUES
855 }, net_causes[128] = {
857 #define D(NAME,VAL,DIAG,STD,STR)
858 #define N(NAME,VAL,DIAG,STD,STR) [UNI_CAUSE_##NAME] = { STR, UNI_DIAG_##DIAG },
860 UNI_DECLARE_CAUSE_VALUES
868 uni_diag(enum uni_cause cause, enum uni_coding code)
871 return (UNI_DIAG_NONE);
873 if (code == UNI_CODING_NET)
874 if (net_causes[cause].str != NULL)
875 return (net_causes[cause].diag);
876 if (itu_causes[cause].str != NULL)
877 return (itu_causes[cause].diag);
878 return (UNI_DIAG_NONE);
881 /**********************************************************************/
884 print_cause(struct unicx *cx, struct uni_ie_cause *ie,
885 const struct causetab *tab1, const struct causetab *tab2)
887 static const struct uni_print_tbl loc_tbl[] = {
888 MKT(UNI_CAUSE_LOC_USER, user),
889 MKT(UNI_CAUSE_LOC_PRIVLOC, priv-net:loc-user),
890 MKT(UNI_CAUSE_LOC_PUBLOC, pub-net:loc-user),
891 MKT(UNI_CAUSE_LOC_TRANSIT, transit-net),
892 MKT(UNI_CAUSE_LOC_PUBREM, pub-net:rem-user),
893 MKT(UNI_CAUSE_LOC_PRIVREM, priv-net:rem-user),
894 MKT(UNI_CAUSE_LOC_INTERNAT, int-net),
895 MKT(UNI_CAUSE_LOC_BEYOND, beyond),
898 static const struct uni_print_tbl pu_tbl[] = {
899 MKT(UNI_CAUSE_PU_PROVIDER, provider),
900 MKT(UNI_CAUSE_PU_USER, user),
903 static const struct uni_print_tbl na_tbl[] = {
904 MKT(UNI_CAUSE_NA_NORMAL, normal),
905 MKT(UNI_CAUSE_NA_ABNORMAL, abnormal),
908 static const struct uni_print_tbl cond_tbl[] = {
909 MKT(UNI_CAUSE_COND_UNKNOWN, unknown),
910 MKT(UNI_CAUSE_COND_PERM, permanent),
911 MKT(UNI_CAUSE_COND_TRANS, transient),
914 static const struct uni_print_tbl rej_tbl[] = {
915 MKT(UNI_CAUSE_REASON_USER, user),
916 MKT(UNI_CAUSE_REASON_IEMISS, ie-missing),
917 MKT(UNI_CAUSE_REASON_IESUFF, ie-not-suff),
923 if (uni_print_iehdr("cause", &ie->h, cx))
926 if (ie->cause < 128 && tab1[ie->cause].str)
927 strcpy(buf, tab1[ie->cause].str);
928 else if (ie->cause < 128 && tab2 != NULL && tab2[ie->cause].str != NULL)
929 strcpy(buf, tab2[ie->cause].str);
931 sprintf(buf, "UNKNOWN-%u", ie->cause);
934 for (s = buf; *s != '\0'; s++)
937 uni_print_entry(cx, "cause", "%s", buf);
939 uni_print_tbl("loc", ie->loc, loc_tbl, cx);
941 if (ie->h.present & UNI_CAUSE_COND_P) {
942 uni_print_tbl("pu", ie->u.cond.pu, pu_tbl, cx);
943 uni_print_tbl("na", ie->u.cond.na, na_tbl, cx);
944 uni_print_tbl("condition", ie->u.cond.cond, cond_tbl, cx);
946 if (ie->h.present & UNI_CAUSE_REJ_P) {
947 uni_print_tbl("reject", ie->u.rej.reason, rej_tbl, cx);
949 if (ie->h.present & UNI_CAUSE_REJ_USER_P) {
950 uni_print_entry(cx, "user", "%u", ie->u.rej.user);
952 if (ie->h.present & UNI_CAUSE_REJ_IE_P) {
953 uni_print_entry(cx, "ie", "%u", ie->u.rej.ie);
955 if (ie->h.present & UNI_CAUSE_IE_P) {
956 uni_print_entry(cx, "ie", "(");
957 for (i = 0; i < ie->u.ie.len; i++) {
960 uni_printf(cx, "0x%02x", ie->u.ie.ie[i]);
964 if (ie->h.present & UNI_CAUSE_TRAFFIC_P) {
965 uni_print_entry(cx, "traffic", "(");
966 for (i = 0; i < ie->u.traffic.len; i++) {
969 uni_printf(cx, "0x%02x", ie->u.traffic.traffic[i]);
973 if (ie->h.present & UNI_CAUSE_VPCI_P) {
974 uni_print_entry(cx, "vpci", "(%u,%u)", ie->u.vpci.vpci, ie->u.vpci.vci);
976 if (ie->h.present & UNI_CAUSE_MTYPE_P) {
977 uni_print_entry(cx, "mtype", "%u", ie->u.mtype);
979 if (ie->h.present & UNI_CAUSE_TIMER_P) {
980 for (i = 0, s = buf; i < 3; i++) {
981 if (ie->u.timer[i] < ' ') {
983 *s++ = ie->u.timer[i] + '@';
984 } else if (ie->u.timer[i] <= '~')
985 *s++ = ie->u.timer[i];
988 *s++ = ie->u.timer[i] / 0100 + '0';
989 *s++ = (ie->u.timer[i] % 0100) / 010 + '0';
990 *s++ = ie->u.timer[i] % 010 + '0';
994 uni_print_entry(cx, "timer", "\"%s\"", buf);
996 if (ie->h.present & UNI_CAUSE_TNS_P) {
998 uni_print_ie_internal(UNI_IE_TNS, (union uni_ieall *)&ie->u.tns, cx);
1000 if (ie->h.present & UNI_CAUSE_NUMBER_P) {
1002 uni_print_ie_internal(UNI_IE_CALLED, (union uni_ieall *)&ie->u.number, cx);
1004 if (ie->h.present & UNI_CAUSE_ATTR_P) {
1005 uni_print_entry(cx, "attr", "(");
1006 for (i = 0; i < ie->u.attr.nattr; i++) {
1007 uni_printf(cx, "(%u", ie->u.attr.attr[i][0]);
1008 if (!(ie->u.attr.attr[i][0] & 0x80)) {
1009 uni_printf(cx, ",%u", ie->u.attr.attr[i][1]);
1010 if (!(ie->u.attr.attr[i][1] & 0x80))
1011 uni_printf(cx, ",%u",
1012 ie->u.attr.attr[i][2]);
1018 uni_print_ieend(cx);
1021 DEF_IE_PRINT(itu, cause)
1023 print_cause(cx, ie, itu_causes, NULL);
1025 DEF_IE_PRINT(net, cause)
1027 print_cause(cx, ie, net_causes, itu_causes);
1031 uni_ie_cause2str(enum uni_coding coding, u_int cause)
1034 if (coding == UNI_CODING_ITU)
1035 return (itu_causes[cause].str);
1036 if (coding == UNI_CODING_NET) {
1037 if (net_causes[cause].str != NULL)
1038 return (net_causes[cause].str);
1039 return (itu_causes[cause].str);
1045 /**********************************************************************/
1048 check_cause(struct uni_ie_cause *ie, struct unicx *cx,
1049 const struct causetab *tab1, const struct causetab *tab2)
1051 static const u_int mask =
1052 UNI_CAUSE_COND_P | UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P |
1053 UNI_CAUSE_REJ_IE_P | UNI_CAUSE_IE_P | UNI_CAUSE_TRAFFIC_P |
1054 UNI_CAUSE_VPCI_P | UNI_CAUSE_MTYPE_P | UNI_CAUSE_TIMER_P |
1055 UNI_CAUSE_TNS_P | UNI_CAUSE_NUMBER_P | UNI_CAUSE_ATTR_P |
1058 const struct causetab *ptr;
1060 if (ie->cause >= 128)
1067 case UNI_CAUSE_LOC_USER:
1068 case UNI_CAUSE_LOC_PRIVLOC:
1069 case UNI_CAUSE_LOC_PUBLOC:
1070 case UNI_CAUSE_LOC_TRANSIT:
1071 case UNI_CAUSE_LOC_PUBREM:
1072 case UNI_CAUSE_LOC_PRIVREM:
1073 case UNI_CAUSE_LOC_INTERNAT:
1074 case UNI_CAUSE_LOC_BEYOND:
1078 if (tab1[ie->cause].str != NULL)
1079 ptr = &tab1[ie->cause];
1080 else if (tab2 != NULL && tab2[ie->cause].str != NULL)
1081 ptr = &tab2[ie->cause];
1083 return (cx->cause_hard ? -1 : 0);
1085 switch (ptr->diag) {
1088 switch (ie->h.present & mask) {
1100 switch (ie->h.present & mask) {
1107 case UNI_CAUSE_COND_P:
1113 switch (ie->h.present & mask) {
1120 case UNI_CAUSE_REJ_P:
1121 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P:
1122 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_IE_P:
1127 case UNI_DIAG_CRATE:
1128 switch (ie->h.present & mask) {
1135 case UNI_CAUSE_TRAFFIC_P:
1141 switch (ie->h.present & mask) {
1148 case UNI_CAUSE_IE_P:
1153 case UNI_DIAG_CHANID:
1154 switch (ie->h.present & mask) {
1161 case UNI_CAUSE_VPCI_P:
1166 case UNI_DIAG_MTYPE:
1167 switch (ie->h.present & mask) {
1174 case UNI_CAUSE_MTYPE_P:
1179 case UNI_DIAG_TIMER:
1180 switch (ie->h.present & mask) {
1187 case UNI_CAUSE_TIMER_P:
1193 switch (ie->h.present & mask) {
1200 case UNI_CAUSE_TNS_P:
1205 case UNI_DIAG_NUMBER:
1206 switch (ie->h.present & mask) {
1213 case UNI_CAUSE_NUMBER_P:
1219 switch (ie->h.present & mask) {
1226 case UNI_CAUSE_ATTR_P:
1231 case UNI_DIAG_PARAM:
1232 switch (ie->h.present & mask) {
1239 case UNI_CAUSE_PARAM_P:
1245 if (ie->h.present & UNI_CAUSE_COND_P) {
1246 switch (ie->u.cond.pu) {
1250 case UNI_CAUSE_PU_PROVIDER:
1251 case UNI_CAUSE_PU_USER:
1254 switch (ie->u.cond.na) {
1258 case UNI_CAUSE_NA_NORMAL:
1259 case UNI_CAUSE_NA_ABNORMAL:
1262 switch (ie->u.cond.cond) {
1266 case UNI_CAUSE_COND_UNKNOWN:
1267 case UNI_CAUSE_COND_PERM:
1268 case UNI_CAUSE_COND_TRANS:
1272 if (ie->h.present & UNI_CAUSE_REJ_P) {
1273 switch (ie->u.rej.reason) {
1277 case UNI_CAUSE_REASON_USER:
1278 switch (ie->h.present & mask) {
1282 case UNI_CAUSE_REJ_P:
1283 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P:
1288 case UNI_CAUSE_REASON_IEMISS:
1289 case UNI_CAUSE_REASON_IESUFF:
1290 switch (ie->h.present & mask) {
1294 case UNI_CAUSE_REJ_P:
1295 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_IE_P:
1301 if (ie->h.present & UNI_CAUSE_IE_P) {
1302 if (ie->u.ie.len == 0 || ie->u.ie.len > UNI_CAUSE_IE_N)
1305 if (ie->h.present & UNI_CAUSE_TRAFFIC_P) {
1306 if (ie->u.traffic.len == 0 ||
1307 ie->u.traffic.len > UNI_CAUSE_TRAFFIC_N)
1311 if (ie->h.present & UNI_CAUSE_TNS_P) {
1312 if (uni_check_ie(UNI_IE_TNS, (union uni_ieall *)&ie->u.tns, cx))
1315 if (ie->h.present & UNI_CAUSE_NUMBER_P) {
1316 if(uni_check_ie(UNI_IE_CALLED, (union uni_ieall *)&ie->u.number, cx))
1319 if (ie->h.present & UNI_CAUSE_ATTR_P) {
1320 if(ie->u.attr.nattr > UNI_CAUSE_ATTR_N || ie->u.attr.nattr == 0)
1323 if (ie->h.present & UNI_CAUSE_PARAM_P) {
1330 DEF_IE_CHECK(itu, cause)
1332 return (check_cause(ie, cx, itu_causes, NULL));
1334 DEF_IE_CHECK(net, cause)
1336 return (check_cause(ie, cx, net_causes, itu_causes));
1338 /**********************************************************************/
1341 encode_cause(struct uni_msg *msg, struct uni_ie_cause *ie, struct unicx *cx)
1345 START_IE(cause, UNI_IE_CAUSE, 30);
1347 if (IE_ISERROR(*ie)) {
1348 APP_BYTE(msg, 0x00 | ie->loc);
1350 APP_BYTE(msg, 0x80 | ie->loc);
1352 APP_BYTE(msg, 0x80 | ie->cause);
1354 if (ie->h.present & UNI_CAUSE_COND_P)
1355 APP_BYTE(msg, 0x80 | (ie->u.cond.pu << 3) |
1356 (ie->u.cond.na << 2) | ie->u.cond.cond);
1358 else if (ie->h.present & UNI_CAUSE_REJ_P) {
1359 APP_BYTE(msg, 0x80 | (ie->u.rej.reason << 2) | ie->u.rej.cond);
1360 if (ie->h.present & UNI_CAUSE_REJ_USER_P)
1361 APP_BYTE(msg, ie->u.rej.user);
1362 else if (ie->h.present & UNI_CAUSE_REJ_IE_P)
1363 APP_BYTE(msg, ie->u.rej.ie);
1365 } else if(ie->h.present & UNI_CAUSE_IE_P)
1366 APP_BUF(msg, ie->u.ie.ie, ie->u.ie.len);
1368 else if (ie->h.present & UNI_CAUSE_TRAFFIC_P)
1369 APP_BUF(msg, ie->u.traffic.traffic, ie->u.traffic.len);
1371 else if (ie->h.present & UNI_CAUSE_VPCI_P) {
1372 APP_BYTE(msg, (ie->u.vpci.vpci >> 8));
1373 APP_BYTE(msg, (ie->u.vpci.vpci >> 0));
1374 APP_BYTE(msg, (ie->u.vpci.vci >> 8));
1375 APP_BYTE(msg, (ie->u.vpci.vci >> 0));
1377 } else if (ie->h.present & UNI_CAUSE_MTYPE_P)
1378 APP_BYTE(msg, ie->u.mtype);
1380 else if (ie->h.present & UNI_CAUSE_TIMER_P) {
1381 APP_BYTE(msg, ie->u.timer[0]);
1382 APP_BYTE(msg, ie->u.timer[1]);
1383 APP_BYTE(msg, ie->u.timer[2]);
1385 } else if (ie->h.present & UNI_CAUSE_TNS_P)
1386 uni_encode_ie(UNI_IE_TNS, msg,
1387 (union uni_ieall *)&ie->u.tns, cx);
1389 else if (ie->h.present & UNI_CAUSE_NUMBER_P)
1390 uni_encode_ie(UNI_IE_CALLED, msg,
1391 (union uni_ieall *)&ie->u.number, cx);
1393 else if (ie->h.present & UNI_CAUSE_ATTR_P) {
1394 for (i = 0; i < ie->u.attr.nattr; i++) {
1395 APP_BYTE(msg, ie->u.attr.attr[i][0]);
1396 if (!ie->u.attr.attr[i][0]) {
1397 APP_BYTE(msg, ie->u.attr.attr[i][1]);
1398 if (!ie->u.attr.attr[i][1])
1399 APP_BYTE(msg, ie->u.attr.attr[i][2]);
1402 } else if (ie->h.present & UNI_CAUSE_PARAM_P)
1403 APP_BYTE(msg, ie->u.param);
1410 DEF_IE_ENCODE(itu, cause)
1412 return encode_cause(msg, ie, cx);
1414 DEF_IE_ENCODE(net, cause)
1416 return encode_cause(msg, ie, cx);
1419 /**********************************************************************/
1422 decode_cause(struct uni_ie_cause *ie, struct uni_msg *msg, u_int ielen,
1423 struct unicx *cx, const struct causetab *tab1, const struct causetab *tab2)
1426 const struct causetab *ptr;
1427 enum uni_ietype ietype;
1432 if(ielen < 2 || ielen > 30)
1445 ie->cause = c & 0x7f;
1447 if(tab1[ie->cause].str != NULL)
1448 ptr = &tab1[ie->cause];
1449 else if(tab2 != NULL && tab2[ie->cause].str != NULL)
1450 ptr = &tab2[ie->cause];
1453 ielen = 0; /* ignore diags */
1468 ie->h.present |= UNI_CAUSE_COND_P;
1469 ie->u.cond.pu = (c >> 3) & 1;
1470 ie->u.cond.na = (c >> 2) & 1;
1471 ie->u.cond.cond = c & 3;
1483 ie->h.present |= UNI_CAUSE_REJ_P;
1484 ie->u.rej.reason = (c >> 2) & 0x1f;
1485 ie->u.rej.cond = c & 3;
1494 switch(ie->u.rej.reason) {
1496 case UNI_CAUSE_REASON_USER:
1497 ie->h.present |= UNI_CAUSE_REJ_USER_P;
1501 case UNI_CAUSE_REASON_IEMISS:
1502 case UNI_CAUSE_REASON_IESUFF:
1503 ie->h.present |= UNI_CAUSE_REJ_IE_P;
1510 case UNI_DIAG_CRATE:
1511 ie->h.present |= UNI_CAUSE_TRAFFIC_P;
1512 while(ielen && ie->u.traffic.len < UNI_CAUSE_TRAFFIC_N) {
1513 ie->u.traffic.traffic[ie->u.traffic.len++] =
1520 ie->h.present |= UNI_CAUSE_IE_P;
1521 while(ielen && ie->u.ie.len < UNI_CAUSE_IE_N) {
1522 ie->u.ie.ie[ie->u.ie.len++] = *msg->b_rptr++;
1527 case UNI_DIAG_CHANID:
1530 ie->h.present |= UNI_CAUSE_VPCI_P;
1531 ie->u.vpci.vpci = *msg->b_rptr++ << 8;
1532 ie->u.vpci.vpci |= *msg->b_rptr++;
1533 ie->u.vpci.vci = *msg->b_rptr++ << 8;
1534 ie->u.vpci.vci |= *msg->b_rptr++;
1538 case UNI_DIAG_MTYPE:
1539 ie->h.present |= UNI_CAUSE_MTYPE_P;
1540 ie->u.mtype = *msg->b_rptr++;
1544 case UNI_DIAG_TIMER:
1547 ie->h.present |= UNI_CAUSE_TIMER_P;
1548 ie->u.timer[0] = *msg->b_rptr++;
1549 ie->u.timer[1] = *msg->b_rptr++;
1550 ie->u.timer[2] = *msg->b_rptr++;
1557 if(uni_decode_ie_hdr(&ietype, &ie->u.tns.h, msg, cx, &xielen))
1559 if(ietype != UNI_IE_TNS)
1561 if(uni_decode_ie_body(ietype,
1562 (union uni_ieall *)&ie->u.tns, msg, xielen, cx))
1564 ie->h.present |= UNI_CAUSE_TNS_P;
1567 case UNI_DIAG_NUMBER:
1570 if(uni_decode_ie_hdr(&ietype, &ie->u.number.h, msg, cx, &xielen))
1572 if(ietype != UNI_IE_CALLED)
1574 if(uni_decode_ie_body(ietype,
1575 (union uni_ieall *)&ie->u.number, msg, xielen, cx))
1577 ie->h.present |= UNI_CAUSE_NUMBER_P;
1581 ie->h.present |= UNI_CAUSE_ATTR_P;
1582 while(ielen > 0 && ie->u.attr.nattr < UNI_CAUSE_ATTR_N) {
1584 ie->u.attr.attr[ie->u.attr.nattr][0] = c;
1586 if(ielen > 0 && !(c & 0x80)) {
1588 ie->u.attr.attr[ie->u.attr.nattr][1] = c;
1590 if(ielen > 0 && !(c & 0x80)) {
1592 ie->u.attr.attr[ie->u.attr.nattr][2] = c;
1599 case UNI_DIAG_PARAM:
1600 ie->h.present |= UNI_CAUSE_PARAM_P;
1601 ie->u.param = *msg->b_rptr++;
1610 DEF_IE_DECODE(itu, cause)
1612 return decode_cause(ie, msg, ielen, cx, itu_causes, NULL);
1614 DEF_IE_DECODE(net, cause)
1616 return decode_cause(ie, msg, ielen, cx, net_causes, itu_causes);
1619 /*********************************************************************
1623 * References for this IE are:
1625 * Q.2931 pp. 59...60
1628 * Only ITU-T coding allowed.
1630 DEF_IE_PRINT(itu, callstate)
1632 static const struct uni_print_tbl tbl[] = {
1633 MKT(UNI_CALLSTATE_U0, U0/N0/REST0),
1634 MKT(UNI_CALLSTATE_U1, U1/N1),
1635 MKT(UNI_CALLSTATE_U3, U3/N3),
1636 MKT(UNI_CALLSTATE_U4, U4/N4),
1637 MKT(UNI_CALLSTATE_U6, U6/N6),
1638 MKT(UNI_CALLSTATE_U7, U7/N7),
1639 MKT(UNI_CALLSTATE_U8, U8/N8),
1640 MKT(UNI_CALLSTATE_U9, U9/N9),
1641 MKT(UNI_CALLSTATE_U10, U10/N10),
1642 MKT(UNI_CALLSTATE_U11, U11/N11),
1643 MKT(UNI_CALLSTATE_U12, U12/N12),
1644 MKT(UNI_CALLSTATE_REST1,REST1),
1645 MKT(UNI_CALLSTATE_REST2,REST2),
1646 MKT(UNI_CALLSTATE_U13, U13/N13),
1647 MKT(UNI_CALLSTATE_U14, U14/N14),
1651 if(uni_print_iehdr("callstate", &ie->h, cx))
1653 uni_print_tbl("state", ie->state, tbl, cx);
1654 uni_print_ieend(cx);
1657 DEF_IE_CHECK(itu, callstate)
1665 case UNI_CALLSTATE_U0:
1666 case UNI_CALLSTATE_U1:
1667 case UNI_CALLSTATE_U3:
1668 case UNI_CALLSTATE_U4:
1669 case UNI_CALLSTATE_U6:
1670 case UNI_CALLSTATE_U7:
1671 case UNI_CALLSTATE_U8:
1672 case UNI_CALLSTATE_U9:
1673 case UNI_CALLSTATE_U10:
1674 case UNI_CALLSTATE_U11:
1675 case UNI_CALLSTATE_U12:
1676 case UNI_CALLSTATE_REST1:
1677 case UNI_CALLSTATE_REST2:
1678 case UNI_CALLSTATE_U13:
1679 case UNI_CALLSTATE_U14:
1686 DEF_IE_ENCODE(itu, callstate)
1688 START_IE(callstate, UNI_IE_CALLSTATE, 1);
1690 APP_BYTE(msg, ie->state);
1696 DEF_IE_DECODE(itu, callstate)
1703 ie->state = *msg->b_rptr++ & 0x3f;
1709 /*********************************************************************
1711 * Facility Information.
1713 * References for this IE are:
1717 * The standard allows only ROSE as protocol. We allow everything up to the
1720 * Only ITU-T coding allowed.
1722 DEF_IE_PRINT(itu, facility)
1726 if(uni_print_iehdr("facility", &ie->h, cx))
1729 if(ie->proto == UNI_FACILITY_ROSE)
1730 uni_print_entry(cx, "proto", "rose");
1732 uni_print_entry(cx, "proto", "0x%02x", ie->proto);
1734 uni_print_entry(cx, "len", "%u", ie->len);
1735 uni_print_entry(cx, "info", "(");
1736 for(i = 0; i < ie->len; i++)
1737 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->apdu[i]);
1738 uni_printf(cx, ")");
1740 uni_print_ieend(cx);
1743 DEF_IE_CHECK(itu, facility)
1747 if(ie->len > UNI_FACILITY_MAXAPDU)
1753 DEF_IE_ENCODE(itu, facility)
1755 START_IE(facility, UNI_IE_FACILITY, 1 + ie->len);
1757 APP_BYTE(msg, ie->proto | 0x80);
1758 APP_BUF(msg, ie->apdu, ie->len);
1764 DEF_IE_DECODE(itu, facility)
1770 if(ielen > UNI_FACILITY_MAXAPDU + 1 || ielen < 1)
1773 ie->proto = (c = *msg->b_rptr++) & 0x1f;
1775 if((c & 0xe0) != 0x80)
1780 (void)memcpy(ie->apdu, msg->b_rptr, ie->len);
1781 msg->b_rptr += ie->len;
1786 /*********************************************************************
1788 * Notification Indicator
1790 * References for this IE are:
1795 * Only ITU-T coding allowed.
1798 DEF_IE_PRINT(itu, notify)
1802 if(uni_print_iehdr("notify", &ie->h, cx))
1804 uni_print_entry(cx, "len", "%u", ie->len);
1805 uni_print_entry(cx, "info", "(");
1806 for(i = 0; i < ie->len; i++)
1807 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->notify[i]);
1808 uni_printf(cx, ")");
1809 uni_print_ieend(cx);
1812 DEF_IE_CHECK(itu, notify)
1816 if(ie->len > UNI_NOTIFY_MAXLEN)
1822 DEF_IE_ENCODE(itu, notify)
1824 START_IE(notify, UNI_IE_NOTIFY, ie->len);
1826 APP_BUF(msg, ie->notify, ie->len);
1827 if (IE_ISERROR(*ie)) {
1828 /* make it too long */
1831 while (i < UNI_NOTIFY_MAXLEN + 1) {
1832 APP_BYTE(msg, 0x00);
1841 DEF_IE_DECODE(itu, notify)
1845 if (ielen > UNI_NOTIFY_MAXLEN || ielen < 1)
1850 (void)memcpy(ie->notify, msg->b_rptr, ie->len);
1851 msg->b_rptr += ie->len;
1856 /*********************************************************************
1858 * End-to-end transit delay.
1860 * References for this IE are:
1862 * Q.2931 pp. 70...71
1863 * UNI4.0 pp. 69...70
1864 * PNNI1.0 pp. 198...200
1866 * Not clear, whether the new indicator should be used with NET coding or
1869 * Only ITU-T coding allowed.
1873 print_eetd(struct uni_ie_eetd *ie, struct unicx *cx)
1875 if (uni_print_iehdr("eetd", &ie->h, cx))
1878 if (ie->h.present & UNI_EETD_CUM_P)
1879 uni_print_entry(cx, "cum", "%u", ie->cumulative);
1880 if (ie->h.present & UNI_EETD_MAX_P) {
1881 if (ie->maximum == UNI_EETD_ANYMAX)
1882 uni_print_entry(cx, "max", "any");
1884 uni_print_entry(cx, "max", "%u", ie->maximum);
1886 if (ie->h.present & UNI_EETD_PCTD_P)
1887 uni_print_entry(cx, "pnni_cum", "%u", ie->pctd);
1888 if (ie->h.present & UNI_EETD_PMTD_P)
1889 uni_print_entry(cx, "pnni_max", "%u", ie->pmtd);
1890 if (ie->h.present & UNI_EETD_NET_P)
1891 uni_print_flag("netgen", cx);
1893 uni_print_ieend(cx);
1895 DEF_IE_PRINT(itu, eetd)
1899 DEF_IE_PRINT(net, eetd)
1904 DEF_IE_CHECK(itu, eetd)
1909 if (!(ie->h.present & UNI_EETD_CUM_P))
1911 if (ie->h.present & (UNI_EETD_PMTD_P | UNI_EETD_PCTD_P))
1916 DEF_IE_CHECK(net, eetd)
1920 if (!(ie->h.present & UNI_EETD_CUM_P))
1922 if (ie->h.present & (UNI_EETD_PMTD_P | UNI_EETD_PCTD_P))
1925 if (ie->h.present & UNI_EETD_MAX_P)
1927 if ((ie->h.present & UNI_EETD_CUM_P) &&
1928 (ie->h.present & UNI_EETD_PCTD_P))
1934 DEF_IE_ENCODE(itu, eetd)
1936 START_IE(eetd, UNI_IE_EETD, 9);
1938 if (ie->h.present & UNI_EETD_CUM_P) {
1939 APP_BYTE(msg, UNI_EETD_CTD_ID);
1940 APP_16BIT(msg, ie->cumulative);
1942 if (ie->h.present & UNI_EETD_MAX_P) {
1943 APP_BYTE(msg, UNI_EETD_MTD_ID);
1944 APP_16BIT(msg, ie->maximum);
1946 if (ie->h.present & UNI_EETD_PMTD_P) {
1947 APP_BYTE(msg, UNI_EETD_PMTD_ID);
1948 APP_24BIT(msg, ie->pmtd);
1950 if (ie->h.present & UNI_EETD_PCTD_P) {
1951 APP_BYTE(msg, UNI_EETD_PCTD_ID);
1952 APP_24BIT(msg, ie->pctd);
1954 if (ie->h.present & UNI_EETD_NET_P) {
1955 APP_BYTE(msg, UNI_EETD_NET_ID);
1962 DEF_IE_ENCODE(net, eetd)
1964 return (uni_ie_encode_itu_eetd(msg, ie, cx));
1967 DEF_IE_DECODE(itu, eetd)
1972 switch (ielen--, *msg->b_rptr++) {
1974 case UNI_EETD_CTD_ID:
1977 ie->h.present |= UNI_EETD_CUM_P;
1978 ie->cumulative = *msg->b_rptr++ << 8;
1979 ie->cumulative |= *msg->b_rptr++;
1983 case UNI_EETD_MTD_ID:
1986 ie->h.present |= UNI_EETD_MAX_P;
1987 ie->maximum = *msg->b_rptr++ << 8;
1988 ie->maximum |= *msg->b_rptr++;
1992 case UNI_EETD_PCTD_ID:
1995 ie->h.present |= UNI_EETD_PCTD_P;
1996 ie->pctd = *msg->b_rptr++ << 16;
1997 ie->pctd |= *msg->b_rptr++ << 8;
1998 ie->pctd |= *msg->b_rptr++;
2002 case UNI_EETD_PMTD_ID:
2005 ie->h.present |= UNI_EETD_PMTD_P;
2006 ie->pmtd = *msg->b_rptr++ << 16;
2007 ie->pmtd |= *msg->b_rptr++ << 8;
2008 ie->pmtd |= *msg->b_rptr++;
2012 case UNI_EETD_NET_ID:
2013 ie->h.present |= UNI_EETD_NET_P;
2023 DEF_IE_DECODE(net, eetd)
2025 return (uni_ie_decode_itu_eetd(ie, msg, ielen, cx));
2028 /*********************************************************************
2033 * Calling subaddress
2035 * Connected subaddress
2037 * References for this IE are:
2039 * Q.2931 pp. 60...68
2041 * UNI4.0 pp. 14...15
2042 * Q.2951 pp. 28...40
2044 * It is assumed, that the coding of the addr arrays is ok.
2046 * Only ITU-T coding allowed.
2049 static const struct uni_print_tbl screen_tbl[] = {
2050 MKT(UNI_ADDR_SCREEN_NOT, no),
2051 MKT(UNI_ADDR_SCREEN_PASSED, passed),
2052 MKT(UNI_ADDR_SCREEN_FAILED, failed),
2053 MKT(UNI_ADDR_SCREEN_NET, network),
2056 static const struct uni_print_tbl pres_tbl[] = {
2057 MKT(UNI_ADDR_PRES, allowed),
2058 MKT(UNI_ADDR_RESTRICT, restricted),
2059 MKT(UNI_ADDR_NONUMBER, no-number),
2065 print_addr(struct unicx *cx, struct uni_addr *addr)
2067 static const struct uni_print_tbl plan_tbl[] = {
2068 MKT(UNI_ADDR_UNKNOWN, unknown),
2069 MKT(UNI_ADDR_E164, E164),
2070 MKT(UNI_ADDR_ATME, ATME),
2071 MKT(UNI_ADDR_DATA, data),
2072 MKT(UNI_ADDR_PRIVATE, private),
2075 static const struct uni_print_tbl type_tbl[] = {
2076 MKT(UNI_ADDR_UNKNOWN, unknown),
2077 MKT(UNI_ADDR_INTERNATIONAL, international),
2078 MKT(UNI_ADDR_NATIONAL, national),
2079 MKT(UNI_ADDR_NETWORK, network),
2080 MKT(UNI_ADDR_SUBSCR, subscriber),
2081 MKT(UNI_ADDR_ABBR, abbreviated),
2086 uni_print_entry(cx, "addr", "(");
2087 uni_print_tbl(NULL, addr->type, type_tbl, cx);
2089 uni_print_tbl(NULL, addr->plan, plan_tbl, cx);
2091 if(addr->plan == UNI_ADDR_E164) {
2093 for(i = 0; i < addr->len; i++) {
2094 if(addr->addr[i] < ' ')
2095 uni_printf(cx, "^%c", addr->addr[i] + '@');
2096 else if(addr->addr[i] <= '~')
2097 uni_putc(addr->addr[i], cx);
2099 uni_printf(cx, "\\%03o", addr->addr[i]);
2103 } else if(addr->plan == UNI_ADDR_ATME) {
2104 for(i = 0; i < addr->len; i++)
2105 uni_printf(cx, "%02x", addr->addr[i]);
2111 print_addrsub(struct unicx *cx, struct uni_subaddr *addr)
2113 static const struct uni_print_tbl type_tbl[] = {
2114 MKT(UNI_SUBADDR_NSAP, NSAP),
2115 MKT(UNI_SUBADDR_ATME, ATME),
2116 MKT(UNI_SUBADDR_USER, USER),
2121 uni_print_entry(cx, "addr", "(");
2122 uni_print_tbl(NULL, addr->type, type_tbl, cx);
2125 for(i = 0; i < addr->len; i++)
2126 uni_printf(cx, "%02x", addr->addr[i]);
2132 check_addr(struct uni_addr *addr)
2136 switch(addr->plan) {
2141 if(addr->type != UNI_ADDR_INTERNATIONAL)
2143 if(addr->len > 15 || addr->len == 0)
2145 for(i = 0; i < addr->len; i++)
2146 if(addr->addr[i] == 0 || (addr->addr[i] & 0x80))
2151 if(addr->type != UNI_ADDR_UNKNOWN)
2162 check_subaddr(struct uni_subaddr *addr)
2164 switch(addr->type) {
2168 case UNI_SUBADDR_NSAP:
2173 case UNI_SUBADDR_ATME:
2182 check_screen(enum uni_addr_screen screen, enum uni_addr_pres pres)
2189 case UNI_ADDR_RESTRICT:
2190 case UNI_ADDR_NONUMBER:
2197 case UNI_ADDR_SCREEN_NOT:
2198 case UNI_ADDR_SCREEN_PASSED:
2199 case UNI_ADDR_SCREEN_FAILED:
2200 case UNI_ADDR_SCREEN_NET:
2208 encode_addr(struct uni_msg *msg, struct uni_addr *addr, u_int flag,
2209 enum uni_addr_screen screen, enum uni_addr_pres pres, int err)
2211 u_char ext = err ? 0x00 : 0x80;
2214 APP_BYTE(msg, (addr->type << 4) | addr->plan);
2215 APP_BYTE(msg, ext | (pres << 5) | (screen));
2217 APP_BYTE(msg, ext | (addr->type << 4) | addr->plan);
2219 APP_BUF(msg, addr->addr, addr->len);
2223 encode_subaddr(struct uni_msg *msg, struct uni_subaddr *addr)
2225 APP_BYTE(msg, 0x80|(addr->type<<4));
2226 APP_BUF(msg, addr->addr, addr->len);
2230 decode_addr(struct uni_addr *addr, u_int ielen, struct uni_msg *msg, u_int plan)
2232 addr->plan = plan & 0xf;
2233 addr->type = (plan >> 4) & 0x7;
2235 switch(addr->plan) {
2238 if(ielen > 15 || ielen == 0)
2240 addr->addr[ielen] = 0;
2251 (void)memcpy(addr->addr, msg->b_rptr, ielen);
2253 msg->b_rptr += ielen;
2259 decode_subaddr(struct uni_subaddr *addr, u_int ielen, struct uni_msg *msg,
2262 switch(addr->type = (type >> 4) & 0x7) {
2264 case UNI_SUBADDR_NSAP:
2265 if(ielen == 0 || ielen > 20)
2269 case UNI_SUBADDR_ATME:
2279 if((type & 0x7) != 0)
2283 (void)memcpy(addr->addr, msg->b_rptr, ielen);
2284 msg->b_rptr += ielen;
2289 /**********************************************************************/
2291 DEF_IE_PRINT(itu, called)
2293 if (uni_print_iehdr("called", &ie->h, cx))
2295 print_addr(cx, &ie->addr);
2296 uni_print_ieend(cx);
2299 DEF_IE_CHECK(itu, called)
2303 if (check_addr(&ie->addr))
2308 DEF_IE_ENCODE(itu, called)
2310 START_IE(called, UNI_IE_CALLED, 21);
2311 encode_addr(msg, &ie->addr, 0, 0, 0, IE_ISERROR(*ie));
2316 DEF_IE_DECODE(itu, called)
2321 if (ielen > 21 || ielen < 1)
2330 if (decode_addr(&ie->addr, ielen, msg, c))
2336 /**********************************************************************/
2338 DEF_IE_PRINT(itu, calledsub)
2340 if(uni_print_iehdr("calledsub", &ie->h, cx))
2342 print_addrsub(cx, &ie->addr);
2343 uni_print_ieend(cx);
2346 DEF_IE_CHECK(itu, calledsub)
2350 if(check_subaddr(&ie->addr))
2355 DEF_IE_ENCODE(itu, calledsub)
2357 START_IE(calledsub, UNI_IE_CALLEDSUB, 21);
2358 encode_subaddr(msg, &ie->addr);
2363 DEF_IE_DECODE(itu, calledsub)
2375 if(decode_subaddr(&ie->addr, ielen, msg, c))
2381 /**********************************************************************/
2383 DEF_IE_PRINT(itu, calling)
2385 if(uni_print_iehdr("calling", &ie->h, cx))
2387 print_addr(cx, &ie->addr);
2389 if(ie->h.present & UNI_CALLING_SCREEN_P) {
2390 uni_print_tbl("screening", ie->screen, screen_tbl, cx);
2391 uni_print_tbl("presentation", ie->pres, pres_tbl, cx);
2394 uni_print_ieend(cx);
2397 DEF_IE_CHECK(itu, calling)
2401 if(check_addr(&ie->addr))
2404 if(ie->h.present & UNI_CALLING_SCREEN_P)
2405 if(check_screen(ie->screen, ie->pres))
2410 DEF_IE_ENCODE(itu, calling)
2412 START_IE(calling, UNI_IE_CALLING, 22);
2413 encode_addr(msg, &ie->addr, ie->h.present & UNI_CALLING_SCREEN_P, ie->screen, ie->pres, IE_ISERROR(*ie));
2418 DEF_IE_DECODE(itu, calling)
2424 if(ielen > 22 || ielen < 1)
2427 plan = *msg->b_rptr++;
2430 if(!(plan & 0x80)) {
2436 ie->h.present |= UNI_CALLING_SCREEN_P;
2437 ie->pres = (c >> 5) & 0x3;
2438 ie->screen = c & 0x3;
2444 if(decode_addr(&ie->addr, ielen, msg, plan))
2450 /**********************************************************************/
2452 DEF_IE_PRINT(itu, callingsub)
2454 if(uni_print_iehdr("callingsub", &ie->h, cx))
2456 print_addrsub(cx, &ie->addr);
2457 uni_print_ieend(cx);
2460 DEF_IE_CHECK(itu, callingsub)
2464 if(check_subaddr(&ie->addr))
2469 DEF_IE_ENCODE(itu, callingsub)
2471 START_IE(callingsub, UNI_IE_CALLINGSUB, 21);
2472 encode_subaddr(msg, &ie->addr);
2477 DEF_IE_DECODE(itu, callingsub)
2489 if(decode_subaddr(&ie->addr, ielen, msg, c))
2495 /**********************************************************************/
2497 DEF_IE_PRINT(itu, conned)
2499 if(uni_print_iehdr("conned", &ie->h, cx))
2501 print_addr(cx, &ie->addr);
2503 if(ie->h.present & UNI_CONNED_SCREEN_P) {
2504 uni_print_tbl("screening", ie->screen, screen_tbl, cx);
2505 uni_print_tbl("presentation", ie->pres, pres_tbl, cx);
2508 uni_print_ieend(cx);
2511 DEF_IE_CHECK(itu, conned)
2515 if(check_addr(&ie->addr))
2518 if(ie->h.present & UNI_CONNED_SCREEN_P)
2519 if(check_screen(ie->screen, ie->pres))
2524 DEF_IE_ENCODE(itu, conned)
2526 START_IE(conned, UNI_IE_CONNED, 22);
2527 encode_addr(msg, &ie->addr, ie->h.present & UNI_CONNED_SCREEN_P, ie->screen, ie->pres, IE_ISERROR(*ie));
2532 DEF_IE_DECODE(itu, conned)
2538 if(ielen > 22 || ielen < 1)
2541 plan = *msg->b_rptr++;
2544 if(!(plan & 0x80)) {
2550 ie->h.present |= UNI_CONNED_SCREEN_P;
2551 ie->pres = (c >> 5) & 0x3;
2552 ie->screen = c & 0x3;
2558 if(decode_addr(&ie->addr, ielen, msg, plan))
2564 /**********************************************************************/
2566 DEF_IE_PRINT(itu, connedsub)
2568 if(uni_print_iehdr("connedsub", &ie->h, cx))
2570 print_addrsub(cx, &ie->addr);
2571 uni_print_ieend(cx);
2574 DEF_IE_CHECK(itu, connedsub)
2578 if(check_subaddr(&ie->addr))
2583 DEF_IE_ENCODE(itu, connedsub)
2585 START_IE(connedsub, UNI_IE_CONNEDSUB, 21);
2586 encode_subaddr(msg, &ie->addr);
2591 DEF_IE_DECODE(itu, connedsub)
2603 if(decode_subaddr(&ie->addr, ielen, msg, c))
2609 /*********************************************************************
2611 * Endpoint reference.
2613 * References for this IE are:
2617 * Only ITU-T coding allowed.
2620 DEF_IE_PRINT(itu, epref)
2622 if(uni_print_iehdr("epref", &ie->h, cx))
2624 uni_print_entry(cx, "epref", "(%u,%u)", ie->flag, ie->epref);
2625 uni_print_ieend(cx);
2628 DEF_IE_CHECK(itu, epref)
2632 if(ie->epref >= (2<<15))
2638 DEF_IE_ENCODE(itu, epref)
2640 START_IE(epref, UNI_IE_EPREF, 3);
2642 if (IE_ISERROR(*ie))
2643 APP_BYTE(msg, 0xff);
2646 APP_BYTE(msg, (ie->flag << 7) | ((ie->epref >> 8) & 0x7f));
2647 APP_BYTE(msg, (ie->epref & 0xff));
2653 DEF_IE_DECODE(itu, epref)
2661 if(*msg->b_rptr++ != 0)
2665 ie->flag = (c & 0x80) ? 1 : 0;
2666 ie->epref = (c & 0x7f) << 8;
2667 ie->epref |= *msg->b_rptr++;
2672 /*********************************************************************
2676 * References for this IE are:
2678 * Q.2971 pp. 14...15
2680 * Only ITU-T coding allowed.
2683 DEF_IE_PRINT(itu, epstate)
2685 static const struct uni_print_tbl tbl[] = {
2686 MKT(UNI_EPSTATE_NULL, null),
2687 MKT(UNI_EPSTATE_ADD_INIT, add-initiated),
2688 MKT(UNI_EPSTATE_ALERT_DLVD, alerting-delivered),
2689 MKT(UNI_EPSTATE_ADD_RCVD, add-received),
2690 MKT(UNI_EPSTATE_ALERT_RCVD, alerting-received),
2691 MKT(UNI_EPSTATE_ACTIVE, active),
2692 MKT(UNI_EPSTATE_DROP_INIT, drop-initiated),
2693 MKT(UNI_EPSTATE_DROP_RCVD, drop-received),
2697 if(uni_print_iehdr("epstate", &ie->h, cx))
2699 uni_print_tbl("state", ie->state, tbl, cx);
2700 uni_print_ieend(cx);
2703 DEF_IE_CHECK(itu, epstate)
2711 case UNI_EPSTATE_NULL:
2712 case UNI_EPSTATE_ADD_INIT:
2713 case UNI_EPSTATE_ALERT_DLVD:
2714 case UNI_EPSTATE_ADD_RCVD:
2715 case UNI_EPSTATE_ALERT_RCVD:
2716 case UNI_EPSTATE_DROP_INIT:
2717 case UNI_EPSTATE_DROP_RCVD:
2718 case UNI_EPSTATE_ACTIVE:
2725 DEF_IE_ENCODE(itu, epstate)
2727 START_IE(epstate, UNI_IE_EPSTATE, 1);
2729 APP_BYTE(msg, ie->state);
2735 DEF_IE_DECODE(itu, epstate)
2742 ie->state = *msg->b_rptr++ & 0x3f;
2747 /*********************************************************************
2749 * ATM adaptation layer parameters
2751 * References for this IE are:
2753 * Q.2931 pp. 43...49
2757 * UNI4.0 states, that AAL2 is not supported. However we keep it. No
2758 * parameters are associated with AAL2.
2760 * Amd2 not checked. XXX
2762 * Only ITU-T coding allowed.
2764 DEF_IE_PRINT(itu, aal)
2766 static const struct uni_print_tbl aal_tbl[] = {
2767 MKT(UNI_AAL_0, VOICE),
2770 MKT(UNI_AAL_4, 3/4),
2772 MKT(UNI_AAL_USER, USER),
2775 static const struct uni_print_tbl subtype_tbl[] = {
2776 MKT(UNI_AAL1_SUB_NULL, null),
2777 MKT(UNI_AAL1_SUB_VOICE, voice),
2778 MKT(UNI_AAL1_SUB_CIRCUIT, circuit),
2779 MKT(UNI_AAL1_SUB_HQAUDIO, hqaudio),
2780 MKT(UNI_AAL1_SUB_VIDEO, video),
2783 static const struct uni_print_tbl cbr_rate_tbl[] = {
2784 MKT(UNI_AAL1_CBR_64, 64),
2785 MKT(UNI_AAL1_CBR_1544, 1544(DS1)),
2786 MKT(UNI_AAL1_CBR_6312, 6312(DS2)),
2787 MKT(UNI_AAL1_CBR_32064, 32064),
2788 MKT(UNI_AAL1_CBR_44736, 44736(DS3)),
2789 MKT(UNI_AAL1_CBR_97728, 97728),
2790 MKT(UNI_AAL1_CBR_2048, 2048(E1)),
2791 MKT(UNI_AAL1_CBR_8448, 8448(E2)),
2792 MKT(UNI_AAL1_CBR_34368, 34368(E3)),
2793 MKT(UNI_AAL1_CBR_139264, 139264),
2794 MKT(UNI_AAL1_CBR_N64, Nx64),
2795 MKT(UNI_AAL1_CBR_N8, Nx8),
2798 static const struct uni_print_tbl screc_tbl[] = {
2799 MKT(UNI_AAL1_SCREC_NULL, null),
2800 MKT(UNI_AAL1_SCREC_SRTS, srts),
2801 MKT(UNI_AAL1_SCREC_ACLK, aclk),
2804 static const struct uni_print_tbl ecm_tbl[] = {
2805 MKT(UNI_AAL1_ECM_NULL, null),
2806 MKT(UNI_AAL1_ECM_LOSS, loss),
2807 MKT(UNI_AAL1_ECM_DELAY, delay),
2810 static const struct uni_print_tbl sscs_tbl[] = {
2811 MKT(UNI_AAL_SSCS_NULL, null),
2812 MKT(UNI_AAL_SSCS_SSCOPA, sscopa),
2813 MKT(UNI_AAL_SSCS_SSCOPU, sscopu),
2814 MKT(UNI_AAL_SSCS_FRAME, frame),
2818 if(uni_print_iehdr("aal", &ie->h, cx))
2820 uni_print_tbl("type", ie->type, aal_tbl, cx);
2825 uni_print_push_prefix("0", cx);
2830 uni_print_push_prefix("2", cx);
2835 uni_print_push_prefix("1", cx);
2837 uni_print_tbl("subtype", ie->u.aal1.subtype, subtype_tbl, cx);
2838 uni_print_tbl("cbr_rate", ie->u.aal1.cbr_rate, cbr_rate_tbl, cx);
2839 if(ie->h.present & UNI_AAL1_MULT_P)
2840 uni_print_entry(cx, "mult", "%u", ie->u.aal1.mult);
2841 if(ie->h.present & UNI_AAL1_SCREC_P)
2842 uni_print_tbl("screc", ie->u.aal1.screc, screc_tbl, cx);
2843 if(ie->h.present & UNI_AAL1_ECM_P)
2844 uni_print_tbl("ecm", ie->u.aal1.ecm, ecm_tbl, cx);
2845 if(ie->h.present & UNI_AAL1_BSIZE_P)
2846 uni_print_entry(cx, "bsize", "%u", ie->u.aal1.bsize);
2847 if(ie->h.present & UNI_AAL1_PART_P)
2848 uni_print_entry(cx, "part", "%u", ie->u.aal1.part);
2852 uni_print_push_prefix("4", cx);
2854 if(ie->h.present & UNI_AAL4_CPCS_P)
2855 uni_print_entry(cx, "cpcs", "(%u,%u)", ie->u.aal4.fwd_cpcs,
2856 ie->u.aal4.bwd_cpcs);
2857 if(ie->h.present & UNI_AAL4_MID_P)
2858 uni_print_entry(cx, "mid", "(%u,%u)", ie->u.aal4.mid_low,
2859 ie->u.aal4.mid_high);
2860 if(ie->h.present & UNI_AAL4_SSCS_P)
2861 uni_print_tbl("sscs", ie->u.aal4.sscs, sscs_tbl, cx);
2865 uni_print_push_prefix("5", cx);
2867 if(ie->h.present & UNI_AAL5_CPCS_P)
2868 uni_print_entry(cx, "cpcs", "(%u,%u)", ie->u.aal5.fwd_cpcs,
2869 ie->u.aal5.bwd_cpcs);
2870 if(ie->h.present & UNI_AAL5_SSCS_P)
2871 uni_print_tbl("sscs", ie->u.aal5.sscs, sscs_tbl, cx);
2875 uni_print_push_prefix("user", cx);
2877 if(ie->u.aalu.len > 4) {
2878 uni_print_entry(cx, "info", "ERROR(len=%u)", ie->u.aalu.len);
2882 uni_print_entry(cx, "info", "(");
2883 for(i = 0; i < ie->u.aalu.len; i++)
2884 uni_printf(cx, "%s%u", !i?"":",", ie->u.aalu.user[i]);
2885 uni_printf(cx, ")");
2890 uni_print_pop_prefix(cx);
2893 uni_print_ieend(cx);
2896 DEF_IE_CHECK(itu, aal)
2900 if(ie->type == UNI_AAL_0) {
2902 } else if(ie->type == UNI_AAL_1) {
2903 switch(ie->u.aal1.subtype) {
2908 case UNI_AAL1_SUB_NULL:
2909 case UNI_AAL1_SUB_VOICE:
2910 case UNI_AAL1_SUB_CIRCUIT:
2911 case UNI_AAL1_SUB_HQAUDIO:
2912 case UNI_AAL1_SUB_VIDEO:
2915 switch(ie->u.aal1.cbr_rate) {
2920 case UNI_AAL1_CBR_64:
2921 case UNI_AAL1_CBR_1544:
2922 case UNI_AAL1_CBR_6312:
2923 case UNI_AAL1_CBR_32064:
2924 case UNI_AAL1_CBR_44736:
2925 case UNI_AAL1_CBR_97728:
2926 case UNI_AAL1_CBR_2048:
2927 case UNI_AAL1_CBR_8448:
2928 case UNI_AAL1_CBR_34368:
2929 case UNI_AAL1_CBR_139264:
2930 if((ie->h.present & UNI_AAL1_MULT_P))
2934 case UNI_AAL1_CBR_N64:
2935 if(!(ie->h.present & UNI_AAL1_MULT_P))
2937 if(ie->u.aal1.mult < 2)
2941 case UNI_AAL1_CBR_N8:
2942 if(!(ie->h.present & UNI_AAL1_MULT_P))
2944 if(ie->u.aal1.mult == 0 || ie->u.aal1.mult > 7)
2948 if(ie->h.present & UNI_AAL1_SCREC_P) {
2949 switch(ie->u.aal1.screc) {
2954 case UNI_AAL1_SCREC_NULL:
2955 case UNI_AAL1_SCREC_SRTS:
2956 case UNI_AAL1_SCREC_ACLK:
2960 if(ie->h.present & UNI_AAL1_ECM_P) {
2961 switch(ie->u.aal1.ecm) {
2966 case UNI_AAL1_ECM_NULL:
2967 case UNI_AAL1_ECM_LOSS:
2968 case UNI_AAL1_ECM_DELAY:
2972 if(ie->h.present & UNI_AAL1_BSIZE_P) {
2973 if(ie->u.aal1.bsize == 0)
2976 if(ie->h.present & UNI_AAL1_PART_P) {
2977 if(ie->u.aal1.part == 0 || ie->u.aal1.part > 47)
2981 } else if(ie->type == UNI_AAL_2) {
2984 } else if(ie->type == UNI_AAL_4) {
2985 if(ie->h.present & UNI_AAL4_MID_P) {
2986 if(ie->u.aal4.mid_low >= 1024)
2988 if(ie->u.aal4.mid_high >= 1024)
2990 if(ie->u.aal4.mid_low > ie->u.aal4.mid_high)
2993 if(ie->h.present & UNI_AAL4_SSCS_P) {
2994 switch(ie->u.aal4.sscs) {
2999 case UNI_AAL_SSCS_NULL:
3000 case UNI_AAL_SSCS_SSCOPA:
3001 case UNI_AAL_SSCS_SSCOPU:
3002 case UNI_AAL_SSCS_FRAME:
3007 } else if(ie->type == UNI_AAL_5) {
3008 if(ie->h.present & UNI_AAL5_SSCS_P) {
3009 switch(ie->u.aal5.sscs) {
3014 case UNI_AAL_SSCS_NULL:
3015 case UNI_AAL_SSCS_SSCOPA:
3016 case UNI_AAL_SSCS_SSCOPU:
3017 case UNI_AAL_SSCS_FRAME:
3022 } else if(ie->type == UNI_AAL_USER) {
3023 if(ie->u.aalu.len > 4)
3032 DEF_IE_ENCODE(itu, aal)
3034 START_IE(aal, UNI_IE_AAL, 16);
3036 APP_BYTE(msg, ie->type);
3044 UNI_AAL_SUB_ID, ie->u.aal1.subtype);
3046 UNI_AAL_CBR_ID, ie->u.aal1.cbr_rate);
3047 APP_OPT_16BIT(msg, ie->h.present, UNI_AAL1_MULT_P,
3048 UNI_AAL_MULT_ID, ie->u.aal1.mult);
3049 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_SCREC_P,
3050 UNI_AAL_SCREC_ID, ie->u.aal1.screc);
3051 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_ECM_P,
3052 UNI_AAL_ECM_ID, ie->u.aal1.ecm);
3053 APP_OPT_16BIT(msg, ie->h.present, UNI_AAL1_BSIZE_P,
3054 UNI_AAL_BSIZE_ID, ie->u.aal1.bsize);
3055 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_PART_P,
3056 UNI_AAL_PART_ID, ie->u.aal1.part);
3063 if(ie->h.present & UNI_AAL4_CPCS_P) {
3065 UNI_AAL_FWDCPCS_ID, ie->u.aal4.fwd_cpcs);
3067 UNI_AAL_BWDCPCS_ID, ie->u.aal4.bwd_cpcs);
3069 if(ie->h.present & UNI_AAL4_MID_P) {
3070 APP_BYTE(msg, UNI_AAL_MID_ID);
3071 APP_16BIT(msg, ie->u.aal4.mid_low);
3072 APP_16BIT(msg, ie->u.aal4.mid_high);
3074 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL4_SSCS_P,
3075 UNI_AAL_SSCS_ID, ie->u.aal4.sscs);
3079 if(ie->h.present & UNI_AAL5_CPCS_P) {
3081 UNI_AAL_FWDCPCS_ID, ie->u.aal5.fwd_cpcs);
3083 UNI_AAL_BWDCPCS_ID, ie->u.aal5.bwd_cpcs);
3085 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL5_SSCS_P,
3086 UNI_AAL_SSCS_ID, ie->u.aal5.sscs);
3090 APP_BUF(msg, ie->u.aalu.user, ie->u.aalu.len);
3102 * XXX What should we do with multiple subtype occurences? Ignore
3103 * or reject. Currently we reject.
3106 decode_aal_1(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3108 int subtype_p, cbr_p;
3110 subtype_p = cbr_p = 0;
3112 while(ielen-- > 0) {
3113 switch(*msg->b_rptr++) {
3115 case UNI_AAL_SUB_ID:
3116 if(ielen == 0 || subtype_p)
3120 ie->u.aal1.subtype = *msg->b_rptr++;
3123 case UNI_AAL_CBR_ID:
3124 if(ielen == 0 || cbr_p)
3128 ie->u.aal1.cbr_rate = *msg->b_rptr++;
3131 case UNI_AAL_MULT_ID:
3132 if(ielen < 2 || (ie->h.present & UNI_AAL1_MULT_P))
3135 ie->h.present |= UNI_AAL1_MULT_P;
3136 ie->u.aal1.mult = *msg->b_rptr++ << 8;
3137 ie->u.aal1.mult |= *msg->b_rptr++;
3140 case UNI_AAL_SCREC_ID:
3141 if(ielen == 0 || (ie->h.present & UNI_AAL1_SCREC_P))
3144 ie->h.present |= UNI_AAL1_SCREC_P;
3145 ie->u.aal1.screc = *msg->b_rptr++;
3148 case UNI_AAL_ECM_ID:
3149 if(ielen == 0 || (ie->h.present & UNI_AAL1_ECM_P))
3152 ie->h.present |= UNI_AAL1_ECM_P;
3153 ie->u.aal1.ecm = *msg->b_rptr++;
3156 case UNI_AAL_BSIZE_ID:
3157 if(ielen < 2 || (ie->h.present & UNI_AAL1_BSIZE_P))
3160 ie->h.present |= UNI_AAL1_BSIZE_P;
3161 ie->u.aal1.bsize = *msg->b_rptr++ << 8;
3162 ie->u.aal1.bsize |= *msg->b_rptr++;
3165 case UNI_AAL_PART_ID:
3166 if(ielen == 0 || (ie->h.present & UNI_AAL1_PART_P))
3169 ie->h.present |= UNI_AAL1_PART_P;
3170 ie->u.aal1.part = *msg->b_rptr++;
3177 if(!subtype_p || !cbr_p)
3184 decode_aal_4(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3186 int fcpcs_p, bcpcs_p;
3188 fcpcs_p = bcpcs_p = 0;
3190 while(ielen-- > 0) {
3191 switch(*msg->b_rptr++) {
3193 case UNI_AAL_FWDCPCS_ID:
3194 if(ielen < 2 || fcpcs_p)
3198 ie->u.aal4.fwd_cpcs = *msg->b_rptr++ << 8;
3199 ie->u.aal4.fwd_cpcs |= *msg->b_rptr++;
3202 case UNI_AAL_BWDCPCS_ID:
3203 if(ielen < 2 || bcpcs_p)
3207 ie->u.aal4.bwd_cpcs = *msg->b_rptr++ << 8;
3208 ie->u.aal4.bwd_cpcs |= *msg->b_rptr++;
3211 case UNI_AAL_MID_ID:
3212 if(ielen < 4 || (ie->h.present & UNI_AAL4_MID_P))
3215 ie->h.present |= UNI_AAL4_MID_P;
3216 ie->u.aal4.mid_low = *msg->b_rptr++ << 8;
3217 ie->u.aal4.mid_low |= *msg->b_rptr++;
3218 ie->u.aal4.mid_high = *msg->b_rptr++ << 8;
3219 ie->u.aal4.mid_high |= *msg->b_rptr++;
3222 case UNI_AAL_SSCS_ID:
3223 if(ielen == 0 || (ie->h.present & UNI_AAL4_SSCS_P))
3226 ie->h.present |= UNI_AAL4_SSCS_P;
3227 ie->u.aal4.sscs = *msg->b_rptr++;
3235 if(fcpcs_p ^ bcpcs_p)
3238 ie->h.present |= UNI_AAL4_CPCS_P;
3244 decode_aal_5(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3246 int fcpcs_p, bcpcs_p;
3248 fcpcs_p = bcpcs_p = 0;
3250 while(ielen-- > 0) {
3251 switch(*msg->b_rptr++) {
3253 case UNI_AAL_FWDCPCS_ID:
3254 if(ielen < 2 || fcpcs_p)
3258 ie->u.aal5.fwd_cpcs = *msg->b_rptr++ << 8;
3259 ie->u.aal5.fwd_cpcs |= *msg->b_rptr++;
3262 case UNI_AAL_BWDCPCS_ID:
3263 if(ielen < 2 || bcpcs_p)
3267 ie->u.aal5.bwd_cpcs = *msg->b_rptr++ << 8;
3268 ie->u.aal5.bwd_cpcs |= *msg->b_rptr++;
3271 case UNI_AAL_SSCS_ID:
3272 if(ielen == 0 || (ie->h.present & UNI_AAL5_SSCS_P))
3275 ie->h.present |= UNI_AAL5_SSCS_P;
3276 ie->u.aal5.sscs = *msg->b_rptr++;
3284 if(fcpcs_p ^ bcpcs_p)
3287 ie->h.present |= UNI_AAL5_CPCS_P;
3293 decode_aal_user(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3300 ie->u.aalu.user[ie->u.aalu.len++] = *msg->b_rptr++;
3305 DEF_IE_DECODE(itu, aal)
3309 IE_START(DISC_ACC_ERR(AAL));
3311 if(ielen < 1 || ielen > 21)
3325 if(decode_aal_1(ie, msg, ielen))
3335 if(decode_aal_4(ie, msg, ielen))
3341 if(decode_aal_5(ie, msg, ielen))
3347 if(decode_aal_user(ie, msg, ielen))
3358 /*********************************************************************
3360 * Traffic descriptor.
3361 * Alternate traffic descriptor.
3362 * Minimum traffic descriptor.
3364 * References for this IE are:
3366 * Q.2931 pp. 49...51
3369 * UNI4.0 pp. 9...10, 106...109
3371 * The Q.s specify the coding. UNI4.0 adds frame discard and best-effort.
3372 * Appendix in UNI4.0 lists the allowed combinations.
3374 * PCR0 PCR1 SCR/MBS0 SCR/MBS1 BE TAG FDISC ABR
3375 * 1 CBR.1 - Y - - - N Y/N -
3376 * 2 CBR.2 - Y - - - N Y/N - (*)
3377 * 3 CBR.3 Y Y - - - Y Y/N - (*)
3378 * 4 rt-VBR.1 - Y - Y - N Y/N -
3379 * 5 rt-VBR.2 - Y Y - - N Y/N -
3380 * 6 rt-VBR.3 - Y Y - - Y Y/N -
3381 * 7 rt-VBR.4 Y Y - - - Y/N Y/N - (*)
3382 * 8 rt-VBR.5 - Y - - - N Y/N - (*)
3383 * 9 rt-VBR.6 - Y - Y - N Y/N - (*)
3384 * 10 nrt-VBR.1 - Y - Y - N Y/N -
3385 * 11 nrt-VBR.2 - Y Y - - N Y/N -
3386 * 12 nrt-VBR.3 - Y Y - - Y Y/N -
3387 * 13 nrt-VBR.4 Y Y - - - Y/N Y/N - (*)
3388 * 14 nrt-VBR.5 - Y - - - N Y/N - (*)
3389 * 15 nrt-VBR.6 - Y - Y - N Y/N - (*)
3390 * 16 ABR - Y - - - N Y/N O (*)
3391 * 17 UBR.1 - Y - - Y N Y/N -
3392 * 18 UBR.2 - Y - - Y Y Y/N -
3394 * Allow ITU-T and NET coding, because its not clear, whether the
3395 * new fields in UNI4.0 should be used with NET coding or not.
3396 * Does not allow for experimental codings yet.
3400 print_ie_traffic_common(struct unicx *cx, u_int present, struct uni_xtraffic *ie)
3402 uni_print_entry(cx, "fwd", "(");
3403 if(present & UNI_TRAFFIC_FPCR0_P)
3404 uni_printf(cx, "%u", ie->fpcr0);
3406 if(present & UNI_TRAFFIC_FPCR1_P)
3407 uni_printf(cx, "%u", ie->fpcr1);
3409 if(present & UNI_TRAFFIC_FSCR0_P)
3410 uni_printf(cx, "%u", ie->fscr0);
3412 if(present & UNI_TRAFFIC_FSCR1_P)
3413 uni_printf(cx, "%u", ie->fscr1);
3415 if(present & UNI_TRAFFIC_FMBS0_P)
3416 uni_printf(cx, "%u", ie->fmbs0);
3418 if(present & UNI_TRAFFIC_FMBS1_P)
3419 uni_printf(cx, "%u", ie->fmbs1);
3421 if(present & UNI_TRAFFIC_FABR1_P)
3422 uni_printf(cx, "%u", ie->fabr1);
3423 uni_printf(cx, ")");
3425 uni_print_entry(cx, "bwd", "(");
3426 if(present & UNI_TRAFFIC_BPCR0_P)
3427 uni_printf(cx, "%u", ie->bpcr0);
3429 if(present & UNI_TRAFFIC_BPCR1_P)
3430 uni_printf(cx, "%u", ie->bpcr1);
3432 if(present & UNI_TRAFFIC_BSCR0_P)
3433 uni_printf(cx, "%u", ie->bscr0);
3435 if(present & UNI_TRAFFIC_BSCR1_P)
3436 uni_printf(cx, "%u", ie->bscr1);
3438 if(present & UNI_TRAFFIC_BMBS0_P)
3439 uni_printf(cx, "%u", ie->bmbs0);
3441 if(present & UNI_TRAFFIC_BMBS1_P)
3442 uni_printf(cx, "%u", ie->bmbs1);
3444 if(present & UNI_TRAFFIC_BABR1_P)
3445 uni_printf(cx, "%u", ie->babr1);
3446 uni_printf(cx, ")");
3448 if(present & UNI_TRAFFIC_BEST_P)
3449 uni_print_flag("best_effort", cx);
3450 if(present & UNI_TRAFFIC_MOPT_P) {
3451 uni_print_entry(cx, "tag", "(");
3453 uni_printf(cx, "fwd");
3456 uni_printf(cx, "bwd");
3459 uni_print_entry(cx, "disc", "(");
3461 uni_printf(cx, "fwd");
3464 uni_printf(cx, "bwd");
3472 u_char mopt_mask, mopt_val;
3476 check_traffic(u_int mask, u_int mopt, struct tallow *a)
3481 if(a->mopt_flag == 0) {
3488 if(a->mopt_flag < 0) {
3492 if((mopt & a->mopt_mask) == a->mopt_val)
3500 if((mopt & a->mopt_mask) == a->mopt_val)
3506 check_ie_traffic_common(struct uni_xtraffic *ie, u_int present,
3507 struct unicx *cx __unused)
3509 static u_int fmask =
3510 UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P |
3511 UNI_TRAFFIC_FSCR0_P | UNI_TRAFFIC_FSCR1_P |
3512 UNI_TRAFFIC_FMBS0_P | UNI_TRAFFIC_FMBS1_P |
3513 UNI_TRAFFIC_FABR1_P;
3514 static u_int bmask =
3515 UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P |
3516 UNI_TRAFFIC_BSCR0_P | UNI_TRAFFIC_BSCR1_P |
3517 UNI_TRAFFIC_BMBS0_P | UNI_TRAFFIC_BMBS1_P |
3518 UNI_TRAFFIC_BABR1_P;
3521 -1, U##X##TAG, 0 }, /* 1, 2, 8, 14 */ \
3522 { U##X##PCR0_P | U##X##PCR1_P, \
3523 +1, U##X##TAG, U##X##TAG }, /* 3 */ \
3524 { U##X##PCR1_P | U##X##SCR1_P | U##X##MBS1_P, \
3525 -1, U##X##TAG, 0 }, /* 4, 9, 10, 15 */ \
3526 { U##X##PCR1_P | U##X##SCR0_P | U##X##MBS0_P, \
3527 -1, 0, 0 }, /* 5, 6, 11, 12 */ \
3528 { U##X##PCR0_P | U##X##PCR1_P, \
3529 -1, 0, 0 }, /* 7, 13 */ \
3530 { U##X##PCR1_P | U##X##ABR1_P, \
3531 -1, U##X##TAG, 0 }, /* 16a */
3534 static struct tallow allow[2][DTABSIZE] = {
3535 { DTAB(UNI_TRAFFIC_, F) },
3536 { DTAB(UNI_TRAFFIC_, B) },
3543 f = present & fmask;
3544 b = present & bmask;
3545 p = present & (fmask | bmask);
3546 m = (present & UNI_TRAFFIC_MOPT_P)
3547 ? ( (ie->ftag ? UNI_TRAFFIC_FTAG : 0)
3548 | (ie->btag ? UNI_TRAFFIC_BTAG : 0)
3549 | (ie->fdisc ? UNI_TRAFFIC_FDISC : 0)
3550 | (ie->bdisc ? UNI_TRAFFIC_BDISC : 0))
3554 if(present & UNI_TRAFFIC_BEST_P) {
3558 if(p != (UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_BPCR1_P))
3564 * Check forward and backward independent. There must be a higher
3565 * level checking in the CAC
3567 for(i = 0; i < DTABSIZE; i++)
3568 if(check_traffic(f, m, &allow[0][i]))
3573 for(i = 0; i < DTABSIZE; i++)
3574 if(check_traffic(b, m, &allow[1][i]))
3583 encode_traffic_common(struct uni_msg *msg, struct uni_xtraffic *ie,
3584 u_int present, struct unicx *cx __unused)
3586 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FPCR0_P,
3587 UNI_TRAFFIC_FPCR0_ID, ie->fpcr0);
3588 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BPCR0_P,
3589 UNI_TRAFFIC_BPCR0_ID, ie->bpcr0);
3590 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FPCR1_P,
3591 UNI_TRAFFIC_FPCR1_ID, ie->fpcr1);
3592 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BPCR1_P,
3593 UNI_TRAFFIC_BPCR1_ID, ie->bpcr1);
3594 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FSCR0_P,
3595 UNI_TRAFFIC_FSCR0_ID, ie->fscr0);
3596 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BSCR0_P,
3597 UNI_TRAFFIC_BSCR0_ID, ie->bscr0);
3598 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FSCR1_P,
3599 UNI_TRAFFIC_FSCR1_ID, ie->fscr1);
3600 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BSCR1_P,
3601 UNI_TRAFFIC_BSCR1_ID, ie->bscr1);
3602 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FMBS0_P,
3603 UNI_TRAFFIC_FMBS0_ID, ie->fmbs0);
3604 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BMBS0_P,
3605 UNI_TRAFFIC_BMBS0_ID, ie->bmbs0);
3606 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FMBS1_P,
3607 UNI_TRAFFIC_FMBS1_ID, ie->fmbs1);
3608 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BMBS1_P,
3609 UNI_TRAFFIC_BMBS1_ID, ie->bmbs1);
3610 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FABR1_P,
3611 UNI_TRAFFIC_FABR1_ID, ie->fabr1);
3612 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BABR1_P,
3613 UNI_TRAFFIC_BABR1_ID, ie->babr1);
3615 APP_OPT(msg, present, UNI_TRAFFIC_BEST_P,
3616 UNI_TRAFFIC_BEST_ID);
3617 APP_OPT_BYTE(msg, present, UNI_TRAFFIC_MOPT_P,
3618 UNI_TRAFFIC_MOPT_ID,
3619 (ie->ftag ? UNI_TRAFFIC_FTAG : 0) |
3620 (ie->btag ? UNI_TRAFFIC_BTAG : 0) |
3621 (ie->fdisc ? UNI_TRAFFIC_FDISC : 0) |
3622 (ie->fdisc ? UNI_TRAFFIC_BDISC : 0));
3628 decode_traffic_common(struct uni_xtraffic *ie, struct uni_msg *msg,
3629 u_int ielen, u_int *present)
3634 switch(c = *msg->b_rptr++) {
3640 DEC_GETF3(TRAFFIC_FPCR0, fpcr0, *present);
3641 DEC_GETF3(TRAFFIC_BPCR0, bpcr0, *present);
3642 DEC_GETF3(TRAFFIC_FPCR1, fpcr1, *present);
3643 DEC_GETF3(TRAFFIC_BPCR1, bpcr1, *present);
3644 DEC_GETF3(TRAFFIC_FSCR0, fscr0, *present);
3645 DEC_GETF3(TRAFFIC_BSCR0, bscr0, *present);
3646 DEC_GETF3(TRAFFIC_FSCR1, fscr1, *present);
3647 DEC_GETF3(TRAFFIC_BSCR1, bscr1, *present);
3648 DEC_GETF3(TRAFFIC_FMBS0, fmbs0, *present);
3649 DEC_GETF3(TRAFFIC_BMBS0, bmbs0, *present);
3650 DEC_GETF3(TRAFFIC_BMBS1, bmbs1, *present);
3651 DEC_GETF3(TRAFFIC_FABR1, fabr1, *present);
3652 DEC_GETF3(TRAFFIC_BABR1, babr1, *present);
3654 case UNI_TRAFFIC_BEST_ID:
3655 *present |= UNI_TRAFFIC_BEST_P;
3658 case UNI_TRAFFIC_MOPT_ID:
3662 if(!(*present & UNI_TRAFFIC_MOPT_P)) {
3663 *present |= UNI_TRAFFIC_MOPT_P;
3664 ie->ftag = (*msg->b_rptr&UNI_TRAFFIC_FTAG)?1:0;
3665 ie->btag = (*msg->b_rptr&UNI_TRAFFIC_BTAG)?1:0;
3666 ie->fdisc = (*msg->b_rptr&UNI_TRAFFIC_FDISC)?1:0;
3667 ie->bdisc = (*msg->b_rptr&UNI_TRAFFIC_BDISC)?1:0;
3677 /*****************************************************************/
3679 DEF_IE_PRINT(itu, traffic)
3681 if(uni_print_iehdr("traffic", &ie->h, cx))
3683 print_ie_traffic_common(cx, ie->h.present, &ie->t);
3684 uni_print_ieend(cx);
3687 DEF_IE_CHECK(itu, traffic)
3689 return check_ie_traffic_common(&ie->t, ie->h.present, cx);
3692 DEF_IE_ENCODE(itu, traffic)
3694 START_IE(traffic, UNI_IE_TRAFFIC, 26);
3695 encode_traffic_common(msg, &ie->t, ie->h.present, cx);
3700 DEF_IE_DECODE(itu, traffic)
3707 if(decode_traffic_common(&ie->t, msg, ielen, &ie->h.present))
3713 /*****************************************************************/
3715 DEF_IE_PRINT(itu, atraffic)
3717 if(uni_print_iehdr("atraffic", &ie->h, cx))
3719 print_ie_traffic_common(cx, ie->h.present, &ie->t);
3720 uni_print_ieend(cx);
3723 DEF_IE_CHECK(itu, atraffic)
3725 return check_ie_traffic_common(&ie->t, ie->h.present, cx);
3728 DEF_IE_ENCODE(itu, atraffic)
3730 START_IE(traffic, UNI_IE_ATRAFFIC, 26);
3731 encode_traffic_common(msg, &ie->t, ie->h.present, cx);
3736 DEF_IE_DECODE(itu, atraffic)
3743 if(decode_traffic_common(&ie->t, msg, ielen, &ie->h.present))
3749 /*****************************************************************/
3751 DEF_IE_PRINT(itu, mintraffic)
3753 if(uni_print_iehdr("mintraffic", &ie->h, cx))
3756 uni_print_entry(cx, "pcr0", "(");
3757 if(ie->h.present & UNI_MINTRAFFIC_FPCR0_P)
3758 uni_printf(cx, "%u", ie->fpcr0);
3760 if(ie->h.present & UNI_MINTRAFFIC_BPCR0_P)
3761 uni_printf(cx, "%u", ie->bpcr0);
3764 uni_print_entry(cx, "pcr1", "(");
3765 if(ie->h.present & UNI_MINTRAFFIC_FPCR1_P)
3766 uni_printf(cx, "%u", ie->fpcr1);
3768 if(ie->h.present & UNI_MINTRAFFIC_BPCR1_P)
3769 uni_printf(cx, "%u", ie->bpcr1);
3772 uni_print_entry(cx, "abr1", "(");
3773 if(ie->h.present & UNI_MINTRAFFIC_FABR1_P)
3774 uni_printf(cx, "%u", ie->fabr1);
3776 if(ie->h.present & UNI_MINTRAFFIC_BABR1_P)
3777 uni_printf(cx, "%u", ie->babr1);
3778 uni_printf(cx, ")");
3780 uni_print_ieend(cx);
3783 DEF_IE_CHECK(itu, mintraffic)
3789 abr = ie->h.present & (UNI_MINTRAFFIC_FABR1_P|UNI_MINTRAFFIC_BABR1_P);
3790 xbr = ie->h.present & (UNI_MINTRAFFIC_FPCR0_P|UNI_MINTRAFFIC_BPCR0_P|
3791 UNI_MINTRAFFIC_FPCR1_P|UNI_MINTRAFFIC_BPCR1_P);
3799 DEF_IE_ENCODE(itu, mintraffic)
3801 START_IE(mintraffic, UNI_IE_MINTRAFFIC, 16);
3803 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FPCR0_P,
3804 UNI_TRAFFIC_FPCR0_ID, ie->fpcr0);
3805 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BPCR0_P,
3806 UNI_TRAFFIC_BPCR0_ID, ie->bpcr0);
3807 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FPCR1_P,
3808 UNI_TRAFFIC_FPCR1_ID, ie->fpcr1);
3809 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BPCR1_P,
3810 UNI_TRAFFIC_BPCR1_ID, ie->bpcr1);
3811 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FABR1_P,
3812 UNI_TRAFFIC_FABR1_ID, ie->fabr1);
3813 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BABR1_P,
3814 UNI_TRAFFIC_BABR1_ID, ie->babr1);
3820 DEF_IE_DECODE(itu, mintraffic)
3830 switch(c = *msg->b_rptr++) {
3835 DEC_GETF3(MINTRAFFIC_FPCR0, fpcr0, ie->h.present);
3836 DEC_GETF3(MINTRAFFIC_BPCR0, bpcr0, ie->h.present);
3837 DEC_GETF3(MINTRAFFIC_FPCR1, fpcr1, ie->h.present);
3838 DEC_GETF3(MINTRAFFIC_BPCR1, bpcr1, ie->h.present);
3839 DEC_GETF3(MINTRAFFIC_FABR1, fabr1, ie->h.present);
3840 DEC_GETF3(MINTRAFFIC_BABR1, babr1, ie->h.present);
3847 /*****************************************************************/
3849 DEF_IE_PRINT(net, mdcr)
3851 static const struct uni_print_tbl origin_tbl[] = {
3852 MKT(UNI_MDCR_ORIGIN_USER, user),
3853 MKT(UNI_MDCR_ORIGIN_NET, net),
3857 if(uni_print_iehdr("mdcr", &ie->h, cx))
3860 uni_print_tbl("origin", ie->origin, origin_tbl, cx);
3861 uni_print_entry(cx, "mdcr", "(");
3862 uni_printf(cx, "%u", ie->fmdcr);
3864 uni_printf(cx, "%u", ie->bmdcr);
3867 uni_print_ieend(cx);
3870 DEF_IE_CHECK(net, mdcr)
3874 if ((ie->origin != UNI_MDCR_ORIGIN_USER &&
3875 ie->origin != UNI_MDCR_ORIGIN_NET) ||
3876 ie->fmdcr >= (1 << 24) || ie->bmdcr >= (1 << 24))
3882 DEF_IE_ENCODE(net, mdcr)
3884 START_IE(mdcr, UNI_IE_MDCR, 9);
3886 APP_BYTE(msg, ie->origin);
3887 APP_SUB_24BIT(msg, UNI_TRAFFIC_FMDCR_ID, ie->fmdcr);
3888 APP_SUB_24BIT(msg, UNI_TRAFFIC_BMDCR_ID, ie->bmdcr);
3894 DEF_IE_DECODE(net, mdcr)
3897 #define UNI_TRAFFIC_FMDCR_P 0x01
3898 #define UNI_TRAFFIC_BMDCR_P 0x02
3906 ie->origin = *msg->b_rptr++;
3910 switch(c = *msg->b_rptr++) {
3915 DEC_GETF3(TRAFFIC_FMDCR, fmdcr, p);
3916 DEC_GETF3(TRAFFIC_BMDCR, bmdcr, p);
3919 if (p != (UNI_TRAFFIC_FMDCR_P | UNI_TRAFFIC_BMDCR_P))
3925 /*********************************************************************
3927 * Connection identifier
3929 * References for this IE are:
3931 * Q.2931 pp. 69...70
3932 * UNI4.0 pp. 15...16
3935 * Only ITU-T coding allowed.
3938 DEF_IE_PRINT(itu, connid)
3940 static const struct uni_print_tbl tbl[] = {
3941 MKT(UNI_CONNID_VCI, exclusive),
3942 MKT(UNI_CONNID_ANYVCI, any),
3943 MKT(UNI_CONNID_NOVCI, no),
3946 static const struct uni_print_tbl assoc_tbl[] = {
3947 MKT(UNI_CONNID_ASSOC, associated),
3948 MKT(UNI_CONNID_NONASSOC,non-associated),
3952 if(uni_print_iehdr("connid", &ie->h, cx))
3955 uni_print_tbl("mode", ie->assoc, assoc_tbl, cx);
3956 uni_print_entry(cx, "connid", "(%u,", ie->vpci);
3957 if(ie->type == UNI_CONNID_VCI)
3958 uni_printf(cx, "%u", ie->vci);
3960 uni_print_tbl(NULL, ie->type, tbl, cx);
3961 uni_printf(cx, ")");
3963 uni_print_ieend(cx);
3966 DEF_IE_CHECK(itu, connid)
3972 case UNI_CONNID_VCI:
3973 case UNI_CONNID_ANYVCI:
3974 case UNI_CONNID_NOVCI:
3980 * This field must be checked by the application to fulfil
3981 * Q.2931Amd4 27) 5.2.3 last sentence
3985 case UNI_CONNID_ASSOC:
3990 case UNI_CONNID_NONASSOC:
4000 DEF_IE_ENCODE(itu, connid)
4002 START_IE(connid, UNI_IE_CONNID, 5);
4004 APP_BYTE(msg, 0x80 | (ie->assoc << 3) | ie->type);
4005 APP_BYTE(msg, ie->vpci >> 8);
4006 APP_BYTE(msg, ie->vpci >> 0);
4007 APP_BYTE(msg, ie->vci >> 8);
4008 APP_BYTE(msg, ie->vci >> 0);
4014 DEF_IE_DECODE(itu, connid)
4026 ie->assoc = (c >> 3) & 3;
4028 ie->vpci = *msg->b_rptr++ << 8;
4029 ie->vpci |= *msg->b_rptr++;
4030 ie->vci = *msg->b_rptr++ << 8;
4031 ie->vci |= *msg->b_rptr++;
4036 /*********************************************************************
4038 * Quality of Service
4040 * References for this IE are:
4043 * UNI4.0 pp. 16...17
4047 print_qos(struct unicx *cx, struct uni_ie_qos *ie)
4049 static const struct uni_print_tbl class_tbl[] = {
4050 MKT(UNI_QOS_CLASS0, Class0),
4051 MKT(UNI_QOS_CLASS1, Class1),
4052 MKT(UNI_QOS_CLASS2, Class2),
4053 MKT(UNI_QOS_CLASS3, Class3),
4054 MKT(UNI_QOS_CLASS4, Class4),
4058 if(uni_print_iehdr("qos", &ie->h, cx))
4061 uni_print_tbl("fwd", ie->fwd, class_tbl, cx);
4062 uni_print_tbl("bwd", ie->bwd, class_tbl, cx);
4064 uni_print_ieend(cx);
4067 DEF_IE_PRINT(itu, qos)
4071 DEF_IE_PRINT(net, qos)
4076 DEF_IE_CHECK(itu, qos)
4084 case UNI_QOS_CLASS0:
4091 case UNI_QOS_CLASS0:
4097 DEF_IE_CHECK(net, qos)
4105 case UNI_QOS_CLASS1:
4106 case UNI_QOS_CLASS2:
4107 case UNI_QOS_CLASS3:
4108 case UNI_QOS_CLASS4:
4115 case UNI_QOS_CLASS1:
4116 case UNI_QOS_CLASS2:
4117 case UNI_QOS_CLASS3:
4118 case UNI_QOS_CLASS4:
4124 DEF_IE_ENCODE(itu, qos)
4126 START_IE(qos, UNI_IE_QOS, 2);
4128 APP_BYTE(msg, ie->fwd);
4129 APP_BYTE(msg, ie->bwd);
4134 DEF_IE_ENCODE(net, qos)
4136 START_IE(qos, UNI_IE_QOS, 2);
4138 APP_BYTE(msg, ie->fwd);
4139 APP_BYTE(msg, ie->bwd);
4145 DEF_IE_DECODE(itu, qos)
4152 ie->fwd = *msg->b_rptr++;
4153 ie->bwd = *msg->b_rptr++;
4158 DEF_IE_DECODE(net, qos)
4165 ie->fwd = *msg->b_rptr++;
4166 ie->bwd = *msg->b_rptr++;
4171 /*********************************************************************
4173 * Broadband Lower Layer Information
4175 * References for this IE are:
4177 * Q.2931 pp. 53...54
4180 * Only ITU-T coding allowed.
4183 DEF_IE_PRINT(itu, bhli)
4185 static const struct uni_print_tbl type_tbl[] = {
4186 MKT(UNI_BHLI_ISO, iso),
4187 MKT(UNI_BHLI_USER, user),
4188 MKT(UNI_BHLI_VENDOR, vendor),
4193 if(uni_print_iehdr("bhli", &ie->h, cx))
4196 uni_print_tbl("type", ie->type, type_tbl, cx);
4197 uni_print_entry(cx, "len", "%d", ie->len);
4198 uni_print_entry(cx, "info", "(");
4199 for(i = 0; i < ie->len; i++)
4200 uni_printf(cx, ",0x%02x", ie->info[i]);
4201 uni_printf(cx, ")");
4203 uni_print_ieend(cx);
4206 DEF_IE_CHECK(itu, bhli)
4216 case UNI_BHLI_VENDOR:
4225 DEF_IE_ENCODE(itu, bhli)
4227 START_IE(bhli, UNI_IE_BHLI, 9);
4229 APP_BYTE(msg, 0x80 | ie->type);
4230 APP_BUF(msg, ie->info, ie->len);
4236 DEF_IE_DECODE(itu, bhli)
4250 ie->type = c & 0x7f;
4252 (void)memcpy(ie->info, msg->b_rptr, ielen);
4253 msg->b_rptr += ielen;
4258 /*********************************************************************
4260 * Broadband bearer capabilities
4262 * References for this IE are:
4264 * Q.2931 pp. 51...52
4266 * UNI4.0 pp. 10...12, 106...109
4268 * UNI4.0 changed the meaning of byte 5a. Instead of 3 bit traffic type and
4269 * 2 bit timing requirements there are now 7 bits ATM transfer capabilities.
4270 * However the old format is still supported: it should be recognized on
4271 * input, but never be generated on output. Mapping is left to the user of
4274 * Amd 1 not checked XXX.
4276 * The Appendix in UNI4.0 lists all the supported combinations of various
4277 * traffic IE's. The check function implements part of it.
4281 * 2 CBR.2 - . 4,5,6 5 (*)
4282 * 3 CBR.3 - . 4,5,6 5 (*)
4283 * 4 rt-VBR.1 . 19 19 19
4284 * 5 rt-VBR.2 . 9 1,9 9
4285 * 6 rt-VBR.3 . 9 1,9 9
4286 * 7 rt-VBR.4 . . 1,9 . (*)
4287 * 8 rt-VBR.5 . . 1,9 . (*)
4288 * 9 rt-VBR.6 . 9 1,9 9 (*)
4289 * 10 nrt-VBR.1 . 11 11 11
4290 * 11 nrt-VBR.2 . - -,0,2,8,10 -,10
4291 * 12 nrt-VBR.3 . - -,0,2,8,10 -,10
4292 * 13 nrt-VBR.4 . - -,0,2,8,10 . (*)
4293 * 14 nrt-VBR.5 . - -,0,2,8,10 . (*)
4294 * 15 nrt-VBR.6 . - -,0,2,8,10 -,10(*)
4296 * 17 UBR.1 . - -,0,2,8,10 -,10
4297 * 18 UBR.2 . - -,0,2,8,10 -,10
4301 * Only ITU-T coding allowed.
4304 DEF_IE_PRINT(itu, bearer)
4306 static const struct uni_print_tbl bclass_tbl[] = {
4307 MKT(UNI_BEARER_A, bcob-A),
4308 MKT(UNI_BEARER_C, bcob-C),
4309 MKT(UNI_BEARER_X, bcob-X),
4310 MKT(UNI_BEARER_TVP, transparent-VP),
4313 static const struct uni_print_tbl atc_tbl[] = {
4314 MKT(UNI_BEARER_ATC_CBR, cbr),
4315 MKT(UNI_BEARER_ATC_CBR1, cbr1),
4316 MKT(UNI_BEARER_ATC_VBR, vbr),
4317 MKT(UNI_BEARER_ATC_VBR1, vbr1),
4318 MKT(UNI_BEARER_ATC_NVBR, nvbr),
4319 MKT(UNI_BEARER_ATC_NVBR1, nvbr1),
4320 MKT(UNI_BEARER_ATC_ABR, abr),
4322 MKT(UNI_BEARER_ATCX_0, x0),
4323 MKT(UNI_BEARER_ATCX_1, x1),
4324 MKT(UNI_BEARER_ATCX_2, x2),
4325 MKT(UNI_BEARER_ATCX_4, x4),
4326 MKT(UNI_BEARER_ATCX_6, x6),
4327 MKT(UNI_BEARER_ATCX_8, x8),
4330 static const struct uni_print_tbl cfg_tbl[] = {
4331 MKT(UNI_BEARER_P2P, p2p),
4332 MKT(UNI_BEARER_MP, mp),
4335 static const struct uni_print_tbl clip_tbl[] = {
4336 MKT(UNI_BEARER_NOCLIP, no),
4337 MKT(UNI_BEARER_CLIP, yes),
4341 if(uni_print_iehdr("bearer", &ie->h, cx))
4344 uni_print_tbl("class", ie->bclass, bclass_tbl, cx);
4346 if(ie->h.present & UNI_BEARER_ATC_P) {
4347 uni_print_tbl("atc", ie->atc, atc_tbl, cx);
4349 uni_print_tbl("clip", ie->clip, clip_tbl, cx);
4350 uni_print_tbl("cfg", ie->cfg, cfg_tbl, cx);
4352 uni_print_ieend(cx);
4355 #define QTYPE(C,A) ((UNI_BEARER_##C << 8) | UNI_BEARER_ATC_##A)
4356 #define QTYPEX(C,A) ((UNI_BEARER_##C << 8) | UNI_BEARER_ATCX_##A)
4357 #define QTYPE0(C) ((UNI_BEARER_##C << 8) | (1 << 16))
4358 DEF_IE_CHECK(itu, bearer)
4362 switch((ie->bclass << 8) |
4363 ((ie->h.present & UNI_BEARER_ATC_P) == 0
4370 case QTYPE (A, CBR1): /* 1 */
4371 case QTYPE (X, CBR1): /* 1 */
4372 case QTYPE (TVP, CBR1): /* 1 */
4374 case QTYPE0(A): /* 2,3 */
4375 case QTYPEX(X, 4): /* 2,3 */
4376 case QTYPE (X, CBR): /* 2,3 */
4377 case QTYPEX(X, 6): /* 2,3 */
4378 case QTYPE (TVP, CBR): /* 2,3 */
4380 case QTYPE (C, VBR1): /* 4 */
4381 case QTYPE (X, VBR1): /* 4 */
4382 case QTYPE (TVP, VBR1): /* 4 */
4384 case QTYPE (C, VBR): /* 5,6,9 */
4385 case QTYPEX(X, 1): /* 5,6,7,8,9 */
4386 case QTYPE (X, VBR): /* 5,6,7,8,9 */
4387 case QTYPE (TVP, VBR): /* 5,6,9 */
4389 case QTYPE (C, NVBR1): /* 10 */
4390 case QTYPE (X, NVBR1): /* 10 */
4391 case QTYPE (TVP, NVBR1): /* 10 */
4393 case QTYPE0(C): /* 11,12,13,14,15,17,18 */
4394 case QTYPE0(X): /* 11,12,13,14,15,17,18 */
4395 case QTYPEX(X, 0): /* 11,12,13,14,15,17,18 */
4396 case QTYPEX(X, 2): /* 11,12,13,14,15,17,18 */
4397 case QTYPEX(X, 8): /* 11,12,13,14,15,17,18 */
4398 case QTYPE (X, NVBR): /* 11,12,13,14,15,17,18 */
4399 case QTYPE0(TVP): /* 11,12,15,17,18 */
4400 case QTYPE (TVP, NVBR): /* 11,12,15,17,18 */
4402 case QTYPE (C, ABR): /* 16 */
4403 case QTYPE (X, ABR): /* 16 */
4404 case QTYPE (TVP, ABR): /* 16 */
4412 case UNI_BEARER_NOCLIP:
4413 case UNI_BEARER_CLIP:
4420 case UNI_BEARER_P2P:
4431 DEF_IE_ENCODE(itu, bearer)
4433 START_IE(bearer, UNI_IE_BEARER, 3);
4435 APP_BYTE(msg, ie->bclass |
4436 ((ie->h.present & UNI_BEARER_ATC_P) ? 0:0x80));
4437 APP_OPT(msg, ie->h.present, UNI_BEARER_ATC_P,
4439 APP_BYTE(msg, 0x80 | (ie->clip << 5) | ie->cfg);
4445 DEF_IE_DECODE(itu, bearer)
4451 if(ielen != 2 && ielen != 3)
4456 ie->bclass = c & 0x1f;
4460 ie->h.present |= UNI_BEARER_ATC_P;
4466 case UNI_BEARER_ATC_CBR:
4467 case UNI_BEARER_ATC_CBR1:
4468 case UNI_BEARER_ATC_VBR:
4469 case UNI_BEARER_ATC_VBR1:
4470 case UNI_BEARER_ATC_NVBR:
4471 case UNI_BEARER_ATC_NVBR1:
4472 case UNI_BEARER_ATC_ABR:
4478 case UNI_BEARER_ATCX_0:
4479 case UNI_BEARER_ATCX_1:
4480 case UNI_BEARER_ATCX_2:
4481 case UNI_BEARER_ATCX_4:
4482 case UNI_BEARER_ATCX_6:
4483 case UNI_BEARER_ATCX_8:
4501 ie->clip = (c >> 5) & 0x3;
4507 /*********************************************************************
4509 * Broadband Lower Layer Information
4511 * References for this IE are:
4513 * Q.2931 pp. 54...59
4514 * UNI4.0 pp. 12...14
4516 * UNI4.0 states, that layer 1 info is not supported.
4517 * We allow a layer 1 protocol identifier.
4519 * UNI4.0 states, that the layer information subelements are NOT position
4520 * dependent. We allow them in any order on input, but generate always the
4521 * definit order on output.
4523 * Only ITU-T coding allowed.
4526 DEF_IE_PRINT(itu, blli)
4528 static const struct uni_print_tbl l2_tbl[] = {
4529 MKT(UNI_BLLI_L2_BASIC, basic),
4530 MKT(UNI_BLLI_L2_Q921, Q921),
4531 MKT(UNI_BLLI_L2_X25LL, X25-LL),
4532 MKT(UNI_BLLI_L2_X25ML, X25-ML),
4533 MKT(UNI_BLLI_L2_LABP, LAPB),
4534 MKT(UNI_BLLI_L2_HDLC_ARM, HDLC-ARM),
4535 MKT(UNI_BLLI_L2_HDLC_NRM, HDLC-NRM),
4536 MKT(UNI_BLLI_L2_HDLC_ABM, HDLC-ABM),
4537 MKT(UNI_BLLI_L2_LAN, LAN),
4538 MKT(UNI_BLLI_L2_X75, X75),
4539 MKT(UNI_BLLI_L2_Q922, Q922),
4540 MKT(UNI_BLLI_L2_USER, user),
4541 MKT(UNI_BLLI_L2_ISO7776, ISO7776),
4544 static const struct uni_print_tbl l2mode_tbl[] = {
4545 MKT(UNI_BLLI_L2NORM, normal),
4546 MKT(UNI_BLLI_L2EXT, extended),
4549 static const struct uni_print_tbl l3_tbl[] = {
4550 MKT(UNI_BLLI_L3_X25, X25),
4551 MKT(UNI_BLLI_L3_ISO8208, ISO8208),
4552 MKT(UNI_BLLI_L3_X223, X223),
4553 MKT(UNI_BLLI_L3_CLMP, CLMP),
4554 MKT(UNI_BLLI_L3_T70, T70),
4555 MKT(UNI_BLLI_L3_TR9577, TR9577),
4556 MKT(UNI_BLLI_L3_USER, user),
4557 MKT(UNI_BLLI_L3_H310, H310),
4558 MKT(UNI_BLLI_L3_H321, H321),
4561 static const struct uni_print_tbl l3mode_tbl[] = {
4562 MKT(UNI_BLLI_L3NSEQ, normal-seq),
4563 MKT(UNI_BLLI_L3ESEQ, extended-seq),
4566 static const struct uni_print_tbl l3psiz_tbl[] = {
4567 MKT(UNI_BLLI_L3_16, 16),
4568 MKT(UNI_BLLI_L3_32, 32),
4569 MKT(UNI_BLLI_L3_64, 64),
4570 MKT(UNI_BLLI_L3_128, 128),
4571 MKT(UNI_BLLI_L3_256, 256),
4572 MKT(UNI_BLLI_L3_512, 512),
4573 MKT(UNI_BLLI_L3_1024, 1024),
4574 MKT(UNI_BLLI_L3_2048, 2048),
4575 MKT(UNI_BLLI_L3_4096, 4096),
4578 static const struct uni_print_tbl l3ttype_tbl[] = {
4579 MKT(UNI_BLLI_L3_TTYPE_RECV, receive_only),
4580 MKT(UNI_BLLI_L3_TTYPE_SEND, send_only),
4581 MKT(UNI_BLLI_L3_TTYPE_BOTH, both),
4584 static const struct uni_print_tbl l3mux_tbl[] = {
4585 MKT(UNI_BLLI_L3_MUX_NOMUX, NOMUX),
4586 MKT(UNI_BLLI_L3_MUX_TS, TS),
4587 MKT(UNI_BLLI_L3_MUX_TSFEC, TSFEC),
4588 MKT(UNI_BLLI_L3_MUX_PS, PS),
4589 MKT(UNI_BLLI_L3_MUX_PSFEC, PSFEC),
4590 MKT(UNI_BLLI_L3_MUX_H221, H221),
4593 static const struct uni_print_tbl l3tcap_tbl[] = {
4594 MKT(UNI_BLLI_L3_TCAP_NOIND, noind),
4595 MKT(UNI_BLLI_L3_TCAP_AAL1, aal1),
4596 MKT(UNI_BLLI_L3_TCAP_AAL5, aal5),
4597 MKT(UNI_BLLI_L3_TCAP_AAL15, aal1&5),
4601 if(uni_print_iehdr("blli", &ie->h, cx))
4604 if(ie->h.present & UNI_BLLI_L1_P) {
4605 uni_print_entry(cx, "l1", "%u", ie->l1);
4608 if(ie->h.present & UNI_BLLI_L2_P) {
4609 uni_print_tbl("l2", ie->l2, l2_tbl, cx);
4610 uni_print_push_prefix("l2", cx);
4612 if(ie->h.present & UNI_BLLI_L2_USER_P)
4613 uni_print_entry(cx, "proto", "%u", ie->l2_user);
4614 if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4615 uni_print_entry(cx, "q933", "%u", ie->l2_q933);
4616 uni_print_tbl("mode", ie->l2_mode, l2mode_tbl, cx);
4618 if(ie->h.present & UNI_BLLI_L2_WSIZ_P)
4619 uni_print_entry(cx, "wsize", "%u", ie->l2_wsiz);
4620 uni_print_pop_prefix(cx);
4625 if(ie->h.present & UNI_BLLI_L3_P) {
4626 uni_print_tbl("l3", ie->l3, l3_tbl, cx);
4627 uni_print_push_prefix("l3", cx);
4629 if(ie->h.present & UNI_BLLI_L3_USER_P)
4630 uni_print_entry(cx, "proto", "%u", ie->l3_user);
4631 if(ie->h.present & UNI_BLLI_L3_MODE_P)
4632 uni_print_tbl("mode", ie->l3_mode, l3mode_tbl, cx);
4633 if(ie->h.present & UNI_BLLI_L3_PSIZ_P)
4634 uni_print_tbl("packet-size", ie->l3_psiz, l3psiz_tbl, cx);
4635 if(ie->h.present & UNI_BLLI_L3_WSIZ_P)
4636 uni_print_entry(cx, "window-size", "%u", ie->l3_wsiz);
4637 if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4638 uni_print_tbl("ttype", ie->l3_ttype, l3ttype_tbl, cx);
4639 uni_print_tbl("tcap", ie->l3_tcap, l3tcap_tbl, cx);
4641 if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4642 uni_print_tbl("fmux", ie->l3_fmux, l3mux_tbl, cx);
4643 uni_print_tbl("bmux", ie->l3_bmux, l3mux_tbl, cx);
4645 if(ie->h.present & UNI_BLLI_L3_IPI_P)
4646 uni_print_entry(cx, "ipi", "0x%02x", ie->l3_ipi);
4647 if(ie->h.present & UNI_BLLI_L3_SNAP_P)
4648 uni_print_entry(cx, "snap", "%06x.%04x", ie->oui, ie->pid);
4649 uni_print_pop_prefix(cx);
4654 uni_print_ieend(cx);
4657 DEF_IE_CHECK(itu, blli)
4661 if(ie->h.present & UNI_BLLI_L1_P)
4665 if(ie->h.present & UNI_BLLI_L2_P) {
4667 UNI_BLLI_L2_Q933_P | UNI_BLLI_L2_WSIZ_P |
4674 case UNI_BLLI_L2_BASIC:
4675 case UNI_BLLI_L2_Q921:
4676 case UNI_BLLI_L2_LABP:
4677 case UNI_BLLI_L2_LAN:
4678 case UNI_BLLI_L2_X75:
4679 if(ie->h.present & mask)
4683 case UNI_BLLI_L2_X25LL:
4684 case UNI_BLLI_L2_X25ML:
4685 case UNI_BLLI_L2_HDLC_ARM:
4686 case UNI_BLLI_L2_HDLC_NRM:
4687 case UNI_BLLI_L2_HDLC_ABM:
4688 case UNI_BLLI_L2_Q922:
4689 case UNI_BLLI_L2_ISO7776:
4690 switch(ie->h.present & mask) {
4695 case UNI_BLLI_L2_Q933_P:
4696 case UNI_BLLI_L2_Q933_P | UNI_BLLI_L2_WSIZ_P:
4701 case UNI_BLLI_L2_USER:
4702 switch(ie->h.present & mask) {
4707 case UNI_BLLI_L2_USER_P:
4712 if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4713 if(ie->l2_q933 != 0)
4716 switch(ie->l2_mode) {
4720 case UNI_BLLI_L2NORM:
4721 case UNI_BLLI_L2EXT:
4725 if(ie->h.present & UNI_BLLI_L2_WSIZ_P) {
4726 if(ie->l2_wsiz == 0 || ie->l2_wsiz > 127)
4729 if(ie->h.present & UNI_BLLI_L2_USER_P) {
4730 if(ie->l2_user > 127)
4734 if(ie->h.present & UNI_BLLI_L3_P) {
4736 UNI_BLLI_L3_MODE_P | UNI_BLLI_L3_PSIZ_P |
4737 UNI_BLLI_L3_WSIZ_P | UNI_BLLI_L3_USER_P |
4738 UNI_BLLI_L3_IPI_P | UNI_BLLI_L3_SNAP_P |
4739 UNI_BLLI_L3_TTYPE_P | UNI_BLLI_L3_MUX_P;
4745 case UNI_BLLI_L3_X25:
4746 case UNI_BLLI_L3_ISO8208:
4747 case UNI_BLLI_L3_X223:
4748 switch(ie->h.present & mask) {
4753 case UNI_BLLI_L3_MODE_P:
4754 case UNI_BLLI_L3_MODE_P |
4756 case UNI_BLLI_L3_MODE_P |
4757 UNI_BLLI_L3_PSIZ_P |
4763 case UNI_BLLI_L3_CLMP:
4764 case UNI_BLLI_L3_T70:
4765 if(ie->h.present & mask)
4769 case UNI_BLLI_L3_TR9577:
4770 switch(ie->h.present & mask) {
4775 case UNI_BLLI_L3_IPI_P:
4776 case UNI_BLLI_L3_IPI_P | UNI_BLLI_L3_SNAP_P:
4781 case UNI_BLLI_L3_H310:
4782 switch(ie->h.present & mask) {
4787 case UNI_BLLI_L3_TTYPE_P:
4788 case UNI_BLLI_L3_TTYPE_P|UNI_BLLI_L3_MUX_P:
4793 case UNI_BLLI_L3_USER:
4794 switch(ie->h.present & mask) {
4799 case UNI_BLLI_L3_USER_P:
4804 if(ie->h.present & UNI_BLLI_L3_MODE_P) {
4805 switch(ie->l3_mode) {
4809 case UNI_BLLI_L3NSEQ:
4810 case UNI_BLLI_L3ESEQ:
4814 if(ie->h.present & UNI_BLLI_L3_PSIZ_P) {
4815 switch(ie->l3_psiz) {
4819 case UNI_BLLI_L3_16:
4820 case UNI_BLLI_L3_32:
4821 case UNI_BLLI_L3_64:
4822 case UNI_BLLI_L3_128:
4823 case UNI_BLLI_L3_256:
4824 case UNI_BLLI_L3_512:
4825 case UNI_BLLI_L3_1024:
4826 case UNI_BLLI_L3_2048:
4827 case UNI_BLLI_L3_4096:
4831 if(ie->h.present & UNI_BLLI_L3_WSIZ_P) {
4832 if(ie->l3_wsiz == 0 || ie->l3_wsiz > 127)
4835 if(ie->h.present & UNI_BLLI_L3_IPI_P) {
4836 if(ie->l3_ipi == UNI_BLLI_L3_SNAP) {
4837 if(!(ie->h.present & UNI_BLLI_L3_SNAP_P))
4840 if(ie->h.present & UNI_BLLI_L3_SNAP_P)
4844 if(ie->h.present & UNI_BLLI_L3_USER_P) {
4845 if(ie->l3_user > 127)
4848 if(ie->h.present & UNI_BLLI_L3_SNAP_P) {
4849 if(ie->oui >= (1<<24))
4851 if(ie->pid >= (1<<16))
4854 if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4855 switch(ie->l3_ttype) {
4859 case UNI_BLLI_L3_TTYPE_RECV:
4860 case UNI_BLLI_L3_TTYPE_SEND:
4861 case UNI_BLLI_L3_TTYPE_BOTH:
4864 switch(ie->l3_tcap) {
4868 case UNI_BLLI_L3_TCAP_NOIND:
4869 case UNI_BLLI_L3_TCAP_AAL1:
4870 case UNI_BLLI_L3_TCAP_AAL5:
4871 case UNI_BLLI_L3_TCAP_AAL15:
4875 if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4876 switch(ie->l3_fmux) {
4880 case UNI_BLLI_L3_MUX_NOMUX:
4881 case UNI_BLLI_L3_MUX_TS:
4882 case UNI_BLLI_L3_MUX_TSFEC:
4883 case UNI_BLLI_L3_MUX_PS:
4884 case UNI_BLLI_L3_MUX_PSFEC:
4885 case UNI_BLLI_L3_MUX_H221:
4888 switch(ie->l3_bmux) {
4892 case UNI_BLLI_L3_MUX_NOMUX:
4893 case UNI_BLLI_L3_MUX_TS:
4894 case UNI_BLLI_L3_MUX_TSFEC:
4895 case UNI_BLLI_L3_MUX_PS:
4896 case UNI_BLLI_L3_MUX_PSFEC:
4897 case UNI_BLLI_L3_MUX_H221:
4906 DEF_IE_ENCODE(itu, blli)
4908 START_IE(blli, UNI_IE_BLLI, 13);
4910 if (IE_ISERROR(*ie)) {
4911 APP_BYTE(msg, 0xff);
4912 APP_BYTE(msg, 0xff);
4916 if(ie->h.present & UNI_BLLI_L1_P)
4917 APP_BYTE(msg, (UNI_BLLI_L1_ID<<5)|ie->l1|0x80);
4919 if(ie->h.present & UNI_BLLI_L2_P) {
4920 if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4921 APP_BYTE(msg, (UNI_BLLI_L2_ID<<5)|ie->l2);
4922 if(ie->h.present & UNI_BLLI_L2_WSIZ_P) {
4923 APP_BYTE(msg, (ie->l2_mode<<5)|ie->l2_q933);
4924 APP_BYTE(msg, ie->l2_wsiz | 0x80);
4926 APP_BYTE(msg, (ie->l2_mode<<5)|ie->l2_q933|0x80);
4928 } else if(ie->h.present & UNI_BLLI_L2_USER_P) {
4929 APP_BYTE(msg, (UNI_BLLI_L2_ID<<5)|ie->l2);
4930 APP_BYTE(msg, ie->l2_user | 0x80);
4932 APP_BYTE(msg, (UNI_BLLI_L2_ID << 5) | ie->l2 | 0x80);
4936 if(ie->h.present & UNI_BLLI_L3_P) {
4937 if(ie->h.present & UNI_BLLI_L3_MODE_P) {
4938 if(ie->h.present & UNI_BLLI_L3_PSIZ_P) {
4939 if(ie->h.present & UNI_BLLI_L3_WSIZ_P) {
4940 APP_BYTE(msg,(UNI_BLLI_L3_ID<<5)|ie->l3);
4941 APP_BYTE(msg,(ie->l3_mode<<5));
4942 APP_BYTE(msg,ie->l3_psiz);
4943 APP_BYTE(msg,ie->l3_wsiz|0x80);
4945 APP_BYTE(msg,(UNI_BLLI_L3_ID<<5)|ie->l3);
4946 APP_BYTE(msg,(ie->l3_mode<<5));
4947 APP_BYTE(msg,(ie->l3_psiz|0x80));
4950 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4951 APP_BYTE(msg, (ie->l3_mode<<5)|0x80);
4953 } else if(ie->h.present & UNI_BLLI_L3_USER_P) {
4954 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4955 APP_BYTE(msg,(ie->l3_user|0x80));
4956 } else if(ie->h.present & UNI_BLLI_L3_IPI_P) {
4957 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4958 APP_BYTE(msg,((ie->l3_ipi>>1) & 0x7f));
4959 APP_BYTE(msg,(((ie->l3_ipi&1)<<6)|0x80));
4960 if(ie->h.present & UNI_BLLI_L3_SNAP_P) {
4961 APP_BYTE(msg, 0x80);
4962 APP_BYTE(msg, (ie->oui >> 16));
4963 APP_BYTE(msg, (ie->oui >> 8));
4964 APP_BYTE(msg, (ie->oui >> 0));
4965 APP_BYTE(msg, (ie->pid >> 8));
4966 APP_BYTE(msg, (ie->pid >> 0));
4968 } else if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4969 if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4970 APP_BYTE(msg, ie->l3_ttype | (ie->l3_tcap << 4));
4971 APP_BYTE(msg, 0x80 | (ie->l3_fmux << 3) | ie->l3_bmux);
4973 APP_BYTE(msg, 0x80 | ie->l3_ttype | (ie->l3_tcap << 4));
4976 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3|0x80);
4985 DEF_IE_DECODE(itu, blli)
4995 switch(((c = *msg->b_rptr++) >> 5) & 0x3) {
4999 case UNI_BLLI_L1_ID:
5000 ie->h.present |= UNI_BLLI_L1_P;
5006 case UNI_BLLI_L2_ID:
5007 ie->h.present |= UNI_BLLI_L2_P;
5014 if(ie->l2 == UNI_BLLI_L2_USER) {
5015 ie->h.present |= UNI_BLLI_L2_USER_P;
5016 ie->l2_user = c & 0x7f;
5020 ie->h.present |= UNI_BLLI_L2_Q933_P;
5021 ie->l2_q933 = c & 0x3;
5022 ie->l2_mode = (c >> 5) & 0x3;
5028 ie->h.present |= UNI_BLLI_L2_WSIZ_P;
5029 ie->l2_wsiz = c & 0x7f;
5037 case UNI_BLLI_L3_ID:
5038 ie->h.present |= UNI_BLLI_L3_P;
5043 case UNI_BLLI_L3_CLMP:
5044 case UNI_BLLI_L3_T70:
5047 case UNI_BLLI_L3_X25:
5048 case UNI_BLLI_L3_ISO8208:
5049 case UNI_BLLI_L3_X223:
5054 ie->l3_mode = (c >> 5) & 0x3;
5055 ie->h.present |= UNI_BLLI_L3_MODE_P;
5064 ie->l3_psiz = c & 0xf;
5065 ie->h.present |= UNI_BLLI_L3_PSIZ_P;
5074 ie->l3_wsiz = c & 0x7f;
5075 ie->h.present |= UNI_BLLI_L3_WSIZ_P;
5081 case UNI_BLLI_L3_TR9577:
5086 ie->l3_ipi = (c << 1) & 0xfe;
5090 ie->l3_ipi |= c & 1;
5093 ie->h.present |= UNI_BLLI_L3_IPI_P;
5095 if(ie->l3_ipi != UNI_BLLI_L3_SNAP)
5100 if(*msg->b_rptr++ != 0x80)
5102 ie->h.present |= UNI_BLLI_L3_SNAP_P;
5103 ie->oui = *msg->b_rptr++ << 16;
5104 ie->oui |= *msg->b_rptr++ << 8;
5105 ie->oui |= *msg->b_rptr++;
5106 ie->pid = *msg->b_rptr++ << 8;
5107 ie->pid |= *msg->b_rptr++;
5110 case UNI_BLLI_L3_H310:
5115 ie->l3_ttype = c & 0xf;
5116 ie->l3_tcap = (c >> 4) & 0x7;
5117 ie->h.present |= UNI_BLLI_L3_TTYPE_P;
5124 ie->l3_fmux = (c >> 3) & 7;
5125 ie->l3_bmux = c & 7;
5126 ie->h.present |= UNI_BLLI_L3_MUX_P;
5131 case UNI_BLLI_L3_USER:
5136 ie->l3_user = c & 0x7f;
5137 ie->h.present |= UNI_BLLI_L3_USER_P;
5150 /*********************************************************************
5152 * Broadband locking shift
5153 * Broadband non-locking shift.
5155 * References for this IE are:
5157 * Q.2931 pp. 41...42
5160 * Procedure not supported in UNI4.0, but IE's must be recognized.
5162 * Only ITU-T coding allowed.
5165 DEF_IE_PRINT(itu, lshift)
5167 if(uni_print_iehdr("locking_shift", &ie->h, cx))
5169 uni_print_ieend(cx);
5172 DEF_IE_CHECK(itu, lshift)
5178 DEF_IE_ENCODE(itu, lshift)
5180 START_IE(lshift, UNI_IE_LSHIFT, 1);
5181 APP_BYTE(msg, 0x80 | ie->set);
5186 DEF_IE_DECODE(itu, lshift)
5204 /***********************************************************************/
5206 DEF_IE_PRINT(itu, nlshift)
5208 if(uni_print_iehdr("nonlocking_shift", &ie->h, cx))
5210 uni_print_ieend(cx);
5213 DEF_IE_CHECK(itu, nlshift)
5219 DEF_IE_ENCODE(itu, nlshift)
5221 START_IE(nlshift, UNI_IE_NLSHIFT, 1);
5222 APP_BYTE(msg, 0x80 | ie->set);
5227 DEF_IE_DECODE(itu, nlshift)
5245 /*********************************************************************
5247 * Broadband Sending Complete Indicator
5249 * References for this IE are:
5253 * Only ITU-T coding allowed.
5255 DEF_IE_PRINT(itu, scompl)
5257 if(uni_print_iehdr("sending_complete", &ie->h, cx))
5259 uni_print_ieend(cx);
5262 DEF_IE_CHECK(itu, scompl)
5268 DEF_IE_ENCODE(itu, scompl)
5270 START_IE(scompl, UNI_IE_SCOMPL, 1);
5272 APP_BYTE(msg, 0x80 | 0x21);
5278 DEF_IE_DECODE(itu, scompl)
5285 if(*msg->b_rptr++ != (0x80 | 0x21))
5291 /*********************************************************************
5293 * Broadband Repeat Indicator
5295 * References for this IE are:
5300 * Q.2931 has table 4-19. Only codepoints 0x2 and 0xa (for PNNI) supported.
5302 * Only ITU-T coding allowed.
5304 DEF_IE_PRINT(itu, repeat)
5306 static const struct uni_print_tbl tbl[] = {
5307 MKT(UNI_REPEAT_PRIDESC, desc),
5308 MKT(UNI_REPEAT_STACK, stack),
5312 if(uni_print_iehdr("repeat", &ie->h, cx))
5314 uni_print_tbl("type", ie->type, tbl, cx);
5315 uni_print_ieend(cx);
5318 DEF_IE_CHECK(itu, repeat)
5322 case UNI_REPEAT_PRIDESC:
5325 case UNI_REPEAT_STACK:
5336 DEF_IE_ENCODE(itu, repeat)
5338 START_IE(repeat, UNI_IE_REPEAT, 1);
5340 APP_BYTE(msg, 0x80 | ie->type);
5346 DEF_IE_DECODE(itu, repeat)
5363 /*********************************************************************
5365 * Transit Network Selection
5367 * References for this IE are:
5369 * Q.2931 pp. 75...76
5372 * According to UNI4.0 this is always National Network Id/Carried Id.
5374 * ITU-T/Net coding allowed.
5377 DEF_IE_PRINT(itu, tns)
5381 if(uni_print_iehdr("tns", &ie->h, cx))
5383 uni_print_entry(cx, "net", "%u,\"", ie->len);
5385 for(i = 0; i < ie->len; i++) {
5386 if(ie->net[i] < ' ')
5387 uni_printf(cx, "^%c", ie->net[i] + '@');
5388 else if(ie->net[i] < '~')
5389 uni_putc(ie->net[i], cx);
5391 uni_printf(cx, "\\%03o", ie->net[i]);
5394 uni_print_ieend(cx);
5397 DEF_IE_CHECK(itu, tns)
5403 if(ie->len == 0 || ie->len > UNI_TNS_MAXLEN)
5405 for(i = 0; i < ie->len; i++)
5406 if(ie->net[i] < ' ' || ie->net[i] > '~')
5411 DEF_IE_ENCODE(itu, tns)
5413 START_IE(tns, UNI_IE_TNS, ie->len + 1);
5415 APP_BYTE(msg, 0x80 | (0x2 << 4) | 0x1);
5416 APP_BUF(msg, ie->net, ie->len);
5422 DEF_IE_DECODE(itu, tns)
5426 if(ielen < 2 || ielen > 5)
5429 if(*msg->b_rptr++ != (0x80 | (0x2 << 4) | 0x1))
5435 ie->net[ie->len++] = *msg->b_rptr++;
5440 /*********************************************************************
5444 * References for this IE are:
5446 * Q.2931 pp. 73...74
5449 * Only ITU-T coding allowed.
5452 DEF_IE_PRINT(itu, restart)
5454 static const struct uni_print_tbl tbl[] = {
5455 MKT(UNI_RESTART_CHANNEL, channel),
5456 MKT(UNI_RESTART_PATH, path),
5457 MKT(UNI_RESTART_ALL, all),
5461 if(uni_print_iehdr("restart", &ie->h, cx))
5463 uni_print_tbl("class", ie->rclass, tbl, cx);
5464 uni_print_ieend(cx);
5467 DEF_IE_CHECK(itu, restart)
5471 switch(ie->rclass) {
5475 case UNI_RESTART_CHANNEL:
5476 case UNI_RESTART_PATH:
5477 case UNI_RESTART_ALL:
5484 DEF_IE_ENCODE(itu, restart)
5486 START_IE(restart, UNI_IE_RESTART, 1);
5488 APP_BYTE(msg, 0x80 | ie->rclass);
5494 DEF_IE_DECODE(itu, restart)
5503 ie->rclass = (c = *msg->b_rptr++) & 0x7;
5511 /*********************************************************************
5513 * User-to-user info.
5515 * References for this IE are:
5519 * Only ITU-T coding allowed.
5522 DEF_IE_PRINT(itu, uu)
5526 if(uni_print_iehdr("uu", &ie->h, cx))
5528 uni_print_entry(cx, "len", "%u", ie->len);
5529 uni_print_entry(cx, "info", "(");
5530 for(i = 0; i < ie->len; i++)
5531 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->uu[i]);
5532 uni_printf(cx, ")");
5533 uni_print_ieend(cx);
5536 DEF_IE_CHECK(itu, uu)
5540 if(ie->len > UNI_UU_MAXLEN)
5546 DEF_IE_ENCODE(itu, uu)
5548 START_IE(uu, UNI_IE_UU, ie->len);
5550 APP_BUF(msg, ie->uu, ie->len);
5556 DEF_IE_DECODE(itu, uu)
5560 if(ielen > UNI_UU_MAXLEN || ielen < 1)
5565 (void)memcpy(ie->uu, msg->b_rptr, ie->len);
5566 msg->b_rptr += ie->len;
5571 /*********************************************************************
5573 * Generic Identifier Transport
5575 * References for this IE are:
5577 * UNI4.0 pp. 26...28
5579 * UNI4.0 prescribes a fixed format for this IE. We have a flag in the
5580 * context structur, which tells us whether the check of this IE should be
5581 * hard or soft. Probably it should be hard for end systems and soft for
5584 * Only Net Coding allowed. (XXX)
5587 DEF_IE_PRINT(net, git)
5589 static const struct uni_print_tbl std_tbl[] = {
5590 MKT(UNI_GIT_STD_DSMCC, dsmcc),
5591 MKT(UNI_GIT_STD_H245, H.245),
5594 static const struct uni_print_tbl type_tbl[] = {
5595 MKT(UNI_GIT_TYPE_SESS, sess),
5596 MKT(UNI_GIT_TYPE_RES, res),
5602 if(uni_print_iehdr("git", &ie->h, cx))
5605 uni_print_tbl("std", ie->std, std_tbl, cx);
5608 uni_print_push_prefix("id", cx);
5610 for(i = 0; i < ie->numsub; i++) {
5611 sprintf(buf, "%u", i);
5612 uni_print_entry(cx, buf, "(");
5613 uni_print_tbl(NULL, ie->sub[i].type, type_tbl, cx);
5614 for(j = 0; j < ie->sub[i].len; j++)
5615 uni_printf(cx, ",0x%02x", ie->sub[i].val[j]);
5616 uni_printf(cx, ")");
5620 uni_print_pop_prefix(cx);
5622 uni_print_ieend(cx);
5625 DEF_IE_CHECK(net, git)
5631 case UNI_GIT_STD_DSMCC:
5632 case UNI_GIT_STD_H245:
5639 if(ie->sub[0].type != UNI_GIT_TYPE_SESS)
5641 if(ie->sub[0].len > UNI_GIT_MAXSESS)
5643 if(ie->sub[1].type != UNI_GIT_TYPE_RES)
5645 if(ie->sub[1].len > UNI_GIT_MAXRES)
5648 if(ie->numsub > UNI_GIT_MAXSUB)
5650 for(i = 0; i < ie->numsub; i++)
5651 if(ie->sub[i].len > UNI_GIT_MAXVAL)
5657 DEF_IE_ENCODE(net, git)
5661 START_IE(git, UNI_IE_GIT, 1 + ie->numsub * (1 + UNI_GIT_MAXVAL));
5663 APP_BYTE(msg, ie->std);
5664 for(i = 0; i < ie->numsub; i++) {
5665 APP_BYTE(msg, ie->sub[i].type);
5666 APP_BYTE(msg, ie->sub[i].len);
5667 APP_BUF(msg, ie->sub[i].val, ie->sub[i].len);
5674 DEF_IE_DECODE(net, git)
5678 if(ielen > 1 + UNI_GIT_MAXSUB * (1 + UNI_GIT_MAXVAL) || ielen < 1)
5681 ie->std = *msg->b_rptr++;
5686 if(ie->numsub >= UNI_GIT_MAXSUB)
5689 ie->sub[ie->numsub].type = *msg->b_rptr++;
5694 ie->sub[ie->numsub].len = *msg->b_rptr++;
5697 if(ie->sub[ie->numsub].len > UNI_GIT_MAXVAL)
5699 if(ie->sub[ie->numsub].len > (u_int)ielen)
5702 (void)memcpy(ie->sub[ie->numsub].val, msg->b_rptr, ie->sub[ie->numsub].len);
5703 ielen -= ie->sub[ie->numsub].len;
5704 msg->b_rptr += ie->sub[ie->numsub].len;
5712 /*********************************************************************
5714 * Additional ABR Parameters
5715 * ABR Setup parameters
5717 * References for this IE are:
5719 * UNI4.0 pp. 78...82
5727 print_abr_rec(struct unicx *cx, struct uni_abr_rec *rec)
5729 if(rec->present & UNI_ABR_REC_NRM_P)
5730 uni_print_entry(cx, "nrm", "%d", rec->nrm);
5731 if(rec->present & UNI_ABR_REC_TRM_P)
5732 uni_print_entry(cx, "trm", "%d", rec->trm);
5733 if(rec->present & UNI_ABR_REC_CDF_P)
5734 uni_print_entry(cx, "cdf", "%d", rec->cdf);
5735 if(rec->present & UNI_ABR_REC_ADTF_P)
5736 uni_print_entry(cx, "adtf", "%d", rec->adtf);
5739 DEF_IE_PRINT(net, abradd)
5741 if(uni_print_iehdr("abradd", &ie->h, cx))
5744 uni_print_push_prefix("fwd", cx);
5745 print_abr_rec(cx, &ie->fwd);
5746 uni_print_pop_prefix(cx);
5748 uni_print_push_prefix("bwd", cx);
5749 print_abr_rec(cx, &ie->bwd);
5750 uni_print_pop_prefix(cx);
5752 uni_print_ieend(cx);
5755 DEF_IE_CHECK(net, abradd)
5764 encode_abr_rec(struct uni_abr_rec *rec)
5766 u_int ret = rec->present & 0xf000;
5768 if(ret & UNI_ABR_REC_NRM_P)
5769 ret |= (rec->nrm & 0x7) << 25;
5770 if(ret & UNI_ABR_REC_TRM_P)
5771 ret |= (rec->trm & 0x7) << 22;
5772 if(ret & UNI_ABR_REC_CDF_P)
5773 ret |= (rec->cdf & 0x7) << 19;
5774 if(ret & UNI_ABR_REC_ADTF_P)
5775 ret |= (rec->adtf & 0x3ff) << 9;
5780 DEF_IE_ENCODE(net, abradd)
5782 START_IE(abradd, UNI_IE_ABRADD, 10);
5784 APP_SUB_32BIT(msg, UNI_ABRADD_FADD_ID, encode_abr_rec(&ie->fwd));
5785 APP_SUB_32BIT(msg, UNI_ABRADD_BADD_ID, encode_abr_rec(&ie->bwd));
5792 decode_abr_rec(struct uni_msg *msg, struct uni_abr_rec *rec)
5796 val = *msg->b_rptr++ << 24;
5797 val |= *msg->b_rptr++ << 16;
5798 val |= *msg->b_rptr++ << 8;
5799 val |= *msg->b_rptr++ << 0;
5801 rec->present = val & 0xf000;
5803 rec->nrm = (val & UNI_ABR_REC_NRM_P) ? ((val >> 25) & 0x7) : 0;
5804 rec->trm = (val & UNI_ABR_REC_TRM_P) ? ((val >> 22) & 0x7) : 0;
5805 rec->cdf = (val & UNI_ABR_REC_CDF_P) ? ((val >> 19) & 0x7) : 0;
5806 rec->adtf = (val & UNI_ABR_REC_ADTF_P)? ((val >> 9) & 0x3ff) : 0;
5811 DEF_IE_DECODE(net, abradd)
5820 switch(*msg->b_rptr++) {
5825 case UNI_ABRADD_FADD_ID:
5826 if(decode_abr_rec(msg, &ie->fwd))
5831 case UNI_ABRADD_BADD_ID:
5832 if(decode_abr_rec(msg, &ie->bwd))
5841 /*********************************************************************/
5843 DEF_IE_PRINT(net, abrsetup)
5845 if(uni_print_iehdr("abrsetup", &ie->h, cx))
5848 uni_print_entry(cx, "rm_frt", "%d", ie->rmfrt);
5850 uni_print_push_prefix("fwd", cx);
5851 if(ie->h.present & UNI_ABRSETUP_FICR_P)
5852 uni_print_entry(cx, "icr", "%d", ie->ficr);
5853 if(ie->h.present & UNI_ABRSETUP_FTBE_P)
5854 uni_print_entry(cx, "tbe", "%d", ie->ftbe);
5855 if(ie->h.present & UNI_ABRSETUP_FRIF_P)
5856 uni_print_entry(cx, "rif", "%d", ie->frif);
5857 if(ie->h.present & UNI_ABRSETUP_FRDF_P)
5858 uni_print_entry(cx, "rdf", "%d", ie->frdf);
5859 uni_print_pop_prefix(cx);
5861 uni_print_push_prefix("bwd", cx);
5862 if(ie->h.present & UNI_ABRSETUP_BICR_P)
5863 uni_print_entry(cx, "icr", "%d", ie->bicr);
5864 if(ie->h.present & UNI_ABRSETUP_BTBE_P)
5865 uni_print_entry(cx, "tbe", "%d", ie->btbe);
5866 if(ie->h.present & UNI_ABRSETUP_BRIF_P)
5867 uni_print_entry(cx, "rif", "%d", ie->brif);
5868 if(ie->h.present & UNI_ABRSETUP_BRDF_P)
5869 uni_print_entry(cx, "rdf", "%d", ie->brdf);
5870 uni_print_pop_prefix(cx);
5872 uni_print_ieend(cx);
5875 DEF_IE_CHECK(net, abrsetup)
5878 if(!(ie->h.present & UNI_ABRSETUP_FICR_P))
5880 if(!(ie->h.present & UNI_ABRSETUP_BICR_P))
5882 if(!(ie->h.present & UNI_ABRSETUP_FTBE_P))
5884 if(!(ie->h.present & UNI_ABRSETUP_BTBE_P))
5886 if(!(ie->h.present & UNI_ABRSETUP_FRIF_P))
5888 if(!(ie->h.present & UNI_ABRSETUP_BRIF_P))
5890 if(!(ie->h.present & UNI_ABRSETUP_FRDF_P))
5892 if(!(ie->h.present & UNI_ABRSETUP_BRDF_P))
5894 if(!(ie->h.present & UNI_ABRSETUP_RMFRT_P))
5898 if(!(ie->h.present & UNI_ABRSETUP_RMFRT_P))
5901 if(ie->h.present & UNI_ABRSETUP_FICR_P)
5902 if(ie->ficr >= 1 << 24)
5904 if(ie->h.present & UNI_ABRSETUP_BICR_P)
5905 if(ie->bicr >= 1 << 24)
5908 if(ie->h.present & UNI_ABRSETUP_FTBE_P)
5909 if(ie->ftbe >= 1 << 24 || ie->ftbe == 0)
5911 if(ie->h.present & UNI_ABRSETUP_BTBE_P)
5912 if(ie->btbe >= 1 << 24 || ie->btbe == 0)
5915 if(ie->rmfrt >= 1 << 24)
5918 if(ie->h.present & UNI_ABRSETUP_FRIF_P)
5921 if(ie->h.present & UNI_ABRSETUP_FRDF_P)
5924 if(ie->h.present & UNI_ABRSETUP_BRIF_P)
5927 if(ie->h.present & UNI_ABRSETUP_BRDF_P)
5933 DEF_IE_ENCODE(net, abrsetup)
5935 START_IE(abrsetup, UNI_IE_ABRSETUP, 32);
5937 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_FICR_P,
5938 UNI_ABRSETUP_FICR_ID, ie->ficr);
5939 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_BICR_P,
5940 UNI_ABRSETUP_BICR_ID, ie->bicr);
5941 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_FTBE_P,
5942 UNI_ABRSETUP_FTBE_ID, ie->ftbe);
5943 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_BTBE_P,
5944 UNI_ABRSETUP_BTBE_ID, ie->btbe);
5945 APP_SUB_24BIT(msg, UNI_ABRSETUP_RMFRT_ID, ie->rmfrt);
5946 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_FRIF_P,
5947 UNI_ABRSETUP_FRIF_ID, ie->frif);
5948 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_BRIF_P,
5949 UNI_ABRSETUP_BRIF_ID, ie->brif);
5950 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_FRDF_P,
5951 UNI_ABRSETUP_FRDF_ID, ie->frdf);
5952 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_BRDF_P,
5953 UNI_ABRSETUP_BRDF_ID, ie->brdf);
5959 DEF_IE_DECODE(net, abrsetup)
5963 if(ielen < 4 || ielen > 32)
5968 switch(*msg->b_rptr++) {
5974 DEC_GETF3(ABRSETUP_FICR, ficr, ie->h.present);
5975 DEC_GETF3(ABRSETUP_BICR, bicr, ie->h.present);
5976 DEC_GETF3(ABRSETUP_FTBE, ftbe, ie->h.present);
5977 DEC_GETF3(ABRSETUP_BTBE, btbe, ie->h.present);
5978 DEC_GETF1(ABRSETUP_FRIF, frif, ie->h.present);
5979 DEC_GETF1(ABRSETUP_BRIF, brif, ie->h.present);
5980 DEC_GETF1(ABRSETUP_FRDF, frdf, ie->h.present);
5981 DEC_GETF1(ABRSETUP_BRDF, brdf, ie->h.present);
5982 DEC_GETF3(ABRSETUP_RMFRT, frif, ie->h.present);
5988 /*********************************************************************
5990 * Broadband report type
5992 * References for this IE are:
5994 * Q.2963.1 pp. 7...8
5996 * Only ITU-T coding allowed.
5999 DEF_IE_PRINT(itu, report)
6001 static const struct uni_print_tbl tbl[] = {
6002 MKT(UNI_REPORT_MODCONF, modconf),
6003 MKT(UNI_REPORT_CLOCK, clock),
6004 MKT(UNI_REPORT_EEAVAIL, eeavail),
6005 MKT(UNI_REPORT_EEREQ, eereq),
6006 MKT(UNI_REPORT_EECOMPL, eecompl),
6010 if(uni_print_iehdr("report", &ie->h, cx))
6012 uni_print_tbl("type", ie->report, tbl, cx);
6013 uni_print_ieend(cx);
6016 DEF_IE_CHECK(itu, report)
6020 switch(ie->report) {
6025 case UNI_REPORT_MODCONF:
6026 case UNI_REPORT_CLOCK:
6027 case UNI_REPORT_EEAVAIL:
6028 case UNI_REPORT_EEREQ:
6029 case UNI_REPORT_EECOMPL:
6035 DEF_IE_ENCODE(itu, report)
6037 START_IE(report, UNI_IE_REPORT, 1);
6039 APP_BYTE(msg, ie->report);
6045 DEF_IE_DECODE(itu, report)
6051 ie->report = *msg->b_rptr++;
6056 /*********************************************************************
6060 * References for this IE are:
6062 * PNNI1.0 pp. 201...203
6064 * Only NET coding allowed.
6066 DEF_IE_PRINT(net, calling_soft)
6068 if(uni_print_iehdr("calling_soft", &ie->h, cx))
6071 uni_print_entry(cx, "vpi", "%d", ie->vpi);
6072 if(ie->h.present & UNI_CALLING_SOFT_VCI_P)
6073 uni_print_entry(cx, "vci", "%d", ie->vci);
6075 uni_print_ieend(cx);
6078 DEF_IE_PRINT(net, called_soft)
6080 static const struct uni_print_tbl tab[] = {
6081 MKT(UNI_SOFT_SEL_ANY, any),
6082 MKT(UNI_SOFT_SEL_REQ, required),
6083 MKT(UNI_SOFT_SEL_ASS, assigned),
6087 if(uni_print_iehdr("called_soft", &ie->h, cx))
6090 uni_print_tbl("selection", ie->sel, tab, cx);
6091 if(ie->h.present & UNI_CALLED_SOFT_VPI_P)
6092 uni_print_entry(cx, "vpi", "%d", ie->vpi);
6093 if(ie->h.present & UNI_CALLED_SOFT_VCI_P)
6094 uni_print_entry(cx, "vci", "%d", ie->vci);
6096 uni_print_ieend(cx);
6099 DEF_IE_CHECK(net, calling_soft)
6103 if(ie->vpi >= 1 << 12)
6108 DEF_IE_CHECK(net, called_soft)
6114 case UNI_SOFT_SEL_ANY:
6115 case UNI_SOFT_SEL_REQ:
6116 case UNI_SOFT_SEL_ASS:
6122 if(ie->h.present & UNI_CALLED_SOFT_VPI_P) {
6123 if(ie->vpi >= 1 << 12)
6126 if(ie->sel != UNI_SOFT_SEL_ANY)
6130 if(ie->h.present & UNI_CALLED_SOFT_VCI_P)
6131 if(!(ie->h.present & UNI_CALLED_SOFT_VPI_P))
6138 DEF_IE_ENCODE(net, calling_soft)
6140 START_IE(calling_soft, UNI_IE_CALLING_SOFT, 6);
6142 APP_BYTE(msg, 0x81);
6143 APP_16BIT(msg, ie->vpi);
6145 if(ie->h.present & UNI_CALLING_SOFT_VCI_P) {
6146 APP_BYTE(msg, 0x82);
6147 APP_16BIT(msg, ie->vci);
6154 DEF_IE_ENCODE(net, called_soft)
6156 START_IE(called_soft, UNI_IE_CALLED_SOFT, 7);
6158 APP_BYTE(msg, ie->sel);
6160 if(ie->h.present & UNI_CALLED_SOFT_VPI_P) {
6161 APP_BYTE(msg, 0x81);
6162 APP_16BIT(msg, ie->vpi);
6165 if(ie->h.present & UNI_CALLED_SOFT_VCI_P) {
6166 APP_BYTE(msg, 0x82);
6167 APP_16BIT(msg, ie->vci);
6174 DEF_IE_DECODE(net, calling_soft)
6176 int vci_seen, vpi_seen;
6186 switch(*msg->b_rptr++) {
6190 ie->vpi = *msg->b_rptr++ << 8;
6191 ie->vpi |= *msg->b_rptr++;
6200 ie->vci = *msg->b_rptr++ << 8;
6201 ie->vci |= *msg->b_rptr++;
6205 ie->h.present |= UNI_CALLING_SOFT_VCI_P;
6217 IE_END(CALLING_SOFT);
6220 DEF_IE_DECODE(net, called_soft)
6222 int vci_seen, vpi_seen;
6232 switch(*msg->b_rptr++) {
6236 ie->vpi = *msg->b_rptr++ << 8;
6237 ie->vpi |= *msg->b_rptr++;
6243 ie->h.present |= UNI_CALLED_SOFT_VCI_P;
6248 ie->vci = *msg->b_rptr++ << 8;
6249 ie->vci |= *msg->b_rptr++;
6254 ie->h.present |= UNI_CALLED_SOFT_VCI_P;
6263 IE_END(CALLED_SOFT);
6266 /*********************************************************************
6270 * References for this IE are:
6272 * PNNI1.0 pp. 203...206
6274 * Only NET coding allowed.
6277 DEF_IE_PRINT(net, crankback)
6281 if(uni_print_iehdr("crankback", &ie->h, cx))
6284 uni_print_entry(cx, "level", "%d", ie->level);
6288 case UNI_CRANKBACK_IF:
6289 uni_print_entry(cx, "type", "interface");
6292 case UNI_CRANKBACK_NODE:
6293 uni_print_entry(cx, "type", "node");
6294 uni_print_entry(cx, "node", "{%d/", ie->id.node.level);
6295 for(j = 0; j < 21; j++)
6296 uni_printf(cx, "%02x", ie->id.node.id[j]);
6297 uni_printf(cx, "}");
6301 case UNI_CRANKBACK_LINK:
6302 uni_print_entry(cx, "type", "link");
6303 uni_print_push_prefix("link", cx);
6306 uni_print_entry(cx, "prec", "{%d/", ie->id.link.plevel);
6307 for(j = 0; j < 21; j++)
6308 uni_printf(cx, "%02x", ie->id.link.pid[j]);
6309 uni_printf(cx, "}");
6312 uni_print_entry(cx, "port", "0x%04x", ie->id.link.port);
6315 uni_print_entry(cx, "succ", "{%d/", ie->id.link.slevel);
6316 for(j = 0; j < 21; j++)
6317 uni_printf(cx, "%02x", ie->id.link.sid[j]);
6318 uni_printf(cx, "}");
6322 uni_print_pop_prefix(cx);
6326 uni_print_entry(cx, "type", "0x%02x", ie->type);
6330 uni_print_entry(cx, "cause", "0x%02x", ie->cause);
6332 if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6333 uni_print_push_prefix("topol", cx);
6334 uni_print_entry(cx, "dir", "%d", ie->diag.top.dir);
6335 uni_print_entry(cx, "port", "0x%04x", ie->diag.top.port);
6336 uni_print_entry(cx, "avcr", "%u", ie->diag.top.avcr);
6337 if(ie->h.present & UNI_CRANKBACK_TOPX_P) {
6338 uni_print_entry(cx, "crm", "%u", ie->diag.top.crm);
6339 uni_print_entry(cx, "vf", "%u", ie->diag.top.vf);
6341 uni_print_pop_prefix(cx);
6344 if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6345 uni_print_push_prefix("qos", cx);
6346 uni_print_entry(cx, "ctd", "%savail", ie->diag.qos.ctd ? "" : "un");
6347 uni_print_entry(cx, "cdv", "%savail", ie->diag.qos.cdv ? "" : "un");
6348 uni_print_entry(cx, "clr", "%savail", ie->diag.qos.clr ? "" : "un");
6349 uni_print_entry(cx, "other", "%savail", ie->diag.qos.other ? "" : "un");
6350 uni_print_pop_prefix(cx);
6355 uni_print_ieend(cx);
6358 DEF_IE_CHECK(net, crankback)
6365 case UNI_CRANKBACK_IF:
6367 case UNI_CRANKBACK_NODE:
6368 if(ie->id.node.level > 104)
6372 case UNI_CRANKBACK_LINK:
6373 if(ie->id.link.plevel > 104)
6375 if(ie->id.link.slevel > 104)
6383 if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6384 if(ie->h.present & UNI_CRANKBACK_QOS_P)
6387 if(ie->cause != UNI_CAUSE_CRATE_NAVL)
6389 switch(ie->diag.top.dir) {
6399 if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6400 if(ie->cause != UNI_CAUSE_QOS_NAVL)
6406 DEF_IE_ENCODE(net, crankback)
6408 START_IE(crankback, UNI_IE_CRANKBACK, 72);
6410 APP_BYTE(msg, ie->level);
6411 APP_BYTE(msg, ie->type);
6415 case UNI_CRANKBACK_IF:
6418 case UNI_CRANKBACK_NODE:
6419 APP_BYTE(msg, ie->id.node.level);
6420 APP_BUF(msg, ie->id.node.id, 21);
6423 case UNI_CRANKBACK_LINK:
6424 APP_BYTE(msg, ie->id.link.plevel);
6425 APP_BUF(msg, ie->id.link.pid, 21);
6426 APP_32BIT(msg, ie->id.link.port);
6427 APP_BYTE(msg, ie->id.link.slevel);
6428 APP_BUF(msg, ie->id.link.sid, 21);
6432 APP_BYTE(msg, ie->cause);
6434 if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6435 APP_BYTE(msg, ie->diag.top.dir);
6436 APP_32BIT(msg, ie->diag.top.port);
6437 APP_32BIT(msg, ie->diag.top.avcr);
6438 if(ie->h.present & UNI_CRANKBACK_TOPX_P) {
6439 APP_32BIT(msg, ie->diag.top.crm);
6440 APP_32BIT(msg, ie->diag.top.vf);
6444 if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6445 APP_BYTE(msg, (ie->diag.qos.ctd << 3)
6446 |(ie->diag.qos.cdv << 2)
6447 |(ie->diag.qos.clr << 1)
6448 |(ie->diag.qos.other));
6455 DEF_IE_DECODE(net, crankback)
6462 ie->level = *msg->b_rptr++;
6465 ie->type = *msg->b_rptr++;
6473 case UNI_CRANKBACK_IF:
6476 case UNI_CRANKBACK_NODE:
6479 ie->id.node.level = *msg->b_rptr++;
6480 (void)memcpy(ie->id.node.id, msg->b_rptr, 21);
6485 case UNI_CRANKBACK_LINK:
6488 ie->id.link.plevel = *msg->b_rptr++;
6489 (void)memcpy(ie->id.link.pid, msg->b_rptr, 21);
6493 ie->id.link.port = *msg->b_rptr++ << 24;
6494 ie->id.link.port |= *msg->b_rptr++ << 16;
6495 ie->id.link.port |= *msg->b_rptr++ << 8;
6496 ie->id.link.port |= *msg->b_rptr++ << 0;
6499 ie->id.link.slevel = *msg->b_rptr++;
6500 (void)memcpy(ie->id.link.sid, msg->b_rptr, 21);
6509 ie->cause = *msg->b_rptr++;
6512 if(ie->cause == UNI_CAUSE_CRATE_NAVL) {
6514 if(ielen != 9 && ielen != 17)
6516 ie->diag.top.dir = *msg->b_rptr++;
6517 ie->diag.top.port = *msg->b_rptr++ << 24;
6518 ie->diag.top.port |= *msg->b_rptr++ << 16;
6519 ie->diag.top.port |= *msg->b_rptr++ << 8;
6520 ie->diag.top.port |= *msg->b_rptr++ << 0;
6521 ie->diag.top.avcr = *msg->b_rptr++ << 24;
6522 ie->diag.top.avcr |= *msg->b_rptr++ << 16;
6523 ie->diag.top.avcr |= *msg->b_rptr++ << 8;
6524 ie->diag.top.avcr |= *msg->b_rptr++ << 0;
6526 ie->h.present |= UNI_CRANKBACK_TOP_P;
6528 ie->diag.top.crm = *msg->b_rptr++ << 24;
6529 ie->diag.top.crm |= *msg->b_rptr++ << 16;
6530 ie->diag.top.crm |= *msg->b_rptr++ << 8;
6531 ie->diag.top.crm |= *msg->b_rptr++ << 0;
6532 ie->diag.top.vf = *msg->b_rptr++ << 24;
6533 ie->diag.top.vf |= *msg->b_rptr++ << 16;
6534 ie->diag.top.vf |= *msg->b_rptr++ << 8;
6535 ie->diag.top.vf |= *msg->b_rptr++ << 0;
6536 ie->h.present |= UNI_CRANKBACK_TOPX_P;
6540 } else if(ie->cause == UNI_CAUSE_QOS_NAVL) {
6544 ie->diag.qos.ctd = *msg->b_rptr >> 3;
6545 ie->diag.qos.cdv = *msg->b_rptr >> 2;
6546 ie->diag.qos.clr = *msg->b_rptr >> 1;
6547 ie->diag.qos.other = *msg->b_rptr >> 0;
6548 ie->h.present |= UNI_CRANKBACK_QOS_P;
6559 /*********************************************************************
6561 * Designated transit list
6563 * References for this IE are:
6565 * PNNI1.0 pp. 206...208
6567 * Only NET coding allowed.
6569 DEF_IE_PRINT(net, dtl)
6574 if(uni_print_iehdr("dtl", &ie->h, cx))
6577 uni_print_entry(cx, "ptr", "%d(%d)", ie->ptr, ie->ptr / UNI_DTL_LOGNP_SIZE);
6578 uni_print_push_prefix("dtl", cx);
6580 uni_printf(cx, "{");
6581 for(i = 0; i < ie->num; i++) {
6582 sprintf(buf, "%d", i);
6583 uni_print_entry(cx, buf, "{%d/", ie->dtl[i].node_level);
6584 for(j = 0; j < 21; j++)
6585 uni_printf(cx, "%02x", ie->dtl[i].node_id[j]);
6586 uni_printf(cx, ",%04x}", ie->dtl[i].port_id);
6590 uni_print_pop_prefix(cx);
6591 uni_print_ieend(cx);
6594 DEF_IE_CHECK(net, dtl)
6600 if(ie->ptr % UNI_DTL_LOGNP_SIZE != 0)
6602 if(ie->ptr / UNI_DTL_LOGNP_SIZE > UNI_DTL_MAXNUM)
6604 if(ie->num > UNI_DTL_MAXNUM)
6606 for(i = 0; i < ie->num; i++)
6607 if(ie->dtl[i].node_level > 104)
6612 DEF_IE_ENCODE(net, dtl)
6616 START_IE(dtl, UNI_IE_DTL, 2 + UNI_DTL_LOGNP_SIZE * ie->num);
6618 APP_16BIT(msg, ie->ptr);
6620 for(i = 0; i < ie->num; i++) {
6621 APP_BYTE(msg, UNI_DTL_LOGNP);
6622 APP_BYTE(msg, ie->dtl[i].node_level);
6623 APP_BUF(msg, ie->dtl[i].node_id, 21);
6624 APP_32BIT(msg, ie->dtl[i].port_id);
6632 DEF_IE_DECODE(net, dtl)
6639 ie->ptr = *msg->b_rptr++ << 8;
6640 ie->ptr |= *msg->b_rptr++;
6643 if(ielen % UNI_DTL_LOGNP_SIZE != 0)
6645 if(ielen / UNI_DTL_LOGNP_SIZE > UNI_DTL_MAXNUM)
6650 if(*msg->b_rptr++ != UNI_DTL_LOGNP)
6654 ie->dtl[ie->num].node_level = *msg->b_rptr++;
6657 (void)memcpy(ie->dtl[ie->num].node_id, msg->b_rptr, 21);
6661 ie->dtl[ie->num].port_id = *msg->b_rptr++ << 24;
6662 ie->dtl[ie->num].port_id |= *msg->b_rptr++ << 16;
6663 ie->dtl[ie->num].port_id |= *msg->b_rptr++ << 8;
6664 ie->dtl[ie->num].port_id |= *msg->b_rptr++ << 0;
6673 /*********************************************************************
6675 * Leaf initiated join call identifier.
6676 * Leaf initiated join parameters.
6677 * Leaf initiated join sequence number.
6679 * References for this IE are:
6681 * UNI4.0 pp. 46...48
6683 * Only NET coding allowed.
6686 /**********************************************************************/
6688 DEF_IE_PRINT(net, lij_callid)
6690 static const struct uni_print_tbl type_tbl[] = {
6691 MKT(UNI_LIJ_IDTYPE_ROOT, root),
6695 if(uni_print_iehdr("lij_callid", &ie->h, cx))
6698 uni_print_tbl("type", ie->type, type_tbl, cx);
6699 uni_print_entry(cx, "id", "0x%x", ie->callid);
6701 uni_print_ieend(cx);
6704 DEF_IE_CHECK(net, lij_callid)
6710 case UNI_LIJ_IDTYPE_ROOT:
6720 DEF_IE_ENCODE(net, lij_callid)
6722 START_IE(lij_callid, UNI_IE_LIJ_CALLID, 5);
6724 APP_BYTE(msg, 0x80 | ie->type);
6725 APP_32BIT(msg, ie->callid);
6731 DEF_IE_DECODE(net, lij_callid)
6738 ie->type = *msg->b_rptr++ & 0xf;
6739 ie->callid = *msg->b_rptr++ << 24;
6740 ie->callid |= *msg->b_rptr++ << 16;
6741 ie->callid |= *msg->b_rptr++ << 8;
6742 ie->callid |= *msg->b_rptr++ << 0;
6747 /**********************************************************************/
6749 DEF_IE_PRINT(net, lij_param)
6751 static const struct uni_print_tbl lscreen_tbl[] = {
6752 MKT(UNI_LIJ_SCREEN_NETJOIN, netjoin),
6756 if(uni_print_iehdr("lij_param", &ie->h, cx))
6758 uni_print_tbl("screen", ie->screen, lscreen_tbl, cx);
6759 uni_print_ieend(cx);
6762 DEF_IE_CHECK(net, lij_param)
6766 switch(ie->screen) {
6768 case UNI_LIJ_SCREEN_NETJOIN:
6778 DEF_IE_ENCODE(net, lij_param)
6780 START_IE(lij_param, UNI_IE_LIJ_PARAM, 1);
6782 APP_BYTE(msg, 0x80 | ie->screen);
6788 DEF_IE_DECODE(net, lij_param)
6795 ie->screen = *msg->b_rptr++ & 0xf;
6800 /**********************************************************************/
6802 DEF_IE_PRINT(net, lij_seqno)
6804 if(uni_print_iehdr("lij_seqno", &ie->h, cx))
6806 uni_print_entry(cx, "seqno", "0x%x", ie->seqno);
6807 uni_print_ieend(cx);
6810 DEF_IE_CHECK(net, lij_seqno)
6817 DEF_IE_ENCODE(net, lij_seqno)
6819 START_IE(lij_seqno, UNI_IE_LIJ_SEQNO, 4);
6821 APP_32BIT(msg, ie->seqno);
6827 DEF_IE_DECODE(net, lij_seqno)
6834 ie->seqno = *msg->b_rptr++ << 24;
6835 ie->seqno |= *msg->b_rptr++ << 16;
6836 ie->seqno |= *msg->b_rptr++ << 8;
6837 ie->seqno |= *msg->b_rptr++ << 0;
6842 /*********************************************************************
6846 * References for this IE are:
6848 * UNI4.0 pp. 57...58
6850 * Only NET coding allowed.
6852 DEF_IE_PRINT(net, cscope)
6854 static const struct uni_print_tbl type_tbl[] = {
6855 MKT(UNI_CSCOPE_ORG, org),
6858 static const struct uni_print_tbl scope_tbl[] = {
6859 MKT(UNI_CSCOPE_ORG_LOC, local_network),
6860 MKT(UNI_CSCOPE_ORG_LOC_P1, local_network_plus_one),
6861 MKT(UNI_CSCOPE_ORG_LOC_P2, local_network_plus_two),
6862 MKT(UNI_CSCOPE_ORG_SITE_M1, site_minus_one),
6863 MKT(UNI_CSCOPE_ORG_SITE, intra_site),
6864 MKT(UNI_CSCOPE_ORG_SITE_P1, site_plus_one),
6865 MKT(UNI_CSCOPE_ORG_ORG_M1, organisation_minus_one),
6866 MKT(UNI_CSCOPE_ORG_ORG, intra_organisation),
6867 MKT(UNI_CSCOPE_ORG_ORG_P1, organisation_plus_one),
6868 MKT(UNI_CSCOPE_ORG_COMM_M1, community_minus_one),
6869 MKT(UNI_CSCOPE_ORG_COMM, intra_community),
6870 MKT(UNI_CSCOPE_ORG_COMM_P1, community_plus_one),
6871 MKT(UNI_CSCOPE_ORG_REG, regional),
6872 MKT(UNI_CSCOPE_ORG_INTER, inter_regional),
6873 MKT(UNI_CSCOPE_ORG_GLOBAL, global),
6877 if(uni_print_iehdr("cscope", &ie->h, cx))
6880 uni_print_tbl("type", ie->type, type_tbl, cx);
6881 if(ie->type == UNI_CSCOPE_ORG)
6882 uni_print_tbl("scope", (u_int)ie->scope, scope_tbl, cx);
6884 uni_print_entry(cx, "scope", "0x%02x", ie->scope);
6886 uni_print_ieend(cx);
6889 DEF_IE_CHECK(net, cscope)
6898 case UNI_CSCOPE_ORG:
6904 case UNI_CSCOPE_ORG_LOC:
6905 case UNI_CSCOPE_ORG_LOC_P1:
6906 case UNI_CSCOPE_ORG_LOC_P2:
6907 case UNI_CSCOPE_ORG_SITE_M1:
6908 case UNI_CSCOPE_ORG_SITE:
6909 case UNI_CSCOPE_ORG_SITE_P1:
6910 case UNI_CSCOPE_ORG_ORG_M1:
6911 case UNI_CSCOPE_ORG_ORG:
6912 case UNI_CSCOPE_ORG_ORG_P1:
6913 case UNI_CSCOPE_ORG_COMM_M1:
6914 case UNI_CSCOPE_ORG_COMM:
6915 case UNI_CSCOPE_ORG_COMM_P1:
6916 case UNI_CSCOPE_ORG_REG:
6917 case UNI_CSCOPE_ORG_INTER:
6918 case UNI_CSCOPE_ORG_GLOBAL:
6926 DEF_IE_ENCODE(net, cscope)
6928 START_IE(cscope, UNI_IE_CSCOPE, 2);
6930 APP_BYTE(msg, ie->type | 0x80);
6931 APP_BYTE(msg, ie->scope);
6937 DEF_IE_DECODE(net, cscope)
6943 if((*msg->b_rptr & 0xf0) != 0x80)
6946 ie->type = *msg->b_rptr++ & 0xf;
6947 ie->scope = *msg->b_rptr++;
6952 /*********************************************************************
6954 * Extended Quality of Service
6956 * References for this IE are:
6958 * UNI4.0 pp. 70...72
6963 DEF_IE_PRINT(net, exqos)
6965 static const struct uni_print_tbl tab[] = {
6966 MKT(UNI_EXQOS_USER, user),
6967 MKT(UNI_EXQOS_NET, net),
6971 if(uni_print_iehdr("exqos", &ie->h, cx))
6974 uni_print_tbl("origin", ie->origin, tab, cx);
6976 uni_print_entry(cx, "acceptable", "(");
6977 if(ie->h.present & UNI_EXQOS_FACC_P) {
6978 if(ie->facc == UNI_EXQOS_ANY_CDV)
6979 uni_printf(cx, "ANY");
6981 uni_printf(cx, "%d", ie->facc);
6984 if(ie->h.present & UNI_EXQOS_BACC_P) {
6985 if(ie->bacc == UNI_EXQOS_ANY_CDV)
6986 uni_printf(cx, "ANY");
6988 uni_printf(cx, "%d", ie->bacc);
6992 uni_print_entry(cx, "cumulative", "(");
6993 if(ie->h.present & UNI_EXQOS_FCUM_P)
6994 uni_printf(cx, "%d", ie->fcum);
6996 if(ie->h.present & UNI_EXQOS_BCUM_P)
6997 uni_printf(cx, "%d", ie->bcum);
7000 uni_print_entry(cx, "clrid", "(");
7001 if(ie->h.present & UNI_EXQOS_FCLR_P) {
7002 if(ie->fclr == UNI_EXQOS_ANY_CLR)
7003 uni_printf(cx, "ANY");
7005 uni_printf(cx, "%d", ie->fclr);
7008 if(ie->h.present & UNI_EXQOS_BCLR_P) {
7009 if(ie->bclr == UNI_EXQOS_ANY_CLR)
7010 uni_printf(cx, "ANY");
7012 uni_printf(cx, "%d", ie->bclr);
7016 uni_print_ieend(cx);
7019 DEF_IE_CHECK(net, exqos)
7023 switch(ie->origin) {
7024 case UNI_EXQOS_USER:
7031 if(ie->h.present & UNI_EXQOS_FACC_P)
7032 if(!(ie->h.present & UNI_EXQOS_FCUM_P))
7034 if(ie->h.present & UNI_EXQOS_BACC_P)
7035 if(!(ie->h.present & UNI_EXQOS_BCUM_P))
7038 if(ie->h.present & UNI_EXQOS_FACC_P)
7039 if(ie->facc >= 1 << 24)
7041 if(ie->h.present & UNI_EXQOS_BACC_P)
7042 if(ie->bacc >= 1 << 24)
7044 if(ie->h.present & UNI_EXQOS_FCUM_P)
7045 if(ie->fcum >= 1 << 24)
7047 if(ie->h.present & UNI_EXQOS_BCUM_P)
7048 if(ie->bcum >= 1 << 24)
7051 if(ie->h.present & UNI_EXQOS_FCLR_P)
7052 if(ie->fclr==0 || (ie->fclr>15 && ie->fclr!=UNI_EXQOS_ANY_CLR))
7054 if(ie->h.present & UNI_EXQOS_BCLR_P)
7055 if(ie->bclr==0 || (ie->bclr>15 && ie->bclr!=UNI_EXQOS_ANY_CLR))
7060 DEF_IE_ENCODE(net, exqos)
7062 START_IE(exqos, UNI_IE_EXQOS, 21);
7064 APP_BYTE(msg, ie->origin);
7066 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_FACC_P,
7067 UNI_EXQOS_FACC_ID, ie->facc);
7068 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_BACC_P,
7069 UNI_EXQOS_BACC_ID, ie->bacc);
7070 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_FCUM_P,
7071 UNI_EXQOS_FCUM_ID, ie->fcum);
7072 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_BCUM_P,
7073 UNI_EXQOS_BCUM_ID, ie->bcum);
7075 APP_OPT_BYTE(msg, ie->h.present, UNI_EXQOS_FCLR_P,
7076 UNI_EXQOS_FCLR_ID, ie->fclr);
7077 APP_OPT_BYTE(msg, ie->h.present, UNI_EXQOS_BCLR_P,
7078 UNI_EXQOS_BCLR_ID, ie->bclr);
7084 DEF_IE_DECODE(net, exqos)
7088 if(ielen < 1 || ielen > 21)
7091 ie->origin = *msg->b_rptr++;
7095 switch(*msg->b_rptr++) {
7100 DEC_GETF3(EXQOS_FACC, facc, ie->h.present);
7101 DEC_GETF3(EXQOS_BACC, bacc, ie->h.present);
7102 DEC_GETF3(EXQOS_FCUM, fcum, ie->h.present);
7103 DEC_GETF3(EXQOS_BCUM, bcum, ie->h.present);
7105 DEC_GETF1(EXQOS_FCLR, fclr, ie->h.present);
7106 DEC_GETF1(EXQOS_BCLR, bclr, ie->h.present);
7113 /**************************************************************
7115 * Free form IE (for testing mainly)
7117 DEF_IE_PRINT(itu, unrec)
7121 if (uni_print_iehdr("unrec", &ie->h, cx))
7123 uni_print_entry(cx, "len", "%u", ie->len);
7124 uni_print_entry(cx, "data", "(");
7125 for (i = 0; i < ie->len; i++)
7126 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->data[i]);
7127 uni_printf(cx, ")");
7128 uni_print_ieend(cx);
7131 DEF_IE_CHECK(itu, unrec)
7135 if (ie->len > sizeof(ie->data))
7141 DEF_IE_ENCODE(itu, unrec)
7143 START_IE2(unrec, UNI_IE_UNREC, ie->len, ie->id);
7145 APP_BUF(msg, ie->data, ie->len);
7151 DEF_IE_DECODE(itu, unrec)
7155 if (ielen > sizeof(ie->data) / sizeof(ie->data[0]) || ielen < 1)
7160 (void)memcpy(ie->data, msg->b_rptr, ie->len);
7161 msg->b_rptr += ie->len;