386BSD 0.1 development
[unix-history] / usr / othersrc / contrib / isode / compat / ubcx25.c
CommitLineData
48435ab0
WJ
1/* ubcx25.c - X.25 abstractions for UBC X25 */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/compat/RCS/ubcx25.c,v 7.4 91/02/22 09:16:13 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/compat/RCS/ubcx25.c,v 7.4 91/02/22 09:16:13 mrose Interim $
9 *
10 * Contributed by Julian Onions, Nottingham University in the UK
11 *
12 *
13 * $Log: ubcx25.c,v $
14 * Revision 7.4 91/02/22 09:16:13 mrose
15 * Interim 6.8
16 *
17 * Revision 7.3 91/01/14 13:33:53 mrose
18 * loader
19 *
20 * Revision 7.2 90/07/09 14:32:28 mrose
21 * sync
22 *
23 * Revision 7.1 89/12/07 01:08:02 mrose
24 * queued writes
25 *
26 * Revision 7.0 89/11/23 21:23:47 mrose
27 * Release 6.0
28 *
29 */
30
31/*
32 * NOTICE
33 *
34 * Acquisition, use, and distribution of this module and related
35 * materials are subject to the restrictions of a license agreement.
36 * Consult the Preface in the User's Manual for the full terms of
37 * this agreement.
38 *
39 */
40
41
42/* LINTLIBRARY */
43
44#include <errno.h>
45#include <stdio.h>
46#include "general.h"
47#include "manifest.h"
48#include "tailor.h"
49#include "tpkt.h"
50
51/* \f 4.[23] UNIX: UBC X25 */
52
53#ifdef X25
54#ifdef UBC_X25
55
56#include "x25.h"
57#include <sys/uio.h>
58
59#define X25_MBIT 0x40
60#define X25_QBIT 0x80
61
62/* \f */
63
64int start_x25_client (local)
65struct NSAPaddr *local;
66{
67 int sd, pgrp;
68
69 if (local != NULLNA)
70 local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
71 if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
72 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
73 return NOTOK; /* Error can be found in errno */
74 }
75
76 pgrp = getpid();
77 if (ioctl(sd, SIOCSPGRP, &pgrp)) {
78 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
79 return NOTOK; /* Error can be found in errno */
80 }
81
82 return sd;
83}
84
85/* \f */
86
87int start_x25_server (local, backlog, opt1, opt2)
88struct NSAPaddr *local;
89int backlog,
90 opt1,
91 opt2;
92{
93 int sd, pgrp;
94#ifdef notyet
95#ifdef BSD43
96 int onoff;
97#endif
98#endif
99 CONN_DB zsck;
100 CONN_DB *sck = &zsck;
101
102 if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
103 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
104 return NOTOK; /* Can't get an X.25 socket */
105 }
106
107 pgrp = getpid();
108 if (ioctl(sd, SIOCSPGRP, &pgrp)) {
109 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
110 return NOTOK; /* Error can be found in errno */
111 }
112
113 if (local != NULLNA) {
114 local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
115 if (local -> na_dtelen == 0) {
116 (void) strcpy (local -> na_dte, x25_local_dte);
117 local -> na_dtelen = strlen(x25_local_dte);
118 if (local -> na_pidlen == 0 && *x25_local_pid)
119 local -> na_pidlen =
120 str2sel (x25_local_pid, -1, local -> na_pid, NPSIZE);
121 }
122 }
123
124 (void) gen2if (local, sck, ADDR_LISTEN);
125 if (bind (sd, sck, sizeof(CONN_DB)) == NOTOK) {
126 SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
127 (void) close_x25_socket (sd);
128 return NOTOK;
129 }
130
131
132#ifdef notyet /* not sure if these are supported... */
133#ifndef BSD43
134 if (opt1)
135 (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
136 if (opt2)
137 (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
138#else
139 onoff = 1;
140 if (opt1)
141 (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
142 if (opt2)
143 (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
144#endif
145#endif
146
147 (void) listen (sd, backlog);
148
149 return sd;
150}
151
152/* \f */
153
154int join_x25_client (fd, remote)
155int fd;
156struct NSAPaddr *remote;
157{
158 CONN_DB sck;
159 int len = sizeof sck;
160 int nfd;
161
162 if((nfd = accept (fd, (struct sockaddr *) &sck, &len)) == NOTOK)
163 return NOTOK;
164 (void) if2gen (remote, &sck, ADDR_REMOTE);
165 return nfd;
166}
167
168int join_x25_server (fd, remote)
169int fd;
170struct NSAPaddr *remote;
171{
172 CONN_DB zsck;
173 CONN_DB *sck = &zsck;
174
175 if (remote == NULLNA || remote -> na_stack != NA_X25)
176 {
177 SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
178 ("Invalid type na%d", remote->na_stack));
179 return NOTOK;
180 }
181 (void) gen2if (remote, sck, ADDR_REMOTE);
182 return connect (fd, sck, sizeof (CONN_DB));
183}
184
185int read_x25_socket (fd, buffer, len)
186int fd, len;
187char *buffer;
188{
189 static u_char mode;
190 static struct iovec iov[2] = {
191 (char *)&mode, 1,
192 "", 0
193 };
194 char *p = buffer;
195 int cc, count = 0, total = len;
196
197 do {
198 iov[1].iov_base = p;
199 iov[1].iov_len = total > X25_PACKETSIZE ? X25_PACKETSIZE : total;
200
201 switch (cc = readv (fd, iov, 2)) {
202 /*
203 * for the -1,0 & 1 cases these returns should be ok
204 * if it's the first time through, then they are valid anyway
205 * later stages means the M bit is set so there must
206 * be more data else someone is violating the
207 * protocol badly.
208 */
209
210 case NOTOK:
211 case 0:
212 return cc;
213
214 case 1:
215 SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
216 ("strange return from read_x25_socket"));
217 return NOTOK;
218
219 default:
220 cc --; /* discount the info byte */
221 count += cc;
222 p += cc;
223 total -= cc;
224 }
225 } while (len > 0 && (mode & X25_MBIT));
226 DLOG (compat_log, LLOG_DEBUG, ("X25 read, total %d/%d", count, len));
227
228 return count;
229}
230
231#ifdef UBC_X25_WRITEV
232/* God this all very bizarre - iovecs work on read but not write!! */
233
234/*
235 * OK, this is due to a bug in UBC implementation. It may or may not
236 * be fixed in later versions. If writev allows you to write single
237 * bytes in the first vector then use this version. It's much more
238 * efficient.
239 */
240
241int write_x25_socket (fd, buffer, len)
242int fd, len;
243char *buffer;
244{
245 static u_char mode;
246 static struct iovec iov[2] = {
247 (char *)&mode, 1,
248 "", 0
249 };
250 int cc;
251 char *p = buffer;
252 int count, total = 0;
253
254 do {
255 count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len;
256 mode = len > X25_PACKETSIZE ? X25_MBIT : 0;
257 iov[1].iov_base = p;
258 iov[1].iov_len = count;
259 switch (cc = writev (fd, iov, 2))
260 {
261 case NOTOK:
262 case 0:
263 return cc;
264
265 case 1:
266 SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
267 ("strange return from write_x25_socket"));
268 return NOTOK;
269
270 default:
271 cc --;
272 len -= cc;
273 p += cc;
274 total += cc;
275 }
276 } while (len > 0);
277 DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len));
278 return total;
279}
280#else
281int write_x25_socket (fd, buffer, len)
282int fd, len;
283char *buffer;
284{
285 char mybuffer[X25_PACKETSIZE+1];
286 char *p = buffer;
287 int count, total = 0;
288 int cc;
289
290 do {
291 count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len;
292 mybuffer[0] = len > X25_PACKETSIZE ? X25_MBIT : 0;
293 bcopy (p, &mybuffer[1], count);
294 switch (cc = write (fd, mybuffer, count + 1))
295 {
296 case NOTOK:
297 case 0:
298 return cc;
299
300 case 1:
301 SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
302 ("strange return from write_x25_socket"));
303 return NOTOK;
304
305 default:
306 cc --;
307 len -= cc;
308 p += cc;
309 total += cc;
310 }
311 } while (len > 0);
312 DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len));
313 return total;
314}
315#endif
316
317#else /* UBC_X25 */
318int _ubcx25_stub2 () {};
319#endif /* UBC_X25 */
320#else /* X25 */
321int _ubcx25_stub () {};
322#endif /* X25 */