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>
50 #define UNUSED(_p) do { (void)(_p); } while (0)
53 * Define internal functions.
55 #define DEF_IE_PRINT(Coding, IE) \
56 void uni_ie_print_##Coding##_##IE(struct uni_ie_##IE *ie, struct unicx *cx)
58 #define DEF_IE_CHECK(Coding, IE) \
59 int uni_ie_check_##Coding##_##IE(struct uni_ie_##IE *ie, struct unicx *cx)
61 #define DEF_IE_ENCODE(Coding, IE) \
62 int uni_ie_encode_##Coding##_##IE(struct uni_msg *msg, struct uni_ie_##IE *ie, struct unicx *cx)
64 #define DEF_IE_DECODE(Coding, IE) \
65 int uni_ie_decode_##Coding##_##IE(struct uni_ie_##IE *ie, struct uni_msg *msg, u_int ielen, struct unicx *cx)
68 * This structure is used to define value->string mappings. MKT() is used
69 * to generate a table entry. EOT() to end the table.
71 #define MKT(V,N) { #N, V }
72 #define EOT() { NULL, 0 }
74 /* library internal functions */
75 static void uni_entry(const char *, struct unicx *);
76 static int uni_print_iehdr(const char *, struct uni_iehdr *h, struct unicx *);
77 static void uni_print_ieend(struct unicx *);
78 static void uni_putc(int, struct unicx *);
84 #define APP_BYTE(M, B) do { \
85 *(M)->b_wptr++ = (B); \
87 #define APP_16BIT(M, B) do { \
89 *(M)->b_wptr++ = _v >> 8; \
90 *(M)->b_wptr++ = _v; \
92 #define APP_24BIT(M, B) do { \
94 *(M)->b_wptr++ = _v >> 16; \
95 *(M)->b_wptr++ = _v >> 8; \
96 *(M)->b_wptr++ = _v; \
98 #define APP_32BIT(M, B) do { \
100 *(M)->b_wptr++ = _v >> 24; \
101 *(M)->b_wptr++ = _v >> 16; \
102 *(M)->b_wptr++ = _v >> 8; \
103 *(M)->b_wptr++ = _v; \
105 #define APP_BUF(M, B, L) do { \
106 (void)memcpy((M)->b_wptr, (B), (L)); \
107 (M)->b_wptr += (L); \
110 #define APP_SUB_BYTE(M, T, B) do { APP_BYTE(M, T); APP_BYTE(M, B); } while (0)
111 #define APP_SUB_16BIT(M, T, B) do { APP_BYTE(M, T); APP_16BIT(M, B); } while (0)
112 #define APP_SUB_24BIT(M, T, B) do { APP_BYTE(M, T); APP_24BIT(M, B); } while (0)
113 #define APP_SUB_32BIT(M, T, B) do { APP_BYTE(M, T); APP_32BIT(M, B); } while (0)
115 #define APP_OPT(M, F, P, T) do { \
117 APP_BYTE((M), (T)); \
119 #define APP_OPT_BYTE(M, F, P, T, B) do { \
121 APP_SUB_BYTE((M), (T), (B)); \
123 #define APP_OPT_16BIT(M, F, P, T, B) do { \
125 APP_SUB_16BIT((M), (T), (B)); \
127 #define APP_OPT_24BIT(M, F, P, T, B) do { \
129 APP_SUB_24BIT((M), (T), (B)); \
132 #define START_IE(TYPE,CODE,LEN) \
135 if (uni_check_ie(CODE, (union uni_ieall *)ie, cx)) \
137 if (uni_encode_ie_hdr(msg, CODE, &ie->h, (LEN), cx)) \
140 ielen = msg->b_wptr - msg->b_rptr - 2;
142 #define START_IE2(TYPE,CODE,LEN,REALCODE) \
145 if (uni_check_ie(CODE, (union uni_ieall *)ie, cx)) \
147 if (uni_encode_ie_hdr(msg, REALCODE, &ie->h, (LEN), cx)) \
150 ielen = msg->b_wptr - msg->b_rptr - 2;
152 #define SET_IE_LEN(M) do { \
153 (M)->b_buf[ielen + 0] = \
154 (((M)->b_wptr - (M)->b_rptr) - ielen - 2) >> 8; \
155 (M)->b_buf[ielen + 1] = \
156 (((M)->b_wptr - (M)->b_rptr) - ielen - 2) >> 0; \
160 /***********************************************************************/
164 #define IE_START(ERR) \
165 if (IE_ISPRESENT(*ie)) \
173 IE_SETPRESENT(*ie); \
174 if (uni_check_ie(UNI_IE_##IE, (union uni_ieall *)ie, cx) == 0) \
177 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT; \
180 #define DEC_GETF3(ID, F, P) \
181 case UNI_##ID##_ID: \
185 if (!(P & UNI_##ID##_P)) { \
187 ie->F = *msg->b_rptr++ << 16; \
188 ie->F |= *msg->b_rptr++ << 8; \
189 ie->F |= *msg->b_rptr++; \
194 #define DEC_GETF1(ID, F, P) \
195 case UNI_##ID##_ID: \
199 if (!(P & UNI_##ID##_P)) { \
201 ie->F = *msg->b_rptr++; \
207 #define PRINT_NPREFIX (sizeof(((struct unicx *)0)->prefix) / \
208 sizeof(((struct unicx *)0)->prefix[0]))
211 * This is rather here than in privmsg.c because we need the APP macros.
214 uni_encode_msg_hdr(struct uni_msg *msg, struct uni_msghdr *h,
215 enum uni_msgtype type, struct unicx *cx, int *mlen)
219 (void)uni_msg_ensure(msg, 9);
221 APP_BYTE(msg, cx->pnni ? PNNI_PROTO : UNI_PROTO);
223 if(h->cref.cref >= 1<<23)
225 APP_24BIT(msg, h->cref.cref | (h->cref.flag ? 0x800000 : 0));
229 if(h->act != UNI_MSGACT_DEFAULT)
230 byte |= 0x10 | (h->act & 3);
231 if(cx->pnni && h->pass)
235 *mlen = msg->b_wptr - msg->b_rptr;
242 * Initialize printing. This must be called by all printing routines
243 * that are exported to the user.
246 uni_print_init(char *buf, size_t bufsiz, struct unicx *cx)
261 * Append a character to the buffer if there is still space
264 uni_putc(int c, struct unicx *cx)
274 uni_printf(struct unicx *cx, const char *fmt, ...)
281 n = vsnprintf(cx->buf, cx->bufsiz, fmt, ap);
288 cx->buf += cx->bufsiz - 1;
298 * 0 - print all into one line, fully prefixed
299 * 1 - print on multiple lines, full prefixed, but equal level
300 * entries on one line
301 * 2 - like 2, but only partial prefixed
302 * 3 - like 1, but each entry onto a new line
307 * If we are in multiline mode, end the current line and set the
308 * flag, that we need indentation. But prevent double new lines.
311 uni_print_eol(struct unicx *cx)
322 * New entry. Do the prefixing, indentation and spacing.
325 doprefix(struct unicx *cx, const char *s)
329 if(cx->multiline == 0) {
331 for(i = 0; i < cx->nprefix; i++)
333 uni_printf(cx, "%s.", cx->prefix[i]);
334 } else if(cx->multiline == 1) {
336 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
340 for(i = 0; i < cx->nprefix; i++)
342 uni_printf(cx, "%s.", cx->prefix[i]);
343 } else if(cx->multiline == 2) {
345 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
349 } else if(cx->multiline == 3) {
354 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
355 for(i = 0; i < cx->nprefix; i++)
357 uni_printf(cx, "%s.", cx->prefix[i]);
358 } else if(cx->multiline == 4) {
363 uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
365 uni_printf(cx, "%s", s);
368 uni_entry(const char *s, struct unicx *cx)
374 uni_print_flag(const char *s, struct unicx *cx)
381 * Start a deeper level of indendation. If multiline is in effect,
382 * we end the current line.
385 uni_print_push_prefix(const char *prefix, struct unicx *cx)
387 if (cx->nprefix < PRINT_NPREFIX)
388 cx->prefix[cx->nprefix++] = prefix;
391 uni_print_pop_prefix(struct unicx *cx)
398 uni_print_tbl(const char *entry, u_int val, const struct uni_print_tbl *tbl,
402 uni_entry(entry, cx);
404 if (tbl->val == val) {
405 uni_printf(cx, "%s", tbl->name);
410 uni_printf(cx, "ERROR(0x%x)", val);
414 uni_print_entry(struct unicx *cx, const char *e, const char *fmt, ...)
421 if (cx->bufsiz > 1) {
423 n = vsnprintf(cx->buf, cx->bufsiz, fmt, ap);
426 if (n < cx->bufsiz) {
430 cx->buf += cx->bufsiz - 1;
438 /**********************************************************************/
440 * Printing information elements.
443 uni_print_iehdr(const char *name, struct uni_iehdr *h, struct unicx *cx)
445 static const struct uni_print_tbl act_tab[] = {
446 MKT(UNI_IEACT_CLEAR, clear),
447 MKT(UNI_IEACT_IGNORE, ignore),
448 MKT(UNI_IEACT_REPORT, report),
449 MKT(UNI_IEACT_MSG_IGNORE, ignore-msg),
450 MKT(UNI_IEACT_MSG_REPORT, report-msg),
451 MKT(UNI_IEACT_DEFAULT, default),
454 static const struct uni_print_tbl cod_tab[] = {
455 MKT(UNI_CODING_ITU, itut),
456 MKT(UNI_CODING_NET, atmf),
460 uni_print_entry(cx, name, "(");
461 uni_print_tbl(NULL, h->act, act_tab, cx);
463 uni_print_tbl(NULL, h->coding, cod_tab, cx);
464 if(cx->pnni && h->pass)
465 uni_printf(cx, ",pass");
466 if(IE_ISEMPTY(*(struct uni_ie_aal *)h)) {
467 uni_printf(cx, ",empty)");
471 if(IE_ISERROR(*(struct uni_ie_aal *)h)) {
472 uni_printf(cx, ",error)");
479 uni_print_push_prefix(name, cx);
487 uni_print_ieend(struct unicx *cx)
489 uni_print_pop_prefix(cx);
495 uni_print_ie_internal(enum uni_ietype code, const union uni_ieall *ie,
498 const struct iedecl *iedecl;
500 if((iedecl = GET_IEDECL(code, ie->h.coding)) != NULL)
501 (*iedecl->print)(ie, cx);
505 uni_print_ie(char *buf, size_t size, enum uni_ietype code,
506 const union uni_ieall *ie, struct unicx *cx)
508 uni_print_init(buf, size, cx);
509 uni_print_ie_internal(code, ie, cx);
513 uni_check_ie(enum uni_ietype code, union uni_ieall *ie, struct unicx *cx)
515 const struct iedecl *iedecl = GET_IEDECL(code, ie->h.coding);
518 return (iedecl->check(ie, cx));
524 * Decode a information element header.
525 * Returns -1 if the message is too short.
526 * Strip the header from the message.
527 * The header is stripped, even if it is too short.
530 uni_decode_ie_hdr(enum uni_ietype *ietype, struct uni_iehdr *hdr,
531 struct uni_msg *msg, struct unicx *cx, u_int *ielen)
535 *ietype = (enum uni_ietype)0;
538 hdr->coding = UNI_CODING_ITU;
539 hdr->act = UNI_IEACT_DEFAULT;
541 if ((len = uni_msg_len(msg)) == 0)
544 *ietype = *msg->b_rptr++;
549 hdr->coding = (*msg->b_rptr >> 5) & 3;
552 switch (*msg->b_rptr & 0x17) {
554 case 0x10: case 0x11: case 0x12:
555 case 0x15: case 0x16:
556 hdr->act = *msg->b_rptr & 0x7;
559 case 0x00: case 0x01: case 0x02: case 0x03:
560 case 0x04: case 0x05: case 0x06: case 0x07:
561 hdr->act = UNI_IEACT_DEFAULT;
565 /* Q.2931 5.7.2 last sentence */
566 hdr->act = UNI_IEACT_REPORT;
569 if (cx->pnni && (*msg->b_rptr & 0x08))
576 hdr->present = UNI_IE_ERROR | UNI_IE_PRESENT;
582 hdr->present = UNI_IE_ERROR | UNI_IE_PRESENT;
586 *ielen = *msg->b_rptr++ << 8;
587 *ielen |= *msg->b_rptr++;
593 * Decode the body of an information element.
596 uni_decode_ie_body(enum uni_ietype ietype, union uni_ieall *ie,
597 struct uni_msg *msg, u_int ielen, struct unicx *cx)
599 const struct iedecl *iedecl;
603 if (ielen > uni_msg_len(msg)) {
605 * Information element too long -> content error.
608 msg->b_rptr = msg->b_wptr;
609 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
613 if ((iedecl = GET_IEDECL(ietype, ie->h.coding)) == NULL) {
615 * entirly unknown IE.
618 msg->b_rptr += ielen;
619 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
623 if (ielen > iedecl->maxlen) {
625 * Information element too long -> content error.
628 msg->b_rptr += iedecl->maxlen;
629 ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
633 end = msg->b_rptr + ielen;
634 ret = (*iedecl->decode)(ie, msg, ielen, cx);
641 uni_encode_ie(enum uni_ietype code, struct uni_msg *msg, union uni_ieall *ie,
644 const struct iedecl *iedecl = GET_IEDECL(code, ie->h.coding);
648 return (iedecl->encode(msg, ie, cx));
652 uni_encode_ie_hdr(struct uni_msg *msg, enum uni_ietype type,
653 struct uni_iehdr *h, u_int len, struct unicx *cx)
657 (void)uni_msg_ensure(msg, 4 + len);
658 *msg->b_wptr++ = type;
660 byte = 0x80 | (h->coding << 5);
661 if(h->act != UNI_IEACT_DEFAULT)
662 byte |= 0x10 | (h->act & 7);
664 byte |= h->pass << 3;
665 *msg->b_wptr++ = byte;
667 if(h->present & UNI_IE_EMPTY) {
682 uni_print_cref_internal(const struct uni_cref *cref, struct unicx *cx)
684 uni_print_entry(cx, "cref", "%d.", cref->flag);
685 if (cref->cref == CREF_GLOBAL)
686 uni_printf(cx, "GLOBAL");
687 else if (cref->cref == CREF_DUMMY)
688 uni_printf(cx, "DUMMY");
690 uni_printf(cx, "%d", cref->cref);
693 uni_print_cref(char *str, size_t len, const struct uni_cref *cref,
696 uni_print_init(str, len, cx);
697 uni_print_cref_internal(cref, cx);
701 uni_print_msghdr_internal(const struct uni_msghdr *hdr, struct unicx *cx)
703 static const struct uni_print_tbl tab[] = {
704 MKT(UNI_MSGACT_CLEAR, clear),
705 MKT(UNI_MSGACT_IGNORE, ignore),
706 MKT(UNI_MSGACT_REPORT, report),
707 MKT(UNI_MSGACT_DEFAULT, default),
711 uni_print_cref_internal(&hdr->cref, cx);
712 uni_print_tbl("act", hdr->act, tab, cx);
714 uni_print_entry(cx, "pass", "%s", hdr->pass ? "yes" : "no");
718 uni_print_msghdr(char *str, size_t len, const struct uni_msghdr *hdr,
721 uni_print_init(str, len, cx);
722 uni_print_msghdr_internal(hdr, cx);
727 uni_print_internal(const struct uni_all *msg, struct unicx *cx)
729 uni_entry("mtype", cx);
730 if(msg->mtype >= 256 || uni_msgtable[msg->mtype] == NULL) {
731 uni_printf(cx, "0x%02x(ERROR)", msg->mtype);
733 uni_printf(cx, "%s", uni_msgtable[msg->mtype]->name);
734 uni_print_msghdr_internal(&msg->u.hdr, cx);
737 (*uni_msgtable[msg->mtype]->print)(&msg->u, cx);
741 if(cx->multiline == 0)
742 uni_printf(cx, "\n");
746 uni_print(char *buf, size_t size, const struct uni_all *all, struct unicx *cx)
748 uni_print_init(buf, size, cx);
749 uni_print_internal(all, cx);
753 uni_print_msg_internal(u_int mtype, const union uni_msgall *msg,
757 uni_entry("mtype", cx);
758 if (mtype >= 256 || uni_msgtable[mtype] == NULL) {
759 uni_printf(cx, "0x%02x(ERROR)", mtype);
761 uni_printf(cx, "%s", uni_msgtable[mtype]->name);
762 uni_print_msghdr_internal(&msg->hdr, cx);
765 (*uni_msgtable[mtype]->print)(msg, cx);
769 if(cx->multiline == 0)
770 uni_printf(cx, "\n");
774 uni_print_msg(char *buf, size_t size, u_int mtype, const union uni_msgall *all,
777 uni_print_init(buf, size, cx);
778 uni_print_msg_internal(mtype, all, cx);
782 uni_print_cx(char *buf, size_t size, struct unicx *cx)
784 static const char *acttab[] = {
796 static const char *errtab[] = {
797 [UNI_IERR_UNK] = "unk", /* unknown IE */
798 [UNI_IERR_LEN] = "len", /* length error */
799 [UNI_IERR_BAD] = "bad", /* content error */
800 [UNI_IERR_ACC] = "acc", /* access element discarded */
801 [UNI_IERR_MIS] = "mis", /* missing IE */
806 uni_print_init(buf, size, cx);
808 uni_printf(cx, "q2932 %d\n", cx->q2932);
809 uni_printf(cx, "pnni %d\n", cx->pnni);
810 uni_printf(cx, "git_hard %d\n", cx->git_hard);
811 uni_printf(cx, "bearer_hard %d\n", cx->bearer_hard);
812 uni_printf(cx, "cause_hard %d\n", cx->cause_hard);
814 uni_printf(cx, "multiline %d\n", cx->multiline);
815 uni_printf(cx, "tabsiz %d\n", cx->tabsiz);
817 uni_printf(cx, "errcnt %d (", cx->errcnt);
818 for(i = 0; i < cx->errcnt; i++) {
819 uni_printf(cx, "%02x[%s,%s%s]", cx->err[i].ie,
820 errtab[cx->err[i].err], acttab[cx->err[i].act],
821 cx->err[i].man ? ",M" : "");
822 if(i != cx->errcnt - 1)
825 uni_printf(cx, ")\n");
828 #include <netnatm/msg/uni_ietab.h>
830 /*********************************************************************
834 * References for this IE are:
836 * Q.2931 pp. 69 (just a pointer to Q.2610)
837 * Q.2610 (this is a small diff to Q.850)
842 * ITU-T and NET coding for different values.
844 static const struct causetab {
847 } itu_causes[128] = {
849 #define D(NAME,VAL,DIAG,STD,STR) [UNI_CAUSE_##NAME] = { STR, UNI_DIAG_##DIAG },
850 #define N(NAME,VAL,DIAG,STD,STR)
852 UNI_DECLARE_CAUSE_VALUES
857 }, net_causes[128] = {
859 #define D(NAME,VAL,DIAG,STD,STR)
860 #define N(NAME,VAL,DIAG,STD,STR) [UNI_CAUSE_##NAME] = { STR, UNI_DIAG_##DIAG },
862 UNI_DECLARE_CAUSE_VALUES
870 uni_diag(enum uni_cause cause, enum uni_coding code)
872 if ((int)cause >= 128)
873 return (UNI_DIAG_NONE);
875 if (code == UNI_CODING_NET)
876 if (net_causes[cause].str != NULL)
877 return (net_causes[cause].diag);
878 if (itu_causes[cause].str != NULL)
879 return (itu_causes[cause].diag);
880 return (UNI_DIAG_NONE);
883 /**********************************************************************/
886 print_cause(struct unicx *cx, struct uni_ie_cause *ie,
887 const struct causetab *tab1, const struct causetab *tab2)
889 static const struct uni_print_tbl loc_tbl[] = {
890 MKT(UNI_CAUSE_LOC_USER, user),
891 MKT(UNI_CAUSE_LOC_PRIVLOC, priv-net:loc-user),
892 MKT(UNI_CAUSE_LOC_PUBLOC, pub-net:loc-user),
893 MKT(UNI_CAUSE_LOC_TRANSIT, transit-net),
894 MKT(UNI_CAUSE_LOC_PUBREM, pub-net:rem-user),
895 MKT(UNI_CAUSE_LOC_PRIVREM, priv-net:rem-user),
896 MKT(UNI_CAUSE_LOC_INTERNAT, int-net),
897 MKT(UNI_CAUSE_LOC_BEYOND, beyond),
900 static const struct uni_print_tbl pu_tbl[] = {
901 MKT(UNI_CAUSE_PU_PROVIDER, provider),
902 MKT(UNI_CAUSE_PU_USER, user),
905 static const struct uni_print_tbl na_tbl[] = {
906 MKT(UNI_CAUSE_NA_NORMAL, normal),
907 MKT(UNI_CAUSE_NA_ABNORMAL, abnormal),
910 static const struct uni_print_tbl cond_tbl[] = {
911 MKT(UNI_CAUSE_COND_UNKNOWN, unknown),
912 MKT(UNI_CAUSE_COND_PERM, permanent),
913 MKT(UNI_CAUSE_COND_TRANS, transient),
916 static const struct uni_print_tbl rej_tbl[] = {
917 MKT(UNI_CAUSE_REASON_USER, user),
918 MKT(UNI_CAUSE_REASON_IEMISS, ie-missing),
919 MKT(UNI_CAUSE_REASON_IESUFF, ie-not-suff),
925 if (uni_print_iehdr("cause", &ie->h, cx))
928 if ((int)ie->cause < 128 && tab1[ie->cause].str)
929 strcpy(buf, tab1[ie->cause].str);
930 else if ((int)ie->cause < 128 && tab2 != NULL && tab2[ie->cause].str != NULL)
931 strcpy(buf, tab2[ie->cause].str);
933 sprintf(buf, "UNKNOWN-%u", ie->cause);
936 for (s = buf; *s != '\0'; s++)
939 uni_print_entry(cx, "cause", "%s", buf);
941 uni_print_tbl("loc", ie->loc, loc_tbl, cx);
943 if (ie->h.present & UNI_CAUSE_COND_P) {
944 uni_print_tbl("pu", ie->u.cond.pu, pu_tbl, cx);
945 uni_print_tbl("na", ie->u.cond.na, na_tbl, cx);
946 uni_print_tbl("condition", ie->u.cond.cond, cond_tbl, cx);
948 if (ie->h.present & UNI_CAUSE_REJ_P) {
949 uni_print_tbl("reject", ie->u.rej.reason, rej_tbl, cx);
951 if (ie->h.present & UNI_CAUSE_REJ_USER_P) {
952 uni_print_entry(cx, "user", "%u", ie->u.rej.user);
954 if (ie->h.present & UNI_CAUSE_REJ_IE_P) {
955 uni_print_entry(cx, "ie", "%u", ie->u.rej.ie);
957 if (ie->h.present & UNI_CAUSE_IE_P) {
958 uni_print_entry(cx, "ie", "(");
959 for (i = 0; i < ie->u.ie.len; i++) {
962 uni_printf(cx, "0x%02x", ie->u.ie.ie[i]);
966 if (ie->h.present & UNI_CAUSE_TRAFFIC_P) {
967 uni_print_entry(cx, "traffic", "(");
968 for (i = 0; i < ie->u.traffic.len; i++) {
971 uni_printf(cx, "0x%02x", ie->u.traffic.traffic[i]);
975 if (ie->h.present & UNI_CAUSE_VPCI_P) {
976 uni_print_entry(cx, "vpci", "(%u,%u)", ie->u.vpci.vpci, ie->u.vpci.vci);
978 if (ie->h.present & UNI_CAUSE_MTYPE_P) {
979 uni_print_entry(cx, "mtype", "%u", ie->u.mtype);
981 if (ie->h.present & UNI_CAUSE_TIMER_P) {
982 for (i = 0, s = buf; i < 3; i++) {
983 if (ie->u.timer[i] < ' ') {
985 *s++ = ie->u.timer[i] + '@';
986 } else if (ie->u.timer[i] <= '~')
987 *s++ = ie->u.timer[i];
990 *s++ = ie->u.timer[i] / 0100 + '0';
991 *s++ = (ie->u.timer[i] % 0100) / 010 + '0';
992 *s++ = ie->u.timer[i] % 010 + '0';
996 uni_print_entry(cx, "timer", "\"%s\"", buf);
998 if (ie->h.present & UNI_CAUSE_TNS_P) {
1000 uni_print_ie_internal(UNI_IE_TNS, (union uni_ieall *)&ie->u.tns, cx);
1002 if (ie->h.present & UNI_CAUSE_NUMBER_P) {
1004 uni_print_ie_internal(UNI_IE_CALLED, (union uni_ieall *)&ie->u.number, cx);
1006 if (ie->h.present & UNI_CAUSE_ATTR_P) {
1007 uni_print_entry(cx, "attr", "(");
1008 for (i = 0; i < ie->u.attr.nattr; i++) {
1009 uni_printf(cx, "(%u", ie->u.attr.attr[i][0]);
1010 if (!(ie->u.attr.attr[i][0] & 0x80)) {
1011 uni_printf(cx, ",%u", ie->u.attr.attr[i][1]);
1012 if (!(ie->u.attr.attr[i][1] & 0x80))
1013 uni_printf(cx, ",%u",
1014 ie->u.attr.attr[i][2]);
1020 uni_print_ieend(cx);
1023 DEF_IE_PRINT(itu, cause)
1025 print_cause(cx, ie, itu_causes, NULL);
1027 DEF_IE_PRINT(net, cause)
1029 print_cause(cx, ie, net_causes, itu_causes);
1033 uni_ie_cause2str(enum uni_coding coding, u_int cause)
1036 if (coding == UNI_CODING_ITU)
1037 return (itu_causes[cause].str);
1038 if (coding == UNI_CODING_NET) {
1039 if (net_causes[cause].str != NULL)
1040 return (net_causes[cause].str);
1041 return (itu_causes[cause].str);
1047 /**********************************************************************/
1050 check_cause(struct uni_ie_cause *ie, struct unicx *cx,
1051 const struct causetab *tab1, const struct causetab *tab2)
1053 static const u_int mask =
1054 UNI_CAUSE_COND_P | UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P |
1055 UNI_CAUSE_REJ_IE_P | UNI_CAUSE_IE_P | UNI_CAUSE_TRAFFIC_P |
1056 UNI_CAUSE_VPCI_P | UNI_CAUSE_MTYPE_P | UNI_CAUSE_TIMER_P |
1057 UNI_CAUSE_TNS_P | UNI_CAUSE_NUMBER_P | UNI_CAUSE_ATTR_P |
1060 const struct causetab *ptr;
1062 if ((int)ie->cause >= 128)
1069 case UNI_CAUSE_LOC_USER:
1070 case UNI_CAUSE_LOC_PRIVLOC:
1071 case UNI_CAUSE_LOC_PUBLOC:
1072 case UNI_CAUSE_LOC_TRANSIT:
1073 case UNI_CAUSE_LOC_PUBREM:
1074 case UNI_CAUSE_LOC_PRIVREM:
1075 case UNI_CAUSE_LOC_INTERNAT:
1076 case UNI_CAUSE_LOC_BEYOND:
1080 if (tab1[ie->cause].str != NULL)
1081 ptr = &tab1[ie->cause];
1082 else if (tab2 != NULL && tab2[ie->cause].str != NULL)
1083 ptr = &tab2[ie->cause];
1085 return (cx->cause_hard ? -1 : 0);
1087 switch (ptr->diag) {
1090 switch (ie->h.present & mask) {
1102 switch (ie->h.present & mask) {
1109 case UNI_CAUSE_COND_P:
1115 switch (ie->h.present & mask) {
1122 case UNI_CAUSE_REJ_P:
1123 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P:
1124 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_IE_P:
1129 case UNI_DIAG_CRATE:
1130 switch (ie->h.present & mask) {
1137 case UNI_CAUSE_TRAFFIC_P:
1143 switch (ie->h.present & mask) {
1150 case UNI_CAUSE_IE_P:
1155 case UNI_DIAG_CHANID:
1156 switch (ie->h.present & mask) {
1163 case UNI_CAUSE_VPCI_P:
1168 case UNI_DIAG_MTYPE:
1169 switch (ie->h.present & mask) {
1176 case UNI_CAUSE_MTYPE_P:
1181 case UNI_DIAG_TIMER:
1182 switch (ie->h.present & mask) {
1189 case UNI_CAUSE_TIMER_P:
1195 switch (ie->h.present & mask) {
1202 case UNI_CAUSE_TNS_P:
1207 case UNI_DIAG_NUMBER:
1208 switch (ie->h.present & mask) {
1215 case UNI_CAUSE_NUMBER_P:
1221 switch (ie->h.present & mask) {
1228 case UNI_CAUSE_ATTR_P:
1233 case UNI_DIAG_PARAM:
1234 switch (ie->h.present & mask) {
1241 case UNI_CAUSE_PARAM_P:
1247 if (ie->h.present & UNI_CAUSE_COND_P) {
1248 switch (ie->u.cond.pu) {
1252 case UNI_CAUSE_PU_PROVIDER:
1253 case UNI_CAUSE_PU_USER:
1256 switch (ie->u.cond.na) {
1260 case UNI_CAUSE_NA_NORMAL:
1261 case UNI_CAUSE_NA_ABNORMAL:
1264 switch (ie->u.cond.cond) {
1268 case UNI_CAUSE_COND_UNKNOWN:
1269 case UNI_CAUSE_COND_PERM:
1270 case UNI_CAUSE_COND_TRANS:
1274 if (ie->h.present & UNI_CAUSE_REJ_P) {
1275 switch (ie->u.rej.reason) {
1279 case UNI_CAUSE_REASON_USER:
1280 switch (ie->h.present & mask) {
1284 case UNI_CAUSE_REJ_P:
1285 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P:
1290 case UNI_CAUSE_REASON_IEMISS:
1291 case UNI_CAUSE_REASON_IESUFF:
1292 switch (ie->h.present & mask) {
1296 case UNI_CAUSE_REJ_P:
1297 case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_IE_P:
1303 if (ie->h.present & UNI_CAUSE_IE_P) {
1304 if (ie->u.ie.len == 0 || ie->u.ie.len > UNI_CAUSE_IE_N)
1307 if (ie->h.present & UNI_CAUSE_TRAFFIC_P) {
1308 if (ie->u.traffic.len == 0 ||
1309 ie->u.traffic.len > UNI_CAUSE_TRAFFIC_N)
1313 if (ie->h.present & UNI_CAUSE_TNS_P) {
1314 if (uni_check_ie(UNI_IE_TNS, (union uni_ieall *)&ie->u.tns, cx))
1317 if (ie->h.present & UNI_CAUSE_NUMBER_P) {
1318 if(uni_check_ie(UNI_IE_CALLED, (union uni_ieall *)&ie->u.number, cx))
1321 if (ie->h.present & UNI_CAUSE_ATTR_P) {
1322 if(ie->u.attr.nattr > UNI_CAUSE_ATTR_N || ie->u.attr.nattr == 0)
1325 if (ie->h.present & UNI_CAUSE_PARAM_P) {
1332 DEF_IE_CHECK(itu, cause)
1334 return (check_cause(ie, cx, itu_causes, NULL));
1336 DEF_IE_CHECK(net, cause)
1338 return (check_cause(ie, cx, net_causes, itu_causes));
1340 /**********************************************************************/
1343 encode_cause(struct uni_msg *msg, struct uni_ie_cause *ie, struct unicx *cx)
1347 START_IE(cause, UNI_IE_CAUSE, 30);
1349 if (IE_ISERROR(*ie)) {
1350 APP_BYTE(msg, 0x00 | ie->loc);
1352 APP_BYTE(msg, 0x80 | ie->loc);
1354 APP_BYTE(msg, 0x80 | ie->cause);
1356 if (ie->h.present & UNI_CAUSE_COND_P)
1357 APP_BYTE(msg, 0x80 | (ie->u.cond.pu << 3) |
1358 (ie->u.cond.na << 2) | ie->u.cond.cond);
1360 else if (ie->h.present & UNI_CAUSE_REJ_P) {
1361 APP_BYTE(msg, 0x80 | (ie->u.rej.reason << 2) | ie->u.rej.cond);
1362 if (ie->h.present & UNI_CAUSE_REJ_USER_P)
1363 APP_BYTE(msg, ie->u.rej.user);
1364 else if (ie->h.present & UNI_CAUSE_REJ_IE_P)
1365 APP_BYTE(msg, ie->u.rej.ie);
1367 } else if(ie->h.present & UNI_CAUSE_IE_P)
1368 APP_BUF(msg, ie->u.ie.ie, ie->u.ie.len);
1370 else if (ie->h.present & UNI_CAUSE_TRAFFIC_P)
1371 APP_BUF(msg, ie->u.traffic.traffic, ie->u.traffic.len);
1373 else if (ie->h.present & UNI_CAUSE_VPCI_P) {
1374 APP_BYTE(msg, (ie->u.vpci.vpci >> 8));
1375 APP_BYTE(msg, (ie->u.vpci.vpci >> 0));
1376 APP_BYTE(msg, (ie->u.vpci.vci >> 8));
1377 APP_BYTE(msg, (ie->u.vpci.vci >> 0));
1379 } else if (ie->h.present & UNI_CAUSE_MTYPE_P)
1380 APP_BYTE(msg, ie->u.mtype);
1382 else if (ie->h.present & UNI_CAUSE_TIMER_P) {
1383 APP_BYTE(msg, ie->u.timer[0]);
1384 APP_BYTE(msg, ie->u.timer[1]);
1385 APP_BYTE(msg, ie->u.timer[2]);
1387 } else if (ie->h.present & UNI_CAUSE_TNS_P)
1388 uni_encode_ie(UNI_IE_TNS, msg,
1389 (union uni_ieall *)&ie->u.tns, cx);
1391 else if (ie->h.present & UNI_CAUSE_NUMBER_P)
1392 uni_encode_ie(UNI_IE_CALLED, msg,
1393 (union uni_ieall *)&ie->u.number, cx);
1395 else if (ie->h.present & UNI_CAUSE_ATTR_P) {
1396 for (i = 0; i < ie->u.attr.nattr; i++) {
1397 APP_BYTE(msg, ie->u.attr.attr[i][0]);
1398 if (!ie->u.attr.attr[i][0]) {
1399 APP_BYTE(msg, ie->u.attr.attr[i][1]);
1400 if (!ie->u.attr.attr[i][1])
1401 APP_BYTE(msg, ie->u.attr.attr[i][2]);
1404 } else if (ie->h.present & UNI_CAUSE_PARAM_P)
1405 APP_BYTE(msg, ie->u.param);
1412 DEF_IE_ENCODE(itu, cause)
1414 return encode_cause(msg, ie, cx);
1416 DEF_IE_ENCODE(net, cause)
1418 return encode_cause(msg, ie, cx);
1421 /**********************************************************************/
1424 decode_cause(struct uni_ie_cause *ie, struct uni_msg *msg, u_int ielen,
1425 struct unicx *cx, const struct causetab *tab1, const struct causetab *tab2)
1428 const struct causetab *ptr;
1429 enum uni_ietype ietype;
1434 if(ielen < 2 || ielen > 30)
1447 ie->cause = c & 0x7f;
1449 if(tab1[ie->cause].str != NULL)
1450 ptr = &tab1[ie->cause];
1451 else if(tab2 != NULL && tab2[ie->cause].str != NULL)
1452 ptr = &tab2[ie->cause];
1455 ielen = 0; /* ignore diags */
1470 ie->h.present |= UNI_CAUSE_COND_P;
1471 ie->u.cond.pu = (c >> 3) & 1;
1472 ie->u.cond.na = (c >> 2) & 1;
1473 ie->u.cond.cond = c & 3;
1485 ie->h.present |= UNI_CAUSE_REJ_P;
1486 ie->u.rej.reason = (c >> 2) & 0x1f;
1487 ie->u.rej.cond = c & 3;
1496 switch(ie->u.rej.reason) {
1498 case UNI_CAUSE_REASON_USER:
1499 ie->h.present |= UNI_CAUSE_REJ_USER_P;
1503 case UNI_CAUSE_REASON_IEMISS:
1504 case UNI_CAUSE_REASON_IESUFF:
1505 ie->h.present |= UNI_CAUSE_REJ_IE_P;
1512 case UNI_DIAG_CRATE:
1513 ie->h.present |= UNI_CAUSE_TRAFFIC_P;
1514 while(ielen && ie->u.traffic.len < UNI_CAUSE_TRAFFIC_N) {
1515 ie->u.traffic.traffic[ie->u.traffic.len++] =
1522 ie->h.present |= UNI_CAUSE_IE_P;
1523 while(ielen && ie->u.ie.len < UNI_CAUSE_IE_N) {
1524 ie->u.ie.ie[ie->u.ie.len++] = *msg->b_rptr++;
1529 case UNI_DIAG_CHANID:
1532 ie->h.present |= UNI_CAUSE_VPCI_P;
1533 ie->u.vpci.vpci = *msg->b_rptr++ << 8;
1534 ie->u.vpci.vpci |= *msg->b_rptr++;
1535 ie->u.vpci.vci = *msg->b_rptr++ << 8;
1536 ie->u.vpci.vci |= *msg->b_rptr++;
1540 case UNI_DIAG_MTYPE:
1541 ie->h.present |= UNI_CAUSE_MTYPE_P;
1542 ie->u.mtype = *msg->b_rptr++;
1546 case UNI_DIAG_TIMER:
1549 ie->h.present |= UNI_CAUSE_TIMER_P;
1550 ie->u.timer[0] = *msg->b_rptr++;
1551 ie->u.timer[1] = *msg->b_rptr++;
1552 ie->u.timer[2] = *msg->b_rptr++;
1559 if(uni_decode_ie_hdr(&ietype, &ie->u.tns.h, msg, cx, &xielen))
1561 if(ietype != UNI_IE_TNS)
1563 if(uni_decode_ie_body(ietype,
1564 (union uni_ieall *)&ie->u.tns, msg, xielen, cx))
1566 ie->h.present |= UNI_CAUSE_TNS_P;
1569 case UNI_DIAG_NUMBER:
1572 if(uni_decode_ie_hdr(&ietype, &ie->u.number.h, msg, cx, &xielen))
1574 if(ietype != UNI_IE_CALLED)
1576 if(uni_decode_ie_body(ietype,
1577 (union uni_ieall *)&ie->u.number, msg, xielen, cx))
1579 ie->h.present |= UNI_CAUSE_NUMBER_P;
1583 ie->h.present |= UNI_CAUSE_ATTR_P;
1584 while(ielen > 0 && ie->u.attr.nattr < UNI_CAUSE_ATTR_N) {
1586 ie->u.attr.attr[ie->u.attr.nattr][0] = c;
1588 if(ielen > 0 && !(c & 0x80)) {
1590 ie->u.attr.attr[ie->u.attr.nattr][1] = c;
1592 if(ielen > 0 && !(c & 0x80)) {
1594 ie->u.attr.attr[ie->u.attr.nattr][2] = c;
1601 case UNI_DIAG_PARAM:
1602 ie->h.present |= UNI_CAUSE_PARAM_P;
1603 ie->u.param = *msg->b_rptr++;
1612 DEF_IE_DECODE(itu, cause)
1614 return decode_cause(ie, msg, ielen, cx, itu_causes, NULL);
1616 DEF_IE_DECODE(net, cause)
1618 return decode_cause(ie, msg, ielen, cx, net_causes, itu_causes);
1621 /*********************************************************************
1625 * References for this IE are:
1627 * Q.2931 pp. 59...60
1630 * Only ITU-T coding allowed.
1632 DEF_IE_PRINT(itu, callstate)
1634 static const struct uni_print_tbl tbl[] = {
1635 MKT(UNI_CALLSTATE_U0, U0/N0/REST0),
1636 MKT(UNI_CALLSTATE_U1, U1/N1),
1637 MKT(UNI_CALLSTATE_U3, U3/N3),
1638 MKT(UNI_CALLSTATE_U4, U4/N4),
1639 MKT(UNI_CALLSTATE_U6, U6/N6),
1640 MKT(UNI_CALLSTATE_U7, U7/N7),
1641 MKT(UNI_CALLSTATE_U8, U8/N8),
1642 MKT(UNI_CALLSTATE_U9, U9/N9),
1643 MKT(UNI_CALLSTATE_U10, U10/N10),
1644 MKT(UNI_CALLSTATE_U11, U11/N11),
1645 MKT(UNI_CALLSTATE_U12, U12/N12),
1646 MKT(UNI_CALLSTATE_REST1,REST1),
1647 MKT(UNI_CALLSTATE_REST2,REST2),
1648 MKT(UNI_CALLSTATE_U13, U13/N13),
1649 MKT(UNI_CALLSTATE_U14, U14/N14),
1653 if(uni_print_iehdr("callstate", &ie->h, cx))
1655 uni_print_tbl("state", ie->state, tbl, cx);
1656 uni_print_ieend(cx);
1659 DEF_IE_CHECK(itu, callstate)
1667 case UNI_CALLSTATE_U0:
1668 case UNI_CALLSTATE_U1:
1669 case UNI_CALLSTATE_U3:
1670 case UNI_CALLSTATE_U4:
1671 case UNI_CALLSTATE_U6:
1672 case UNI_CALLSTATE_U7:
1673 case UNI_CALLSTATE_U8:
1674 case UNI_CALLSTATE_U9:
1675 case UNI_CALLSTATE_U10:
1676 case UNI_CALLSTATE_U11:
1677 case UNI_CALLSTATE_U12:
1678 case UNI_CALLSTATE_REST1:
1679 case UNI_CALLSTATE_REST2:
1680 case UNI_CALLSTATE_U13:
1681 case UNI_CALLSTATE_U14:
1688 DEF_IE_ENCODE(itu, callstate)
1690 START_IE(callstate, UNI_IE_CALLSTATE, 1);
1692 APP_BYTE(msg, ie->state);
1698 DEF_IE_DECODE(itu, callstate)
1705 ie->state = *msg->b_rptr++ & 0x3f;
1711 /*********************************************************************
1713 * Facility Information.
1715 * References for this IE are:
1719 * The standard allows only ROSE as protocol. We allow everything up to the
1722 * Only ITU-T coding allowed.
1724 DEF_IE_PRINT(itu, facility)
1728 if(uni_print_iehdr("facility", &ie->h, cx))
1731 if(ie->proto == UNI_FACILITY_ROSE)
1732 uni_print_entry(cx, "proto", "rose");
1734 uni_print_entry(cx, "proto", "0x%02x", ie->proto);
1736 uni_print_entry(cx, "len", "%u", ie->len);
1737 uni_print_entry(cx, "info", "(");
1738 for(i = 0; i < ie->len; i++)
1739 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->apdu[i]);
1740 uni_printf(cx, ")");
1742 uni_print_ieend(cx);
1745 DEF_IE_CHECK(itu, facility)
1749 if(ie->len > UNI_FACILITY_MAXAPDU)
1755 DEF_IE_ENCODE(itu, facility)
1757 START_IE(facility, UNI_IE_FACILITY, 1 + ie->len);
1759 APP_BYTE(msg, ie->proto | 0x80);
1760 APP_BUF(msg, ie->apdu, ie->len);
1766 DEF_IE_DECODE(itu, facility)
1772 if(ielen > UNI_FACILITY_MAXAPDU + 1 || ielen < 1)
1775 ie->proto = (c = *msg->b_rptr++) & 0x1f;
1777 if((c & 0xe0) != 0x80)
1782 (void)memcpy(ie->apdu, msg->b_rptr, ie->len);
1783 msg->b_rptr += ie->len;
1788 /*********************************************************************
1790 * Notification Indicator
1792 * References for this IE are:
1797 * Only ITU-T coding allowed.
1800 DEF_IE_PRINT(itu, notify)
1804 if(uni_print_iehdr("notify", &ie->h, cx))
1806 uni_print_entry(cx, "len", "%u", ie->len);
1807 uni_print_entry(cx, "info", "(");
1808 for(i = 0; i < ie->len; i++)
1809 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->notify[i]);
1810 uni_printf(cx, ")");
1811 uni_print_ieend(cx);
1814 DEF_IE_CHECK(itu, notify)
1818 if(ie->len > UNI_NOTIFY_MAXLEN)
1824 DEF_IE_ENCODE(itu, notify)
1826 START_IE(notify, UNI_IE_NOTIFY, ie->len);
1828 APP_BUF(msg, ie->notify, ie->len);
1829 if (IE_ISERROR(*ie)) {
1830 /* make it too long */
1833 while (i < UNI_NOTIFY_MAXLEN + 1) {
1834 APP_BYTE(msg, 0x00);
1843 DEF_IE_DECODE(itu, notify)
1847 if (ielen > UNI_NOTIFY_MAXLEN || ielen < 1)
1852 (void)memcpy(ie->notify, msg->b_rptr, ie->len);
1853 msg->b_rptr += ie->len;
1858 /*********************************************************************
1860 * End-to-end transit delay.
1862 * References for this IE are:
1864 * Q.2931 pp. 70...71
1865 * UNI4.0 pp. 69...70
1866 * PNNI1.0 pp. 198...200
1868 * Not clear, whether the new indicator should be used with NET coding or
1871 * Only ITU-T coding allowed.
1875 print_eetd(struct uni_ie_eetd *ie, struct unicx *cx)
1877 if (uni_print_iehdr("eetd", &ie->h, cx))
1880 if (ie->h.present & UNI_EETD_CUM_P)
1881 uni_print_entry(cx, "cum", "%u", ie->cumulative);
1882 if (ie->h.present & UNI_EETD_MAX_P) {
1883 if (ie->maximum == UNI_EETD_ANYMAX)
1884 uni_print_entry(cx, "max", "any");
1886 uni_print_entry(cx, "max", "%u", ie->maximum);
1888 if (ie->h.present & UNI_EETD_PCTD_P)
1889 uni_print_entry(cx, "pnni_cum", "%u", ie->pctd);
1890 if (ie->h.present & UNI_EETD_PMTD_P)
1891 uni_print_entry(cx, "pnni_max", "%u", ie->pmtd);
1892 if (ie->h.present & UNI_EETD_NET_P)
1893 uni_print_flag("netgen", cx);
1895 uni_print_ieend(cx);
1897 DEF_IE_PRINT(itu, eetd)
1901 DEF_IE_PRINT(net, eetd)
1906 DEF_IE_CHECK(itu, eetd)
1911 if (!(ie->h.present & UNI_EETD_CUM_P))
1913 if (ie->h.present & (UNI_EETD_PMTD_P | UNI_EETD_PCTD_P))
1918 DEF_IE_CHECK(net, eetd)
1922 if (!(ie->h.present & UNI_EETD_CUM_P))
1924 if (ie->h.present & (UNI_EETD_PMTD_P | UNI_EETD_PCTD_P))
1927 if (ie->h.present & UNI_EETD_MAX_P)
1929 if ((ie->h.present & UNI_EETD_CUM_P) &&
1930 (ie->h.present & UNI_EETD_PCTD_P))
1936 DEF_IE_ENCODE(itu, eetd)
1938 START_IE(eetd, UNI_IE_EETD, 9);
1940 if (ie->h.present & UNI_EETD_CUM_P) {
1941 APP_BYTE(msg, UNI_EETD_CTD_ID);
1942 APP_16BIT(msg, ie->cumulative);
1944 if (ie->h.present & UNI_EETD_MAX_P) {
1945 APP_BYTE(msg, UNI_EETD_MTD_ID);
1946 APP_16BIT(msg, ie->maximum);
1948 if (ie->h.present & UNI_EETD_PMTD_P) {
1949 APP_BYTE(msg, UNI_EETD_PMTD_ID);
1950 APP_24BIT(msg, ie->pmtd);
1952 if (ie->h.present & UNI_EETD_PCTD_P) {
1953 APP_BYTE(msg, UNI_EETD_PCTD_ID);
1954 APP_24BIT(msg, ie->pctd);
1956 if (ie->h.present & UNI_EETD_NET_P) {
1957 APP_BYTE(msg, UNI_EETD_NET_ID);
1964 DEF_IE_ENCODE(net, eetd)
1966 return (uni_ie_encode_itu_eetd(msg, ie, cx));
1969 DEF_IE_DECODE(itu, eetd)
1974 switch (ielen--, *msg->b_rptr++) {
1976 case UNI_EETD_CTD_ID:
1979 ie->h.present |= UNI_EETD_CUM_P;
1980 ie->cumulative = *msg->b_rptr++ << 8;
1981 ie->cumulative |= *msg->b_rptr++;
1985 case UNI_EETD_MTD_ID:
1988 ie->h.present |= UNI_EETD_MAX_P;
1989 ie->maximum = *msg->b_rptr++ << 8;
1990 ie->maximum |= *msg->b_rptr++;
1994 case UNI_EETD_PCTD_ID:
1997 ie->h.present |= UNI_EETD_PCTD_P;
1998 ie->pctd = *msg->b_rptr++ << 16;
1999 ie->pctd |= *msg->b_rptr++ << 8;
2000 ie->pctd |= *msg->b_rptr++;
2004 case UNI_EETD_PMTD_ID:
2007 ie->h.present |= UNI_EETD_PMTD_P;
2008 ie->pmtd = *msg->b_rptr++ << 16;
2009 ie->pmtd |= *msg->b_rptr++ << 8;
2010 ie->pmtd |= *msg->b_rptr++;
2014 case UNI_EETD_NET_ID:
2015 ie->h.present |= UNI_EETD_NET_P;
2025 DEF_IE_DECODE(net, eetd)
2027 return (uni_ie_decode_itu_eetd(ie, msg, ielen, cx));
2030 /*********************************************************************
2035 * Calling subaddress
2037 * Connected subaddress
2039 * References for this IE are:
2041 * Q.2931 pp. 60...68
2043 * UNI4.0 pp. 14...15
2044 * Q.2951 pp. 28...40
2046 * It is assumed, that the coding of the addr arrays is ok.
2048 * Only ITU-T coding allowed.
2051 static const struct uni_print_tbl screen_tbl[] = {
2052 MKT(UNI_ADDR_SCREEN_NOT, no),
2053 MKT(UNI_ADDR_SCREEN_PASSED, passed),
2054 MKT(UNI_ADDR_SCREEN_FAILED, failed),
2055 MKT(UNI_ADDR_SCREEN_NET, network),
2058 static const struct uni_print_tbl pres_tbl[] = {
2059 MKT(UNI_ADDR_PRES, allowed),
2060 MKT(UNI_ADDR_RESTRICT, restricted),
2061 MKT(UNI_ADDR_NONUMBER, no-number),
2067 print_addr(struct unicx *cx, struct uni_addr *addr)
2069 static const struct uni_print_tbl plan_tbl[] = {
2070 MKT(UNI_ADDR_UNKNOWN, unknown),
2071 MKT(UNI_ADDR_E164, E164),
2072 MKT(UNI_ADDR_ATME, ATME),
2073 MKT(UNI_ADDR_DATA, data),
2074 MKT(UNI_ADDR_PRIVATE, private),
2077 static const struct uni_print_tbl type_tbl[] = {
2078 MKT(UNI_ADDR_UNKNOWN, unknown),
2079 MKT(UNI_ADDR_INTERNATIONAL, international),
2080 MKT(UNI_ADDR_NATIONAL, national),
2081 MKT(UNI_ADDR_NETWORK, network),
2082 MKT(UNI_ADDR_SUBSCR, subscriber),
2083 MKT(UNI_ADDR_ABBR, abbreviated),
2088 uni_print_entry(cx, "addr", "(");
2089 uni_print_tbl(NULL, addr->type, type_tbl, cx);
2091 uni_print_tbl(NULL, addr->plan, plan_tbl, cx);
2093 if(addr->plan == UNI_ADDR_E164) {
2095 for(i = 0; i < addr->len; i++) {
2096 if(addr->addr[i] < ' ')
2097 uni_printf(cx, "^%c", addr->addr[i] + '@');
2098 else if(addr->addr[i] <= '~')
2099 uni_putc(addr->addr[i], cx);
2101 uni_printf(cx, "\\%03o", addr->addr[i]);
2105 } else if(addr->plan == UNI_ADDR_ATME) {
2106 for(i = 0; i < addr->len; i++)
2107 uni_printf(cx, "%02x", addr->addr[i]);
2113 print_addrsub(struct unicx *cx, struct uni_subaddr *addr)
2115 static const struct uni_print_tbl type_tbl[] = {
2116 MKT(UNI_SUBADDR_NSAP, NSAP),
2117 MKT(UNI_SUBADDR_ATME, ATME),
2118 MKT(UNI_SUBADDR_USER, USER),
2123 uni_print_entry(cx, "addr", "(");
2124 uni_print_tbl(NULL, addr->type, type_tbl, cx);
2127 for(i = 0; i < addr->len; i++)
2128 uni_printf(cx, "%02x", addr->addr[i]);
2134 check_addr(struct uni_addr *addr)
2138 switch(addr->plan) {
2143 if(addr->type != UNI_ADDR_INTERNATIONAL)
2145 if(addr->len > 15 || addr->len == 0)
2147 for(i = 0; i < addr->len; i++)
2148 if(addr->addr[i] == 0 || (addr->addr[i] & 0x80))
2153 if(addr->type != UNI_ADDR_UNKNOWN)
2164 check_subaddr(struct uni_subaddr *addr)
2166 switch(addr->type) {
2170 case UNI_SUBADDR_NSAP:
2175 case UNI_SUBADDR_ATME:
2184 check_screen(enum uni_addr_screen screen, enum uni_addr_pres pres)
2191 case UNI_ADDR_RESTRICT:
2192 case UNI_ADDR_NONUMBER:
2199 case UNI_ADDR_SCREEN_NOT:
2200 case UNI_ADDR_SCREEN_PASSED:
2201 case UNI_ADDR_SCREEN_FAILED:
2202 case UNI_ADDR_SCREEN_NET:
2210 encode_addr(struct uni_msg *msg, struct uni_addr *addr, u_int flag,
2211 enum uni_addr_screen screen, enum uni_addr_pres pres, int err)
2213 u_char ext = err ? 0x00 : 0x80;
2216 APP_BYTE(msg, (addr->type << 4) | addr->plan);
2217 APP_BYTE(msg, ext | (pres << 5) | (screen));
2219 APP_BYTE(msg, ext | (addr->type << 4) | addr->plan);
2221 APP_BUF(msg, addr->addr, addr->len);
2225 encode_subaddr(struct uni_msg *msg, struct uni_subaddr *addr)
2227 APP_BYTE(msg, 0x80|(addr->type<<4));
2228 APP_BUF(msg, addr->addr, addr->len);
2232 decode_addr(struct uni_addr *addr, u_int ielen, struct uni_msg *msg, u_int plan)
2234 addr->plan = plan & 0xf;
2235 addr->type = (plan >> 4) & 0x7;
2237 switch(addr->plan) {
2240 if(ielen > 15 || ielen == 0)
2242 addr->addr[ielen] = 0;
2253 (void)memcpy(addr->addr, msg->b_rptr, ielen);
2255 msg->b_rptr += ielen;
2261 decode_subaddr(struct uni_subaddr *addr, u_int ielen, struct uni_msg *msg,
2264 switch(addr->type = (type >> 4) & 0x7) {
2266 case UNI_SUBADDR_NSAP:
2267 if(ielen == 0 || ielen > 20)
2271 case UNI_SUBADDR_ATME:
2281 if((type & 0x7) != 0)
2285 (void)memcpy(addr->addr, msg->b_rptr, ielen);
2286 msg->b_rptr += ielen;
2291 /**********************************************************************/
2293 DEF_IE_PRINT(itu, called)
2295 if (uni_print_iehdr("called", &ie->h, cx))
2297 print_addr(cx, &ie->addr);
2298 uni_print_ieend(cx);
2301 DEF_IE_CHECK(itu, called)
2305 if (check_addr(&ie->addr))
2310 DEF_IE_ENCODE(itu, called)
2312 START_IE(called, UNI_IE_CALLED, 21);
2313 encode_addr(msg, &ie->addr, 0, 0, 0, IE_ISERROR(*ie));
2318 DEF_IE_DECODE(itu, called)
2323 if (ielen > 21 || ielen < 1)
2332 if (decode_addr(&ie->addr, ielen, msg, c))
2338 /**********************************************************************/
2340 DEF_IE_PRINT(itu, calledsub)
2342 if(uni_print_iehdr("calledsub", &ie->h, cx))
2344 print_addrsub(cx, &ie->addr);
2345 uni_print_ieend(cx);
2348 DEF_IE_CHECK(itu, calledsub)
2352 if(check_subaddr(&ie->addr))
2357 DEF_IE_ENCODE(itu, calledsub)
2359 START_IE(calledsub, UNI_IE_CALLEDSUB, 21);
2360 encode_subaddr(msg, &ie->addr);
2365 DEF_IE_DECODE(itu, calledsub)
2377 if(decode_subaddr(&ie->addr, ielen, msg, c))
2383 /**********************************************************************/
2385 DEF_IE_PRINT(itu, calling)
2387 if(uni_print_iehdr("calling", &ie->h, cx))
2389 print_addr(cx, &ie->addr);
2391 if(ie->h.present & UNI_CALLING_SCREEN_P) {
2392 uni_print_tbl("screening", ie->screen, screen_tbl, cx);
2393 uni_print_tbl("presentation", ie->pres, pres_tbl, cx);
2396 uni_print_ieend(cx);
2399 DEF_IE_CHECK(itu, calling)
2403 if(check_addr(&ie->addr))
2406 if(ie->h.present & UNI_CALLING_SCREEN_P)
2407 if(check_screen(ie->screen, ie->pres))
2412 DEF_IE_ENCODE(itu, calling)
2414 START_IE(calling, UNI_IE_CALLING, 22);
2415 encode_addr(msg, &ie->addr, ie->h.present & UNI_CALLING_SCREEN_P, ie->screen, ie->pres, IE_ISERROR(*ie));
2420 DEF_IE_DECODE(itu, calling)
2426 if(ielen > 22 || ielen < 1)
2429 plan = *msg->b_rptr++;
2432 if(!(plan & 0x80)) {
2438 ie->h.present |= UNI_CALLING_SCREEN_P;
2439 ie->pres = (c >> 5) & 0x3;
2440 ie->screen = c & 0x3;
2446 if(decode_addr(&ie->addr, ielen, msg, plan))
2452 /**********************************************************************/
2454 DEF_IE_PRINT(itu, callingsub)
2456 if(uni_print_iehdr("callingsub", &ie->h, cx))
2458 print_addrsub(cx, &ie->addr);
2459 uni_print_ieend(cx);
2462 DEF_IE_CHECK(itu, callingsub)
2466 if(check_subaddr(&ie->addr))
2471 DEF_IE_ENCODE(itu, callingsub)
2473 START_IE(callingsub, UNI_IE_CALLINGSUB, 21);
2474 encode_subaddr(msg, &ie->addr);
2479 DEF_IE_DECODE(itu, callingsub)
2491 if(decode_subaddr(&ie->addr, ielen, msg, c))
2497 /**********************************************************************/
2499 DEF_IE_PRINT(itu, conned)
2501 if(uni_print_iehdr("conned", &ie->h, cx))
2503 print_addr(cx, &ie->addr);
2505 if(ie->h.present & UNI_CONNED_SCREEN_P) {
2506 uni_print_tbl("screening", ie->screen, screen_tbl, cx);
2507 uni_print_tbl("presentation", ie->pres, pres_tbl, cx);
2510 uni_print_ieend(cx);
2513 DEF_IE_CHECK(itu, conned)
2517 if(check_addr(&ie->addr))
2520 if(ie->h.present & UNI_CONNED_SCREEN_P)
2521 if(check_screen(ie->screen, ie->pres))
2526 DEF_IE_ENCODE(itu, conned)
2528 START_IE(conned, UNI_IE_CONNED, 22);
2529 encode_addr(msg, &ie->addr, ie->h.present & UNI_CONNED_SCREEN_P, ie->screen, ie->pres, IE_ISERROR(*ie));
2534 DEF_IE_DECODE(itu, conned)
2540 if(ielen > 22 || ielen < 1)
2543 plan = *msg->b_rptr++;
2546 if(!(plan & 0x80)) {
2552 ie->h.present |= UNI_CONNED_SCREEN_P;
2553 ie->pres = (c >> 5) & 0x3;
2554 ie->screen = c & 0x3;
2560 if(decode_addr(&ie->addr, ielen, msg, plan))
2566 /**********************************************************************/
2568 DEF_IE_PRINT(itu, connedsub)
2570 if(uni_print_iehdr("connedsub", &ie->h, cx))
2572 print_addrsub(cx, &ie->addr);
2573 uni_print_ieend(cx);
2576 DEF_IE_CHECK(itu, connedsub)
2580 if(check_subaddr(&ie->addr))
2585 DEF_IE_ENCODE(itu, connedsub)
2587 START_IE(connedsub, UNI_IE_CONNEDSUB, 21);
2588 encode_subaddr(msg, &ie->addr);
2593 DEF_IE_DECODE(itu, connedsub)
2605 if(decode_subaddr(&ie->addr, ielen, msg, c))
2611 /*********************************************************************
2613 * Endpoint reference.
2615 * References for this IE are:
2619 * Only ITU-T coding allowed.
2622 DEF_IE_PRINT(itu, epref)
2624 if(uni_print_iehdr("epref", &ie->h, cx))
2626 uni_print_entry(cx, "epref", "(%u,%u)", ie->flag, ie->epref);
2627 uni_print_ieend(cx);
2630 DEF_IE_CHECK(itu, epref)
2634 if(ie->epref >= (2<<15))
2640 DEF_IE_ENCODE(itu, epref)
2642 START_IE(epref, UNI_IE_EPREF, 3);
2644 if (IE_ISERROR(*ie))
2645 APP_BYTE(msg, 0xff);
2648 APP_BYTE(msg, (ie->flag << 7) | ((ie->epref >> 8) & 0x7f));
2649 APP_BYTE(msg, (ie->epref & 0xff));
2655 DEF_IE_DECODE(itu, epref)
2663 if(*msg->b_rptr++ != 0)
2667 ie->flag = (c & 0x80) ? 1 : 0;
2668 ie->epref = (c & 0x7f) << 8;
2669 ie->epref |= *msg->b_rptr++;
2674 /*********************************************************************
2678 * References for this IE are:
2680 * Q.2971 pp. 14...15
2682 * Only ITU-T coding allowed.
2685 DEF_IE_PRINT(itu, epstate)
2687 static const struct uni_print_tbl tbl[] = {
2688 MKT(UNI_EPSTATE_NULL, null),
2689 MKT(UNI_EPSTATE_ADD_INIT, add-initiated),
2690 MKT(UNI_EPSTATE_ALERT_DLVD, alerting-delivered),
2691 MKT(UNI_EPSTATE_ADD_RCVD, add-received),
2692 MKT(UNI_EPSTATE_ALERT_RCVD, alerting-received),
2693 MKT(UNI_EPSTATE_ACTIVE, active),
2694 MKT(UNI_EPSTATE_DROP_INIT, drop-initiated),
2695 MKT(UNI_EPSTATE_DROP_RCVD, drop-received),
2699 if(uni_print_iehdr("epstate", &ie->h, cx))
2701 uni_print_tbl("state", ie->state, tbl, cx);
2702 uni_print_ieend(cx);
2705 DEF_IE_CHECK(itu, epstate)
2713 case UNI_EPSTATE_NULL:
2714 case UNI_EPSTATE_ADD_INIT:
2715 case UNI_EPSTATE_ALERT_DLVD:
2716 case UNI_EPSTATE_ADD_RCVD:
2717 case UNI_EPSTATE_ALERT_RCVD:
2718 case UNI_EPSTATE_DROP_INIT:
2719 case UNI_EPSTATE_DROP_RCVD:
2720 case UNI_EPSTATE_ACTIVE:
2727 DEF_IE_ENCODE(itu, epstate)
2729 START_IE(epstate, UNI_IE_EPSTATE, 1);
2731 APP_BYTE(msg, ie->state);
2737 DEF_IE_DECODE(itu, epstate)
2744 ie->state = *msg->b_rptr++ & 0x3f;
2749 /*********************************************************************
2751 * ATM adaptation layer parameters
2753 * References for this IE are:
2755 * Q.2931 pp. 43...49
2759 * UNI4.0 states, that AAL2 is not supported. However we keep it. No
2760 * parameters are associated with AAL2.
2762 * Amd2 not checked. XXX
2764 * Only ITU-T coding allowed.
2766 DEF_IE_PRINT(itu, aal)
2768 static const struct uni_print_tbl aal_tbl[] = {
2769 MKT(UNI_AAL_0, VOICE),
2772 MKT(UNI_AAL_4, 3/4),
2774 MKT(UNI_AAL_USER, USER),
2777 static const struct uni_print_tbl subtype_tbl[] = {
2778 MKT(UNI_AAL1_SUB_NULL, null),
2779 MKT(UNI_AAL1_SUB_VOICE, voice),
2780 MKT(UNI_AAL1_SUB_CIRCUIT, circuit),
2781 MKT(UNI_AAL1_SUB_HQAUDIO, hqaudio),
2782 MKT(UNI_AAL1_SUB_VIDEO, video),
2785 static const struct uni_print_tbl cbr_rate_tbl[] = {
2786 MKT(UNI_AAL1_CBR_64, 64),
2787 MKT(UNI_AAL1_CBR_1544, 1544(DS1)),
2788 MKT(UNI_AAL1_CBR_6312, 6312(DS2)),
2789 MKT(UNI_AAL1_CBR_32064, 32064),
2790 MKT(UNI_AAL1_CBR_44736, 44736(DS3)),
2791 MKT(UNI_AAL1_CBR_97728, 97728),
2792 MKT(UNI_AAL1_CBR_2048, 2048(E1)),
2793 MKT(UNI_AAL1_CBR_8448, 8448(E2)),
2794 MKT(UNI_AAL1_CBR_34368, 34368(E3)),
2795 MKT(UNI_AAL1_CBR_139264, 139264),
2796 MKT(UNI_AAL1_CBR_N64, Nx64),
2797 MKT(UNI_AAL1_CBR_N8, Nx8),
2800 static const struct uni_print_tbl screc_tbl[] = {
2801 MKT(UNI_AAL1_SCREC_NULL, null),
2802 MKT(UNI_AAL1_SCREC_SRTS, srts),
2803 MKT(UNI_AAL1_SCREC_ACLK, aclk),
2806 static const struct uni_print_tbl ecm_tbl[] = {
2807 MKT(UNI_AAL1_ECM_NULL, null),
2808 MKT(UNI_AAL1_ECM_LOSS, loss),
2809 MKT(UNI_AAL1_ECM_DELAY, delay),
2812 static const struct uni_print_tbl sscs_tbl[] = {
2813 MKT(UNI_AAL_SSCS_NULL, null),
2814 MKT(UNI_AAL_SSCS_SSCOPA, sscopa),
2815 MKT(UNI_AAL_SSCS_SSCOPU, sscopu),
2816 MKT(UNI_AAL_SSCS_FRAME, frame),
2820 if(uni_print_iehdr("aal", &ie->h, cx))
2822 uni_print_tbl("type", ie->type, aal_tbl, cx);
2827 uni_print_push_prefix("0", cx);
2832 uni_print_push_prefix("2", cx);
2837 uni_print_push_prefix("1", cx);
2839 uni_print_tbl("subtype", ie->u.aal1.subtype, subtype_tbl, cx);
2840 uni_print_tbl("cbr_rate", ie->u.aal1.cbr_rate, cbr_rate_tbl, cx);
2841 if(ie->h.present & UNI_AAL1_MULT_P)
2842 uni_print_entry(cx, "mult", "%u", ie->u.aal1.mult);
2843 if(ie->h.present & UNI_AAL1_SCREC_P)
2844 uni_print_tbl("screc", ie->u.aal1.screc, screc_tbl, cx);
2845 if(ie->h.present & UNI_AAL1_ECM_P)
2846 uni_print_tbl("ecm", ie->u.aal1.ecm, ecm_tbl, cx);
2847 if(ie->h.present & UNI_AAL1_BSIZE_P)
2848 uni_print_entry(cx, "bsize", "%u", ie->u.aal1.bsize);
2849 if(ie->h.present & UNI_AAL1_PART_P)
2850 uni_print_entry(cx, "part", "%u", ie->u.aal1.part);
2854 uni_print_push_prefix("4", cx);
2856 if(ie->h.present & UNI_AAL4_CPCS_P)
2857 uni_print_entry(cx, "cpcs", "(%u,%u)", ie->u.aal4.fwd_cpcs,
2858 ie->u.aal4.bwd_cpcs);
2859 if(ie->h.present & UNI_AAL4_MID_P)
2860 uni_print_entry(cx, "mid", "(%u,%u)", ie->u.aal4.mid_low,
2861 ie->u.aal4.mid_high);
2862 if(ie->h.present & UNI_AAL4_SSCS_P)
2863 uni_print_tbl("sscs", ie->u.aal4.sscs, sscs_tbl, cx);
2867 uni_print_push_prefix("5", cx);
2869 if(ie->h.present & UNI_AAL5_CPCS_P)
2870 uni_print_entry(cx, "cpcs", "(%u,%u)", ie->u.aal5.fwd_cpcs,
2871 ie->u.aal5.bwd_cpcs);
2872 if(ie->h.present & UNI_AAL5_SSCS_P)
2873 uni_print_tbl("sscs", ie->u.aal5.sscs, sscs_tbl, cx);
2877 uni_print_push_prefix("user", cx);
2879 if(ie->u.aalu.len > 4) {
2880 uni_print_entry(cx, "info", "ERROR(len=%u)", ie->u.aalu.len);
2884 uni_print_entry(cx, "info", "(");
2885 for(i = 0; i < ie->u.aalu.len; i++)
2886 uni_printf(cx, "%s%u", !i?"":",", ie->u.aalu.user[i]);
2887 uni_printf(cx, ")");
2892 uni_print_pop_prefix(cx);
2895 uni_print_ieend(cx);
2898 DEF_IE_CHECK(itu, aal)
2902 if(ie->type == UNI_AAL_0) {
2904 } else if(ie->type == UNI_AAL_1) {
2905 switch(ie->u.aal1.subtype) {
2910 case UNI_AAL1_SUB_NULL:
2911 case UNI_AAL1_SUB_VOICE:
2912 case UNI_AAL1_SUB_CIRCUIT:
2913 case UNI_AAL1_SUB_HQAUDIO:
2914 case UNI_AAL1_SUB_VIDEO:
2917 switch(ie->u.aal1.cbr_rate) {
2922 case UNI_AAL1_CBR_64:
2923 case UNI_AAL1_CBR_1544:
2924 case UNI_AAL1_CBR_6312:
2925 case UNI_AAL1_CBR_32064:
2926 case UNI_AAL1_CBR_44736:
2927 case UNI_AAL1_CBR_97728:
2928 case UNI_AAL1_CBR_2048:
2929 case UNI_AAL1_CBR_8448:
2930 case UNI_AAL1_CBR_34368:
2931 case UNI_AAL1_CBR_139264:
2932 if((ie->h.present & UNI_AAL1_MULT_P))
2936 case UNI_AAL1_CBR_N64:
2937 if(!(ie->h.present & UNI_AAL1_MULT_P))
2939 if(ie->u.aal1.mult < 2)
2943 case UNI_AAL1_CBR_N8:
2944 if(!(ie->h.present & UNI_AAL1_MULT_P))
2946 if(ie->u.aal1.mult == 0 || ie->u.aal1.mult > 7)
2950 if(ie->h.present & UNI_AAL1_SCREC_P) {
2951 switch(ie->u.aal1.screc) {
2956 case UNI_AAL1_SCREC_NULL:
2957 case UNI_AAL1_SCREC_SRTS:
2958 case UNI_AAL1_SCREC_ACLK:
2962 if(ie->h.present & UNI_AAL1_ECM_P) {
2963 switch(ie->u.aal1.ecm) {
2968 case UNI_AAL1_ECM_NULL:
2969 case UNI_AAL1_ECM_LOSS:
2970 case UNI_AAL1_ECM_DELAY:
2974 if(ie->h.present & UNI_AAL1_BSIZE_P) {
2975 if(ie->u.aal1.bsize == 0)
2978 if(ie->h.present & UNI_AAL1_PART_P) {
2979 if(ie->u.aal1.part == 0 || ie->u.aal1.part > 47)
2983 } else if(ie->type == UNI_AAL_2) {
2986 } else if(ie->type == UNI_AAL_4) {
2987 if(ie->h.present & UNI_AAL4_MID_P) {
2988 if(ie->u.aal4.mid_low >= 1024)
2990 if(ie->u.aal4.mid_high >= 1024)
2992 if(ie->u.aal4.mid_low > ie->u.aal4.mid_high)
2995 if(ie->h.present & UNI_AAL4_SSCS_P) {
2996 switch(ie->u.aal4.sscs) {
3001 case UNI_AAL_SSCS_NULL:
3002 case UNI_AAL_SSCS_SSCOPA:
3003 case UNI_AAL_SSCS_SSCOPU:
3004 case UNI_AAL_SSCS_FRAME:
3009 } else if(ie->type == UNI_AAL_5) {
3010 if(ie->h.present & UNI_AAL5_SSCS_P) {
3011 switch(ie->u.aal5.sscs) {
3016 case UNI_AAL_SSCS_NULL:
3017 case UNI_AAL_SSCS_SSCOPA:
3018 case UNI_AAL_SSCS_SSCOPU:
3019 case UNI_AAL_SSCS_FRAME:
3024 } else if(ie->type == UNI_AAL_USER) {
3025 if(ie->u.aalu.len > 4)
3034 DEF_IE_ENCODE(itu, aal)
3036 START_IE(aal, UNI_IE_AAL, 16);
3038 APP_BYTE(msg, ie->type);
3046 UNI_AAL_SUB_ID, ie->u.aal1.subtype);
3048 UNI_AAL_CBR_ID, ie->u.aal1.cbr_rate);
3049 APP_OPT_16BIT(msg, ie->h.present, UNI_AAL1_MULT_P,
3050 UNI_AAL_MULT_ID, ie->u.aal1.mult);
3051 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_SCREC_P,
3052 UNI_AAL_SCREC_ID, ie->u.aal1.screc);
3053 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_ECM_P,
3054 UNI_AAL_ECM_ID, ie->u.aal1.ecm);
3055 APP_OPT_16BIT(msg, ie->h.present, UNI_AAL1_BSIZE_P,
3056 UNI_AAL_BSIZE_ID, ie->u.aal1.bsize);
3057 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_PART_P,
3058 UNI_AAL_PART_ID, ie->u.aal1.part);
3065 if(ie->h.present & UNI_AAL4_CPCS_P) {
3067 UNI_AAL_FWDCPCS_ID, ie->u.aal4.fwd_cpcs);
3069 UNI_AAL_BWDCPCS_ID, ie->u.aal4.bwd_cpcs);
3071 if(ie->h.present & UNI_AAL4_MID_P) {
3072 APP_BYTE(msg, UNI_AAL_MID_ID);
3073 APP_16BIT(msg, ie->u.aal4.mid_low);
3074 APP_16BIT(msg, ie->u.aal4.mid_high);
3076 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL4_SSCS_P,
3077 UNI_AAL_SSCS_ID, ie->u.aal4.sscs);
3081 if(ie->h.present & UNI_AAL5_CPCS_P) {
3083 UNI_AAL_FWDCPCS_ID, ie->u.aal5.fwd_cpcs);
3085 UNI_AAL_BWDCPCS_ID, ie->u.aal5.bwd_cpcs);
3087 APP_OPT_BYTE(msg, ie->h.present, UNI_AAL5_SSCS_P,
3088 UNI_AAL_SSCS_ID, ie->u.aal5.sscs);
3092 APP_BUF(msg, ie->u.aalu.user, ie->u.aalu.len);
3104 * XXX What should we do with multiple subtype occurences? Ignore
3105 * or reject. Currently we reject.
3108 decode_aal_1(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3110 int subtype_p, cbr_p;
3112 subtype_p = cbr_p = 0;
3114 while(ielen-- > 0) {
3115 switch(*msg->b_rptr++) {
3117 case UNI_AAL_SUB_ID:
3118 if(ielen == 0 || subtype_p)
3122 ie->u.aal1.subtype = *msg->b_rptr++;
3125 case UNI_AAL_CBR_ID:
3126 if(ielen == 0 || cbr_p)
3130 ie->u.aal1.cbr_rate = *msg->b_rptr++;
3133 case UNI_AAL_MULT_ID:
3134 if(ielen < 2 || (ie->h.present & UNI_AAL1_MULT_P))
3137 ie->h.present |= UNI_AAL1_MULT_P;
3138 ie->u.aal1.mult = *msg->b_rptr++ << 8;
3139 ie->u.aal1.mult |= *msg->b_rptr++;
3142 case UNI_AAL_SCREC_ID:
3143 if(ielen == 0 || (ie->h.present & UNI_AAL1_SCREC_P))
3146 ie->h.present |= UNI_AAL1_SCREC_P;
3147 ie->u.aal1.screc = *msg->b_rptr++;
3150 case UNI_AAL_ECM_ID:
3151 if(ielen == 0 || (ie->h.present & UNI_AAL1_ECM_P))
3154 ie->h.present |= UNI_AAL1_ECM_P;
3155 ie->u.aal1.ecm = *msg->b_rptr++;
3158 case UNI_AAL_BSIZE_ID:
3159 if(ielen < 2 || (ie->h.present & UNI_AAL1_BSIZE_P))
3162 ie->h.present |= UNI_AAL1_BSIZE_P;
3163 ie->u.aal1.bsize = *msg->b_rptr++ << 8;
3164 ie->u.aal1.bsize |= *msg->b_rptr++;
3167 case UNI_AAL_PART_ID:
3168 if(ielen == 0 || (ie->h.present & UNI_AAL1_PART_P))
3171 ie->h.present |= UNI_AAL1_PART_P;
3172 ie->u.aal1.part = *msg->b_rptr++;
3179 if(!subtype_p || !cbr_p)
3186 decode_aal_4(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3188 int fcpcs_p, bcpcs_p;
3190 fcpcs_p = bcpcs_p = 0;
3192 while(ielen-- > 0) {
3193 switch(*msg->b_rptr++) {
3195 case UNI_AAL_FWDCPCS_ID:
3196 if(ielen < 2 || fcpcs_p)
3200 ie->u.aal4.fwd_cpcs = *msg->b_rptr++ << 8;
3201 ie->u.aal4.fwd_cpcs |= *msg->b_rptr++;
3204 case UNI_AAL_BWDCPCS_ID:
3205 if(ielen < 2 || bcpcs_p)
3209 ie->u.aal4.bwd_cpcs = *msg->b_rptr++ << 8;
3210 ie->u.aal4.bwd_cpcs |= *msg->b_rptr++;
3213 case UNI_AAL_MID_ID:
3214 if(ielen < 4 || (ie->h.present & UNI_AAL4_MID_P))
3217 ie->h.present |= UNI_AAL4_MID_P;
3218 ie->u.aal4.mid_low = *msg->b_rptr++ << 8;
3219 ie->u.aal4.mid_low |= *msg->b_rptr++;
3220 ie->u.aal4.mid_high = *msg->b_rptr++ << 8;
3221 ie->u.aal4.mid_high |= *msg->b_rptr++;
3224 case UNI_AAL_SSCS_ID:
3225 if(ielen == 0 || (ie->h.present & UNI_AAL4_SSCS_P))
3228 ie->h.present |= UNI_AAL4_SSCS_P;
3229 ie->u.aal4.sscs = *msg->b_rptr++;
3237 if(fcpcs_p ^ bcpcs_p)
3240 ie->h.present |= UNI_AAL4_CPCS_P;
3246 decode_aal_5(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3248 int fcpcs_p, bcpcs_p;
3250 fcpcs_p = bcpcs_p = 0;
3252 while(ielen-- > 0) {
3253 switch(*msg->b_rptr++) {
3255 case UNI_AAL_FWDCPCS_ID:
3256 if(ielen < 2 || fcpcs_p)
3260 ie->u.aal5.fwd_cpcs = *msg->b_rptr++ << 8;
3261 ie->u.aal5.fwd_cpcs |= *msg->b_rptr++;
3264 case UNI_AAL_BWDCPCS_ID:
3265 if(ielen < 2 || bcpcs_p)
3269 ie->u.aal5.bwd_cpcs = *msg->b_rptr++ << 8;
3270 ie->u.aal5.bwd_cpcs |= *msg->b_rptr++;
3273 case UNI_AAL_SSCS_ID:
3274 if(ielen == 0 || (ie->h.present & UNI_AAL5_SSCS_P))
3277 ie->h.present |= UNI_AAL5_SSCS_P;
3278 ie->u.aal5.sscs = *msg->b_rptr++;
3286 if(fcpcs_p ^ bcpcs_p)
3289 ie->h.present |= UNI_AAL5_CPCS_P;
3295 decode_aal_user(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3302 ie->u.aalu.user[ie->u.aalu.len++] = *msg->b_rptr++;
3307 DEF_IE_DECODE(itu, aal)
3311 IE_START(DISC_ACC_ERR(AAL));
3313 if(ielen < 1 || ielen > 21)
3327 if(decode_aal_1(ie, msg, ielen))
3337 if(decode_aal_4(ie, msg, ielen))
3343 if(decode_aal_5(ie, msg, ielen))
3349 if(decode_aal_user(ie, msg, ielen))
3360 /*********************************************************************
3362 * Traffic descriptor.
3363 * Alternate traffic descriptor.
3364 * Minimum traffic descriptor.
3366 * References for this IE are:
3368 * Q.2931 pp. 49...51
3371 * UNI4.0 pp. 9...10, 106...109
3373 * The Q.s specify the coding. UNI4.0 adds frame discard and best-effort.
3374 * Appendix in UNI4.0 lists the allowed combinations.
3376 * PCR0 PCR1 SCR/MBS0 SCR/MBS1 BE TAG FDISC ABR
3377 * 1 CBR.1 - Y - - - N Y/N -
3378 * 2 CBR.2 - Y - - - N Y/N - (*)
3379 * 3 CBR.3 Y Y - - - Y Y/N - (*)
3380 * 4 rt-VBR.1 - Y - Y - N Y/N -
3381 * 5 rt-VBR.2 - Y Y - - N Y/N -
3382 * 6 rt-VBR.3 - Y Y - - Y Y/N -
3383 * 7 rt-VBR.4 Y Y - - - Y/N Y/N - (*)
3384 * 8 rt-VBR.5 - Y - - - N Y/N - (*)
3385 * 9 rt-VBR.6 - Y - Y - N Y/N - (*)
3386 * 10 nrt-VBR.1 - Y - Y - N Y/N -
3387 * 11 nrt-VBR.2 - Y Y - - N Y/N -
3388 * 12 nrt-VBR.3 - Y Y - - Y Y/N -
3389 * 13 nrt-VBR.4 Y Y - - - Y/N Y/N - (*)
3390 * 14 nrt-VBR.5 - Y - - - N Y/N - (*)
3391 * 15 nrt-VBR.6 - Y - Y - N Y/N - (*)
3392 * 16 ABR - Y - - - N Y/N O (*)
3393 * 17 UBR.1 - Y - - Y N Y/N -
3394 * 18 UBR.2 - Y - - Y Y Y/N -
3396 * Allow ITU-T and NET coding, because its not clear, whether the
3397 * new fields in UNI4.0 should be used with NET coding or not.
3398 * Does not allow for experimental codings yet.
3402 print_ie_traffic_common(struct unicx *cx, u_int present, struct uni_xtraffic *ie)
3404 uni_print_entry(cx, "fwd", "(");
3405 if(present & UNI_TRAFFIC_FPCR0_P)
3406 uni_printf(cx, "%u", ie->fpcr0);
3408 if(present & UNI_TRAFFIC_FPCR1_P)
3409 uni_printf(cx, "%u", ie->fpcr1);
3411 if(present & UNI_TRAFFIC_FSCR0_P)
3412 uni_printf(cx, "%u", ie->fscr0);
3414 if(present & UNI_TRAFFIC_FSCR1_P)
3415 uni_printf(cx, "%u", ie->fscr1);
3417 if(present & UNI_TRAFFIC_FMBS0_P)
3418 uni_printf(cx, "%u", ie->fmbs0);
3420 if(present & UNI_TRAFFIC_FMBS1_P)
3421 uni_printf(cx, "%u", ie->fmbs1);
3423 if(present & UNI_TRAFFIC_FABR1_P)
3424 uni_printf(cx, "%u", ie->fabr1);
3425 uni_printf(cx, ")");
3427 uni_print_entry(cx, "bwd", "(");
3428 if(present & UNI_TRAFFIC_BPCR0_P)
3429 uni_printf(cx, "%u", ie->bpcr0);
3431 if(present & UNI_TRAFFIC_BPCR1_P)
3432 uni_printf(cx, "%u", ie->bpcr1);
3434 if(present & UNI_TRAFFIC_BSCR0_P)
3435 uni_printf(cx, "%u", ie->bscr0);
3437 if(present & UNI_TRAFFIC_BSCR1_P)
3438 uni_printf(cx, "%u", ie->bscr1);
3440 if(present & UNI_TRAFFIC_BMBS0_P)
3441 uni_printf(cx, "%u", ie->bmbs0);
3443 if(present & UNI_TRAFFIC_BMBS1_P)
3444 uni_printf(cx, "%u", ie->bmbs1);
3446 if(present & UNI_TRAFFIC_BABR1_P)
3447 uni_printf(cx, "%u", ie->babr1);
3448 uni_printf(cx, ")");
3450 if(present & UNI_TRAFFIC_BEST_P)
3451 uni_print_flag("best_effort", cx);
3452 if(present & UNI_TRAFFIC_MOPT_P) {
3453 uni_print_entry(cx, "tag", "(");
3455 uni_printf(cx, "fwd");
3458 uni_printf(cx, "bwd");
3461 uni_print_entry(cx, "disc", "(");
3463 uni_printf(cx, "fwd");
3466 uni_printf(cx, "bwd");
3474 u_char mopt_mask, mopt_val;
3478 check_traffic(u_int mask, u_int mopt, struct tallow *a)
3483 if(a->mopt_flag == 0) {
3490 if(a->mopt_flag < 0) {
3494 if((mopt & a->mopt_mask) == a->mopt_val)
3502 if((mopt & a->mopt_mask) == a->mopt_val)
3508 check_ie_traffic_common(struct uni_xtraffic *ie, u_int present,
3509 struct unicx *cx __unused)
3511 static u_int fmask =
3512 UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P |
3513 UNI_TRAFFIC_FSCR0_P | UNI_TRAFFIC_FSCR1_P |
3514 UNI_TRAFFIC_FMBS0_P | UNI_TRAFFIC_FMBS1_P |
3515 UNI_TRAFFIC_FABR1_P;
3516 static u_int bmask =
3517 UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P |
3518 UNI_TRAFFIC_BSCR0_P | UNI_TRAFFIC_BSCR1_P |
3519 UNI_TRAFFIC_BMBS0_P | UNI_TRAFFIC_BMBS1_P |
3520 UNI_TRAFFIC_BABR1_P;
3523 -1, U##X##TAG, 0 }, /* 1, 2, 8, 14 */ \
3524 { U##X##PCR0_P | U##X##PCR1_P, \
3525 +1, U##X##TAG, U##X##TAG }, /* 3 */ \
3526 { U##X##PCR1_P | U##X##SCR1_P | U##X##MBS1_P, \
3527 -1, U##X##TAG, 0 }, /* 4, 9, 10, 15 */ \
3528 { U##X##PCR1_P | U##X##SCR0_P | U##X##MBS0_P, \
3529 -1, 0, 0 }, /* 5, 6, 11, 12 */ \
3530 { U##X##PCR0_P | U##X##PCR1_P, \
3531 -1, 0, 0 }, /* 7, 13 */ \
3532 { U##X##PCR1_P | U##X##ABR1_P, \
3533 -1, U##X##TAG, 0 }, /* 16a */
3536 static struct tallow allow[2][DTABSIZE] = {
3537 { DTAB(UNI_TRAFFIC_, F) },
3538 { DTAB(UNI_TRAFFIC_, B) },
3545 f = present & fmask;
3546 b = present & bmask;
3547 p = present & (fmask | bmask);
3548 m = (present & UNI_TRAFFIC_MOPT_P)
3549 ? ( (ie->ftag ? UNI_TRAFFIC_FTAG : 0)
3550 | (ie->btag ? UNI_TRAFFIC_BTAG : 0)
3551 | (ie->fdisc ? UNI_TRAFFIC_FDISC : 0)
3552 | (ie->bdisc ? UNI_TRAFFIC_BDISC : 0))
3556 if(present & UNI_TRAFFIC_BEST_P) {
3560 if(p != (UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_BPCR1_P))
3566 * Check forward and backward independent. There must be a higher
3567 * level checking in the CAC
3569 for(i = 0; i < DTABSIZE; i++)
3570 if(check_traffic(f, m, &allow[0][i]))
3575 for(i = 0; i < DTABSIZE; i++)
3576 if(check_traffic(b, m, &allow[1][i]))
3585 encode_traffic_common(struct uni_msg *msg, struct uni_xtraffic *ie,
3586 u_int present, struct unicx *cx __unused)
3588 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FPCR0_P,
3589 UNI_TRAFFIC_FPCR0_ID, ie->fpcr0);
3590 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BPCR0_P,
3591 UNI_TRAFFIC_BPCR0_ID, ie->bpcr0);
3592 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FPCR1_P,
3593 UNI_TRAFFIC_FPCR1_ID, ie->fpcr1);
3594 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BPCR1_P,
3595 UNI_TRAFFIC_BPCR1_ID, ie->bpcr1);
3596 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FSCR0_P,
3597 UNI_TRAFFIC_FSCR0_ID, ie->fscr0);
3598 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BSCR0_P,
3599 UNI_TRAFFIC_BSCR0_ID, ie->bscr0);
3600 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FSCR1_P,
3601 UNI_TRAFFIC_FSCR1_ID, ie->fscr1);
3602 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BSCR1_P,
3603 UNI_TRAFFIC_BSCR1_ID, ie->bscr1);
3604 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FMBS0_P,
3605 UNI_TRAFFIC_FMBS0_ID, ie->fmbs0);
3606 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BMBS0_P,
3607 UNI_TRAFFIC_BMBS0_ID, ie->bmbs0);
3608 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FMBS1_P,
3609 UNI_TRAFFIC_FMBS1_ID, ie->fmbs1);
3610 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BMBS1_P,
3611 UNI_TRAFFIC_BMBS1_ID, ie->bmbs1);
3612 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FABR1_P,
3613 UNI_TRAFFIC_FABR1_ID, ie->fabr1);
3614 APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BABR1_P,
3615 UNI_TRAFFIC_BABR1_ID, ie->babr1);
3617 APP_OPT(msg, present, UNI_TRAFFIC_BEST_P,
3618 UNI_TRAFFIC_BEST_ID);
3619 APP_OPT_BYTE(msg, present, UNI_TRAFFIC_MOPT_P,
3620 UNI_TRAFFIC_MOPT_ID,
3621 (ie->ftag ? UNI_TRAFFIC_FTAG : 0) |
3622 (ie->btag ? UNI_TRAFFIC_BTAG : 0) |
3623 (ie->fdisc ? UNI_TRAFFIC_FDISC : 0) |
3624 (ie->fdisc ? UNI_TRAFFIC_BDISC : 0));
3630 decode_traffic_common(struct uni_xtraffic *ie, struct uni_msg *msg,
3631 u_int ielen, u_int *present)
3636 switch(c = *msg->b_rptr++) {
3642 DEC_GETF3(TRAFFIC_FPCR0, fpcr0, *present);
3643 DEC_GETF3(TRAFFIC_BPCR0, bpcr0, *present);
3644 DEC_GETF3(TRAFFIC_FPCR1, fpcr1, *present);
3645 DEC_GETF3(TRAFFIC_BPCR1, bpcr1, *present);
3646 DEC_GETF3(TRAFFIC_FSCR0, fscr0, *present);
3647 DEC_GETF3(TRAFFIC_BSCR0, bscr0, *present);
3648 DEC_GETF3(TRAFFIC_FSCR1, fscr1, *present);
3649 DEC_GETF3(TRAFFIC_BSCR1, bscr1, *present);
3650 DEC_GETF3(TRAFFIC_FMBS0, fmbs0, *present);
3651 DEC_GETF3(TRAFFIC_BMBS0, bmbs0, *present);
3652 DEC_GETF3(TRAFFIC_BMBS1, bmbs1, *present);
3653 DEC_GETF3(TRAFFIC_FABR1, fabr1, *present);
3654 DEC_GETF3(TRAFFIC_BABR1, babr1, *present);
3656 case UNI_TRAFFIC_BEST_ID:
3657 *present |= UNI_TRAFFIC_BEST_P;
3660 case UNI_TRAFFIC_MOPT_ID:
3664 if(!(*present & UNI_TRAFFIC_MOPT_P)) {
3665 *present |= UNI_TRAFFIC_MOPT_P;
3666 ie->ftag = (*msg->b_rptr&UNI_TRAFFIC_FTAG)?1:0;
3667 ie->btag = (*msg->b_rptr&UNI_TRAFFIC_BTAG)?1:0;
3668 ie->fdisc = (*msg->b_rptr&UNI_TRAFFIC_FDISC)?1:0;
3669 ie->bdisc = (*msg->b_rptr&UNI_TRAFFIC_BDISC)?1:0;
3679 /*****************************************************************/
3681 DEF_IE_PRINT(itu, traffic)
3683 if(uni_print_iehdr("traffic", &ie->h, cx))
3685 print_ie_traffic_common(cx, ie->h.present, &ie->t);
3686 uni_print_ieend(cx);
3689 DEF_IE_CHECK(itu, traffic)
3691 return check_ie_traffic_common(&ie->t, ie->h.present, cx);
3694 DEF_IE_ENCODE(itu, traffic)
3696 START_IE(traffic, UNI_IE_TRAFFIC, 26);
3697 encode_traffic_common(msg, &ie->t, ie->h.present, cx);
3702 DEF_IE_DECODE(itu, traffic)
3709 if(decode_traffic_common(&ie->t, msg, ielen, &ie->h.present))
3715 /*****************************************************************/
3717 DEF_IE_PRINT(itu, atraffic)
3719 if(uni_print_iehdr("atraffic", &ie->h, cx))
3721 print_ie_traffic_common(cx, ie->h.present, &ie->t);
3722 uni_print_ieend(cx);
3725 DEF_IE_CHECK(itu, atraffic)
3727 return check_ie_traffic_common(&ie->t, ie->h.present, cx);
3730 DEF_IE_ENCODE(itu, atraffic)
3732 START_IE(traffic, UNI_IE_ATRAFFIC, 26);
3733 encode_traffic_common(msg, &ie->t, ie->h.present, cx);
3738 DEF_IE_DECODE(itu, atraffic)
3745 if(decode_traffic_common(&ie->t, msg, ielen, &ie->h.present))
3751 /*****************************************************************/
3753 DEF_IE_PRINT(itu, mintraffic)
3755 if(uni_print_iehdr("mintraffic", &ie->h, cx))
3758 uni_print_entry(cx, "pcr0", "(");
3759 if(ie->h.present & UNI_MINTRAFFIC_FPCR0_P)
3760 uni_printf(cx, "%u", ie->fpcr0);
3762 if(ie->h.present & UNI_MINTRAFFIC_BPCR0_P)
3763 uni_printf(cx, "%u", ie->bpcr0);
3766 uni_print_entry(cx, "pcr1", "(");
3767 if(ie->h.present & UNI_MINTRAFFIC_FPCR1_P)
3768 uni_printf(cx, "%u", ie->fpcr1);
3770 if(ie->h.present & UNI_MINTRAFFIC_BPCR1_P)
3771 uni_printf(cx, "%u", ie->bpcr1);
3774 uni_print_entry(cx, "abr1", "(");
3775 if(ie->h.present & UNI_MINTRAFFIC_FABR1_P)
3776 uni_printf(cx, "%u", ie->fabr1);
3778 if(ie->h.present & UNI_MINTRAFFIC_BABR1_P)
3779 uni_printf(cx, "%u", ie->babr1);
3780 uni_printf(cx, ")");
3782 uni_print_ieend(cx);
3785 DEF_IE_CHECK(itu, mintraffic)
3791 abr = ie->h.present & (UNI_MINTRAFFIC_FABR1_P|UNI_MINTRAFFIC_BABR1_P);
3792 xbr = ie->h.present & (UNI_MINTRAFFIC_FPCR0_P|UNI_MINTRAFFIC_BPCR0_P|
3793 UNI_MINTRAFFIC_FPCR1_P|UNI_MINTRAFFIC_BPCR1_P);
3801 DEF_IE_ENCODE(itu, mintraffic)
3803 START_IE(mintraffic, UNI_IE_MINTRAFFIC, 16);
3805 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FPCR0_P,
3806 UNI_TRAFFIC_FPCR0_ID, ie->fpcr0);
3807 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BPCR0_P,
3808 UNI_TRAFFIC_BPCR0_ID, ie->bpcr0);
3809 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FPCR1_P,
3810 UNI_TRAFFIC_FPCR1_ID, ie->fpcr1);
3811 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BPCR1_P,
3812 UNI_TRAFFIC_BPCR1_ID, ie->bpcr1);
3813 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FABR1_P,
3814 UNI_TRAFFIC_FABR1_ID, ie->fabr1);
3815 APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BABR1_P,
3816 UNI_TRAFFIC_BABR1_ID, ie->babr1);
3822 DEF_IE_DECODE(itu, mintraffic)
3832 switch(c = *msg->b_rptr++) {
3837 DEC_GETF3(MINTRAFFIC_FPCR0, fpcr0, ie->h.present);
3838 DEC_GETF3(MINTRAFFIC_BPCR0, bpcr0, ie->h.present);
3839 DEC_GETF3(MINTRAFFIC_FPCR1, fpcr1, ie->h.present);
3840 DEC_GETF3(MINTRAFFIC_BPCR1, bpcr1, ie->h.present);
3841 DEC_GETF3(MINTRAFFIC_FABR1, fabr1, ie->h.present);
3842 DEC_GETF3(MINTRAFFIC_BABR1, babr1, ie->h.present);
3849 /*****************************************************************/
3851 DEF_IE_PRINT(net, mdcr)
3853 static const struct uni_print_tbl origin_tbl[] = {
3854 MKT(UNI_MDCR_ORIGIN_USER, user),
3855 MKT(UNI_MDCR_ORIGIN_NET, net),
3859 if(uni_print_iehdr("mdcr", &ie->h, cx))
3862 uni_print_tbl("origin", ie->origin, origin_tbl, cx);
3863 uni_print_entry(cx, "mdcr", "(");
3864 uni_printf(cx, "%u", ie->fmdcr);
3866 uni_printf(cx, "%u", ie->bmdcr);
3869 uni_print_ieend(cx);
3872 DEF_IE_CHECK(net, mdcr)
3876 if ((ie->origin != UNI_MDCR_ORIGIN_USER &&
3877 ie->origin != UNI_MDCR_ORIGIN_NET) ||
3878 ie->fmdcr >= (1 << 24) || ie->bmdcr >= (1 << 24))
3884 DEF_IE_ENCODE(net, mdcr)
3886 START_IE(mdcr, UNI_IE_MDCR, 9);
3888 APP_BYTE(msg, ie->origin);
3889 APP_SUB_24BIT(msg, UNI_TRAFFIC_FMDCR_ID, ie->fmdcr);
3890 APP_SUB_24BIT(msg, UNI_TRAFFIC_BMDCR_ID, ie->bmdcr);
3896 DEF_IE_DECODE(net, mdcr)
3899 #define UNI_TRAFFIC_FMDCR_P 0x01
3900 #define UNI_TRAFFIC_BMDCR_P 0x02
3908 ie->origin = *msg->b_rptr++;
3912 switch(c = *msg->b_rptr++) {
3917 DEC_GETF3(TRAFFIC_FMDCR, fmdcr, p);
3918 DEC_GETF3(TRAFFIC_BMDCR, bmdcr, p);
3921 if (p != (UNI_TRAFFIC_FMDCR_P | UNI_TRAFFIC_BMDCR_P))
3927 /*********************************************************************
3929 * Connection identifier
3931 * References for this IE are:
3933 * Q.2931 pp. 69...70
3934 * UNI4.0 pp. 15...16
3937 * Only ITU-T coding allowed.
3940 DEF_IE_PRINT(itu, connid)
3942 static const struct uni_print_tbl tbl[] = {
3943 MKT(UNI_CONNID_VCI, exclusive),
3944 MKT(UNI_CONNID_ANYVCI, any),
3945 MKT(UNI_CONNID_NOVCI, no),
3948 static const struct uni_print_tbl assoc_tbl[] = {
3949 MKT(UNI_CONNID_ASSOC, associated),
3950 MKT(UNI_CONNID_NONASSOC,non-associated),
3954 if(uni_print_iehdr("connid", &ie->h, cx))
3957 uni_print_tbl("mode", ie->assoc, assoc_tbl, cx);
3958 uni_print_entry(cx, "connid", "(%u,", ie->vpci);
3959 if(ie->type == UNI_CONNID_VCI)
3960 uni_printf(cx, "%u", ie->vci);
3962 uni_print_tbl(NULL, ie->type, tbl, cx);
3963 uni_printf(cx, ")");
3965 uni_print_ieend(cx);
3968 DEF_IE_CHECK(itu, connid)
3974 case UNI_CONNID_VCI:
3975 case UNI_CONNID_ANYVCI:
3976 case UNI_CONNID_NOVCI:
3982 * This field must be checked by the application to fulfil
3983 * Q.2931Amd4 27) 5.2.3 last sentence
3987 case UNI_CONNID_ASSOC:
3992 case UNI_CONNID_NONASSOC:
4002 DEF_IE_ENCODE(itu, connid)
4004 START_IE(connid, UNI_IE_CONNID, 5);
4006 APP_BYTE(msg, 0x80 | (ie->assoc << 3) | ie->type);
4007 APP_BYTE(msg, ie->vpci >> 8);
4008 APP_BYTE(msg, ie->vpci >> 0);
4009 APP_BYTE(msg, ie->vci >> 8);
4010 APP_BYTE(msg, ie->vci >> 0);
4016 DEF_IE_DECODE(itu, connid)
4028 ie->assoc = (c >> 3) & 3;
4030 ie->vpci = *msg->b_rptr++ << 8;
4031 ie->vpci |= *msg->b_rptr++;
4032 ie->vci = *msg->b_rptr++ << 8;
4033 ie->vci |= *msg->b_rptr++;
4038 /*********************************************************************
4040 * Quality of Service
4042 * References for this IE are:
4045 * UNI4.0 pp. 16...17
4049 print_qos(struct unicx *cx, struct uni_ie_qos *ie)
4051 static const struct uni_print_tbl class_tbl[] = {
4052 MKT(UNI_QOS_CLASS0, Class0),
4053 MKT(UNI_QOS_CLASS1, Class1),
4054 MKT(UNI_QOS_CLASS2, Class2),
4055 MKT(UNI_QOS_CLASS3, Class3),
4056 MKT(UNI_QOS_CLASS4, Class4),
4060 if(uni_print_iehdr("qos", &ie->h, cx))
4063 uni_print_tbl("fwd", ie->fwd, class_tbl, cx);
4064 uni_print_tbl("bwd", ie->bwd, class_tbl, cx);
4066 uni_print_ieend(cx);
4069 DEF_IE_PRINT(itu, qos)
4073 DEF_IE_PRINT(net, qos)
4078 DEF_IE_CHECK(itu, qos)
4086 case UNI_QOS_CLASS0:
4093 case UNI_QOS_CLASS0:
4099 DEF_IE_CHECK(net, qos)
4107 case UNI_QOS_CLASS1:
4108 case UNI_QOS_CLASS2:
4109 case UNI_QOS_CLASS3:
4110 case UNI_QOS_CLASS4:
4117 case UNI_QOS_CLASS1:
4118 case UNI_QOS_CLASS2:
4119 case UNI_QOS_CLASS3:
4120 case UNI_QOS_CLASS4:
4126 DEF_IE_ENCODE(itu, qos)
4128 START_IE(qos, UNI_IE_QOS, 2);
4130 APP_BYTE(msg, ie->fwd);
4131 APP_BYTE(msg, ie->bwd);
4136 DEF_IE_ENCODE(net, qos)
4138 START_IE(qos, UNI_IE_QOS, 2);
4140 APP_BYTE(msg, ie->fwd);
4141 APP_BYTE(msg, ie->bwd);
4147 DEF_IE_DECODE(itu, qos)
4154 ie->fwd = *msg->b_rptr++;
4155 ie->bwd = *msg->b_rptr++;
4160 DEF_IE_DECODE(net, qos)
4167 ie->fwd = *msg->b_rptr++;
4168 ie->bwd = *msg->b_rptr++;
4173 /*********************************************************************
4175 * Broadband Lower Layer Information
4177 * References for this IE are:
4179 * Q.2931 pp. 53...54
4182 * Only ITU-T coding allowed.
4185 DEF_IE_PRINT(itu, bhli)
4187 static const struct uni_print_tbl type_tbl[] = {
4188 MKT(UNI_BHLI_ISO, iso),
4189 MKT(UNI_BHLI_USER, user),
4190 MKT(UNI_BHLI_VENDOR, vendor),
4195 if(uni_print_iehdr("bhli", &ie->h, cx))
4198 uni_print_tbl("type", ie->type, type_tbl, cx);
4199 uni_print_entry(cx, "len", "%d", ie->len);
4200 uni_print_entry(cx, "info", "(");
4201 for(i = 0; i < ie->len; i++)
4202 uni_printf(cx, ",0x%02x", ie->info[i]);
4203 uni_printf(cx, ")");
4205 uni_print_ieend(cx);
4208 DEF_IE_CHECK(itu, bhli)
4218 case UNI_BHLI_VENDOR:
4227 DEF_IE_ENCODE(itu, bhli)
4229 START_IE(bhli, UNI_IE_BHLI, 9);
4231 APP_BYTE(msg, 0x80 | ie->type);
4232 APP_BUF(msg, ie->info, ie->len);
4238 DEF_IE_DECODE(itu, bhli)
4252 ie->type = c & 0x7f;
4254 (void)memcpy(ie->info, msg->b_rptr, ielen);
4255 msg->b_rptr += ielen;
4260 /*********************************************************************
4262 * Broadband bearer capabilities
4264 * References for this IE are:
4266 * Q.2931 pp. 51...52
4268 * UNI4.0 pp. 10...12, 106...109
4270 * UNI4.0 changed the meaning of byte 5a. Instead of 3 bit traffic type and
4271 * 2 bit timing requirements there are now 7 bits ATM transfer capabilities.
4272 * However the old format is still supported: it should be recognized on
4273 * input, but never be generated on output. Mapping is left to the user of
4276 * Amd 1 not checked XXX.
4278 * The Appendix in UNI4.0 lists all the supported combinations of various
4279 * traffic IE's. The check function implements part of it.
4283 * 2 CBR.2 - . 4,5,6 5 (*)
4284 * 3 CBR.3 - . 4,5,6 5 (*)
4285 * 4 rt-VBR.1 . 19 19 19
4286 * 5 rt-VBR.2 . 9 1,9 9
4287 * 6 rt-VBR.3 . 9 1,9 9
4288 * 7 rt-VBR.4 . . 1,9 . (*)
4289 * 8 rt-VBR.5 . . 1,9 . (*)
4290 * 9 rt-VBR.6 . 9 1,9 9 (*)
4291 * 10 nrt-VBR.1 . 11 11 11
4292 * 11 nrt-VBR.2 . - -,0,2,8,10 -,10
4293 * 12 nrt-VBR.3 . - -,0,2,8,10 -,10
4294 * 13 nrt-VBR.4 . - -,0,2,8,10 . (*)
4295 * 14 nrt-VBR.5 . - -,0,2,8,10 . (*)
4296 * 15 nrt-VBR.6 . - -,0,2,8,10 -,10(*)
4298 * 17 UBR.1 . - -,0,2,8,10 -,10
4299 * 18 UBR.2 . - -,0,2,8,10 -,10
4303 * Only ITU-T coding allowed.
4306 DEF_IE_PRINT(itu, bearer)
4308 static const struct uni_print_tbl bclass_tbl[] = {
4309 MKT(UNI_BEARER_A, bcob-A),
4310 MKT(UNI_BEARER_C, bcob-C),
4311 MKT(UNI_BEARER_X, bcob-X),
4312 MKT(UNI_BEARER_TVP, transparent-VP),
4315 static const struct uni_print_tbl atc_tbl[] = {
4316 MKT(UNI_BEARER_ATC_CBR, cbr),
4317 MKT(UNI_BEARER_ATC_CBR1, cbr1),
4318 MKT(UNI_BEARER_ATC_VBR, vbr),
4319 MKT(UNI_BEARER_ATC_VBR1, vbr1),
4320 MKT(UNI_BEARER_ATC_NVBR, nvbr),
4321 MKT(UNI_BEARER_ATC_NVBR1, nvbr1),
4322 MKT(UNI_BEARER_ATC_ABR, abr),
4324 MKT(UNI_BEARER_ATCX_0, x0),
4325 MKT(UNI_BEARER_ATCX_1, x1),
4326 MKT(UNI_BEARER_ATCX_2, x2),
4327 MKT(UNI_BEARER_ATCX_4, x4),
4328 MKT(UNI_BEARER_ATCX_6, x6),
4329 MKT(UNI_BEARER_ATCX_8, x8),
4332 static const struct uni_print_tbl cfg_tbl[] = {
4333 MKT(UNI_BEARER_P2P, p2p),
4334 MKT(UNI_BEARER_MP, mp),
4337 static const struct uni_print_tbl clip_tbl[] = {
4338 MKT(UNI_BEARER_NOCLIP, no),
4339 MKT(UNI_BEARER_CLIP, yes),
4343 if(uni_print_iehdr("bearer", &ie->h, cx))
4346 uni_print_tbl("class", ie->bclass, bclass_tbl, cx);
4348 if(ie->h.present & UNI_BEARER_ATC_P) {
4349 uni_print_tbl("atc", ie->atc, atc_tbl, cx);
4351 uni_print_tbl("clip", ie->clip, clip_tbl, cx);
4352 uni_print_tbl("cfg", ie->cfg, cfg_tbl, cx);
4354 uni_print_ieend(cx);
4357 #define QTYPE(C,A) ((UNI_BEARER_##C << 8) | UNI_BEARER_ATC_##A)
4358 #define QTYPEX(C,A) ((UNI_BEARER_##C << 8) | UNI_BEARER_ATCX_##A)
4359 #define QTYPE0(C) ((UNI_BEARER_##C << 8) | (1 << 16))
4360 DEF_IE_CHECK(itu, bearer)
4364 switch((ie->bclass << 8) |
4365 ((ie->h.present & UNI_BEARER_ATC_P) == 0
4372 case QTYPE (A, CBR1): /* 1 */
4373 case QTYPE (X, CBR1): /* 1 */
4374 case QTYPE (TVP, CBR1): /* 1 */
4376 case QTYPE0(A): /* 2,3 */
4377 case QTYPEX(X, 4): /* 2,3 */
4378 case QTYPE (X, CBR): /* 2,3 */
4379 case QTYPEX(X, 6): /* 2,3 */
4380 case QTYPE (TVP, CBR): /* 2,3 */
4382 case QTYPE (C, VBR1): /* 4 */
4383 case QTYPE (X, VBR1): /* 4 */
4384 case QTYPE (TVP, VBR1): /* 4 */
4386 case QTYPE (C, VBR): /* 5,6,9 */
4387 case QTYPEX(X, 1): /* 5,6,7,8,9 */
4388 case QTYPE (X, VBR): /* 5,6,7,8,9 */
4389 case QTYPE (TVP, VBR): /* 5,6,9 */
4391 case QTYPE (C, NVBR1): /* 10 */
4392 case QTYPE (X, NVBR1): /* 10 */
4393 case QTYPE (TVP, NVBR1): /* 10 */
4395 case QTYPE0(C): /* 11,12,13,14,15,17,18 */
4396 case QTYPE0(X): /* 11,12,13,14,15,17,18 */
4397 case QTYPEX(X, 0): /* 11,12,13,14,15,17,18 */
4398 case QTYPEX(X, 2): /* 11,12,13,14,15,17,18 */
4399 case QTYPEX(X, 8): /* 11,12,13,14,15,17,18 */
4400 case QTYPE (X, NVBR): /* 11,12,13,14,15,17,18 */
4401 case QTYPE0(TVP): /* 11,12,15,17,18 */
4402 case QTYPE (TVP, NVBR): /* 11,12,15,17,18 */
4404 case QTYPE (C, ABR): /* 16 */
4405 case QTYPE (X, ABR): /* 16 */
4406 case QTYPE (TVP, ABR): /* 16 */
4414 case UNI_BEARER_NOCLIP:
4415 case UNI_BEARER_CLIP:
4422 case UNI_BEARER_P2P:
4433 DEF_IE_ENCODE(itu, bearer)
4435 START_IE(bearer, UNI_IE_BEARER, 3);
4437 APP_BYTE(msg, ie->bclass |
4438 ((ie->h.present & UNI_BEARER_ATC_P) ? 0:0x80));
4439 APP_OPT(msg, ie->h.present, UNI_BEARER_ATC_P,
4441 APP_BYTE(msg, 0x80 | (ie->clip << 5) | ie->cfg);
4447 DEF_IE_DECODE(itu, bearer)
4453 if(ielen != 2 && ielen != 3)
4458 ie->bclass = c & 0x1f;
4462 ie->h.present |= UNI_BEARER_ATC_P;
4468 case UNI_BEARER_ATC_CBR:
4469 case UNI_BEARER_ATC_CBR1:
4470 case UNI_BEARER_ATC_VBR:
4471 case UNI_BEARER_ATC_VBR1:
4472 case UNI_BEARER_ATC_NVBR:
4473 case UNI_BEARER_ATC_NVBR1:
4474 case UNI_BEARER_ATC_ABR:
4480 case UNI_BEARER_ATCX_0:
4481 case UNI_BEARER_ATCX_1:
4482 case UNI_BEARER_ATCX_2:
4483 case UNI_BEARER_ATCX_4:
4484 case UNI_BEARER_ATCX_6:
4485 case UNI_BEARER_ATCX_8:
4503 ie->clip = (c >> 5) & 0x3;
4509 /*********************************************************************
4511 * Broadband Lower Layer Information
4513 * References for this IE are:
4515 * Q.2931 pp. 54...59
4516 * UNI4.0 pp. 12...14
4518 * UNI4.0 states, that layer 1 info is not supported.
4519 * We allow a layer 1 protocol identifier.
4521 * UNI4.0 states, that the layer information subelements are NOT position
4522 * dependent. We allow them in any order on input, but generate always the
4523 * definit order on output.
4525 * Only ITU-T coding allowed.
4528 DEF_IE_PRINT(itu, blli)
4530 static const struct uni_print_tbl l2_tbl[] = {
4531 MKT(UNI_BLLI_L2_BASIC, basic),
4532 MKT(UNI_BLLI_L2_Q921, Q921),
4533 MKT(UNI_BLLI_L2_X25LL, X25-LL),
4534 MKT(UNI_BLLI_L2_X25ML, X25-ML),
4535 MKT(UNI_BLLI_L2_LABP, LAPB),
4536 MKT(UNI_BLLI_L2_HDLC_ARM, HDLC-ARM),
4537 MKT(UNI_BLLI_L2_HDLC_NRM, HDLC-NRM),
4538 MKT(UNI_BLLI_L2_HDLC_ABM, HDLC-ABM),
4539 MKT(UNI_BLLI_L2_LAN, LAN),
4540 MKT(UNI_BLLI_L2_X75, X75),
4541 MKT(UNI_BLLI_L2_Q922, Q922),
4542 MKT(UNI_BLLI_L2_USER, user),
4543 MKT(UNI_BLLI_L2_ISO7776, ISO7776),
4546 static const struct uni_print_tbl l2mode_tbl[] = {
4547 MKT(UNI_BLLI_L2NORM, normal),
4548 MKT(UNI_BLLI_L2EXT, extended),
4551 static const struct uni_print_tbl l3_tbl[] = {
4552 MKT(UNI_BLLI_L3_X25, X25),
4553 MKT(UNI_BLLI_L3_ISO8208, ISO8208),
4554 MKT(UNI_BLLI_L3_X223, X223),
4555 MKT(UNI_BLLI_L3_CLMP, CLMP),
4556 MKT(UNI_BLLI_L3_T70, T70),
4557 MKT(UNI_BLLI_L3_TR9577, TR9577),
4558 MKT(UNI_BLLI_L3_USER, user),
4559 MKT(UNI_BLLI_L3_H310, H310),
4560 MKT(UNI_BLLI_L3_H321, H321),
4563 static const struct uni_print_tbl l3mode_tbl[] = {
4564 MKT(UNI_BLLI_L3NSEQ, normal-seq),
4565 MKT(UNI_BLLI_L3ESEQ, extended-seq),
4568 static const struct uni_print_tbl l3psiz_tbl[] = {
4569 MKT(UNI_BLLI_L3_16, 16),
4570 MKT(UNI_BLLI_L3_32, 32),
4571 MKT(UNI_BLLI_L3_64, 64),
4572 MKT(UNI_BLLI_L3_128, 128),
4573 MKT(UNI_BLLI_L3_256, 256),
4574 MKT(UNI_BLLI_L3_512, 512),
4575 MKT(UNI_BLLI_L3_1024, 1024),
4576 MKT(UNI_BLLI_L3_2048, 2048),
4577 MKT(UNI_BLLI_L3_4096, 4096),
4580 static const struct uni_print_tbl l3ttype_tbl[] = {
4581 MKT(UNI_BLLI_L3_TTYPE_RECV, receive_only),
4582 MKT(UNI_BLLI_L3_TTYPE_SEND, send_only),
4583 MKT(UNI_BLLI_L3_TTYPE_BOTH, both),
4586 static const struct uni_print_tbl l3mux_tbl[] = {
4587 MKT(UNI_BLLI_L3_MUX_NOMUX, NOMUX),
4588 MKT(UNI_BLLI_L3_MUX_TS, TS),
4589 MKT(UNI_BLLI_L3_MUX_TSFEC, TSFEC),
4590 MKT(UNI_BLLI_L3_MUX_PS, PS),
4591 MKT(UNI_BLLI_L3_MUX_PSFEC, PSFEC),
4592 MKT(UNI_BLLI_L3_MUX_H221, H221),
4595 static const struct uni_print_tbl l3tcap_tbl[] = {
4596 MKT(UNI_BLLI_L3_TCAP_NOIND, noind),
4597 MKT(UNI_BLLI_L3_TCAP_AAL1, aal1),
4598 MKT(UNI_BLLI_L3_TCAP_AAL5, aal5),
4599 MKT(UNI_BLLI_L3_TCAP_AAL15, aal1&5),
4603 if(uni_print_iehdr("blli", &ie->h, cx))
4606 if(ie->h.present & UNI_BLLI_L1_P) {
4607 uni_print_entry(cx, "l1", "%u", ie->l1);
4610 if(ie->h.present & UNI_BLLI_L2_P) {
4611 uni_print_tbl("l2", ie->l2, l2_tbl, cx);
4612 uni_print_push_prefix("l2", cx);
4614 if(ie->h.present & UNI_BLLI_L2_USER_P)
4615 uni_print_entry(cx, "proto", "%u", ie->l2_user);
4616 if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4617 uni_print_entry(cx, "q933", "%u", ie->l2_q933);
4618 uni_print_tbl("mode", ie->l2_mode, l2mode_tbl, cx);
4620 if(ie->h.present & UNI_BLLI_L2_WSIZ_P)
4621 uni_print_entry(cx, "wsize", "%u", ie->l2_wsiz);
4622 uni_print_pop_prefix(cx);
4627 if(ie->h.present & UNI_BLLI_L3_P) {
4628 uni_print_tbl("l3", ie->l3, l3_tbl, cx);
4629 uni_print_push_prefix("l3", cx);
4631 if(ie->h.present & UNI_BLLI_L3_USER_P)
4632 uni_print_entry(cx, "proto", "%u", ie->l3_user);
4633 if(ie->h.present & UNI_BLLI_L3_MODE_P)
4634 uni_print_tbl("mode", ie->l3_mode, l3mode_tbl, cx);
4635 if(ie->h.present & UNI_BLLI_L3_PSIZ_P)
4636 uni_print_tbl("packet-size", ie->l3_psiz, l3psiz_tbl, cx);
4637 if(ie->h.present & UNI_BLLI_L3_WSIZ_P)
4638 uni_print_entry(cx, "window-size", "%u", ie->l3_wsiz);
4639 if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4640 uni_print_tbl("ttype", ie->l3_ttype, l3ttype_tbl, cx);
4641 uni_print_tbl("tcap", ie->l3_tcap, l3tcap_tbl, cx);
4643 if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4644 uni_print_tbl("fmux", ie->l3_fmux, l3mux_tbl, cx);
4645 uni_print_tbl("bmux", ie->l3_bmux, l3mux_tbl, cx);
4647 if(ie->h.present & UNI_BLLI_L3_IPI_P)
4648 uni_print_entry(cx, "ipi", "0x%02x", ie->l3_ipi);
4649 if(ie->h.present & UNI_BLLI_L3_SNAP_P)
4650 uni_print_entry(cx, "snap", "%06x.%04x", ie->oui, ie->pid);
4651 uni_print_pop_prefix(cx);
4656 uni_print_ieend(cx);
4659 DEF_IE_CHECK(itu, blli)
4663 if(ie->h.present & UNI_BLLI_L1_P)
4667 if(ie->h.present & UNI_BLLI_L2_P) {
4669 UNI_BLLI_L2_Q933_P | UNI_BLLI_L2_WSIZ_P |
4676 case UNI_BLLI_L2_BASIC:
4677 case UNI_BLLI_L2_Q921:
4678 case UNI_BLLI_L2_LABP:
4679 case UNI_BLLI_L2_LAN:
4680 case UNI_BLLI_L2_X75:
4681 if(ie->h.present & mask)
4685 case UNI_BLLI_L2_X25LL:
4686 case UNI_BLLI_L2_X25ML:
4687 case UNI_BLLI_L2_HDLC_ARM:
4688 case UNI_BLLI_L2_HDLC_NRM:
4689 case UNI_BLLI_L2_HDLC_ABM:
4690 case UNI_BLLI_L2_Q922:
4691 case UNI_BLLI_L2_ISO7776:
4692 switch(ie->h.present & mask) {
4697 case UNI_BLLI_L2_Q933_P:
4698 case UNI_BLLI_L2_Q933_P | UNI_BLLI_L2_WSIZ_P:
4703 case UNI_BLLI_L2_USER:
4704 switch(ie->h.present & mask) {
4709 case UNI_BLLI_L2_USER_P:
4714 if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4715 if(ie->l2_q933 != 0)
4718 switch(ie->l2_mode) {
4722 case UNI_BLLI_L2NORM:
4723 case UNI_BLLI_L2EXT:
4727 if(ie->h.present & UNI_BLLI_L2_WSIZ_P) {
4728 if(ie->l2_wsiz == 0 || ie->l2_wsiz > 127)
4731 if(ie->h.present & UNI_BLLI_L2_USER_P) {
4732 if(ie->l2_user > 127)
4736 if(ie->h.present & UNI_BLLI_L3_P) {
4738 UNI_BLLI_L3_MODE_P | UNI_BLLI_L3_PSIZ_P |
4739 UNI_BLLI_L3_WSIZ_P | UNI_BLLI_L3_USER_P |
4740 UNI_BLLI_L3_IPI_P | UNI_BLLI_L3_SNAP_P |
4741 UNI_BLLI_L3_TTYPE_P | UNI_BLLI_L3_MUX_P;
4747 case UNI_BLLI_L3_X25:
4748 case UNI_BLLI_L3_ISO8208:
4749 case UNI_BLLI_L3_X223:
4750 switch(ie->h.present & mask) {
4755 case UNI_BLLI_L3_MODE_P:
4756 case UNI_BLLI_L3_MODE_P |
4758 case UNI_BLLI_L3_MODE_P |
4759 UNI_BLLI_L3_PSIZ_P |
4765 case UNI_BLLI_L3_CLMP:
4766 case UNI_BLLI_L3_T70:
4767 if(ie->h.present & mask)
4771 case UNI_BLLI_L3_TR9577:
4772 switch(ie->h.present & mask) {
4777 case UNI_BLLI_L3_IPI_P:
4778 case UNI_BLLI_L3_IPI_P | UNI_BLLI_L3_SNAP_P:
4783 case UNI_BLLI_L3_H310:
4784 switch(ie->h.present & mask) {
4789 case UNI_BLLI_L3_TTYPE_P:
4790 case UNI_BLLI_L3_TTYPE_P|UNI_BLLI_L3_MUX_P:
4795 case UNI_BLLI_L3_USER:
4796 switch(ie->h.present & mask) {
4801 case UNI_BLLI_L3_USER_P:
4806 if(ie->h.present & UNI_BLLI_L3_MODE_P) {
4807 switch(ie->l3_mode) {
4811 case UNI_BLLI_L3NSEQ:
4812 case UNI_BLLI_L3ESEQ:
4816 if(ie->h.present & UNI_BLLI_L3_PSIZ_P) {
4817 switch(ie->l3_psiz) {
4821 case UNI_BLLI_L3_16:
4822 case UNI_BLLI_L3_32:
4823 case UNI_BLLI_L3_64:
4824 case UNI_BLLI_L3_128:
4825 case UNI_BLLI_L3_256:
4826 case UNI_BLLI_L3_512:
4827 case UNI_BLLI_L3_1024:
4828 case UNI_BLLI_L3_2048:
4829 case UNI_BLLI_L3_4096:
4833 if(ie->h.present & UNI_BLLI_L3_WSIZ_P) {
4834 if(ie->l3_wsiz == 0 || ie->l3_wsiz > 127)
4837 if(ie->h.present & UNI_BLLI_L3_IPI_P) {
4838 if(ie->l3_ipi == UNI_BLLI_L3_SNAP) {
4839 if(!(ie->h.present & UNI_BLLI_L3_SNAP_P))
4842 if(ie->h.present & UNI_BLLI_L3_SNAP_P)
4846 if(ie->h.present & UNI_BLLI_L3_USER_P) {
4847 if(ie->l3_user > 127)
4850 if(ie->h.present & UNI_BLLI_L3_SNAP_P) {
4851 if(ie->oui >= (1<<24))
4853 if(ie->pid >= (1<<16))
4856 if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4857 switch(ie->l3_ttype) {
4861 case UNI_BLLI_L3_TTYPE_RECV:
4862 case UNI_BLLI_L3_TTYPE_SEND:
4863 case UNI_BLLI_L3_TTYPE_BOTH:
4866 switch(ie->l3_tcap) {
4870 case UNI_BLLI_L3_TCAP_NOIND:
4871 case UNI_BLLI_L3_TCAP_AAL1:
4872 case UNI_BLLI_L3_TCAP_AAL5:
4873 case UNI_BLLI_L3_TCAP_AAL15:
4877 if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4878 switch(ie->l3_fmux) {
4882 case UNI_BLLI_L3_MUX_NOMUX:
4883 case UNI_BLLI_L3_MUX_TS:
4884 case UNI_BLLI_L3_MUX_TSFEC:
4885 case UNI_BLLI_L3_MUX_PS:
4886 case UNI_BLLI_L3_MUX_PSFEC:
4887 case UNI_BLLI_L3_MUX_H221:
4890 switch(ie->l3_bmux) {
4894 case UNI_BLLI_L3_MUX_NOMUX:
4895 case UNI_BLLI_L3_MUX_TS:
4896 case UNI_BLLI_L3_MUX_TSFEC:
4897 case UNI_BLLI_L3_MUX_PS:
4898 case UNI_BLLI_L3_MUX_PSFEC:
4899 case UNI_BLLI_L3_MUX_H221:
4908 DEF_IE_ENCODE(itu, blli)
4910 START_IE(blli, UNI_IE_BLLI, 13);
4912 if (IE_ISERROR(*ie)) {
4913 APP_BYTE(msg, 0xff);
4914 APP_BYTE(msg, 0xff);
4918 if(ie->h.present & UNI_BLLI_L1_P)
4919 APP_BYTE(msg, (UNI_BLLI_L1_ID<<5)|ie->l1|0x80);
4921 if(ie->h.present & UNI_BLLI_L2_P) {
4922 if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4923 APP_BYTE(msg, (UNI_BLLI_L2_ID<<5)|ie->l2);
4924 if(ie->h.present & UNI_BLLI_L2_WSIZ_P) {
4925 APP_BYTE(msg, (ie->l2_mode<<5)|ie->l2_q933);
4926 APP_BYTE(msg, ie->l2_wsiz | 0x80);
4928 APP_BYTE(msg, (ie->l2_mode<<5)|ie->l2_q933|0x80);
4930 } else if(ie->h.present & UNI_BLLI_L2_USER_P) {
4931 APP_BYTE(msg, (UNI_BLLI_L2_ID<<5)|ie->l2);
4932 APP_BYTE(msg, ie->l2_user | 0x80);
4934 APP_BYTE(msg, (UNI_BLLI_L2_ID << 5) | ie->l2 | 0x80);
4938 if(ie->h.present & UNI_BLLI_L3_P) {
4939 if(ie->h.present & UNI_BLLI_L3_MODE_P) {
4940 if(ie->h.present & UNI_BLLI_L3_PSIZ_P) {
4941 if(ie->h.present & UNI_BLLI_L3_WSIZ_P) {
4942 APP_BYTE(msg,(UNI_BLLI_L3_ID<<5)|ie->l3);
4943 APP_BYTE(msg,(ie->l3_mode<<5));
4944 APP_BYTE(msg,ie->l3_psiz);
4945 APP_BYTE(msg,ie->l3_wsiz|0x80);
4947 APP_BYTE(msg,(UNI_BLLI_L3_ID<<5)|ie->l3);
4948 APP_BYTE(msg,(ie->l3_mode<<5));
4949 APP_BYTE(msg,(ie->l3_psiz|0x80));
4952 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4953 APP_BYTE(msg, (ie->l3_mode<<5)|0x80);
4955 } else if(ie->h.present & UNI_BLLI_L3_USER_P) {
4956 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4957 APP_BYTE(msg,(ie->l3_user|0x80));
4958 } else if(ie->h.present & UNI_BLLI_L3_IPI_P) {
4959 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4960 APP_BYTE(msg,((ie->l3_ipi>>1) & 0x7f));
4961 APP_BYTE(msg,(((ie->l3_ipi&1)<<6)|0x80));
4962 if(ie->h.present & UNI_BLLI_L3_SNAP_P) {
4963 APP_BYTE(msg, 0x80);
4964 APP_BYTE(msg, (ie->oui >> 16));
4965 APP_BYTE(msg, (ie->oui >> 8));
4966 APP_BYTE(msg, (ie->oui >> 0));
4967 APP_BYTE(msg, (ie->pid >> 8));
4968 APP_BYTE(msg, (ie->pid >> 0));
4970 } else if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4971 if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4972 APP_BYTE(msg, ie->l3_ttype | (ie->l3_tcap << 4));
4973 APP_BYTE(msg, 0x80 | (ie->l3_fmux << 3) | ie->l3_bmux);
4975 APP_BYTE(msg, 0x80 | ie->l3_ttype | (ie->l3_tcap << 4));
4978 APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3|0x80);
4987 DEF_IE_DECODE(itu, blli)
4997 switch(((c = *msg->b_rptr++) >> 5) & 0x3) {
5001 case UNI_BLLI_L1_ID:
5002 ie->h.present |= UNI_BLLI_L1_P;
5008 case UNI_BLLI_L2_ID:
5009 ie->h.present |= UNI_BLLI_L2_P;
5016 if(ie->l2 == UNI_BLLI_L2_USER) {
5017 ie->h.present |= UNI_BLLI_L2_USER_P;
5018 ie->l2_user = c & 0x7f;
5022 ie->h.present |= UNI_BLLI_L2_Q933_P;
5023 ie->l2_q933 = c & 0x3;
5024 ie->l2_mode = (c >> 5) & 0x3;
5030 ie->h.present |= UNI_BLLI_L2_WSIZ_P;
5031 ie->l2_wsiz = c & 0x7f;
5039 case UNI_BLLI_L3_ID:
5040 ie->h.present |= UNI_BLLI_L3_P;
5045 case UNI_BLLI_L3_CLMP:
5046 case UNI_BLLI_L3_T70:
5049 case UNI_BLLI_L3_X25:
5050 case UNI_BLLI_L3_ISO8208:
5051 case UNI_BLLI_L3_X223:
5056 ie->l3_mode = (c >> 5) & 0x3;
5057 ie->h.present |= UNI_BLLI_L3_MODE_P;
5066 ie->l3_psiz = c & 0xf;
5067 ie->h.present |= UNI_BLLI_L3_PSIZ_P;
5076 ie->l3_wsiz = c & 0x7f;
5077 ie->h.present |= UNI_BLLI_L3_WSIZ_P;
5083 case UNI_BLLI_L3_TR9577:
5088 ie->l3_ipi = (c << 1) & 0xfe;
5092 ie->l3_ipi |= c & 1;
5095 ie->h.present |= UNI_BLLI_L3_IPI_P;
5097 if(ie->l3_ipi != UNI_BLLI_L3_SNAP)
5102 if(*msg->b_rptr++ != 0x80)
5104 ie->h.present |= UNI_BLLI_L3_SNAP_P;
5105 ie->oui = *msg->b_rptr++ << 16;
5106 ie->oui |= *msg->b_rptr++ << 8;
5107 ie->oui |= *msg->b_rptr++;
5108 ie->pid = *msg->b_rptr++ << 8;
5109 ie->pid |= *msg->b_rptr++;
5112 case UNI_BLLI_L3_H310:
5117 ie->l3_ttype = c & 0xf;
5118 ie->l3_tcap = (c >> 4) & 0x7;
5119 ie->h.present |= UNI_BLLI_L3_TTYPE_P;
5126 ie->l3_fmux = (c >> 3) & 7;
5127 ie->l3_bmux = c & 7;
5128 ie->h.present |= UNI_BLLI_L3_MUX_P;
5133 case UNI_BLLI_L3_USER:
5138 ie->l3_user = c & 0x7f;
5139 ie->h.present |= UNI_BLLI_L3_USER_P;
5152 /*********************************************************************
5154 * Broadband locking shift
5155 * Broadband non-locking shift.
5157 * References for this IE are:
5159 * Q.2931 pp. 41...42
5162 * Procedure not supported in UNI4.0, but IE's must be recognized.
5164 * Only ITU-T coding allowed.
5167 DEF_IE_PRINT(itu, lshift)
5169 if(uni_print_iehdr("locking_shift", &ie->h, cx))
5171 uni_print_ieend(cx);
5174 DEF_IE_CHECK(itu, lshift)
5176 UNUSED(cx); UNUSED(ie);
5180 DEF_IE_ENCODE(itu, lshift)
5182 START_IE(lshift, UNI_IE_LSHIFT, 1);
5183 APP_BYTE(msg, 0x80 | ie->set);
5188 DEF_IE_DECODE(itu, lshift)
5206 /***********************************************************************/
5208 DEF_IE_PRINT(itu, nlshift)
5210 if(uni_print_iehdr("nonlocking_shift", &ie->h, cx))
5212 uni_print_ieend(cx);
5215 DEF_IE_CHECK(itu, nlshift)
5217 UNUSED(cx); UNUSED(ie);
5221 DEF_IE_ENCODE(itu, nlshift)
5223 START_IE(nlshift, UNI_IE_NLSHIFT, 1);
5224 APP_BYTE(msg, 0x80 | ie->set);
5229 DEF_IE_DECODE(itu, nlshift)
5247 /*********************************************************************
5249 * Broadband Sending Complete Indicator
5251 * References for this IE are:
5255 * Only ITU-T coding allowed.
5257 DEF_IE_PRINT(itu, scompl)
5259 if(uni_print_iehdr("sending_complete", &ie->h, cx))
5261 uni_print_ieend(cx);
5264 DEF_IE_CHECK(itu, scompl)
5266 UNUSED(ie); UNUSED(cx);
5270 DEF_IE_ENCODE(itu, scompl)
5272 START_IE(scompl, UNI_IE_SCOMPL, 1);
5274 APP_BYTE(msg, 0x80 | 0x21);
5280 DEF_IE_DECODE(itu, scompl)
5287 if(*msg->b_rptr++ != (0x80 | 0x21))
5293 /*********************************************************************
5295 * Broadband Repeat Indicator
5297 * References for this IE are:
5302 * Q.2931 has table 4-19. Only codepoints 0x2 and 0xa (for PNNI) supported.
5304 * Only ITU-T coding allowed.
5306 DEF_IE_PRINT(itu, repeat)
5308 static const struct uni_print_tbl tbl[] = {
5309 MKT(UNI_REPEAT_PRIDESC, desc),
5310 MKT(UNI_REPEAT_STACK, stack),
5314 if(uni_print_iehdr("repeat", &ie->h, cx))
5316 uni_print_tbl("type", ie->type, tbl, cx);
5317 uni_print_ieend(cx);
5320 DEF_IE_CHECK(itu, repeat)
5324 case UNI_REPEAT_PRIDESC:
5327 case UNI_REPEAT_STACK:
5338 DEF_IE_ENCODE(itu, repeat)
5340 START_IE(repeat, UNI_IE_REPEAT, 1);
5342 APP_BYTE(msg, 0x80 | ie->type);
5348 DEF_IE_DECODE(itu, repeat)
5365 /*********************************************************************
5367 * Transit Network Selection
5369 * References for this IE are:
5371 * Q.2931 pp. 75...76
5374 * According to UNI4.0 this is always National Network Id/Carried Id.
5376 * ITU-T/Net coding allowed.
5379 DEF_IE_PRINT(itu, tns)
5383 if(uni_print_iehdr("tns", &ie->h, cx))
5385 uni_print_entry(cx, "net", "%u,\"", ie->len);
5387 for(i = 0; i < ie->len; i++) {
5388 if(ie->net[i] < ' ')
5389 uni_printf(cx, "^%c", ie->net[i] + '@');
5390 else if(ie->net[i] < '~')
5391 uni_putc(ie->net[i], cx);
5393 uni_printf(cx, "\\%03o", ie->net[i]);
5396 uni_print_ieend(cx);
5399 DEF_IE_CHECK(itu, tns)
5405 if(ie->len == 0 || ie->len > UNI_TNS_MAXLEN)
5407 for(i = 0; i < ie->len; i++)
5408 if(ie->net[i] < ' ' || ie->net[i] > '~')
5413 DEF_IE_ENCODE(itu, tns)
5415 START_IE(tns, UNI_IE_TNS, ie->len + 1);
5417 APP_BYTE(msg, 0x80 | (0x2 << 4) | 0x1);
5418 APP_BUF(msg, ie->net, ie->len);
5424 DEF_IE_DECODE(itu, tns)
5428 if(ielen < 2 || ielen > 5)
5431 if(*msg->b_rptr++ != (0x80 | (0x2 << 4) | 0x1))
5437 ie->net[ie->len++] = *msg->b_rptr++;
5442 /*********************************************************************
5446 * References for this IE are:
5448 * Q.2931 pp. 73...74
5451 * Only ITU-T coding allowed.
5454 DEF_IE_PRINT(itu, restart)
5456 static const struct uni_print_tbl tbl[] = {
5457 MKT(UNI_RESTART_CHANNEL, channel),
5458 MKT(UNI_RESTART_PATH, path),
5459 MKT(UNI_RESTART_ALL, all),
5463 if(uni_print_iehdr("restart", &ie->h, cx))
5465 uni_print_tbl("class", ie->rclass, tbl, cx);
5466 uni_print_ieend(cx);
5469 DEF_IE_CHECK(itu, restart)
5473 switch(ie->rclass) {
5477 case UNI_RESTART_CHANNEL:
5478 case UNI_RESTART_PATH:
5479 case UNI_RESTART_ALL:
5486 DEF_IE_ENCODE(itu, restart)
5488 START_IE(restart, UNI_IE_RESTART, 1);
5490 APP_BYTE(msg, 0x80 | ie->rclass);
5496 DEF_IE_DECODE(itu, restart)
5505 ie->rclass = (c = *msg->b_rptr++) & 0x7;
5513 /*********************************************************************
5515 * User-to-user info.
5517 * References for this IE are:
5521 * Only ITU-T coding allowed.
5524 DEF_IE_PRINT(itu, uu)
5528 if(uni_print_iehdr("uu", &ie->h, cx))
5530 uni_print_entry(cx, "len", "%u", ie->len);
5531 uni_print_entry(cx, "info", "(");
5532 for(i = 0; i < ie->len; i++)
5533 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->uu[i]);
5534 uni_printf(cx, ")");
5535 uni_print_ieend(cx);
5538 DEF_IE_CHECK(itu, uu)
5542 if(ie->len > UNI_UU_MAXLEN)
5548 DEF_IE_ENCODE(itu, uu)
5550 START_IE(uu, UNI_IE_UU, ie->len);
5552 APP_BUF(msg, ie->uu, ie->len);
5558 DEF_IE_DECODE(itu, uu)
5562 if(ielen > UNI_UU_MAXLEN || ielen < 1)
5567 (void)memcpy(ie->uu, msg->b_rptr, ie->len);
5568 msg->b_rptr += ie->len;
5573 /*********************************************************************
5575 * Generic Identifier Transport
5577 * References for this IE are:
5579 * UNI4.0 pp. 26...28
5581 * UNI4.0 prescribes a fixed format for this IE. We have a flag in the
5582 * context structur, which tells us whether the check of this IE should be
5583 * hard or soft. Probably it should be hard for end systems and soft for
5586 * Only Net Coding allowed. (XXX)
5589 DEF_IE_PRINT(net, git)
5591 static const struct uni_print_tbl std_tbl[] = {
5592 MKT(UNI_GIT_STD_DSMCC, dsmcc),
5593 MKT(UNI_GIT_STD_H245, H.245),
5596 static const struct uni_print_tbl type_tbl[] = {
5597 MKT(UNI_GIT_TYPE_SESS, sess),
5598 MKT(UNI_GIT_TYPE_RES, res),
5604 if(uni_print_iehdr("git", &ie->h, cx))
5607 uni_print_tbl("std", ie->std, std_tbl, cx);
5610 uni_print_push_prefix("id", cx);
5612 for(i = 0; i < ie->numsub; i++) {
5613 sprintf(buf, "%u", i);
5614 uni_print_entry(cx, buf, "(");
5615 uni_print_tbl(NULL, ie->sub[i].type, type_tbl, cx);
5616 for(j = 0; j < ie->sub[i].len; j++)
5617 uni_printf(cx, ",0x%02x", ie->sub[i].val[j]);
5618 uni_printf(cx, ")");
5622 uni_print_pop_prefix(cx);
5624 uni_print_ieend(cx);
5627 DEF_IE_CHECK(net, git)
5633 case UNI_GIT_STD_DSMCC:
5634 case UNI_GIT_STD_H245:
5641 if(ie->sub[0].type != UNI_GIT_TYPE_SESS)
5643 if(ie->sub[0].len > UNI_GIT_MAXSESS)
5645 if(ie->sub[1].type != UNI_GIT_TYPE_RES)
5647 if(ie->sub[1].len > UNI_GIT_MAXRES)
5650 if(ie->numsub > UNI_GIT_MAXSUB)
5652 for(i = 0; i < ie->numsub; i++)
5653 if(ie->sub[i].len > UNI_GIT_MAXVAL)
5659 DEF_IE_ENCODE(net, git)
5663 START_IE(git, UNI_IE_GIT, 1 + ie->numsub * (1 + UNI_GIT_MAXVAL));
5665 APP_BYTE(msg, ie->std);
5666 for(i = 0; i < ie->numsub; i++) {
5667 APP_BYTE(msg, ie->sub[i].type);
5668 APP_BYTE(msg, ie->sub[i].len);
5669 APP_BUF(msg, ie->sub[i].val, ie->sub[i].len);
5676 DEF_IE_DECODE(net, git)
5680 if(ielen > 1 + UNI_GIT_MAXSUB * (1 + UNI_GIT_MAXVAL) || ielen < 1)
5683 ie->std = *msg->b_rptr++;
5688 if(ie->numsub >= UNI_GIT_MAXSUB)
5691 ie->sub[ie->numsub].type = *msg->b_rptr++;
5696 ie->sub[ie->numsub].len = *msg->b_rptr++;
5699 if(ie->sub[ie->numsub].len > UNI_GIT_MAXVAL)
5701 if(ie->sub[ie->numsub].len > (u_int)ielen)
5704 (void)memcpy(ie->sub[ie->numsub].val, msg->b_rptr, ie->sub[ie->numsub].len);
5705 ielen -= ie->sub[ie->numsub].len;
5706 msg->b_rptr += ie->sub[ie->numsub].len;
5714 /*********************************************************************
5716 * Additional ABR Parameters
5717 * ABR Setup parameters
5719 * References for this IE are:
5721 * UNI4.0 pp. 78...82
5729 print_abr_rec(struct unicx *cx, struct uni_abr_rec *rec)
5731 if(rec->present & UNI_ABR_REC_NRM_P)
5732 uni_print_entry(cx, "nrm", "%d", rec->nrm);
5733 if(rec->present & UNI_ABR_REC_TRM_P)
5734 uni_print_entry(cx, "trm", "%d", rec->trm);
5735 if(rec->present & UNI_ABR_REC_CDF_P)
5736 uni_print_entry(cx, "cdf", "%d", rec->cdf);
5737 if(rec->present & UNI_ABR_REC_ADTF_P)
5738 uni_print_entry(cx, "adtf", "%d", rec->adtf);
5741 DEF_IE_PRINT(net, abradd)
5743 if(uni_print_iehdr("abradd", &ie->h, cx))
5746 uni_print_push_prefix("fwd", cx);
5747 print_abr_rec(cx, &ie->fwd);
5748 uni_print_pop_prefix(cx);
5750 uni_print_push_prefix("bwd", cx);
5751 print_abr_rec(cx, &ie->bwd);
5752 uni_print_pop_prefix(cx);
5754 uni_print_ieend(cx);
5757 DEF_IE_CHECK(net, abradd)
5766 encode_abr_rec(struct uni_abr_rec *rec)
5768 u_int ret = rec->present & 0xf000;
5770 if(ret & UNI_ABR_REC_NRM_P)
5771 ret |= (rec->nrm & 0x7) << 25;
5772 if(ret & UNI_ABR_REC_TRM_P)
5773 ret |= (rec->trm & 0x7) << 22;
5774 if(ret & UNI_ABR_REC_CDF_P)
5775 ret |= (rec->cdf & 0x7) << 19;
5776 if(ret & UNI_ABR_REC_ADTF_P)
5777 ret |= (rec->adtf & 0x3ff) << 9;
5782 DEF_IE_ENCODE(net, abradd)
5784 START_IE(abradd, UNI_IE_ABRADD, 10);
5786 APP_SUB_32BIT(msg, UNI_ABRADD_FADD_ID, encode_abr_rec(&ie->fwd));
5787 APP_SUB_32BIT(msg, UNI_ABRADD_BADD_ID, encode_abr_rec(&ie->bwd));
5794 decode_abr_rec(struct uni_msg *msg, struct uni_abr_rec *rec)
5798 val = *msg->b_rptr++ << 24;
5799 val |= *msg->b_rptr++ << 16;
5800 val |= *msg->b_rptr++ << 8;
5801 val |= *msg->b_rptr++ << 0;
5803 rec->present = val & 0xf000;
5805 rec->nrm = (val & UNI_ABR_REC_NRM_P) ? ((val >> 25) & 0x7) : 0;
5806 rec->trm = (val & UNI_ABR_REC_TRM_P) ? ((val >> 22) & 0x7) : 0;
5807 rec->cdf = (val & UNI_ABR_REC_CDF_P) ? ((val >> 19) & 0x7) : 0;
5808 rec->adtf = (val & UNI_ABR_REC_ADTF_P)? ((val >> 9) & 0x3ff) : 0;
5813 DEF_IE_DECODE(net, abradd)
5822 switch(*msg->b_rptr++) {
5827 case UNI_ABRADD_FADD_ID:
5828 if(decode_abr_rec(msg, &ie->fwd))
5833 case UNI_ABRADD_BADD_ID:
5834 if(decode_abr_rec(msg, &ie->bwd))
5843 /*********************************************************************/
5845 DEF_IE_PRINT(net, abrsetup)
5847 if(uni_print_iehdr("abrsetup", &ie->h, cx))
5850 uni_print_entry(cx, "rm_frt", "%d", ie->rmfrt);
5852 uni_print_push_prefix("fwd", cx);
5853 if(ie->h.present & UNI_ABRSETUP_FICR_P)
5854 uni_print_entry(cx, "icr", "%d", ie->ficr);
5855 if(ie->h.present & UNI_ABRSETUP_FTBE_P)
5856 uni_print_entry(cx, "tbe", "%d", ie->ftbe);
5857 if(ie->h.present & UNI_ABRSETUP_FRIF_P)
5858 uni_print_entry(cx, "rif", "%d", ie->frif);
5859 if(ie->h.present & UNI_ABRSETUP_FRDF_P)
5860 uni_print_entry(cx, "rdf", "%d", ie->frdf);
5861 uni_print_pop_prefix(cx);
5863 uni_print_push_prefix("bwd", cx);
5864 if(ie->h.present & UNI_ABRSETUP_BICR_P)
5865 uni_print_entry(cx, "icr", "%d", ie->bicr);
5866 if(ie->h.present & UNI_ABRSETUP_BTBE_P)
5867 uni_print_entry(cx, "tbe", "%d", ie->btbe);
5868 if(ie->h.present & UNI_ABRSETUP_BRIF_P)
5869 uni_print_entry(cx, "rif", "%d", ie->brif);
5870 if(ie->h.present & UNI_ABRSETUP_BRDF_P)
5871 uni_print_entry(cx, "rdf", "%d", ie->brdf);
5872 uni_print_pop_prefix(cx);
5874 uni_print_ieend(cx);
5877 DEF_IE_CHECK(net, abrsetup)
5880 if(!(ie->h.present & UNI_ABRSETUP_FICR_P))
5882 if(!(ie->h.present & UNI_ABRSETUP_BICR_P))
5884 if(!(ie->h.present & UNI_ABRSETUP_FTBE_P))
5886 if(!(ie->h.present & UNI_ABRSETUP_BTBE_P))
5888 if(!(ie->h.present & UNI_ABRSETUP_FRIF_P))
5890 if(!(ie->h.present & UNI_ABRSETUP_BRIF_P))
5892 if(!(ie->h.present & UNI_ABRSETUP_FRDF_P))
5894 if(!(ie->h.present & UNI_ABRSETUP_BRDF_P))
5896 if(!(ie->h.present & UNI_ABRSETUP_RMFRT_P))
5900 if(!(ie->h.present & UNI_ABRSETUP_RMFRT_P))
5903 if(ie->h.present & UNI_ABRSETUP_FICR_P)
5904 if(ie->ficr >= 1 << 24)
5906 if(ie->h.present & UNI_ABRSETUP_BICR_P)
5907 if(ie->bicr >= 1 << 24)
5910 if(ie->h.present & UNI_ABRSETUP_FTBE_P)
5911 if(ie->ftbe >= 1 << 24 || ie->ftbe == 0)
5913 if(ie->h.present & UNI_ABRSETUP_BTBE_P)
5914 if(ie->btbe >= 1 << 24 || ie->btbe == 0)
5917 if(ie->rmfrt >= 1 << 24)
5920 if(ie->h.present & UNI_ABRSETUP_FRIF_P)
5923 if(ie->h.present & UNI_ABRSETUP_FRDF_P)
5926 if(ie->h.present & UNI_ABRSETUP_BRIF_P)
5929 if(ie->h.present & UNI_ABRSETUP_BRDF_P)
5935 DEF_IE_ENCODE(net, abrsetup)
5937 START_IE(abrsetup, UNI_IE_ABRSETUP, 32);
5939 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_FICR_P,
5940 UNI_ABRSETUP_FICR_ID, ie->ficr);
5941 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_BICR_P,
5942 UNI_ABRSETUP_BICR_ID, ie->bicr);
5943 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_FTBE_P,
5944 UNI_ABRSETUP_FTBE_ID, ie->ftbe);
5945 APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_BTBE_P,
5946 UNI_ABRSETUP_BTBE_ID, ie->btbe);
5947 APP_SUB_24BIT(msg, UNI_ABRSETUP_RMFRT_ID, ie->rmfrt);
5948 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_FRIF_P,
5949 UNI_ABRSETUP_FRIF_ID, ie->frif);
5950 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_BRIF_P,
5951 UNI_ABRSETUP_BRIF_ID, ie->brif);
5952 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_FRDF_P,
5953 UNI_ABRSETUP_FRDF_ID, ie->frdf);
5954 APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_BRDF_P,
5955 UNI_ABRSETUP_BRDF_ID, ie->brdf);
5961 DEF_IE_DECODE(net, abrsetup)
5965 if(ielen < 4 || ielen > 32)
5970 switch(*msg->b_rptr++) {
5976 DEC_GETF3(ABRSETUP_FICR, ficr, ie->h.present);
5977 DEC_GETF3(ABRSETUP_BICR, bicr, ie->h.present);
5978 DEC_GETF3(ABRSETUP_FTBE, ftbe, ie->h.present);
5979 DEC_GETF3(ABRSETUP_BTBE, btbe, ie->h.present);
5980 DEC_GETF1(ABRSETUP_FRIF, frif, ie->h.present);
5981 DEC_GETF1(ABRSETUP_BRIF, brif, ie->h.present);
5982 DEC_GETF1(ABRSETUP_FRDF, frdf, ie->h.present);
5983 DEC_GETF1(ABRSETUP_BRDF, brdf, ie->h.present);
5984 DEC_GETF3(ABRSETUP_RMFRT, frif, ie->h.present);
5990 /*********************************************************************
5992 * Broadband report type
5994 * References for this IE are:
5996 * Q.2963.1 pp. 7...8
5998 * Only ITU-T coding allowed.
6001 DEF_IE_PRINT(itu, report)
6003 static const struct uni_print_tbl tbl[] = {
6004 MKT(UNI_REPORT_MODCONF, modconf),
6005 MKT(UNI_REPORT_CLOCK, clock),
6006 MKT(UNI_REPORT_EEAVAIL, eeavail),
6007 MKT(UNI_REPORT_EEREQ, eereq),
6008 MKT(UNI_REPORT_EECOMPL, eecompl),
6012 if(uni_print_iehdr("report", &ie->h, cx))
6014 uni_print_tbl("type", ie->report, tbl, cx);
6015 uni_print_ieend(cx);
6018 DEF_IE_CHECK(itu, report)
6022 switch(ie->report) {
6027 case UNI_REPORT_MODCONF:
6028 case UNI_REPORT_CLOCK:
6029 case UNI_REPORT_EEAVAIL:
6030 case UNI_REPORT_EEREQ:
6031 case UNI_REPORT_EECOMPL:
6037 DEF_IE_ENCODE(itu, report)
6039 START_IE(report, UNI_IE_REPORT, 1);
6041 APP_BYTE(msg, ie->report);
6047 DEF_IE_DECODE(itu, report)
6053 ie->report = *msg->b_rptr++;
6058 /*********************************************************************
6062 * References for this IE are:
6064 * PNNI1.0 pp. 201...203
6066 * Only NET coding allowed.
6068 DEF_IE_PRINT(net, calling_soft)
6070 if(uni_print_iehdr("calling_soft", &ie->h, cx))
6073 uni_print_entry(cx, "vpi", "%d", ie->vpi);
6074 if(ie->h.present & UNI_CALLING_SOFT_VCI_P)
6075 uni_print_entry(cx, "vci", "%d", ie->vci);
6077 uni_print_ieend(cx);
6080 DEF_IE_PRINT(net, called_soft)
6082 static const struct uni_print_tbl tab[] = {
6083 MKT(UNI_SOFT_SEL_ANY, any),
6084 MKT(UNI_SOFT_SEL_REQ, required),
6085 MKT(UNI_SOFT_SEL_ASS, assigned),
6089 if(uni_print_iehdr("called_soft", &ie->h, cx))
6092 uni_print_tbl("selection", ie->sel, tab, cx);
6093 if(ie->h.present & UNI_CALLED_SOFT_VPI_P)
6094 uni_print_entry(cx, "vpi", "%d", ie->vpi);
6095 if(ie->h.present & UNI_CALLED_SOFT_VCI_P)
6096 uni_print_entry(cx, "vci", "%d", ie->vci);
6098 uni_print_ieend(cx);
6101 DEF_IE_CHECK(net, calling_soft)
6105 if(ie->vpi >= 1 << 12)
6110 DEF_IE_CHECK(net, called_soft)
6116 case UNI_SOFT_SEL_ANY:
6117 case UNI_SOFT_SEL_REQ:
6118 case UNI_SOFT_SEL_ASS:
6124 if(ie->h.present & UNI_CALLED_SOFT_VPI_P) {
6125 if(ie->vpi >= 1 << 12)
6128 if(ie->sel != UNI_SOFT_SEL_ANY)
6132 if(ie->h.present & UNI_CALLED_SOFT_VCI_P)
6133 if(!(ie->h.present & UNI_CALLED_SOFT_VPI_P))
6140 DEF_IE_ENCODE(net, calling_soft)
6142 START_IE(calling_soft, UNI_IE_CALLING_SOFT, 6);
6144 APP_BYTE(msg, 0x81);
6145 APP_16BIT(msg, ie->vpi);
6147 if(ie->h.present & UNI_CALLING_SOFT_VCI_P) {
6148 APP_BYTE(msg, 0x82);
6149 APP_16BIT(msg, ie->vci);
6156 DEF_IE_ENCODE(net, called_soft)
6158 START_IE(called_soft, UNI_IE_CALLED_SOFT, 7);
6160 APP_BYTE(msg, ie->sel);
6162 if(ie->h.present & UNI_CALLED_SOFT_VPI_P) {
6163 APP_BYTE(msg, 0x81);
6164 APP_16BIT(msg, ie->vpi);
6167 if(ie->h.present & UNI_CALLED_SOFT_VCI_P) {
6168 APP_BYTE(msg, 0x82);
6169 APP_16BIT(msg, ie->vci);
6176 DEF_IE_DECODE(net, calling_soft)
6178 int vci_seen, vpi_seen;
6188 switch(*msg->b_rptr++) {
6192 ie->vpi = *msg->b_rptr++ << 8;
6193 ie->vpi |= *msg->b_rptr++;
6202 ie->vci = *msg->b_rptr++ << 8;
6203 ie->vci |= *msg->b_rptr++;
6207 ie->h.present |= UNI_CALLING_SOFT_VCI_P;
6219 IE_END(CALLING_SOFT);
6222 DEF_IE_DECODE(net, called_soft)
6224 int vci_seen, vpi_seen;
6234 switch(*msg->b_rptr++) {
6238 ie->vpi = *msg->b_rptr++ << 8;
6239 ie->vpi |= *msg->b_rptr++;
6245 ie->h.present |= UNI_CALLED_SOFT_VCI_P;
6250 ie->vci = *msg->b_rptr++ << 8;
6251 ie->vci |= *msg->b_rptr++;
6256 ie->h.present |= UNI_CALLED_SOFT_VCI_P;
6265 IE_END(CALLED_SOFT);
6268 /*********************************************************************
6272 * References for this IE are:
6274 * PNNI1.0 pp. 203...206
6276 * Only NET coding allowed.
6279 DEF_IE_PRINT(net, crankback)
6283 if(uni_print_iehdr("crankback", &ie->h, cx))
6286 uni_print_entry(cx, "level", "%d", ie->level);
6290 case UNI_CRANKBACK_IF:
6291 uni_print_entry(cx, "type", "interface");
6294 case UNI_CRANKBACK_NODE:
6295 uni_print_entry(cx, "type", "node");
6296 uni_print_entry(cx, "node", "{%d/", ie->id.node.level);
6297 for(j = 0; j < 21; j++)
6298 uni_printf(cx, "%02x", ie->id.node.id[j]);
6299 uni_printf(cx, "}");
6303 case UNI_CRANKBACK_LINK:
6304 uni_print_entry(cx, "type", "link");
6305 uni_print_push_prefix("link", cx);
6308 uni_print_entry(cx, "prec", "{%d/", ie->id.link.plevel);
6309 for(j = 0; j < 21; j++)
6310 uni_printf(cx, "%02x", ie->id.link.pid[j]);
6311 uni_printf(cx, "}");
6314 uni_print_entry(cx, "port", "0x%04x", ie->id.link.port);
6317 uni_print_entry(cx, "succ", "{%d/", ie->id.link.slevel);
6318 for(j = 0; j < 21; j++)
6319 uni_printf(cx, "%02x", ie->id.link.sid[j]);
6320 uni_printf(cx, "}");
6324 uni_print_pop_prefix(cx);
6328 uni_print_entry(cx, "type", "0x%02x", ie->type);
6332 uni_print_entry(cx, "cause", "0x%02x", ie->cause);
6334 if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6335 uni_print_push_prefix("topol", cx);
6336 uni_print_entry(cx, "dir", "%d", ie->diag.top.dir);
6337 uni_print_entry(cx, "port", "0x%04x", ie->diag.top.port);
6338 uni_print_entry(cx, "avcr", "%u", ie->diag.top.avcr);
6339 if(ie->h.present & UNI_CRANKBACK_TOPX_P) {
6340 uni_print_entry(cx, "crm", "%u", ie->diag.top.crm);
6341 uni_print_entry(cx, "vf", "%u", ie->diag.top.vf);
6343 uni_print_pop_prefix(cx);
6346 if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6347 uni_print_push_prefix("qos", cx);
6348 uni_print_entry(cx, "ctd", "%savail", ie->diag.qos.ctd ? "" : "un");
6349 uni_print_entry(cx, "cdv", "%savail", ie->diag.qos.cdv ? "" : "un");
6350 uni_print_entry(cx, "clr", "%savail", ie->diag.qos.clr ? "" : "un");
6351 uni_print_entry(cx, "other", "%savail", ie->diag.qos.other ? "" : "un");
6352 uni_print_pop_prefix(cx);
6357 uni_print_ieend(cx);
6360 DEF_IE_CHECK(net, crankback)
6367 case UNI_CRANKBACK_IF:
6369 case UNI_CRANKBACK_NODE:
6370 if(ie->id.node.level > 104)
6374 case UNI_CRANKBACK_LINK:
6375 if(ie->id.link.plevel > 104)
6377 if(ie->id.link.slevel > 104)
6385 if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6386 if(ie->h.present & UNI_CRANKBACK_QOS_P)
6389 if(ie->cause != UNI_CAUSE_CRATE_NAVL)
6391 switch(ie->diag.top.dir) {
6401 if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6402 if(ie->cause != UNI_CAUSE_QOS_NAVL)
6408 DEF_IE_ENCODE(net, crankback)
6410 START_IE(crankback, UNI_IE_CRANKBACK, 72);
6412 APP_BYTE(msg, ie->level);
6413 APP_BYTE(msg, ie->type);
6417 case UNI_CRANKBACK_IF:
6420 case UNI_CRANKBACK_NODE:
6421 APP_BYTE(msg, ie->id.node.level);
6422 APP_BUF(msg, ie->id.node.id, 21);
6425 case UNI_CRANKBACK_LINK:
6426 APP_BYTE(msg, ie->id.link.plevel);
6427 APP_BUF(msg, ie->id.link.pid, 21);
6428 APP_32BIT(msg, ie->id.link.port);
6429 APP_BYTE(msg, ie->id.link.slevel);
6430 APP_BUF(msg, ie->id.link.sid, 21);
6434 APP_BYTE(msg, ie->cause);
6436 if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6437 APP_BYTE(msg, ie->diag.top.dir);
6438 APP_32BIT(msg, ie->diag.top.port);
6439 APP_32BIT(msg, ie->diag.top.avcr);
6440 if(ie->h.present & UNI_CRANKBACK_TOPX_P) {
6441 APP_32BIT(msg, ie->diag.top.crm);
6442 APP_32BIT(msg, ie->diag.top.vf);
6446 if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6447 APP_BYTE(msg, (ie->diag.qos.ctd << 3)
6448 |(ie->diag.qos.cdv << 2)
6449 |(ie->diag.qos.clr << 1)
6450 |(ie->diag.qos.other));
6457 DEF_IE_DECODE(net, crankback)
6464 ie->level = *msg->b_rptr++;
6467 ie->type = *msg->b_rptr++;
6475 case UNI_CRANKBACK_IF:
6478 case UNI_CRANKBACK_NODE:
6481 ie->id.node.level = *msg->b_rptr++;
6482 (void)memcpy(ie->id.node.id, msg->b_rptr, 21);
6487 case UNI_CRANKBACK_LINK:
6490 ie->id.link.plevel = *msg->b_rptr++;
6491 (void)memcpy(ie->id.link.pid, msg->b_rptr, 21);
6495 ie->id.link.port = *msg->b_rptr++ << 24;
6496 ie->id.link.port |= *msg->b_rptr++ << 16;
6497 ie->id.link.port |= *msg->b_rptr++ << 8;
6498 ie->id.link.port |= *msg->b_rptr++ << 0;
6501 ie->id.link.slevel = *msg->b_rptr++;
6502 (void)memcpy(ie->id.link.sid, msg->b_rptr, 21);
6511 ie->cause = *msg->b_rptr++;
6514 if(ie->cause == UNI_CAUSE_CRATE_NAVL) {
6516 if(ielen != 9 && ielen != 17)
6518 ie->diag.top.dir = *msg->b_rptr++;
6519 ie->diag.top.port = *msg->b_rptr++ << 24;
6520 ie->diag.top.port |= *msg->b_rptr++ << 16;
6521 ie->diag.top.port |= *msg->b_rptr++ << 8;
6522 ie->diag.top.port |= *msg->b_rptr++ << 0;
6523 ie->diag.top.avcr = *msg->b_rptr++ << 24;
6524 ie->diag.top.avcr |= *msg->b_rptr++ << 16;
6525 ie->diag.top.avcr |= *msg->b_rptr++ << 8;
6526 ie->diag.top.avcr |= *msg->b_rptr++ << 0;
6528 ie->h.present |= UNI_CRANKBACK_TOP_P;
6530 ie->diag.top.crm = *msg->b_rptr++ << 24;
6531 ie->diag.top.crm |= *msg->b_rptr++ << 16;
6532 ie->diag.top.crm |= *msg->b_rptr++ << 8;
6533 ie->diag.top.crm |= *msg->b_rptr++ << 0;
6534 ie->diag.top.vf = *msg->b_rptr++ << 24;
6535 ie->diag.top.vf |= *msg->b_rptr++ << 16;
6536 ie->diag.top.vf |= *msg->b_rptr++ << 8;
6537 ie->diag.top.vf |= *msg->b_rptr++ << 0;
6538 ie->h.present |= UNI_CRANKBACK_TOPX_P;
6542 } else if(ie->cause == UNI_CAUSE_QOS_NAVL) {
6546 ie->diag.qos.ctd = *msg->b_rptr >> 3;
6547 ie->diag.qos.cdv = *msg->b_rptr >> 2;
6548 ie->diag.qos.clr = *msg->b_rptr >> 1;
6549 ie->diag.qos.other = *msg->b_rptr >> 0;
6550 ie->h.present |= UNI_CRANKBACK_QOS_P;
6561 /*********************************************************************
6563 * Designated transit list
6565 * References for this IE are:
6567 * PNNI1.0 pp. 206...208
6569 * Only NET coding allowed.
6571 DEF_IE_PRINT(net, dtl)
6576 if(uni_print_iehdr("dtl", &ie->h, cx))
6579 uni_print_entry(cx, "ptr", "%d(%d)", ie->ptr, ie->ptr / UNI_DTL_LOGNP_SIZE);
6580 uni_print_push_prefix("dtl", cx);
6582 uni_printf(cx, "{");
6583 for(i = 0; i < ie->num; i++) {
6584 sprintf(buf, "%d", i);
6585 uni_print_entry(cx, buf, "{%d/", ie->dtl[i].node_level);
6586 for(j = 0; j < 21; j++)
6587 uni_printf(cx, "%02x", ie->dtl[i].node_id[j]);
6588 uni_printf(cx, ",%04x}", ie->dtl[i].port_id);
6592 uni_print_pop_prefix(cx);
6593 uni_print_ieend(cx);
6596 DEF_IE_CHECK(net, dtl)
6602 if(ie->ptr % UNI_DTL_LOGNP_SIZE != 0)
6604 if(ie->ptr / UNI_DTL_LOGNP_SIZE > UNI_DTL_MAXNUM)
6606 if(ie->num > UNI_DTL_MAXNUM)
6608 for(i = 0; i < ie->num; i++)
6609 if(ie->dtl[i].node_level > 104)
6614 DEF_IE_ENCODE(net, dtl)
6618 START_IE(dtl, UNI_IE_DTL, 2 + UNI_DTL_LOGNP_SIZE * ie->num);
6620 APP_16BIT(msg, ie->ptr);
6622 for(i = 0; i < ie->num; i++) {
6623 APP_BYTE(msg, UNI_DTL_LOGNP);
6624 APP_BYTE(msg, ie->dtl[i].node_level);
6625 APP_BUF(msg, ie->dtl[i].node_id, 21);
6626 APP_32BIT(msg, ie->dtl[i].port_id);
6634 DEF_IE_DECODE(net, dtl)
6641 ie->ptr = *msg->b_rptr++ << 8;
6642 ie->ptr |= *msg->b_rptr++;
6645 if(ielen % UNI_DTL_LOGNP_SIZE != 0)
6647 if(ielen / UNI_DTL_LOGNP_SIZE > UNI_DTL_MAXNUM)
6652 if(*msg->b_rptr++ != UNI_DTL_LOGNP)
6656 ie->dtl[ie->num].node_level = *msg->b_rptr++;
6659 (void)memcpy(ie->dtl[ie->num].node_id, msg->b_rptr, 21);
6663 ie->dtl[ie->num].port_id = *msg->b_rptr++ << 24;
6664 ie->dtl[ie->num].port_id |= *msg->b_rptr++ << 16;
6665 ie->dtl[ie->num].port_id |= *msg->b_rptr++ << 8;
6666 ie->dtl[ie->num].port_id |= *msg->b_rptr++ << 0;
6675 /*********************************************************************
6677 * Leaf initiated join call identifier.
6678 * Leaf initiated join parameters.
6679 * Leaf initiated join sequence number.
6681 * References for this IE are:
6683 * UNI4.0 pp. 46...48
6685 * Only NET coding allowed.
6688 /**********************************************************************/
6690 DEF_IE_PRINT(net, lij_callid)
6692 static const struct uni_print_tbl type_tbl[] = {
6693 MKT(UNI_LIJ_IDTYPE_ROOT, root),
6697 if(uni_print_iehdr("lij_callid", &ie->h, cx))
6700 uni_print_tbl("type", ie->type, type_tbl, cx);
6701 uni_print_entry(cx, "id", "0x%x", ie->callid);
6703 uni_print_ieend(cx);
6706 DEF_IE_CHECK(net, lij_callid)
6712 case UNI_LIJ_IDTYPE_ROOT:
6722 DEF_IE_ENCODE(net, lij_callid)
6724 START_IE(lij_callid, UNI_IE_LIJ_CALLID, 5);
6726 APP_BYTE(msg, 0x80 | ie->type);
6727 APP_32BIT(msg, ie->callid);
6733 DEF_IE_DECODE(net, lij_callid)
6740 ie->type = *msg->b_rptr++ & 0xf;
6741 ie->callid = *msg->b_rptr++ << 24;
6742 ie->callid |= *msg->b_rptr++ << 16;
6743 ie->callid |= *msg->b_rptr++ << 8;
6744 ie->callid |= *msg->b_rptr++ << 0;
6749 /**********************************************************************/
6751 DEF_IE_PRINT(net, lij_param)
6753 static const struct uni_print_tbl lscreen_tbl[] = {
6754 MKT(UNI_LIJ_SCREEN_NETJOIN, netjoin),
6758 if(uni_print_iehdr("lij_param", &ie->h, cx))
6760 uni_print_tbl("screen", ie->screen, lscreen_tbl, cx);
6761 uni_print_ieend(cx);
6764 DEF_IE_CHECK(net, lij_param)
6768 switch(ie->screen) {
6770 case UNI_LIJ_SCREEN_NETJOIN:
6780 DEF_IE_ENCODE(net, lij_param)
6782 START_IE(lij_param, UNI_IE_LIJ_PARAM, 1);
6784 APP_BYTE(msg, 0x80 | ie->screen);
6790 DEF_IE_DECODE(net, lij_param)
6797 ie->screen = *msg->b_rptr++ & 0xf;
6802 /**********************************************************************/
6804 DEF_IE_PRINT(net, lij_seqno)
6806 if(uni_print_iehdr("lij_seqno", &ie->h, cx))
6808 uni_print_entry(cx, "seqno", "0x%x", ie->seqno);
6809 uni_print_ieend(cx);
6812 DEF_IE_CHECK(net, lij_seqno)
6814 UNUSED(cx); UNUSED(ie);
6819 DEF_IE_ENCODE(net, lij_seqno)
6821 START_IE(lij_seqno, UNI_IE_LIJ_SEQNO, 4);
6823 APP_32BIT(msg, ie->seqno);
6829 DEF_IE_DECODE(net, lij_seqno)
6836 ie->seqno = *msg->b_rptr++ << 24;
6837 ie->seqno |= *msg->b_rptr++ << 16;
6838 ie->seqno |= *msg->b_rptr++ << 8;
6839 ie->seqno |= *msg->b_rptr++ << 0;
6844 /*********************************************************************
6848 * References for this IE are:
6850 * UNI4.0 pp. 57...58
6852 * Only NET coding allowed.
6854 DEF_IE_PRINT(net, cscope)
6856 static const struct uni_print_tbl type_tbl[] = {
6857 MKT(UNI_CSCOPE_ORG, org),
6860 static const struct uni_print_tbl scope_tbl[] = {
6861 MKT(UNI_CSCOPE_ORG_LOC, local_network),
6862 MKT(UNI_CSCOPE_ORG_LOC_P1, local_network_plus_one),
6863 MKT(UNI_CSCOPE_ORG_LOC_P2, local_network_plus_two),
6864 MKT(UNI_CSCOPE_ORG_SITE_M1, site_minus_one),
6865 MKT(UNI_CSCOPE_ORG_SITE, intra_site),
6866 MKT(UNI_CSCOPE_ORG_SITE_P1, site_plus_one),
6867 MKT(UNI_CSCOPE_ORG_ORG_M1, organisation_minus_one),
6868 MKT(UNI_CSCOPE_ORG_ORG, intra_organisation),
6869 MKT(UNI_CSCOPE_ORG_ORG_P1, organisation_plus_one),
6870 MKT(UNI_CSCOPE_ORG_COMM_M1, community_minus_one),
6871 MKT(UNI_CSCOPE_ORG_COMM, intra_community),
6872 MKT(UNI_CSCOPE_ORG_COMM_P1, community_plus_one),
6873 MKT(UNI_CSCOPE_ORG_REG, regional),
6874 MKT(UNI_CSCOPE_ORG_INTER, inter_regional),
6875 MKT(UNI_CSCOPE_ORG_GLOBAL, global),
6879 if(uni_print_iehdr("cscope", &ie->h, cx))
6882 uni_print_tbl("type", ie->type, type_tbl, cx);
6883 if(ie->type == UNI_CSCOPE_ORG)
6884 uni_print_tbl("scope", (u_int)ie->scope, scope_tbl, cx);
6886 uni_print_entry(cx, "scope", "0x%02x", ie->scope);
6888 uni_print_ieend(cx);
6891 DEF_IE_CHECK(net, cscope)
6900 case UNI_CSCOPE_ORG:
6906 case UNI_CSCOPE_ORG_LOC:
6907 case UNI_CSCOPE_ORG_LOC_P1:
6908 case UNI_CSCOPE_ORG_LOC_P2:
6909 case UNI_CSCOPE_ORG_SITE_M1:
6910 case UNI_CSCOPE_ORG_SITE:
6911 case UNI_CSCOPE_ORG_SITE_P1:
6912 case UNI_CSCOPE_ORG_ORG_M1:
6913 case UNI_CSCOPE_ORG_ORG:
6914 case UNI_CSCOPE_ORG_ORG_P1:
6915 case UNI_CSCOPE_ORG_COMM_M1:
6916 case UNI_CSCOPE_ORG_COMM:
6917 case UNI_CSCOPE_ORG_COMM_P1:
6918 case UNI_CSCOPE_ORG_REG:
6919 case UNI_CSCOPE_ORG_INTER:
6920 case UNI_CSCOPE_ORG_GLOBAL:
6928 DEF_IE_ENCODE(net, cscope)
6930 START_IE(cscope, UNI_IE_CSCOPE, 2);
6932 APP_BYTE(msg, ie->type | 0x80);
6933 APP_BYTE(msg, ie->scope);
6939 DEF_IE_DECODE(net, cscope)
6945 if((*msg->b_rptr & 0xf0) != 0x80)
6948 ie->type = *msg->b_rptr++ & 0xf;
6949 ie->scope = *msg->b_rptr++;
6954 /*********************************************************************
6956 * Extended Quality of Service
6958 * References for this IE are:
6960 * UNI4.0 pp. 70...72
6965 DEF_IE_PRINT(net, exqos)
6967 static const struct uni_print_tbl tab[] = {
6968 MKT(UNI_EXQOS_USER, user),
6969 MKT(UNI_EXQOS_NET, net),
6973 if(uni_print_iehdr("exqos", &ie->h, cx))
6976 uni_print_tbl("origin", ie->origin, tab, cx);
6978 uni_print_entry(cx, "acceptable", "(");
6979 if(ie->h.present & UNI_EXQOS_FACC_P) {
6980 if(ie->facc == UNI_EXQOS_ANY_CDV)
6981 uni_printf(cx, "ANY");
6983 uni_printf(cx, "%d", ie->facc);
6986 if(ie->h.present & UNI_EXQOS_BACC_P) {
6987 if(ie->bacc == UNI_EXQOS_ANY_CDV)
6988 uni_printf(cx, "ANY");
6990 uni_printf(cx, "%d", ie->bacc);
6994 uni_print_entry(cx, "cumulative", "(");
6995 if(ie->h.present & UNI_EXQOS_FCUM_P)
6996 uni_printf(cx, "%d", ie->fcum);
6998 if(ie->h.present & UNI_EXQOS_BCUM_P)
6999 uni_printf(cx, "%d", ie->bcum);
7002 uni_print_entry(cx, "clrid", "(");
7003 if(ie->h.present & UNI_EXQOS_FCLR_P) {
7004 if(ie->fclr == UNI_EXQOS_ANY_CLR)
7005 uni_printf(cx, "ANY");
7007 uni_printf(cx, "%d", ie->fclr);
7010 if(ie->h.present & UNI_EXQOS_BCLR_P) {
7011 if(ie->bclr == UNI_EXQOS_ANY_CLR)
7012 uni_printf(cx, "ANY");
7014 uni_printf(cx, "%d", ie->bclr);
7018 uni_print_ieend(cx);
7021 DEF_IE_CHECK(net, exqos)
7025 switch(ie->origin) {
7026 case UNI_EXQOS_USER:
7033 if(ie->h.present & UNI_EXQOS_FACC_P)
7034 if(!(ie->h.present & UNI_EXQOS_FCUM_P))
7036 if(ie->h.present & UNI_EXQOS_BACC_P)
7037 if(!(ie->h.present & UNI_EXQOS_BCUM_P))
7040 if(ie->h.present & UNI_EXQOS_FACC_P)
7041 if(ie->facc >= 1 << 24)
7043 if(ie->h.present & UNI_EXQOS_BACC_P)
7044 if(ie->bacc >= 1 << 24)
7046 if(ie->h.present & UNI_EXQOS_FCUM_P)
7047 if(ie->fcum >= 1 << 24)
7049 if(ie->h.present & UNI_EXQOS_BCUM_P)
7050 if(ie->bcum >= 1 << 24)
7053 if(ie->h.present & UNI_EXQOS_FCLR_P)
7054 if(ie->fclr==0 || (ie->fclr>15 && ie->fclr!=UNI_EXQOS_ANY_CLR))
7056 if(ie->h.present & UNI_EXQOS_BCLR_P)
7057 if(ie->bclr==0 || (ie->bclr>15 && ie->bclr!=UNI_EXQOS_ANY_CLR))
7062 DEF_IE_ENCODE(net, exqos)
7064 START_IE(exqos, UNI_IE_EXQOS, 21);
7066 APP_BYTE(msg, ie->origin);
7068 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_FACC_P,
7069 UNI_EXQOS_FACC_ID, ie->facc);
7070 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_BACC_P,
7071 UNI_EXQOS_BACC_ID, ie->bacc);
7072 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_FCUM_P,
7073 UNI_EXQOS_FCUM_ID, ie->fcum);
7074 APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_BCUM_P,
7075 UNI_EXQOS_BCUM_ID, ie->bcum);
7077 APP_OPT_BYTE(msg, ie->h.present, UNI_EXQOS_FCLR_P,
7078 UNI_EXQOS_FCLR_ID, ie->fclr);
7079 APP_OPT_BYTE(msg, ie->h.present, UNI_EXQOS_BCLR_P,
7080 UNI_EXQOS_BCLR_ID, ie->bclr);
7086 DEF_IE_DECODE(net, exqos)
7090 if(ielen < 1 || ielen > 21)
7093 ie->origin = *msg->b_rptr++;
7097 switch(*msg->b_rptr++) {
7102 DEC_GETF3(EXQOS_FACC, facc, ie->h.present);
7103 DEC_GETF3(EXQOS_BACC, bacc, ie->h.present);
7104 DEC_GETF3(EXQOS_FCUM, fcum, ie->h.present);
7105 DEC_GETF3(EXQOS_BCUM, bcum, ie->h.present);
7107 DEC_GETF1(EXQOS_FCLR, fclr, ie->h.present);
7108 DEC_GETF1(EXQOS_BCLR, bclr, ie->h.present);
7115 /**************************************************************
7117 * Free form IE (for testing mainly)
7119 DEF_IE_PRINT(itu, unrec)
7123 if (uni_print_iehdr("unrec", &ie->h, cx))
7125 uni_print_entry(cx, "len", "%u", ie->len);
7126 uni_print_entry(cx, "data", "(");
7127 for (i = 0; i < ie->len; i++)
7128 uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->data[i]);
7129 uni_printf(cx, ")");
7130 uni_print_ieend(cx);
7133 DEF_IE_CHECK(itu, unrec)
7137 if (ie->len > sizeof(ie->data))
7143 DEF_IE_ENCODE(itu, unrec)
7145 START_IE2(unrec, UNI_IE_UNREC, ie->len, ie->id);
7147 APP_BUF(msg, ie->data, ie->len);
7153 DEF_IE_DECODE(itu, unrec)
7157 if (ielen > sizeof(ie->data) / sizeof(ie->data[0]) || ielen < 1)
7162 (void)memcpy(ie->data, msg->b_rptr, ie->len);
7163 msg->b_rptr += ie->len;