1 /*
2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * All rights reserved.
5 * Copyright (c) 2004
6 * Hartmut Brandt
7 *
8 * Author: Hartmut Brandt <harti@freebsd.org>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Begemot: libunimsg/netnatm/api/unisap.c,v 1.4 2004/07/08 08:22:01 brandt Exp $
32 */
33
34 #include <sys/types.h>
35 #ifdef _KERNEL
36 #include <sys/ctype.h>
37 #include <sys/libkern.h>
38 #else
39 #include <ctype.h>
40 #include <string.h>
41 #endif
42 #include <netnatm/msg/unistruct.h>
43 #include <netnatm/api/unisap.h>
44
45 int
46 unisve_check_addr(const struct unisve_addr *sve)
47 {
48 if (sve->tag == UNISVE_ABSENT)
49 return (UNISVE_OK);
50 if (sve->tag == UNISVE_ANY)
51 return (UNISVE_OK);
52 if (sve->tag != UNISVE_PRESENT)
53 return (UNISVE_ERROR_BAD_TAG);
54
55 if (sve->type == UNI_ADDR_INTERNATIONAL) {
56 if (sve->plan != UNI_ADDR_E164)
57 return (UNISVE_ERROR_TYPE_PLAN_CONFLICT);
58 if (sve->len == 0 || sve->len > 15)
59 return (UNISVE_ERROR_ADDR_LEN);
60
61 } else if (sve->type == UNI_ADDR_UNKNOWN) {
62 if (sve->plan != UNI_ADDR_ATME)
63 return (UNISVE_ERROR_TYPE_PLAN_CONFLICT);
64 if (sve->len != 19)
65 return (UNISVE_ERROR_ADDR_LEN);
66 } else
67 return (UNISVE_ERROR_BAD_ADDR_TYPE);
68
69 return (UNISVE_OK);
70 }
71
72 int
73 unisve_check_selector(const struct unisve_selector *sve)
74 {
75 if (sve->tag != UNISVE_PRESENT &&
76 sve->tag != UNISVE_ABSENT &&
77 sve->tag != UNISVE_ANY)
78 return (UNISVE_ERROR_BAD_TAG);
79 return (UNISVE_OK);
80 }
81
82 /*
83 * We don't want to check the protocol values here.
84 */
85 int
86 unisve_check_blli_id2(const struct unisve_blli_id2 *sve)
87 {
88 if (sve->tag != UNISVE_PRESENT &&
89 sve->tag != UNISVE_ABSENT &&
90 sve->tag != UNISVE_ANY)
91 return (UNISVE_ERROR_BAD_TAG);
92 return (UNISVE_OK);
93 }
94
95 /*
96 * We don't want to check the protocol values here.
97 */
98 int
99 unisve_check_blli_id3(const struct unisve_blli_id3 *sve)
100 {
101 if (sve->tag != UNISVE_PRESENT &&
102 sve->tag != UNISVE_ABSENT &&
103 sve->tag != UNISVE_ANY)
104 return (UNISVE_ERROR_BAD_TAG);
105 return (UNISVE_OK);
106 }
107
108 int
109 unisve_check_bhli(const struct unisve_bhli *sve)
110 {
111 if (sve->tag == UNISVE_ABSENT)
112 return (UNISVE_OK);
113 if (sve->tag == UNISVE_ANY)
114 return (UNISVE_OK);
115
116 if (sve->tag != UNISVE_PRESENT)
117 return (UNISVE_ERROR_BAD_TAG);
118
119 if (sve->type != UNI_BHLI_ISO &&
120 sve->type != UNI_BHLI_USER &&
121 sve->type != UNI_BHLI_VENDOR)
122 return (UNISVE_ERROR_BAD_BHLI_TYPE);
123
124 if (sve->len > sizeof(sve->info))
125 return (UNISVE_ERROR_BAD_BHLI_LEN);
126
127 return (UNISVE_OK);
128 }
129
130 int
131 unisve_check_sap(const struct uni_sap *sap)
132 {
133 int err;
134
135 if ((err = unisve_check_addr(&sap->addr)) != 0 ||
136 (err = unisve_check_selector(&sap->selector)) != 0 ||
137 (err = unisve_check_blli_id2(&sap->blli_id2)) != 0 ||
138 (err = unisve_check_blli_id3(&sap->blli_id3)) != 0 ||
139 (err = unisve_check_bhli(&sap->bhli)) != 0)
140 return (err);
141
142 if (sap->addr.plan == UNI_ADDR_E164) {
143 if (sap->selector.tag == UNISVE_PRESENT)
144 return (UNISVE_ERROR_ADDR_SEL_CONFLICT);
145 } else if (sap->addr.plan == UNI_ADDR_ATME) {
146 if (sap->selector.tag == UNISVE_ABSENT)
147 return (UNISVE_ERROR_ADDR_SEL_CONFLICT);
148 }
149 return (0);
150 }
151
152 #define COMMON_OVERLAP(A1,A2) \
153 if ((A1->tag == UNISVE_ABSENT && A2->tag == UNISVE_ABSENT) || \
154 A1->tag == UNISVE_ANY || A2->tag == UNISVE_ANY) \
155 return (1); \
156 if ((A1->tag == UNISVE_ABSENT && A2->tag == UNISVE_PRESENT) || \
157 (A2->tag == UNISVE_ABSENT && A1->tag == UNISVE_PRESENT)) \
158 return (0);
159
160 int
161 unisve_overlap_addr(const struct unisve_addr *s1, const struct unisve_addr *s2)
162 {
163 COMMON_OVERLAP(s1, s2);
164
165 return (s1->type == s2->type && s1->plan == s2->plan &&
166 s1->len == s2->len && memcmp(s1->addr, s2->addr, s1->len) == 0);
167 }
168
169 int
170 unisve_overlap_selector(const struct unisve_selector *s1,
171 const struct unisve_selector *s2)
172 {
173 COMMON_OVERLAP(s1, s2);
174
175 return (s1->selector == s2->selector);
176 }
177
178 int
179 unisve_overlap_blli_id2(const struct unisve_blli_id2 *s1,
180 const struct unisve_blli_id2 *s2)
181 {
182 COMMON_OVERLAP(s1, s2);
183
184 return (s1->proto == s2->proto &&
185 (s1->proto != UNI_BLLI_L2_USER || s1->user == s2->user));
186 }
187
188 int
189 unisve_overlap_blli_id3(const struct unisve_blli_id3 *s1,
190 const struct unisve_blli_id3 *s2)
191 {
192 COMMON_OVERLAP(s1, s2);
193
194 if (s1->proto != s2->proto)
195 return (0);
196 if (s1->proto == UNI_BLLI_L3_USER)
197 return (s1->user == s2->user);
198 if (s1->proto == UNI_BLLI_L3_TR9577) {
199 if (s1->noipi && s2->noipi)
200 return (1);
201 if (!s1->noipi && !s2->noipi) {
202 if (s1->ipi == s2->ipi) {
203 if (s1->ipi != UNI_BLLI_L3_SNAP)
204 return (1);
205 if (s1->oui == s2->oui && s1->pid == s2->pid)
206 return (1);
207 }
208 }
209 return (0);
210 }
211 return (1);
212 }
213
214 int
215 unisve_overlap_bhli(const struct unisve_bhli *s1, const struct unisve_bhli *s2)
216 {
217 COMMON_OVERLAP(s1, s2);
218
219 return (s1->type == s2->type && s1->len == s2->len &&
220 memcmp(s1->info, s2->info, s1->len) == 0);
221 }
222
223 int
224 unisve_overlap_sap(const struct uni_sap *s1, const struct uni_sap *s2)
225 {
226 int any1, any2;
227
228 /*
229 * Two catch-all's SAP's are not allowed. A catch-all does never
230 * overlap with a non-catch all SAP.
231 */
232 any1 = unisve_is_catchall(s1);
233 any2 = unisve_is_catchall(s2);
234
235 if (any1 && any2)
236 return (1);
237 if(any1 || any2)
238 return (0);
239
240 return (unisve_overlap_addr(&s1->addr, &s2->addr) &&
241 unisve_overlap_selector(&s1->selector, &s2->selector) &&
242 unisve_overlap_blli_id2(&s1->blli_id2, &s2->blli_id2) &&
243 unisve_overlap_blli_id3(&s1->blli_id3, &s2->blli_id3) &&
244 unisve_overlap_bhli(&s1->bhli, &s2->bhli));
245 }
246
247 int
248 unisve_is_catchall(const struct uni_sap *sap)
249 {
250 return (sap->addr.tag == UNISVE_ANY &&
251 sap->selector.tag == UNISVE_ANY &&
252 sap->blli_id2.tag == UNISVE_ANY &&
253 sap->blli_id3.tag == UNISVE_ANY &&
254 sap->bhli.tag == UNISVE_ANY);
255 }
256
257 int
258 unisve_match(const struct uni_sap *sap, const struct uni_ie_called *called,
259 const struct uni_ie_blli *blli, const struct uni_ie_bhli *bhli)
260 {
261 switch (sap->addr.tag) {
262 case UNISVE_ABSENT:
263 if (IE_ISGOOD(*called))
264 return (0);
265 break;
266
267 case UNISVE_ANY:
268 break;
269
270 case UNISVE_PRESENT:
271 if (!IE_ISGOOD(*called))
272 return (0);
273 if (called->addr.type != sap->addr.type ||
274 called->addr.plan != sap->addr.plan)
275 return (0);
276 if (called->addr.plan == UNI_ADDR_E164) {
277 if (called->addr.len != sap->addr.len ||
278 memcmp(called->addr.addr, sap->addr.addr,
279 called->addr.len) != 0)
280 return (0);
281 } else if (called->addr.plan == UNI_ADDR_ATME) {
282 if (called->addr.len != 20 ||
283 memcmp(called->addr.addr, sap->addr.addr, 19) != 0)
284 return (0);
285 }
286 break;
287
288 default:
289 return (0);
290 }
291
292 switch (sap->selector.tag) {
293
294 case UNISVE_ABSENT:
295 if (IE_ISGOOD(*called) && called->addr.plan == UNI_ADDR_ATME)
296 return (0);
297 break;
298
299 case UNISVE_ANY:
300 break;
301
302 case UNISVE_PRESENT:
303 if (!IE_ISGOOD(*called))
304 return (0);
305 if (called->addr.plan != UNI_ADDR_ATME)
306 return (0);
307 if (called->addr.addr[19] != sap->selector.selector)
308 return (0);
309 break;
310
311 default:
312 return (0);
313 }
314
315 switch (sap->blli_id2.tag) {
316
317 case UNISVE_ABSENT:
318 if (IE_ISGOOD(*blli) && (blli->h.present & UNI_BLLI_L2_P))
319 return (0);
320 break;
321
322 case UNISVE_ANY:
323 break;
324
325 case UNISVE_PRESENT:
326 if (!IE_ISGOOD(*blli) || (blli->h.present & UNI_BLLI_L2_P) == 0)
327 return (0);
328 if (blli->l2 != sap->blli_id2.proto)
329 return (0);
330 if (blli->l2 == UNI_BLLI_L2_USER) {
331 if ((blli->h.present & UNI_BLLI_L2_USER_P) == 0)
332 return (0);
333 if (blli->l2_user != sap->blli_id2.user)
334 return (0);
335 }
336 break;
337
338 default:
339 return (0);
340 }
341
342 switch (sap->blli_id3.tag) {
343
344 case UNISVE_ABSENT:
345 if (IE_ISGOOD(*blli) && (blli->h.present & UNI_BLLI_L3_P))
346 return (0);
347 break;
348
349 case UNISVE_ANY:
350 break;
351
352 case UNISVE_PRESENT:
353 if (!IE_ISGOOD(*blli) || (blli->h.present & UNI_BLLI_L3_P) == 0)
354 return (0);
355 if (blli->l3 != sap->blli_id3.proto)
356 return (0);
357 if (blli->l3 == UNI_BLLI_L3_USER) {
358 if ((blli->h.present & UNI_BLLI_L3_USER_P) == 0)
359 return (0);
360 if (blli->l3_user != sap->blli_id3.user)
361 return (0);
362 break;
363 }
364 if (blli->l3 == UNI_BLLI_L3_TR9577) {
365 if (sap->blli_id3.noipi) {
366 if (blli->h.present & UNI_BLLI_L3_IPI_P)
367 return (0);
368 } else {
369 if (!(blli->h.present & UNI_BLLI_L3_IPI_P))
370 return (0);
371 if (blli->l3_ipi != sap->blli_id3.ipi)
372 return (0);
373 if (blli->l3_ipi == UNI_BLLI_L3_SNAP) {
374 if (!(blli->h.present &
375 UNI_BLLI_L3_SNAP_P))
376 return (0);
377 if (blli->oui != sap->blli_id3.oui ||
378 blli->pid != sap->blli_id3.pid)
379 return (0);
380 }
381 }
382 }
383 break;
384
385 default:
386 return (0);
387 }
388
389 switch (sap->bhli.tag) {
390
391 case UNISVE_ABSENT:
392 if (IE_ISGOOD(*bhli))
393 return (0);
394 break;
395
396 case UNISVE_ANY:
397 break;
398
399 case UNISVE_PRESENT:
400 if (!IE_ISGOOD(*bhli))
401 return (0);
402 if (sap->bhli.type != bhli->type)
403 return (0);
404 if (sap->bhli.len != bhli->len)
405 return (0);
406 if (memcmp(sap->bhli.info, bhli->info, bhli->len) != 0)
407 return (0);
408 break;
409
410 default:
411 return (0);
412 }
413 /* Uff */
414 return (1);
415 }
Cache object: c76fbdd5428cbbf85363ffdd3ec5088c
|