2 * Copyright (c) 1995, Index Data
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.17 1999-06-16 11:55:24 adam
8 * Added APDU log to client.
10 * Revision 1.16 1997/09/17 12:10:30 adam
13 * Revision 1.15 1997/05/14 06:53:34 adam
16 * Revision 1.14 1996/07/26 12:34:07 quinn
19 * Revision 1.13 1996/07/06 19:58:30 quinn
20 * System headerfiles gathered in yconfig
22 * Revision 1.12 1996/05/22 08:34:44 adam
23 * Added ifdef USE_XTIMOSI; so that 'make depend' works.
25 * Revision 1.11 1996/02/23 10:00:41 quinn
28 * Revision 1.10 1996/02/10 12:23:13 quinn
29 * Enablie inetd operations fro TCP/IP stack
31 * Revision 1.9 1996/01/02 08:57:28 quinn
32 * Changed enums in the ASN.1 .h files to #defines. Changed oident.class to oclass
34 * Revision 1.8 1995/11/01 13:54:29 quinn
37 * Revision 1.7 1995/10/30 12:41:17 quinn
38 * Added hostname lookup for server.
40 * Revision 1.6 1995/09/29 17:12:00 quinn
43 * Revision 1.5 1995/09/28 10:24:32 quinn
46 * Revision 1.4 1995/09/27 15:02:45 quinn
47 * Modified function heads & prototypes.
49 * Revision 1.3 1995/06/16 10:30:38 quinn
52 * Revision 1.2 1995/06/15 12:30:07 quinn
53 * Added @ as hostname alias for INADDR ANY.
55 * Revision 1.1 1995/06/14 09:58:20 quinn
56 * Renamed yazlib to comstack.
58 * Revision 1.15 1995/05/29 08:12:33 quinn
59 * Updates to aynch. operations.
61 * Revision 1.14 1995/05/16 09:37:31 quinn
64 * Revision 1.13 1995/05/16 08:51:19 quinn
65 * License, documentation, and memory fixes
67 * Revision 1.12 1995/05/02 08:53:24 quinn
68 * Trying in vain to fix comm with ISODE
70 * Revision 1.11 1995/04/21 16:32:08 quinn
71 * *** empty log message ***
73 * Revision 1.10 1995/03/27 08:36:14 quinn
74 * Some work on nonblocking operation in xmosi.c and rfct.c.
75 * Added protocol parameter to cs_create()
77 * Revision 1.9 1995/03/20 09:47:23 quinn
78 * Added server-side support to xmosi.c
79 * Fixed possible problems in rfct
82 * Revision 1.8 1995/03/16 13:29:30 quinn
83 * Beginning to add server-side functions
85 * Revision 1.7 1995/03/14 10:28:47 quinn
86 * Adding server-side support to tcpip.c and fixing bugs in nonblocking I/O
88 * Revision 1.6 1995/03/09 15:22:43 quinn
89 * Fixed two bugs in get/rcv
91 * Revision 1.5 1995/03/07 16:29:47 quinn
94 * Revision 1.4 1995/03/07 10:26:56 quinn
95 * Initialized type field in the comstacks.
97 * Revision 1.3 1995/03/06 16:48:03 quinn
100 * Revision 1.2 1995/03/06 10:54:41 quinn
101 * Server-side functions (t_bind/t_listen/t_accept) seem to work ok, now.
102 * Nonblocking mode needs work (and testing!)
103 * Added makensap to replace function in mosiutil.c.
105 * Revision 1.1 1995/03/01 08:40:33 quinn
106 * First working version of rfct. Addressing needs work.
112 * Glue layer for Peter Furniss' xtimosi package.
123 #include <comstack.h>
128 int mosi_connect(COMSTACK h, void *address);
129 int mosi_get(COMSTACK h, char **buf, int *bufsize);
130 int mosi_put(COMSTACK h, char *buf, int size);
131 int mosi_more(COMSTACK h) { return 0; } /* not correct */
132 int mosi_close(COMSTACK h);
133 int mosi_rcvconnect(COMSTACK h);
134 int mosi_bind(COMSTACK h, void *address, int mode);
135 int mosi_listen(COMSTACK h, char *addrp, int *addrlen);
136 COMSTACK mosi_accept(COMSTACK h);
137 char *mosi_addrstr(COMSTACK h);
138 void *mosi_straddr(COMSTACK h, const char *str);
140 typedef struct mosi_state
142 struct t_info info; /* data returned by t_open */
144 int hasread; /* how many bytes read of current PDU */
145 int haswrit; /* how many bytes have we written */
146 struct netbuf netbuf;
149 static char *oidtostr(int *o)
151 static char buf[512];
156 sprintf(buf + strlen(buf), "%d", *o);
163 static int addopt(struct netbuf *optbuf, unsigned long level, unsigned long
164 name, enum oid_proto proto, enum oid_class class, enum oid_value value)
173 if (!(oid = oid_getoidbyent(&ent)))
176 if (addoidoption(optbuf, level, name, str) < 0)
181 COMSTACK mosi_type(int s, int blocking, int protocol)
190 if (!(r = xmalloc(sizeof(*r))))
192 if (!(state = r->cprivate = xmalloc(sizeof(*state))))
198 r->protocol = protocol;
201 r->blocking = blocking;
202 r->f_connect = mosi_connect;
205 r->f_close = mosi_close;
206 r->f_more = mosi_more;
207 r->f_rcvconnect = mosi_rcvconnect;
208 r->f_bind = mosi_bind;
209 r->f_listen = mosi_listen;
210 r->f_accept = mosi_accept;
211 r->f_addrstr = mosi_addrstr;
212 r->r_straddr = mosi_straddr;
216 if ((r->iofile = u_open(CO_MOSI_NAME, flags, &state->info)) < 0)
219 r->timeout = COMSTACK_DEFAULT_TIMEOUT;
224 int hex2oct(char *hex, char *oct)
229 while (sscanf(hex, "%2x", &val) == 1)
233 *((unsigned char*) oct++) = (unsigned char) val;
241 * addressing specific to our hack of OSI transport. A sockaddr_in wrapped
242 * up in a t_mosiaddr in a netbuf (on a stick).
245 int *mosi_strtoaddr_ex(const char *str, struct netbuf *ret)
247 struct sockaddr_in *add = xmalloc(sizeof(struct sockaddr_in));
248 struct t_mosiaddr *mosiaddr = xmalloc(sizeof(struct t_mosiaddr));
250 char *p, *b, buf[512], *nsap;
251 short int port = 102;
252 unsigned long tmpadd;
255 assert(ret && add && mosiaddr);
257 mosiaddr->osi_ap_inv_id = NO_INVOKEID;
258 mosiaddr->osi_ae_inv_id = NO_INVOKEID;
260 mosiaddr->osi_apt_len = 0;
261 mosiaddr->osi_aeq_len = 0;
262 p = (char*)MOSI_PADDR(mosiaddr);
263 *(p++) = 0; /* No presentation selector */
265 *(p++) = 0; /* no session selector */
267 /* do we have a transport selector? */
269 if ((nsap = strchr(buf, '/')))
272 if ((*p = hex2oct(buf, p + 1)) < 0)
285 add->sin_family = AF_INET;
287 if ((b = strchr(buf, ':')))
292 add->sin_port = htons(port);
293 if (!strcmp("@", buf))
294 add->sin_addr.s_addr = INADDR_ANY;
295 else if ((hp = gethostbyname(buf)))
296 memcpy(&add->sin_addr.s_addr, *hp->h_addr_list, sizeof(struct in_addr));
297 else if ((tmpadd = inet_addr(buf)) != 0)
298 memcpy(&add->sin_addr.s_addr, &tmpadd, sizeof(struct in_addr));
301 *(p++) = (char) sizeof(*add);
303 memcpy(p, add, sizeof(*add));
311 mosiaddr->osi_paddr_len = ll;
312 ret->buf = (char*)mosiaddr;
313 ret->len = ret->maxlen = 100 /* sizeof(*mosiaddr) */ ;
318 struct netbuf *mosi_strtoaddr(const char *str)
320 struct netbuf *ret = xmalloc(sizeof(struct netbuf));
322 if (!mosi_strtoaddr_ex (str, ret))
330 struct netbuf *mosi_straddr(COMSTACK h, const char *str)
332 mosi_state *st = h->cprivate;
333 struct netbuf *ret = &st->netbuf;
335 if (!mosi_strtoaddr_ex (str, ret))
343 int mosi_connect(COMSTACK h, void *address)
345 struct netbuf *addr = address, *local;
346 struct t_call *snd, *rcv;
349 if (!(snd = (struct t_call *) u_alloc(h->iofile, T_CALL, T_ALL)))
351 if (!(rcv = (struct t_call *) u_alloc(h->iofile, T_CALL, T_ALL)))
355 if (addopt(&snd->opt, ISO_APCO, AP_CNTX_NAME, h->protocol, CLASS_APPCTX,
358 if (addopt(&snd->opt, ISO_APCO, AP_ABS_SYN, h->protocol, CLASS_ABSYN,
362 * We don't specify record formats yet.
364 * Xtimosi adds the oid for BER as transfer syntax automatically.
369 if (h->state == CS_UNBND)
371 local = mosi_strtoaddr(""); /* not good in long run */
372 memcpy(&bnd.addr, local, sizeof(*local));
373 if (u_bind(h->iofile, &bnd, 0) < 0)
377 memcpy(&snd->addr, addr, sizeof(*addr));
378 if (u_connect(h->iofile, snd, rcv) < 0)
380 if (t_errno == TNODATA)
387 int mosi_rcvconnect(COMSTACK h)
389 if (u_rcvconnect(h->iofile, 0) < 0)
391 if (t_errno == TNODATA)
398 int mosi_bind(COMSTACK h, void *address, int mode)
404 if (setsockopt(h->iofile, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
409 if (mode == CS_SERVER)
413 memcpy(&bnd.addr, address, sizeof(struct netbuf));
414 if ((res = u_bind(h->iofile, &bnd, 0)) < 0)
420 int mosi_listen(COMSTACK h, char *addp, int *addrlen)
423 mosi_state *st = h->cprivate;
425 if (!(st->call = (struct t_call*) t_alloc(h->iofile, T_CALL_STR,
428 if ((res = u_listen(h->iofile, st->call)) < 0)
430 if (t_errno == TNODATA)
438 COMSTACK mosi_accept(COMSTACK h)
442 struct mosi_state *st = h->cprivate, *ns;
445 if (h->state != CS_INCON)
447 h->cerrno = CSOUTSTATE;
450 if (!(new = xmalloc(sizeof(*new))))
453 if (!(new->cprivate = ns = xmalloc(sizeof(*ns))))
458 if ((new->iofile = u_open_r(CO_MOSI_NAME, flags, &st->info, st->call)) < 0)
460 if (!(local = mosi_strtoaddr("")))
462 if (mosi_bind(new, local, CS_CLIENT) < 0) /* CS_CLIENT: qlen == 0 */
464 memcpy(&st->call->addr, local, sizeof(st->call->addr));
465 if (u_accept(h->iofile, new->iofile, st->call) < 0)
473 #define CS_MOSI_BUFCHUNK 4096
475 int mosi_get(COMSTACK h, char **buf, int *bufsize)
478 mosi_state *ct = h->cprivate;
485 if (!(*buf = xmalloc(*bufsize = CS_MOSI_BUFCHUNK)))
488 else if (*bufsize - ct->hasread < CS_MOSI_BUFCHUNK)
489 if (!(*buf =xrealloc(*buf, *bufsize *= 2)))
492 if ((res = u_rcv(h->iofile, *buf + ct->hasread, CS_MOSI_BUFCHUNK,
495 if (t_errno == TNODATA)
501 while (flags & T_MORE);
503 /* all done. Reset hasread */
509 int mosi_put(COMSTACK h, char *buf, int size)
511 mosi_state *ct = h->cprivate;
512 int res = u_snd(h->iofile, buf + ct->haswrit, size - ct->haswrit, 0);
514 if (res == size - ct->haswrit)
521 if (t_errno == TFLOW)
529 int mosi_close(COMSTACK h)
538 char *mosi_addrstr(COMSTACK h)
540 return "osi:[UNIMPLEMENTED]";