Deleted Added
sdiff udiff text old ( 121934 ) new ( 131826 )
full compact
1/*
2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Author: Hartmut Brandt <harti@freebsd.org>
28 *
29 * $Begemot: libunimsg/atm/msg/privmsg.c,v 1.3 2003/09/19 11:58:15 hbb Exp $
30 *
31 * Private definitions for the MSG code file.
32 *
33 * This file is included at the begin of the automatically generated
34 * uni_msg.c.
35 */
36
37/*
38 * Decode a UNI message header.
39 * Return values:
40 * 0 - ok
41 * -1 - ignore message (proto, length, CR error)
42 */
43int
44uni_decode_head(struct uni_msg *msg, struct uni_all *out,
45 struct unicx *cx __unused)
46{
47 u_int mlen;
48
49 cx->errcnt = 0;
50 (void)memset(out, 0, sizeof(struct uni_all));
51
52 if(uni_msg_len(msg) < 9)
53 return -1; /* Q.2931 5.6.2 */
54 if(cx->pnni) {
55 if(*msg->b_rptr++ != PNNI_PROTO)
56 return -1; /* Q.2931 5.6.1 */
57 } else {
58 if(*msg->b_rptr++ != UNI_PROTO)
59 return -1; /* Q.2931 5.6.1 */
60 }
61 if(*msg->b_rptr++ != 3)
62 return -1; /* Q.2931 5.6.3.1 */
63
64 out->u.hdr.cref.flag = (*msg->b_rptr & 0x80) ? 1 : 0;
65 out->u.hdr.cref.cref = (*msg->b_rptr++ & 0x7f) << 16;
66 out->u.hdr.cref.cref |= *msg->b_rptr++ << 8;
67 out->u.hdr.cref.cref |= *msg->b_rptr++;
68
69 out->mtype = *msg->b_rptr++;
70
71 /*
72 * Be not too piggy about this byte
73 */
74 switch(*msg->b_rptr & 0x13) {
75
76 case 0x00: case 0x01: case 0x02: case 0x03:
77 out->u.hdr.act = UNI_MSGACT_DEFAULT;
78 break;
79
80 case 0x10: case 0x11: case 0x12:
81 out->u.hdr.act = *msg->b_rptr & 0x3;
82 break;
83
84 case 0x13: /* Q.2931 5.7.1 */
85 out->u.hdr.act = UNI_MSGACT_REPORT;
86 break;
87 }
88 if(cx->pnni && (*msg->b_rptr & 0x08))
89 out->u.hdr.pass = 1;
90 else
91 out->u.hdr.pass = 0;
92
93 msg->b_rptr++;
94
95 mlen = *msg->b_rptr++ << 8;
96 mlen |= *msg->b_rptr++;
97
98 /*
99 * If the message is longer than the indicated length
100 * shorten it. If it is shorter, probably one of the IE
101 * decoders will break, but we should proceed. 5.5.6.5
102 */
103#if 0
104 if(uni_msg_len(msg) > mlen)
105 msg->b_wptr = msg->b_rptr + mlen;
106#endif
107
108 return 0;
109}
110
111static int
112uni_decode_body_internal(enum uni_msgtype mtype, struct uni_msg *msg,
113 union uni_msgall *out, struct unicx *cx)
114{
115 enum uni_ietype ietype;
116 struct uni_iehdr hdr;
117 u_int ielen;
118 const struct iedecl *iedecl;
119 int err = 0, ret;
120 u_char *end;
121
122 cx->ielast = (enum uni_ietype)0;
123 cx->repeat.h.present = 0;
124
125 while (uni_msg_len(msg) != 0) {
126 if (uni_decode_ie_hdr(&ietype, &hdr, msg, cx, &ielen)) {
127 /*
128 * Short header. Set the ielen to an impossible size.
129 * Then we should bump out in the error handling below.
130 * We should have at least an IE type here.
131 */
132 ielen = 0xffffffff;
133 }
134#ifdef DTRACE
135 printf("IE %x\n", ietype);
136#endif
137
138 if ((iedecl = GET_IEDECL(ietype, hdr.coding)) == NULL ||
139 ietype == UNI_IE_UNREC) {
140 /*
141 * entirly unknown IE. Check the length and skip it.
142 * Q.2931 5.6.8.1
143 */
144 if (ielen > uni_msg_len(msg))
145 msg->b_rptr = msg->b_wptr;
146 else
147 msg->b_rptr += ielen;
148 UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_UNK);
149 err = -1;
150 continue;
151 }
152#ifdef DTRACE
153 printf("IE %x known\n", ietype);
154#endif
155 if (ielen > iedecl->maxlen - 4 || ielen > uni_msg_len(msg)) {
156 /*
157 * Information element too long -> content error.
158 * Let the decoding routine set the error flag and
159 * return DEC_ERR.
160 * Q.2931 5.6.8.2
161 */
162#if 0
163 /*
164 * It is not clear how to best handle this error.
165 */
166 if (ielen > iedecl->maxlen - 4)
167 ielen = iedecl->maxlen - 4;
168#endif
169
170 if (ielen > uni_msg_len(msg))
171 ielen = uni_msg_len(msg);
172
173 hdr.present |= UNI_IE_ERROR;
174
175#ifdef DTRACE
176 printf("IE %x length too large\n", ietype);
177#endif
178 }
179
180#ifdef DTRACE
181 else
182 printf("IE %x length ok\n", ietype);
183#endif
184 end = msg->b_rptr + ielen;
185 ret = uni_msgtable[mtype]->decode(out, msg, ietype,
186 &hdr, ielen, cx);
187 msg->b_rptr = end;
188
189#ifdef DTRACE
190 printf("IE %x ret %d\n", ietype, ret);
191#endif
192
193 switch (ret) {
194
195 case DEC_OK: /* ok */
196 break;
197
198 case DEC_ILL: /* illegal IE */
199 /*
200 * Unexpected but recognized.
201 * Q.2931 5.6.8.3
202 */
203 UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_UNK);
204 err = -1;
205 break;
206
207 case DEC_ERR: /* bad IE */
208 if (iedecl->flags & UNIFL_ACCESS)
209 /* this may be wrong: 5.6.8.2 */
210 UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_ACC);
211 else
212 UNI_SAVE_IERR(cx, ietype, hdr.act, UNI_IERR_BAD);
213 err = -1;
214 break;
215
216 default:
217 PANIC(("bad decode return"));
218 }
219 cx->ielast = ietype;
220 if (ietype != UNI_IE_REPEAT)
221 cx->repeat.h.present = 0;
222 }
223 return err;
224}
225
226/*
227 * Decode the body of a message. The header is assumed to be decoded
228 * already and out->hdr is filled in. Only information elements remain.
229 */
230int
231uni_decode_body(struct uni_msg *msg, struct uni_all *out, struct unicx *cx)
232{
233 cx->errcnt = 0;
234 if (out->mtype >= 256)
235 return (-1);
236 if (uni_msgtable[out->mtype] == NULL)
237 return (-1);
238 return (uni_decode_body_internal(out->mtype, msg, &out->u, cx));
239}
240
241
242/*
243 * Decode a uni message
244 */
245int
246uni_decode(struct uni_msg *msg, struct uni_all *out, struct unicx *cx)
247{
248 cx->errcnt = 0;
249 if (uni_decode_head(msg, out, cx))
250 return (-1);
251 if (uni_decode_body(msg, out, cx))
252 return (-2);
253 return (0);
254}
255
256int
257uni_encode(struct uni_msg *msg, struct uni_all *in, struct unicx *cx)
258{
259 if (in->mtype >= 256)
260 return (-1);
261 if (uni_msgtable[in->mtype] == NULL)
262 return (-3);
263
264 return ((uni_msgtable[in->mtype]->encode)(msg, &in->u, cx));
265}
266
267/*
268 * Doesn't belong here
269 */
270void
271uni_initcx(struct unicx *cx)
272{
273 memset(cx, 0, sizeof(struct unicx));
274 cx->tabsiz = 4;
275}