1121934Sharti/*
2121934Sharti * Copyright (c) 2001-2003
3121934Sharti *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4121934Sharti * 	All rights reserved.
5121934Sharti *
6121934Sharti * Redistribution and use in source and binary forms, with or without
7121934Sharti * modification, are permitted provided that the following conditions
8121934Sharti * are met:
9121934Sharti * 1. Redistributions of source code must retain the above copyright
10121934Sharti *    notice, this list of conditions and the following disclaimer.
11121934Sharti * 2. Redistributions in binary form must reproduce the above copyright
12121934Sharti *    notice, this list of conditions and the following disclaimer in the
13121934Sharti *    documentation and/or other materials provided with the distribution.
14121934Sharti *
15121934Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16121934Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17121934Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18121934Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19121934Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20121934Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21121934Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22121934Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23121934Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24121934Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25121934Sharti * SUCH DAMAGE.
26121934Sharti *
27121934Sharti * Author: Hartmut Brandt <harti@freebsd.org>
28121934Sharti *
29146539Sharti * $Begemot: libunimsg/netnatm/msg/uni_ie.c,v 1.16 2005/05/23 12:06:30 brandt_h Exp $
30121934Sharti *
31121934Sharti * Private definitions for the IE code file.
32121934Sharti *
33121934Sharti * This file includes the table generated automatically.
34121934Sharti */
35121934Sharti
36121934Sharti#include <sys/types.h>
37121934Sharti#include <sys/param.h>
38121934Sharti
39121934Sharti#ifdef _KERNEL
40121934Sharti#include <sys/libkern.h>
41121934Sharti#else
42121934Sharti#include <string.h>
43121934Sharti#endif
44121934Sharti#include <netnatm/unimsg.h>
45121934Sharti#include <netnatm/msg/unistruct.h>
46121934Sharti#include <netnatm/msg/unimsglib.h>
47121934Sharti#include <netnatm/msg/uniprint.h>
48121934Sharti#include <netnatm/msg/priv.h>
49121934Sharti
50228554Sdim#define UNUSED(_p) do { (void)(_p); } while (0)
51228554Sdim
52121934Sharti/*
53121934Sharti * Define internal functions.
54121934Sharti */
55121934Sharti#define DEF_IE_PRINT(Coding, IE) \
56121934Sharti	void uni_ie_print_##Coding##_##IE(struct uni_ie_##IE *ie, struct unicx *cx)
57121934Sharti
58121934Sharti#define DEF_IE_CHECK(Coding, IE) \
59121934Sharti	int uni_ie_check_##Coding##_##IE(struct uni_ie_##IE *ie, struct unicx *cx)
60121934Sharti
61121934Sharti#define DEF_IE_ENCODE(Coding, IE) \
62121934Sharti	int uni_ie_encode_##Coding##_##IE(struct uni_msg *msg, struct uni_ie_##IE *ie, struct unicx *cx)
63121934Sharti
64121934Sharti#define DEF_IE_DECODE(Coding, IE) \
65121934Sharti	int uni_ie_decode_##Coding##_##IE(struct uni_ie_##IE *ie, struct uni_msg *msg, u_int ielen, struct unicx *cx)
66121934Sharti
67121934Sharti/*
68121934Sharti * This structure is used to define value->string mappings. MKT() is used
69121934Sharti * to generate a table entry. EOT() to end the table.
70121934Sharti */
71121934Sharti#define MKT(V,N)	{ #N, V }
72121934Sharti#define EOT()		{ NULL, 0 }
73121934Sharti
74121934Sharti/* library internal functions */
75121934Shartistatic void uni_entry(const char *, struct unicx *);
76121934Shartistatic int  uni_print_iehdr(const char *, struct uni_iehdr *h, struct unicx *);
77121934Shartistatic void uni_print_ieend(struct unicx *);
78121934Shartistatic void uni_putc(int, struct unicx *);
79121934Sharti
80121934Sharti
81121934Sharti/*
82121934Sharti * Encoding
83121934Sharti */
84121934Sharti#define APP_BYTE(M, B) do {					\
85121934Sharti	*(M)->b_wptr++ = (B);					\
86121934Sharti    } while (0)
87121934Sharti#define APP_16BIT(M, B) do {					\
88121934Sharti	u_int _v = (B);						\
89121934Sharti	*(M)->b_wptr++ = _v >> 8; 				\
90121934Sharti	*(M)->b_wptr++ = _v;					\
91121934Sharti    } while (0)
92121934Sharti#define APP_24BIT(M, B) do {					\
93121934Sharti	u_int _v = (B);						\
94121934Sharti	*(M)->b_wptr++ = _v >> 16;				\
95121934Sharti	*(M)->b_wptr++ = _v >> 8;				\
96121934Sharti	*(M)->b_wptr++ = _v;					\
97121934Sharti    } while (0)
98121934Sharti#define APP_32BIT(M, B) do {					\
99121934Sharti	u_int _v = (B);						\
100121934Sharti	*(M)->b_wptr++ = _v >> 24;				\
101121934Sharti	*(M)->b_wptr++ = _v >> 16;				\
102121934Sharti	*(M)->b_wptr++ = _v >> 8;				\
103121934Sharti	*(M)->b_wptr++ = _v;					\
104121934Sharti    } while (0)
105121934Sharti#define APP_BUF(M, B, L) do {					\
106121934Sharti	(void)memcpy((M)->b_wptr, (B), (L));			\
107121934Sharti	(M)->b_wptr += (L);					\
108121934Sharti    } while (0)
109121934Sharti
110121934Sharti#define APP_SUB_BYTE(M, T, B)  do { APP_BYTE(M, T); APP_BYTE(M, B); } while (0)
111121934Sharti#define APP_SUB_16BIT(M, T, B) do { APP_BYTE(M, T); APP_16BIT(M, B); } while (0)
112121934Sharti#define APP_SUB_24BIT(M, T, B) do { APP_BYTE(M, T); APP_24BIT(M, B); } while (0)
113121934Sharti#define APP_SUB_32BIT(M, T, B) do { APP_BYTE(M, T); APP_32BIT(M, B); } while (0)
114121934Sharti
115121934Sharti#define APP_OPT(M, F, P, T) do {				\
116121934Sharti	if ((F) & (P))						\
117121934Sharti		APP_BYTE((M), (T));				\
118121934Sharti    } while (0)
119121934Sharti#define APP_OPT_BYTE(M, F, P, T, B) do {			\
120121934Sharti	if ((F) & (P))						\
121121934Sharti		APP_SUB_BYTE((M), (T), (B));			\
122121934Sharti    } while (0)
123121934Sharti#define APP_OPT_16BIT(M, F, P, T, B) do {			\
124121934Sharti	if ((F) & (P))						\
125121934Sharti		APP_SUB_16BIT((M), (T), (B));			\
126121934Sharti    } while (0)
127121934Sharti#define APP_OPT_24BIT(M, F, P, T, B) do {			\
128121934Sharti	if ((F) & (P))						\
129121934Sharti		APP_SUB_24BIT((M), (T), (B));			\
130121934Sharti    } while (0)
131121934Sharti
132121934Sharti#define START_IE(TYPE,CODE,LEN) 				\
133121934Sharti	u_int ielen; 						\
134121934Sharti								\
135121934Sharti	if (uni_check_ie(CODE, (union uni_ieall *)ie, cx)) 	\
136121934Sharti		return (-1); 					\
137121934Sharti	if (uni_encode_ie_hdr(msg, CODE, &ie->h, (LEN), cx))	\
138121934Sharti		return (0);					\
139121934Sharti								\
140121934Sharti	ielen = msg->b_wptr - msg->b_rptr - 2;
141121934Sharti
142121934Sharti#define START_IE2(TYPE,CODE,LEN,REALCODE) 			\
143121934Sharti	u_int ielen; 						\
144121934Sharti								\
145121934Sharti	if (uni_check_ie(CODE, (union uni_ieall *)ie, cx)) 	\
146121934Sharti		return (-1); 					\
147121934Sharti	if (uni_encode_ie_hdr(msg, REALCODE, &ie->h, (LEN), cx)) \
148121934Sharti		return (0);					\
149121934Sharti								\
150121934Sharti	ielen = msg->b_wptr - msg->b_rptr - 2;
151121934Sharti
152121934Sharti#define SET_IE_LEN(M) do {					\
153121934Sharti	(M)->b_buf[ielen + 0] =					\
154121934Sharti	    (((M)->b_wptr - (M)->b_rptr) - ielen - 2) >> 8;	\
155121934Sharti	(M)->b_buf[ielen + 1] =					\
156121934Sharti	    (((M)->b_wptr - (M)->b_rptr) - ielen - 2) >> 0;	\
157121934Sharti    } while (0)
158121934Sharti
159121934Sharti
160121934Sharti/***********************************************************************/
161121934Sharti/*
162121934Sharti * Decoding
163121934Sharti */
164121934Sharti#define IE_START(ERR) 							\
165121934Sharti	if (IE_ISPRESENT(*ie))						\
166121934Sharti		return (0);						\
167121934Sharti	if (ielen == 0) {						\
168121934Sharti		IE_SETEMPTY(*ie);					\
169121934Sharti		return (0);						\
170121934Sharti	}
171121934Sharti
172121934Sharti#define IE_END(IE)							\
173121934Sharti	IE_SETPRESENT(*ie);						\
174121934Sharti	if (uni_check_ie(UNI_IE_##IE, (union uni_ieall *)ie, cx) == 0) 	\
175121934Sharti		return (0);						\
176121934Sharti  rej:									\
177121934Sharti	ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;			\
178121934Sharti	return (1);
179121934Sharti
180121934Sharti#define DEC_GETF3(ID, F, P) 						\
181121934Sharti		  case UNI_##ID##_ID:					\
182121934Sharti			if (ielen < 3)					\
183121934Sharti				goto rej;				\
184121934Sharti			ielen -= 3;					\
185121934Sharti		  	if (!(P & UNI_##ID##_P)) {			\
186121934Sharti		  		P |= UNI_##ID##_P;			\
187121934Sharti				ie->F  = *msg->b_rptr++ << 16;		\
188121934Sharti				ie->F |= *msg->b_rptr++ << 8;		\
189121934Sharti				ie->F |= *msg->b_rptr++;		\
190121934Sharti			} else						\
191121934Sharti				msg->b_rptr += 3;			\
192121934Sharti			break;
193121934Sharti
194121934Sharti#define DEC_GETF1(ID, F, P) 						\
195121934Sharti		  case UNI_##ID##_ID:					\
196121934Sharti			if (ielen < 1)					\
197121934Sharti				goto rej;				\
198121934Sharti			ielen--;					\
199121934Sharti		  	if (!(P & UNI_##ID##_P)) {			\
200121934Sharti		  		P |= UNI_##ID##_P;			\
201121934Sharti				ie->F = *msg->b_rptr++;			\
202121934Sharti			} else						\
203121934Sharti				msg->b_rptr++;				\
204121934Sharti			break;
205121934Sharti
206121934Sharti
207121934Sharti#define PRINT_NPREFIX (sizeof(((struct unicx *)0)->prefix) /		\
208121934Sharti	    sizeof(((struct unicx *)0)->prefix[0]))
209121934Sharti
210121934Sharti/*
211121934Sharti * This is rather here than in privmsg.c because we need the APP macros.
212121934Sharti */
213121934Shartiint
214121934Shartiuni_encode_msg_hdr(struct uni_msg *msg, struct uni_msghdr *h,
215121934Sharti    enum uni_msgtype type, struct unicx *cx, int *mlen)
216121934Sharti{
217121934Sharti	u_char byte;
218121934Sharti
219213789Srpaulo	(void)uni_msg_ensure(msg, 9);
220121934Sharti
221121934Sharti	APP_BYTE(msg, cx->pnni ? PNNI_PROTO : UNI_PROTO);
222121934Sharti	APP_BYTE(msg, 3);
223121934Sharti	if(h->cref.cref >= 1<<23)
224121934Sharti		return -1;
225121934Sharti	APP_24BIT(msg, h->cref.cref | (h->cref.flag ? 0x800000 : 0));
226121934Sharti	APP_BYTE(msg, type);
227121934Sharti
228121934Sharti	byte = 0x80;
229121934Sharti	if(h->act != UNI_MSGACT_DEFAULT)
230121934Sharti		byte |= 0x10 | (h->act & 3);
231121934Sharti	if(cx->pnni && h->pass)
232121934Sharti		byte |= 0x08;
233121934Sharti	APP_BYTE(msg, byte);
234121934Sharti
235121934Sharti	*mlen = msg->b_wptr - msg->b_rptr;
236121934Sharti	APP_16BIT(msg, 0);
237121934Sharti
238121934Sharti	return 0;
239121934Sharti}
240121934Sharti
241121934Sharti/*
242121934Sharti * Initialize printing. This must be called by all printing routines
243121934Sharti * that are exported to the user.
244121934Sharti */
245121934Shartivoid
246121934Shartiuni_print_init(char *buf, size_t bufsiz, struct unicx *cx)
247121934Sharti{
248121934Sharti	if (cx->dont_init)
249121934Sharti		return;
250121934Sharti
251121934Sharti	cx->indent = 0;
252121934Sharti	cx->nprefix = 0;
253121934Sharti	cx->doindent = 0;
254121934Sharti	if (cx->tabsiz == 0)
255121934Sharti		cx->tabsiz = 4;
256121934Sharti	cx->buf = buf;
257121934Sharti	cx->bufsiz = bufsiz;
258121934Sharti}
259121934Sharti
260121934Sharti/*
261121934Sharti * Append a character to the buffer if there is still space
262121934Sharti */
263121934Shartistatic void
264121934Shartiuni_putc(int c, struct unicx *cx)
265121934Sharti{
266121934Sharti	if(cx->bufsiz > 1) {
267121934Sharti		*cx->buf++ = c;
268121934Sharti		cx->bufsiz--;
269121934Sharti		*cx->buf = '\0';
270121934Sharti	}
271121934Sharti}
272121934Sharti
273121934Shartivoid
274121934Shartiuni_printf(struct unicx *cx, const char *fmt, ...)
275121934Sharti{
276121934Sharti	u_int n;
277121934Sharti	va_list ap;
278121934Sharti
279121934Sharti	if(cx->bufsiz > 1) {
280121934Sharti		va_start(ap, fmt);
281121934Sharti		n = vsnprintf(cx->buf, cx->bufsiz, fmt, ap);
282121934Sharti		va_end(ap);
283121934Sharti		if(n > 0) {
284121934Sharti			if(n < cx->bufsiz) {
285121934Sharti				cx->bufsiz -= n;
286121934Sharti				cx->buf += n;
287121934Sharti			} else {
288121934Sharti				cx->buf += cx->bufsiz - 1;
289121934Sharti				cx->bufsiz = 1;
290121934Sharti			}
291121934Sharti		}
292121934Sharti		*cx->buf = '\0';
293121934Sharti	}
294121934Sharti}
295121934Sharti
296121934Sharti/*
297121934Sharti * Print mode:
298121934Sharti *	0 - print all into one line, fully prefixed
299121934Sharti *	1 - print on multiple lines, full prefixed, but equal level
300121934Sharti *	    entries on one line
301121934Sharti *	2 - like 2, but only partial prefixed
302121934Sharti *	3 - like 1, but each entry onto a new line
303121934Sharti *	4 - like 2 + 3
304121934Sharti */
305121934Sharti
306121934Sharti/*
307121934Sharti * If we are in multiline mode, end the current line and set the
308121934Sharti * flag, that we need indentation. But prevent double new lines.
309121934Sharti */
310121934Shartivoid
311121934Shartiuni_print_eol(struct unicx *cx)
312121934Sharti{
313121934Sharti	if (cx->multiline) {
314121934Sharti		if (!cx->doindent) {
315121934Sharti			uni_putc('\n', cx);
316121934Sharti			cx->doindent = 1;
317121934Sharti		}
318121934Sharti	}
319121934Sharti}
320121934Sharti
321121934Sharti/*
322121934Sharti * New entry. Do the prefixing, indentation and spacing.
323121934Sharti */
324121934Shartistatic void
325121934Shartidoprefix(struct unicx *cx, const char *s)
326121934Sharti{
327121934Sharti	u_int i;
328121934Sharti
329121934Sharti	if(cx->multiline == 0) {
330121934Sharti		uni_putc(' ', cx);
331121934Sharti		for(i = 0; i < cx->nprefix; i++)
332121934Sharti			if(cx->prefix[i])
333121934Sharti				uni_printf(cx, "%s.", cx->prefix[i]);
334121934Sharti	} else if(cx->multiline == 1) {
335121934Sharti		if(cx->doindent) {
336121934Sharti			uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
337121934Sharti			cx->doindent = 0;
338121934Sharti		} else
339121934Sharti			uni_putc(' ', cx);
340121934Sharti		for(i = 0; i < cx->nprefix; i++)
341121934Sharti			if(cx->prefix[i])
342121934Sharti				uni_printf(cx, "%s.", cx->prefix[i]);
343121934Sharti	} else if(cx->multiline == 2) {
344121934Sharti		if(cx->doindent) {
345121934Sharti			uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
346121934Sharti			cx->doindent = 0;
347121934Sharti		} else
348121934Sharti			uni_putc(' ', cx);
349121934Sharti	} else if(cx->multiline == 3) {
350121934Sharti		if(cx->doindent)
351121934Sharti			cx->doindent = 0;
352121934Sharti		else
353121934Sharti			uni_putc('\n', cx);
354121934Sharti		uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
355121934Sharti		for(i = 0; i < cx->nprefix; i++)
356121934Sharti			if(cx->prefix[i])
357121934Sharti				uni_printf(cx, "%s.", cx->prefix[i]);
358121934Sharti	} else if(cx->multiline == 4) {
359121934Sharti		if(cx->doindent)
360121934Sharti			cx->doindent = 0;
361121934Sharti		else
362121934Sharti			uni_putc('\n', cx);
363121934Sharti		uni_printf(cx, "%*s", cx->indent * cx->tabsiz, "");
364121934Sharti	}
365121934Sharti	uni_printf(cx, "%s", s);
366121934Sharti}
367121934Shartistatic void
368121934Shartiuni_entry(const char *s, struct unicx *cx)
369121934Sharti{
370121934Sharti	doprefix(cx, s);
371121934Sharti	uni_putc('=', cx);
372121934Sharti}
373121934Shartivoid
374121934Shartiuni_print_flag(const char *s, struct unicx *cx)
375121934Sharti{
376121934Sharti	doprefix(cx, s);
377121934Sharti}
378121934Sharti
379121934Sharti
380121934Sharti/*
381121934Sharti * Start a deeper level of indendation. If multiline is in effect,
382121934Sharti * we end the current line.
383121934Sharti */
384121934Shartivoid
385121934Shartiuni_print_push_prefix(const char *prefix, struct unicx *cx)
386121934Sharti{
387121934Sharti	if (cx->nprefix < PRINT_NPREFIX)
388121934Sharti		cx->prefix[cx->nprefix++] = prefix;
389121934Sharti}
390121934Shartivoid
391121934Shartiuni_print_pop_prefix(struct unicx *cx)
392121934Sharti{
393121934Sharti	if (cx->nprefix > 0)
394121934Sharti		cx->nprefix--;
395121934Sharti}
396121934Sharti
397121934Shartivoid
398121934Shartiuni_print_tbl(const char *entry, u_int val, const struct uni_print_tbl *tbl,
399121934Sharti    struct unicx *cx)
400121934Sharti{
401121934Sharti	if (entry)
402121934Sharti		uni_entry(entry, cx);
403121934Sharti	while (tbl->name) {
404121934Sharti		if (tbl->val == val) {
405121934Sharti			uni_printf(cx, "%s", tbl->name);
406121934Sharti			return;
407121934Sharti		}
408121934Sharti		tbl++;
409121934Sharti	}
410121934Sharti	uni_printf(cx, "ERROR(0x%x)", val);
411121934Sharti}
412121934Sharti
413121934Shartivoid
414121934Shartiuni_print_entry(struct unicx *cx, const char *e, const char *fmt, ...)
415121934Sharti{
416121934Sharti	u_int n;
417121934Sharti	va_list ap;
418121934Sharti
419121934Sharti	uni_entry(e, cx);
420121934Sharti
421121934Sharti	if (cx->bufsiz > 1) {
422121934Sharti		va_start(ap, fmt);
423121934Sharti		n = vsnprintf(cx->buf, cx->bufsiz, fmt, ap);
424121934Sharti		va_end(ap);
425121934Sharti		if (n > 0) {
426121934Sharti			if (n < cx->bufsiz) {
427121934Sharti				cx->bufsiz -= n;
428121934Sharti				cx->buf += n;
429121934Sharti			} else {
430121934Sharti				cx->buf += cx->bufsiz - 1;
431121934Sharti				cx->bufsiz = 1;
432121934Sharti			}
433121934Sharti		}
434121934Sharti		*cx->buf = '\0';
435121934Sharti	}
436121934Sharti}
437121934Sharti
438121934Sharti/**********************************************************************/
439121934Sharti/*
440121934Sharti * Printing information elements.
441121934Sharti */
442121934Shartistatic int
443121934Shartiuni_print_iehdr(const char *name, struct uni_iehdr *h, struct unicx *cx)
444121934Sharti{
445121934Sharti	static const struct uni_print_tbl act_tab[] = {
446121934Sharti		MKT(UNI_IEACT_CLEAR,	clear),
447121934Sharti		MKT(UNI_IEACT_IGNORE,	ignore),
448121934Sharti		MKT(UNI_IEACT_REPORT,	report),
449121934Sharti		MKT(UNI_IEACT_MSG_IGNORE, ignore-msg),
450121934Sharti		MKT(UNI_IEACT_MSG_REPORT, report-msg),
451121934Sharti		MKT(UNI_IEACT_DEFAULT,	default),
452121934Sharti		EOT()
453121934Sharti	};
454121934Sharti	static const struct uni_print_tbl cod_tab[] = {
455121934Sharti		MKT(UNI_CODING_ITU, itut),
456121934Sharti		MKT(UNI_CODING_NET, atmf),
457121934Sharti		EOT()
458121934Sharti	};
459121934Sharti
460121934Sharti	uni_print_entry(cx, name, "(");
461121934Sharti	uni_print_tbl(NULL, h->act, act_tab, cx);
462121934Sharti	uni_putc(',', cx);
463121934Sharti	uni_print_tbl(NULL, h->coding, cod_tab, cx);
464121934Sharti	if(cx->pnni && h->pass)
465121934Sharti		uni_printf(cx, ",pass");
466121934Sharti	if(IE_ISEMPTY(*(struct uni_ie_aal *)h)) {
467121934Sharti		uni_printf(cx, ",empty)");
468121934Sharti		uni_print_eol(cx);
469121934Sharti		return 1;
470121934Sharti	}
471121934Sharti	if(IE_ISERROR(*(struct uni_ie_aal *)h)) {
472121934Sharti		uni_printf(cx, ",error)");
473121934Sharti		uni_print_eol(cx);
474121934Sharti		return 1;
475121934Sharti	}
476121934Sharti
477121934Sharti	uni_putc(')', cx);
478121934Sharti
479121934Sharti	uni_print_push_prefix(name, cx);
480121934Sharti	uni_print_eol(cx);
481121934Sharti	cx->indent++;
482121934Sharti
483121934Sharti	return 0;
484121934Sharti}
485121934Sharti
486121934Shartistatic void
487121934Shartiuni_print_ieend(struct unicx *cx)
488121934Sharti{
489121934Sharti	uni_print_pop_prefix(cx);
490121934Sharti	uni_print_eol(cx);
491121934Sharti	cx->indent--;
492121934Sharti}
493121934Sharti
494121934Shartivoid
495121934Shartiuni_print_ie_internal(enum uni_ietype code, const union uni_ieall *ie,
496121934Sharti    struct unicx *cx)
497121934Sharti{
498121934Sharti	const struct iedecl *iedecl;
499121934Sharti
500121934Sharti	if((iedecl = GET_IEDECL(code, ie->h.coding)) != NULL)
501121934Sharti		(*iedecl->print)(ie, cx);
502121934Sharti}
503121934Sharti
504121934Shartivoid
505121934Shartiuni_print_ie(char *buf, size_t size, enum uni_ietype code,
506121934Sharti    const union uni_ieall *ie, struct unicx *cx)
507121934Sharti{
508121934Sharti	uni_print_init(buf, size, cx);
509121934Sharti	uni_print_ie_internal(code, ie, cx);
510121934Sharti}
511121934Sharti
512121934Shartiint
513121934Shartiuni_check_ie(enum uni_ietype code, union uni_ieall *ie, struct unicx *cx)
514121934Sharti{
515121934Sharti	const struct iedecl *iedecl = GET_IEDECL(code, ie->h.coding);
516121934Sharti
517121934Sharti	if (iedecl != NULL)
518121934Sharti		return (iedecl->check(ie, cx));
519121934Sharti	else
520121934Sharti		return (-1);
521121934Sharti}
522121934Sharti
523121934Sharti/*
524121934Sharti * Decode a information element header.
525121934Sharti * Returns -1 if the message is too short.
526121934Sharti * Strip the header from the message.
527121934Sharti * The header is stripped, even if it is too short.
528121934Sharti */
529121934Shartiint
530121934Shartiuni_decode_ie_hdr(enum uni_ietype *ietype, struct uni_iehdr *hdr,
531121934Sharti    struct uni_msg *msg, struct unicx *cx, u_int *ielen)
532121934Sharti{
533121934Sharti	u_int len;
534121934Sharti
535121934Sharti	*ietype = (enum uni_ietype)0;
536121934Sharti	*ielen = 0;
537121934Sharti	hdr->present = 0;
538121934Sharti	hdr->coding = UNI_CODING_ITU;
539121934Sharti	hdr->act = UNI_IEACT_DEFAULT;
540121934Sharti
541121934Sharti	if ((len = uni_msg_len(msg)) == 0)
542121934Sharti		return (-1);
543121934Sharti
544121934Sharti	*ietype = *msg->b_rptr++;
545121934Sharti
546121934Sharti	if (--len == 0)
547121934Sharti		return (-1);
548121934Sharti
549121934Sharti	hdr->coding = (*msg->b_rptr >> 5) & 3;
550121934Sharti	hdr->present = 0;
551121934Sharti
552121934Sharti	switch (*msg->b_rptr & 0x17) {
553121934Sharti
554121934Sharti	  case 0x10: case 0x11: case 0x12:
555121934Sharti	  case 0x15: case 0x16:
556121934Sharti		hdr->act = *msg->b_rptr & 0x7;
557121934Sharti		break;
558121934Sharti
559121934Sharti	  case 0x00: case 0x01: case 0x02: case 0x03:
560121934Sharti	  case 0x04: case 0x05: case 0x06: case 0x07:
561121934Sharti		hdr->act = UNI_IEACT_DEFAULT;
562121934Sharti		break;
563121934Sharti
564121934Sharti	  default:
565121934Sharti		/* Q.2931 5.7.2 last sentence */
566121934Sharti		hdr->act = UNI_IEACT_REPORT;
567121934Sharti		break;
568121934Sharti	}
569121934Sharti	if (cx->pnni && (*msg->b_rptr & 0x08))
570121934Sharti		hdr->pass = 1;
571121934Sharti	else
572121934Sharti		hdr->pass = 0;
573121934Sharti	msg->b_rptr++;
574121934Sharti
575121934Sharti	if (--len == 0) {
576121934Sharti		hdr->present = UNI_IE_ERROR | UNI_IE_PRESENT;
577121934Sharti		return (-1);
578121934Sharti	}
579121934Sharti
580121934Sharti	if (len < 2) {
581121934Sharti		msg->b_rptr += len;
582121934Sharti		hdr->present = UNI_IE_ERROR | UNI_IE_PRESENT;
583121934Sharti		return (-1);
584121934Sharti	}
585121934Sharti
586121934Sharti	*ielen = *msg->b_rptr++ << 8;
587121934Sharti	*ielen |= *msg->b_rptr++;
588121934Sharti
589121934Sharti	return (0);
590121934Sharti}
591121934Sharti
592121934Sharti/*
593121934Sharti * Decode the body of an information element.
594121934Sharti */
595121934Shartiint
596121934Shartiuni_decode_ie_body(enum uni_ietype ietype, union uni_ieall *ie,
597121934Sharti    struct uni_msg *msg, u_int ielen, struct unicx *cx)
598121934Sharti{
599121934Sharti	const struct iedecl *iedecl;
600121934Sharti	u_char *end;
601121934Sharti	int ret;
602121934Sharti
603121934Sharti	if (ielen > uni_msg_len(msg)) {
604121934Sharti		/*
605121934Sharti		 * Information element too long -> content error.
606121934Sharti		 * Q.2931 5.6.8.2
607121934Sharti		 */
608121934Sharti		msg->b_rptr = msg->b_wptr;
609121934Sharti		ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
610121934Sharti		return (-1);
611121934Sharti	}
612121934Sharti
613121934Sharti	if ((iedecl = GET_IEDECL(ietype, ie->h.coding)) == NULL) {
614121934Sharti		/*
615121934Sharti		 * entirly unknown IE.
616121934Sharti		 * Q.2931 5.6.8.1
617121934Sharti		 */
618121934Sharti		msg->b_rptr += ielen;
619121934Sharti		ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
620121934Sharti		return (-1);
621121934Sharti	}
622121934Sharti
623121934Sharti	if (ielen > iedecl->maxlen) {
624121934Sharti		/*
625121934Sharti		 * Information element too long -> content error.
626121934Sharti		 * Q.2931 5.6.8.2
627121934Sharti		 */
628121934Sharti		msg->b_rptr += iedecl->maxlen;
629121934Sharti		ie->h.present = UNI_IE_ERROR | UNI_IE_PRESENT;
630121934Sharti		return (-1);
631121934Sharti	}
632121934Sharti
633121934Sharti	end = msg->b_rptr + ielen;
634121934Sharti	ret = (*iedecl->decode)(ie, msg, ielen, cx);
635121934Sharti	msg->b_rptr = end;
636121934Sharti
637121934Sharti	return (ret);
638121934Sharti}
639121934Sharti
640121934Shartiint
641121934Shartiuni_encode_ie(enum uni_ietype code, struct uni_msg *msg, union uni_ieall *ie,
642121934Sharti    struct unicx *cx)
643121934Sharti{
644121934Sharti	const struct iedecl *iedecl = GET_IEDECL(code, ie->h.coding);
645121934Sharti
646121934Sharti	if (iedecl == NULL)
647121934Sharti		return (-1);
648121934Sharti	return (iedecl->encode(msg, ie, cx));
649121934Sharti}
650121934Sharti
651121934Shartiint
652121934Shartiuni_encode_ie_hdr(struct uni_msg *msg, enum uni_ietype type,
653121934Sharti    struct uni_iehdr *h, u_int len, struct unicx *cx)
654121934Sharti{
655121934Sharti	u_char byte;
656121934Sharti
657213789Srpaulo	(void)uni_msg_ensure(msg, 4 + len);
658121934Sharti	*msg->b_wptr++ = type;
659121934Sharti
660121934Sharti	byte = 0x80 | (h->coding << 5);
661121934Sharti	if(h->act != UNI_IEACT_DEFAULT)
662121934Sharti		byte |= 0x10 | (h->act & 7);
663121934Sharti	if(cx->pnni)
664121934Sharti		byte |= h->pass << 3;
665121934Sharti	*msg->b_wptr++ = byte;
666121934Sharti
667121934Sharti	if(h->present & UNI_IE_EMPTY) {
668121934Sharti		*msg->b_wptr++ = 0;
669121934Sharti		*msg->b_wptr++ = 4;
670121934Sharti		return -1;
671121934Sharti	}
672121934Sharti	*msg->b_wptr++ = 0;
673121934Sharti	*msg->b_wptr++ = 0;
674121934Sharti
675121934Sharti	return 0;
676121934Sharti}
677121934Sharti
678121934Sharti/*
679121934Sharti * Printing messages.
680121934Sharti */
681121934Shartistatic void
682121934Shartiuni_print_cref_internal(const struct uni_cref *cref, struct unicx *cx)
683121934Sharti{
684121934Sharti	uni_print_entry(cx, "cref", "%d.", cref->flag);
685121934Sharti	if (cref->cref == CREF_GLOBAL)
686121934Sharti		uni_printf(cx, "GLOBAL");
687121934Sharti	else if (cref->cref == CREF_DUMMY)
688121934Sharti		uni_printf(cx, "DUMMY");
689121934Sharti	else
690121934Sharti		uni_printf(cx, "%d", cref->cref);
691121934Sharti}
692121934Shartivoid
693121934Shartiuni_print_cref(char *str, size_t len, const struct uni_cref *cref,
694121934Sharti    struct unicx *cx)
695121934Sharti{
696121934Sharti	uni_print_init(str, len, cx);
697121934Sharti	uni_print_cref_internal(cref, cx);
698121934Sharti}
699121934Sharti
700121934Shartistatic void
701121934Shartiuni_print_msghdr_internal(const struct uni_msghdr *hdr, struct unicx *cx)
702121934Sharti{
703121934Sharti	static const struct uni_print_tbl tab[] = {
704121934Sharti		MKT(UNI_MSGACT_CLEAR,	clear),
705121934Sharti		MKT(UNI_MSGACT_IGNORE,	ignore),
706121934Sharti		MKT(UNI_MSGACT_REPORT,	report),
707121934Sharti		MKT(UNI_MSGACT_DEFAULT,	default),
708121934Sharti		EOT()
709121934Sharti	};
710121934Sharti
711121934Sharti	uni_print_cref_internal(&hdr->cref, cx);
712121934Sharti	uni_print_tbl("act", hdr->act, tab, cx);
713121934Sharti	if (cx->pnni)
714121934Sharti		uni_print_entry(cx, "pass", "%s", hdr->pass ? "yes" : "no");
715121934Sharti}
716121934Sharti
717121934Shartivoid
718121934Shartiuni_print_msghdr(char *str, size_t len, const struct uni_msghdr *hdr,
719121934Sharti    struct unicx *cx)
720121934Sharti{
721121934Sharti	uni_print_init(str, len, cx);
722121934Sharti	uni_print_msghdr_internal(hdr, cx);
723121934Sharti}
724121934Sharti
725121934Sharti
726121934Shartistatic void
727121934Shartiuni_print_internal(const struct uni_all *msg, struct unicx *cx)
728121934Sharti{
729121934Sharti	uni_entry("mtype", cx);
730121934Sharti	if(msg->mtype >= 256 || uni_msgtable[msg->mtype] == NULL) {
731121934Sharti		uni_printf(cx, "0x%02x(ERROR)", msg->mtype);
732121934Sharti	} else {
733121934Sharti		uni_printf(cx, "%s", uni_msgtable[msg->mtype]->name);
734121934Sharti		uni_print_msghdr_internal(&msg->u.hdr, cx);
735121934Sharti		cx->indent++;
736121934Sharti		uni_print_eol(cx);
737121934Sharti		(*uni_msgtable[msg->mtype]->print)(&msg->u, cx);
738121934Sharti		cx->indent--;
739121934Sharti	}
740121934Sharti
741121934Sharti	if(cx->multiline == 0)
742121934Sharti		uni_printf(cx, "\n");
743121934Sharti}
744121934Sharti
745121934Shartivoid
746121934Shartiuni_print(char *buf, size_t size, const struct uni_all *all, struct unicx *cx)
747121934Sharti{
748121934Sharti	uni_print_init(buf, size, cx);
749121934Sharti	uni_print_internal(all, cx);
750121934Sharti}
751121934Sharti
752121934Shartistatic void
753121934Shartiuni_print_msg_internal(u_int mtype, const union uni_msgall *msg,
754121934Sharti    struct unicx *cx)
755121934Sharti{
756121934Sharti
757121934Sharti	uni_entry("mtype", cx);
758121934Sharti	if (mtype >= 256 || uni_msgtable[mtype] == NULL) {
759121934Sharti		uni_printf(cx, "0x%02x(ERROR)", mtype);
760121934Sharti	} else {
761121934Sharti		uni_printf(cx, "%s", uni_msgtable[mtype]->name);
762121934Sharti		uni_print_msghdr_internal(&msg->hdr, cx);
763121934Sharti		cx->indent++;
764121934Sharti		uni_print_eol(cx);
765121934Sharti		(*uni_msgtable[mtype]->print)(msg, cx);
766121934Sharti		cx->indent--;
767121934Sharti	}
768121934Sharti
769121934Sharti	if(cx->multiline == 0)
770121934Sharti		uni_printf(cx, "\n");
771121934Sharti}
772121934Sharti
773121934Shartivoid
774121934Shartiuni_print_msg(char *buf, size_t size, u_int mtype, const union uni_msgall *all,
775121934Sharti    struct unicx *cx)
776121934Sharti{
777121934Sharti	uni_print_init(buf, size, cx);
778121934Sharti	uni_print_msg_internal(mtype, all, cx);
779121934Sharti}
780121934Sharti
781121934Shartivoid
782121934Shartiuni_print_cx(char *buf, size_t size, struct unicx *cx)
783121934Sharti{
784121934Sharti	static const char *acttab[] = {
785121934Sharti		"clr",	/* 0x00 */
786121934Sharti		"ign",	/* 0x01 */
787121934Sharti		"rep",	/* 0x02 */
788121934Sharti		"x03",	/* 0x03 */
789121934Sharti		"x04",	/* 0x04 */
790121934Sharti		"mig",	/* 0x05 */
791121934Sharti		"mrp",	/* 0x06 */
792121934Sharti		"x07",	/* 0x07 */
793121934Sharti		"def",	/* 0x08 */
794121934Sharti	};
795121934Sharti
796121934Sharti	static const char *errtab[] = {
797133492Sharti		[UNI_IERR_UNK] = "unk",	/* unknown IE */
798133492Sharti		[UNI_IERR_LEN] = "len",	/* length error */
799133492Sharti		[UNI_IERR_BAD] = "bad",	/* content error */
800133492Sharti		[UNI_IERR_ACC] = "acc",	/* access element discarded */
801133492Sharti		[UNI_IERR_MIS] = "mis",	/* missing IE */
802121934Sharti	};
803121934Sharti
804121934Sharti	u_int i;
805121934Sharti
806121934Sharti	uni_print_init(buf, size, cx);
807121934Sharti
808121934Sharti	uni_printf(cx, "q2932		%d\n", cx->q2932);
809121934Sharti	uni_printf(cx, "pnni		%d\n", cx->pnni);
810121934Sharti	uni_printf(cx, "git_hard	%d\n", cx->git_hard);
811121934Sharti	uni_printf(cx, "bearer_hard	%d\n", cx->bearer_hard);
812121934Sharti	uni_printf(cx, "cause_hard	%d\n", cx->cause_hard);
813121934Sharti
814121934Sharti	uni_printf(cx, "multiline	%d\n", cx->multiline);
815121934Sharti	uni_printf(cx, "tabsiz		%d\n", cx->tabsiz);
816121934Sharti
817121934Sharti	uni_printf(cx, "errcnt		%d (", cx->errcnt);
818121934Sharti	for(i = 0; i < cx->errcnt; i++) {
819121934Sharti		uni_printf(cx, "%02x[%s,%s%s]", cx->err[i].ie,
820121934Sharti		    errtab[cx->err[i].err], acttab[cx->err[i].act],
821121934Sharti		    cx->err[i].man ? ",M" : "");
822121934Sharti		if(i != cx->errcnt - 1)
823121934Sharti			uni_putc(' ', cx);
824121934Sharti	}
825121934Sharti	uni_printf(cx, ")\n");
826121934Sharti}
827121934Sharti
828121934Sharti#include <netnatm/msg/uni_ietab.h>
829121934Sharti
830121934Sharti/*********************************************************************
831121934Sharti *
832121934Sharti * Cause
833121934Sharti *
834121934Sharti * References for this IE are:
835121934Sharti *
836121934Sharti *  Q.2931 pp. 69 (just a pointer to Q.2610)
837121934Sharti *  Q.2610        (this is a small diff to Q.850)
838121934Sharti *  Q.850         !!
839121934Sharti *  UNI4.0 pp. 15
840121934Sharti *  PNNI1.0 p. 198
841121934Sharti *
842121934Sharti * ITU-T and NET coding for different values.
843121934Sharti */
844121934Shartistatic const struct causetab {
845121934Sharti	const char	*str;
846121934Sharti	enum uni_diag	diag;
847121934Sharti} itu_causes[128] = {
848121934Sharti
849133492Sharti#define D(NAME,VAL,DIAG,STD,STR) [UNI_CAUSE_##NAME] = { STR, UNI_DIAG_##DIAG },
850121934Sharti#define N(NAME,VAL,DIAG,STD,STR)
851121934Sharti
852121934ShartiUNI_DECLARE_CAUSE_VALUES
853121934Sharti
854121934Sharti#undef D
855121934Sharti#undef N
856121934Sharti
857121934Sharti}, net_causes[128] = {
858121934Sharti
859121934Sharti#define D(NAME,VAL,DIAG,STD,STR)
860133492Sharti#define N(NAME,VAL,DIAG,STD,STR) [UNI_CAUSE_##NAME] = { STR, UNI_DIAG_##DIAG },
861121934Sharti
862121934ShartiUNI_DECLARE_CAUSE_VALUES
863121934Sharti
864121934Sharti#undef D
865121934Sharti#undef N
866121934Sharti
867121934Sharti};
868121934Sharti
869121934Shartienum uni_diag
870121934Shartiuni_diag(enum uni_cause cause, enum uni_coding code)
871121934Sharti{
872242623Sdim	if ((int)cause >= 128)
873121934Sharti		return (UNI_DIAG_NONE);
874121934Sharti
875121934Sharti	if (code == UNI_CODING_NET)
876121934Sharti		if (net_causes[cause].str != NULL)
877121934Sharti			return (net_causes[cause].diag);
878121934Sharti	if (itu_causes[cause].str != NULL)
879121934Sharti		return (itu_causes[cause].diag);
880121934Sharti	return (UNI_DIAG_NONE);
881121934Sharti}
882121934Sharti
883121934Sharti/**********************************************************************/
884121934Sharti
885121934Shartistatic void
886121934Shartiprint_cause(struct unicx *cx, struct uni_ie_cause *ie,
887121934Sharti    const struct causetab *tab1, const struct causetab *tab2)
888121934Sharti{
889121934Sharti	static const struct uni_print_tbl loc_tbl[] = {
890121934Sharti		MKT(UNI_CAUSE_LOC_USER,		user),
891121934Sharti		MKT(UNI_CAUSE_LOC_PRIVLOC,	priv-net:loc-user),
892121934Sharti		MKT(UNI_CAUSE_LOC_PUBLOC,	pub-net:loc-user),
893121934Sharti		MKT(UNI_CAUSE_LOC_TRANSIT,	transit-net),
894121934Sharti		MKT(UNI_CAUSE_LOC_PUBREM,	pub-net:rem-user),
895121934Sharti		MKT(UNI_CAUSE_LOC_PRIVREM,	priv-net:rem-user),
896121934Sharti		MKT(UNI_CAUSE_LOC_INTERNAT,	int-net),
897121934Sharti		MKT(UNI_CAUSE_LOC_BEYOND,	beyond),
898121934Sharti		EOT()
899121934Sharti	};
900121934Sharti	static const struct uni_print_tbl pu_tbl[] = {
901121934Sharti		MKT(UNI_CAUSE_PU_PROVIDER,	provider),
902121934Sharti		MKT(UNI_CAUSE_PU_USER,		user),
903121934Sharti		EOT()
904121934Sharti	};
905121934Sharti	static const struct uni_print_tbl na_tbl[] = {
906121934Sharti		MKT(UNI_CAUSE_NA_NORMAL,	normal),
907121934Sharti		MKT(UNI_CAUSE_NA_ABNORMAL,	abnormal),
908121934Sharti		EOT()
909121934Sharti	};
910121934Sharti	static const struct uni_print_tbl cond_tbl[] = {
911121934Sharti		MKT(UNI_CAUSE_COND_UNKNOWN,	unknown),
912121934Sharti		MKT(UNI_CAUSE_COND_PERM,	permanent),
913121934Sharti		MKT(UNI_CAUSE_COND_TRANS,	transient),
914121934Sharti		EOT()
915121934Sharti	};
916121934Sharti	static const struct uni_print_tbl rej_tbl[] = {
917121934Sharti		MKT(UNI_CAUSE_REASON_USER,	user),
918121934Sharti		MKT(UNI_CAUSE_REASON_IEMISS,	ie-missing),
919121934Sharti		MKT(UNI_CAUSE_REASON_IESUFF,	ie-not-suff),
920121934Sharti		EOT()
921121934Sharti	};
922121934Sharti	char buf[100], *s;
923121934Sharti	u_int i;
924121934Sharti
925121934Sharti	if (uni_print_iehdr("cause", &ie->h, cx))
926121934Sharti		return;
927121934Sharti
928242623Sdim	if ((int)ie->cause < 128 && tab1[ie->cause].str)
929121934Sharti		strcpy(buf, tab1[ie->cause].str);
930242623Sdim	else if ((int)ie->cause < 128 && tab2 != NULL && tab2[ie->cause].str != NULL)
931121934Sharti		strcpy(buf, tab2[ie->cause].str);
932121934Sharti	else {
933121934Sharti		sprintf(buf, "UNKNOWN-%u", ie->cause);
934121934Sharti	}
935121934Sharti
936121934Sharti	for (s = buf; *s != '\0'; s++)
937121934Sharti		if (*s == ' ')
938121934Sharti			*s = '_';
939121934Sharti	uni_print_entry(cx, "cause", "%s", buf);
940121934Sharti
941121934Sharti	uni_print_tbl("loc", ie->loc, loc_tbl, cx);
942121934Sharti
943121934Sharti	if (ie->h.present & UNI_CAUSE_COND_P) {
944121934Sharti		uni_print_tbl("pu", ie->u.cond.pu, pu_tbl, cx);
945121934Sharti		uni_print_tbl("na", ie->u.cond.na, na_tbl, cx);
946121934Sharti		uni_print_tbl("condition", ie->u.cond.cond, cond_tbl, cx);
947121934Sharti	}
948121934Sharti	if (ie->h.present & UNI_CAUSE_REJ_P) {
949121934Sharti		uni_print_tbl("reject", ie->u.rej.reason, rej_tbl, cx);
950121934Sharti	}
951121934Sharti	if (ie->h.present & UNI_CAUSE_REJ_USER_P) {
952121934Sharti		uni_print_entry(cx, "user", "%u", ie->u.rej.user);
953121934Sharti	}
954121934Sharti	if (ie->h.present & UNI_CAUSE_REJ_IE_P) {
955121934Sharti		uni_print_entry(cx, "ie", "%u", ie->u.rej.ie);
956121934Sharti	}
957121934Sharti	if (ie->h.present & UNI_CAUSE_IE_P) {
958121934Sharti		uni_print_entry(cx, "ie", "(");
959121934Sharti		for (i = 0; i < ie->u.ie.len; i++) {
960121934Sharti			if (i)
961121934Sharti				uni_putc(',', cx);
962121934Sharti			uni_printf(cx, "0x%02x", ie->u.ie.ie[i]);
963121934Sharti		}
964121934Sharti		uni_putc(')', cx);
965121934Sharti	}
966121934Sharti	if (ie->h.present & UNI_CAUSE_TRAFFIC_P) {
967121934Sharti		uni_print_entry(cx, "traffic", "(");
968121934Sharti		for (i = 0; i < ie->u.traffic.len; i++) {
969121934Sharti			if (i)
970121934Sharti				uni_putc(',', cx);
971121934Sharti			uni_printf(cx, "0x%02x", ie->u.traffic.traffic[i]);
972121934Sharti		}
973121934Sharti		uni_putc(')', cx);
974121934Sharti	}
975121934Sharti	if (ie->h.present & UNI_CAUSE_VPCI_P) {
976121934Sharti		uni_print_entry(cx, "vpci", "(%u,%u)", ie->u.vpci.vpci, ie->u.vpci.vci);
977121934Sharti	}
978121934Sharti	if (ie->h.present & UNI_CAUSE_MTYPE_P) {
979121934Sharti		uni_print_entry(cx, "mtype", "%u", ie->u.mtype);
980121934Sharti	}
981121934Sharti	if (ie->h.present & UNI_CAUSE_TIMER_P) {
982121934Sharti		for (i = 0, s = buf; i < 3; i++) {
983121934Sharti			if (ie->u.timer[i] < ' ') {
984121934Sharti				*s++ = '^';
985121934Sharti				*s++ = ie->u.timer[i] + '@';
986121934Sharti			} else if (ie->u.timer[i] <= '~')
987121934Sharti				*s++ = ie->u.timer[i];
988121934Sharti			else {
989121934Sharti				*s++ = '\\';
990121934Sharti				*s++ = ie->u.timer[i] / 0100 + '0';
991121934Sharti				*s++ = (ie->u.timer[i] % 0100) / 010 + '0';
992121934Sharti				*s++ = ie->u.timer[i] % 010 + '0';
993121934Sharti			}
994121934Sharti		}
995121934Sharti		*s++ = '\0';
996121934Sharti		uni_print_entry(cx, "timer", "\"%s\"", buf);
997121934Sharti	}
998121934Sharti	if (ie->h.present & UNI_CAUSE_TNS_P) {
999121934Sharti		uni_print_eol(cx);
1000121934Sharti		uni_print_ie_internal(UNI_IE_TNS, (union uni_ieall *)&ie->u.tns, cx);
1001121934Sharti	}
1002121934Sharti	if (ie->h.present & UNI_CAUSE_NUMBER_P) {
1003121934Sharti		uni_print_eol(cx);
1004121934Sharti		uni_print_ie_internal(UNI_IE_CALLED, (union uni_ieall *)&ie->u.number, cx);
1005121934Sharti	}
1006121934Sharti	if (ie->h.present & UNI_CAUSE_ATTR_P) {
1007121934Sharti		uni_print_entry(cx, "attr", "(");
1008121934Sharti		for (i = 0; i < ie->u.attr.nattr; i++) {
1009121934Sharti			uni_printf(cx, "(%u", ie->u.attr.attr[i][0]);
1010121934Sharti			if (!(ie->u.attr.attr[i][0] & 0x80)) {
1011121934Sharti				uni_printf(cx, ",%u", ie->u.attr.attr[i][1]);
1012121934Sharti				if (!(ie->u.attr.attr[i][1] & 0x80))
1013121934Sharti					uni_printf(cx, ",%u",
1014121934Sharti					    ie->u.attr.attr[i][2]);
1015121934Sharti			}
1016121934Sharti			uni_putc(')', cx);
1017121934Sharti		}
1018121934Sharti	}
1019121934Sharti
1020121934Sharti	uni_print_ieend(cx);
1021121934Sharti}
1022121934Sharti
1023121934ShartiDEF_IE_PRINT(itu, cause)
1024121934Sharti{
1025121934Sharti	print_cause(cx, ie, itu_causes, NULL);
1026121934Sharti}
1027121934ShartiDEF_IE_PRINT(net, cause)
1028121934Sharti{
1029121934Sharti	print_cause(cx, ie, net_causes, itu_causes);
1030121934Sharti}
1031121934Sharti
1032121934Sharticonst char *
1033121934Shartiuni_ie_cause2str(enum uni_coding coding, u_int cause)
1034121934Sharti{
1035121934Sharti	if (cause < 128) {
1036121934Sharti		if (coding == UNI_CODING_ITU)
1037121934Sharti			return (itu_causes[cause].str);
1038121934Sharti		if (coding == UNI_CODING_NET) {
1039121934Sharti			if (net_causes[cause].str != NULL)
1040121934Sharti				return (net_causes[cause].str);
1041121934Sharti			return (itu_causes[cause].str);
1042121934Sharti		}
1043121934Sharti	}
1044121934Sharti	return (NULL);
1045121934Sharti}
1046121934Sharti
1047121934Sharti/**********************************************************************/
1048121934Sharti
1049121934Shartistatic int
1050121934Sharticheck_cause(struct uni_ie_cause *ie, struct unicx *cx,
1051121934Sharti    const struct causetab *tab1, const struct causetab *tab2)
1052121934Sharti{
1053121934Sharti	static const u_int mask =
1054121934Sharti		UNI_CAUSE_COND_P | UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P |
1055121934Sharti		UNI_CAUSE_REJ_IE_P | UNI_CAUSE_IE_P | UNI_CAUSE_TRAFFIC_P |
1056121934Sharti		UNI_CAUSE_VPCI_P | UNI_CAUSE_MTYPE_P | UNI_CAUSE_TIMER_P |
1057121934Sharti		UNI_CAUSE_TNS_P | UNI_CAUSE_NUMBER_P | UNI_CAUSE_ATTR_P |
1058121934Sharti		UNI_CAUSE_PARAM_P;
1059121934Sharti
1060121934Sharti	const struct causetab *ptr;
1061121934Sharti
1062242623Sdim	if ((int)ie->cause >= 128)
1063121934Sharti		return (-1);
1064121934Sharti
1065121934Sharti	switch (ie->loc) {
1066121934Sharti	  default:
1067121934Sharti		return (-1);
1068121934Sharti
1069121934Sharti	  case UNI_CAUSE_LOC_USER:
1070121934Sharti	  case UNI_CAUSE_LOC_PRIVLOC:
1071121934Sharti	  case UNI_CAUSE_LOC_PUBLOC:
1072121934Sharti	  case UNI_CAUSE_LOC_TRANSIT:
1073121934Sharti	  case UNI_CAUSE_LOC_PUBREM:
1074121934Sharti	  case UNI_CAUSE_LOC_PRIVREM:
1075121934Sharti	  case UNI_CAUSE_LOC_INTERNAT:
1076121934Sharti	  case UNI_CAUSE_LOC_BEYOND:
1077121934Sharti		break;
1078121934Sharti	}
1079121934Sharti
1080121934Sharti	if (tab1[ie->cause].str != NULL)
1081121934Sharti		ptr = &tab1[ie->cause];
1082121934Sharti	else if (tab2 != NULL && tab2[ie->cause].str != NULL)
1083121934Sharti		ptr = &tab2[ie->cause];
1084121934Sharti	else
1085121934Sharti		return (cx->cause_hard ? -1 : 0);
1086121934Sharti
1087121934Sharti	switch (ptr->diag) {
1088121934Sharti
1089121934Sharti	  case UNI_DIAG_NONE:
1090121934Sharti		switch (ie->h.present & mask) {
1091121934Sharti		  default:
1092121934Sharti			if (cx->cause_hard)
1093121934Sharti				return (-1);
1094121934Sharti			break;
1095121934Sharti
1096121934Sharti		  case 0:
1097121934Sharti			break;
1098121934Sharti		}
1099121934Sharti		break;
1100121934Sharti
1101121934Sharti	  case UNI_DIAG_COND:
1102121934Sharti		switch (ie->h.present & mask) {
1103121934Sharti		  default:
1104121934Sharti			if (cx->cause_hard)
1105121934Sharti				return (-1);
1106121934Sharti			break;
1107121934Sharti
1108121934Sharti		  case 0:
1109121934Sharti		  case UNI_CAUSE_COND_P:
1110121934Sharti			break;
1111121934Sharti		}
1112121934Sharti		break;
1113121934Sharti
1114121934Sharti	  case UNI_DIAG_REJ:
1115121934Sharti		switch (ie->h.present & mask) {
1116121934Sharti		  default:
1117121934Sharti			if (cx->cause_hard)
1118121934Sharti				return (-1);
1119121934Sharti			break;
1120121934Sharti
1121121934Sharti		  case 0:
1122121934Sharti		  case UNI_CAUSE_REJ_P:
1123121934Sharti		  case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P:
1124121934Sharti		  case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_IE_P:
1125121934Sharti			break;
1126121934Sharti		}
1127121934Sharti		break;
1128121934Sharti
1129121934Sharti	  case UNI_DIAG_CRATE:
1130121934Sharti		switch (ie->h.present & mask) {
1131121934Sharti		  default:
1132121934Sharti			if (cx->cause_hard)
1133121934Sharti				return (-1);
1134121934Sharti			break;
1135121934Sharti
1136121934Sharti		  case 0:
1137121934Sharti		  case UNI_CAUSE_TRAFFIC_P:
1138121934Sharti			break;
1139121934Sharti		}
1140121934Sharti		break;
1141121934Sharti
1142121934Sharti	  case UNI_DIAG_IE:
1143121934Sharti		switch (ie->h.present & mask) {
1144121934Sharti		  default:
1145121934Sharti			if (cx->cause_hard)
1146121934Sharti				return (-1);
1147121934Sharti			break;
1148121934Sharti
1149121934Sharti		  case 0:
1150121934Sharti		  case UNI_CAUSE_IE_P:
1151121934Sharti			break;
1152121934Sharti		}
1153121934Sharti		break;
1154121934Sharti
1155121934Sharti	  case UNI_DIAG_CHANID:
1156121934Sharti		switch (ie->h.present & mask) {
1157121934Sharti		  default:
1158121934Sharti			if (cx->cause_hard)
1159121934Sharti				return (-1);
1160121934Sharti			break;
1161121934Sharti
1162121934Sharti		  case 0:
1163121934Sharti		  case UNI_CAUSE_VPCI_P:
1164121934Sharti			break;
1165121934Sharti		}
1166121934Sharti		break;
1167121934Sharti
1168121934Sharti	  case UNI_DIAG_MTYPE:
1169121934Sharti		switch (ie->h.present & mask) {
1170121934Sharti		  default:
1171121934Sharti			if (cx->cause_hard)
1172121934Sharti				return (-1);
1173121934Sharti			break;
1174121934Sharti
1175121934Sharti		  case 0:
1176121934Sharti		  case UNI_CAUSE_MTYPE_P:
1177121934Sharti			break;
1178121934Sharti		}
1179121934Sharti		break;
1180121934Sharti
1181121934Sharti	  case UNI_DIAG_TIMER:
1182121934Sharti		switch (ie->h.present & mask) {
1183121934Sharti		  default:
1184121934Sharti			if (cx->cause_hard)
1185121934Sharti				return (-1);
1186121934Sharti			break;
1187121934Sharti
1188121934Sharti		  case 0:
1189121934Sharti		  case UNI_CAUSE_TIMER_P:
1190121934Sharti			break;
1191121934Sharti		}
1192121934Sharti		break;
1193121934Sharti
1194121934Sharti	  case UNI_DIAG_TNS:
1195121934Sharti		switch (ie->h.present & mask) {
1196121934Sharti		  default:
1197121934Sharti			if (cx->cause_hard)
1198121934Sharti				return (-1);
1199121934Sharti			break;
1200121934Sharti
1201121934Sharti		  case 0:
1202121934Sharti		  case UNI_CAUSE_TNS_P:
1203121934Sharti			break;
1204121934Sharti		}
1205121934Sharti		break;
1206121934Sharti
1207121934Sharti	  case UNI_DIAG_NUMBER:
1208121934Sharti		switch (ie->h.present & mask) {
1209121934Sharti		  default:
1210121934Sharti			if (cx->cause_hard)
1211121934Sharti				return (-1);
1212121934Sharti			break;
1213121934Sharti
1214121934Sharti		  case 0:
1215121934Sharti		  case UNI_CAUSE_NUMBER_P:
1216121934Sharti			break;
1217121934Sharti		}
1218121934Sharti		break;
1219121934Sharti
1220121934Sharti	  case UNI_DIAG_ATTR:
1221121934Sharti		switch (ie->h.present & mask) {
1222121934Sharti		  default:
1223121934Sharti			if (cx->cause_hard)
1224121934Sharti				return (-1);
1225121934Sharti			break;
1226121934Sharti
1227121934Sharti		  case 0:
1228121934Sharti		  case UNI_CAUSE_ATTR_P:
1229121934Sharti			break;
1230121934Sharti		}
1231121934Sharti		break;
1232121934Sharti
1233121934Sharti	  case UNI_DIAG_PARAM:
1234121934Sharti		switch (ie->h.present & mask) {
1235121934Sharti		  default:
1236121934Sharti			if (cx->cause_hard)
1237121934Sharti				return (-1);
1238121934Sharti			break;
1239121934Sharti
1240121934Sharti		  case 0:
1241121934Sharti		  case UNI_CAUSE_PARAM_P:
1242121934Sharti			break;
1243121934Sharti		}
1244121934Sharti		break;
1245121934Sharti	}
1246121934Sharti
1247121934Sharti	if (ie->h.present & UNI_CAUSE_COND_P) {
1248121934Sharti		switch (ie->u.cond.pu) {
1249121934Sharti		  default:
1250121934Sharti			return (-1);
1251121934Sharti
1252121934Sharti		  case UNI_CAUSE_PU_PROVIDER:
1253121934Sharti		  case UNI_CAUSE_PU_USER:
1254121934Sharti			break;
1255121934Sharti		}
1256121934Sharti		switch (ie->u.cond.na) {
1257121934Sharti		  default:
1258121934Sharti			return (-1);
1259121934Sharti
1260121934Sharti		  case UNI_CAUSE_NA_NORMAL:
1261121934Sharti		  case UNI_CAUSE_NA_ABNORMAL:
1262121934Sharti			break;
1263121934Sharti		}
1264121934Sharti		switch (ie->u.cond.cond) {
1265121934Sharti		  default:
1266121934Sharti			return (-1);
1267121934Sharti
1268121934Sharti		  case UNI_CAUSE_COND_UNKNOWN:
1269121934Sharti		  case UNI_CAUSE_COND_PERM:
1270121934Sharti		  case UNI_CAUSE_COND_TRANS:
1271121934Sharti			break;
1272121934Sharti		}
1273121934Sharti	}
1274121934Sharti	if (ie->h.present & UNI_CAUSE_REJ_P) {
1275121934Sharti		switch (ie->u.rej.reason) {
1276121934Sharti		  default:
1277121934Sharti			return (-1);
1278121934Sharti
1279121934Sharti		  case UNI_CAUSE_REASON_USER:
1280121934Sharti			switch (ie->h.present & mask) {
1281121934Sharti			  default:
1282121934Sharti				return (-1);
1283121934Sharti
1284121934Sharti			  case UNI_CAUSE_REJ_P:
1285121934Sharti			  case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_USER_P:
1286121934Sharti				break;
1287121934Sharti			}
1288121934Sharti			break;
1289121934Sharti
1290121934Sharti		  case UNI_CAUSE_REASON_IEMISS:
1291121934Sharti		  case UNI_CAUSE_REASON_IESUFF:
1292121934Sharti			switch (ie->h.present & mask) {
1293121934Sharti			  default:
1294121934Sharti				return (-1);
1295121934Sharti
1296121934Sharti			  case UNI_CAUSE_REJ_P:
1297121934Sharti			  case UNI_CAUSE_REJ_P | UNI_CAUSE_REJ_IE_P:
1298121934Sharti				break;
1299121934Sharti			}
1300121934Sharti			break;
1301121934Sharti		}
1302121934Sharti	}
1303121934Sharti	if (ie->h.present & UNI_CAUSE_IE_P) {
1304121934Sharti		if (ie->u.ie.len == 0 || ie->u.ie.len > UNI_CAUSE_IE_N)
1305121934Sharti			return (-1);
1306121934Sharti	}
1307121934Sharti	if (ie->h.present & UNI_CAUSE_TRAFFIC_P) {
1308121934Sharti		if (ie->u.traffic.len == 0 ||
1309121934Sharti		    ie->u.traffic.len > UNI_CAUSE_TRAFFIC_N)
1310121934Sharti			return (-1);
1311121934Sharti	}
1312121934Sharti
1313121934Sharti	if (ie->h.present & UNI_CAUSE_TNS_P) {
1314121934Sharti		if (uni_check_ie(UNI_IE_TNS, (union uni_ieall *)&ie->u.tns, cx))
1315121934Sharti			return (-1);
1316121934Sharti	}
1317121934Sharti	if (ie->h.present & UNI_CAUSE_NUMBER_P) {
1318121934Sharti		if(uni_check_ie(UNI_IE_CALLED, (union uni_ieall *)&ie->u.number, cx))
1319121934Sharti			return (-1);
1320121934Sharti	}
1321121934Sharti	if (ie->h.present & UNI_CAUSE_ATTR_P) {
1322121934Sharti		if(ie->u.attr.nattr > UNI_CAUSE_ATTR_N || ie->u.attr.nattr == 0)
1323121934Sharti			return (-1);
1324121934Sharti	}
1325121934Sharti	if (ie->h.present & UNI_CAUSE_PARAM_P) {
1326228554Sdim		UNUSED(cx);
1327121934Sharti	}
1328121934Sharti
1329121934Sharti	return (0);
1330121934Sharti}
1331121934Sharti
1332121934ShartiDEF_IE_CHECK(itu, cause)
1333121934Sharti{
1334121934Sharti	return (check_cause(ie, cx, itu_causes, NULL));
1335121934Sharti}
1336121934ShartiDEF_IE_CHECK(net, cause)
1337121934Sharti{
1338121934Sharti	return (check_cause(ie, cx, net_causes, itu_causes));
1339121934Sharti}
1340121934Sharti/**********************************************************************/
1341121934Sharti
1342121934Shartistatic int
1343121934Shartiencode_cause(struct uni_msg *msg, struct uni_ie_cause *ie, struct unicx *cx)
1344121934Sharti{
1345121934Sharti	u_int i;
1346121934Sharti
1347121934Sharti	START_IE(cause, UNI_IE_CAUSE, 30);
1348121934Sharti
1349121934Sharti	if (IE_ISERROR(*ie)) {
1350121934Sharti		APP_BYTE(msg, 0x00 | ie->loc);
1351121934Sharti	} else {
1352121934Sharti		APP_BYTE(msg, 0x80 | ie->loc);
1353121934Sharti	}
1354121934Sharti	APP_BYTE(msg, 0x80 | ie->cause);
1355121934Sharti
1356121934Sharti	if (ie->h.present & UNI_CAUSE_COND_P)
1357121934Sharti		APP_BYTE(msg, 0x80 | (ie->u.cond.pu << 3) |
1358121934Sharti		    (ie->u.cond.na << 2) | ie->u.cond.cond);
1359121934Sharti
1360121934Sharti	else if (ie->h.present & UNI_CAUSE_REJ_P) {
1361121934Sharti		APP_BYTE(msg, 0x80 | (ie->u.rej.reason << 2) | ie->u.rej.cond);
1362121934Sharti		if (ie->h.present & UNI_CAUSE_REJ_USER_P)
1363121934Sharti			APP_BYTE(msg, ie->u.rej.user);
1364121934Sharti		else if (ie->h.present & UNI_CAUSE_REJ_IE_P)
1365121934Sharti			APP_BYTE(msg, ie->u.rej.ie);
1366121934Sharti
1367121934Sharti	} else if(ie->h.present & UNI_CAUSE_IE_P)
1368121934Sharti		APP_BUF(msg, ie->u.ie.ie, ie->u.ie.len);
1369121934Sharti
1370121934Sharti	else if (ie->h.present & UNI_CAUSE_TRAFFIC_P)
1371121934Sharti		APP_BUF(msg, ie->u.traffic.traffic, ie->u.traffic.len);
1372121934Sharti
1373121934Sharti	else if (ie->h.present & UNI_CAUSE_VPCI_P) {
1374121934Sharti		APP_BYTE(msg, (ie->u.vpci.vpci >> 8));
1375121934Sharti		APP_BYTE(msg, (ie->u.vpci.vpci >> 0));
1376121934Sharti		APP_BYTE(msg, (ie->u.vpci.vci >> 8));
1377121934Sharti		APP_BYTE(msg, (ie->u.vpci.vci >> 0));
1378121934Sharti
1379121934Sharti	} else if (ie->h.present & UNI_CAUSE_MTYPE_P)
1380121934Sharti		APP_BYTE(msg, ie->u.mtype);
1381121934Sharti
1382121934Sharti	else if (ie->h.present & UNI_CAUSE_TIMER_P) {
1383121934Sharti		APP_BYTE(msg, ie->u.timer[0]);
1384121934Sharti		APP_BYTE(msg, ie->u.timer[1]);
1385121934Sharti		APP_BYTE(msg, ie->u.timer[2]);
1386121934Sharti
1387121934Sharti	} else if (ie->h.present & UNI_CAUSE_TNS_P)
1388121934Sharti		uni_encode_ie(UNI_IE_TNS, msg,
1389121934Sharti		    (union uni_ieall *)&ie->u.tns, cx);
1390121934Sharti
1391121934Sharti	else if (ie->h.present & UNI_CAUSE_NUMBER_P)
1392121934Sharti		uni_encode_ie(UNI_IE_CALLED, msg,
1393121934Sharti		    (union uni_ieall *)&ie->u.number, cx);
1394121934Sharti
1395121934Sharti	else if (ie->h.present & UNI_CAUSE_ATTR_P) {
1396121934Sharti		for (i = 0; i < ie->u.attr.nattr; i++) {
1397121934Sharti			APP_BYTE(msg, ie->u.attr.attr[i][0]);
1398121934Sharti			if (!ie->u.attr.attr[i][0]) {
1399121934Sharti				APP_BYTE(msg, ie->u.attr.attr[i][1]);
1400121934Sharti				if (!ie->u.attr.attr[i][1])
1401121934Sharti					APP_BYTE(msg, ie->u.attr.attr[i][2]);
1402121934Sharti			}
1403121934Sharti		}
1404121934Sharti	} else if (ie->h.present & UNI_CAUSE_PARAM_P)
1405121934Sharti		APP_BYTE(msg, ie->u.param);
1406121934Sharti
1407121934Sharti	SET_IE_LEN(msg);
1408121934Sharti
1409121934Sharti	return (0);
1410121934Sharti}
1411121934Sharti
1412121934ShartiDEF_IE_ENCODE(itu, cause)
1413121934Sharti{
1414121934Sharti	return encode_cause(msg, ie, cx);
1415121934Sharti}
1416121934ShartiDEF_IE_ENCODE(net, cause)
1417121934Sharti{
1418121934Sharti	return encode_cause(msg, ie, cx);
1419121934Sharti}
1420121934Sharti
1421121934Sharti/**********************************************************************/
1422121934Sharti
1423121934Shartistatic int
1424121934Shartidecode_cause(struct uni_ie_cause *ie, struct uni_msg *msg, u_int ielen,
1425121934Sharti    struct unicx *cx, const struct causetab *tab1, const struct causetab *tab2)
1426121934Sharti{
1427121934Sharti	u_char c;
1428121934Sharti	const struct causetab *ptr;
1429121934Sharti	enum uni_ietype ietype;
1430121934Sharti	u_int xielen;
1431121934Sharti
1432121934Sharti	IE_START(;);
1433121934Sharti
1434121934Sharti	if(ielen < 2 || ielen > 30)
1435121934Sharti		goto rej;
1436121934Sharti
1437121934Sharti	c = *msg->b_rptr++;
1438121934Sharti	ielen--;
1439121934Sharti	if(!(c & 0x80))
1440121934Sharti		goto rej;
1441121934Sharti	ie->loc = c & 0xf;
1442121934Sharti
1443121934Sharti	c = *msg->b_rptr++;
1444121934Sharti	ielen--;
1445121934Sharti	if(!(c & 0x80))
1446121934Sharti		goto rej;
1447121934Sharti	ie->cause = c & 0x7f;
1448121934Sharti
1449121934Sharti	if(tab1[ie->cause].str != NULL)
1450121934Sharti		ptr = &tab1[ie->cause];
1451121934Sharti	else if(tab2 != NULL && tab2[ie->cause].str != NULL)
1452121934Sharti		ptr = &tab2[ie->cause];
1453121934Sharti	else {
1454121934Sharti		ptr = NULL;
1455121934Sharti		ielen = 0;	/* ignore diags */
1456121934Sharti	}
1457121934Sharti
1458121934Sharti	if(ielen) {
1459121934Sharti		switch(ptr->diag) {
1460121934Sharti
1461121934Sharti		  case UNI_DIAG_NONE:
1462121934Sharti			break;
1463121934Sharti
1464121934Sharti		  case UNI_DIAG_COND:
1465121934Sharti			if(ielen < 1)
1466121934Sharti				goto rej;
1467121934Sharti			c = *msg->b_rptr++;
1468121934Sharti			ielen--;
1469121934Sharti
1470121934Sharti			ie->h.present |= UNI_CAUSE_COND_P;
1471121934Sharti			ie->u.cond.pu = (c >> 3) & 1;
1472121934Sharti			ie->u.cond.na = (c >> 2) & 1;
1473121934Sharti			ie->u.cond.cond = c & 3;
1474121934Sharti
1475121934Sharti			if(!(c & 0x80))
1476121934Sharti				goto rej;
1477121934Sharti			break;
1478121934Sharti
1479121934Sharti		  case UNI_DIAG_REJ:
1480121934Sharti			if(ielen < 1)
1481121934Sharti				goto rej;
1482121934Sharti			c = *msg->b_rptr++;
1483121934Sharti			ielen--;
1484121934Sharti
1485121934Sharti			ie->h.present |= UNI_CAUSE_REJ_P;
1486121934Sharti			ie->u.rej.reason = (c >> 2) & 0x1f;
1487121934Sharti			ie->u.rej.cond = c & 3;
1488121934Sharti
1489121934Sharti			if(!(c & 0x80))
1490121934Sharti				goto rej;
1491121934Sharti
1492121934Sharti			if(ielen > 0) {
1493121934Sharti				c = *msg->b_rptr++;
1494121934Sharti				ielen--;
1495121934Sharti
1496121934Sharti				switch(ie->u.rej.reason) {
1497121934Sharti
1498121934Sharti				  case UNI_CAUSE_REASON_USER:
1499121934Sharti					ie->h.present |= UNI_CAUSE_REJ_USER_P;
1500121934Sharti					ie->u.rej.user = c;
1501121934Sharti					break;
1502121934Sharti
1503121934Sharti				  case UNI_CAUSE_REASON_IEMISS:
1504121934Sharti				  case UNI_CAUSE_REASON_IESUFF:
1505121934Sharti					ie->h.present |= UNI_CAUSE_REJ_IE_P;
1506121934Sharti					ie->u.rej.ie = c;
1507121934Sharti					break;
1508121934Sharti				}
1509121934Sharti			}
1510121934Sharti			break;
1511121934Sharti
1512121934Sharti		  case UNI_DIAG_CRATE:
1513121934Sharti			ie->h.present |= UNI_CAUSE_TRAFFIC_P;
1514121934Sharti			while(ielen && ie->u.traffic.len < UNI_CAUSE_TRAFFIC_N) {
1515121934Sharti				ie->u.traffic.traffic[ie->u.traffic.len++] =
1516121934Sharti					*msg->b_rptr++;
1517121934Sharti				ielen--;
1518121934Sharti			}
1519121934Sharti			break;
1520121934Sharti
1521121934Sharti		  case UNI_DIAG_IE:
1522121934Sharti			ie->h.present |= UNI_CAUSE_IE_P;
1523121934Sharti			while(ielen && ie->u.ie.len < UNI_CAUSE_IE_N) {
1524121934Sharti				ie->u.ie.ie[ie->u.ie.len++] = *msg->b_rptr++;
1525121934Sharti				ielen--;
1526121934Sharti			}
1527121934Sharti			break;
1528121934Sharti
1529121934Sharti		  case UNI_DIAG_CHANID:
1530121934Sharti			if(ielen < 4)
1531121934Sharti				break;
1532121934Sharti			ie->h.present |= UNI_CAUSE_VPCI_P;
1533121934Sharti			ie->u.vpci.vpci  = *msg->b_rptr++ << 8;
1534121934Sharti			ie->u.vpci.vpci |= *msg->b_rptr++;
1535121934Sharti			ie->u.vpci.vci  = *msg->b_rptr++ << 8;
1536121934Sharti			ie->u.vpci.vci |= *msg->b_rptr++;
1537121934Sharti			ielen -= 4;
1538121934Sharti			break;
1539121934Sharti
1540121934Sharti		  case UNI_DIAG_MTYPE:
1541121934Sharti			ie->h.present |= UNI_CAUSE_MTYPE_P;
1542121934Sharti			ie->u.mtype = *msg->b_rptr++;
1543121934Sharti			ielen--;
1544121934Sharti			break;
1545121934Sharti
1546121934Sharti		  case UNI_DIAG_TIMER:
1547121934Sharti			if(ielen < 3)
1548121934Sharti				break;
1549121934Sharti			ie->h.present |= UNI_CAUSE_TIMER_P;
1550121934Sharti			ie->u.timer[0] = *msg->b_rptr++;
1551121934Sharti			ie->u.timer[1] = *msg->b_rptr++;
1552121934Sharti			ie->u.timer[2] = *msg->b_rptr++;
1553121934Sharti			ielen -= 3;
1554121934Sharti			break;
1555121934Sharti
1556121934Sharti		  case UNI_DIAG_TNS:
1557121934Sharti			if(ielen < 4)
1558121934Sharti				break;
1559121934Sharti			if(uni_decode_ie_hdr(&ietype, &ie->u.tns.h, msg, cx, &xielen))
1560121934Sharti				break;
1561121934Sharti			if(ietype != UNI_IE_TNS)
1562121934Sharti				break;
1563121934Sharti			if(uni_decode_ie_body(ietype,
1564121934Sharti			    (union uni_ieall *)&ie->u.tns, msg, xielen, cx))
1565121934Sharti				break;
1566121934Sharti			ie->h.present |= UNI_CAUSE_TNS_P;
1567121934Sharti			break;
1568121934Sharti
1569121934Sharti		  case UNI_DIAG_NUMBER:
1570121934Sharti			if(ielen < 4)
1571121934Sharti				break;
1572121934Sharti			if(uni_decode_ie_hdr(&ietype, &ie->u.number.h, msg, cx, &xielen))
1573121934Sharti				break;
1574121934Sharti			if(ietype != UNI_IE_CALLED)
1575121934Sharti				break;
1576121934Sharti			if(uni_decode_ie_body(ietype,
1577121934Sharti			    (union uni_ieall *)&ie->u.number, msg, xielen, cx))
1578121934Sharti				break;
1579121934Sharti			ie->h.present |= UNI_CAUSE_NUMBER_P;
1580121934Sharti			break;
1581121934Sharti
1582121934Sharti		  case UNI_DIAG_ATTR:
1583121934Sharti			ie->h.present |= UNI_CAUSE_ATTR_P;
1584121934Sharti			while(ielen > 0 && ie->u.attr.nattr < UNI_CAUSE_ATTR_N) {
1585121934Sharti				c = *msg->b_rptr++;
1586121934Sharti				ie->u.attr.attr[ie->u.attr.nattr][0] = c;
1587121934Sharti				ielen--;
1588121934Sharti				if(ielen > 0 && !(c & 0x80)) {
1589121934Sharti					c = *msg->b_rptr++;
1590121934Sharti					ie->u.attr.attr[ie->u.attr.nattr][1] = c;
1591121934Sharti					ielen--;
1592121934Sharti					if(ielen > 0 && !(c & 0x80)) {
1593121934Sharti						c = *msg->b_rptr++;
1594121934Sharti						ie->u.attr.attr[ie->u.attr.nattr][2] = c;
1595121934Sharti						ielen--;
1596121934Sharti					}
1597121934Sharti				}
1598121934Sharti			}
1599121934Sharti			break;
1600121934Sharti
1601121934Sharti		  case UNI_DIAG_PARAM:
1602121934Sharti			ie->h.present |= UNI_CAUSE_PARAM_P;
1603121934Sharti			ie->u.param = *msg->b_rptr++;
1604121934Sharti			ielen--;
1605121934Sharti			break;
1606121934Sharti		}
1607121934Sharti	}
1608121934Sharti
1609121934Sharti	IE_END(CAUSE);
1610121934Sharti}
1611121934Sharti
1612121934ShartiDEF_IE_DECODE(itu, cause)
1613121934Sharti{
1614121934Sharti	return decode_cause(ie, msg, ielen, cx, itu_causes, NULL);
1615121934Sharti}
1616121934ShartiDEF_IE_DECODE(net, cause)
1617121934Sharti{
1618121934Sharti	return decode_cause(ie, msg, ielen, cx, net_causes, itu_causes);
1619121934Sharti}
1620121934Sharti
1621121934Sharti/*********************************************************************
1622121934Sharti *
1623121934Sharti * Callstate
1624121934Sharti *
1625121934Sharti * References for this IE are:
1626121934Sharti *
1627121934Sharti *  Q.2931 pp. 59...60
1628121934Sharti *  UNI4.0 pp. 14
1629121934Sharti *
1630121934Sharti * Only ITU-T coding allowed.
1631121934Sharti */
1632121934ShartiDEF_IE_PRINT(itu, callstate)
1633121934Sharti{
1634121934Sharti	static const struct uni_print_tbl tbl[] = {
1635121934Sharti		MKT(UNI_CALLSTATE_U0,	U0/N0/REST0),
1636121934Sharti		MKT(UNI_CALLSTATE_U1,	U1/N1),
1637121934Sharti		MKT(UNI_CALLSTATE_U3,	U3/N3),
1638121934Sharti		MKT(UNI_CALLSTATE_U4,	U4/N4),
1639121934Sharti		MKT(UNI_CALLSTATE_U6,	U6/N6),
1640121934Sharti		MKT(UNI_CALLSTATE_U7,	U7/N7),
1641121934Sharti		MKT(UNI_CALLSTATE_U8,	U8/N8),
1642121934Sharti		MKT(UNI_CALLSTATE_U9,	U9/N9),
1643121934Sharti		MKT(UNI_CALLSTATE_U10,	U10/N10),
1644121934Sharti		MKT(UNI_CALLSTATE_U11,	U11/N11),
1645121934Sharti		MKT(UNI_CALLSTATE_U12,	U12/N12),
1646121934Sharti		MKT(UNI_CALLSTATE_REST1,REST1),
1647121934Sharti		MKT(UNI_CALLSTATE_REST2,REST2),
1648121934Sharti		MKT(UNI_CALLSTATE_U13,	U13/N13),
1649121934Sharti		MKT(UNI_CALLSTATE_U14,	U14/N14),
1650121934Sharti		EOT()
1651121934Sharti	};
1652121934Sharti
1653121934Sharti	if(uni_print_iehdr("callstate", &ie->h, cx))
1654121934Sharti		return;
1655121934Sharti	uni_print_tbl("state", ie->state, tbl, cx);
1656121934Sharti	uni_print_ieend(cx);
1657121934Sharti}
1658121934Sharti
1659121934ShartiDEF_IE_CHECK(itu, callstate)
1660121934Sharti{
1661228554Sdim	UNUSED(cx);
1662121934Sharti
1663121934Sharti	switch(ie->state) {
1664121934Sharti	  default:
1665121934Sharti		return -1;
1666121934Sharti
1667121934Sharti	  case UNI_CALLSTATE_U0:
1668121934Sharti	  case UNI_CALLSTATE_U1:
1669121934Sharti	  case UNI_CALLSTATE_U3:
1670121934Sharti	  case UNI_CALLSTATE_U4:
1671121934Sharti	  case UNI_CALLSTATE_U6:
1672121934Sharti	  case UNI_CALLSTATE_U7:
1673121934Sharti	  case UNI_CALLSTATE_U8:
1674121934Sharti	  case UNI_CALLSTATE_U9:
1675121934Sharti	  case UNI_CALLSTATE_U10:
1676121934Sharti	  case UNI_CALLSTATE_U11:
1677121934Sharti	  case UNI_CALLSTATE_U12:
1678121934Sharti	  case UNI_CALLSTATE_REST1:
1679121934Sharti	  case UNI_CALLSTATE_REST2:
1680121934Sharti	  case UNI_CALLSTATE_U13:
1681121934Sharti	  case UNI_CALLSTATE_U14:
1682121934Sharti		break;
1683121934Sharti	}
1684121934Sharti
1685121934Sharti	return 0;
1686121934Sharti}
1687121934Sharti
1688121934ShartiDEF_IE_ENCODE(itu, callstate)
1689121934Sharti{
1690121934Sharti	START_IE(callstate, UNI_IE_CALLSTATE, 1);
1691121934Sharti
1692121934Sharti	APP_BYTE(msg, ie->state);
1693121934Sharti
1694121934Sharti	SET_IE_LEN(msg);
1695121934Sharti	return 0;
1696121934Sharti}
1697121934Sharti
1698121934ShartiDEF_IE_DECODE(itu, callstate)
1699121934Sharti{
1700121934Sharti	IE_START(;);
1701121934Sharti
1702121934Sharti	if(ielen != 1)
1703121934Sharti		goto rej;
1704121934Sharti
1705121934Sharti	ie->state = *msg->b_rptr++ & 0x3f;
1706121934Sharti	ielen--;
1707121934Sharti
1708121934Sharti	IE_END(CALLSTATE);
1709121934Sharti}
1710121934Sharti
1711121934Sharti/*********************************************************************
1712121934Sharti *
1713121934Sharti * Facility Information.
1714121934Sharti *
1715121934Sharti * References for this IE are:
1716121934Sharti *
1717121934Sharti *  Q.2932.1
1718121934Sharti *
1719121934Sharti * The standard allows only ROSE as protocol. We allow everything up to the
1720121934Sharti * maximum size.
1721121934Sharti *
1722121934Sharti * Only ITU-T coding allowed.
1723121934Sharti */
1724121934ShartiDEF_IE_PRINT(itu, facility)
1725121934Sharti{
1726121934Sharti	u_int i;
1727121934Sharti
1728121934Sharti	if(uni_print_iehdr("facility", &ie->h, cx))
1729121934Sharti		return;
1730121934Sharti
1731121934Sharti	if(ie->proto == UNI_FACILITY_ROSE)
1732121934Sharti		uni_print_entry(cx, "proto", "rose");
1733121934Sharti	else
1734121934Sharti		uni_print_entry(cx, "proto", "0x%02x", ie->proto);
1735121934Sharti
1736121934Sharti	uni_print_entry(cx, "len", "%u", ie->len);
1737121934Sharti	uni_print_entry(cx, "info", "(");
1738121934Sharti	for(i = 0; i < ie->len; i++)
1739121934Sharti		uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->apdu[i]);
1740121934Sharti	uni_printf(cx, ")");
1741121934Sharti
1742121934Sharti	uni_print_ieend(cx);
1743121934Sharti}
1744121934Sharti
1745121934ShartiDEF_IE_CHECK(itu, facility)
1746121934Sharti{
1747228554Sdim	UNUSED(cx);
1748121934Sharti
1749121934Sharti	if(ie->len > UNI_FACILITY_MAXAPDU)
1750121934Sharti		return -1;
1751121934Sharti
1752121934Sharti	return 0;
1753121934Sharti}
1754121934Sharti
1755121934ShartiDEF_IE_ENCODE(itu, facility)
1756121934Sharti{
1757121934Sharti	START_IE(facility, UNI_IE_FACILITY, 1 + ie->len);
1758121934Sharti
1759121934Sharti	APP_BYTE(msg, ie->proto | 0x80);
1760121934Sharti	APP_BUF(msg, ie->apdu, ie->len);
1761121934Sharti
1762121934Sharti	SET_IE_LEN(msg);
1763121934Sharti	return 0;
1764121934Sharti}
1765121934Sharti
1766121934ShartiDEF_IE_DECODE(itu, facility)
1767121934Sharti{
1768121934Sharti	u_char c;
1769121934Sharti
1770121934Sharti	IE_START(;);
1771121934Sharti
1772121934Sharti	if(ielen > UNI_FACILITY_MAXAPDU + 1 || ielen < 1)
1773121934Sharti		goto rej;
1774121934Sharti
1775121934Sharti	ie->proto = (c = *msg->b_rptr++) & 0x1f;
1776121934Sharti	ielen--;
1777121934Sharti	if((c & 0xe0) != 0x80)
1778121934Sharti		goto rej;
1779121934Sharti
1780121934Sharti	ie->len = ielen;
1781121934Sharti	ielen = 0;
1782121934Sharti	(void)memcpy(ie->apdu, msg->b_rptr, ie->len);
1783121934Sharti	msg->b_rptr += ie->len;
1784121934Sharti
1785121934Sharti	IE_END(FACILITY);
1786121934Sharti}
1787121934Sharti
1788121934Sharti/*********************************************************************
1789121934Sharti *
1790121934Sharti * Notification Indicator
1791121934Sharti *
1792121934Sharti * References for this IE are:
1793121934Sharti *
1794121934Sharti *  Q.2931 p.  76
1795121934Sharti *  UNI4.0 p.  17
1796121934Sharti *
1797121934Sharti * Only ITU-T coding allowed.
1798121934Sharti */
1799121934Sharti
1800121934ShartiDEF_IE_PRINT(itu, notify)
1801121934Sharti{
1802121934Sharti	u_int i;
1803121934Sharti
1804121934Sharti	if(uni_print_iehdr("notify", &ie->h, cx))
1805121934Sharti		return;
1806121934Sharti	uni_print_entry(cx, "len", "%u", ie->len);
1807121934Sharti	uni_print_entry(cx, "info", "(");
1808121934Sharti	for(i = 0; i < ie->len; i++)
1809121934Sharti		uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->notify[i]);
1810121934Sharti	uni_printf(cx, ")");
1811121934Sharti	uni_print_ieend(cx);
1812121934Sharti}
1813121934Sharti
1814121934ShartiDEF_IE_CHECK(itu, notify)
1815121934Sharti{
1816228554Sdim	UNUSED(cx);
1817121934Sharti
1818121934Sharti	if(ie->len > UNI_NOTIFY_MAXLEN)
1819121934Sharti		return -1;
1820121934Sharti
1821121934Sharti	return 0;
1822121934Sharti}
1823121934Sharti
1824121934ShartiDEF_IE_ENCODE(itu, notify)
1825121934Sharti{
1826121934Sharti	START_IE(notify, UNI_IE_NOTIFY, ie->len);
1827121934Sharti
1828121934Sharti	APP_BUF(msg, ie->notify, ie->len);
1829121934Sharti	if (IE_ISERROR(*ie)) {
1830121934Sharti		/* make it too long */
1831121934Sharti		u_int i = ie->len;
1832121934Sharti
1833121934Sharti		while (i < UNI_NOTIFY_MAXLEN + 1) {
1834121934Sharti			APP_BYTE(msg, 0x00);
1835121934Sharti			i++;
1836121934Sharti		}
1837121934Sharti	}
1838121934Sharti
1839121934Sharti	SET_IE_LEN(msg);
1840121934Sharti	return (0);
1841121934Sharti}
1842121934Sharti
1843121934ShartiDEF_IE_DECODE(itu, notify)
1844121934Sharti{
1845121934Sharti	IE_START(;);
1846121934Sharti
1847121934Sharti	if (ielen > UNI_NOTIFY_MAXLEN || ielen < 1)
1848121934Sharti		goto rej;
1849121934Sharti
1850121934Sharti	ie->len = ielen;
1851121934Sharti	ielen = 0;
1852121934Sharti	(void)memcpy(ie->notify, msg->b_rptr, ie->len);
1853121934Sharti	msg->b_rptr += ie->len;
1854121934Sharti
1855121934Sharti	IE_END(NOTIFY);
1856121934Sharti}
1857121934Sharti
1858121934Sharti/*********************************************************************
1859121934Sharti *
1860121934Sharti * End-to-end transit delay.
1861121934Sharti *
1862121934Sharti * References for this IE are:
1863121934Sharti *
1864121934Sharti *  Q.2931 pp. 70...71
1865121934Sharti *  UNI4.0 pp. 69...70
1866121934Sharti *  PNNI1.0 pp. 198...200
1867121934Sharti *
1868121934Sharti * Not clear, whether the new indicator should be used with NET coding or
1869121934Sharti * not.
1870121934Sharti *
1871121934Sharti * Only ITU-T coding allowed.
1872121934Sharti */
1873121934Sharti
1874121934Shartistatic void
1875121934Shartiprint_eetd(struct uni_ie_eetd *ie, struct unicx *cx)
1876121934Sharti{
1877121934Sharti	if (uni_print_iehdr("eetd", &ie->h, cx))
1878121934Sharti		return;
1879121934Sharti
1880121934Sharti	if (ie->h.present & UNI_EETD_CUM_P)
1881121934Sharti		uni_print_entry(cx, "cum", "%u", ie->cumulative);
1882121934Sharti	if (ie->h.present & UNI_EETD_MAX_P) {
1883121934Sharti		if (ie->maximum == UNI_EETD_ANYMAX)
1884121934Sharti			uni_print_entry(cx, "max", "any");
1885121934Sharti		else
1886121934Sharti			uni_print_entry(cx, "max", "%u", ie->maximum);
1887121934Sharti	}
1888121934Sharti	if (ie->h.present & UNI_EETD_PCTD_P)
1889121934Sharti		uni_print_entry(cx, "pnni_cum", "%u", ie->pctd);
1890121934Sharti	if (ie->h.present & UNI_EETD_PMTD_P)
1891121934Sharti		uni_print_entry(cx, "pnni_max", "%u", ie->pmtd);
1892121934Sharti	if (ie->h.present & UNI_EETD_NET_P)
1893121934Sharti		uni_print_flag("netgen", cx);
1894121934Sharti
1895121934Sharti	uni_print_ieend(cx);
1896121934Sharti}
1897121934ShartiDEF_IE_PRINT(itu, eetd)
1898121934Sharti{
1899121934Sharti	print_eetd(ie, cx);
1900121934Sharti}
1901121934ShartiDEF_IE_PRINT(net, eetd)
1902121934Sharti{
1903121934Sharti	print_eetd(ie, cx);
1904121934Sharti}
1905121934Sharti
1906121934ShartiDEF_IE_CHECK(itu, eetd)
1907121934Sharti{
1908121934Sharti
1909228554Sdim	UNUSED(cx);
1910121934Sharti
1911121934Sharti	if (!(ie->h.present & UNI_EETD_CUM_P))
1912121934Sharti		return (-1);
1913121934Sharti	if (ie->h.present & (UNI_EETD_PMTD_P | UNI_EETD_PCTD_P))
1914121934Sharti		return (-1);
1915121934Sharti	return (0);
1916121934Sharti}
1917121934Sharti
1918121934ShartiDEF_IE_CHECK(net, eetd)
1919121934Sharti{
1920121934Sharti
1921121934Sharti	if (!cx->pnni) {
1922121934Sharti		if (!(ie->h.present & UNI_EETD_CUM_P))
1923121934Sharti			return (-1);
1924121934Sharti		if (ie->h.present & (UNI_EETD_PMTD_P | UNI_EETD_PCTD_P))
1925121934Sharti			return (-1);
1926121934Sharti	} else {
1927121934Sharti		if (ie->h.present & UNI_EETD_MAX_P)
1928121934Sharti			return (-1);
1929121934Sharti		if ((ie->h.present & UNI_EETD_CUM_P) &&
1930121934Sharti		    (ie->h.present & UNI_EETD_PCTD_P))
1931121934Sharti			return (-1);
1932121934Sharti	}
1933121934Sharti	return (0);
1934121934Sharti}
1935121934Sharti
1936121934ShartiDEF_IE_ENCODE(itu, eetd)
1937121934Sharti{
1938121934Sharti	START_IE(eetd, UNI_IE_EETD, 9);
1939121934Sharti
1940121934Sharti	if (ie->h.present & UNI_EETD_CUM_P) {
1941121934Sharti		APP_BYTE(msg, UNI_EETD_CTD_ID);
1942121934Sharti		APP_16BIT(msg, ie->cumulative);
1943121934Sharti	}
1944121934Sharti	if (ie->h.present & UNI_EETD_MAX_P) {
1945121934Sharti		APP_BYTE(msg, UNI_EETD_MTD_ID);
1946121934Sharti		APP_16BIT(msg, ie->maximum);
1947121934Sharti	}
1948121934Sharti	if (ie->h.present & UNI_EETD_PMTD_P) {
1949121934Sharti		APP_BYTE(msg, UNI_EETD_PMTD_ID);
1950121934Sharti		APP_24BIT(msg, ie->pmtd);
1951121934Sharti	}
1952121934Sharti	if (ie->h.present & UNI_EETD_PCTD_P) {
1953121934Sharti		APP_BYTE(msg, UNI_EETD_PCTD_ID);
1954121934Sharti		APP_24BIT(msg, ie->pctd);
1955121934Sharti	}
1956121934Sharti	if (ie->h.present & UNI_EETD_NET_P) {
1957121934Sharti		APP_BYTE(msg, UNI_EETD_NET_ID);
1958121934Sharti	}
1959121934Sharti
1960121934Sharti	SET_IE_LEN(msg);
1961121934Sharti	return (0);
1962121934Sharti}
1963121934Sharti
1964121934ShartiDEF_IE_ENCODE(net, eetd)
1965121934Sharti{
1966121934Sharti	return (uni_ie_encode_itu_eetd(msg, ie, cx));
1967121934Sharti}
1968121934Sharti
1969121934ShartiDEF_IE_DECODE(itu, eetd)
1970121934Sharti{
1971121934Sharti	IE_START(;);
1972121934Sharti
1973121934Sharti	while (ielen > 0) {
1974121934Sharti		switch (ielen--, *msg->b_rptr++) {
1975121934Sharti
1976121934Sharti		  case UNI_EETD_CTD_ID:
1977121934Sharti			if (ielen < 2)
1978121934Sharti				goto rej;
1979121934Sharti			ie->h.present |= UNI_EETD_CUM_P;
1980121934Sharti			ie->cumulative = *msg->b_rptr++ << 8;
1981121934Sharti			ie->cumulative |= *msg->b_rptr++;
1982121934Sharti			ielen -= 2;
1983121934Sharti			break;
1984121934Sharti
1985121934Sharti		  case UNI_EETD_MTD_ID:
1986121934Sharti			if (ielen < 2)
1987121934Sharti				goto rej;
1988121934Sharti			ie->h.present |= UNI_EETD_MAX_P;
1989121934Sharti			ie->maximum = *msg->b_rptr++ << 8;
1990121934Sharti			ie->maximum |= *msg->b_rptr++;
1991121934Sharti			ielen -= 2;
1992121934Sharti			break;
1993121934Sharti
1994121934Sharti		  case UNI_EETD_PCTD_ID:
1995121934Sharti			if (ielen < 3)
1996121934Sharti				goto rej;
1997121934Sharti			ie->h.present |= UNI_EETD_PCTD_P;
1998121934Sharti			ie->pctd = *msg->b_rptr++ << 16;
1999121934Sharti			ie->pctd |= *msg->b_rptr++ << 8;
2000121934Sharti			ie->pctd |= *msg->b_rptr++;
2001121934Sharti			ielen -= 3;
2002121934Sharti			break;
2003121934Sharti
2004121934Sharti		  case UNI_EETD_PMTD_ID:
2005121934Sharti			if (ielen < 3)
2006121934Sharti				goto rej;
2007121934Sharti			ie->h.present |= UNI_EETD_PMTD_P;
2008121934Sharti			ie->pmtd = *msg->b_rptr++ << 16;
2009121934Sharti			ie->pmtd |= *msg->b_rptr++ << 8;
2010121934Sharti			ie->pmtd |= *msg->b_rptr++;
2011121934Sharti			ielen -= 3;
2012121934Sharti			break;
2013121934Sharti
2014121934Sharti		  case UNI_EETD_NET_ID:
2015121934Sharti			ie->h.present |= UNI_EETD_NET_P;
2016121934Sharti			break;
2017121934Sharti
2018121934Sharti		  default:
2019121934Sharti			goto rej;
2020121934Sharti		}
2021121934Sharti	}
2022121934Sharti
2023121934Sharti	IE_END(EETD);
2024121934Sharti}
2025121934ShartiDEF_IE_DECODE(net, eetd)
2026121934Sharti{
2027121934Sharti	return (uni_ie_decode_itu_eetd(ie, msg, ielen, cx));
2028121934Sharti}
2029121934Sharti
2030121934Sharti/*********************************************************************
2031121934Sharti *
2032121934Sharti * Called address
2033121934Sharti * Called subaddress
2034121934Sharti * Calling address
2035121934Sharti * Calling subaddress
2036121934Sharti * Connected address
2037121934Sharti * Connected subaddress
2038121934Sharti *
2039121934Sharti * References for this IE are:
2040121934Sharti *
2041121934Sharti *  Q.2931 pp. 60...68
2042121934Sharti *  ...A4  pp. 27...36
2043121934Sharti *  UNI4.0 pp. 14...15
2044121934Sharti *  Q.2951 pp. 28...40
2045121934Sharti *
2046121934Sharti * It is assumed, that the coding of the addr arrays is ok.
2047121934Sharti *
2048121934Sharti * Only ITU-T coding allowed.
2049121934Sharti */
2050121934Sharti
2051121934Shartistatic const struct uni_print_tbl screen_tbl[] = {
2052121934Sharti	MKT(UNI_ADDR_SCREEN_NOT,	no),
2053121934Sharti	MKT(UNI_ADDR_SCREEN_PASSED,	passed),
2054121934Sharti	MKT(UNI_ADDR_SCREEN_FAILED,	failed),
2055121934Sharti	MKT(UNI_ADDR_SCREEN_NET,	network),
2056121934Sharti	EOT()
2057121934Sharti};
2058121934Shartistatic const struct uni_print_tbl pres_tbl[] = {
2059121934Sharti	MKT(UNI_ADDR_PRES,		allowed),
2060121934Sharti	MKT(UNI_ADDR_RESTRICT,		restricted),
2061121934Sharti	MKT(UNI_ADDR_NONUMBER,		no-number),
2062121934Sharti	EOT()
2063121934Sharti};
2064121934Sharti
2065121934Sharti
2066121934Shartistatic void
2067121934Shartiprint_addr(struct unicx *cx, struct uni_addr *addr)
2068121934Sharti{
2069121934Sharti	static const struct uni_print_tbl plan_tbl[] = {
2070121934Sharti		MKT(UNI_ADDR_UNKNOWN,	unknown),
2071121934Sharti		MKT(UNI_ADDR_E164,	E164),
2072121934Sharti		MKT(UNI_ADDR_ATME,	ATME),
2073121934Sharti		MKT(UNI_ADDR_DATA,	data),
2074121934Sharti		MKT(UNI_ADDR_PRIVATE,	private),
2075121934Sharti		EOT()
2076121934Sharti	};
2077121934Sharti	static const struct uni_print_tbl type_tbl[] = {
2078121934Sharti		MKT(UNI_ADDR_UNKNOWN,		unknown),
2079121934Sharti		MKT(UNI_ADDR_INTERNATIONAL,	international),
2080121934Sharti		MKT(UNI_ADDR_NATIONAL,		national),
2081121934Sharti		MKT(UNI_ADDR_NETWORK,		network),
2082121934Sharti		MKT(UNI_ADDR_SUBSCR,		subscriber),
2083121934Sharti		MKT(UNI_ADDR_ABBR,		abbreviated),
2084121934Sharti		EOT()
2085121934Sharti	};
2086121934Sharti	u_int i;
2087121934Sharti
2088121934Sharti	uni_print_entry(cx, "addr", "(");
2089121934Sharti	uni_print_tbl(NULL, addr->type, type_tbl, cx);
2090121934Sharti	uni_putc(',', cx);
2091121934Sharti	uni_print_tbl(NULL, addr->plan, plan_tbl, cx);
2092121934Sharti	uni_putc(',', cx);
2093121934Sharti	if(addr->plan == UNI_ADDR_E164) {
2094121934Sharti		uni_putc('"', cx);
2095121934Sharti		for(i = 0; i < addr->len; i++) {
2096121934Sharti			if(addr->addr[i] < ' ')
2097121934Sharti				uni_printf(cx, "^%c", addr->addr[i] + '@');
2098121934Sharti			else if(addr->addr[i] <= '~')
2099121934Sharti				uni_putc(addr->addr[i], cx);
2100121934Sharti			else
2101121934Sharti				uni_printf(cx, "\\%03o", addr->addr[i]);
2102121934Sharti		}
2103121934Sharti		uni_putc('"', cx);
2104121934Sharti
2105121934Sharti	} else if(addr->plan == UNI_ADDR_ATME) {
2106121934Sharti		for(i = 0; i < addr->len; i++)
2107121934Sharti			uni_printf(cx, "%02x", addr->addr[i]);
2108121934Sharti	}
2109121934Sharti	uni_putc(')', cx);
2110121934Sharti}
2111121934Sharti
2112121934Shartistatic void
2113121934Shartiprint_addrsub(struct unicx *cx, struct uni_subaddr *addr)
2114121934Sharti{
2115121934Sharti	static const struct uni_print_tbl type_tbl[] = {
2116121934Sharti		MKT(UNI_SUBADDR_NSAP,	NSAP),
2117121934Sharti		MKT(UNI_SUBADDR_ATME,	ATME),
2118121934Sharti		MKT(UNI_SUBADDR_USER,	USER),
2119121934Sharti		EOT()
2120121934Sharti	};
2121121934Sharti	u_int i;
2122121934Sharti
2123121934Sharti	uni_print_entry(cx, "addr", "(");
2124121934Sharti	uni_print_tbl(NULL, addr->type, type_tbl, cx);
2125121934Sharti	uni_putc(',', cx);
2126121934Sharti
2127121934Sharti	for(i = 0; i < addr->len; i++)
2128121934Sharti		uni_printf(cx, "%02x", addr->addr[i]);
2129121934Sharti
2130121934Sharti	uni_putc(')', cx);
2131121934Sharti}
2132121934Sharti
2133121934Shartistatic int
2134121934Sharticheck_addr(struct uni_addr *addr)
2135121934Sharti{
2136121934Sharti	u_int i;
2137121934Sharti
2138121934Sharti	switch(addr->plan) {
2139121934Sharti	  default:
2140121934Sharti		return -1;
2141121934Sharti
2142121934Sharti	  case UNI_ADDR_E164:
2143121934Sharti		if(addr->type != UNI_ADDR_INTERNATIONAL)
2144121934Sharti			return -1;
2145121934Sharti		if(addr->len > 15 || addr->len == 0)
2146121934Sharti			return -1;
2147121934Sharti		for(i = 0; i < addr->len; i++)
2148121934Sharti			if(addr->addr[i] == 0 || (addr->addr[i] & 0x80))
2149121934Sharti				return -1;
2150121934Sharti		break;
2151121934Sharti
2152121934Sharti	  case UNI_ADDR_ATME:
2153121934Sharti		if(addr->type != UNI_ADDR_UNKNOWN)
2154121934Sharti			return -1;
2155121934Sharti		if(addr->len != 20)
2156121934Sharti			return -1;
2157121934Sharti		break;
2158121934Sharti	}
2159121934Sharti
2160121934Sharti	return 0;
2161121934Sharti}
2162121934Sharti
2163121934Shartistatic int
2164121934Sharticheck_subaddr(struct uni_subaddr *addr)
2165121934Sharti{
2166121934Sharti	switch(addr->type) {
2167121934Sharti	  default:
2168121934Sharti		return -1;
2169121934Sharti
2170121934Sharti	  case UNI_SUBADDR_NSAP:
2171121934Sharti		if(addr->len != 20)
2172121934Sharti			return -1;
2173121934Sharti		break;
2174121934Sharti
2175121934Sharti	  case UNI_SUBADDR_ATME:
2176121934Sharti		if(addr->len > 20)
2177121934Sharti			return -1;
2178121934Sharti		break;
2179121934Sharti	}
2180121934Sharti	return 0;
2181121934Sharti}
2182121934Sharti
2183121934Shartistatic int
2184121934Sharticheck_screen(enum uni_addr_screen screen, enum uni_addr_pres pres)
2185121934Sharti{
2186121934Sharti	switch(pres) {
2187121934Sharti	  default:
2188121934Sharti		return -1;
2189121934Sharti
2190121934Sharti	  case UNI_ADDR_PRES:
2191121934Sharti	  case UNI_ADDR_RESTRICT:
2192121934Sharti	  case UNI_ADDR_NONUMBER:
2193121934Sharti		break;
2194121934Sharti	}
2195121934Sharti	switch(screen) {
2196121934Sharti	  default:
2197121934Sharti		return -1;
2198121934Sharti
2199121934Sharti	  case UNI_ADDR_SCREEN_NOT:
2200121934Sharti	  case UNI_ADDR_SCREEN_PASSED:
2201121934Sharti	  case UNI_ADDR_SCREEN_FAILED:
2202121934Sharti	  case UNI_ADDR_SCREEN_NET:
2203121934Sharti		break;
2204121934Sharti	}
2205121934Sharti
2206121934Sharti	return 0;
2207121934Sharti}
2208121934Sharti
2209121934Shartistatic void
2210121934Shartiencode_addr(struct uni_msg *msg, struct uni_addr *addr, u_int flag,
2211121934Sharti    enum uni_addr_screen screen, enum uni_addr_pres pres, int err)
2212121934Sharti{
2213121934Sharti	u_char ext = err ? 0x00 : 0x80;
2214121934Sharti
2215121934Sharti	if (flag) {
2216121934Sharti		APP_BYTE(msg, (addr->type << 4) | addr->plan);
2217121934Sharti		APP_BYTE(msg, ext | (pres << 5) | (screen));
2218121934Sharti	} else {
2219121934Sharti		APP_BYTE(msg, ext | (addr->type << 4) | addr->plan);
2220121934Sharti	}
2221121934Sharti	APP_BUF(msg, addr->addr, addr->len);
2222121934Sharti}
2223121934Sharti
2224121934Shartistatic void
2225121934Shartiencode_subaddr(struct uni_msg *msg, struct uni_subaddr *addr)
2226121934Sharti{
2227121934Sharti	APP_BYTE(msg, 0x80|(addr->type<<4));
2228121934Sharti	APP_BUF(msg, addr->addr, addr->len);
2229121934Sharti}
2230121934Sharti
2231121934Shartistatic int
2232121934Shartidecode_addr(struct uni_addr *addr, u_int ielen, struct uni_msg *msg, u_int plan)
2233121934Sharti{
2234121934Sharti	addr->plan = plan & 0xf;
2235121934Sharti	addr->type = (plan >> 4) & 0x7;
2236121934Sharti
2237121934Sharti	switch(addr->plan) {
2238121934Sharti
2239121934Sharti	  case UNI_ADDR_E164:
2240121934Sharti		if(ielen > 15 || ielen == 0)
2241121934Sharti			return -1;
2242121934Sharti		addr->addr[ielen] = 0;
2243121934Sharti		break;
2244121934Sharti
2245121934Sharti	  case UNI_ADDR_ATME:
2246121934Sharti		if(ielen != 20)
2247121934Sharti			return -1;
2248121934Sharti		break;
2249121934Sharti
2250121934Sharti	  default:
2251121934Sharti		return -1;
2252121934Sharti	}
2253121934Sharti	(void)memcpy(addr->addr, msg->b_rptr, ielen);
2254121934Sharti	addr->len = ielen;
2255121934Sharti	msg->b_rptr += ielen;
2256121934Sharti
2257121934Sharti	return 0;
2258121934Sharti}
2259121934Sharti
2260121934Shartistatic int
2261121934Shartidecode_subaddr(struct uni_subaddr *addr, u_int ielen, struct uni_msg *msg,
2262121934Sharti    u_int type)
2263121934Sharti{
2264121934Sharti	switch(addr->type = (type >> 4) & 0x7) {
2265121934Sharti
2266121934Sharti	  case UNI_SUBADDR_NSAP:
2267121934Sharti		if(ielen == 0 || ielen > 20)
2268121934Sharti			return -1;
2269121934Sharti		break;
2270121934Sharti
2271121934Sharti	  case UNI_SUBADDR_ATME:
2272121934Sharti		if(ielen != 20)
2273121934Sharti			return -1;
2274121934Sharti		break;
2275121934Sharti
2276121934Sharti	  default:
2277121934Sharti		return -1;
2278121934Sharti	}
2279121934Sharti	if(!(type & 0x80))
2280121934Sharti		return -1;
2281121934Sharti	if((type & 0x7) != 0)
2282121934Sharti		return -1;
2283121934Sharti
2284121934Sharti	addr->len = ielen;
2285121934Sharti	(void)memcpy(addr->addr, msg->b_rptr, ielen);
2286121934Sharti	msg->b_rptr += ielen;
2287121934Sharti
2288121934Sharti	return 0;
2289121934Sharti}
2290121934Sharti
2291121934Sharti/**********************************************************************/
2292121934Sharti
2293121934ShartiDEF_IE_PRINT(itu, called)
2294121934Sharti{
2295121934Sharti	if (uni_print_iehdr("called", &ie->h, cx))
2296121934Sharti		return;
2297121934Sharti	print_addr(cx, &ie->addr);
2298121934Sharti	uni_print_ieend(cx);
2299121934Sharti}
2300121934Sharti
2301121934ShartiDEF_IE_CHECK(itu, called)
2302121934Sharti{
2303228554Sdim	UNUSED(cx);
2304121934Sharti
2305121934Sharti	if (check_addr(&ie->addr))
2306121934Sharti		return (-1);
2307121934Sharti	return (0);
2308121934Sharti}
2309121934Sharti
2310121934ShartiDEF_IE_ENCODE(itu, called)
2311121934Sharti{
2312121934Sharti	START_IE(called, UNI_IE_CALLED, 21);
2313121934Sharti	encode_addr(msg, &ie->addr, 0, 0, 0, IE_ISERROR(*ie));
2314121934Sharti	SET_IE_LEN(msg);
2315121934Sharti	return (0);
2316121934Sharti}
2317121934Sharti
2318121934ShartiDEF_IE_DECODE(itu, called)
2319121934Sharti{
2320121934Sharti	u_char c;
2321121934Sharti	IE_START(;);
2322121934Sharti
2323121934Sharti	if (ielen > 21 || ielen < 1)
2324121934Sharti		goto rej;
2325121934Sharti
2326121934Sharti	c = *msg->b_rptr++;
2327121934Sharti	ielen--;
2328121934Sharti
2329121934Sharti	if (!(c & 0x80))
2330121934Sharti		goto rej;
2331121934Sharti
2332121934Sharti	if (decode_addr(&ie->addr, ielen, msg, c))
2333121934Sharti		goto rej;
2334121934Sharti
2335121934Sharti	IE_END(CALLED);
2336121934Sharti}
2337121934Sharti
2338121934Sharti/**********************************************************************/
2339121934Sharti
2340121934ShartiDEF_IE_PRINT(itu, calledsub)
2341121934Sharti{
2342121934Sharti	if(uni_print_iehdr("calledsub", &ie->h, cx))
2343121934Sharti		return;
2344121934Sharti	print_addrsub(cx, &ie->addr);
2345121934Sharti	uni_print_ieend(cx);
2346121934Sharti}
2347121934Sharti
2348121934ShartiDEF_IE_CHECK(itu, calledsub)
2349121934Sharti{
2350228554Sdim	UNUSED(cx);
2351121934Sharti
2352121934Sharti	if(check_subaddr(&ie->addr))
2353121934Sharti		return -1;
2354121934Sharti	return 0;
2355121934Sharti}
2356121934Sharti
2357121934ShartiDEF_IE_ENCODE(itu, calledsub)
2358121934Sharti{
2359121934Sharti	START_IE(calledsub, UNI_IE_CALLEDSUB, 21);
2360121934Sharti	encode_subaddr(msg, &ie->addr);
2361121934Sharti	SET_IE_LEN(msg);
2362121934Sharti	return 0;
2363121934Sharti}
2364121934Sharti
2365121934ShartiDEF_IE_DECODE(itu, calledsub)
2366121934Sharti{
2367121934Sharti	u_char c;
2368121934Sharti
2369121934Sharti	IE_START(;);
2370121934Sharti
2371121934Sharti	if(ielen > 21)
2372121934Sharti		goto rej;
2373121934Sharti
2374121934Sharti	c = *msg->b_rptr++;
2375121934Sharti	ielen--;
2376121934Sharti
2377121934Sharti	if(decode_subaddr(&ie->addr, ielen, msg, c))
2378121934Sharti		goto rej;
2379121934Sharti
2380121934Sharti	IE_END(CALLEDSUB);
2381121934Sharti}
2382121934Sharti
2383121934Sharti/**********************************************************************/
2384121934Sharti
2385121934ShartiDEF_IE_PRINT(itu, calling)
2386121934Sharti{
2387121934Sharti	if(uni_print_iehdr("calling", &ie->h, cx))
2388121934Sharti		return;
2389121934Sharti	print_addr(cx, &ie->addr);
2390121934Sharti
2391121934Sharti	if(ie->h.present & UNI_CALLING_SCREEN_P) {
2392121934Sharti		uni_print_tbl("screening", ie->screen, screen_tbl, cx);
2393121934Sharti		uni_print_tbl("presentation", ie->pres, pres_tbl, cx);
2394121934Sharti	}
2395121934Sharti
2396121934Sharti	uni_print_ieend(cx);
2397121934Sharti}
2398121934Sharti
2399121934ShartiDEF_IE_CHECK(itu, calling)
2400121934Sharti{
2401228554Sdim	UNUSED(cx);
2402121934Sharti
2403121934Sharti	if(check_addr(&ie->addr))
2404121934Sharti		return -1;
2405121934Sharti
2406121934Sharti	if(ie->h.present & UNI_CALLING_SCREEN_P)
2407121934Sharti		if(check_screen(ie->screen, ie->pres))
2408121934Sharti			return -1;
2409121934Sharti	return 0;
2410121934Sharti}
2411121934Sharti
2412121934ShartiDEF_IE_ENCODE(itu, calling)
2413121934Sharti{
2414121934Sharti	START_IE(calling, UNI_IE_CALLING, 22);
2415121934Sharti	encode_addr(msg, &ie->addr, ie->h.present & UNI_CALLING_SCREEN_P, ie->screen, ie->pres, IE_ISERROR(*ie));
2416121934Sharti	SET_IE_LEN(msg);
2417121934Sharti	return 0;
2418121934Sharti}
2419121934Sharti
2420121934ShartiDEF_IE_DECODE(itu, calling)
2421121934Sharti{
2422121934Sharti	u_char c, plan;
2423121934Sharti
2424121934Sharti	IE_START(;);
2425121934Sharti
2426121934Sharti	if(ielen > 22 || ielen < 1)
2427121934Sharti		goto rej;
2428121934Sharti
2429121934Sharti	plan = *msg->b_rptr++;
2430121934Sharti	ielen--;
2431121934Sharti
2432121934Sharti	if(!(plan & 0x80)) {
2433121934Sharti		if(ielen == 0)
2434121934Sharti			goto rej;
2435121934Sharti		ielen--;
2436121934Sharti		c = *msg->b_rptr++;
2437121934Sharti
2438121934Sharti		ie->h.present |= UNI_CALLING_SCREEN_P;
2439121934Sharti		ie->pres = (c >> 5) & 0x3;
2440121934Sharti		ie->screen = c & 0x3;
2441121934Sharti
2442121934Sharti		if(!(c & 0x80))
2443121934Sharti			goto rej;
2444121934Sharti	}
2445121934Sharti
2446121934Sharti	if(decode_addr(&ie->addr, ielen, msg, plan))
2447121934Sharti		goto rej;
2448121934Sharti
2449121934Sharti	IE_END(CALLING);
2450121934Sharti}
2451121934Sharti
2452121934Sharti/**********************************************************************/
2453121934Sharti
2454121934ShartiDEF_IE_PRINT(itu, callingsub)
2455121934Sharti{
2456121934Sharti	if(uni_print_iehdr("callingsub", &ie->h, cx))
2457121934Sharti		return;
2458121934Sharti	print_addrsub(cx, &ie->addr);
2459121934Sharti	uni_print_ieend(cx);
2460121934Sharti}
2461121934Sharti
2462121934ShartiDEF_IE_CHECK(itu, callingsub)
2463121934Sharti{
2464228554Sdim	UNUSED(cx);
2465121934Sharti
2466121934Sharti	if(check_subaddr(&ie->addr))
2467121934Sharti		return -1;
2468121934Sharti	return 0;
2469121934Sharti}
2470121934Sharti
2471121934ShartiDEF_IE_ENCODE(itu, callingsub)
2472121934Sharti{
2473121934Sharti	START_IE(callingsub, UNI_IE_CALLINGSUB, 21);
2474121934Sharti	encode_subaddr(msg, &ie->addr);
2475121934Sharti	SET_IE_LEN(msg);
2476121934Sharti	return 0;
2477121934Sharti}
2478121934Sharti
2479121934ShartiDEF_IE_DECODE(itu, callingsub)
2480121934Sharti{
2481121934Sharti	u_char c;
2482121934Sharti
2483121934Sharti	IE_START(;);
2484121934Sharti
2485121934Sharti	if(ielen > 21)
2486121934Sharti		goto rej;
2487121934Sharti
2488121934Sharti	c = *msg->b_rptr++;
2489121934Sharti	ielen--;
2490121934Sharti
2491121934Sharti	if(decode_subaddr(&ie->addr, ielen, msg, c))
2492121934Sharti		goto rej;
2493121934Sharti
2494121934Sharti	IE_END(CALLINGSUB);
2495121934Sharti}
2496121934Sharti
2497121934Sharti/**********************************************************************/
2498121934Sharti
2499121934ShartiDEF_IE_PRINT(itu, conned)
2500121934Sharti{
2501121934Sharti	if(uni_print_iehdr("conned", &ie->h, cx))
2502121934Sharti		return;
2503121934Sharti	print_addr(cx, &ie->addr);
2504121934Sharti
2505121934Sharti	if(ie->h.present & UNI_CONNED_SCREEN_P) {
2506121934Sharti		uni_print_tbl("screening", ie->screen, screen_tbl, cx);
2507121934Sharti		uni_print_tbl("presentation", ie->pres, pres_tbl, cx);
2508121934Sharti	}
2509121934Sharti
2510121934Sharti	uni_print_ieend(cx);
2511121934Sharti}
2512121934Sharti
2513121934ShartiDEF_IE_CHECK(itu, conned)
2514121934Sharti{
2515228554Sdim	UNUSED(cx);
2516121934Sharti
2517121934Sharti	if(check_addr(&ie->addr))
2518121934Sharti		return -1;
2519121934Sharti
2520121934Sharti	if(ie->h.present & UNI_CONNED_SCREEN_P)
2521121934Sharti		if(check_screen(ie->screen, ie->pres))
2522121934Sharti			return -1;
2523121934Sharti	return 0;
2524121934Sharti}
2525121934Sharti
2526121934ShartiDEF_IE_ENCODE(itu, conned)
2527121934Sharti{
2528121934Sharti	START_IE(conned, UNI_IE_CONNED, 22);
2529121934Sharti	encode_addr(msg, &ie->addr, ie->h.present & UNI_CONNED_SCREEN_P, ie->screen, ie->pres, IE_ISERROR(*ie));
2530121934Sharti	SET_IE_LEN(msg);
2531121934Sharti	return 0;
2532121934Sharti}
2533121934Sharti
2534121934ShartiDEF_IE_DECODE(itu, conned)
2535121934Sharti{
2536121934Sharti	u_char c, plan;
2537121934Sharti
2538121934Sharti	IE_START(;);
2539121934Sharti
2540121934Sharti	if(ielen > 22 || ielen < 1)
2541121934Sharti		goto rej;
2542121934Sharti
2543121934Sharti	plan = *msg->b_rptr++;
2544121934Sharti	ielen--;
2545121934Sharti
2546121934Sharti	if(!(plan & 0x80)) {
2547121934Sharti		if(ielen == 0)
2548121934Sharti			goto rej;
2549121934Sharti		ielen--;
2550121934Sharti		c = *msg->b_rptr++;
2551121934Sharti
2552121934Sharti		ie->h.present |= UNI_CONNED_SCREEN_P;
2553121934Sharti		ie->pres = (c >> 5) & 0x3;
2554121934Sharti		ie->screen = c & 0x3;
2555121934Sharti
2556121934Sharti		if(!(c & 0x80))
2557121934Sharti			goto rej;
2558121934Sharti	}
2559121934Sharti
2560121934Sharti	if(decode_addr(&ie->addr, ielen, msg, plan))
2561121934Sharti		goto rej;
2562121934Sharti
2563121934Sharti	IE_END(CONNED);
2564121934Sharti}
2565121934Sharti
2566121934Sharti/**********************************************************************/
2567121934Sharti
2568121934ShartiDEF_IE_PRINT(itu, connedsub)
2569121934Sharti{
2570121934Sharti	if(uni_print_iehdr("connedsub", &ie->h, cx))
2571121934Sharti		return;
2572121934Sharti	print_addrsub(cx, &ie->addr);
2573121934Sharti	uni_print_ieend(cx);
2574121934Sharti}
2575121934Sharti
2576121934ShartiDEF_IE_CHECK(itu, connedsub)
2577121934Sharti{
2578228554Sdim	UNUSED(cx);
2579121934Sharti
2580121934Sharti	if(check_subaddr(&ie->addr))
2581121934Sharti		return -1;
2582121934Sharti	return 0;
2583121934Sharti}
2584121934Sharti
2585121934ShartiDEF_IE_ENCODE(itu, connedsub)
2586121934Sharti{
2587121934Sharti	START_IE(connedsub, UNI_IE_CONNEDSUB, 21);
2588121934Sharti	encode_subaddr(msg, &ie->addr);
2589121934Sharti	SET_IE_LEN(msg);
2590121934Sharti	return 0;
2591121934Sharti}
2592121934Sharti
2593121934ShartiDEF_IE_DECODE(itu, connedsub)
2594121934Sharti{
2595121934Sharti	u_char c;
2596121934Sharti
2597121934Sharti	IE_START(;);
2598121934Sharti
2599121934Sharti	if(ielen > 21)
2600121934Sharti		goto rej;
2601121934Sharti
2602121934Sharti	c = *msg->b_rptr++;
2603121934Sharti	ielen--;
2604121934Sharti
2605121934Sharti	if(decode_subaddr(&ie->addr, ielen, msg, c))
2606121934Sharti		goto rej;
2607121934Sharti
2608121934Sharti	IE_END(CONNEDSUB);
2609121934Sharti}
2610121934Sharti
2611121934Sharti/*********************************************************************
2612121934Sharti *
2613121934Sharti * Endpoint reference.
2614121934Sharti *
2615121934Sharti * References for this IE are:
2616121934Sharti *
2617121934Sharti *  Q.2971 p.  14
2618121934Sharti *
2619121934Sharti * Only ITU-T coding allowed.
2620121934Sharti */
2621121934Sharti
2622121934ShartiDEF_IE_PRINT(itu, epref)
2623121934Sharti{
2624121934Sharti	if(uni_print_iehdr("epref", &ie->h, cx))
2625121934Sharti		return;
2626121934Sharti	uni_print_entry(cx, "epref", "(%u,%u)", ie->flag, ie->epref);
2627121934Sharti	uni_print_ieend(cx);
2628121934Sharti}
2629121934Sharti
2630121934ShartiDEF_IE_CHECK(itu, epref)
2631121934Sharti{
2632228554Sdim	UNUSED(cx);
2633121934Sharti
2634121934Sharti	if(ie->epref >= (2<<15))
2635121934Sharti		return -1;
2636121934Sharti
2637121934Sharti	return 0;
2638121934Sharti}
2639121934Sharti
2640121934ShartiDEF_IE_ENCODE(itu, epref)
2641121934Sharti{
2642121934Sharti	START_IE(epref, UNI_IE_EPREF, 3);
2643121934Sharti
2644121934Sharti	if (IE_ISERROR(*ie))
2645121934Sharti		APP_BYTE(msg, 0xff);
2646121934Sharti	else
2647121934Sharti		APP_BYTE(msg, 0);
2648121934Sharti	APP_BYTE(msg, (ie->flag << 7) | ((ie->epref >> 8) & 0x7f));
2649121934Sharti	APP_BYTE(msg, (ie->epref & 0xff));
2650121934Sharti
2651121934Sharti	SET_IE_LEN(msg);
2652121934Sharti	return 0;
2653121934Sharti}
2654121934Sharti
2655121934ShartiDEF_IE_DECODE(itu, epref)
2656121934Sharti{
2657121934Sharti	u_char c;
2658121934Sharti
2659121934Sharti	IE_START(;);
2660121934Sharti
2661121934Sharti	if(ielen != 3)
2662121934Sharti		goto rej;
2663121934Sharti	if(*msg->b_rptr++ != 0)
2664121934Sharti		goto rej;
2665121934Sharti
2666121934Sharti	c = *msg->b_rptr++;
2667121934Sharti	ie->flag = (c & 0x80) ? 1 : 0;
2668121934Sharti	ie->epref = (c & 0x7f) << 8;
2669121934Sharti	ie->epref |= *msg->b_rptr++;
2670121934Sharti
2671121934Sharti	IE_END(EPREF);
2672121934Sharti}
2673121934Sharti
2674121934Sharti/*********************************************************************
2675121934Sharti *
2676121934Sharti * Endpoint state.
2677121934Sharti *
2678121934Sharti * References for this IE are:
2679121934Sharti *
2680121934Sharti *  Q.2971 pp. 14...15
2681121934Sharti *
2682121934Sharti * Only ITU-T coding allowed.
2683121934Sharti */
2684121934Sharti
2685121934ShartiDEF_IE_PRINT(itu, epstate)
2686121934Sharti{
2687121934Sharti	static const struct uni_print_tbl tbl[] = {
2688121934Sharti		MKT(UNI_EPSTATE_NULL,		null),
2689121934Sharti		MKT(UNI_EPSTATE_ADD_INIT,	add-initiated),
2690121934Sharti		MKT(UNI_EPSTATE_ALERT_DLVD,	alerting-delivered),
2691121934Sharti		MKT(UNI_EPSTATE_ADD_RCVD,	add-received),
2692121934Sharti		MKT(UNI_EPSTATE_ALERT_RCVD,	alerting-received),
2693121934Sharti		MKT(UNI_EPSTATE_ACTIVE,		active),
2694121934Sharti		MKT(UNI_EPSTATE_DROP_INIT,	drop-initiated),
2695121934Sharti		MKT(UNI_EPSTATE_DROP_RCVD,	drop-received),
2696121934Sharti		EOT()
2697121934Sharti	};
2698121934Sharti
2699121934Sharti	if(uni_print_iehdr("epstate", &ie->h, cx))
2700121934Sharti		return;
2701121934Sharti	uni_print_tbl("state", ie->state, tbl, cx);
2702121934Sharti	uni_print_ieend(cx);
2703121934Sharti}
2704121934Sharti
2705121934ShartiDEF_IE_CHECK(itu, epstate)
2706121934Sharti{
2707228554Sdim	UNUSED(cx);
2708121934Sharti
2709121934Sharti	switch(ie->state) {
2710121934Sharti	  default:
2711121934Sharti		return -1;
2712121934Sharti
2713121934Sharti	  case UNI_EPSTATE_NULL:
2714121934Sharti	  case UNI_EPSTATE_ADD_INIT:
2715121934Sharti	  case UNI_EPSTATE_ALERT_DLVD:
2716121934Sharti	  case UNI_EPSTATE_ADD_RCVD:
2717121934Sharti	  case UNI_EPSTATE_ALERT_RCVD:
2718121934Sharti	  case UNI_EPSTATE_DROP_INIT:
2719121934Sharti	  case UNI_EPSTATE_DROP_RCVD:
2720121934Sharti	  case UNI_EPSTATE_ACTIVE:
2721121934Sharti		break;
2722121934Sharti	}
2723121934Sharti
2724121934Sharti	return 0;
2725121934Sharti}
2726121934Sharti
2727121934ShartiDEF_IE_ENCODE(itu, epstate)
2728121934Sharti{
2729121934Sharti	START_IE(epstate, UNI_IE_EPSTATE, 1);
2730121934Sharti
2731121934Sharti	APP_BYTE(msg, ie->state);
2732121934Sharti
2733121934Sharti	SET_IE_LEN(msg);
2734121934Sharti	return 0;
2735121934Sharti}
2736121934Sharti
2737121934ShartiDEF_IE_DECODE(itu, epstate)
2738121934Sharti{
2739121934Sharti	IE_START(;);
2740121934Sharti
2741121934Sharti	if(ielen != 1)
2742121934Sharti		goto rej;
2743121934Sharti
2744121934Sharti	ie->state = *msg->b_rptr++ & 0x3f;
2745121934Sharti
2746121934Sharti	IE_END(EPSTATE);
2747121934Sharti}
2748121934Sharti
2749121934Sharti/*********************************************************************
2750121934Sharti *
2751121934Sharti * ATM adaptation layer parameters
2752121934Sharti *
2753121934Sharti * References for this IE are:
2754121934Sharti *
2755121934Sharti *  Q.2931 pp. 43...49
2756121934Sharti *  Q.2931 Amd 2
2757121934Sharti *  UNI4.0 p.  9
2758121934Sharti *
2759121934Sharti * UNI4.0 states, that AAL2 is not supported. However we keep it. No
2760121934Sharti * parameters are associated with AAL2.
2761121934Sharti *
2762121934Sharti * Amd2 not checked. XXX
2763121934Sharti *
2764121934Sharti * Only ITU-T coding allowed.
2765121934Sharti */
2766121934ShartiDEF_IE_PRINT(itu, aal)
2767121934Sharti{
2768121934Sharti	static const struct uni_print_tbl aal_tbl[] = {
2769121934Sharti		MKT(UNI_AAL_0,			VOICE),
2770121934Sharti		MKT(UNI_AAL_1,			1),
2771121934Sharti		MKT(UNI_AAL_2,			2),
2772121934Sharti		MKT(UNI_AAL_4,			3/4),
2773121934Sharti		MKT(UNI_AAL_5,			5),
2774121934Sharti		MKT(UNI_AAL_USER,		USER),
2775121934Sharti		EOT()
2776121934Sharti	};
2777121934Sharti	static const struct uni_print_tbl subtype_tbl[] = {
2778121934Sharti		MKT(UNI_AAL1_SUB_NULL,		null),
2779121934Sharti		MKT(UNI_AAL1_SUB_VOICE,		voice),
2780121934Sharti		MKT(UNI_AAL1_SUB_CIRCUIT,	circuit),
2781121934Sharti		MKT(UNI_AAL1_SUB_HQAUDIO,	hqaudio),
2782121934Sharti		MKT(UNI_AAL1_SUB_VIDEO,		video),
2783121934Sharti		EOT()
2784121934Sharti	};
2785121934Sharti	static const struct uni_print_tbl cbr_rate_tbl[] = {
2786121934Sharti		MKT(UNI_AAL1_CBR_64,		64),
2787121934Sharti		MKT(UNI_AAL1_CBR_1544,		1544(DS1)),
2788121934Sharti		MKT(UNI_AAL1_CBR_6312,		6312(DS2)),
2789121934Sharti		MKT(UNI_AAL1_CBR_32064,		32064),
2790121934Sharti		MKT(UNI_AAL1_CBR_44736,		44736(DS3)),
2791121934Sharti		MKT(UNI_AAL1_CBR_97728,		97728),
2792121934Sharti		MKT(UNI_AAL1_CBR_2048,		2048(E1)),
2793121934Sharti		MKT(UNI_AAL1_CBR_8448,		8448(E2)),
2794121934Sharti		MKT(UNI_AAL1_CBR_34368,		34368(E3)),
2795121934Sharti		MKT(UNI_AAL1_CBR_139264,	139264),
2796121934Sharti		MKT(UNI_AAL1_CBR_N64,		Nx64),
2797121934Sharti		MKT(UNI_AAL1_CBR_N8,		Nx8),
2798121934Sharti		EOT()
2799121934Sharti	};
2800121934Sharti	static const struct uni_print_tbl screc_tbl[] = {
2801121934Sharti		MKT(UNI_AAL1_SCREC_NULL,	null),
2802121934Sharti		MKT(UNI_AAL1_SCREC_SRTS,	srts),
2803121934Sharti		MKT(UNI_AAL1_SCREC_ACLK,	aclk),
2804121934Sharti		EOT()
2805121934Sharti	};
2806121934Sharti	static const struct uni_print_tbl ecm_tbl[] = {
2807121934Sharti		MKT(UNI_AAL1_ECM_NULL,		null),
2808121934Sharti		MKT(UNI_AAL1_ECM_LOSS,		loss),
2809121934Sharti		MKT(UNI_AAL1_ECM_DELAY,		delay),
2810121934Sharti		EOT()
2811121934Sharti	};
2812121934Sharti	static const struct uni_print_tbl sscs_tbl[] = {
2813121934Sharti		MKT(UNI_AAL_SSCS_NULL,		null),
2814121934Sharti		MKT(UNI_AAL_SSCS_SSCOPA,	sscopa),
2815121934Sharti		MKT(UNI_AAL_SSCS_SSCOPU,	sscopu),
2816121934Sharti		MKT(UNI_AAL_SSCS_FRAME,		frame),
2817121934Sharti		EOT()
2818121934Sharti	};
2819121934Sharti
2820121934Sharti	if(uni_print_iehdr("aal", &ie->h, cx))
2821121934Sharti		return;
2822121934Sharti	uni_print_tbl("type", ie->type, aal_tbl, cx);
2823121934Sharti
2824121934Sharti	switch(ie->type) {
2825121934Sharti
2826121934Sharti	  case UNI_AAL_0:
2827121934Sharti		uni_print_push_prefix("0", cx);
2828121934Sharti		cx->indent++;
2829121934Sharti		break;
2830121934Sharti
2831121934Sharti	  case UNI_AAL_2:
2832121934Sharti		uni_print_push_prefix("2", cx);
2833121934Sharti		cx->indent++;
2834121934Sharti		break;
2835121934Sharti
2836121934Sharti	  case UNI_AAL_1:
2837121934Sharti		uni_print_push_prefix("1", cx);
2838121934Sharti		cx->indent++;
2839121934Sharti		uni_print_tbl("subtype", ie->u.aal1.subtype, subtype_tbl, cx);
2840121934Sharti		uni_print_tbl("cbr_rate", ie->u.aal1.cbr_rate, cbr_rate_tbl, cx);
2841121934Sharti		if(ie->h.present & UNI_AAL1_MULT_P)
2842121934Sharti			uni_print_entry(cx, "mult", "%u", ie->u.aal1.mult);
2843121934Sharti		if(ie->h.present & UNI_AAL1_SCREC_P)
2844121934Sharti			uni_print_tbl("screc", ie->u.aal1.screc, screc_tbl, cx);
2845121934Sharti		if(ie->h.present & UNI_AAL1_ECM_P)
2846121934Sharti			uni_print_tbl("ecm", ie->u.aal1.ecm, ecm_tbl, cx);
2847121934Sharti		if(ie->h.present & UNI_AAL1_BSIZE_P)
2848121934Sharti			uni_print_entry(cx, "bsize", "%u", ie->u.aal1.bsize);
2849121934Sharti		if(ie->h.present & UNI_AAL1_PART_P)
2850121934Sharti			uni_print_entry(cx, "part", "%u", ie->u.aal1.part);
2851121934Sharti		break;
2852121934Sharti
2853121934Sharti	  case UNI_AAL_4:
2854121934Sharti		uni_print_push_prefix("4", cx);
2855121934Sharti		cx->indent++;
2856121934Sharti		if(ie->h.present & UNI_AAL4_CPCS_P)
2857121934Sharti			uni_print_entry(cx, "cpcs", "(%u,%u)", ie->u.aal4.fwd_cpcs,
2858121934Sharti				ie->u.aal4.bwd_cpcs);
2859121934Sharti		if(ie->h.present & UNI_AAL4_MID_P)
2860121934Sharti			uni_print_entry(cx, "mid", "(%u,%u)", ie->u.aal4.mid_low,
2861121934Sharti				ie->u.aal4.mid_high);
2862121934Sharti		if(ie->h.present & UNI_AAL4_SSCS_P)
2863121934Sharti			uni_print_tbl("sscs", ie->u.aal4.sscs, sscs_tbl, cx);
2864121934Sharti		break;
2865121934Sharti
2866121934Sharti	  case UNI_AAL_5:
2867121934Sharti		uni_print_push_prefix("5", cx);
2868121934Sharti		cx->indent++;
2869121934Sharti		if(ie->h.present & UNI_AAL5_CPCS_P)
2870121934Sharti			uni_print_entry(cx, "cpcs", "(%u,%u)", ie->u.aal5.fwd_cpcs,
2871121934Sharti				ie->u.aal5.bwd_cpcs);
2872121934Sharti		if(ie->h.present & UNI_AAL5_SSCS_P)
2873121934Sharti			uni_print_tbl("sscs", ie->u.aal5.sscs, sscs_tbl, cx);
2874121934Sharti		break;
2875121934Sharti
2876121934Sharti	  case UNI_AAL_USER:
2877121934Sharti		uni_print_push_prefix("user", cx);
2878121934Sharti		cx->indent++;
2879121934Sharti		if(ie->u.aalu.len > 4) {
2880121934Sharti			uni_print_entry(cx, "info", "ERROR(len=%u)", ie->u.aalu.len);
2881121934Sharti		} else {
2882121934Sharti			u_int i;
2883121934Sharti
2884121934Sharti			uni_print_entry(cx, "info", "(");
2885121934Sharti			for(i = 0; i < ie->u.aalu.len; i++)
2886121934Sharti				uni_printf(cx, "%s%u", !i?"":",", ie->u.aalu.user[i]);
2887121934Sharti			uni_printf(cx, ")");
2888121934Sharti		}
2889121934Sharti		break;
2890121934Sharti	}
2891121934Sharti	cx->indent--;
2892121934Sharti	uni_print_pop_prefix(cx);
2893121934Sharti	uni_print_eol(cx);
2894121934Sharti
2895121934Sharti	uni_print_ieend(cx);
2896121934Sharti}
2897121934Sharti
2898121934ShartiDEF_IE_CHECK(itu, aal)
2899121934Sharti{
2900228554Sdim	UNUSED(cx);
2901121934Sharti
2902121934Sharti	if(ie->type == UNI_AAL_0) {
2903121934Sharti		;
2904121934Sharti	} else if(ie->type == UNI_AAL_1) {
2905121934Sharti		switch(ie->u.aal1.subtype) {
2906121934Sharti
2907121934Sharti		  default:
2908121934Sharti			return -1;
2909121934Sharti
2910121934Sharti		  case UNI_AAL1_SUB_NULL:
2911121934Sharti		  case UNI_AAL1_SUB_VOICE:
2912121934Sharti		  case UNI_AAL1_SUB_CIRCUIT:
2913121934Sharti		  case UNI_AAL1_SUB_HQAUDIO:
2914121934Sharti		  case UNI_AAL1_SUB_VIDEO:
2915121934Sharti			break;
2916121934Sharti		}
2917121934Sharti		switch(ie->u.aal1.cbr_rate) {
2918121934Sharti
2919121934Sharti		  default:
2920121934Sharti			return -1;
2921121934Sharti
2922121934Sharti		  case UNI_AAL1_CBR_64:
2923121934Sharti		  case UNI_AAL1_CBR_1544:
2924121934Sharti		  case UNI_AAL1_CBR_6312:
2925121934Sharti		  case UNI_AAL1_CBR_32064:
2926121934Sharti		  case UNI_AAL1_CBR_44736:
2927121934Sharti		  case UNI_AAL1_CBR_97728:
2928121934Sharti		  case UNI_AAL1_CBR_2048:
2929121934Sharti		  case UNI_AAL1_CBR_8448:
2930121934Sharti		  case UNI_AAL1_CBR_34368:
2931121934Sharti		  case UNI_AAL1_CBR_139264:
2932121934Sharti			if((ie->h.present & UNI_AAL1_MULT_P))
2933121934Sharti				return -1;
2934121934Sharti			break;
2935121934Sharti
2936121934Sharti		  case UNI_AAL1_CBR_N64:
2937121934Sharti			if(!(ie->h.present & UNI_AAL1_MULT_P))
2938121934Sharti				return -1;
2939121934Sharti			if(ie->u.aal1.mult < 2)
2940121934Sharti				return -1;
2941121934Sharti			break;
2942121934Sharti
2943121934Sharti		  case UNI_AAL1_CBR_N8:
2944121934Sharti			if(!(ie->h.present & UNI_AAL1_MULT_P))
2945121934Sharti				return -1;
2946121934Sharti			if(ie->u.aal1.mult == 0 || ie->u.aal1.mult > 7)
2947121934Sharti				return -1;
2948121934Sharti			break;
2949121934Sharti		}
2950121934Sharti		if(ie->h.present & UNI_AAL1_SCREC_P) {
2951121934Sharti			switch(ie->u.aal1.screc) {
2952121934Sharti
2953121934Sharti			  default:
2954121934Sharti				return -1;
2955121934Sharti
2956121934Sharti			  case UNI_AAL1_SCREC_NULL:
2957121934Sharti			  case UNI_AAL1_SCREC_SRTS:
2958121934Sharti			  case UNI_AAL1_SCREC_ACLK:
2959121934Sharti				break;
2960121934Sharti			}
2961121934Sharti		}
2962121934Sharti		if(ie->h.present & UNI_AAL1_ECM_P) {
2963121934Sharti			switch(ie->u.aal1.ecm) {
2964121934Sharti
2965121934Sharti			  default:
2966121934Sharti				return -1;
2967121934Sharti
2968121934Sharti			  case UNI_AAL1_ECM_NULL:
2969121934Sharti			  case UNI_AAL1_ECM_LOSS:
2970121934Sharti			  case UNI_AAL1_ECM_DELAY:
2971121934Sharti				break;
2972121934Sharti			}
2973121934Sharti		}
2974121934Sharti		if(ie->h.present & UNI_AAL1_BSIZE_P) {
2975121934Sharti			if(ie->u.aal1.bsize == 0)
2976121934Sharti				return -1;
2977121934Sharti		}
2978121934Sharti		if(ie->h.present & UNI_AAL1_PART_P) {
2979121934Sharti			if(ie->u.aal1.part == 0 || ie->u.aal1.part > 47)
2980121934Sharti				return -1;
2981121934Sharti		}
2982121934Sharti
2983121934Sharti	} else if(ie->type == UNI_AAL_2) {
2984121934Sharti		;
2985121934Sharti
2986121934Sharti	} else if(ie->type == UNI_AAL_4) {
2987121934Sharti		if(ie->h.present & UNI_AAL4_MID_P) {
2988121934Sharti			if(ie->u.aal4.mid_low >= 1024)
2989121934Sharti				return -1;
2990121934Sharti			if(ie->u.aal4.mid_high >= 1024)
2991121934Sharti				return -1;
2992121934Sharti			if(ie->u.aal4.mid_low > ie->u.aal4.mid_high)
2993121934Sharti				return -1;
2994121934Sharti		}
2995121934Sharti		if(ie->h.present & UNI_AAL4_SSCS_P) {
2996121934Sharti			switch(ie->u.aal4.sscs) {
2997121934Sharti
2998121934Sharti			  default:
2999121934Sharti				return -1;
3000121934Sharti
3001121934Sharti			  case UNI_AAL_SSCS_NULL:
3002121934Sharti			  case UNI_AAL_SSCS_SSCOPA:
3003121934Sharti			  case UNI_AAL_SSCS_SSCOPU:
3004121934Sharti			  case UNI_AAL_SSCS_FRAME:
3005121934Sharti				break;
3006121934Sharti			}
3007121934Sharti		}
3008121934Sharti
3009121934Sharti	} else if(ie->type == UNI_AAL_5) {
3010121934Sharti		if(ie->h.present & UNI_AAL5_SSCS_P) {
3011121934Sharti			switch(ie->u.aal5.sscs) {
3012121934Sharti
3013121934Sharti			  default:
3014121934Sharti				return -1;
3015121934Sharti
3016121934Sharti			  case UNI_AAL_SSCS_NULL:
3017121934Sharti			  case UNI_AAL_SSCS_SSCOPA:
3018121934Sharti			  case UNI_AAL_SSCS_SSCOPU:
3019121934Sharti			  case UNI_AAL_SSCS_FRAME:
3020121934Sharti				break;
3021121934Sharti			}
3022121934Sharti		}
3023121934Sharti
3024121934Sharti	} else if(ie->type == UNI_AAL_USER) {
3025121934Sharti		if(ie->u.aalu.len > 4)
3026121934Sharti			return -1;
3027121934Sharti
3028121934Sharti	} else
3029121934Sharti		return -1;
3030121934Sharti
3031121934Sharti	return 0;
3032121934Sharti}
3033121934Sharti
3034121934ShartiDEF_IE_ENCODE(itu, aal)
3035121934Sharti{
3036121934Sharti	START_IE(aal, UNI_IE_AAL, 16);
3037121934Sharti
3038121934Sharti	APP_BYTE(msg, ie->type);
3039121934Sharti	switch(ie->type) {
3040121934Sharti
3041121934Sharti	  case UNI_AAL_0:
3042121934Sharti		break;
3043121934Sharti
3044121934Sharti	  case UNI_AAL_1:
3045121934Sharti		APP_SUB_BYTE(msg,
3046121934Sharti			UNI_AAL_SUB_ID, ie->u.aal1.subtype);
3047121934Sharti		APP_SUB_BYTE(msg,
3048121934Sharti			UNI_AAL_CBR_ID, ie->u.aal1.cbr_rate);
3049121934Sharti		APP_OPT_16BIT(msg, ie->h.present, UNI_AAL1_MULT_P,
3050121934Sharti			UNI_AAL_MULT_ID, ie->u.aal1.mult);
3051121934Sharti		APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_SCREC_P,
3052121934Sharti			UNI_AAL_SCREC_ID, ie->u.aal1.screc);
3053121934Sharti		APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_ECM_P,
3054121934Sharti			UNI_AAL_ECM_ID, ie->u.aal1.ecm);
3055121934Sharti		APP_OPT_16BIT(msg, ie->h.present, UNI_AAL1_BSIZE_P,
3056121934Sharti			UNI_AAL_BSIZE_ID, ie->u.aal1.bsize);
3057121934Sharti		APP_OPT_BYTE(msg, ie->h.present, UNI_AAL1_PART_P,
3058121934Sharti			UNI_AAL_PART_ID, ie->u.aal1.part);
3059121934Sharti		break;
3060121934Sharti
3061121934Sharti	  case UNI_AAL_2:
3062121934Sharti		break;
3063121934Sharti
3064121934Sharti	  case UNI_AAL_4:
3065121934Sharti		if(ie->h.present & UNI_AAL4_CPCS_P) {
3066121934Sharti			APP_SUB_16BIT(msg,
3067121934Sharti				UNI_AAL_FWDCPCS_ID, ie->u.aal4.fwd_cpcs);
3068121934Sharti			APP_SUB_16BIT(msg,
3069121934Sharti				UNI_AAL_BWDCPCS_ID, ie->u.aal4.bwd_cpcs);
3070121934Sharti		}
3071121934Sharti		if(ie->h.present & UNI_AAL4_MID_P) {
3072121934Sharti			APP_BYTE(msg, UNI_AAL_MID_ID);
3073121934Sharti			APP_16BIT(msg, ie->u.aal4.mid_low);
3074121934Sharti			APP_16BIT(msg, ie->u.aal4.mid_high);
3075121934Sharti		}
3076121934Sharti		APP_OPT_BYTE(msg, ie->h.present, UNI_AAL4_SSCS_P,
3077121934Sharti			UNI_AAL_SSCS_ID, ie->u.aal4.sscs);
3078121934Sharti		break;
3079121934Sharti
3080121934Sharti	  case UNI_AAL_5:
3081121934Sharti		if(ie->h.present & UNI_AAL5_CPCS_P) {
3082121934Sharti			APP_SUB_16BIT(msg,
3083121934Sharti				UNI_AAL_FWDCPCS_ID, ie->u.aal5.fwd_cpcs);
3084121934Sharti			APP_SUB_16BIT(msg,
3085121934Sharti				UNI_AAL_BWDCPCS_ID, ie->u.aal5.bwd_cpcs);
3086121934Sharti		}
3087121934Sharti		APP_OPT_BYTE(msg, ie->h.present, UNI_AAL5_SSCS_P,
3088121934Sharti			UNI_AAL_SSCS_ID, ie->u.aal5.sscs);
3089121934Sharti		break;
3090121934Sharti
3091121934Sharti	  case UNI_AAL_USER:
3092121934Sharti		APP_BUF(msg, ie->u.aalu.user, ie->u.aalu.len);
3093121934Sharti		break;
3094121934Sharti
3095121934Sharti	  default:
3096121934Sharti		return -1;
3097121934Sharti	}
3098121934Sharti
3099121934Sharti	SET_IE_LEN(msg);
3100121934Sharti	return 0;
3101121934Sharti}
3102121934Sharti
3103121934Sharti/*
3104121934Sharti * XXX What should we do with multiple subtype occurences? Ignore
3105121934Sharti * or reject. Currently we reject.
3106121934Sharti */
3107121934Shartistatic int
3108121934Shartidecode_aal_1(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3109121934Sharti{
3110121934Sharti	int subtype_p, cbr_p;
3111121934Sharti
3112121934Sharti	subtype_p = cbr_p = 0;
3113121934Sharti
3114121934Sharti	while(ielen-- > 0) {
3115121934Sharti		switch(*msg->b_rptr++) {
3116121934Sharti
3117121934Sharti		  case UNI_AAL_SUB_ID:
3118121934Sharti			if(ielen == 0 || subtype_p)
3119121934Sharti				return -1;
3120121934Sharti			ielen--;
3121121934Sharti			subtype_p = 1;
3122121934Sharti			ie->u.aal1.subtype = *msg->b_rptr++;
3123121934Sharti			break;
3124121934Sharti
3125121934Sharti		  case UNI_AAL_CBR_ID:
3126121934Sharti			if(ielen == 0 || cbr_p)
3127121934Sharti				return -1;
3128121934Sharti			ielen--;
3129121934Sharti			cbr_p = 1;
3130121934Sharti			ie->u.aal1.cbr_rate = *msg->b_rptr++;
3131121934Sharti			break;
3132121934Sharti
3133121934Sharti		  case UNI_AAL_MULT_ID:
3134121934Sharti			if(ielen < 2 || (ie->h.present & UNI_AAL1_MULT_P))
3135121934Sharti				return -1;
3136121934Sharti			ielen -= 2;
3137121934Sharti			ie->h.present |= UNI_AAL1_MULT_P;
3138121934Sharti			ie->u.aal1.mult  = *msg->b_rptr++ << 8;
3139121934Sharti			ie->u.aal1.mult |= *msg->b_rptr++;
3140121934Sharti			break;
3141121934Sharti
3142121934Sharti		  case UNI_AAL_SCREC_ID:
3143121934Sharti			if(ielen == 0 || (ie->h.present & UNI_AAL1_SCREC_P))
3144121934Sharti				return -1;
3145121934Sharti			ielen--;
3146121934Sharti			ie->h.present |= UNI_AAL1_SCREC_P;
3147121934Sharti			ie->u.aal1.screc = *msg->b_rptr++;
3148121934Sharti			break;
3149121934Sharti
3150121934Sharti		  case UNI_AAL_ECM_ID:
3151121934Sharti			if(ielen == 0 || (ie->h.present & UNI_AAL1_ECM_P))
3152121934Sharti				return -1;
3153121934Sharti			ielen--;
3154121934Sharti			ie->h.present |= UNI_AAL1_ECM_P;
3155121934Sharti			ie->u.aal1.ecm = *msg->b_rptr++;
3156121934Sharti			break;
3157121934Sharti
3158121934Sharti		  case UNI_AAL_BSIZE_ID:
3159121934Sharti			if(ielen < 2 || (ie->h.present & UNI_AAL1_BSIZE_P))
3160121934Sharti				return -1;
3161121934Sharti			ielen -= 2;
3162121934Sharti			ie->h.present |= UNI_AAL1_BSIZE_P;
3163121934Sharti			ie->u.aal1.bsize  = *msg->b_rptr++ << 8;
3164121934Sharti			ie->u.aal1.bsize |= *msg->b_rptr++;
3165121934Sharti			break;
3166121934Sharti
3167121934Sharti		  case UNI_AAL_PART_ID:
3168121934Sharti			if(ielen == 0 || (ie->h.present & UNI_AAL1_PART_P))
3169121934Sharti				return -1;
3170121934Sharti			ielen--;
3171121934Sharti			ie->h.present |= UNI_AAL1_PART_P;
3172121934Sharti			ie->u.aal1.part = *msg->b_rptr++;
3173121934Sharti			break;
3174121934Sharti
3175121934Sharti		  default:
3176121934Sharti			return -1;
3177121934Sharti		}
3178121934Sharti	}
3179121934Sharti	if(!subtype_p || !cbr_p)
3180121934Sharti		return -1;
3181121934Sharti
3182121934Sharti	return 0;
3183121934Sharti}
3184121934Sharti
3185121934Shartistatic int
3186121934Shartidecode_aal_4(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3187121934Sharti{
3188121934Sharti	int fcpcs_p, bcpcs_p;
3189121934Sharti
3190121934Sharti	fcpcs_p = bcpcs_p = 0;
3191121934Sharti
3192121934Sharti	while(ielen-- > 0) {
3193121934Sharti		switch(*msg->b_rptr++) {
3194121934Sharti
3195121934Sharti		  case UNI_AAL_FWDCPCS_ID:
3196121934Sharti			if(ielen < 2 || fcpcs_p)
3197121934Sharti				return -1;
3198121934Sharti			ielen -= 2;
3199121934Sharti			fcpcs_p = 1;
3200121934Sharti			ie->u.aal4.fwd_cpcs  = *msg->b_rptr++ << 8;
3201121934Sharti			ie->u.aal4.fwd_cpcs |= *msg->b_rptr++;
3202121934Sharti			break;
3203121934Sharti
3204121934Sharti		  case UNI_AAL_BWDCPCS_ID:
3205121934Sharti			if(ielen < 2 || bcpcs_p)
3206121934Sharti				return -1;
3207121934Sharti			ielen -= 2;
3208121934Sharti			bcpcs_p = 1;
3209121934Sharti			ie->u.aal4.bwd_cpcs  = *msg->b_rptr++ << 8;
3210121934Sharti			ie->u.aal4.bwd_cpcs |= *msg->b_rptr++;
3211121934Sharti			break;
3212121934Sharti
3213121934Sharti		  case UNI_AAL_MID_ID:
3214121934Sharti			if(ielen < 4 || (ie->h.present & UNI_AAL4_MID_P))
3215121934Sharti				return -1;
3216121934Sharti			ielen -= 4;
3217121934Sharti			ie->h.present |= UNI_AAL4_MID_P;
3218121934Sharti			ie->u.aal4.mid_low  = *msg->b_rptr++ << 8;
3219121934Sharti			ie->u.aal4.mid_low |= *msg->b_rptr++;
3220121934Sharti			ie->u.aal4.mid_high  = *msg->b_rptr++ << 8;
3221121934Sharti			ie->u.aal4.mid_high |= *msg->b_rptr++;
3222121934Sharti			break;
3223121934Sharti
3224121934Sharti		  case UNI_AAL_SSCS_ID:
3225121934Sharti			if(ielen == 0 || (ie->h.present & UNI_AAL4_SSCS_P))
3226121934Sharti				return -1;
3227121934Sharti			ielen--;
3228121934Sharti			ie->h.present |= UNI_AAL4_SSCS_P;
3229121934Sharti			ie->u.aal4.sscs = *msg->b_rptr++;
3230121934Sharti			break;
3231121934Sharti
3232121934Sharti		  default:
3233121934Sharti			return -1;
3234121934Sharti		}
3235121934Sharti	}
3236121934Sharti
3237121934Sharti	if(fcpcs_p ^ bcpcs_p)
3238121934Sharti		return -1;
3239121934Sharti	if(fcpcs_p)
3240121934Sharti		ie->h.present |= UNI_AAL4_CPCS_P;
3241121934Sharti
3242121934Sharti	return 0;
3243121934Sharti}
3244121934Sharti
3245121934Shartistatic int
3246121934Shartidecode_aal_5(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3247121934Sharti{
3248121934Sharti	int fcpcs_p, bcpcs_p;
3249121934Sharti
3250121934Sharti	fcpcs_p = bcpcs_p = 0;
3251121934Sharti
3252121934Sharti	while(ielen-- > 0) {
3253121934Sharti		switch(*msg->b_rptr++) {
3254121934Sharti
3255121934Sharti		  case UNI_AAL_FWDCPCS_ID:
3256121934Sharti			if(ielen < 2 || fcpcs_p)
3257121934Sharti				return -1;
3258121934Sharti			ielen -= 2;
3259121934Sharti			fcpcs_p = 1;
3260121934Sharti			ie->u.aal5.fwd_cpcs  = *msg->b_rptr++ << 8;
3261121934Sharti			ie->u.aal5.fwd_cpcs |= *msg->b_rptr++;
3262121934Sharti			break;
3263121934Sharti
3264121934Sharti		  case UNI_AAL_BWDCPCS_ID:
3265121934Sharti			if(ielen < 2 || bcpcs_p)
3266121934Sharti				return -1;
3267121934Sharti			ielen -= 2;
3268121934Sharti			bcpcs_p = 1;
3269121934Sharti			ie->u.aal5.bwd_cpcs  = *msg->b_rptr++ << 8;
3270121934Sharti			ie->u.aal5.bwd_cpcs |= *msg->b_rptr++;
3271121934Sharti			break;
3272121934Sharti
3273121934Sharti		  case UNI_AAL_SSCS_ID:
3274121934Sharti			if(ielen == 0 || (ie->h.present & UNI_AAL5_SSCS_P))
3275121934Sharti				return -1;
3276121934Sharti			ielen--;
3277121934Sharti			ie->h.present |= UNI_AAL5_SSCS_P;
3278121934Sharti			ie->u.aal5.sscs = *msg->b_rptr++;
3279121934Sharti			break;
3280121934Sharti
3281121934Sharti		  default:
3282121934Sharti			return -1;
3283121934Sharti		}
3284121934Sharti	}
3285121934Sharti
3286121934Sharti	if(fcpcs_p ^ bcpcs_p)
3287121934Sharti		return -1;
3288121934Sharti	if(fcpcs_p)
3289121934Sharti		ie->h.present |= UNI_AAL5_CPCS_P;
3290121934Sharti
3291121934Sharti	return 0;
3292121934Sharti}
3293121934Sharti
3294121934Shartistatic int
3295121934Shartidecode_aal_user(struct uni_ie_aal *ie, struct uni_msg *msg, u_int ielen)
3296121934Sharti{
3297121934Sharti	if(ielen > 4)
3298121934Sharti		return -1;
3299121934Sharti
3300121934Sharti	ie->u.aalu.len = 0;
3301121934Sharti	while(ielen--)
3302121934Sharti		ie->u.aalu.user[ie->u.aalu.len++] = *msg->b_rptr++;
3303121934Sharti
3304121934Sharti	return 0;
3305121934Sharti}
3306121934Sharti
3307121934ShartiDEF_IE_DECODE(itu, aal)
3308121934Sharti{
3309121934Sharti	u_char c;
3310121934Sharti
3311121934Sharti	IE_START(DISC_ACC_ERR(AAL));
3312121934Sharti
3313121934Sharti	if(ielen < 1 || ielen > 21)
3314121934Sharti		goto rej;
3315121934Sharti
3316121934Sharti	c = *msg->b_rptr++;
3317121934Sharti	ielen--;
3318121934Sharti
3319121934Sharti	switch(c) {
3320121934Sharti
3321121934Sharti	  case UNI_AAL_0:
3322121934Sharti		ie->type = c;
3323121934Sharti		break;
3324121934Sharti
3325121934Sharti	  case UNI_AAL_1:
3326121934Sharti		ie->type = c;
3327121934Sharti		if(decode_aal_1(ie, msg, ielen))
3328121934Sharti			goto rej;
3329121934Sharti		break;
3330121934Sharti
3331121934Sharti	  case UNI_AAL_2:
3332121934Sharti		ie->type = c;
3333121934Sharti		break;
3334121934Sharti
3335121934Sharti	  case UNI_AAL_4:
3336121934Sharti		ie->type = c;
3337121934Sharti		if(decode_aal_4(ie, msg, ielen))
3338121934Sharti			goto rej;
3339121934Sharti		break;
3340121934Sharti
3341121934Sharti	  case UNI_AAL_5:
3342121934Sharti		ie->type = c;
3343121934Sharti		if(decode_aal_5(ie, msg, ielen))
3344121934Sharti			goto rej;
3345121934Sharti		break;
3346121934Sharti
3347121934Sharti	  case UNI_AAL_USER:
3348121934Sharti		ie->type = c;
3349121934Sharti		if(decode_aal_user(ie, msg, ielen))
3350121934Sharti			goto rej;
3351121934Sharti		break;
3352121934Sharti
3353121934Sharti	  default:
3354121934Sharti		goto rej;
3355121934Sharti	}
3356121934Sharti
3357121934Sharti	IE_END(AAL);
3358121934Sharti}
3359121934Sharti
3360121934Sharti/*********************************************************************
3361121934Sharti *
3362121934Sharti * Traffic descriptor.
3363121934Sharti * Alternate traffic descriptor.
3364121934Sharti * Minimum traffic descriptor.
3365121934Sharti *
3366121934Sharti * References for this IE are:
3367121934Sharti *
3368121934Sharti *  Q.2931 pp. 49...51
3369121934Sharti *  Q.2961
3370121934Sharti *  Q.2962
3371121934Sharti *  UNI4.0 pp. 9...10, 106...109
3372121934Sharti *
3373121934Sharti * The Q.s specify the coding. UNI4.0 adds frame discard and best-effort.
3374121934Sharti * Appendix in UNI4.0 lists the allowed combinations.
3375121934Sharti *
3376121934Sharti *		  PCR0 PCR1 SCR/MBS0 SCR/MBS1 BE TAG FDISC ABR
3377121934Sharti *  1	CBR.1 	  -    Y    -        -        -  N   Y/N   -
3378121934Sharti *  2	CBR.2 	  -    Y    -        -        -  N   Y/N   -    (*)
3379121934Sharti *  3	CBR.3 	  Y    Y    -        -        -  Y   Y/N   -    (*)
3380121934Sharti *  4	rt-VBR.1  -    Y    -        Y        -  N   Y/N   -
3381121934Sharti *  5	rt-VBR.2  -    Y    Y        -        -  N   Y/N   -
3382121934Sharti *  6	rt-VBR.3  -    Y    Y        -        -  Y   Y/N   -
3383121934Sharti *  7	rt-VBR.4  Y    Y    -        -        -  Y/N Y/N   -    (*)
3384121934Sharti *  8	rt-VBR.5  -    Y    -        -        -  N   Y/N   -    (*)
3385121934Sharti *  9	rt-VBR.6  -    Y    -        Y        -  N   Y/N   -    (*)
3386121934Sharti * 10	nrt-VBR.1 -    Y    -        Y        -  N   Y/N   -
3387121934Sharti * 11	nrt-VBR.2 -    Y    Y        -        -  N   Y/N   -
3388121934Sharti * 12	nrt-VBR.3 -    Y    Y        -        -  Y   Y/N   -
3389121934Sharti * 13	nrt-VBR.4 Y    Y    -        -        -  Y/N Y/N   -	(*)
3390121934Sharti * 14	nrt-VBR.5 -    Y    -        -        -  N   Y/N   -	(*)
3391121934Sharti * 15	nrt-VBR.6 -    Y    -        Y        -  N   Y/N   -	(*)
3392121934Sharti * 16	ABR	  -    Y    -        -        -  N   Y/N   O	(*)
3393121934Sharti * 17	UBR.1	  -    Y    -        -        Y  N   Y/N   -
3394121934Sharti * 18	UBR.2	  -    Y    -        -        Y  Y   Y/N   -
3395121934Sharti *
3396121934Sharti * Allow ITU-T and NET coding, because its not clear, whether the
3397121934Sharti * new fields in UNI4.0 should be used with NET coding or not.
3398121934Sharti * Does not allow for experimental codings yet.
3399121934Sharti */
3400121934Sharti
3401121934Shartistatic void
3402121934Shartiprint_ie_traffic_common(struct unicx *cx, u_int present, struct uni_xtraffic *ie)
3403121934Sharti{
3404121934Sharti	uni_print_entry(cx, "fwd", "(");
3405121934Sharti	if(present & UNI_TRAFFIC_FPCR0_P)
3406121934Sharti		uni_printf(cx, "%u", ie->fpcr0);
3407121934Sharti	uni_putc(',', cx);
3408121934Sharti	if(present & UNI_TRAFFIC_FPCR1_P)
3409121934Sharti		uni_printf(cx, "%u", ie->fpcr1);
3410121934Sharti	uni_putc(',', cx);
3411121934Sharti	if(present & UNI_TRAFFIC_FSCR0_P)
3412121934Sharti		uni_printf(cx, "%u", ie->fscr0);
3413121934Sharti	uni_putc(',', cx);
3414121934Sharti	if(present & UNI_TRAFFIC_FSCR1_P)
3415121934Sharti		uni_printf(cx, "%u", ie->fscr1);
3416121934Sharti	uni_putc(',', cx);
3417121934Sharti	if(present & UNI_TRAFFIC_FMBS0_P)
3418121934Sharti		uni_printf(cx, "%u", ie->fmbs0);
3419121934Sharti	uni_putc(',', cx);
3420121934Sharti	if(present & UNI_TRAFFIC_FMBS1_P)
3421121934Sharti		uni_printf(cx, "%u", ie->fmbs1);
3422121934Sharti	uni_putc(',', cx);
3423121934Sharti	if(present & UNI_TRAFFIC_FABR1_P)
3424121934Sharti		uni_printf(cx, "%u", ie->fabr1);
3425121934Sharti	uni_printf(cx, ")");
3426121934Sharti
3427121934Sharti	uni_print_entry(cx, "bwd", "(");
3428121934Sharti	if(present & UNI_TRAFFIC_BPCR0_P)
3429121934Sharti		uni_printf(cx, "%u", ie->bpcr0);
3430121934Sharti	uni_putc(',', cx);
3431121934Sharti	if(present & UNI_TRAFFIC_BPCR1_P)
3432121934Sharti		uni_printf(cx, "%u", ie->bpcr1);
3433121934Sharti	uni_putc(',', cx);
3434121934Sharti	if(present & UNI_TRAFFIC_BSCR0_P)
3435121934Sharti		uni_printf(cx, "%u", ie->bscr0);
3436121934Sharti	uni_putc(',', cx);
3437121934Sharti	if(present & UNI_TRAFFIC_BSCR1_P)
3438121934Sharti		uni_printf(cx, "%u", ie->bscr1);
3439121934Sharti	uni_putc(',', cx);
3440121934Sharti	if(present & UNI_TRAFFIC_BMBS0_P)
3441121934Sharti		uni_printf(cx, "%u", ie->bmbs0);
3442121934Sharti	uni_putc(',', cx);
3443121934Sharti	if(present & UNI_TRAFFIC_BMBS1_P)
3444121934Sharti		uni_printf(cx, "%u", ie->bmbs1);
3445121934Sharti	uni_putc(',', cx);
3446121934Sharti	if(present & UNI_TRAFFIC_BABR1_P)
3447121934Sharti		uni_printf(cx, "%u", ie->babr1);
3448121934Sharti	uni_printf(cx, ")");
3449121934Sharti
3450121934Sharti	if(present & UNI_TRAFFIC_BEST_P)
3451121934Sharti		uni_print_flag("best_effort", cx);
3452121934Sharti	if(present & UNI_TRAFFIC_MOPT_P) {
3453121934Sharti		uni_print_entry(cx, "tag", "(");
3454121934Sharti		if(ie->ftag)
3455121934Sharti			uni_printf(cx, "fwd");
3456121934Sharti		uni_putc(',', cx);
3457121934Sharti		if(ie->btag)
3458121934Sharti			uni_printf(cx, "bwd");
3459121934Sharti		uni_putc(')', cx);
3460121934Sharti
3461121934Sharti		uni_print_entry(cx, "disc", "(");
3462121934Sharti		if(ie->fdisc)
3463121934Sharti			uni_printf(cx, "fwd");
3464121934Sharti		uni_putc(',', cx);
3465121934Sharti		if(ie->bdisc)
3466121934Sharti			uni_printf(cx, "bwd");
3467121934Sharti		uni_putc(')', cx);
3468121934Sharti	}
3469121934Sharti}
3470121934Sharti
3471121934Shartistruct tallow {
3472121934Sharti	u_int	mask;
3473121934Sharti	int	mopt_flag;
3474121934Sharti	u_char	mopt_mask, mopt_val;
3475121934Sharti};
3476121934Sharti
3477121934Shartistatic int
3478121934Sharticheck_traffic(u_int mask, u_int mopt, struct tallow *a)
3479121934Sharti{
3480121934Sharti	if(mask != a->mask)
3481121934Sharti		return 0;
3482121934Sharti
3483121934Sharti	if(a->mopt_flag == 0) {
3484121934Sharti		/* not allowed */
3485121934Sharti		if(mopt == 0xffff)
3486121934Sharti			return 1;
3487121934Sharti		return 0;
3488121934Sharti	}
3489121934Sharti
3490121934Sharti	if(a->mopt_flag < 0) {
3491121934Sharti		/* optional */
3492121934Sharti		if(mopt == 0xffff)
3493121934Sharti			return 1;
3494121934Sharti		if((mopt & a->mopt_mask) == a->mopt_val)
3495121934Sharti			return 1;
3496121934Sharti		return 0;
3497121934Sharti	}
3498121934Sharti
3499121934Sharti	/* required */
3500121934Sharti	if(mopt == 0xffff)
3501121934Sharti		return 0;
3502121934Sharti	if((mopt & a->mopt_mask) == a->mopt_val)
3503121934Sharti		return 1;
3504121934Sharti	return 0;
3505121934Sharti}
3506121934Sharti
3507121934Shartistatic int
3508121934Sharticheck_ie_traffic_common(struct uni_xtraffic *ie, u_int present,
3509121934Sharti    struct unicx *cx __unused)
3510121934Sharti{
3511121934Sharti	static u_int fmask =
3512121934Sharti		UNI_TRAFFIC_FPCR0_P | UNI_TRAFFIC_FPCR1_P |
3513121934Sharti		UNI_TRAFFIC_FSCR0_P | UNI_TRAFFIC_FSCR1_P |
3514121934Sharti		UNI_TRAFFIC_FMBS0_P | UNI_TRAFFIC_FMBS1_P |
3515121934Sharti		UNI_TRAFFIC_FABR1_P;
3516121934Sharti	static u_int bmask =
3517121934Sharti		UNI_TRAFFIC_BPCR0_P | UNI_TRAFFIC_BPCR1_P |
3518121934Sharti		UNI_TRAFFIC_BSCR0_P | UNI_TRAFFIC_BSCR1_P |
3519121934Sharti		UNI_TRAFFIC_BMBS0_P | UNI_TRAFFIC_BMBS1_P |
3520121934Sharti		UNI_TRAFFIC_BABR1_P;
3521121934Sharti#define DTAB(U,X)							\
3522121934Sharti	{ U##X##PCR1_P,							\
3523121934Sharti	  -1, U##X##TAG,	0 },		/* 1, 2, 8, 14 */	\
3524121934Sharti	{ U##X##PCR0_P | U##X##PCR1_P,					\
3525121934Sharti	  +1, U##X##TAG,	U##X##TAG },	/* 3 */			\
3526121934Sharti	{ U##X##PCR1_P | U##X##SCR1_P | U##X##MBS1_P,			\
3527121934Sharti	  -1, U##X##TAG,	0 },		/* 4, 9, 10, 15 */	\
3528121934Sharti	{ U##X##PCR1_P | U##X##SCR0_P | U##X##MBS0_P,			\
3529121934Sharti	  -1, 0,		0 },		/* 5, 6, 11, 12 */	\
3530121934Sharti	{ U##X##PCR0_P | U##X##PCR1_P,					\
3531121934Sharti	  -1, 0,		0 },		/* 7, 13 */		\
3532121934Sharti	{ U##X##PCR1_P | U##X##ABR1_P,					\
3533121934Sharti	  -1, U##X##TAG,	0 },		/* 16a */
3534121934Sharti#define DTABSIZE 6
3535121934Sharti
3536121934Sharti	static struct tallow allow[2][DTABSIZE] = {
3537121934Sharti		{ DTAB(UNI_TRAFFIC_, F) },
3538121934Sharti	  	{ DTAB(UNI_TRAFFIC_, B) },
3539121934Sharti	};
3540121934Sharti#undef DTAB
3541121934Sharti
3542121934Sharti	u_int f, b, p, m;
3543121934Sharti	int i;
3544121934Sharti
3545121934Sharti	f = present & fmask;
3546121934Sharti	b = present & bmask;
3547121934Sharti	p = present & (fmask | bmask);
3548121934Sharti	m = (present & UNI_TRAFFIC_MOPT_P)
3549121934Sharti		? (  (ie->ftag ? UNI_TRAFFIC_FTAG : 0)
3550121934Sharti		   | (ie->btag ? UNI_TRAFFIC_BTAG : 0)
3551121934Sharti		   | (ie->fdisc ? UNI_TRAFFIC_FDISC : 0)
3552121934Sharti		   | (ie->bdisc ? UNI_TRAFFIC_BDISC : 0))
3553121934Sharti		: 0xffff;
3554121934Sharti
3555121934Sharti
3556121934Sharti	if(present & UNI_TRAFFIC_BEST_P) {
3557121934Sharti		/*
3558121934Sharti		 * Lines 17 and 18
3559121934Sharti		 */
3560121934Sharti		if(p != (UNI_TRAFFIC_FPCR1_P | UNI_TRAFFIC_BPCR1_P))
3561121934Sharti			return -1;
3562121934Sharti		return 0;
3563121934Sharti	}
3564121934Sharti
3565121934Sharti	/*
3566121934Sharti	 * Check forward and backward independent. There must be a higher
3567121934Sharti	 * level checking in the CAC
3568121934Sharti	 */
3569121934Sharti	for(i = 0; i < DTABSIZE; i++)
3570121934Sharti		if(check_traffic(f, m, &allow[0][i]))
3571121934Sharti			break;
3572121934Sharti	if(i == DTABSIZE)
3573121934Sharti		return -1;
3574121934Sharti
3575121934Sharti	for(i = 0; i < DTABSIZE; i++)
3576121934Sharti		if(check_traffic(b, m, &allow[1][i]))
3577121934Sharti			break;
3578121934Sharti	if(i == DTABSIZE)
3579121934Sharti		return -1;
3580121934Sharti
3581121934Sharti	return 0;
3582121934Sharti}
3583121934Sharti
3584121934Shartistatic int
3585121934Shartiencode_traffic_common(struct uni_msg *msg, struct uni_xtraffic *ie,
3586121934Sharti    u_int present, struct unicx *cx __unused)
3587121934Sharti{
3588121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FPCR0_P,
3589121934Sharti		UNI_TRAFFIC_FPCR0_ID, ie->fpcr0);
3590121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BPCR0_P,
3591121934Sharti		UNI_TRAFFIC_BPCR0_ID, ie->bpcr0);
3592121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FPCR1_P,
3593121934Sharti		UNI_TRAFFIC_FPCR1_ID, ie->fpcr1);
3594121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BPCR1_P,
3595121934Sharti		UNI_TRAFFIC_BPCR1_ID, ie->bpcr1);
3596121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FSCR0_P,
3597121934Sharti		UNI_TRAFFIC_FSCR0_ID, ie->fscr0);
3598121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BSCR0_P,
3599121934Sharti		UNI_TRAFFIC_BSCR0_ID, ie->bscr0);
3600121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FSCR1_P,
3601121934Sharti		UNI_TRAFFIC_FSCR1_ID, ie->fscr1);
3602121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BSCR1_P,
3603121934Sharti		UNI_TRAFFIC_BSCR1_ID, ie->bscr1);
3604121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FMBS0_P,
3605121934Sharti		UNI_TRAFFIC_FMBS0_ID, ie->fmbs0);
3606121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BMBS0_P,
3607121934Sharti		UNI_TRAFFIC_BMBS0_ID, ie->bmbs0);
3608121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FMBS1_P,
3609121934Sharti		UNI_TRAFFIC_FMBS1_ID, ie->fmbs1);
3610121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BMBS1_P,
3611121934Sharti		UNI_TRAFFIC_BMBS1_ID, ie->bmbs1);
3612121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_FABR1_P,
3613121934Sharti		UNI_TRAFFIC_FABR1_ID, ie->fabr1);
3614121934Sharti	APP_OPT_24BIT(msg, present, UNI_TRAFFIC_BABR1_P,
3615121934Sharti		UNI_TRAFFIC_BABR1_ID, ie->babr1);
3616121934Sharti
3617121934Sharti	APP_OPT(msg, present, UNI_TRAFFIC_BEST_P,
3618121934Sharti		UNI_TRAFFIC_BEST_ID);
3619121934Sharti	APP_OPT_BYTE(msg, present, UNI_TRAFFIC_MOPT_P,
3620121934Sharti		UNI_TRAFFIC_MOPT_ID,
3621121934Sharti		(ie->ftag ? UNI_TRAFFIC_FTAG : 0) |
3622121934Sharti		(ie->btag ? UNI_TRAFFIC_BTAG : 0) |
3623121934Sharti		(ie->fdisc ? UNI_TRAFFIC_FDISC : 0) |
3624121934Sharti		(ie->fdisc ? UNI_TRAFFIC_BDISC : 0));
3625121934Sharti
3626121934Sharti	return 0;
3627121934Sharti}
3628121934Sharti
3629121934Shartistatic int
3630121934Shartidecode_traffic_common(struct uni_xtraffic *ie, struct uni_msg *msg,
3631121934Sharti    u_int ielen, u_int *present)
3632121934Sharti{
3633121934Sharti	u_char c;
3634121934Sharti
3635121934Sharti	while(ielen--) {
3636121934Sharti		switch(c = *msg->b_rptr++) {
3637121934Sharti
3638121934Sharti		  default:
3639121934Sharti		  rej:
3640121934Sharti			return -1;
3641121934Sharti
3642121934Sharti		  DEC_GETF3(TRAFFIC_FPCR0, fpcr0, *present);
3643121934Sharti		  DEC_GETF3(TRAFFIC_BPCR0, bpcr0, *present);
3644121934Sharti		  DEC_GETF3(TRAFFIC_FPCR1, fpcr1, *present);
3645121934Sharti		  DEC_GETF3(TRAFFIC_BPCR1, bpcr1, *present);
3646121934Sharti		  DEC_GETF3(TRAFFIC_FSCR0, fscr0, *present);
3647121934Sharti		  DEC_GETF3(TRAFFIC_BSCR0, bscr0, *present);
3648121934Sharti		  DEC_GETF3(TRAFFIC_FSCR1, fscr1, *present);
3649121934Sharti		  DEC_GETF3(TRAFFIC_BSCR1, bscr1, *present);
3650121934Sharti		  DEC_GETF3(TRAFFIC_FMBS0, fmbs0, *present);
3651121934Sharti		  DEC_GETF3(TRAFFIC_BMBS0, bmbs0, *present);
3652121934Sharti		  DEC_GETF3(TRAFFIC_BMBS1, bmbs1, *present);
3653121934Sharti		  DEC_GETF3(TRAFFIC_FABR1, fabr1, *present);
3654121934Sharti		  DEC_GETF3(TRAFFIC_BABR1, babr1, *present);
3655121934Sharti
3656121934Sharti		  case UNI_TRAFFIC_BEST_ID:
3657121934Sharti			*present |= UNI_TRAFFIC_BEST_P;
3658121934Sharti			break;
3659121934Sharti
3660121934Sharti		  case UNI_TRAFFIC_MOPT_ID:
3661121934Sharti			if(ielen == 0)
3662121934Sharti				return -1;
3663121934Sharti			ielen--;
3664121934Sharti			if(!(*present & UNI_TRAFFIC_MOPT_P)) {
3665121934Sharti				*present |= UNI_TRAFFIC_MOPT_P;
3666121934Sharti				ie->ftag = (*msg->b_rptr&UNI_TRAFFIC_FTAG)?1:0;
3667121934Sharti				ie->btag = (*msg->b_rptr&UNI_TRAFFIC_BTAG)?1:0;
3668121934Sharti				ie->fdisc = (*msg->b_rptr&UNI_TRAFFIC_FDISC)?1:0;
3669121934Sharti				ie->bdisc = (*msg->b_rptr&UNI_TRAFFIC_BDISC)?1:0;
3670121934Sharti			}
3671121934Sharti			msg->b_rptr++;
3672121934Sharti			break;
3673121934Sharti		}
3674121934Sharti	}
3675121934Sharti	return 0;
3676121934Sharti}
3677121934Sharti
3678121934Sharti
3679121934Sharti/*****************************************************************/
3680121934Sharti
3681121934ShartiDEF_IE_PRINT(itu, traffic)
3682121934Sharti{
3683121934Sharti	if(uni_print_iehdr("traffic", &ie->h, cx))
3684121934Sharti		return;
3685121934Sharti	print_ie_traffic_common(cx, ie->h.present, &ie->t);
3686121934Sharti	uni_print_ieend(cx);
3687121934Sharti}
3688121934Sharti
3689121934ShartiDEF_IE_CHECK(itu, traffic)
3690121934Sharti{
3691121934Sharti	return check_ie_traffic_common(&ie->t, ie->h.present, cx);
3692121934Sharti}
3693121934Sharti
3694121934ShartiDEF_IE_ENCODE(itu, traffic)
3695121934Sharti{
3696121934Sharti	START_IE(traffic, UNI_IE_TRAFFIC, 26);
3697121934Sharti	encode_traffic_common(msg, &ie->t, ie->h.present, cx);
3698121934Sharti	SET_IE_LEN(msg);
3699121934Sharti	return 0;
3700121934Sharti}
3701121934Sharti
3702121934ShartiDEF_IE_DECODE(itu, traffic)
3703121934Sharti{
3704121934Sharti	IE_START(;);
3705121934Sharti
3706121934Sharti	if(ielen > 30)
3707121934Sharti		goto rej;
3708121934Sharti
3709121934Sharti	if(decode_traffic_common(&ie->t, msg, ielen, &ie->h.present))
3710121934Sharti		goto rej;
3711121934Sharti
3712121934Sharti	IE_END(TRAFFIC);
3713121934Sharti}
3714121934Sharti
3715121934Sharti/*****************************************************************/
3716121934Sharti
3717121934ShartiDEF_IE_PRINT(itu, atraffic)
3718121934Sharti{
3719121934Sharti	if(uni_print_iehdr("atraffic", &ie->h, cx))
3720121934Sharti		return;
3721121934Sharti	print_ie_traffic_common(cx, ie->h.present, &ie->t);
3722121934Sharti	uni_print_ieend(cx);
3723121934Sharti}
3724121934Sharti
3725121934ShartiDEF_IE_CHECK(itu, atraffic)
3726121934Sharti{
3727121934Sharti	return check_ie_traffic_common(&ie->t, ie->h.present, cx);
3728121934Sharti}
3729121934Sharti
3730121934ShartiDEF_IE_ENCODE(itu, atraffic)
3731121934Sharti{
3732121934Sharti	START_IE(traffic, UNI_IE_ATRAFFIC, 26);
3733121934Sharti	encode_traffic_common(msg, &ie->t, ie->h.present, cx);
3734121934Sharti	SET_IE_LEN(msg);
3735121934Sharti	return 0;
3736121934Sharti}
3737121934Sharti
3738121934ShartiDEF_IE_DECODE(itu, atraffic)
3739121934Sharti{
3740121934Sharti	IE_START(;);
3741121934Sharti
3742121934Sharti	if(ielen > 30)
3743121934Sharti		goto rej;
3744121934Sharti
3745121934Sharti	if(decode_traffic_common(&ie->t, msg, ielen, &ie->h.present))
3746121934Sharti		goto rej;
3747121934Sharti
3748121934Sharti	IE_END(ATRAFFIC);
3749121934Sharti}
3750121934Sharti
3751121934Sharti/*****************************************************************/
3752121934Sharti
3753121934ShartiDEF_IE_PRINT(itu, mintraffic)
3754121934Sharti{
3755121934Sharti	if(uni_print_iehdr("mintraffic", &ie->h, cx))
3756121934Sharti		return;
3757121934Sharti
3758121934Sharti	uni_print_entry(cx, "pcr0", "(");
3759121934Sharti	if(ie->h.present & UNI_MINTRAFFIC_FPCR0_P)
3760121934Sharti		uni_printf(cx, "%u", ie->fpcr0);
3761121934Sharti	uni_putc(',', cx);
3762121934Sharti	if(ie->h.present & UNI_MINTRAFFIC_BPCR0_P)
3763121934Sharti		uni_printf(cx, "%u", ie->bpcr0);
3764121934Sharti	uni_putc(')', cx);
3765121934Sharti
3766121934Sharti	uni_print_entry(cx, "pcr1", "(");
3767121934Sharti	if(ie->h.present & UNI_MINTRAFFIC_FPCR1_P)
3768121934Sharti		uni_printf(cx, "%u", ie->fpcr1);
3769121934Sharti	uni_putc(',', cx);
3770121934Sharti	if(ie->h.present & UNI_MINTRAFFIC_BPCR1_P)
3771121934Sharti		uni_printf(cx, "%u", ie->bpcr1);
3772121934Sharti	uni_putc(')', cx);
3773121934Sharti
3774121934Sharti	uni_print_entry(cx, "abr1", "(");
3775121934Sharti	if(ie->h.present & UNI_MINTRAFFIC_FABR1_P)
3776121934Sharti		uni_printf(cx, "%u", ie->fabr1);
3777121934Sharti	uni_putc(',', cx);
3778121934Sharti	if(ie->h.present & UNI_MINTRAFFIC_BABR1_P)
3779121934Sharti		uni_printf(cx, "%u", ie->babr1);
3780121934Sharti	uni_printf(cx, ")");
3781121934Sharti
3782121934Sharti	uni_print_ieend(cx);
3783121934Sharti}
3784121934Sharti
3785121934ShartiDEF_IE_CHECK(itu, mintraffic)
3786121934Sharti{
3787121934Sharti	u_int abr;
3788121934Sharti	u_int xbr;
3789228554Sdim	UNUSED(cx);
3790121934Sharti
3791121934Sharti	abr = ie->h.present & (UNI_MINTRAFFIC_FABR1_P|UNI_MINTRAFFIC_BABR1_P);
3792121934Sharti	xbr = ie->h.present & (UNI_MINTRAFFIC_FPCR0_P|UNI_MINTRAFFIC_BPCR0_P|
3793121934Sharti			       UNI_MINTRAFFIC_FPCR1_P|UNI_MINTRAFFIC_BPCR1_P);
3794121934Sharti
3795121934Sharti	if(abr && xbr)
3796121934Sharti		return -1;
3797121934Sharti
3798121934Sharti	return 0;
3799121934Sharti}
3800121934Sharti
3801121934ShartiDEF_IE_ENCODE(itu, mintraffic)
3802121934Sharti{
3803121934Sharti	START_IE(mintraffic, UNI_IE_MINTRAFFIC, 16);
3804121934Sharti
3805121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FPCR0_P,
3806121934Sharti		UNI_TRAFFIC_FPCR0_ID, ie->fpcr0);
3807121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BPCR0_P,
3808121934Sharti		UNI_TRAFFIC_BPCR0_ID, ie->bpcr0);
3809121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FPCR1_P,
3810121934Sharti		UNI_TRAFFIC_FPCR1_ID, ie->fpcr1);
3811121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BPCR1_P,
3812121934Sharti		UNI_TRAFFIC_BPCR1_ID, ie->bpcr1);
3813121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_FABR1_P,
3814121934Sharti		UNI_TRAFFIC_FABR1_ID, ie->fabr1);
3815121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_MINTRAFFIC_BABR1_P,
3816121934Sharti		UNI_TRAFFIC_BABR1_ID, ie->babr1);
3817121934Sharti
3818121934Sharti	SET_IE_LEN(msg);
3819121934Sharti	return 0;
3820121934Sharti}
3821121934Sharti
3822121934ShartiDEF_IE_DECODE(itu, mintraffic)
3823121934Sharti{
3824121934Sharti	u_char c;
3825121934Sharti
3826121934Sharti	IE_START(;);
3827121934Sharti
3828121934Sharti	if(ielen > 20)
3829121934Sharti		goto rej;
3830121934Sharti
3831121934Sharti	while(ielen--) {
3832121934Sharti		switch(c = *msg->b_rptr++) {
3833121934Sharti
3834121934Sharti		  default:
3835121934Sharti			goto rej;
3836121934Sharti
3837121934Sharti		  DEC_GETF3(MINTRAFFIC_FPCR0, fpcr0, ie->h.present);
3838121934Sharti		  DEC_GETF3(MINTRAFFIC_BPCR0, bpcr0, ie->h.present);
3839121934Sharti		  DEC_GETF3(MINTRAFFIC_FPCR1, fpcr1, ie->h.present);
3840121934Sharti		  DEC_GETF3(MINTRAFFIC_BPCR1, bpcr1, ie->h.present);
3841121934Sharti		  DEC_GETF3(MINTRAFFIC_FABR1, fabr1, ie->h.present);
3842121934Sharti		  DEC_GETF3(MINTRAFFIC_BABR1, babr1, ie->h.present);
3843121934Sharti		}
3844121934Sharti	}
3845121934Sharti
3846121934Sharti	IE_END(MINTRAFFIC);
3847121934Sharti}
3848121934Sharti
3849121934Sharti/*****************************************************************/
3850121934Sharti
3851121934ShartiDEF_IE_PRINT(net, mdcr)
3852121934Sharti{
3853121934Sharti	static const struct uni_print_tbl origin_tbl[] = {
3854121934Sharti		MKT(UNI_MDCR_ORIGIN_USER,	user),
3855121934Sharti		MKT(UNI_MDCR_ORIGIN_NET,	net),
3856121934Sharti		EOT()
3857121934Sharti	};
3858121934Sharti
3859121934Sharti	if(uni_print_iehdr("mdcr", &ie->h, cx))
3860121934Sharti		return;
3861121934Sharti
3862121934Sharti	uni_print_tbl("origin", ie->origin, origin_tbl, cx);
3863121934Sharti	uni_print_entry(cx, "mdcr", "(");
3864121934Sharti	uni_printf(cx, "%u", ie->fmdcr);
3865121934Sharti	uni_putc(',', cx);
3866121934Sharti	uni_printf(cx, "%u", ie->bmdcr);
3867121934Sharti	uni_putc(')', cx);
3868121934Sharti
3869121934Sharti	uni_print_ieend(cx);
3870121934Sharti}
3871121934Sharti
3872121934ShartiDEF_IE_CHECK(net, mdcr)
3873121934Sharti{
3874228554Sdim	UNUSED(cx);
3875121934Sharti
3876121934Sharti	if ((ie->origin != UNI_MDCR_ORIGIN_USER &&
3877121934Sharti	    ie->origin != UNI_MDCR_ORIGIN_NET) ||
3878121934Sharti	    ie->fmdcr >= (1 << 24) || ie->bmdcr >= (1 << 24))
3879121934Sharti		return (-1);
3880121934Sharti
3881121934Sharti	return (0);
3882121934Sharti}
3883121934Sharti
3884121934ShartiDEF_IE_ENCODE(net, mdcr)
3885121934Sharti{
3886121934Sharti	START_IE(mdcr, UNI_IE_MDCR, 9);
3887121934Sharti
3888121934Sharti	APP_BYTE(msg, ie->origin);
3889121934Sharti	APP_SUB_24BIT(msg, UNI_TRAFFIC_FMDCR_ID, ie->fmdcr);
3890121934Sharti	APP_SUB_24BIT(msg, UNI_TRAFFIC_BMDCR_ID, ie->bmdcr);
3891121934Sharti
3892121934Sharti	SET_IE_LEN(msg);
3893121934Sharti	return (0);
3894121934Sharti}
3895121934Sharti
3896121934ShartiDEF_IE_DECODE(net, mdcr)
3897121934Sharti{
3898121934Sharti	u_char c;
3899121934Sharti#define UNI_TRAFFIC_FMDCR_P 0x01
3900121934Sharti#define UNI_TRAFFIC_BMDCR_P 0x02
3901121934Sharti	u_int p = 0;
3902121934Sharti
3903121934Sharti	IE_START(;);
3904121934Sharti
3905121934Sharti	if(ielen != 9)
3906121934Sharti		goto rej;
3907121934Sharti
3908121934Sharti	ie->origin = *msg->b_rptr++;
3909121934Sharti	ielen--;
3910121934Sharti
3911121934Sharti	while(ielen--) {
3912121934Sharti		switch(c = *msg->b_rptr++) {
3913121934Sharti
3914121934Sharti		  default:
3915121934Sharti			goto rej;
3916121934Sharti
3917121934Sharti		  DEC_GETF3(TRAFFIC_FMDCR, fmdcr, p);
3918121934Sharti		  DEC_GETF3(TRAFFIC_BMDCR, bmdcr, p);
3919121934Sharti		}
3920121934Sharti	}
3921121934Sharti	if (p != (UNI_TRAFFIC_FMDCR_P | UNI_TRAFFIC_BMDCR_P))
3922121934Sharti		goto rej;
3923121934Sharti
3924121934Sharti	IE_END(MDCR);
3925121934Sharti}
3926121934Sharti
3927121934Sharti/*********************************************************************
3928121934Sharti *
3929121934Sharti * Connection identifier
3930121934Sharti *
3931121934Sharti * References for this IE are:
3932121934Sharti *
3933121934Sharti *  Q.2931 pp. 69...70
3934121934Sharti *  UNI4.0 pp. 15...16
3935121934Sharti *  PNNI1.0 p. 198
3936121934Sharti *
3937121934Sharti * Only ITU-T coding allowed.
3938121934Sharti */
3939121934Sharti
3940121934ShartiDEF_IE_PRINT(itu, connid)
3941121934Sharti{
3942121934Sharti	static const struct uni_print_tbl tbl[] = {
3943121934Sharti		MKT(UNI_CONNID_VCI,	exclusive),
3944121934Sharti		MKT(UNI_CONNID_ANYVCI,	any),
3945121934Sharti		MKT(UNI_CONNID_NOVCI,	no),
3946121934Sharti		EOT()
3947121934Sharti	};
3948121934Sharti	static const struct uni_print_tbl assoc_tbl[] = {
3949121934Sharti		MKT(UNI_CONNID_ASSOC,	associated),
3950121934Sharti		MKT(UNI_CONNID_NONASSOC,non-associated),
3951121934Sharti		EOT()
3952121934Sharti	};
3953121934Sharti
3954121934Sharti	if(uni_print_iehdr("connid", &ie->h, cx))
3955121934Sharti		return;
3956121934Sharti
3957121934Sharti	uni_print_tbl("mode", ie->assoc, assoc_tbl, cx);
3958121934Sharti	uni_print_entry(cx, "connid", "(%u,", ie->vpci);
3959121934Sharti	if(ie->type == UNI_CONNID_VCI)
3960121934Sharti		uni_printf(cx, "%u", ie->vci);
3961121934Sharti	else
3962121934Sharti		uni_print_tbl(NULL, ie->type, tbl, cx);
3963121934Sharti	uni_printf(cx, ")");
3964121934Sharti
3965121934Sharti	uni_print_ieend(cx);
3966121934Sharti}
3967121934Sharti
3968121934ShartiDEF_IE_CHECK(itu, connid)
3969121934Sharti{
3970228554Sdim	UNUSED(cx);
3971121934Sharti	switch(ie->type) {
3972121934Sharti	  default:
3973121934Sharti		return -1;
3974121934Sharti	  case UNI_CONNID_VCI:
3975121934Sharti	  case UNI_CONNID_ANYVCI:
3976121934Sharti	  case UNI_CONNID_NOVCI:
3977121934Sharti		break;
3978121934Sharti	}
3979121934Sharti
3980121934Sharti#if 0
3981121934Sharti	/*
3982121934Sharti	 * This field must be checked by the application to fulfil
3983121934Sharti	 * Q.2931Amd4 27) 5.2.3 last sentence
3984121934Sharti	 */
3985121934Sharti	switch(ie->assoc) {
3986121934Sharti
3987121934Sharti	  case UNI_CONNID_ASSOC:
3988121934Sharti		if(!cx->cx.pnni)
3989121934Sharti			return -1;
3990121934Sharti		break;
3991121934Sharti
3992121934Sharti	  case UNI_CONNID_NONASSOC:
3993121934Sharti		break;
3994121934Sharti
3995121934Sharti	  default:
3996121934Sharti		return -1;
3997121934Sharti	}
3998121934Sharti#endif
3999121934Sharti	return 0;
4000121934Sharti}
4001121934Sharti
4002121934ShartiDEF_IE_ENCODE(itu, connid)
4003121934Sharti{
4004121934Sharti	START_IE(connid, UNI_IE_CONNID, 5);
4005121934Sharti
4006121934Sharti	APP_BYTE(msg, 0x80 | (ie->assoc << 3) | ie->type);
4007121934Sharti	APP_BYTE(msg, ie->vpci >> 8);
4008121934Sharti	APP_BYTE(msg, ie->vpci >> 0);
4009121934Sharti	APP_BYTE(msg, ie->vci >> 8);
4010121934Sharti	APP_BYTE(msg, ie->vci >> 0);
4011121934Sharti
4012121934Sharti	SET_IE_LEN(msg);
4013121934Sharti	return 0;
4014121934Sharti}
4015121934Sharti
4016121934ShartiDEF_IE_DECODE(itu, connid)
4017121934Sharti{
4018121934Sharti	u_char c;
4019121934Sharti
4020121934Sharti	IE_START(;);
4021121934Sharti
4022121934Sharti	if(ielen != 5)
4023121934Sharti		goto rej;
4024121934Sharti
4025121934Sharti	c = *msg->b_rptr++;
4026121934Sharti	if((c & 0x80) == 0)
4027121934Sharti		goto rej;
4028121934Sharti	ie->assoc = (c >> 3) & 3;
4029121934Sharti	ie->type = c & 7;
4030121934Sharti	ie->vpci  = *msg->b_rptr++ << 8;
4031121934Sharti	ie->vpci |= *msg->b_rptr++;
4032121934Sharti	ie->vci  = *msg->b_rptr++ << 8;
4033121934Sharti	ie->vci |= *msg->b_rptr++;
4034121934Sharti
4035121934Sharti	IE_END(CONNID);
4036121934Sharti}
4037121934Sharti
4038121934Sharti/*********************************************************************
4039121934Sharti *
4040121934Sharti * Quality of Service
4041121934Sharti *
4042121934Sharti * References for this IE are:
4043121934Sharti *
4044121934Sharti *  Q.2931 pp. 72
4045121934Sharti *  UNI4.0 pp. 16...17
4046121934Sharti */
4047121934Sharti
4048121934Shartistatic void
4049121934Shartiprint_qos(struct unicx *cx, struct uni_ie_qos *ie)
4050121934Sharti{
4051121934Sharti	static const struct uni_print_tbl class_tbl[] = {
4052121934Sharti		MKT(UNI_QOS_CLASS0,	Class0),
4053121934Sharti		MKT(UNI_QOS_CLASS1,	Class1),
4054121934Sharti		MKT(UNI_QOS_CLASS2,	Class2),
4055121934Sharti		MKT(UNI_QOS_CLASS3,	Class3),
4056121934Sharti		MKT(UNI_QOS_CLASS4,	Class4),
4057121934Sharti		EOT()
4058121934Sharti	};
4059121934Sharti
4060121934Sharti	if(uni_print_iehdr("qos", &ie->h, cx))
4061121934Sharti		return;
4062121934Sharti
4063121934Sharti	uni_print_tbl("fwd", ie->fwd, class_tbl, cx);
4064121934Sharti	uni_print_tbl("bwd", ie->bwd, class_tbl, cx);
4065121934Sharti
4066121934Sharti	uni_print_ieend(cx);
4067121934Sharti}
4068121934Sharti
4069121934ShartiDEF_IE_PRINT(itu, qos)
4070121934Sharti{
4071121934Sharti	print_qos(cx, ie);
4072121934Sharti}
4073121934ShartiDEF_IE_PRINT(net, qos)
4074121934Sharti{
4075121934Sharti	print_qos(cx, ie);
4076121934Sharti}
4077121934Sharti
4078121934ShartiDEF_IE_CHECK(itu, qos)
4079121934Sharti{
4080228554Sdim	UNUSED(cx);
4081121934Sharti
4082121934Sharti	switch(ie->fwd) {
4083121934Sharti	  default:
4084121934Sharti		return -1;
4085121934Sharti
4086121934Sharti	  case UNI_QOS_CLASS0:
4087121934Sharti		break;
4088121934Sharti	}
4089121934Sharti	switch(ie->bwd) {
4090121934Sharti	  default:
4091121934Sharti		return -1;
4092121934Sharti
4093121934Sharti	  case UNI_QOS_CLASS0:
4094121934Sharti		break;
4095121934Sharti	}
4096121934Sharti	return 0;
4097121934Sharti}
4098121934Sharti
4099121934ShartiDEF_IE_CHECK(net, qos)
4100121934Sharti{
4101228554Sdim	UNUSED(cx);
4102121934Sharti
4103121934Sharti	switch(ie->fwd) {
4104121934Sharti	  default:
4105121934Sharti		return -1;
4106121934Sharti
4107121934Sharti	  case UNI_QOS_CLASS1:
4108121934Sharti	  case UNI_QOS_CLASS2:
4109121934Sharti	  case UNI_QOS_CLASS3:
4110121934Sharti	  case UNI_QOS_CLASS4:
4111121934Sharti		break;
4112121934Sharti	}
4113121934Sharti	switch(ie->bwd) {
4114121934Sharti	  default:
4115121934Sharti		return -1;
4116121934Sharti
4117121934Sharti	  case UNI_QOS_CLASS1:
4118121934Sharti	  case UNI_QOS_CLASS2:
4119121934Sharti	  case UNI_QOS_CLASS3:
4120121934Sharti	  case UNI_QOS_CLASS4:
4121121934Sharti		break;
4122121934Sharti	}
4123121934Sharti	return 0;
4124121934Sharti}
4125121934Sharti
4126121934ShartiDEF_IE_ENCODE(itu, qos)
4127121934Sharti{
4128121934Sharti	START_IE(qos, UNI_IE_QOS, 2);
4129121934Sharti
4130121934Sharti	APP_BYTE(msg, ie->fwd);
4131121934Sharti	APP_BYTE(msg, ie->bwd);
4132121934Sharti
4133121934Sharti	SET_IE_LEN(msg);
4134121934Sharti	return 0;
4135121934Sharti}
4136121934ShartiDEF_IE_ENCODE(net, qos)
4137121934Sharti{
4138121934Sharti	START_IE(qos, UNI_IE_QOS, 2);
4139121934Sharti
4140121934Sharti	APP_BYTE(msg, ie->fwd);
4141121934Sharti	APP_BYTE(msg, ie->bwd);
4142121934Sharti
4143121934Sharti	SET_IE_LEN(msg);
4144121934Sharti	return 0;
4145121934Sharti}
4146121934Sharti
4147121934ShartiDEF_IE_DECODE(itu, qos)
4148121934Sharti{
4149121934Sharti	IE_START(;);
4150121934Sharti
4151121934Sharti	if(ielen != 2)
4152121934Sharti		goto rej;
4153121934Sharti
4154121934Sharti	ie->fwd = *msg->b_rptr++;
4155121934Sharti	ie->bwd = *msg->b_rptr++;
4156121934Sharti
4157121934Sharti	IE_END(QOS);
4158121934Sharti}
4159121934Sharti
4160121934ShartiDEF_IE_DECODE(net, qos)
4161121934Sharti{
4162121934Sharti	IE_START(;);
4163121934Sharti
4164121934Sharti	if(ielen != 2)
4165121934Sharti		goto rej;
4166121934Sharti
4167121934Sharti	ie->fwd = *msg->b_rptr++;
4168121934Sharti	ie->bwd = *msg->b_rptr++;
4169121934Sharti
4170121934Sharti	IE_END(QOS);
4171121934Sharti}
4172121934Sharti
4173121934Sharti/*********************************************************************
4174121934Sharti *
4175121934Sharti * Broadband Lower Layer Information
4176121934Sharti *
4177121934Sharti * References for this IE are:
4178121934Sharti *
4179121934Sharti *  Q.2931 pp. 53...54
4180121934Sharti *  UNI4.0 p.  12
4181121934Sharti *
4182121934Sharti * Only ITU-T coding allowed.
4183121934Sharti */
4184121934Sharti
4185121934ShartiDEF_IE_PRINT(itu, bhli)
4186121934Sharti{
4187121934Sharti	static const struct uni_print_tbl type_tbl[] = {
4188121934Sharti		MKT(UNI_BHLI_ISO,	iso),
4189121934Sharti		MKT(UNI_BHLI_USER,	user),
4190121934Sharti		MKT(UNI_BHLI_VENDOR,	vendor),
4191121934Sharti		EOT()
4192121934Sharti	};
4193121934Sharti	u_int i;
4194121934Sharti
4195121934Sharti	if(uni_print_iehdr("bhli", &ie->h, cx))
4196121934Sharti		return;
4197121934Sharti
4198121934Sharti	uni_print_tbl("type", ie->type, type_tbl, cx);
4199121934Sharti	uni_print_entry(cx, "len", "%d", ie->len);
4200121934Sharti	uni_print_entry(cx, "info", "(");
4201121934Sharti	for(i = 0; i < ie->len; i++)
4202121934Sharti		uni_printf(cx, ",0x%02x", ie->info[i]);
4203121934Sharti	uni_printf(cx, ")");
4204121934Sharti
4205121934Sharti	uni_print_ieend(cx);
4206121934Sharti}
4207121934Sharti
4208121934ShartiDEF_IE_CHECK(itu, bhli)
4209121934Sharti{
4210228554Sdim	UNUSED(cx);
4211121934Sharti
4212121934Sharti	switch(ie->type) {
4213121934Sharti	  default:
4214121934Sharti		return -1;
4215121934Sharti
4216121934Sharti	  case UNI_BHLI_ISO:
4217121934Sharti	  case UNI_BHLI_USER:
4218121934Sharti	  case UNI_BHLI_VENDOR:
4219121934Sharti		break;
4220121934Sharti	}
4221121934Sharti	if(ie->len > 8)
4222121934Sharti		return -1;
4223121934Sharti
4224121934Sharti	return 0;
4225121934Sharti}
4226121934Sharti
4227121934ShartiDEF_IE_ENCODE(itu, bhli)
4228121934Sharti{
4229121934Sharti	START_IE(bhli, UNI_IE_BHLI, 9);
4230121934Sharti
4231121934Sharti	APP_BYTE(msg, 0x80 | ie->type);
4232121934Sharti	APP_BUF(msg, ie->info, ie->len);
4233121934Sharti
4234121934Sharti	SET_IE_LEN(msg);
4235121934Sharti	return 0;
4236121934Sharti}
4237121934Sharti
4238121934ShartiDEF_IE_DECODE(itu, bhli)
4239121934Sharti{
4240121934Sharti	u_char c;
4241121934Sharti
4242121934Sharti	IE_START(;);
4243121934Sharti
4244121934Sharti	if(ielen > 9)
4245121934Sharti		goto rej;
4246121934Sharti
4247121934Sharti	c = *msg->b_rptr++;
4248121934Sharti	ielen--;
4249121934Sharti
4250121934Sharti	if(!(c & 0x80))
4251121934Sharti		goto rej;
4252121934Sharti	ie->type = c & 0x7f;
4253121934Sharti	ie->len = ielen;
4254121934Sharti	(void)memcpy(ie->info, msg->b_rptr, ielen);
4255121934Sharti	msg->b_rptr += ielen;
4256121934Sharti
4257121934Sharti	IE_END(BHLI);
4258121934Sharti}
4259121934Sharti
4260121934Sharti/*********************************************************************
4261121934Sharti *
4262121934Sharti * Broadband bearer capabilities
4263121934Sharti *
4264121934Sharti * References for this IE are:
4265121934Sharti *
4266121934Sharti *  Q.2931 pp. 51...52
4267121934Sharti *  Q.2931 Amd 1
4268121934Sharti *  UNI4.0 pp. 10...12, 106...109
4269121934Sharti *
4270121934Sharti * UNI4.0 changed the meaning of byte 5a. Instead of 3 bit traffic type and
4271121934Sharti * 2 bit timing requirements there are now 7 bits ATM transfer capabilities.
4272121934Sharti * However the old format is still supported: it should be recognized on
4273121934Sharti * input, but never be generated on output. Mapping is left to the user of
4274121934Sharti * UNI.
4275121934Sharti *
4276121934Sharti * Amd 1 not checked XXX.
4277121934Sharti *
4278121934Sharti * The Appendix in UNI4.0 lists all the supported combinations of various
4279121934Sharti * traffic IE's. The check function implements part of it.
4280121934Sharti *
4281121934Sharti *			A		C		X		VP
4282121934Sharti * 1	CBR.1		7		.		7		7
4283121934Sharti * 2	CBR.2		-		.		4,5,6		5   (*)
4284121934Sharti * 3	CBR.3		-		.		4,5,6		5   (*)
4285121934Sharti * 4	rt-VBR.1	.		19		19		19
4286121934Sharti * 5	rt-VBR.2	.		9		1,9		9
4287121934Sharti * 6	rt-VBR.3	.		9		1,9		9
4288121934Sharti * 7	rt-VBR.4	.		.		1,9		.   (*)
4289121934Sharti * 8	rt-VBR.5	.		.		1,9		.   (*)
4290121934Sharti * 9	rt-VBR.6	.		9		1,9		9   (*)
4291121934Sharti * 10	nrt-VBR.1	.		11		11		11
4292121934Sharti * 11	nrt-VBR.2	.		-		-,0,2,8,10	-,10
4293121934Sharti * 12	nrt-VBR.3	.		-		-,0,2,8,10	-,10
4294121934Sharti * 13	nrt-VBR.4	.		-		-,0,2,8,10	.   (*)
4295121934Sharti * 14	nrt-VBR.5	.		-		-,0,2,8,10	.   (*)
4296121934Sharti * 15	nrt-VBR.6	.		-		-,0,2,8,10	-,10(*)
4297121934Sharti * 16	ABR		.		12		12		12
4298121934Sharti * 17	UBR.1		.		-		-,0,2,8,10	-,10
4299121934Sharti * 18	UBR.2		.		-		-,0,2,8,10	-,10
4300121934Sharti *
4301121934Sharti * (*) compatibility
4302121934Sharti *
4303121934Sharti * Only ITU-T coding allowed.
4304121934Sharti */
4305121934Sharti
4306121934ShartiDEF_IE_PRINT(itu, bearer)
4307121934Sharti{
4308121934Sharti	static const struct uni_print_tbl bclass_tbl[] = {
4309121934Sharti		MKT(UNI_BEARER_A,	bcob-A),
4310121934Sharti		MKT(UNI_BEARER_C,	bcob-C),
4311121934Sharti		MKT(UNI_BEARER_X,	bcob-X),
4312121934Sharti		MKT(UNI_BEARER_TVP,	transparent-VP),
4313121934Sharti		EOT()
4314121934Sharti	};
4315121934Sharti	static const struct uni_print_tbl atc_tbl[] = {
4316121934Sharti		MKT(UNI_BEARER_ATC_CBR,		cbr),
4317121934Sharti		MKT(UNI_BEARER_ATC_CBR1,	cbr1),
4318121934Sharti		MKT(UNI_BEARER_ATC_VBR,		vbr),
4319121934Sharti		MKT(UNI_BEARER_ATC_VBR1,	vbr1),
4320121934Sharti		MKT(UNI_BEARER_ATC_NVBR,	nvbr),
4321121934Sharti		MKT(UNI_BEARER_ATC_NVBR1,	nvbr1),
4322121934Sharti		MKT(UNI_BEARER_ATC_ABR,		abr),
4323121934Sharti
4324121934Sharti		MKT(UNI_BEARER_ATCX_0,		x0),
4325121934Sharti		MKT(UNI_BEARER_ATCX_1,		x1),
4326121934Sharti		MKT(UNI_BEARER_ATCX_2,		x2),
4327121934Sharti		MKT(UNI_BEARER_ATCX_4,		x4),
4328121934Sharti		MKT(UNI_BEARER_ATCX_6,		x6),
4329121934Sharti		MKT(UNI_BEARER_ATCX_8,		x8),
4330121934Sharti		EOT()
4331121934Sharti	};
4332121934Sharti	static const struct uni_print_tbl cfg_tbl[] = {
4333121934Sharti		MKT(UNI_BEARER_P2P,	p2p),
4334121934Sharti		MKT(UNI_BEARER_MP,	mp),
4335121934Sharti		EOT()
4336121934Sharti	};
4337121934Sharti	static const struct uni_print_tbl clip_tbl[] = {
4338121934Sharti		MKT(UNI_BEARER_NOCLIP,	no),
4339121934Sharti		MKT(UNI_BEARER_CLIP,	yes),
4340121934Sharti		EOT()
4341121934Sharti	};
4342121934Sharti
4343121934Sharti	if(uni_print_iehdr("bearer", &ie->h, cx))
4344121934Sharti		return;
4345121934Sharti
4346121934Sharti	uni_print_tbl("class", ie->bclass, bclass_tbl, cx);
4347121934Sharti
4348121934Sharti	if(ie->h.present & UNI_BEARER_ATC_P) {
4349121934Sharti		uni_print_tbl("atc", ie->atc, atc_tbl, cx);
4350121934Sharti	}
4351121934Sharti	uni_print_tbl("clip", ie->clip, clip_tbl, cx);
4352121934Sharti	uni_print_tbl("cfg", ie->cfg, cfg_tbl, cx);
4353121934Sharti
4354121934Sharti	uni_print_ieend(cx);
4355121934Sharti}
4356121934Sharti
4357121934Sharti#define QTYPE(C,A)	((UNI_BEARER_##C << 8) | UNI_BEARER_ATC_##A)
4358121934Sharti#define QTYPEX(C,A)	((UNI_BEARER_##C << 8) | UNI_BEARER_ATCX_##A)
4359121934Sharti#define QTYPE0(C)	((UNI_BEARER_##C << 8) | (1 << 16))
4360121934ShartiDEF_IE_CHECK(itu, bearer)
4361121934Sharti{
4362228554Sdim	UNUSED(cx);
4363121934Sharti
4364121934Sharti	switch((ie->bclass << 8) |
4365121934Sharti	       ((ie->h.present & UNI_BEARER_ATC_P) == 0
4366121934Sharti			? (1 << 16)
4367121934Sharti			: ie->atc)) {
4368121934Sharti
4369121934Sharti	  default:
4370121934Sharti		return -1;
4371121934Sharti
4372121934Sharti	  case QTYPE (A,   CBR1):	/* 1 */
4373121934Sharti	  case QTYPE (X,   CBR1):	/* 1 */
4374121934Sharti	  case QTYPE (TVP, CBR1):	/* 1 */
4375121934Sharti
4376121934Sharti	  case QTYPE0(A):		/* 2,3 */
4377121934Sharti	  case QTYPEX(X,   4):		/* 2,3 */
4378121934Sharti	  case QTYPE (X,   CBR):	/* 2,3 */
4379121934Sharti	  case QTYPEX(X,   6):		/* 2,3 */
4380121934Sharti	  case QTYPE (TVP, CBR):	/* 2,3 */
4381121934Sharti
4382121934Sharti	  case QTYPE (C,   VBR1):	/* 4 */
4383121934Sharti	  case QTYPE (X,   VBR1):	/* 4 */
4384121934Sharti	  case QTYPE (TVP, VBR1):	/* 4 */
4385121934Sharti
4386121934Sharti	  case QTYPE (C,   VBR):	/* 5,6,9 */
4387121934Sharti	  case QTYPEX(X,   1):		/* 5,6,7,8,9 */
4388121934Sharti	  case QTYPE (X,   VBR):	/* 5,6,7,8,9 */
4389121934Sharti	  case QTYPE (TVP, VBR):	/* 5,6,9 */
4390121934Sharti
4391121934Sharti	  case QTYPE (C,   NVBR1):	/* 10 */
4392121934Sharti	  case QTYPE (X,   NVBR1):	/* 10 */
4393121934Sharti	  case QTYPE (TVP, NVBR1):	/* 10 */
4394121934Sharti
4395121934Sharti	  case QTYPE0(C):		/* 11,12,13,14,15,17,18 */
4396121934Sharti	  case QTYPE0(X):		/* 11,12,13,14,15,17,18 */
4397121934Sharti	  case QTYPEX(X,   0):		/* 11,12,13,14,15,17,18 */
4398121934Sharti	  case QTYPEX(X,   2):		/* 11,12,13,14,15,17,18 */
4399121934Sharti	  case QTYPEX(X,   8):		/* 11,12,13,14,15,17,18 */
4400121934Sharti	  case QTYPE (X,   NVBR):	/* 11,12,13,14,15,17,18 */
4401121934Sharti	  case QTYPE0(TVP):		/* 11,12,15,17,18 */
4402121934Sharti	  case QTYPE (TVP, NVBR):	/* 11,12,15,17,18 */
4403121934Sharti
4404121934Sharti	  case QTYPE (C,   ABR):	/* 16 */
4405121934Sharti	  case QTYPE (X,   ABR):	/* 16 */
4406121934Sharti	  case QTYPE (TVP, ABR):	/* 16 */
4407121934Sharti		break;
4408121934Sharti	}
4409121934Sharti
4410121934Sharti	switch(ie->clip) {
4411121934Sharti	  default:
4412121934Sharti		return -1;
4413121934Sharti
4414121934Sharti	  case UNI_BEARER_NOCLIP:
4415121934Sharti	  case UNI_BEARER_CLIP:
4416121934Sharti		break;
4417121934Sharti	}
4418121934Sharti	switch(ie->cfg) {
4419121934Sharti	  default:
4420121934Sharti		return -1;
4421121934Sharti
4422121934Sharti	  case UNI_BEARER_P2P:
4423121934Sharti	  case UNI_BEARER_MP:
4424121934Sharti		break;
4425121934Sharti	}
4426121934Sharti
4427121934Sharti	return 0;
4428121934Sharti}
4429121934Sharti#undef QTYPE
4430121934Sharti#undef QTYPEX
4431121934Sharti#undef QTYPE0
4432121934Sharti
4433121934ShartiDEF_IE_ENCODE(itu, bearer)
4434121934Sharti{
4435121934Sharti	START_IE(bearer, UNI_IE_BEARER, 3);
4436121934Sharti
4437121934Sharti	APP_BYTE(msg, ie->bclass |
4438121934Sharti		((ie->h.present & UNI_BEARER_ATC_P) ? 0:0x80));
4439121934Sharti	APP_OPT(msg, ie->h.present, UNI_BEARER_ATC_P,
4440121934Sharti		0x80 | ie->atc);
4441121934Sharti	APP_BYTE(msg, 0x80 | (ie->clip << 5) | ie->cfg);
4442121934Sharti
4443121934Sharti	SET_IE_LEN(msg);
4444121934Sharti	return 0;
4445121934Sharti}
4446121934Sharti
4447121934ShartiDEF_IE_DECODE(itu, bearer)
4448121934Sharti{
4449121934Sharti	u_char c;
4450121934Sharti
4451121934Sharti	IE_START(;);
4452121934Sharti
4453121934Sharti	if(ielen != 2 && ielen != 3)
4454121934Sharti		goto rej;
4455121934Sharti
4456121934Sharti	c = *msg->b_rptr++;
4457121934Sharti	ielen--;
4458121934Sharti	ie->bclass = c & 0x1f;
4459121934Sharti	if(!(c & 0x80)) {
4460121934Sharti		c = *msg->b_rptr++;
4461121934Sharti		ielen--;
4462121934Sharti		ie->h.present |= UNI_BEARER_ATC_P;
4463121934Sharti
4464121934Sharti		switch(c & 0x7f) {
4465121934Sharti		  /*
4466121934Sharti		   * Real legal values
4467121934Sharti		   */
4468121934Sharti		  case UNI_BEARER_ATC_CBR:
4469121934Sharti		  case UNI_BEARER_ATC_CBR1:
4470121934Sharti		  case UNI_BEARER_ATC_VBR:
4471121934Sharti		  case UNI_BEARER_ATC_VBR1:
4472121934Sharti		  case UNI_BEARER_ATC_NVBR:
4473121934Sharti		  case UNI_BEARER_ATC_NVBR1:
4474121934Sharti		  case UNI_BEARER_ATC_ABR:
4475121934Sharti			break;
4476121934Sharti
4477121934Sharti		  /*
4478121934Sharti		   * Compat values
4479121934Sharti		   */
4480121934Sharti		  case UNI_BEARER_ATCX_0:
4481121934Sharti		  case UNI_BEARER_ATCX_1:
4482121934Sharti		  case UNI_BEARER_ATCX_2:
4483121934Sharti		  case UNI_BEARER_ATCX_4:
4484121934Sharti		  case UNI_BEARER_ATCX_6:
4485121934Sharti		  case UNI_BEARER_ATCX_8:
4486121934Sharti			break;
4487121934Sharti
4488121934Sharti		  default:
4489121934Sharti			goto rej;
4490121934Sharti		}
4491121934Sharti
4492121934Sharti		if(!(c & 0x80))
4493121934Sharti			goto rej;
4494121934Sharti
4495121934Sharti		ie->atc = c & 0x7f;
4496121934Sharti	}
4497121934Sharti	if(ielen == 0)
4498121934Sharti		goto rej;
4499121934Sharti	c = *msg->b_rptr++;
4500121934Sharti	ielen--;
4501121934Sharti	if(!(c & 0x80))
4502121934Sharti		goto rej;
4503121934Sharti	ie->clip = (c >> 5) & 0x3;
4504121934Sharti	ie->cfg = c & 0x3;
4505121934Sharti
4506121934Sharti	IE_END(BEARER);
4507121934Sharti}
4508121934Sharti
4509121934Sharti/*********************************************************************
4510121934Sharti *
4511121934Sharti * Broadband Lower Layer Information
4512121934Sharti *
4513121934Sharti * References for this IE are:
4514121934Sharti *
4515121934Sharti *  Q.2931 pp. 54...59
4516121934Sharti *  UNI4.0 pp. 12...14
4517121934Sharti *
4518121934Sharti * UNI4.0 states, that layer 1 info is not supported.
4519121934Sharti * We allow a layer 1 protocol identifier.
4520121934Sharti *
4521121934Sharti * UNI4.0 states, that the layer information subelements are NOT position
4522121934Sharti * dependent. We allow them in any order on input, but generate always the
4523121934Sharti * definit order on output.
4524121934Sharti *
4525121934Sharti * Only ITU-T coding allowed.
4526121934Sharti */
4527121934Sharti
4528121934ShartiDEF_IE_PRINT(itu, blli)
4529121934Sharti{
4530121934Sharti	static const struct uni_print_tbl l2_tbl[] = {
4531121934Sharti		MKT(UNI_BLLI_L2_BASIC,		basic),
4532121934Sharti		MKT(UNI_BLLI_L2_Q921,		Q921),
4533121934Sharti		MKT(UNI_BLLI_L2_X25LL,		X25-LL),
4534121934Sharti		MKT(UNI_BLLI_L2_X25ML,		X25-ML),
4535121934Sharti		MKT(UNI_BLLI_L2_LABP,		LAPB),
4536121934Sharti		MKT(UNI_BLLI_L2_HDLC_ARM,	HDLC-ARM),
4537121934Sharti		MKT(UNI_BLLI_L2_HDLC_NRM,	HDLC-NRM),
4538121934Sharti		MKT(UNI_BLLI_L2_HDLC_ABM,	HDLC-ABM),
4539121934Sharti		MKT(UNI_BLLI_L2_LAN,		LAN),
4540121934Sharti		MKT(UNI_BLLI_L2_X75,		X75),
4541121934Sharti		MKT(UNI_BLLI_L2_Q922,		Q922),
4542121934Sharti		MKT(UNI_BLLI_L2_USER,		user),
4543121934Sharti		MKT(UNI_BLLI_L2_ISO7776,	ISO7776),
4544121934Sharti		EOT()
4545121934Sharti	};
4546121934Sharti	static const struct uni_print_tbl l2mode_tbl[] = {
4547121934Sharti		MKT(UNI_BLLI_L2NORM,		normal),
4548121934Sharti		MKT(UNI_BLLI_L2EXT,		extended),
4549121934Sharti		EOT()
4550121934Sharti	};
4551121934Sharti	static const struct uni_print_tbl l3_tbl[] = {
4552121934Sharti		MKT(UNI_BLLI_L3_X25,		X25),
4553121934Sharti		MKT(UNI_BLLI_L3_ISO8208,	ISO8208),
4554121934Sharti		MKT(UNI_BLLI_L3_X223,		X223),
4555121934Sharti		MKT(UNI_BLLI_L3_CLMP,		CLMP),
4556121934Sharti		MKT(UNI_BLLI_L3_T70,		T70),
4557121934Sharti		MKT(UNI_BLLI_L3_TR9577,		TR9577),
4558121934Sharti		MKT(UNI_BLLI_L3_USER,		user),
4559121934Sharti		MKT(UNI_BLLI_L3_H310,		H310),
4560121934Sharti		MKT(UNI_BLLI_L3_H321,		H321),
4561121934Sharti		EOT()
4562121934Sharti	};
4563121934Sharti	static const struct uni_print_tbl l3mode_tbl[] = {
4564121934Sharti		MKT(UNI_BLLI_L3NSEQ,		normal-seq),
4565121934Sharti		MKT(UNI_BLLI_L3ESEQ,		extended-seq),
4566121934Sharti		EOT()
4567121934Sharti	};
4568121934Sharti	static const struct uni_print_tbl l3psiz_tbl[] = {
4569121934Sharti		MKT(UNI_BLLI_L3_16,	16),
4570121934Sharti		MKT(UNI_BLLI_L3_32,	32),
4571121934Sharti		MKT(UNI_BLLI_L3_64,	64),
4572121934Sharti		MKT(UNI_BLLI_L3_128,	128),
4573121934Sharti		MKT(UNI_BLLI_L3_256,	256),
4574121934Sharti		MKT(UNI_BLLI_L3_512,	512),
4575121934Sharti		MKT(UNI_BLLI_L3_1024,	1024),
4576121934Sharti		MKT(UNI_BLLI_L3_2048,	2048),
4577121934Sharti		MKT(UNI_BLLI_L3_4096,	4096),
4578121934Sharti		EOT()
4579121934Sharti	};
4580121934Sharti	static const struct uni_print_tbl l3ttype_tbl[] = {
4581121934Sharti		MKT(UNI_BLLI_L3_TTYPE_RECV,	receive_only),
4582121934Sharti		MKT(UNI_BLLI_L3_TTYPE_SEND,	send_only),
4583121934Sharti		MKT(UNI_BLLI_L3_TTYPE_BOTH,	both),
4584121934Sharti		EOT()
4585121934Sharti	};
4586121934Sharti	static const struct uni_print_tbl l3mux_tbl[] = {
4587121934Sharti		MKT(UNI_BLLI_L3_MUX_NOMUX,	NOMUX),
4588121934Sharti		MKT(UNI_BLLI_L3_MUX_TS,		TS),
4589121934Sharti		MKT(UNI_BLLI_L3_MUX_TSFEC,	TSFEC),
4590121934Sharti		MKT(UNI_BLLI_L3_MUX_PS,		PS),
4591121934Sharti		MKT(UNI_BLLI_L3_MUX_PSFEC,	PSFEC),
4592121934Sharti		MKT(UNI_BLLI_L3_MUX_H221,	H221),
4593121934Sharti		EOT()
4594121934Sharti	};
4595121934Sharti	static const struct uni_print_tbl l3tcap_tbl[] = {
4596121934Sharti		MKT(UNI_BLLI_L3_TCAP_NOIND,	noind),
4597121934Sharti		MKT(UNI_BLLI_L3_TCAP_AAL1,	aal1),
4598121934Sharti		MKT(UNI_BLLI_L3_TCAP_AAL5,	aal5),
4599121934Sharti		MKT(UNI_BLLI_L3_TCAP_AAL15,	aal1&5),
4600121934Sharti		EOT()
4601121934Sharti	};
4602121934Sharti
4603121934Sharti	if(uni_print_iehdr("blli", &ie->h, cx))
4604121934Sharti		return;
4605121934Sharti
4606121934Sharti	if(ie->h.present & UNI_BLLI_L1_P) {
4607121934Sharti		uni_print_entry(cx, "l1", "%u", ie->l1);
4608121934Sharti		uni_print_eol(cx);
4609121934Sharti	}
4610121934Sharti	if(ie->h.present & UNI_BLLI_L2_P) {
4611121934Sharti		uni_print_tbl("l2", ie->l2, l2_tbl, cx);
4612121934Sharti		uni_print_push_prefix("l2", cx);
4613121934Sharti		cx->indent++;
4614121934Sharti		if(ie->h.present & UNI_BLLI_L2_USER_P)
4615121934Sharti			uni_print_entry(cx, "proto", "%u", ie->l2_user);
4616121934Sharti		if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4617121934Sharti			uni_print_entry(cx, "q933", "%u", ie->l2_q933);
4618121934Sharti			uni_print_tbl("mode", ie->l2_mode, l2mode_tbl, cx);
4619121934Sharti		}
4620121934Sharti		if(ie->h.present & UNI_BLLI_L2_WSIZ_P)
4621121934Sharti			uni_print_entry(cx, "wsize", "%u", ie->l2_wsiz);
4622121934Sharti		uni_print_pop_prefix(cx);
4623121934Sharti		cx->indent--;
4624121934Sharti		uni_print_eol(cx);
4625121934Sharti
4626121934Sharti	}
4627121934Sharti	if(ie->h.present & UNI_BLLI_L3_P) {
4628121934Sharti		uni_print_tbl("l3", ie->l3, l3_tbl, cx);
4629121934Sharti		uni_print_push_prefix("l3", cx);
4630121934Sharti		cx->indent++;
4631121934Sharti		if(ie->h.present & UNI_BLLI_L3_USER_P)
4632121934Sharti			uni_print_entry(cx, "proto", "%u", ie->l3_user);
4633121934Sharti		if(ie->h.present & UNI_BLLI_L3_MODE_P)
4634121934Sharti			uni_print_tbl("mode", ie->l3_mode, l3mode_tbl, cx);
4635121934Sharti		if(ie->h.present & UNI_BLLI_L3_PSIZ_P)
4636121934Sharti			uni_print_tbl("packet-size", ie->l3_psiz, l3psiz_tbl, cx);
4637121934Sharti		if(ie->h.present & UNI_BLLI_L3_WSIZ_P)
4638121934Sharti			uni_print_entry(cx, "window-size", "%u", ie->l3_wsiz);
4639121934Sharti		if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4640121934Sharti			uni_print_tbl("ttype", ie->l3_ttype, l3ttype_tbl, cx);
4641121934Sharti			uni_print_tbl("tcap", ie->l3_tcap, l3tcap_tbl, cx);
4642121934Sharti		}
4643121934Sharti		if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4644121934Sharti			uni_print_tbl("fmux", ie->l3_fmux, l3mux_tbl, cx);
4645121934Sharti			uni_print_tbl("bmux", ie->l3_bmux, l3mux_tbl, cx);
4646121934Sharti		}
4647121934Sharti		if(ie->h.present & UNI_BLLI_L3_IPI_P)
4648121934Sharti			uni_print_entry(cx, "ipi", "0x%02x", ie->l3_ipi);
4649121934Sharti		if(ie->h.present & UNI_BLLI_L3_SNAP_P)
4650121934Sharti			uni_print_entry(cx, "snap", "%06x.%04x", ie->oui, ie->pid);
4651121934Sharti		uni_print_pop_prefix(cx);
4652121934Sharti		cx->indent--;
4653121934Sharti		uni_print_eol(cx);
4654121934Sharti	}
4655121934Sharti
4656121934Sharti	uni_print_ieend(cx);
4657121934Sharti}
4658121934Sharti
4659121934ShartiDEF_IE_CHECK(itu, blli)
4660121934Sharti{
4661228554Sdim	UNUSED(cx);
4662121934Sharti/*
4663121934Sharti	if(ie->h.present & UNI_BLLI_L1_P)
4664121934Sharti		;
4665121934Sharti*/
4666121934Sharti
4667121934Sharti	if(ie->h.present & UNI_BLLI_L2_P) {
4668121934Sharti		static u_int mask =
4669121934Sharti			UNI_BLLI_L2_Q933_P | UNI_BLLI_L2_WSIZ_P |
4670121934Sharti			UNI_BLLI_L2_USER_P;
4671121934Sharti
4672121934Sharti		switch(ie->l2) {
4673121934Sharti		  default:
4674121934Sharti			return -1;
4675121934Sharti
4676121934Sharti		  case UNI_BLLI_L2_BASIC:
4677121934Sharti		  case UNI_BLLI_L2_Q921:
4678121934Sharti		  case UNI_BLLI_L2_LABP:
4679121934Sharti		  case UNI_BLLI_L2_LAN:
4680121934Sharti		  case UNI_BLLI_L2_X75:
4681121934Sharti			if(ie->h.present & mask)
4682121934Sharti				return -1;
4683121934Sharti			break;
4684121934Sharti
4685121934Sharti		  case UNI_BLLI_L2_X25LL:
4686121934Sharti		  case UNI_BLLI_L2_X25ML:
4687121934Sharti		  case UNI_BLLI_L2_HDLC_ARM:
4688121934Sharti		  case UNI_BLLI_L2_HDLC_NRM:
4689121934Sharti		  case UNI_BLLI_L2_HDLC_ABM:
4690121934Sharti		  case UNI_BLLI_L2_Q922:
4691121934Sharti		  case UNI_BLLI_L2_ISO7776:
4692121934Sharti			switch(ie->h.present & mask) {
4693121934Sharti			  default:
4694121934Sharti				return -1;
4695121934Sharti
4696121934Sharti			  case 0:
4697121934Sharti			  case UNI_BLLI_L2_Q933_P:
4698121934Sharti			  case UNI_BLLI_L2_Q933_P | UNI_BLLI_L2_WSIZ_P:
4699121934Sharti				break;
4700121934Sharti			}
4701121934Sharti			break;
4702121934Sharti
4703121934Sharti		  case UNI_BLLI_L2_USER:
4704121934Sharti			switch(ie->h.present & mask) {
4705121934Sharti			  default:
4706121934Sharti				return -1;
4707121934Sharti
4708121934Sharti			  case 0:	/* XXX ? */
4709121934Sharti			  case UNI_BLLI_L2_USER_P:
4710121934Sharti				break;
4711121934Sharti			}
4712121934Sharti			break;
4713121934Sharti		}
4714121934Sharti		if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4715121934Sharti			if(ie->l2_q933 != 0)
4716121934Sharti				return -1;
4717121934Sharti
4718121934Sharti			switch(ie->l2_mode) {
4719121934Sharti			  default:
4720121934Sharti				return -1;
4721121934Sharti
4722121934Sharti			  case UNI_BLLI_L2NORM:
4723121934Sharti			  case UNI_BLLI_L2EXT:
4724121934Sharti				break;
4725121934Sharti			}
4726121934Sharti		}
4727121934Sharti		if(ie->h.present & UNI_BLLI_L2_WSIZ_P) {
4728121934Sharti			if(ie->l2_wsiz == 0 || ie->l2_wsiz > 127)
4729121934Sharti				return -1;
4730121934Sharti		}
4731121934Sharti		if(ie->h.present & UNI_BLLI_L2_USER_P) {
4732121934Sharti			if(ie->l2_user > 127)
4733121934Sharti				return -1;
4734121934Sharti		}
4735121934Sharti	}
4736121934Sharti	if(ie->h.present & UNI_BLLI_L3_P) {
4737121934Sharti		static u_int mask =
4738121934Sharti			UNI_BLLI_L3_MODE_P | UNI_BLLI_L3_PSIZ_P |
4739121934Sharti			UNI_BLLI_L3_WSIZ_P | UNI_BLLI_L3_USER_P |
4740121934Sharti			UNI_BLLI_L3_IPI_P | UNI_BLLI_L3_SNAP_P |
4741121934Sharti			UNI_BLLI_L3_TTYPE_P | UNI_BLLI_L3_MUX_P;
4742121934Sharti
4743121934Sharti		switch(ie->l3) {
4744121934Sharti		  default:
4745121934Sharti			return -1;
4746121934Sharti
4747121934Sharti		  case UNI_BLLI_L3_X25:
4748121934Sharti		  case UNI_BLLI_L3_ISO8208:
4749121934Sharti		  case UNI_BLLI_L3_X223:
4750121934Sharti			switch(ie->h.present & mask) {
4751121934Sharti			  default:
4752121934Sharti				return -1;
4753121934Sharti
4754121934Sharti			  case 0:
4755121934Sharti			  case UNI_BLLI_L3_MODE_P:
4756121934Sharti			  case UNI_BLLI_L3_MODE_P |
4757121934Sharti			       UNI_BLLI_L3_PSIZ_P:
4758121934Sharti			  case UNI_BLLI_L3_MODE_P |
4759121934Sharti			       UNI_BLLI_L3_PSIZ_P |
4760121934Sharti			       UNI_BLLI_L3_WSIZ_P:
4761121934Sharti				break;
4762121934Sharti			}
4763121934Sharti			break;
4764121934Sharti
4765121934Sharti		  case UNI_BLLI_L3_CLMP:
4766121934Sharti		  case UNI_BLLI_L3_T70:
4767121934Sharti			if(ie->h.present & mask)
4768121934Sharti				return -1;
4769121934Sharti			break;
4770121934Sharti
4771121934Sharti		  case UNI_BLLI_L3_TR9577:
4772121934Sharti			switch(ie->h.present & mask) {
4773121934Sharti			  default:
4774121934Sharti				return -1;
4775121934Sharti
4776121934Sharti			  case 0:
4777121934Sharti			  case UNI_BLLI_L3_IPI_P:
4778121934Sharti			  case UNI_BLLI_L3_IPI_P | UNI_BLLI_L3_SNAP_P:
4779121934Sharti				break;
4780121934Sharti			}
4781121934Sharti			break;
4782121934Sharti
4783121934Sharti		  case UNI_BLLI_L3_H310:
4784121934Sharti			switch(ie->h.present & mask) {
4785121934Sharti			  default:
4786121934Sharti				return -1;
4787121934Sharti
4788121934Sharti			  case 0:
4789121934Sharti			  case UNI_BLLI_L3_TTYPE_P:
4790121934Sharti			  case UNI_BLLI_L3_TTYPE_P|UNI_BLLI_L3_MUX_P:
4791121934Sharti				break;
4792121934Sharti			}
4793121934Sharti			break;
4794121934Sharti
4795121934Sharti		  case UNI_BLLI_L3_USER:
4796121934Sharti			switch(ie->h.present & mask) {
4797121934Sharti			  default:
4798121934Sharti				return -1;
4799121934Sharti
4800121934Sharti			  case 0:	/* XXX ? */
4801121934Sharti			  case UNI_BLLI_L3_USER_P:
4802121934Sharti				break;
4803121934Sharti			}
4804121934Sharti			break;
4805121934Sharti		}
4806121934Sharti		if(ie->h.present & UNI_BLLI_L3_MODE_P) {
4807121934Sharti			switch(ie->l3_mode) {
4808121934Sharti			  default:
4809121934Sharti				return -1;
4810121934Sharti
4811121934Sharti			  case UNI_BLLI_L3NSEQ:
4812121934Sharti			  case UNI_BLLI_L3ESEQ:
4813121934Sharti				break;
4814121934Sharti			}
4815121934Sharti		}
4816121934Sharti		if(ie->h.present & UNI_BLLI_L3_PSIZ_P) {
4817121934Sharti			switch(ie->l3_psiz) {
4818121934Sharti			  default:
4819121934Sharti				return -1;
4820121934Sharti
4821121934Sharti			  case UNI_BLLI_L3_16:
4822121934Sharti			  case UNI_BLLI_L3_32:
4823121934Sharti			  case UNI_BLLI_L3_64:
4824121934Sharti			  case UNI_BLLI_L3_128:
4825121934Sharti			  case UNI_BLLI_L3_256:
4826121934Sharti			  case UNI_BLLI_L3_512:
4827121934Sharti			  case UNI_BLLI_L3_1024:
4828121934Sharti			  case UNI_BLLI_L3_2048:
4829121934Sharti			  case UNI_BLLI_L3_4096:
4830121934Sharti				break;
4831121934Sharti			}
4832121934Sharti		}
4833121934Sharti		if(ie->h.present & UNI_BLLI_L3_WSIZ_P) {
4834121934Sharti			if(ie->l3_wsiz == 0 || ie->l3_wsiz > 127)
4835121934Sharti				return -1;
4836121934Sharti		}
4837121934Sharti		if(ie->h.present & UNI_BLLI_L3_IPI_P) {
4838121934Sharti			if(ie->l3_ipi == UNI_BLLI_L3_SNAP) {
4839121934Sharti				if(!(ie->h.present & UNI_BLLI_L3_SNAP_P))
4840121934Sharti					return -1;
4841121934Sharti			} else {
4842121934Sharti				if(ie->h.present & UNI_BLLI_L3_SNAP_P)
4843121934Sharti					return -1;
4844121934Sharti			}
4845121934Sharti		}
4846121934Sharti		if(ie->h.present & UNI_BLLI_L3_USER_P) {
4847121934Sharti			if(ie->l3_user > 127)
4848121934Sharti				return -1;
4849121934Sharti		}
4850121934Sharti		if(ie->h.present & UNI_BLLI_L3_SNAP_P) {
4851121934Sharti			if(ie->oui >= (1<<24))
4852121934Sharti				return -1;
4853121934Sharti			if(ie->pid >= (1<<16))
4854121934Sharti				return -1;
4855121934Sharti		}
4856121934Sharti		if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4857121934Sharti			switch(ie->l3_ttype) {
4858121934Sharti			  default:
4859121934Sharti				return -1;
4860121934Sharti
4861121934Sharti			  case UNI_BLLI_L3_TTYPE_RECV:
4862121934Sharti			  case UNI_BLLI_L3_TTYPE_SEND:
4863121934Sharti			  case UNI_BLLI_L3_TTYPE_BOTH:
4864121934Sharti				break;
4865121934Sharti			}
4866121934Sharti			switch(ie->l3_tcap) {
4867121934Sharti			  default:
4868121934Sharti				return -1;
4869121934Sharti
4870121934Sharti			  case UNI_BLLI_L3_TCAP_NOIND:
4871121934Sharti			  case UNI_BLLI_L3_TCAP_AAL1:
4872121934Sharti			  case UNI_BLLI_L3_TCAP_AAL5:
4873121934Sharti			  case UNI_BLLI_L3_TCAP_AAL15:
4874121934Sharti				break;
4875121934Sharti			}
4876121934Sharti		}
4877121934Sharti		if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4878121934Sharti			switch(ie->l3_fmux) {
4879121934Sharti			  default:
4880121934Sharti				return -1;
4881121934Sharti
4882121934Sharti			  case UNI_BLLI_L3_MUX_NOMUX:
4883121934Sharti			  case UNI_BLLI_L3_MUX_TS:
4884121934Sharti			  case UNI_BLLI_L3_MUX_TSFEC:
4885121934Sharti			  case UNI_BLLI_L3_MUX_PS:
4886121934Sharti			  case UNI_BLLI_L3_MUX_PSFEC:
4887121934Sharti			  case UNI_BLLI_L3_MUX_H221:
4888121934Sharti				break;
4889121934Sharti			}
4890121934Sharti			switch(ie->l3_bmux) {
4891121934Sharti			  default:
4892121934Sharti				return -1;
4893121934Sharti
4894121934Sharti			  case UNI_BLLI_L3_MUX_NOMUX:
4895121934Sharti			  case UNI_BLLI_L3_MUX_TS:
4896121934Sharti			  case UNI_BLLI_L3_MUX_TSFEC:
4897121934Sharti			  case UNI_BLLI_L3_MUX_PS:
4898121934Sharti			  case UNI_BLLI_L3_MUX_PSFEC:
4899121934Sharti			  case UNI_BLLI_L3_MUX_H221:
4900121934Sharti				break;
4901121934Sharti			}
4902121934Sharti		}
4903121934Sharti	}
4904121934Sharti
4905121934Sharti	return 0;
4906121934Sharti}
4907121934Sharti
4908121934ShartiDEF_IE_ENCODE(itu, blli)
4909121934Sharti{
4910121934Sharti	START_IE(blli, UNI_IE_BLLI, 13);
4911121934Sharti
4912121934Sharti	if (IE_ISERROR(*ie)) {
4913121934Sharti		APP_BYTE(msg, 0xff);
4914121934Sharti		APP_BYTE(msg, 0xff);
4915121934Sharti		goto out;
4916121934Sharti	}
4917121934Sharti
4918121934Sharti	if(ie->h.present & UNI_BLLI_L1_P)
4919121934Sharti		APP_BYTE(msg, (UNI_BLLI_L1_ID<<5)|ie->l1|0x80);
4920121934Sharti
4921121934Sharti	if(ie->h.present & UNI_BLLI_L2_P) {
4922121934Sharti		if(ie->h.present & UNI_BLLI_L2_Q933_P) {
4923121934Sharti			APP_BYTE(msg, (UNI_BLLI_L2_ID<<5)|ie->l2);
4924121934Sharti			if(ie->h.present & UNI_BLLI_L2_WSIZ_P) {
4925121934Sharti				APP_BYTE(msg, (ie->l2_mode<<5)|ie->l2_q933);
4926121934Sharti				APP_BYTE(msg, ie->l2_wsiz | 0x80);
4927121934Sharti			} else {
4928121934Sharti				APP_BYTE(msg, (ie->l2_mode<<5)|ie->l2_q933|0x80);
4929121934Sharti			}
4930121934Sharti		} else if(ie->h.present & UNI_BLLI_L2_USER_P) {
4931121934Sharti			APP_BYTE(msg, (UNI_BLLI_L2_ID<<5)|ie->l2);
4932121934Sharti			APP_BYTE(msg, ie->l2_user | 0x80);
4933121934Sharti		} else {
4934121934Sharti			APP_BYTE(msg, (UNI_BLLI_L2_ID << 5) | ie->l2 | 0x80);
4935121934Sharti		}
4936121934Sharti	}
4937121934Sharti
4938121934Sharti	if(ie->h.present & UNI_BLLI_L3_P) {
4939121934Sharti		if(ie->h.present & UNI_BLLI_L3_MODE_P) {
4940121934Sharti			if(ie->h.present & UNI_BLLI_L3_PSIZ_P) {
4941121934Sharti				if(ie->h.present & UNI_BLLI_L3_WSIZ_P) {
4942121934Sharti					APP_BYTE(msg,(UNI_BLLI_L3_ID<<5)|ie->l3);
4943121934Sharti					APP_BYTE(msg,(ie->l3_mode<<5));
4944121934Sharti					APP_BYTE(msg,ie->l3_psiz);
4945121934Sharti					APP_BYTE(msg,ie->l3_wsiz|0x80);
4946121934Sharti				} else {
4947121934Sharti					APP_BYTE(msg,(UNI_BLLI_L3_ID<<5)|ie->l3);
4948121934Sharti					APP_BYTE(msg,(ie->l3_mode<<5));
4949121934Sharti					APP_BYTE(msg,(ie->l3_psiz|0x80));
4950121934Sharti				}
4951121934Sharti			} else {
4952121934Sharti				APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4953121934Sharti				APP_BYTE(msg, (ie->l3_mode<<5)|0x80);
4954121934Sharti			}
4955121934Sharti		} else if(ie->h.present & UNI_BLLI_L3_USER_P) {
4956121934Sharti			APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4957121934Sharti			APP_BYTE(msg,(ie->l3_user|0x80));
4958121934Sharti		} else if(ie->h.present & UNI_BLLI_L3_IPI_P) {
4959121934Sharti			APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3);
4960121934Sharti			APP_BYTE(msg,((ie->l3_ipi>>1) & 0x7f));
4961121934Sharti			APP_BYTE(msg,(((ie->l3_ipi&1)<<6)|0x80));
4962121934Sharti			if(ie->h.present & UNI_BLLI_L3_SNAP_P) {
4963121934Sharti				APP_BYTE(msg, 0x80);
4964121934Sharti				APP_BYTE(msg, (ie->oui >> 16));
4965121934Sharti				APP_BYTE(msg, (ie->oui >>  8));
4966121934Sharti				APP_BYTE(msg, (ie->oui >>  0));
4967121934Sharti				APP_BYTE(msg, (ie->pid >>  8));
4968121934Sharti				APP_BYTE(msg, (ie->pid >>  0));
4969121934Sharti			}
4970121934Sharti		} else if(ie->h.present & UNI_BLLI_L3_TTYPE_P) {
4971121934Sharti			if(ie->h.present & UNI_BLLI_L3_MUX_P) {
4972121934Sharti				APP_BYTE(msg, ie->l3_ttype | (ie->l3_tcap << 4));
4973121934Sharti				APP_BYTE(msg, 0x80 | (ie->l3_fmux << 3) | ie->l3_bmux);
4974121934Sharti			} else {
4975121934Sharti				APP_BYTE(msg, 0x80 | ie->l3_ttype | (ie->l3_tcap << 4));
4976121934Sharti			}
4977121934Sharti		} else {
4978121934Sharti			APP_BYTE(msg, (UNI_BLLI_L3_ID<<5)|ie->l3|0x80);
4979121934Sharti		}
4980121934Sharti	}
4981121934Sharti
4982121934Sharti  out:
4983121934Sharti	SET_IE_LEN(msg);
4984121934Sharti	return 0;
4985121934Sharti}
4986121934Sharti
4987121934ShartiDEF_IE_DECODE(itu, blli)
4988121934Sharti{
4989121934Sharti	u_char c;
4990121934Sharti
4991121934Sharti	IE_START(;);
4992121934Sharti
4993121934Sharti	if(ielen > 17)
4994121934Sharti		goto rej;
4995121934Sharti
4996121934Sharti	while(ielen--) {
4997121934Sharti		switch(((c = *msg->b_rptr++) >> 5) & 0x3) {
4998121934Sharti		  default:
4999121934Sharti			goto rej;
5000121934Sharti
5001121934Sharti		  case UNI_BLLI_L1_ID:
5002121934Sharti			ie->h.present |= UNI_BLLI_L1_P;
5003121934Sharti			ie->l1 = c & 0x1f;
5004121934Sharti			if(!(c & 0x80))
5005121934Sharti				goto rej;
5006121934Sharti			break;
5007121934Sharti
5008121934Sharti		  case UNI_BLLI_L2_ID:
5009121934Sharti			ie->h.present |= UNI_BLLI_L2_P;
5010121934Sharti			ie->l2 = c & 0x1f;
5011121934Sharti			if(!(c & 0x80)) {
5012121934Sharti				if(ielen == 0)
5013121934Sharti					goto rej;
5014121934Sharti				ielen--;
5015121934Sharti				c = *msg->b_rptr++;
5016121934Sharti				if(ie->l2 == UNI_BLLI_L2_USER) {
5017121934Sharti					ie->h.present |= UNI_BLLI_L2_USER_P;
5018121934Sharti					ie->l2_user = c & 0x7f;
5019121934Sharti					if(!(c & 0x80))
5020121934Sharti						goto rej;
5021121934Sharti				} else {
5022121934Sharti					ie->h.present |= UNI_BLLI_L2_Q933_P;
5023121934Sharti					ie->l2_q933 = c & 0x3;
5024121934Sharti					ie->l2_mode = (c >> 5) & 0x3;
5025121934Sharti					if(!(c & 0x80)) {
5026121934Sharti						if(ielen == 0)
5027121934Sharti							goto rej;
5028121934Sharti						ielen--;
5029121934Sharti						c = *msg->b_rptr++;
5030121934Sharti						ie->h.present |= UNI_BLLI_L2_WSIZ_P;
5031121934Sharti						ie->l2_wsiz = c & 0x7f;
5032121934Sharti						if(!(c & 0x80))
5033121934Sharti							goto rej;
5034121934Sharti					}
5035121934Sharti				}
5036121934Sharti			}
5037121934Sharti			break;
5038121934Sharti
5039121934Sharti		  case UNI_BLLI_L3_ID:
5040121934Sharti			ie->h.present |= UNI_BLLI_L3_P;
5041121934Sharti			ie->l3 = c & 0x1f;
5042121934Sharti			if(!(c & 0x80)) {
5043121934Sharti				switch(ie->l3) {
5044121934Sharti				  default:
5045121934Sharti				  case UNI_BLLI_L3_CLMP:
5046121934Sharti				  case UNI_BLLI_L3_T70:
5047121934Sharti					goto rej;
5048121934Sharti
5049121934Sharti				  case UNI_BLLI_L3_X25:
5050121934Sharti				  case UNI_BLLI_L3_ISO8208:
5051121934Sharti				  case UNI_BLLI_L3_X223:
5052121934Sharti					if(ielen == 0)
5053121934Sharti						goto rej;
5054121934Sharti					ielen--;
5055121934Sharti					c = *msg->b_rptr++;
5056121934Sharti					ie->l3_mode = (c >> 5) & 0x3;
5057121934Sharti					ie->h.present |= UNI_BLLI_L3_MODE_P;
5058121934Sharti
5059121934Sharti					if(c & 0x80)
5060121934Sharti						break;
5061121934Sharti
5062121934Sharti					if(ielen == 0)
5063121934Sharti						goto rej;
5064121934Sharti					ielen--;
5065121934Sharti					c = *msg->b_rptr++;
5066121934Sharti					ie->l3_psiz = c & 0xf;
5067121934Sharti					ie->h.present |= UNI_BLLI_L3_PSIZ_P;
5068121934Sharti
5069121934Sharti					if(c & 0x80)
5070121934Sharti						break;
5071121934Sharti
5072121934Sharti					if(ielen == 0)
5073121934Sharti						goto rej;
5074121934Sharti					ielen--;
5075121934Sharti					c = *msg->b_rptr++;
5076121934Sharti					ie->l3_wsiz = c & 0x7f;
5077121934Sharti					ie->h.present |= UNI_BLLI_L3_WSIZ_P;
5078121934Sharti
5079121934Sharti					if(!(c & 0x80))
5080121934Sharti						goto rej;
5081121934Sharti					break;
5082121934Sharti
5083121934Sharti				  case UNI_BLLI_L3_TR9577:
5084121934Sharti					if(ielen < 2)
5085121934Sharti						goto rej;
5086121934Sharti					ielen -= 2;
5087121934Sharti					c = *msg->b_rptr++;
5088121934Sharti					ie->l3_ipi = (c << 1) & 0xfe;
5089121934Sharti					if(c & 0x80)
5090121934Sharti						goto rej;
5091121934Sharti					c = *msg->b_rptr++;
5092121934Sharti					ie->l3_ipi |= c & 1;
5093121934Sharti					if(!(c & 0x80))
5094121934Sharti						goto rej;
5095121934Sharti					ie->h.present |= UNI_BLLI_L3_IPI_P;
5096121934Sharti
5097121934Sharti					if(ie->l3_ipi != UNI_BLLI_L3_SNAP)
5098121934Sharti						break;
5099121934Sharti					if(ielen < 6)
5100121934Sharti						goto rej;
5101121934Sharti					ielen -= 6;
5102121934Sharti					if(*msg->b_rptr++ != 0x80)
5103121934Sharti						goto rej;
5104121934Sharti					ie->h.present |= UNI_BLLI_L3_SNAP_P;
5105121934Sharti					ie->oui  = *msg->b_rptr++ << 16;
5106121934Sharti					ie->oui |= *msg->b_rptr++ << 8;
5107121934Sharti					ie->oui |= *msg->b_rptr++;
5108121934Sharti					ie->pid  = *msg->b_rptr++ << 8;
5109121934Sharti					ie->pid |= *msg->b_rptr++;
5110121934Sharti					break;
5111121934Sharti
5112121934Sharti				  case UNI_BLLI_L3_H310:
5113121934Sharti					if(ielen == 0)
5114121934Sharti						goto rej;
5115121934Sharti					ielen--;
5116121934Sharti					c = *msg->b_rptr++;
5117121934Sharti					ie->l3_ttype = c & 0xf;
5118121934Sharti					ie->l3_tcap = (c >> 4) & 0x7;
5119121934Sharti					ie->h.present |= UNI_BLLI_L3_TTYPE_P;
5120121934Sharti					if(c & 0x80)
5121121934Sharti						break;
5122121934Sharti					if(ielen == 0)
5123121934Sharti						goto rej;
5124121934Sharti					ielen--;
5125121934Sharti					c = *msg->b_rptr++;
5126121934Sharti					ie->l3_fmux = (c >> 3) & 7;
5127121934Sharti					ie->l3_bmux = c & 7;
5128121934Sharti					ie->h.present |= UNI_BLLI_L3_MUX_P;
5129121934Sharti					if(!(c & 0x80))
5130121934Sharti						goto rej;
5131121934Sharti					break;
5132121934Sharti
5133121934Sharti				  case UNI_BLLI_L3_USER:
5134121934Sharti					if(ielen == 0)
5135121934Sharti						goto rej;
5136121934Sharti					ielen--;
5137121934Sharti					c = *msg->b_rptr++;
5138121934Sharti					ie->l3_user = c & 0x7f;
5139121934Sharti					ie->h.present |= UNI_BLLI_L3_USER_P;
5140121934Sharti					if(!(c & 0x80))
5141121934Sharti						goto rej;
5142121934Sharti					break;
5143121934Sharti				}
5144121934Sharti			}
5145121934Sharti			break;
5146121934Sharti		}
5147121934Sharti	}
5148121934Sharti
5149121934Sharti	IE_END(BLLI);
5150121934Sharti}
5151121934Sharti
5152121934Sharti/*********************************************************************
5153121934Sharti *
5154121934Sharti * Broadband locking shift
5155121934Sharti * Broadband non-locking shift.
5156121934Sharti *
5157121934Sharti * References for this IE are:
5158121934Sharti *
5159121934Sharti *  Q.2931 pp. 41...42
5160121934Sharti *  UNI4.0 pp. 9
5161121934Sharti *
5162121934Sharti * Procedure not supported in UNI4.0, but IE's must be recognized.
5163121934Sharti *
5164121934Sharti * Only ITU-T coding allowed.
5165121934Sharti */
5166121934Sharti
5167121934ShartiDEF_IE_PRINT(itu, lshift)
5168121934Sharti{
5169121934Sharti	if(uni_print_iehdr("locking_shift", &ie->h, cx))
5170121934Sharti		return;
5171121934Sharti	uni_print_ieend(cx);
5172121934Sharti}
5173121934Sharti
5174121934ShartiDEF_IE_CHECK(itu, lshift)
5175121934Sharti{
5176228554Sdim	UNUSED(cx); UNUSED(ie);
5177121934Sharti	return -1;
5178121934Sharti}
5179121934Sharti
5180121934ShartiDEF_IE_ENCODE(itu, lshift)
5181121934Sharti{
5182121934Sharti	START_IE(lshift, UNI_IE_LSHIFT, 1);
5183121934Sharti	APP_BYTE(msg, 0x80 | ie->set);
5184121934Sharti	SET_IE_LEN(msg);
5185121934Sharti	return 0;
5186121934Sharti}
5187121934Sharti
5188121934ShartiDEF_IE_DECODE(itu, lshift)
5189121934Sharti{
5190121934Sharti	u_char c;
5191121934Sharti
5192121934Sharti	IE_START(;);
5193121934Sharti
5194121934Sharti	if(ielen != 1)
5195121934Sharti		goto rej;
5196121934Sharti
5197121934Sharti	c = *msg->b_rptr++;
5198121934Sharti
5199121934Sharti	if(!(c & 0x80))
5200121934Sharti		goto rej;
5201121934Sharti	ie->set = c & 7;
5202121934Sharti
5203121934Sharti	IE_END(LSHIFT);
5204121934Sharti}
5205121934Sharti
5206121934Sharti/***********************************************************************/
5207121934Sharti
5208121934ShartiDEF_IE_PRINT(itu, nlshift)
5209121934Sharti{
5210121934Sharti	if(uni_print_iehdr("nonlocking_shift", &ie->h, cx))
5211121934Sharti		return;
5212121934Sharti	uni_print_ieend(cx);
5213121934Sharti}
5214121934Sharti
5215121934ShartiDEF_IE_CHECK(itu, nlshift)
5216121934Sharti{
5217228554Sdim	UNUSED(cx); UNUSED(ie);
5218121934Sharti	return -1;
5219121934Sharti}
5220121934Sharti
5221121934ShartiDEF_IE_ENCODE(itu, nlshift)
5222121934Sharti{
5223121934Sharti	START_IE(nlshift, UNI_IE_NLSHIFT, 1);
5224121934Sharti	APP_BYTE(msg, 0x80 | ie->set);
5225121934Sharti	SET_IE_LEN(msg);
5226121934Sharti	return 0;
5227121934Sharti}
5228121934Sharti
5229121934ShartiDEF_IE_DECODE(itu, nlshift)
5230121934Sharti{
5231121934Sharti	u_char c;
5232121934Sharti
5233121934Sharti	IE_START(;);
5234121934Sharti
5235121934Sharti	if(ielen != 1)
5236121934Sharti		goto rej;
5237121934Sharti
5238121934Sharti	c = *msg->b_rptr++;
5239121934Sharti
5240121934Sharti	if(!(c & 0x80))
5241121934Sharti		goto rej;
5242121934Sharti	ie->set = c & 7;
5243121934Sharti
5244121934Sharti	IE_END(NLSHIFT);
5245121934Sharti}
5246121934Sharti
5247121934Sharti/*********************************************************************
5248121934Sharti *
5249121934Sharti * Broadband Sending Complete Indicator
5250121934Sharti *
5251121934Sharti * References for this IE are:
5252121934Sharti *
5253121934Sharti *  Q.2931 pp. 74-75
5254121934Sharti *
5255121934Sharti * Only ITU-T coding allowed.
5256121934Sharti */
5257121934ShartiDEF_IE_PRINT(itu, scompl)
5258121934Sharti{
5259121934Sharti	if(uni_print_iehdr("sending_complete", &ie->h, cx))
5260121934Sharti		return;
5261121934Sharti	uni_print_ieend(cx);
5262121934Sharti}
5263121934Sharti
5264121934ShartiDEF_IE_CHECK(itu, scompl)
5265121934Sharti{
5266228554Sdim	UNUSED(ie); UNUSED(cx);
5267121934Sharti	return 0;
5268121934Sharti}
5269121934Sharti
5270121934ShartiDEF_IE_ENCODE(itu, scompl)
5271121934Sharti{
5272121934Sharti	START_IE(scompl, UNI_IE_SCOMPL, 1);
5273121934Sharti
5274121934Sharti	APP_BYTE(msg, 0x80 | 0x21);
5275121934Sharti
5276121934Sharti	SET_IE_LEN(msg);
5277121934Sharti	return 0;
5278121934Sharti}
5279121934Sharti
5280121934ShartiDEF_IE_DECODE(itu, scompl)
5281121934Sharti{
5282121934Sharti	IE_START(;);
5283121934Sharti
5284121934Sharti	if(ielen != 1)
5285121934Sharti  		goto rej;
5286121934Sharti
5287121934Sharti	if(*msg->b_rptr++ != (0x80 | 0x21))
5288121934Sharti  		goto rej;
5289121934Sharti
5290121934Sharti	IE_END(SCOMPL);
5291121934Sharti}
5292121934Sharti
5293121934Sharti/*********************************************************************
5294121934Sharti *
5295121934Sharti * Broadband Repeat Indicator
5296121934Sharti *
5297121934Sharti * References for this IE are:
5298121934Sharti *
5299121934Sharti *  Q.2931 p.  73
5300121934Sharti *  PNNI1.0 p. 196
5301121934Sharti *
5302121934Sharti * Q.2931 has table 4-19. Only codepoints 0x2 and 0xa (for PNNI) supported.
5303121934Sharti *
5304121934Sharti * Only ITU-T coding allowed.
5305121934Sharti */
5306121934ShartiDEF_IE_PRINT(itu, repeat)
5307121934Sharti{
5308121934Sharti	static const struct uni_print_tbl tbl[] = {
5309121934Sharti		MKT(UNI_REPEAT_PRIDESC,	desc),
5310121934Sharti		MKT(UNI_REPEAT_STACK,   stack),
5311121934Sharti		EOT()
5312121934Sharti	};
5313121934Sharti
5314121934Sharti	if(uni_print_iehdr("repeat", &ie->h, cx))
5315121934Sharti		return;
5316121934Sharti	uni_print_tbl("type", ie->type, tbl, cx);
5317121934Sharti	uni_print_ieend(cx);
5318121934Sharti}
5319121934Sharti
5320121934ShartiDEF_IE_CHECK(itu, repeat)
5321121934Sharti{
5322121934Sharti	switch(ie->type) {
5323121934Sharti
5324121934Sharti	  case UNI_REPEAT_PRIDESC:
5325121934Sharti		break;
5326121934Sharti
5327121934Sharti	  case UNI_REPEAT_STACK:
5328121934Sharti		if(!cx->pnni)
5329121934Sharti			return -1;
5330121934Sharti		break;
5331121934Sharti
5332121934Sharti	  default:
5333121934Sharti		return -1;
5334121934Sharti	}
5335121934Sharti	return 0;
5336121934Sharti}
5337121934Sharti
5338121934ShartiDEF_IE_ENCODE(itu, repeat)
5339121934Sharti{
5340121934Sharti	START_IE(repeat, UNI_IE_REPEAT, 1);
5341121934Sharti
5342121934Sharti	APP_BYTE(msg, 0x80 | ie->type);
5343121934Sharti
5344121934Sharti	SET_IE_LEN(msg);
5345121934Sharti	return 0;
5346121934Sharti}
5347121934Sharti
5348121934ShartiDEF_IE_DECODE(itu, repeat)
5349121934Sharti{
5350121934Sharti	u_char c;
5351121934Sharti
5352121934Sharti	IE_START(;);
5353121934Sharti
5354121934Sharti	if(ielen != 1)
5355121934Sharti  		goto rej;
5356121934Sharti
5357121934Sharti	c = *msg->b_rptr++;
5358121934Sharti	if(!(c & 0x80))
5359121934Sharti  		goto rej;
5360121934Sharti	ie->type = c & 0xf;
5361121934Sharti
5362121934Sharti	IE_END(REPEAT);
5363121934Sharti}
5364121934Sharti
5365121934Sharti/*********************************************************************
5366121934Sharti *
5367121934Sharti * Transit Network Selection
5368121934Sharti *
5369121934Sharti * References for this IE are:
5370121934Sharti *
5371121934Sharti *  Q.2931 pp. 75...76
5372121934Sharti *  UNI4.0 pp. 17
5373121934Sharti *
5374121934Sharti * According to UNI4.0 this is always National Network Id/Carried Id.
5375121934Sharti *
5376121934Sharti * ITU-T/Net coding allowed.
5377121934Sharti */
5378121934Sharti
5379121934ShartiDEF_IE_PRINT(itu, tns)
5380121934Sharti{
5381121934Sharti	u_int i;
5382121934Sharti
5383121934Sharti	if(uni_print_iehdr("tns", &ie->h, cx))
5384121934Sharti		return;
5385121934Sharti	uni_print_entry(cx, "net", "%u,\"", ie->len);
5386121934Sharti	uni_putc('"', cx);
5387121934Sharti	for(i = 0; i < ie->len; i++) {
5388121934Sharti		if(ie->net[i] < ' ')
5389121934Sharti			uni_printf(cx, "^%c", ie->net[i] + '@');
5390121934Sharti		else if(ie->net[i] < '~')
5391121934Sharti			uni_putc(ie->net[i], cx);
5392121934Sharti		else
5393121934Sharti			uni_printf(cx, "\\%03o", ie->net[i]);
5394121934Sharti	}
5395121934Sharti	uni_putc('"', cx);
5396121934Sharti	uni_print_ieend(cx);
5397121934Sharti}
5398121934Sharti
5399121934ShartiDEF_IE_CHECK(itu, tns)
5400121934Sharti{
5401121934Sharti	u_int i;
5402121934Sharti
5403228554Sdim	UNUSED(cx);
5404121934Sharti
5405121934Sharti	if(ie->len == 0 || ie->len > UNI_TNS_MAXLEN)
5406121934Sharti		return -1;
5407121934Sharti	for(i = 0; i < ie->len; i++)
5408121934Sharti		if(ie->net[i] < ' ' || ie->net[i] > '~')
5409121934Sharti			return -1;
5410121934Sharti	return 0;
5411121934Sharti}
5412121934Sharti
5413121934ShartiDEF_IE_ENCODE(itu, tns)
5414121934Sharti{
5415121934Sharti	START_IE(tns, UNI_IE_TNS, ie->len + 1);
5416121934Sharti
5417121934Sharti	APP_BYTE(msg, 0x80 | (0x2 << 4) | 0x1);
5418121934Sharti	APP_BUF(msg, ie->net, ie->len);
5419121934Sharti
5420121934Sharti	SET_IE_LEN(msg);
5421121934Sharti	return 0;
5422121934Sharti}
5423121934Sharti
5424121934ShartiDEF_IE_DECODE(itu, tns)
5425121934Sharti{
5426121934Sharti	IE_START(;);
5427121934Sharti
5428121934Sharti	if(ielen < 2 || ielen > 5)
5429121934Sharti		goto rej;
5430121934Sharti
5431121934Sharti	if(*msg->b_rptr++ != (0x80 | (0x2 << 4) | 0x1))
5432121934Sharti		goto rej;
5433121934Sharti	ielen--;
5434121934Sharti
5435121934Sharti	ie->len = 0;
5436121934Sharti	while(ielen--)
5437121934Sharti		ie->net[ie->len++] = *msg->b_rptr++;
5438121934Sharti
5439121934Sharti	IE_END(TNS);
5440121934Sharti}
5441121934Sharti
5442121934Sharti/*********************************************************************
5443121934Sharti *
5444121934Sharti * Restart indicator
5445121934Sharti *
5446121934Sharti * References for this IE are:
5447121934Sharti *
5448121934Sharti *  Q.2931 pp. 73...74
5449121934Sharti *  UNI4.0 p.  17
5450121934Sharti *
5451121934Sharti * Only ITU-T coding allowed.
5452121934Sharti */
5453121934Sharti
5454121934ShartiDEF_IE_PRINT(itu, restart)
5455121934Sharti{
5456121934Sharti	static const struct uni_print_tbl tbl[] = {
5457121934Sharti		MKT(UNI_RESTART_CHANNEL,	channel),
5458121934Sharti		MKT(UNI_RESTART_PATH,		path),
5459121934Sharti		MKT(UNI_RESTART_ALL,		all),
5460121934Sharti		EOT()
5461121934Sharti	};
5462121934Sharti
5463121934Sharti	if(uni_print_iehdr("restart", &ie->h, cx))
5464121934Sharti		return;
5465121934Sharti	uni_print_tbl("class", ie->rclass, tbl, cx);
5466121934Sharti	uni_print_ieend(cx);
5467121934Sharti}
5468121934Sharti
5469121934ShartiDEF_IE_CHECK(itu, restart)
5470121934Sharti{
5471228554Sdim	UNUSED(cx);
5472121934Sharti
5473121934Sharti	switch(ie->rclass) {
5474121934Sharti	  default:
5475121934Sharti		return -1;
5476121934Sharti
5477121934Sharti	  case UNI_RESTART_CHANNEL:
5478121934Sharti	  case UNI_RESTART_PATH:
5479121934Sharti	  case UNI_RESTART_ALL:
5480121934Sharti		break;
5481121934Sharti	}
5482121934Sharti
5483121934Sharti	return 0;
5484121934Sharti}
5485121934Sharti
5486121934ShartiDEF_IE_ENCODE(itu, restart)
5487121934Sharti{
5488121934Sharti	START_IE(restart, UNI_IE_RESTART, 1);
5489121934Sharti
5490121934Sharti	APP_BYTE(msg, 0x80 | ie->rclass);
5491121934Sharti
5492121934Sharti	SET_IE_LEN(msg);
5493121934Sharti	return 0;
5494121934Sharti}
5495121934Sharti
5496121934ShartiDEF_IE_DECODE(itu, restart)
5497121934Sharti{
5498121934Sharti	u_char c;
5499121934Sharti
5500121934Sharti	IE_START(;);
5501121934Sharti
5502121934Sharti	if(ielen != 1)
5503121934Sharti		goto rej;
5504121934Sharti
5505121934Sharti	ie->rclass = (c = *msg->b_rptr++) & 0x7;
5506121934Sharti
5507121934Sharti	if(!(c & 0x80))
5508121934Sharti		goto rej;
5509121934Sharti
5510121934Sharti	IE_END(RESTART);
5511121934Sharti}
5512121934Sharti
5513121934Sharti/*********************************************************************
5514121934Sharti *
5515121934Sharti * User-to-user info.
5516121934Sharti *
5517121934Sharti * References for this IE are:
5518121934Sharti *
5519121934Sharti *  Q.2957
5520121934Sharti *
5521121934Sharti * Only ITU-T coding allowed.
5522121934Sharti */
5523121934Sharti
5524121934ShartiDEF_IE_PRINT(itu, uu)
5525121934Sharti{
5526121934Sharti	u_int i;
5527121934Sharti
5528121934Sharti	if(uni_print_iehdr("uu", &ie->h, cx))
5529121934Sharti		return;
5530121934Sharti	uni_print_entry(cx, "len", "%u", ie->len);
5531121934Sharti	uni_print_entry(cx, "info", "(");
5532121934Sharti	for(i = 0; i < ie->len; i++)
5533121934Sharti		uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->uu[i]);
5534121934Sharti	uni_printf(cx, ")");
5535121934Sharti	uni_print_ieend(cx);
5536121934Sharti}
5537121934Sharti
5538121934ShartiDEF_IE_CHECK(itu, uu)
5539121934Sharti{
5540228554Sdim	UNUSED(cx);
5541121934Sharti
5542121934Sharti	if(ie->len > UNI_UU_MAXLEN)
5543121934Sharti		return -1;
5544121934Sharti
5545121934Sharti	return 0;
5546121934Sharti}
5547121934Sharti
5548121934ShartiDEF_IE_ENCODE(itu, uu)
5549121934Sharti{
5550121934Sharti	START_IE(uu, UNI_IE_UU, ie->len);
5551121934Sharti
5552121934Sharti	APP_BUF(msg, ie->uu, ie->len);
5553121934Sharti
5554121934Sharti	SET_IE_LEN(msg);
5555121934Sharti	return 0;
5556121934Sharti}
5557121934Sharti
5558121934ShartiDEF_IE_DECODE(itu, uu)
5559121934Sharti{
5560121934Sharti	IE_START(;);
5561121934Sharti
5562121934Sharti	if(ielen > UNI_UU_MAXLEN || ielen < 1)
5563121934Sharti		goto rej;
5564121934Sharti
5565121934Sharti	ie->len = ielen;
5566121934Sharti	ielen = 0;
5567121934Sharti	(void)memcpy(ie->uu, msg->b_rptr, ie->len);
5568121934Sharti	msg->b_rptr += ie->len;
5569121934Sharti
5570121934Sharti	IE_END(UU);
5571121934Sharti}
5572121934Sharti
5573121934Sharti/*********************************************************************
5574121934Sharti *
5575121934Sharti * Generic Identifier Transport
5576121934Sharti *
5577121934Sharti * References for this IE are:
5578121934Sharti *
5579121934Sharti *  UNI4.0 pp. 26...28
5580121934Sharti *
5581121934Sharti * UNI4.0 prescribes a fixed format for this IE. We have a flag in the
5582121934Sharti * context structur, which tells us whether the check of this IE should be
5583121934Sharti * hard or soft. Probably it should be hard for end systems and soft for
5584121934Sharti * network nodes.
5585121934Sharti *
5586121934Sharti * Only Net Coding allowed. (XXX)
5587121934Sharti */
5588121934Sharti
5589121934ShartiDEF_IE_PRINT(net, git)
5590121934Sharti{
5591121934Sharti	static const struct uni_print_tbl std_tbl[] = {
5592121934Sharti		MKT(UNI_GIT_STD_DSMCC,	dsmcc),
5593121934Sharti		MKT(UNI_GIT_STD_H245,	H.245),
5594121934Sharti		EOT()
5595121934Sharti	};
5596121934Sharti	static const struct uni_print_tbl type_tbl[] = {
5597121934Sharti		MKT(UNI_GIT_TYPE_SESS,	sess),
5598121934Sharti		MKT(UNI_GIT_TYPE_RES,	res),
5599121934Sharti		EOT()
5600121934Sharti	};
5601121934Sharti	u_int i, j;
5602121934Sharti	char buf[20];
5603121934Sharti
5604121934Sharti	if(uni_print_iehdr("git", &ie->h, cx))
5605121934Sharti		return;
5606121934Sharti
5607121934Sharti	uni_print_tbl("std", ie->std, std_tbl, cx);
5608121934Sharti
5609121934Sharti	uni_print_eol(cx);
5610121934Sharti	uni_print_push_prefix("id", cx);
5611121934Sharti	cx->indent++;
5612121934Sharti	for(i = 0; i < ie->numsub; i++) {
5613121934Sharti		sprintf(buf, "%u", i);
5614121934Sharti		uni_print_entry(cx, buf, "(");
5615121934Sharti		uni_print_tbl(NULL, ie->sub[i].type, type_tbl, cx);
5616121934Sharti		for(j = 0; j < ie->sub[i].len; j++)
5617121934Sharti			uni_printf(cx, ",0x%02x", ie->sub[i].val[j]);
5618121934Sharti		uni_printf(cx, ")");
5619121934Sharti		uni_print_eol(cx);
5620121934Sharti	}
5621121934Sharti	cx->indent--;
5622121934Sharti	uni_print_pop_prefix(cx);
5623121934Sharti
5624121934Sharti	uni_print_ieend(cx);
5625121934Sharti}
5626121934Sharti
5627121934ShartiDEF_IE_CHECK(net, git)
5628121934Sharti{
5629121934Sharti	u_int i;
5630121934Sharti
5631121934Sharti	if(cx->git_hard) {
5632121934Sharti		switch(ie->std) {
5633121934Sharti		  case UNI_GIT_STD_DSMCC:
5634121934Sharti		  case UNI_GIT_STD_H245:
5635121934Sharti			break;
5636121934Sharti		  default:
5637121934Sharti			return -1;
5638121934Sharti		}
5639121934Sharti		if(ie->numsub != 2)
5640121934Sharti			return -1;
5641121934Sharti		if(ie->sub[0].type != UNI_GIT_TYPE_SESS)
5642121934Sharti			return -1;
5643121934Sharti		if(ie->sub[0].len > UNI_GIT_MAXSESS)
5644121934Sharti			return -1;
5645121934Sharti		if(ie->sub[1].type != UNI_GIT_TYPE_RES)
5646121934Sharti			return -1;
5647121934Sharti		if(ie->sub[1].len > UNI_GIT_MAXRES)
5648121934Sharti			return -1;
5649121934Sharti	} else {
5650121934Sharti		if(ie->numsub > UNI_GIT_MAXSUB)
5651121934Sharti			return -1;
5652121934Sharti		for(i = 0; i < ie->numsub; i++)
5653121934Sharti			if(ie->sub[i].len > UNI_GIT_MAXVAL)
5654121934Sharti				return -1;
5655121934Sharti	}
5656121934Sharti	return 0;
5657121934Sharti}
5658121934Sharti
5659121934ShartiDEF_IE_ENCODE(net, git)
5660121934Sharti{
5661121934Sharti	u_int i;
5662121934Sharti
5663121934Sharti	START_IE(git, UNI_IE_GIT, 1 + ie->numsub * (1 + UNI_GIT_MAXVAL));
5664121934Sharti
5665121934Sharti	APP_BYTE(msg, ie->std);
5666121934Sharti	for(i = 0; i < ie->numsub; i++) {
5667121934Sharti		APP_BYTE(msg, ie->sub[i].type);
5668121934Sharti		APP_BYTE(msg, ie->sub[i].len);
5669121934Sharti		APP_BUF(msg, ie->sub[i].val, ie->sub[i].len);
5670121934Sharti	}
5671121934Sharti
5672121934Sharti	SET_IE_LEN(msg);
5673121934Sharti	return 0;
5674121934Sharti}
5675121934Sharti
5676121934ShartiDEF_IE_DECODE(net, git)
5677121934Sharti{
5678121934Sharti	IE_START(;);
5679121934Sharti
5680121934Sharti	if(ielen > 1 + UNI_GIT_MAXSUB * (1 + UNI_GIT_MAXVAL) || ielen < 1)
5681121934Sharti		goto rej;
5682121934Sharti
5683121934Sharti	ie->std = *msg->b_rptr++;
5684121934Sharti	ielen--;
5685121934Sharti
5686121934Sharti	ie->numsub = 0;
5687121934Sharti	while(ielen > 0) {
5688121934Sharti		if(ie->numsub >= UNI_GIT_MAXSUB)
5689121934Sharti			goto rej;
5690121934Sharti
5691121934Sharti		ie->sub[ie->numsub].type = *msg->b_rptr++;
5692121934Sharti		ielen--;
5693121934Sharti
5694121934Sharti		if(ielen == 0)
5695121934Sharti			goto rej;
5696121934Sharti		ie->sub[ie->numsub].len = *msg->b_rptr++;
5697121934Sharti		ielen--;
5698121934Sharti
5699121934Sharti		if(ie->sub[ie->numsub].len > UNI_GIT_MAXVAL)
5700121934Sharti			goto rej;
5701121934Sharti		if(ie->sub[ie->numsub].len > (u_int)ielen)
5702121934Sharti			goto rej;
5703121934Sharti
5704121934Sharti		(void)memcpy(ie->sub[ie->numsub].val, msg->b_rptr, ie->sub[ie->numsub].len);
5705121934Sharti		ielen -= ie->sub[ie->numsub].len;
5706121934Sharti		msg->b_rptr += ie->sub[ie->numsub].len;
5707121934Sharti
5708121934Sharti		ie->numsub++;
5709121934Sharti	}
5710121934Sharti
5711121934Sharti	IE_END(GIT);
5712121934Sharti}
5713121934Sharti
5714121934Sharti/*********************************************************************
5715121934Sharti *
5716121934Sharti * Additional ABR Parameters
5717121934Sharti * ABR Setup parameters
5718121934Sharti *
5719121934Sharti * References for this IE are:
5720121934Sharti *
5721121934Sharti *  	UNI4.0 pp. 78...82
5722121934Sharti *	PNNI1.0 p. 195
5723121934Sharti *
5724121934Sharti * Notes:
5725121934Sharti *	Only NET coding.
5726121934Sharti */
5727121934Sharti
5728121934Shartistatic void
5729121934Shartiprint_abr_rec(struct unicx *cx, struct uni_abr_rec *rec)
5730121934Sharti{
5731121934Sharti	if(rec->present & UNI_ABR_REC_NRM_P)
5732121934Sharti		uni_print_entry(cx, "nrm", "%d", rec->nrm);
5733121934Sharti	if(rec->present & UNI_ABR_REC_TRM_P)
5734121934Sharti		uni_print_entry(cx, "trm", "%d", rec->trm);
5735121934Sharti	if(rec->present & UNI_ABR_REC_CDF_P)
5736121934Sharti		uni_print_entry(cx, "cdf", "%d", rec->cdf);
5737121934Sharti	if(rec->present & UNI_ABR_REC_ADTF_P)
5738121934Sharti		uni_print_entry(cx, "adtf", "%d", rec->adtf);
5739121934Sharti}
5740121934Sharti
5741121934ShartiDEF_IE_PRINT(net, abradd)
5742121934Sharti{
5743121934Sharti	if(uni_print_iehdr("abradd", &ie->h, cx))
5744121934Sharti		return;
5745121934Sharti
5746121934Sharti	uni_print_push_prefix("fwd", cx);
5747121934Sharti	print_abr_rec(cx, &ie->fwd);
5748121934Sharti	uni_print_pop_prefix(cx);
5749121934Sharti
5750121934Sharti	uni_print_push_prefix("bwd", cx);
5751121934Sharti	print_abr_rec(cx, &ie->bwd);
5752121934Sharti	uni_print_pop_prefix(cx);
5753121934Sharti
5754121934Sharti	uni_print_ieend(cx);
5755121934Sharti}
5756121934Sharti
5757121934ShartiDEF_IE_CHECK(net, abradd)
5758121934Sharti{
5759228554Sdim	UNUSED(cx);
5760228554Sdim	UNUSED(ie);
5761121934Sharti
5762121934Sharti	return 0;
5763121934Sharti}
5764121934Sharti
5765121934Shartistatic u_int
5766121934Shartiencode_abr_rec(struct uni_abr_rec *rec)
5767121934Sharti{
5768121934Sharti	u_int ret = rec->present & 0xf000;
5769121934Sharti
5770121934Sharti	if(ret & UNI_ABR_REC_NRM_P)
5771121934Sharti		ret |= (rec->nrm & 0x7) << 25;
5772121934Sharti	if(ret & UNI_ABR_REC_TRM_P)
5773121934Sharti		ret |= (rec->trm & 0x7) << 22;
5774121934Sharti	if(ret & UNI_ABR_REC_CDF_P)
5775121934Sharti		ret |= (rec->cdf & 0x7) << 19;
5776121934Sharti	if(ret & UNI_ABR_REC_ADTF_P)
5777121934Sharti		ret |= (rec->adtf & 0x3ff) << 9;
5778121934Sharti
5779121934Sharti	return ret;
5780121934Sharti}
5781121934Sharti
5782121934ShartiDEF_IE_ENCODE(net, abradd)
5783121934Sharti{
5784121934Sharti	START_IE(abradd, UNI_IE_ABRADD, 10);
5785121934Sharti
5786121934Sharti	APP_SUB_32BIT(msg, UNI_ABRADD_FADD_ID, encode_abr_rec(&ie->fwd));
5787121934Sharti	APP_SUB_32BIT(msg, UNI_ABRADD_BADD_ID, encode_abr_rec(&ie->bwd));
5788121934Sharti
5789121934Sharti	SET_IE_LEN(msg);
5790121934Sharti	return 0;
5791121934Sharti}
5792121934Sharti
5793121934Shartistatic int
5794121934Shartidecode_abr_rec(struct uni_msg *msg, struct uni_abr_rec *rec)
5795121934Sharti{
5796121934Sharti	u_int val;
5797121934Sharti
5798121934Sharti	val  = *msg->b_rptr++ << 24;
5799121934Sharti	val |= *msg->b_rptr++ << 16;
5800121934Sharti	val |= *msg->b_rptr++ <<  8;
5801121934Sharti	val |= *msg->b_rptr++ <<  0;
5802121934Sharti
5803121934Sharti	rec->present = val & 0xf000;
5804121934Sharti
5805121934Sharti	rec->nrm  = (val & UNI_ABR_REC_NRM_P) ? ((val >> 25) & 0x7) : 0;
5806121934Sharti	rec->trm  = (val & UNI_ABR_REC_TRM_P) ? ((val >> 22) & 0x7) : 0;
5807121934Sharti	rec->cdf  = (val & UNI_ABR_REC_CDF_P) ? ((val >> 19) & 0x7) : 0;
5808121934Sharti	rec->adtf = (val & UNI_ABR_REC_ADTF_P)? ((val >>  9) & 0x3ff) : 0;
5809121934Sharti
5810121934Sharti	return 0;
5811121934Sharti}
5812121934Sharti
5813121934ShartiDEF_IE_DECODE(net, abradd)
5814121934Sharti{
5815121934Sharti	IE_START(;);
5816121934Sharti
5817121934Sharti	if(ielen != 10)
5818121934Sharti		goto rej;
5819121934Sharti
5820121934Sharti
5821121934Sharti	while(ielen--) {
5822121934Sharti		switch(*msg->b_rptr++) {
5823121934Sharti
5824121934Sharti		  default:
5825121934Sharti			goto rej;
5826121934Sharti
5827121934Sharti		  case UNI_ABRADD_FADD_ID:
5828121934Sharti			if(decode_abr_rec(msg, &ie->fwd))
5829121934Sharti				goto rej;
5830121934Sharti			ielen -= 4;
5831121934Sharti			break;
5832121934Sharti
5833121934Sharti		  case UNI_ABRADD_BADD_ID:
5834121934Sharti			if(decode_abr_rec(msg, &ie->bwd))
5835121934Sharti				goto rej;
5836121934Sharti			ielen -= 4;
5837121934Sharti			break;
5838121934Sharti		}
5839121934Sharti	}
5840121934Sharti	IE_END(ABRADD);
5841121934Sharti}
5842121934Sharti
5843121934Sharti/*********************************************************************/
5844121934Sharti
5845121934ShartiDEF_IE_PRINT(net, abrsetup)
5846121934Sharti{
5847121934Sharti	if(uni_print_iehdr("abrsetup", &ie->h, cx))
5848121934Sharti		return;
5849121934Sharti
5850121934Sharti	uni_print_entry(cx, "rm_frt", "%d", ie->rmfrt);
5851121934Sharti
5852121934Sharti	uni_print_push_prefix("fwd", cx);
5853121934Sharti	if(ie->h.present & UNI_ABRSETUP_FICR_P)
5854121934Sharti		uni_print_entry(cx, "icr", "%d", ie->ficr);
5855121934Sharti	if(ie->h.present & UNI_ABRSETUP_FTBE_P)
5856121934Sharti		uni_print_entry(cx, "tbe", "%d", ie->ftbe);
5857121934Sharti	if(ie->h.present & UNI_ABRSETUP_FRIF_P)
5858121934Sharti		uni_print_entry(cx, "rif", "%d", ie->frif);
5859121934Sharti	if(ie->h.present & UNI_ABRSETUP_FRDF_P)
5860121934Sharti		uni_print_entry(cx, "rdf", "%d", ie->frdf);
5861121934Sharti	uni_print_pop_prefix(cx);
5862121934Sharti
5863121934Sharti	uni_print_push_prefix("bwd", cx);
5864121934Sharti	if(ie->h.present & UNI_ABRSETUP_BICR_P)
5865121934Sharti		uni_print_entry(cx, "icr", "%d", ie->bicr);
5866121934Sharti	if(ie->h.present & UNI_ABRSETUP_BTBE_P)
5867121934Sharti		uni_print_entry(cx, "tbe", "%d", ie->btbe);
5868121934Sharti	if(ie->h.present & UNI_ABRSETUP_BRIF_P)
5869121934Sharti		uni_print_entry(cx, "rif", "%d", ie->brif);
5870121934Sharti	if(ie->h.present & UNI_ABRSETUP_BRDF_P)
5871121934Sharti		uni_print_entry(cx, "rdf", "%d", ie->brdf);
5872121934Sharti	uni_print_pop_prefix(cx);
5873121934Sharti
5874121934Sharti	uni_print_ieend(cx);
5875121934Sharti}
5876121934Sharti
5877121934ShartiDEF_IE_CHECK(net, abrsetup)
5878121934Sharti{
5879121934Sharti	if(cx->pnni) {
5880121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_FICR_P))
5881121934Sharti			return -1;
5882121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_BICR_P))
5883121934Sharti			return -1;
5884121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_FTBE_P))
5885121934Sharti			return -1;
5886121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_BTBE_P))
5887121934Sharti			return -1;
5888121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_FRIF_P))
5889121934Sharti			return -1;
5890121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_BRIF_P))
5891121934Sharti			return -1;
5892121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_FRDF_P))
5893121934Sharti			return -1;
5894121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_BRDF_P))
5895121934Sharti			return -1;
5896121934Sharti		if(!(ie->h.present & UNI_ABRSETUP_RMFRT_P))
5897121934Sharti			return -1;
5898121934Sharti	}
5899121934Sharti
5900121934Sharti	if(!(ie->h.present & UNI_ABRSETUP_RMFRT_P))
5901121934Sharti		return -1;
5902121934Sharti
5903121934Sharti	if(ie->h.present & UNI_ABRSETUP_FICR_P)
5904121934Sharti		if(ie->ficr >= 1 << 24)
5905121934Sharti			return -1;
5906121934Sharti	if(ie->h.present & UNI_ABRSETUP_BICR_P)
5907121934Sharti		if(ie->bicr >= 1 << 24)
5908121934Sharti			return -1;
5909121934Sharti
5910121934Sharti	if(ie->h.present & UNI_ABRSETUP_FTBE_P)
5911121934Sharti		if(ie->ftbe >= 1 << 24 || ie->ftbe == 0)
5912121934Sharti			return -1;
5913121934Sharti	if(ie->h.present & UNI_ABRSETUP_BTBE_P)
5914121934Sharti		if(ie->btbe >= 1 << 24 || ie->btbe == 0)
5915121934Sharti			return -1;
5916121934Sharti
5917121934Sharti	if(ie->rmfrt >= 1 << 24)
5918121934Sharti		return -1;
5919121934Sharti
5920121934Sharti	if(ie->h.present & UNI_ABRSETUP_FRIF_P)
5921121934Sharti		if(ie->frif > 15)
5922121934Sharti			return -1;
5923121934Sharti	if(ie->h.present & UNI_ABRSETUP_FRDF_P)
5924121934Sharti		if(ie->frdf > 15)
5925121934Sharti			return -1;
5926121934Sharti	if(ie->h.present & UNI_ABRSETUP_BRIF_P)
5927121934Sharti		if(ie->brif > 15)
5928121934Sharti			return -1;
5929121934Sharti	if(ie->h.present & UNI_ABRSETUP_BRDF_P)
5930121934Sharti		if(ie->brdf > 15)
5931121934Sharti			return -1;
5932121934Sharti	return 0;
5933121934Sharti}
5934121934Sharti
5935121934ShartiDEF_IE_ENCODE(net, abrsetup)
5936121934Sharti{
5937121934Sharti	START_IE(abrsetup, UNI_IE_ABRSETUP, 32);
5938121934Sharti
5939121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_FICR_P,
5940121934Sharti		UNI_ABRSETUP_FICR_ID, ie->ficr);
5941121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_BICR_P,
5942121934Sharti		UNI_ABRSETUP_BICR_ID, ie->bicr);
5943121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_FTBE_P,
5944121934Sharti		UNI_ABRSETUP_FTBE_ID, ie->ftbe);
5945121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_ABRSETUP_BTBE_P,
5946121934Sharti		UNI_ABRSETUP_BTBE_ID, ie->btbe);
5947121934Sharti	APP_SUB_24BIT(msg, UNI_ABRSETUP_RMFRT_ID, ie->rmfrt);
5948121934Sharti	APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_FRIF_P,
5949121934Sharti		UNI_ABRSETUP_FRIF_ID, ie->frif);
5950121934Sharti	APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_BRIF_P,
5951121934Sharti		UNI_ABRSETUP_BRIF_ID, ie->brif);
5952121934Sharti	APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_FRDF_P,
5953121934Sharti		UNI_ABRSETUP_FRDF_ID, ie->frdf);
5954121934Sharti	APP_OPT_BYTE(msg, ie->h.present, UNI_ABRSETUP_BRDF_P,
5955121934Sharti		UNI_ABRSETUP_BRDF_ID, ie->brdf);
5956121934Sharti
5957121934Sharti	SET_IE_LEN(msg);
5958121934Sharti	return 0;
5959121934Sharti}
5960121934Sharti
5961121934ShartiDEF_IE_DECODE(net, abrsetup)
5962121934Sharti{
5963121934Sharti	IE_START(;);
5964121934Sharti
5965121934Sharti	if(ielen < 4 || ielen > 32)
5966121934Sharti		goto rej;
5967121934Sharti
5968121934Sharti
5969121934Sharti	while(ielen--) {
5970121934Sharti		switch(*msg->b_rptr++) {
5971121934Sharti
5972121934Sharti		  default:
5973121934Sharti			goto rej;
5974121934Sharti
5975121934Sharti
5976121934Sharti		  DEC_GETF3(ABRSETUP_FICR, ficr, ie->h.present);
5977121934Sharti		  DEC_GETF3(ABRSETUP_BICR, bicr, ie->h.present);
5978121934Sharti		  DEC_GETF3(ABRSETUP_FTBE, ftbe, ie->h.present);
5979121934Sharti		  DEC_GETF3(ABRSETUP_BTBE, btbe, ie->h.present);
5980121934Sharti		  DEC_GETF1(ABRSETUP_FRIF, frif, ie->h.present);
5981121934Sharti		  DEC_GETF1(ABRSETUP_BRIF, brif, ie->h.present);
5982121934Sharti		  DEC_GETF1(ABRSETUP_FRDF, frdf, ie->h.present);
5983121934Sharti		  DEC_GETF1(ABRSETUP_BRDF, brdf, ie->h.present);
5984121934Sharti		  DEC_GETF3(ABRSETUP_RMFRT, frif, ie->h.present);
5985121934Sharti		}
5986121934Sharti	}
5987121934Sharti	IE_END(ABRSETUP);
5988121934Sharti}
5989121934Sharti
5990121934Sharti/*********************************************************************
5991121934Sharti *
5992121934Sharti * Broadband report type
5993121934Sharti *
5994121934Sharti * References for this IE are:
5995121934Sharti *
5996121934Sharti *  Q.2963.1  pp. 7...8
5997121934Sharti *
5998121934Sharti * Only ITU-T coding allowed.
5999121934Sharti */
6000121934Sharti
6001121934ShartiDEF_IE_PRINT(itu, report)
6002121934Sharti{
6003121934Sharti	static const struct uni_print_tbl tbl[] = {
6004121934Sharti		MKT(UNI_REPORT_MODCONF,	modconf),
6005121934Sharti		MKT(UNI_REPORT_CLOCK,	clock),
6006121934Sharti		MKT(UNI_REPORT_EEAVAIL,	eeavail),
6007121934Sharti		MKT(UNI_REPORT_EEREQ,	eereq),
6008121934Sharti		MKT(UNI_REPORT_EECOMPL,	eecompl),
6009121934Sharti		EOT()
6010121934Sharti	};
6011121934Sharti
6012121934Sharti	if(uni_print_iehdr("report", &ie->h, cx))
6013121934Sharti		return;
6014121934Sharti	uni_print_tbl("type", ie->report, tbl, cx);
6015121934Sharti	uni_print_ieend(cx);
6016121934Sharti}
6017121934Sharti
6018121934ShartiDEF_IE_CHECK(itu, report)
6019121934Sharti{
6020228554Sdim	UNUSED(cx);
6021121934Sharti
6022121934Sharti	switch(ie->report) {
6023121934Sharti
6024121934Sharti	  default:
6025121934Sharti		return -1;
6026121934Sharti
6027121934Sharti	  case UNI_REPORT_MODCONF:
6028121934Sharti	  case UNI_REPORT_CLOCK:
6029121934Sharti	  case UNI_REPORT_EEAVAIL:
6030121934Sharti	  case UNI_REPORT_EEREQ:
6031121934Sharti	  case UNI_REPORT_EECOMPL:
6032121934Sharti		break;
6033121934Sharti	}
6034121934Sharti	return 0;
6035121934Sharti}
6036121934Sharti
6037121934ShartiDEF_IE_ENCODE(itu, report)
6038121934Sharti{
6039121934Sharti	START_IE(report, UNI_IE_REPORT, 1);
6040121934Sharti
6041121934Sharti	APP_BYTE(msg, ie->report);
6042121934Sharti
6043121934Sharti	SET_IE_LEN(msg);
6044121934Sharti	return 0;
6045121934Sharti}
6046121934Sharti
6047121934ShartiDEF_IE_DECODE(itu, report)
6048121934Sharti{
6049121934Sharti	IE_START(;);
6050121934Sharti	if(ielen != 1)
6051121934Sharti		goto rej;
6052121934Sharti
6053121934Sharti	ie->report = *msg->b_rptr++;
6054121934Sharti
6055121934Sharti	IE_END(REPORT);
6056121934Sharti}
6057121934Sharti
6058121934Sharti/*********************************************************************
6059121934Sharti *
6060121934Sharti * Soft PVPC/PVCC
6061121934Sharti *
6062121934Sharti * References for this IE are:
6063121934Sharti *
6064121934Sharti *  PNNI1.0 pp. 201...203
6065121934Sharti *
6066121934Sharti * Only NET coding allowed.
6067121934Sharti */
6068121934ShartiDEF_IE_PRINT(net, calling_soft)
6069121934Sharti{
6070121934Sharti	if(uni_print_iehdr("calling_soft", &ie->h, cx))
6071121934Sharti		return;
6072121934Sharti
6073121934Sharti	uni_print_entry(cx, "vpi", "%d", ie->vpi);
6074121934Sharti	if(ie->h.present & UNI_CALLING_SOFT_VCI_P)
6075121934Sharti		uni_print_entry(cx, "vci", "%d", ie->vci);
6076121934Sharti
6077121934Sharti	uni_print_ieend(cx);
6078121934Sharti}
6079121934Sharti
6080121934ShartiDEF_IE_PRINT(net, called_soft)
6081121934Sharti{
6082121934Sharti	static const struct uni_print_tbl tab[] = {
6083121934Sharti		MKT(UNI_SOFT_SEL_ANY,	any),
6084121934Sharti		MKT(UNI_SOFT_SEL_REQ,	required),
6085121934Sharti		MKT(UNI_SOFT_SEL_ASS,	assigned),
6086121934Sharti		EOT()
6087121934Sharti	};
6088121934Sharti
6089121934Sharti	if(uni_print_iehdr("called_soft", &ie->h, cx))
6090121934Sharti		return;
6091121934Sharti
6092121934Sharti	uni_print_tbl("selection", ie->sel, tab, cx);
6093121934Sharti	if(ie->h.present & UNI_CALLED_SOFT_VPI_P)
6094121934Sharti		uni_print_entry(cx, "vpi", "%d", ie->vpi);
6095121934Sharti	if(ie->h.present & UNI_CALLED_SOFT_VCI_P)
6096121934Sharti		uni_print_entry(cx, "vci", "%d", ie->vci);
6097121934Sharti
6098121934Sharti	uni_print_ieend(cx);
6099121934Sharti}
6100121934Sharti
6101121934ShartiDEF_IE_CHECK(net, calling_soft)
6102121934Sharti{
6103228554Sdim	UNUSED(cx);
6104121934Sharti
6105121934Sharti	if(ie->vpi >= 1 << 12)
6106121934Sharti		return -1;
6107121934Sharti	return 0;
6108121934Sharti}
6109121934Sharti
6110121934ShartiDEF_IE_CHECK(net, called_soft)
6111121934Sharti{
6112228554Sdim	UNUSED(cx);
6113121934Sharti
6114121934Sharti	switch(ie->sel) {
6115121934Sharti
6116121934Sharti	  case UNI_SOFT_SEL_ANY:
6117121934Sharti	  case UNI_SOFT_SEL_REQ:
6118121934Sharti	  case UNI_SOFT_SEL_ASS:
6119121934Sharti		break;
6120121934Sharti
6121121934Sharti	  default:
6122121934Sharti		return -1;
6123121934Sharti	}
6124121934Sharti	if(ie->h.present & UNI_CALLED_SOFT_VPI_P) {
6125121934Sharti		if(ie->vpi >= 1 << 12)
6126121934Sharti			return -1;
6127121934Sharti	} else {
6128121934Sharti		if(ie->sel != UNI_SOFT_SEL_ANY)
6129121934Sharti			return -1;
6130121934Sharti	}
6131121934Sharti
6132121934Sharti	if(ie->h.present & UNI_CALLED_SOFT_VCI_P)
6133121934Sharti		if(!(ie->h.present & UNI_CALLED_SOFT_VPI_P))
6134121934Sharti			return -1;
6135121934Sharti
6136121934Sharti
6137121934Sharti	return 0;
6138121934Sharti}
6139121934Sharti
6140121934ShartiDEF_IE_ENCODE(net, calling_soft)
6141121934Sharti{
6142121934Sharti	START_IE(calling_soft, UNI_IE_CALLING_SOFT, 6);
6143121934Sharti
6144121934Sharti	APP_BYTE(msg, 0x81);
6145121934Sharti	APP_16BIT(msg, ie->vpi);
6146121934Sharti
6147121934Sharti	if(ie->h.present & UNI_CALLING_SOFT_VCI_P) {
6148121934Sharti		APP_BYTE(msg, 0x82);
6149121934Sharti		APP_16BIT(msg, ie->vci);
6150121934Sharti	}
6151121934Sharti
6152121934Sharti	SET_IE_LEN(msg);
6153121934Sharti	return 0;
6154121934Sharti}
6155121934Sharti
6156121934ShartiDEF_IE_ENCODE(net, called_soft)
6157121934Sharti{
6158121934Sharti	START_IE(called_soft, UNI_IE_CALLED_SOFT, 7);
6159121934Sharti
6160121934Sharti	APP_BYTE(msg, ie->sel);
6161121934Sharti
6162121934Sharti	if(ie->h.present & UNI_CALLED_SOFT_VPI_P) {
6163121934Sharti		APP_BYTE(msg, 0x81);
6164121934Sharti		APP_16BIT(msg, ie->vpi);
6165121934Sharti	}
6166121934Sharti
6167121934Sharti	if(ie->h.present & UNI_CALLED_SOFT_VCI_P) {
6168121934Sharti		APP_BYTE(msg, 0x82);
6169121934Sharti		APP_16BIT(msg, ie->vci);
6170121934Sharti	}
6171121934Sharti
6172121934Sharti	SET_IE_LEN(msg);
6173121934Sharti	return 0;
6174121934Sharti}
6175121934Sharti
6176121934ShartiDEF_IE_DECODE(net, calling_soft)
6177121934Sharti{
6178121934Sharti	int vci_seen, vpi_seen;
6179121934Sharti
6180121934Sharti	IE_START(;);
6181121934Sharti	if(ielen < 3)
6182121934Sharti		goto rej;
6183121934Sharti
6184121934Sharti	vci_seen = 0;
6185121934Sharti	vpi_seen = 0;
6186121934Sharti
6187121934Sharti	while(ielen) {
6188121934Sharti		switch(*msg->b_rptr++) {
6189121934Sharti
6190121934Sharti		  case 0x81:
6191121934Sharti			if(!vpi_seen) {
6192121934Sharti				ie->vpi = *msg->b_rptr++ << 8;
6193121934Sharti				ie->vpi |= *msg->b_rptr++;
6194121934Sharti			} else {
6195121934Sharti				msg->b_rptr += 2;
6196121934Sharti			}
6197121934Sharti			ielen -= 3;
6198121934Sharti			break;
6199121934Sharti
6200121934Sharti		  case 0x82:
6201121934Sharti			if(!vci_seen) {
6202121934Sharti				ie->vci = *msg->b_rptr++ << 8;
6203121934Sharti				ie->vci |= *msg->b_rptr++;
6204121934Sharti			} else {
6205121934Sharti				msg->b_rptr += 2;
6206121934Sharti			}
6207121934Sharti			ie->h.present |= UNI_CALLING_SOFT_VCI_P;
6208121934Sharti			ielen -= 3;
6209121934Sharti			break;
6210121934Sharti
6211121934Sharti		  default:
6212121934Sharti			goto rej;
6213121934Sharti		}
6214121934Sharti	}
6215121934Sharti
6216121934Sharti	if(!vpi_seen)
6217121934Sharti		goto rej;
6218121934Sharti
6219121934Sharti	IE_END(CALLING_SOFT);
6220121934Sharti}
6221121934Sharti
6222121934ShartiDEF_IE_DECODE(net, called_soft)
6223121934Sharti{
6224121934Sharti	int vci_seen, vpi_seen;
6225121934Sharti
6226121934Sharti	IE_START(;);
6227121934Sharti	if(ielen < 3)
6228121934Sharti		goto rej;
6229121934Sharti
6230121934Sharti	vci_seen = 0;
6231121934Sharti	vpi_seen = 0;
6232121934Sharti
6233121934Sharti	while(ielen) {
6234121934Sharti		switch(*msg->b_rptr++) {
6235121934Sharti
6236121934Sharti		  case 0x81:
6237121934Sharti			if(!vpi_seen) {
6238121934Sharti				ie->vpi = *msg->b_rptr++ << 8;
6239121934Sharti				ie->vpi |= *msg->b_rptr++;
6240146539Sharti				vpi_seen = 1;
6241121934Sharti			} else {
6242121934Sharti				msg->b_rptr += 2;
6243121934Sharti			}
6244121934Sharti			ielen -= 3;
6245121934Sharti			ie->h.present |= UNI_CALLED_SOFT_VCI_P;
6246121934Sharti			break;
6247121934Sharti
6248121934Sharti		  case 0x82:
6249121934Sharti			if(!vci_seen) {
6250121934Sharti				ie->vci = *msg->b_rptr++ << 8;
6251121934Sharti				ie->vci |= *msg->b_rptr++;
6252146539Sharti				vci_seen = 1;
6253121934Sharti			} else {
6254121934Sharti				msg->b_rptr += 2;
6255121934Sharti			}
6256121934Sharti			ie->h.present |= UNI_CALLED_SOFT_VCI_P;
6257121934Sharti			ielen -= 3;
6258121934Sharti			break;
6259121934Sharti
6260121934Sharti		  default:
6261121934Sharti			goto rej;
6262121934Sharti		}
6263121934Sharti	}
6264121934Sharti
6265121934Sharti	IE_END(CALLED_SOFT);
6266121934Sharti}
6267121934Sharti
6268121934Sharti/*********************************************************************
6269121934Sharti *
6270121934Sharti * Crankback
6271121934Sharti *
6272121934Sharti * References for this IE are:
6273121934Sharti *
6274121934Sharti *  PNNI1.0 pp. 203...206
6275121934Sharti *
6276121934Sharti * Only NET coding allowed.
6277121934Sharti */
6278121934Sharti
6279121934ShartiDEF_IE_PRINT(net, crankback)
6280121934Sharti{
6281121934Sharti	u_int j;
6282121934Sharti
6283121934Sharti	if(uni_print_iehdr("crankback", &ie->h, cx))
6284121934Sharti		return;
6285121934Sharti
6286121934Sharti	uni_print_entry(cx, "level", "%d", ie->level);
6287121934Sharti
6288121934Sharti	switch(ie->type) {
6289121934Sharti
6290121934Sharti	  case UNI_CRANKBACK_IF:
6291121934Sharti		uni_print_entry(cx, "type", "interface");
6292121934Sharti		break;
6293121934Sharti
6294121934Sharti	  case UNI_CRANKBACK_NODE:
6295121934Sharti		uni_print_entry(cx, "type", "node");
6296121934Sharti		uni_print_entry(cx, "node", "{%d/", ie->id.node.level);
6297121934Sharti		for(j = 0; j < 21; j++)
6298121934Sharti			uni_printf(cx, "%02x", ie->id.node.id[j]);
6299121934Sharti		uni_printf(cx, "}");
6300121934Sharti		uni_print_eol(cx);
6301121934Sharti		break;
6302121934Sharti
6303121934Sharti	  case UNI_CRANKBACK_LINK:
6304121934Sharti		uni_print_entry(cx, "type", "link");
6305121934Sharti		uni_print_push_prefix("link", cx);
6306121934Sharti		cx->indent++;
6307121934Sharti
6308121934Sharti		uni_print_entry(cx, "prec", "{%d/", ie->id.link.plevel);
6309121934Sharti		for(j = 0; j < 21; j++)
6310121934Sharti			uni_printf(cx, "%02x", ie->id.link.pid[j]);
6311121934Sharti		uni_printf(cx, "}");
6312121934Sharti		uni_print_eol(cx);
6313121934Sharti
6314121934Sharti		uni_print_entry(cx, "port", "0x%04x", ie->id.link.port);
6315121934Sharti		uni_print_eol(cx);
6316121934Sharti
6317121934Sharti		uni_print_entry(cx, "succ", "{%d/", ie->id.link.slevel);
6318121934Sharti		for(j = 0; j < 21; j++)
6319121934Sharti			uni_printf(cx, "%02x", ie->id.link.sid[j]);
6320121934Sharti		uni_printf(cx, "}");
6321121934Sharti		uni_print_eol(cx);
6322121934Sharti
6323121934Sharti		cx->indent--;
6324121934Sharti		uni_print_pop_prefix(cx);
6325121934Sharti		break;
6326121934Sharti
6327121934Sharti	  default:
6328121934Sharti		uni_print_entry(cx, "type", "0x%02x", ie->type);
6329121934Sharti		break;
6330121934Sharti	}
6331121934Sharti
6332121934Sharti	uni_print_entry(cx, "cause", "0x%02x", ie->cause);
6333121934Sharti
6334121934Sharti	if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6335121934Sharti		uni_print_push_prefix("topol", cx);
6336121934Sharti		uni_print_entry(cx, "dir", "%d", ie->diag.top.dir);
6337121934Sharti		uni_print_entry(cx, "port", "0x%04x", ie->diag.top.port);
6338121934Sharti		uni_print_entry(cx, "avcr", "%u", ie->diag.top.avcr);
6339121934Sharti		if(ie->h.present & UNI_CRANKBACK_TOPX_P) {
6340121934Sharti			uni_print_entry(cx, "crm", "%u", ie->diag.top.crm);
6341121934Sharti			uni_print_entry(cx, "vf", "%u", ie->diag.top.vf);
6342121934Sharti		}
6343121934Sharti		uni_print_pop_prefix(cx);
6344121934Sharti		uni_print_eol(cx);
6345121934Sharti	}
6346121934Sharti	if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6347121934Sharti		uni_print_push_prefix("qos", cx);
6348121934Sharti		uni_print_entry(cx, "ctd", "%savail", ie->diag.qos.ctd ? "" : "un");
6349121934Sharti		uni_print_entry(cx, "cdv", "%savail", ie->diag.qos.cdv ? "" : "un");
6350121934Sharti		uni_print_entry(cx, "clr", "%savail", ie->diag.qos.clr ? "" : "un");
6351121934Sharti		uni_print_entry(cx, "other", "%savail", ie->diag.qos.other ? "" : "un");
6352121934Sharti		uni_print_pop_prefix(cx);
6353121934Sharti		uni_print_eol(cx);
6354121934Sharti	}
6355121934Sharti
6356121934Sharti	uni_print_eol(cx);
6357121934Sharti	uni_print_ieend(cx);
6358121934Sharti}
6359121934Sharti
6360121934ShartiDEF_IE_CHECK(net, crankback)
6361121934Sharti{
6362228554Sdim	UNUSED(cx);
6363121934Sharti
6364121934Sharti	if(ie->level > 104)
6365121934Sharti		return -1;
6366121934Sharti	switch(ie->type) {
6367121934Sharti	  case UNI_CRANKBACK_IF:
6368121934Sharti		break;
6369121934Sharti	  case UNI_CRANKBACK_NODE:
6370121934Sharti		if(ie->id.node.level > 104)
6371121934Sharti			return -1;
6372121934Sharti		break;
6373121934Sharti
6374121934Sharti	  case UNI_CRANKBACK_LINK:
6375121934Sharti		if(ie->id.link.plevel > 104)
6376121934Sharti			return -1;
6377121934Sharti		if(ie->id.link.slevel > 104)
6378121934Sharti			return -1;
6379121934Sharti		break;
6380121934Sharti
6381121934Sharti	  default:
6382121934Sharti		return -1;
6383121934Sharti	}
6384121934Sharti
6385121934Sharti	if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6386121934Sharti		if(ie->h.present & UNI_CRANKBACK_QOS_P)
6387121934Sharti			return -1;
6388121934Sharti
6389121934Sharti		if(ie->cause != UNI_CAUSE_CRATE_NAVL)
6390121934Sharti			return -1;
6391121934Sharti		switch(ie->diag.top.dir) {
6392121934Sharti
6393121934Sharti		  case 0x00:
6394121934Sharti		  case 0x01:
6395121934Sharti			break;
6396121934Sharti
6397121934Sharti		  default:
6398121934Sharti			return -1;
6399121934Sharti		}
6400121934Sharti	}
6401121934Sharti	if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6402121934Sharti		if(ie->cause != UNI_CAUSE_QOS_NAVL)
6403121934Sharti			return -1;
6404121934Sharti	}
6405121934Sharti	return 0;
6406121934Sharti}
6407121934Sharti
6408121934ShartiDEF_IE_ENCODE(net, crankback)
6409121934Sharti{
6410121934Sharti	START_IE(crankback, UNI_IE_CRANKBACK, 72);
6411121934Sharti
6412121934Sharti	APP_BYTE(msg, ie->level);
6413121934Sharti	APP_BYTE(msg, ie->type);
6414121934Sharti
6415121934Sharti	switch(ie->type) {
6416121934Sharti
6417121934Sharti	  case UNI_CRANKBACK_IF:
6418121934Sharti		break;
6419121934Sharti
6420121934Sharti	  case UNI_CRANKBACK_NODE:
6421121934Sharti		APP_BYTE(msg, ie->id.node.level);
6422121934Sharti		APP_BUF(msg, ie->id.node.id, 21);
6423121934Sharti		break;
6424121934Sharti
6425121934Sharti	  case UNI_CRANKBACK_LINK:
6426121934Sharti		APP_BYTE(msg, ie->id.link.plevel);
6427121934Sharti		APP_BUF(msg, ie->id.link.pid, 21);
6428121934Sharti		APP_32BIT(msg, ie->id.link.port);
6429121934Sharti		APP_BYTE(msg, ie->id.link.slevel);
6430121934Sharti		APP_BUF(msg, ie->id.link.sid, 21);
6431121934Sharti		break;
6432121934Sharti	}
6433121934Sharti
6434121934Sharti	APP_BYTE(msg, ie->cause);
6435121934Sharti
6436121934Sharti	if(ie->h.present & UNI_CRANKBACK_TOP_P) {
6437121934Sharti		APP_BYTE(msg, ie->diag.top.dir);
6438121934Sharti		APP_32BIT(msg, ie->diag.top.port);
6439121934Sharti		APP_32BIT(msg, ie->diag.top.avcr);
6440121934Sharti		if(ie->h.present & UNI_CRANKBACK_TOPX_P) {
6441121934Sharti			APP_32BIT(msg, ie->diag.top.crm);
6442121934Sharti			APP_32BIT(msg, ie->diag.top.vf);
6443121934Sharti		}
6444121934Sharti	}
6445121934Sharti
6446121934Sharti	if(ie->h.present & UNI_CRANKBACK_QOS_P) {
6447121934Sharti		APP_BYTE(msg, (ie->diag.qos.ctd << 3)
6448121934Sharti			     |(ie->diag.qos.cdv << 2)
6449121934Sharti			     |(ie->diag.qos.clr << 1)
6450121934Sharti			     |(ie->diag.qos.other));
6451121934Sharti	}
6452121934Sharti	SET_IE_LEN(msg);
6453121934Sharti	return 0;
6454121934Sharti}
6455121934Sharti
6456121934Sharti
6457121934ShartiDEF_IE_DECODE(net, crankback)
6458121934Sharti{
6459121934Sharti	IE_START(;);
6460121934Sharti
6461121934Sharti	if(ielen < 3)
6462121934Sharti		goto rej;
6463121934Sharti
6464121934Sharti	ie->level = *msg->b_rptr++;
6465121934Sharti	ielen--;
6466121934Sharti
6467121934Sharti	ie->type = *msg->b_rptr++;
6468121934Sharti	ielen--;
6469121934Sharti
6470121934Sharti	switch(ie->type) {
6471121934Sharti
6472121934Sharti	  default:
6473121934Sharti		goto rej;
6474121934Sharti
6475121934Sharti	  case UNI_CRANKBACK_IF:
6476121934Sharti		break;
6477121934Sharti
6478121934Sharti	  case UNI_CRANKBACK_NODE:
6479121934Sharti		if(ielen < 22)
6480121934Sharti			goto rej;
6481121934Sharti		ie->id.node.level = *msg->b_rptr++;
6482121934Sharti		(void)memcpy(ie->id.node.id, msg->b_rptr, 21);
6483121934Sharti		msg->b_rptr += 21;
6484121934Sharti		ielen -= 22;
6485121934Sharti		break;
6486121934Sharti
6487121934Sharti	  case UNI_CRANKBACK_LINK:
6488121934Sharti		if(ielen < 48)
6489121934Sharti			goto rej;
6490121934Sharti		ie->id.link.plevel = *msg->b_rptr++;
6491121934Sharti		(void)memcpy(ie->id.link.pid, msg->b_rptr, 21);
6492121934Sharti		msg->b_rptr += 21;
6493121934Sharti		ielen -= 22;
6494121934Sharti
6495121934Sharti		ie->id.link.port  = *msg->b_rptr++ << 24;
6496121934Sharti		ie->id.link.port |= *msg->b_rptr++ << 16;
6497121934Sharti		ie->id.link.port |= *msg->b_rptr++ <<  8;
6498121934Sharti		ie->id.link.port |= *msg->b_rptr++ <<  0;
6499121934Sharti		ielen -= 4;
6500121934Sharti
6501121934Sharti		ie->id.link.slevel = *msg->b_rptr++;
6502121934Sharti		(void)memcpy(ie->id.link.sid, msg->b_rptr, 21);
6503121934Sharti		msg->b_rptr += 21;
6504121934Sharti		ielen -= 22;
6505121934Sharti
6506121934Sharti		break;
6507121934Sharti	}
6508121934Sharti
6509121934Sharti	if(ielen < 1)
6510121934Sharti		goto rej;
6511121934Sharti	ie->cause = *msg->b_rptr++;
6512121934Sharti	ielen--;
6513121934Sharti
6514121934Sharti	if(ie->cause == UNI_CAUSE_CRATE_NAVL) {
6515121934Sharti		if(ielen > 0) {
6516121934Sharti			if(ielen != 9 && ielen != 17)
6517121934Sharti				goto rej;
6518121934Sharti			ie->diag.top.dir = *msg->b_rptr++;
6519121934Sharti			ie->diag.top.port  = *msg->b_rptr++ << 24;
6520121934Sharti			ie->diag.top.port |= *msg->b_rptr++ << 16;
6521121934Sharti			ie->diag.top.port |= *msg->b_rptr++ <<  8;
6522121934Sharti			ie->diag.top.port |= *msg->b_rptr++ <<  0;
6523121934Sharti			ie->diag.top.avcr  = *msg->b_rptr++ << 24;
6524121934Sharti			ie->diag.top.avcr |= *msg->b_rptr++ << 16;
6525121934Sharti			ie->diag.top.avcr |= *msg->b_rptr++ <<  8;
6526121934Sharti			ie->diag.top.avcr |= *msg->b_rptr++ <<  0;
6527121934Sharti			ielen -= 9;
6528121934Sharti			ie->h.present |= UNI_CRANKBACK_TOP_P;
6529121934Sharti			if(ielen > 0) {
6530121934Sharti				ie->diag.top.crm  = *msg->b_rptr++ << 24;
6531121934Sharti				ie->diag.top.crm |= *msg->b_rptr++ << 16;
6532121934Sharti				ie->diag.top.crm |= *msg->b_rptr++ <<  8;
6533121934Sharti				ie->diag.top.crm |= *msg->b_rptr++ <<  0;
6534121934Sharti				ie->diag.top.vf  = *msg->b_rptr++ << 24;
6535121934Sharti				ie->diag.top.vf |= *msg->b_rptr++ << 16;
6536121934Sharti				ie->diag.top.vf |= *msg->b_rptr++ <<  8;
6537121934Sharti				ie->diag.top.vf |= *msg->b_rptr++ <<  0;
6538121934Sharti				ie->h.present |= UNI_CRANKBACK_TOPX_P;
6539121934Sharti				ielen -= 8;
6540121934Sharti			}
6541121934Sharti		}
6542121934Sharti	} else if(ie->cause == UNI_CAUSE_QOS_NAVL) {
6543121934Sharti		if(ielen > 0) {
6544121934Sharti			if(ielen != 1)
6545121934Sharti				goto rej;
6546121934Sharti			ie->diag.qos.ctd = *msg->b_rptr >> 3;
6547121934Sharti			ie->diag.qos.cdv = *msg->b_rptr >> 2;
6548121934Sharti			ie->diag.qos.clr = *msg->b_rptr >> 1;
6549121934Sharti			ie->diag.qos.other = *msg->b_rptr >> 0;
6550121934Sharti			ie->h.present |= UNI_CRANKBACK_QOS_P;
6551121934Sharti			ielen -= 1;
6552121934Sharti		}
6553121934Sharti	} else {
6554121934Sharti		if(ielen > 0)
6555121934Sharti			goto rej;
6556121934Sharti	}
6557121934Sharti
6558121934Sharti	IE_END(CRANKBACK);
6559121934Sharti}
6560121934Sharti
6561121934Sharti/*********************************************************************
6562121934Sharti *
6563121934Sharti * Designated transit list
6564121934Sharti *
6565121934Sharti * References for this IE are:
6566121934Sharti *
6567121934Sharti *  PNNI1.0 pp. 206...208
6568121934Sharti *
6569121934Sharti * Only NET coding allowed.
6570121934Sharti */
6571121934ShartiDEF_IE_PRINT(net, dtl)
6572121934Sharti{
6573121934Sharti	u_int i, j;
6574121934Sharti	char buf[10];
6575121934Sharti
6576121934Sharti	if(uni_print_iehdr("dtl", &ie->h, cx))
6577121934Sharti		return;
6578121934Sharti
6579121934Sharti	uni_print_entry(cx, "ptr", "%d(%d)", ie->ptr, ie->ptr / UNI_DTL_LOGNP_SIZE);
6580121934Sharti	uni_print_push_prefix("dtl", cx);
6581121934Sharti	cx->indent++;
6582121934Sharti	uni_printf(cx, "{");
6583121934Sharti	for(i = 0; i < ie->num; i++) {
6584121934Sharti		sprintf(buf, "%d", i);
6585121934Sharti		uni_print_entry(cx, buf, "{%d/", ie->dtl[i].node_level);
6586121934Sharti		for(j = 0; j < 21; j++)
6587121934Sharti			uni_printf(cx, "%02x", ie->dtl[i].node_id[j]);
6588121934Sharti		uni_printf(cx, ",%04x}", ie->dtl[i].port_id);
6589121934Sharti		uni_print_eol(cx);
6590121934Sharti	}
6591121934Sharti	cx->indent--;
6592121934Sharti	uni_print_pop_prefix(cx);
6593121934Sharti	uni_print_ieend(cx);
6594121934Sharti}
6595121934Sharti
6596121934ShartiDEF_IE_CHECK(net, dtl)
6597121934Sharti{
6598121934Sharti	u_int i;
6599121934Sharti
6600228554Sdim	UNUSED(cx);
6601121934Sharti
6602121934Sharti	if(ie->ptr % UNI_DTL_LOGNP_SIZE != 0)
6603121934Sharti		return -1;
6604121934Sharti	if(ie->ptr / UNI_DTL_LOGNP_SIZE > UNI_DTL_MAXNUM)
6605121934Sharti		return -1;
6606121934Sharti	if(ie->num > UNI_DTL_MAXNUM)
6607121934Sharti		return -1;
6608121934Sharti	for(i = 0; i < ie->num; i++)
6609121934Sharti		if(ie->dtl[i].node_level > 104)
6610121934Sharti			return -1;
6611121934Sharti	return 0;
6612121934Sharti}
6613121934Sharti
6614121934ShartiDEF_IE_ENCODE(net, dtl)
6615121934Sharti{
6616121934Sharti	u_int i;
6617121934Sharti
6618121934Sharti	START_IE(dtl, UNI_IE_DTL, 2 + UNI_DTL_LOGNP_SIZE * ie->num);
6619121934Sharti
6620121934Sharti	APP_16BIT(msg, ie->ptr);
6621121934Sharti
6622121934Sharti	for(i = 0; i < ie->num; i++) {
6623121934Sharti		APP_BYTE(msg, UNI_DTL_LOGNP);
6624121934Sharti		APP_BYTE(msg, ie->dtl[i].node_level);
6625121934Sharti		APP_BUF(msg, ie->dtl[i].node_id, 21);
6626121934Sharti		APP_32BIT(msg, ie->dtl[i].port_id);
6627121934Sharti	}
6628121934Sharti
6629121934Sharti	SET_IE_LEN(msg);
6630121934Sharti	return 0;
6631121934Sharti}
6632121934Sharti
6633121934Sharti
6634121934ShartiDEF_IE_DECODE(net, dtl)
6635121934Sharti{
6636121934Sharti	IE_START(;);
6637121934Sharti
6638121934Sharti	if(ielen < 2)
6639121934Sharti		goto rej;
6640121934Sharti
6641121934Sharti	ie->ptr = *msg->b_rptr++ << 8;
6642121934Sharti	ie->ptr |= *msg->b_rptr++;
6643121934Sharti	ielen -= 2;
6644121934Sharti
6645121934Sharti	if(ielen % UNI_DTL_LOGNP_SIZE != 0)
6646121934Sharti		goto rej;
6647121934Sharti	if(ielen / UNI_DTL_LOGNP_SIZE > UNI_DTL_MAXNUM)
6648121934Sharti		goto rej;
6649121934Sharti
6650121934Sharti	ie->num = 0;
6651121934Sharti	while(ielen) {
6652121934Sharti		if(*msg->b_rptr++ != UNI_DTL_LOGNP)
6653121934Sharti			goto rej;
6654121934Sharti		ielen--;
6655121934Sharti
6656121934Sharti		ie->dtl[ie->num].node_level = *msg->b_rptr++;
6657121934Sharti		ielen--;
6658121934Sharti
6659121934Sharti		(void)memcpy(ie->dtl[ie->num].node_id, msg->b_rptr, 21);
6660121934Sharti		msg->b_rptr += 21;
6661121934Sharti		ielen -= 21;
6662121934Sharti
6663121934Sharti		ie->dtl[ie->num].port_id  = *msg->b_rptr++ << 24;
6664121934Sharti		ie->dtl[ie->num].port_id |= *msg->b_rptr++ << 16;
6665121934Sharti		ie->dtl[ie->num].port_id |= *msg->b_rptr++ <<  8;
6666121934Sharti		ie->dtl[ie->num].port_id |= *msg->b_rptr++ <<  0;
6667121934Sharti		ielen -= 4;
6668121934Sharti
6669121934Sharti		ie->num++;
6670121934Sharti	}
6671121934Sharti
6672121934Sharti	IE_END(DTL);
6673121934Sharti}
6674121934Sharti
6675121934Sharti/*********************************************************************
6676121934Sharti *
6677121934Sharti * Leaf initiated join call identifier.
6678121934Sharti * Leaf initiated join parameters.
6679121934Sharti * Leaf initiated join sequence number.
6680121934Sharti *
6681121934Sharti * References for this IE are:
6682121934Sharti *
6683121934Sharti *  UNI4.0 pp. 46...48
6684121934Sharti *
6685121934Sharti * Only NET coding allowed.
6686121934Sharti */
6687121934Sharti
6688121934Sharti/**********************************************************************/
6689121934Sharti
6690121934ShartiDEF_IE_PRINT(net, lij_callid)
6691121934Sharti{
6692121934Sharti	static const struct uni_print_tbl type_tbl[] = {
6693121934Sharti		MKT(UNI_LIJ_IDTYPE_ROOT, root),
6694121934Sharti		EOT()
6695121934Sharti	};
6696121934Sharti
6697121934Sharti	if(uni_print_iehdr("lij_callid", &ie->h, cx))
6698121934Sharti		return;
6699121934Sharti
6700121934Sharti	uni_print_tbl("type", ie->type, type_tbl, cx);
6701121934Sharti	uni_print_entry(cx, "id", "0x%x", ie->callid);
6702121934Sharti
6703121934Sharti	uni_print_ieend(cx);
6704121934Sharti}
6705121934Sharti
6706121934ShartiDEF_IE_CHECK(net, lij_callid)
6707121934Sharti{
6708228554Sdim	UNUSED(cx);
6709121934Sharti
6710121934Sharti	switch(ie->type) {
6711121934Sharti
6712121934Sharti	  case UNI_LIJ_IDTYPE_ROOT:
6713121934Sharti		break;
6714121934Sharti
6715121934Sharti	  default:
6716121934Sharti		return -1;
6717121934Sharti	}
6718121934Sharti
6719121934Sharti	return 0;
6720121934Sharti}
6721121934Sharti
6722121934ShartiDEF_IE_ENCODE(net, lij_callid)
6723121934Sharti{
6724121934Sharti	START_IE(lij_callid, UNI_IE_LIJ_CALLID, 5);
6725121934Sharti
6726121934Sharti	APP_BYTE(msg, 0x80 | ie->type);
6727121934Sharti	APP_32BIT(msg, ie->callid);
6728121934Sharti
6729121934Sharti	SET_IE_LEN(msg);
6730121934Sharti	return 0;
6731121934Sharti}
6732121934Sharti
6733121934ShartiDEF_IE_DECODE(net, lij_callid)
6734121934Sharti{
6735121934Sharti	IE_START(;);
6736121934Sharti
6737121934Sharti	if(ielen != 5)
6738121934Sharti		goto rej;
6739121934Sharti
6740121934Sharti	ie->type = *msg->b_rptr++ & 0xf;
6741121934Sharti	ie->callid  = *msg->b_rptr++ << 24;
6742121934Sharti	ie->callid |= *msg->b_rptr++ << 16;
6743121934Sharti	ie->callid |= *msg->b_rptr++ <<  8;
6744121934Sharti	ie->callid |= *msg->b_rptr++ <<  0;
6745121934Sharti
6746121934Sharti	IE_END(LIJ_CALLID);
6747121934Sharti}
6748121934Sharti
6749121934Sharti/**********************************************************************/
6750121934Sharti
6751121934ShartiDEF_IE_PRINT(net, lij_param)
6752121934Sharti{
6753121934Sharti	static const struct uni_print_tbl lscreen_tbl[] = {
6754121934Sharti		MKT(UNI_LIJ_SCREEN_NETJOIN, netjoin),
6755121934Sharti		EOT()
6756121934Sharti	};
6757121934Sharti
6758121934Sharti	if(uni_print_iehdr("lij_param", &ie->h, cx))
6759121934Sharti		return;
6760121934Sharti	uni_print_tbl("screen", ie->screen, lscreen_tbl, cx);
6761121934Sharti	uni_print_ieend(cx);
6762121934Sharti}
6763121934Sharti
6764121934ShartiDEF_IE_CHECK(net, lij_param)
6765121934Sharti{
6766228554Sdim	UNUSED(cx);
6767121934Sharti
6768121934Sharti	switch(ie->screen) {
6769121934Sharti
6770121934Sharti	  case UNI_LIJ_SCREEN_NETJOIN:
6771121934Sharti		break;
6772121934Sharti
6773121934Sharti	  default:
6774121934Sharti		return -1;
6775121934Sharti	}
6776121934Sharti
6777121934Sharti	return 0;
6778121934Sharti}
6779121934Sharti
6780121934ShartiDEF_IE_ENCODE(net, lij_param)
6781121934Sharti{
6782121934Sharti	START_IE(lij_param, UNI_IE_LIJ_PARAM, 1);
6783121934Sharti
6784121934Sharti	APP_BYTE(msg, 0x80 | ie->screen);
6785121934Sharti
6786121934Sharti	SET_IE_LEN(msg);
6787121934Sharti	return 0;
6788121934Sharti}
6789121934Sharti
6790121934ShartiDEF_IE_DECODE(net, lij_param)
6791121934Sharti{
6792121934Sharti	IE_START(;);
6793121934Sharti
6794121934Sharti	if(ielen != 1)
6795121934Sharti		goto rej;
6796121934Sharti
6797121934Sharti	ie->screen = *msg->b_rptr++ & 0xf;
6798121934Sharti
6799121934Sharti	IE_END(LIJ_PARAM);
6800121934Sharti}
6801121934Sharti
6802121934Sharti/**********************************************************************/
6803121934Sharti
6804121934ShartiDEF_IE_PRINT(net, lij_seqno)
6805121934Sharti{
6806121934Sharti	if(uni_print_iehdr("lij_seqno", &ie->h, cx))
6807121934Sharti		return;
6808121934Sharti	uni_print_entry(cx, "seqno", "0x%x", ie->seqno);
6809121934Sharti	uni_print_ieend(cx);
6810121934Sharti}
6811121934Sharti
6812121934ShartiDEF_IE_CHECK(net, lij_seqno)
6813121934Sharti{
6814228554Sdim	UNUSED(cx); UNUSED(ie);
6815121934Sharti
6816121934Sharti	return 0;
6817121934Sharti}
6818121934Sharti
6819121934ShartiDEF_IE_ENCODE(net, lij_seqno)
6820121934Sharti{
6821121934Sharti	START_IE(lij_seqno, UNI_IE_LIJ_SEQNO, 4);
6822121934Sharti
6823121934Sharti	APP_32BIT(msg, ie->seqno);
6824121934Sharti
6825121934Sharti	SET_IE_LEN(msg);
6826121934Sharti	return 0;
6827121934Sharti}
6828121934Sharti
6829121934ShartiDEF_IE_DECODE(net, lij_seqno)
6830121934Sharti{
6831121934Sharti	IE_START(;);
6832121934Sharti
6833121934Sharti	if(ielen != 4)
6834121934Sharti		goto rej;
6835121934Sharti
6836121934Sharti	ie->seqno  = *msg->b_rptr++ << 24;
6837121934Sharti	ie->seqno |= *msg->b_rptr++ << 16;
6838121934Sharti	ie->seqno |= *msg->b_rptr++ <<  8;
6839121934Sharti	ie->seqno |= *msg->b_rptr++ <<  0;
6840121934Sharti
6841121934Sharti	IE_END(LIJ_SEQNO);
6842121934Sharti}
6843121934Sharti
6844121934Sharti/*********************************************************************
6845121934Sharti *
6846121934Sharti * Connection scope
6847121934Sharti *
6848121934Sharti * References for this IE are:
6849121934Sharti *
6850121934Sharti *  UNI4.0 pp. 57...58
6851121934Sharti *
6852121934Sharti * Only NET coding allowed.
6853121934Sharti */
6854121934ShartiDEF_IE_PRINT(net, cscope)
6855121934Sharti{
6856121934Sharti	static const struct uni_print_tbl type_tbl[] = {
6857121934Sharti		MKT(UNI_CSCOPE_ORG,	org),
6858121934Sharti		EOT()
6859121934Sharti	};
6860121934Sharti	static const struct uni_print_tbl scope_tbl[] = {
6861121934Sharti		MKT(UNI_CSCOPE_ORG_LOC,		local_network),
6862121934Sharti		MKT(UNI_CSCOPE_ORG_LOC_P1,	local_network_plus_one),
6863121934Sharti		MKT(UNI_CSCOPE_ORG_LOC_P2,	local_network_plus_two),
6864121934Sharti		MKT(UNI_CSCOPE_ORG_SITE_M1,	site_minus_one),
6865121934Sharti		MKT(UNI_CSCOPE_ORG_SITE,	intra_site),
6866121934Sharti		MKT(UNI_CSCOPE_ORG_SITE_P1,	site_plus_one),
6867121934Sharti		MKT(UNI_CSCOPE_ORG_ORG_M1,	organisation_minus_one),
6868121934Sharti		MKT(UNI_CSCOPE_ORG_ORG,		intra_organisation),
6869121934Sharti		MKT(UNI_CSCOPE_ORG_ORG_P1,	organisation_plus_one),
6870121934Sharti		MKT(UNI_CSCOPE_ORG_COMM_M1,	community_minus_one),
6871121934Sharti		MKT(UNI_CSCOPE_ORG_COMM,	intra_community),
6872121934Sharti		MKT(UNI_CSCOPE_ORG_COMM_P1,	community_plus_one),
6873121934Sharti		MKT(UNI_CSCOPE_ORG_REG,		regional),
6874121934Sharti		MKT(UNI_CSCOPE_ORG_INTER,	inter_regional),
6875121934Sharti		MKT(UNI_CSCOPE_ORG_GLOBAL,	global),
6876121934Sharti		EOT()
6877121934Sharti	};
6878121934Sharti
6879121934Sharti	if(uni_print_iehdr("cscope", &ie->h, cx))
6880121934Sharti		return;
6881121934Sharti
6882121934Sharti	uni_print_tbl("type", ie->type, type_tbl, cx);
6883121934Sharti	if(ie->type == UNI_CSCOPE_ORG)
6884121934Sharti		uni_print_tbl("scope", (u_int)ie->scope, scope_tbl, cx);
6885121934Sharti	else
6886121934Sharti		uni_print_entry(cx, "scope", "0x%02x", ie->scope);
6887121934Sharti
6888121934Sharti	uni_print_ieend(cx);
6889121934Sharti}
6890121934Sharti
6891121934ShartiDEF_IE_CHECK(net, cscope)
6892121934Sharti{
6893228554Sdim	UNUSED(cx);
6894121934Sharti
6895121934Sharti	switch(ie->type) {
6896121934Sharti
6897121934Sharti	  default:
6898121934Sharti		return -1;
6899121934Sharti
6900121934Sharti	  case UNI_CSCOPE_ORG:
6901121934Sharti		switch(ie->scope) {
6902121934Sharti
6903121934Sharti		  default:
6904121934Sharti			return -1;
6905121934Sharti
6906121934Sharti		  case UNI_CSCOPE_ORG_LOC:
6907121934Sharti		  case UNI_CSCOPE_ORG_LOC_P1:
6908121934Sharti		  case UNI_CSCOPE_ORG_LOC_P2:
6909121934Sharti		  case UNI_CSCOPE_ORG_SITE_M1:
6910121934Sharti		  case UNI_CSCOPE_ORG_SITE:
6911121934Sharti		  case UNI_CSCOPE_ORG_SITE_P1:
6912121934Sharti		  case UNI_CSCOPE_ORG_ORG_M1:
6913121934Sharti		  case UNI_CSCOPE_ORG_ORG:
6914121934Sharti		  case UNI_CSCOPE_ORG_ORG_P1:
6915121934Sharti		  case UNI_CSCOPE_ORG_COMM_M1:
6916121934Sharti		  case UNI_CSCOPE_ORG_COMM:
6917121934Sharti		  case UNI_CSCOPE_ORG_COMM_P1:
6918121934Sharti		  case UNI_CSCOPE_ORG_REG:
6919121934Sharti		  case UNI_CSCOPE_ORG_INTER:
6920121934Sharti		  case UNI_CSCOPE_ORG_GLOBAL:
6921121934Sharti			break;
6922121934Sharti		}
6923121934Sharti		break;
6924121934Sharti	}
6925121934Sharti	return 0;
6926121934Sharti}
6927121934Sharti
6928121934ShartiDEF_IE_ENCODE(net, cscope)
6929121934Sharti{
6930121934Sharti	START_IE(cscope, UNI_IE_CSCOPE, 2);
6931121934Sharti
6932121934Sharti	APP_BYTE(msg, ie->type | 0x80);
6933121934Sharti	APP_BYTE(msg, ie->scope);
6934121934Sharti
6935121934Sharti	SET_IE_LEN(msg);
6936121934Sharti	return 0;
6937121934Sharti}
6938121934Sharti
6939121934ShartiDEF_IE_DECODE(net, cscope)
6940121934Sharti{
6941121934Sharti	IE_START(;);
6942121934Sharti	if(ielen != 2)
6943121934Sharti		goto rej;
6944121934Sharti
6945121934Sharti	if((*msg->b_rptr & 0xf0) != 0x80)
6946121934Sharti		goto rej;
6947121934Sharti
6948121934Sharti	ie->type = *msg->b_rptr++ & 0xf;
6949121934Sharti	ie->scope = *msg->b_rptr++;
6950121934Sharti
6951121934Sharti	IE_END(CSCOPE);
6952121934Sharti}
6953121934Sharti
6954121934Sharti/*********************************************************************
6955121934Sharti *
6956121934Sharti * Extended Quality of Service
6957121934Sharti *
6958121934Sharti * References for this IE are:
6959121934Sharti *
6960121934Sharti *  	UNI4.0 pp. 70...72
6961121934Sharti *
6962121934Sharti * Notes:
6963121934Sharti *	Only NET coding.
6964121934Sharti */
6965121934ShartiDEF_IE_PRINT(net, exqos)
6966121934Sharti{
6967121934Sharti	static const struct uni_print_tbl tab[] = {
6968121934Sharti		MKT(UNI_EXQOS_USER,	user),
6969121934Sharti		MKT(UNI_EXQOS_NET,	net),
6970121934Sharti		EOT()
6971121934Sharti	};
6972121934Sharti
6973121934Sharti	if(uni_print_iehdr("exqos", &ie->h, cx))
6974121934Sharti		return;
6975121934Sharti
6976121934Sharti	uni_print_tbl("origin", ie->origin, tab, cx);
6977121934Sharti
6978121934Sharti	uni_print_entry(cx, "acceptable", "(");
6979121934Sharti	if(ie->h.present & UNI_EXQOS_FACC_P) {
6980121934Sharti		if(ie->facc == UNI_EXQOS_ANY_CDV)
6981121934Sharti			uni_printf(cx, "ANY");
6982121934Sharti		else
6983121934Sharti			uni_printf(cx, "%d", ie->facc);
6984121934Sharti	}
6985121934Sharti	uni_putc(',', cx);
6986121934Sharti	if(ie->h.present & UNI_EXQOS_BACC_P) {
6987121934Sharti		if(ie->bacc == UNI_EXQOS_ANY_CDV)
6988121934Sharti			uni_printf(cx, "ANY");
6989121934Sharti		else
6990121934Sharti			uni_printf(cx, "%d", ie->bacc);
6991121934Sharti	}
6992121934Sharti	uni_putc(')', cx);
6993121934Sharti
6994121934Sharti	uni_print_entry(cx, "cumulative", "(");
6995121934Sharti	if(ie->h.present & UNI_EXQOS_FCUM_P)
6996121934Sharti		uni_printf(cx, "%d", ie->fcum);
6997121934Sharti	uni_putc(',', cx);
6998121934Sharti	if(ie->h.present & UNI_EXQOS_BCUM_P)
6999121934Sharti		uni_printf(cx, "%d", ie->bcum);
7000121934Sharti	uni_putc(')', cx);
7001121934Sharti
7002121934Sharti	uni_print_entry(cx, "clrid", "(");
7003121934Sharti	if(ie->h.present & UNI_EXQOS_FCLR_P) {
7004121934Sharti		if(ie->fclr == UNI_EXQOS_ANY_CLR)
7005121934Sharti			uni_printf(cx, "ANY");
7006121934Sharti		else
7007121934Sharti			uni_printf(cx, "%d", ie->fclr);
7008121934Sharti	}
7009121934Sharti	uni_putc(',', cx);
7010121934Sharti	if(ie->h.present & UNI_EXQOS_BCLR_P) {
7011121934Sharti		if(ie->bclr == UNI_EXQOS_ANY_CLR)
7012121934Sharti			uni_printf(cx, "ANY");
7013121934Sharti		else
7014121934Sharti			uni_printf(cx, "%d", ie->bclr);
7015121934Sharti	}
7016121934Sharti	uni_putc(')', cx);
7017121934Sharti
7018121934Sharti	uni_print_ieend(cx);
7019121934Sharti}
7020121934Sharti
7021121934ShartiDEF_IE_CHECK(net, exqos)
7022121934Sharti{
7023228554Sdim	UNUSED(cx);
7024121934Sharti
7025121934Sharti	switch(ie->origin) {
7026121934Sharti	  case UNI_EXQOS_USER:
7027121934Sharti	  case UNI_EXQOS_NET:
7028121934Sharti		break;
7029121934Sharti
7030121934Sharti	  default:
7031121934Sharti		return -1;
7032121934Sharti	}
7033121934Sharti	if(ie->h.present & UNI_EXQOS_FACC_P)
7034121934Sharti		if(!(ie->h.present & UNI_EXQOS_FCUM_P))
7035121934Sharti			return -1;
7036121934Sharti	if(ie->h.present & UNI_EXQOS_BACC_P)
7037121934Sharti		if(!(ie->h.present & UNI_EXQOS_BCUM_P))
7038121934Sharti			return -1;
7039121934Sharti
7040121934Sharti	if(ie->h.present & UNI_EXQOS_FACC_P)
7041121934Sharti		if(ie->facc >= 1 << 24)
7042121934Sharti			return -1;
7043121934Sharti	if(ie->h.present & UNI_EXQOS_BACC_P)
7044121934Sharti		if(ie->bacc >= 1 << 24)
7045121934Sharti			return -1;
7046121934Sharti	if(ie->h.present & UNI_EXQOS_FCUM_P)
7047121934Sharti		if(ie->fcum >= 1 << 24)
7048121934Sharti			return -1;
7049121934Sharti	if(ie->h.present & UNI_EXQOS_BCUM_P)
7050121934Sharti		if(ie->bcum >= 1 << 24)
7051121934Sharti			return -1;
7052121934Sharti
7053121934Sharti	if(ie->h.present & UNI_EXQOS_FCLR_P)
7054121934Sharti		if(ie->fclr==0 || (ie->fclr>15 && ie->fclr!=UNI_EXQOS_ANY_CLR))
7055121934Sharti			return -1;
7056121934Sharti	if(ie->h.present & UNI_EXQOS_BCLR_P)
7057121934Sharti		if(ie->bclr==0 || (ie->bclr>15 && ie->bclr!=UNI_EXQOS_ANY_CLR))
7058121934Sharti			return -1;
7059121934Sharti	return 0;
7060121934Sharti}
7061121934Sharti
7062121934ShartiDEF_IE_ENCODE(net, exqos)
7063121934Sharti{
7064121934Sharti	START_IE(exqos, UNI_IE_EXQOS, 21);
7065121934Sharti
7066121934Sharti	APP_BYTE(msg, ie->origin);
7067121934Sharti
7068121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_FACC_P,
7069121934Sharti		UNI_EXQOS_FACC_ID, ie->facc);
7070121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_BACC_P,
7071121934Sharti		UNI_EXQOS_BACC_ID, ie->bacc);
7072121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_FCUM_P,
7073121934Sharti		UNI_EXQOS_FCUM_ID, ie->fcum);
7074121934Sharti	APP_OPT_24BIT(msg, ie->h.present, UNI_EXQOS_BCUM_P,
7075121934Sharti		UNI_EXQOS_BCUM_ID, ie->bcum);
7076121934Sharti
7077121934Sharti	APP_OPT_BYTE(msg, ie->h.present, UNI_EXQOS_FCLR_P,
7078121934Sharti		UNI_EXQOS_FCLR_ID, ie->fclr);
7079121934Sharti	APP_OPT_BYTE(msg, ie->h.present, UNI_EXQOS_BCLR_P,
7080121934Sharti		UNI_EXQOS_BCLR_ID, ie->bclr);
7081121934Sharti
7082121934Sharti	SET_IE_LEN(msg);
7083121934Sharti	return 0;
7084121934Sharti}
7085121934Sharti
7086121934ShartiDEF_IE_DECODE(net, exqos)
7087121934Sharti{
7088121934Sharti	IE_START(;);
7089121934Sharti
7090121934Sharti	if(ielen < 1 || ielen > 21)
7091121934Sharti		goto rej;
7092121934Sharti
7093121934Sharti	ie->origin = *msg->b_rptr++;
7094121934Sharti	ielen--;
7095121934Sharti
7096121934Sharti	while(ielen--) {
7097121934Sharti		switch(*msg->b_rptr++) {
7098121934Sharti
7099121934Sharti		  default:
7100121934Sharti			goto rej;
7101121934Sharti
7102121934Sharti		  DEC_GETF3(EXQOS_FACC, facc, ie->h.present);
7103121934Sharti		  DEC_GETF3(EXQOS_BACC, bacc, ie->h.present);
7104121934Sharti		  DEC_GETF3(EXQOS_FCUM, fcum, ie->h.present);
7105121934Sharti		  DEC_GETF3(EXQOS_BCUM, bcum, ie->h.present);
7106121934Sharti
7107121934Sharti		  DEC_GETF1(EXQOS_FCLR, fclr, ie->h.present);
7108121934Sharti		  DEC_GETF1(EXQOS_BCLR, bclr, ie->h.present);
7109121934Sharti
7110121934Sharti		}
7111121934Sharti	}
7112121934Sharti	IE_END(EXQOS);
7113121934Sharti}
7114121934Sharti
7115121934Sharti/**************************************************************
7116121934Sharti *
7117121934Sharti * Free form IE (for testing mainly)
7118121934Sharti */
7119121934ShartiDEF_IE_PRINT(itu, unrec)
7120121934Sharti{
7121121934Sharti	u_int i;
7122121934Sharti
7123121934Sharti	if (uni_print_iehdr("unrec", &ie->h, cx))
7124121934Sharti		return;
7125121934Sharti	uni_print_entry(cx, "len", "%u", ie->len);
7126121934Sharti	uni_print_entry(cx, "data", "(");
7127121934Sharti	for (i = 0; i < ie->len; i++)
7128121934Sharti		uni_printf(cx, "%s0x%02x", i == 0 ? "" : " ", ie->data[i]);
7129121934Sharti	uni_printf(cx, ")");
7130121934Sharti	uni_print_ieend(cx);
7131121934Sharti}
7132121934Sharti
7133121934ShartiDEF_IE_CHECK(itu, unrec)
7134121934Sharti{
7135228554Sdim	UNUSED(cx);
7136121934Sharti
7137121934Sharti	if (ie->len > sizeof(ie->data))
7138121934Sharti		return (-1);
7139121934Sharti
7140121934Sharti	return (0);
7141121934Sharti}
7142121934Sharti
7143121934ShartiDEF_IE_ENCODE(itu, unrec)
7144121934Sharti{
7145121934Sharti	START_IE2(unrec, UNI_IE_UNREC, ie->len, ie->id);
7146121934Sharti
7147121934Sharti	APP_BUF(msg, ie->data, ie->len);
7148121934Sharti
7149121934Sharti	SET_IE_LEN(msg);
7150121934Sharti	return (0);
7151121934Sharti}
7152121934Sharti
7153121934ShartiDEF_IE_DECODE(itu, unrec)
7154121934Sharti{
7155121934Sharti	IE_START(;);
7156121934Sharti
7157121934Sharti	if (ielen > sizeof(ie->data) / sizeof(ie->data[0]) || ielen < 1)
7158121934Sharti		goto rej;
7159121934Sharti
7160121934Sharti	ie->len = ielen;
7161121934Sharti	ielen = 0;
7162121934Sharti	(void)memcpy(ie->data, msg->b_rptr, ie->len);
7163121934Sharti	msg->b_rptr += ie->len;
7164121934Sharti
7165121934Sharti	IE_END(UNREC);
7166121934Sharti}
7167