|
|
1.1 root 1: /* x25addr.c - X.25 level generic <-> interface address munging */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/compat/RCS/x25addr.c,v 7.3 90/07/09 14:32:30 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/compat/RCS/x25addr.c,v 7.3 90/07/09 14:32:30 mrose Exp $
9: *
10: * Contributed by George Michaelson, Julian Onions, and John Pavel
11: *
12: *
13: * $Log: x25addr.c,v $
14: * Revision 7.3 90/07/09 14:32:30 mrose
15: * sync
16: *
17: * Revision 7.2 89/12/11 16:21:42 mrose
18: * comments
19: *
20: * Revision 7.1 89/12/11 01:36:14 mrose
21: * SUN_X25_HACK
22: *
23: * Revision 7.0 89/11/23 21:23:49 mrose
24: * Release 6.0
25: *
26: */
27:
28: /*
29: * NOTICE
30: *
31: * Acquisition, use, and distribution of this module and related
32: * materials are subject to the restrictions of a license agreement.
33: * Consult the Preface in the User's Manual for the full terms of
34: * this agreement.
35: *
36: */
37:
38:
39: /* LINTLIBRARY */
40:
41: /*
42: * for *really* generic address translation
43: */
44:
45: #include <errno.h>
46: #include <stdio.h>
47: #include "general.h"
48: #include "manifest.h"
49:
50: #ifdef X25
51: #include "tailor.h"
52: #include "tpkt.h"
53: #include <sys/file.h>
54: #include "x25.h"
55:
56: #ifndef DEBUG
57: #define DEBUG
58: #endif
59:
60: /* */
61:
62: /*
63: * convert from the generic X25 structure to interface specific
64: */
65: /* ARGSUSED */
66: CONN_DB *gen2if (generic, specific, context)
67: struct NSAPaddr *generic;
68: CONN_DB *specific;
69: int context;
70: {
71: int dtelen;
72: char dte[NSAP_DTELEN + 1];
73: #ifdef CAMTEC_CCL
74: struct iovec *iov;
75: #endif
76:
77: if (generic == NULLNA
78: || specific == (CONN_DB *) 0
79: || generic -> na_stack != NA_X25)
80: return (CONN_DB *)0;
81:
82: if (x25_dnic_prefix && *x25_dnic_prefix) {
83: /* need DNIC on local calls? */
84: register int i;
85:
86: if ( strncmp(generic -> na_dte, x25_dnic_prefix,
87: i = strlen(x25_dnic_prefix)) == 0 )
88: {
89: if (x25_strip_dnic) bcopy(generic -> na_dte + i, dte, dtelen =
90: generic -> na_dtelen - i);
91: else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen);
92: }
93: else
94: if (x25_intl_zero)
95: {
96: bcopy(generic -> na_dte, dte + 1, dtelen = generic-> na_dtelen);
97: *dte = '0', dtelen++;
98: }
99: else bcopy(generic -> na_dte, dte, dtelen = generic -> na_dtelen);
100:
101: }
102: else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen);
103: dte[dtelen] = NULL;
104:
105: #ifdef SUN_X25_HACK
106: /*
107: * If your X.25 provider expects to receive the subaddress alone
108: * on listen requests, and you are using SunLink X.25, you may need
109: * to enable SUN_X25_HACK in your config file. This will allow you
110: * to use x25_local_dte in isotailor to specify a dte mask to be
111: * stripped when listening, and thus use full DTE strings in
112: * isoentities and QUIPU EDB files. You will also have to use the
113: * tsapd -a <dte> option to specify the listen address in
114: * /etc/rc.local and other tsapd startups since by default this equals
115: * x25_local_dte and thus will be masked to <null> unless overridden
116: * with full DTE + subaddress.
117: */
118:
119: /*
120: * in ADDR_LISTEN context, it may be neccessary to only listen
121: * on the sub-address, because certain PTT-provided networks
122: * remove the local DTE from incoming CR packets.
123: *
124: * SunLink X.25 listen asserts whatever DTE it is given as a simple
125: * string-compare, and will never receive inbound calls that bear
126: * only the sub-address if you assert the full DTE.
127: *
128: * this behaviour is orthogonal to any requirements to remove DNIC
129: * or add a leading 0 on outbound calls, and so needs a separate
130: * test. It uses tailor variable x25_local_dte to assert the local
131: * DTE *without* subaddress which should be tested for and stripped
132: * when detected.
133: */
134:
135: if ((context == ADDR_LISTEN) && x25_local_dte && *x25_local_dte)
136: {
137: register int i;
138:
139: if ( strncmp(generic -> na_dte, x25_local_dte,
140: i = strlen(x25_local_dte)) == 0 )
141: {
142: bcopy(generic -> na_dte + i, dte, dtelen =
143: generic -> na_dtelen - i);
144: dte[dtelen] = NULL;
145: }
146: }
147: #endif
148:
149: DLOG (x25_log, LLOG_DEBUG,
150: ("gen2if %s -> %s, %d octets; PID %s",
151: generic -> na_dte, dte, dtelen,
152: sel2str (generic -> na_pid, (int) generic -> na_pidlen,1)));
153:
154:
155: #ifndef CAMTEC_CCL
156: bzero ((char *)specific, sizeof *specific);
157: #endif
158:
159: #ifdef UBC_X25
160: if ((specific -> xaddr_len = dtelen) != 0) {
161: bcopy (dte, specific -> xaddr_addr,
162: dtelen);
163: specific -> xaddr_len = dtelen;
164: specific -> xaddr_facilities = 0;
165: bcopy (generic -> na_pid, specific -> xaddr_proto,
166: generic -> na_pidlen);
167: bcopy (generic -> na_cudf, specific -> xaddr_userdata,
168: generic -> na_cudflen);
169: }
170: #endif
171:
172: #ifdef SUN_X25
173: specific -> hostlen = char2bcd (dte, specific -> host);
174:
175: /* Zero PID */
176: if (generic -> na_pidlen) { /* non-null PID */
177: if (generic -> na_pidlen > NPSIZE) {
178: SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
179: ("PID too long (%d > %d)", generic -> na_pidlen, NPSIZE));
180: return (CONN_DB *)0;
181: } else {
182: bzero((char *)specific -> data, NPSIZE);
183: bcopy (generic -> na_pid, (char *)specific -> data,
184: generic -> na_pidlen);
185: bcopy (generic -> na_cudf, (char *) specific -> data + NPSIZE,
186: generic -> na_cudflen);
187: specific -> datalen = generic -> na_pidlen + generic -> na_cudflen;
188: }
189: } else { /* Null PID (just copy in CUDF, the first four octets of which
190: will be the PID in any case) */
191: bcopy (generic -> na_cudf, (char *)specific -> data,
192: generic -> na_cudflen);
193: specific -> datalen = generic -> na_cudflen;
194: }
195: #endif
196:
197: #ifdef CAMTEC_CCL
198: switch (context) {
199: case ADDR_REMOTE:
200: iov = &(specific -> ccl_iovec[0]);
201: if (x25_outgoing_port == '#') {
202: char *a, *b;
203: int i;
204:
205: iov -> iov_len = dtelen + 4;
206: bzero(iov -> iov_base, iov -> iov_len + 1);
207: a = iov -> iov_base;
208: b = dte;
209: *a++ = '#';
210: *a++ = '[';
211: for (i = 0; i < dtelen; i++) {
212: if (i == 2) *a++ = ':';
213: else if (i == 14) *a++ = ']';
214: *a++ = *b++;
215: }
216: }
217: else {
218: iov -> iov_len = dtelen+1;
219: bcopy(dte, (iov -> iov_base)+1, dtelen);
220: *(iov -> iov_base) = x25_outgoing_port;
221: }
222: break;
223:
224: case ADDR_LOCAL:
225: iov = &(specific -> ccl_iovec[0]);
226: strncpy(iov -> iov_base, generic -> na_dte, generic -> na_dtelen);
227: iov -> iov_base[generic -> na_dtelen] = '\0';
228: return (specific);
229:
230: case ADDR_LISTEN:
231: iov = &(specific -> ccl_iovec[0]);
232: if (generic -> na_pidlen)
233: { /* listen on a PID */
234: register int i;
235: iov -> iov_base[0] = 'C';
236: bcopy(generic -> na_pid, iov -> iov_base + 1,
237: i = generic -> na_pidlen);
238: iov -> iov_len = i + 1;
239: }
240: else
241: if (generic -> na_dtelen < 6)
242: { /* listen on a subaddress */
243: register int i;
244: iov -> iov_base[0] = 'S';
245: bcopy(generic -> na_dte, iov -> iov_base + 1,
246: i = generic -> na_dtelen);
247: iov -> iov_len = i + 1;
248: }
249: else /* full DTE */
250: bcopy(dte, iov -> iov_base,
251: iov -> iov_len = dtelen);
252: return (specific);
253: }
254: /*
255: * CUDF & PID must be merged. malloc initailly PIDsize space
256: * and bzero it. this may be UK net specific action which
257: * ensures we do NOT fall foul of listeners which use pid
258: * to match as well as "true" cudf & DTE.
259: */
260:
261: (iov = &(specific -> ccl_iovec[2])) -> iov_len = 0;
262: if (generic -> na_faclen != 0)
263: bcopy (generic -> na_fac, iov -> iov_base,
264: iov -> iov_len = min( generic -> na_faclen, FACSIZE) );
265: iov++;
266: if ( (iov -> iov_len = generic -> na_pidlen) != 0)
267: bcopy (generic -> na_pid, iov -> iov_base, generic -> na_pidlen);
268:
269: /*
270: * if there is any other user data add that in now...
271: * actually cudf is a variable length field so this is
272: * all very suspect.
273: */
274:
275: if (generic -> na_cudflen != 0)
276: bcopy(generic -> na_cudf, iov -> iov_base + iov -> iov_len,
277: generic -> na_cudflen), iov -> iov_len += generic -> na_cudflen;
278: #endif
279:
280: return(specific);
281: }
282:
283: /* */
284:
285: /*
286: * convert from interface specific format to generic X.25 structure
287: */
288: /* ARGSUSED */
289: struct NSAPaddr *if2gen (generic, specific, context)
290: struct NSAPaddr *generic;
291: CONN_DB *specific;
292: int context;
293: {
294: int dtelen;
295: char dte[NSAP_DTELEN + 1];
296: #ifdef CAMTEC_CCL
297: struct iovec *iov;
298: #endif
299:
300: if (generic == NULLNA || specific == (CONN_DB *) 0)
301: return NULLNA;
302: bzero ((char *)generic, sizeof *generic);
303: bzero (dte, sizeof dte);
304: dtelen = 0;
305:
306: generic -> na_stack = NA_X25;
307: generic -> na_community = ts_comm_x25_default;
308:
309: #ifdef UBC_X25
310: if (specific -> xaddr_len != 0) {
311: bcopy (specific -> xaddr_addr, dte, specific -> xaddr_len);
312: dtelen = specific -> xaddr_len;
313: bcopy (specific -> xaddr_proto, generic -> na_pid,
314: sizeof(specific -> xaddr_proto));
315: generic -> na_pidlen = sizeof specific -> xaddr_proto;
316: bcopy (specific -> xaddr_userdata, generic -> na_cudf,
317: sizeof(specific -> xaddr_userdata));
318: generic -> na_cudflen = sizeof specific -> xaddr_userdata;
319: }
320: #endif
321:
322: #ifdef SUN_X25
323: dtelen = bcd2char (specific -> host, dte, (int) specific -> hostlen);
324:
325: if (specific -> datalen > NPSIZE) { /* have some real user data after the PID */
326: bcopy((char *)specific -> data, generic -> na_pid,
327: generic -> na_pidlen = NPSIZE);
328: bcopy((char *) specific -> data + generic -> na_pidlen,
329: generic -> na_cudf,
330: generic -> na_cudflen = specific -> datalen - generic -> na_pidlen);
331: }
332: else { /* PID only */
333: bcopy((char *)specific -> data, generic -> na_pid,
334: generic -> na_pidlen = specific -> datalen);
335: generic -> na_cudflen = 0;
336: }
337:
338: #endif
339:
340: #ifdef CAMTEC_CCL
341: switch (context) {
342: case ADDR_REMOTE:
343:
344: iov = &(specific -> ccl_iovec[1]);
345: if (iov -> iov_len) {
346: if (*(iov->iov_base) == '#') {
347: char *a;
348:
349: a = iov -> iov_base;
350: while (*a && iov -> iov_len) {
351: if (*a == ']') {
352: iov -> iov_len--;
353: a++;
354: break;
355: }
356: iov -> iov_len--;
357: a++;
358: }
359: if (*a == 0 || iov -> iov_len == 0)
360: dtelen = 0;
361: else {
362: dtelen = iov -> iov_len;
363: bcopy (a, dte, dtelen);
364: }
365: }
366: else {
367: dtelen = iov -> iov_len - 1;
368: bcopy ((iov -> iov_base)+1, dte,
369: dtelen);
370: }
371: }
372: else dtelen = 0;
373: break;
374:
375: case ADDR_LOCAL:
376: iov = &(specific -> ccl_iovec[0]);
377: if (iov -> iov_len) {
378: dtelen = iov -> iov_len -1;
379: bcopy ((iov -> iov_base)+1, dte,
380: dtelen);
381: }
382: else dtelen = 0;
383: break;
384:
385: case ADDR_LISTEN:
386: return NULLNA;
387: }
388:
389: if ( (iov = &(specific -> ccl_iovec[2])) -> iov_len )
390: bcopy( iov -> iov_base, generic -> na_fac,
391: generic -> na_faclen = min( iov -> iov_len, FACSIZE));
392:
393: if ( ++iov -> iov_len)
394: {
395: bcopy( iov -> iov_base, generic -> na_pid,
396: generic -> na_pidlen = min( iov -> iov_len, NPSIZE));
397: if ( iov -> iov_len > NPSIZE)
398: bcopy( iov -> iov_base + NPSIZE, generic -> na_cudf,
399: generic -> na_cudflen = min(iov -> iov_len - NPSIZE, CUDFSIZE));
400: }
401: #endif
402:
403: if (x25_dnic_prefix && *x25_dnic_prefix) {
404: register int i;
405:
406: i = 0;
407: if (x25_intl_zero && dte[0] == '0' && dte[1] != '0')
408: i = 1;
409: else
410: if (x25_dnic_prefix
411: && *x25_dnic_prefix
412: && x25_strip_dnic
413: && dtelen < 12) /* local call... */
414: bcopy (x25_dnic_prefix, generic -> na_dte,
415: generic -> na_dtelen = strlen (x25_dnic_prefix));
416:
417: bcopy (dte + i, generic -> na_dte + generic -> na_dtelen, dtelen - i);
418: generic -> na_dtelen += dtelen - i;
419: }
420: else
421: bcopy (dte, generic -> na_dte, generic -> na_dtelen = dtelen);
422:
423: DLOG (x25_log, LLOG_DEBUG,
424: ("if2gen %s -> %s, %d octets; PID %s",
425: dte, generic -> na_dte, generic -> na_dtelen,
426: sel2str (generic -> na_pid, (int) generic -> na_pidlen,1)));
427:
428: return(generic);
429: }
430:
431: /* */
432:
433: #ifdef SUN_X25
434: static int char2bcd (s, d)
435: register char *s;
436: register u_char *d;
437: {
438: register int c,
439: i;
440:
441: for (i = 0; *s; i++) {
442: if ((c = *s++) >= 'a' && c <= 'f')
443: c -= 'a' + 0x0a;
444: else
445: if (c >= 'A' && c <= 'F')
446: c -= 'A' + 0x0a;
447: else
448: if (c >= '0' && c <= '9')
449: c -= '0';
450: else
451: c = 0;
452:
453: if (i & 1)
454: *d++ |= c & 0xf;
455: else
456: *d = (c & 0xf) << 4;
457: }
458:
459: return i;
460: }
461:
462: /* */
463:
464: static int bcd2char (s, d, len)
465: register u_char *s;
466: register char *d;
467: int len;
468: {
469: register int i,
470: g;
471:
472: for (i = 0; i < len; i++) {
473: g = s[i >> 1];
474: if ((i & 1) == 0)
475: g >>= 4;
476: g &= 0xf;
477:
478: if (g < 0x0a)
479: *d++ = g + '0';
480: else
481: *d++ = g + 'a' - 0x0a;
482: }
483:
484: *d = NULL;
485:
486: return len;
487: }
488: #endif
489: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.