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