home *** CD-ROM | disk | FTP | other *** search
- /*
- * X.29 specific code for
- * Network Interface Machine server
- *
- * Frank Pronk
- * Copyright (c) 1984
- */
-
- #include <sys/types.h>
- #include "../h/x29.h"
-
- #include "nim.h"
-
- short pnums[NX29_PARMS] = {
- 1,2,3,4,5,6,7,8,9,10,11,12, /* 1978+1980 params */
- 13, 14, 15, 16, 17, 18 /* 1980 only */
- };
-
- char chartab[] = { /* EVEN parity and forwarding code table */
- 0000,0200,0200,0000,0200,0000,0000,0200,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0000,0200,0200,0000,0200,0000,0000,0200,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0000,0200,0200,0000,0200,0000,0000,0200,
- 0000,0200,0200,0000,0200,0000,0000,0200,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0000,0200,0200,0000,0200,0000,0000,0200,
- 0000,0200,0200,0000,0200,0000,0000,0200,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0000,0200,0200,0000,0200,0000,0000,0200,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0200,0000,0000,0200,0000,0200,0200,0000,
- 0000,0200,0200,0000,0200,0000,0000,0200,
- };
-
- char profiles[NPROFILES+1][NX29_PARMS] = {
- /* 1 2 3 4 5 6 7 8 9 10 11 12/13 14 15 16 17 18 */
- { 1, 1, 126, 0, 0, 1, 21, 0, 2, 0, 0, 1, 4, 0, 1, 8, 21, 18 },
- { 1, 0, 126, 0, 1, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 2, 0, 0, 1, 21, 0, 2, 0, 0, 1, 4, 0, 1, 8, 21, 18 },
- { 0, 0, 0, 20, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 2, 0, 0, 1, 21, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 2, 0, 0, 1, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
- };
-
- /*
- * Initialize user's profile
- */
-
- InitProfile(profile)
- {
- register int i;
-
- for(i = 0; i < 128; i++)
- CurrentX29Parms[i] = INVALID;
- for(i = 0; i < NetInfo.n_nparms; i++)
- CurrentX29Parms[pnums[i]] = profiles[profile][i];
- SetSpecialChars();
- CurrentProfile = profile;
- }
-
- SetSpecialChars()
- {
- register int c, code;
-
- for(c = 0; c < 128; c++)
- chartab[c] &= 0200;
-
- code = CurrentX29Parms[X29_FORWARDING_SIGNAL_CODE];
- if (code & 01) { /* A-Z, a-z, 0-9 */
- for (c = 'A'; c <= 'Z'; c++)
- chartab[c] |= C_FORWARD;
- for (c = 'a'; c <= 'z'; c++)
- chartab[c] |= C_FORWARD;
- for (c = '0'; c <= '9'; c++)
- chartab[c] |= C_FORWARD;
- }
- if (code & 02) /* CR */
- chartab['\r'] |= C_FORWARD;
- if (code & 04) { /* ESC, BEL, ENQ, ACK */
- chartab[033] |= C_FORWARD;
- chartab[07] |= C_FORWARD;
- chartab[05] |= C_FORWARD;
- chartab[06] |= C_FORWARD;
- }
- if (code & 8) { /* DEL, CAN, DC2 */
- chartab[0177] |= C_FORWARD;
- chartab[030] |= C_FORWARD;
- chartab[022] |= C_FORWARD;
- }
- if (code & 16) { /* ETX, EOT */
- chartab[03] |= C_FORWARD;
- chartab[04] |= C_FORWARD;
- }
- if (code & 32) { /* HT, LF, VT, FF */
- chartab[011] |= C_FORWARD;
- chartab[012] |= C_FORWARD;
- chartab[013] |= C_FORWARD;
- chartab[014] |= C_FORWARD;
- }
- if (code & 64) { /* control codes not in the above list */
- chartab[01] |= C_FORWARD;
- chartab[02] |= C_FORWARD;
- chartab[010] |= C_FORWARD;
- chartab[016] |= C_FORWARD;
- chartab[017] |= C_FORWARD;
- chartab[020] |= C_FORWARD;
- chartab[021] |= C_FORWARD;
- chartab[023] |= C_FORWARD;
- chartab[024] |= C_FORWARD;
- chartab[025] |= C_FORWARD;
- chartab[026] |= C_FORWARD;
- chartab[027] |= C_FORWARD;
- chartab[031] |= C_FORWARD;
- chartab[032] |= C_FORWARD;
- chartab[034] |= C_FORWARD;
- chartab[035] |= C_FORWARD;
- chartab[036] |= C_FORWARD;
- chartab[037] |= C_FORWARD;
- }
-
- if ((c = CurrentX29Parms[X29_ESCAPE_TO_CMD_CODE]) > 0)
- chartab[c==1 ? ('P' & 037) : c] |= C_ESCAPE;
-
- if (CurrentX29Parms[X29_EDITING]) {
- if ((c = CurrentX29Parms[X29_CHARACTER_DELETE]) > 0)
- chartab[c] |= C_ERASE;
- if ((c = CurrentX29Parms[X29_LINE_DELETE]) > 0)
- chartab[c] |= C_KILL;
- if ((c = CurrentX29Parms[X29_LINE_DISPLAY]) > 0)
- chartab[c] |= C_DISPLAY;
- }
- }
-
- X29ControlMessage (bp, len)
- register struct x29packet *bp;
- {
-
- ForwardPacket ();
- switch (bp->p_x29code) {
- case X29_SET_PARMS:
- if (SetNIM (bp, len))
- ReadNIM (bp, len);
- break;
-
- case X29_READ_PARMS:
- ReadNIM (bp, len);
- break;
-
- case X29_SET_AND_READ_PARMS:
- (void) SetNIM (bp, len);
- ReadNIM (bp, len);
- break;
-
- case X29_INVITATION_TO_CLEAR:
- ExitDataState ("remote directive");
- break;
-
- case X29_INDICATION_OF_BREAK:
- break;
-
- case X29_ERROR:
- log ("x.29 error indication from remote host");
- LogPacket ((char *)bp, len);
- break;
-
- default:
- X29Error ("Unknown X.29 request", bp, len, 1);
- }
- }
-
- /*
- * Bad news - we received an invalid or an
- * unknown packet. Send an error indication
- * to the remote host and dump the contents
- * of the packet in the log file.
- */
-
- X29Error (why, bp, len, code)
- struct x29packet *bp;
- char *why;
- {
- register struct x29packet *pp;
- char errmsg[4];
-
- log ("x.29 error: %s: packet contents:", why);
- LogPacket ((char *)bp, len);
- pp = (struct x29packet *)errmsg;
- pp->p_x29flag = Q_BIT;
- pp->p_x29code = X29_ERROR;
- pp->p_x29errno = code;
- pp->p_x29mtype = bp->p_x29code;
- ToNet (pp, sizeof (errmsg));
- }
-
- SetX29Parm (pnum, value)
- u_char pnum, value;
- {
- register int special = 0;
-
- if (pnum >= 128 || CurrentX29Parms[pnum] < 0)
- return (1);
- switch (pnum) {
- case X29_ESCAPE_TO_CMD_CODE:
- if (value > 1 && value != 033 && (value < 32 || value > 126))
- return (1);
- special++;
- break;
-
- case X29_ECHO_CODE:
- case X29_DISCARD_OUTPUT_CODE:
- case X29_XON_XOFF_CODE:
- if (value > 1)
- return (1);
- break;
-
- case X29_AUX_DEV_CONTROL_CODE:
- if (value > 1)
- return (1);
- OutputBlocked = 0;
- break;
-
- case X29_RECEIVE_NET_MSGS_CODE:
- if (value > 1 && value != 5)
- return (1);
- break;
-
- case X29_FORWARDING_SIGNAL_CODE:
- if (value > 127)
- return (1);
- special++;
- break;
-
- case X29_IDLE_TIMER_CODE:
- break;
-
- case X29_BREAK_PROCEDURE_CODE:
- if (value != 0 && value != 1 && value != 2 && value != 4 &&
- value != 5 && value != 8 && value != 16 && value != 21)
- return (1);
- break;
-
- case X29_PADDING_CODE:
- if (value > 7)
- return (1);
- break;
-
- case X29_LINE_FOLDING_CODE:
- break;
-
- case X29_TRANSMISSION_SPEED_CODE:
- /*
- * Trying to change the line speed is illegal.
- * This seems to be a defect in many PADs.
- * Rather than log an error and send a complaint back
- * to the remote PAD, we will quietly ignore the problem.
- */
- /* return (1); /* read-only variable */
- return (0);
-
- /* Parameters specific to 1980 CCITT recommendation */
-
- case X29_LF_AFTER_CR:
- if (value > 1 && (value < 4 || value > 7))
- return (1);
- break;
-
- case X29_PADDING_AFTER_LF:
- if (value > 7)
- return (1);
- break;
-
- case X29_EDITING:
- if (value > 1)
- return (1);
- special++;
- break;
-
- case X29_CHARACTER_DELETE:
- case X29_LINE_DELETE:
- case X29_LINE_DISPLAY:
- if (value > 127)
- return (1);
- special++;
- break;
-
- default:
- return (1);
- }
- CurrentX29Parms[pnum] = value;
- if (special)
- SetSpecialChars ();
- return (0);
- }
-
- SetNIM (bp, len)
- register struct x29packet *bp;
- {
- register int nparms;
-
- nparms = (struct x29param *)((char *)bp + len) - bp->p_x29param;
- if ((char *)&bp->p_x29param[nparms] != (char *)bp + len) {
- X29Error ("incomplete set parameter request", bp, len, 3);
- return (0);
- }
-
- /*
- * if no parameters then reset to subscription profile
- */
-
- if (nparms == 0) {
- register int i;
-
- nparms = NetInfo.n_nparms;
- for (i = 0; i < nparms; i++)
- (void) SetX29Parm (pnums[i], profiles[CurrentProfile][i]);
- return (0);
- } else {
- register struct x29param *xp;
- register int errors = 0;
-
- for (xp = bp->p_x29param; xp < &bp->p_x29param[nparms]; xp++) {
-
- /*
- * Stop processing parameters if we find a national
- * parameter marker. We don't support any network
- * specific private parameters. Rather than logging
- * an error and bouncing back a complaint to the
- * remote PAD, we will just give up.
- */
-
- if (xp->x29_pnum == X29_NATIONAL_PARAMETER_MARKER)
- break;
-
- /*
- * if attempt to set illegal parameter or legal
- * parameter to illegal value then mark parameter
- * as invalid.
- */
-
- if (SetX29Parm(xp->x29_pnum, xp->x29_value)) {
- if (errors == 0) {
- log ("x.29 error: invalid parameters in set parameter request:");
- LogPacket ((char *)bp, len);
- }
- xp->x29_pnum |= 0200;
- errors++;
- }
- }
- return (errors);
- }
- }
-
- ReadNIM (bp, len)
- register struct x29packet *bp;
- {
- register int nparms;
-
- nparms = (struct x29param *)((char *)bp + len) - bp->p_x29param;
- if ((char *)&bp->p_x29param[nparms] != (char *)bp + len) {
- X29Error ("incomplete read parameter request", bp, len, 3);
- return;
- }
-
- /*
- * if no parameters specified then send
- * all parameters.
- */
-
- if (nparms == 0) {
- register int i;
- register struct x29packet *pp;
- char reply[128];
-
- pp = (struct x29packet *)reply;
- pp->p_x29flag = Q_BIT;
- pp->p_x29code = X29_PARAMETER_INDICATION;
-
- nparms = NetInfo.n_nparms;
- for (i = 0; i < nparms; i++) {
- pp->p_x29param[i].x29_pnum = pnums[i];
- pp->p_x29param[i].x29_value = CurrentX29Parms[pnums[i]];
- }
- ToNet (pp, (char *)&pp->p_x29param[nparms] - (char *)pp);
- } else {
- register int pnum, errors = 0;
- register struct x29param *xp;
-
- /*
- * Scribble over the original Read Parameter request
- * replacing the message code and filling in the values
- * for the requested parameters.
- */
-
- bp->p_x29code = X29_PARAMETER_INDICATION;
- for (xp = bp->p_x29param; xp < &bp->p_x29param[nparms]; xp++) {
- pnum = xp->x29_pnum;
-
- /*
- * Parameters private to specific networks generate
- * lots of errors because we don't support any of them.
- * We'll set the errors flag to avoid filling our
- * log file with messages related to this limitation.
- */
-
- if (pnum == X29_NATIONAL_PARAMETER_MARKER)
- errors++;
- /*
- * If the requested parameter is invalid and has
- * not already been marked as invalid (by SetNIM()
- * in a set and read parameter request) then mark
- * the parameter as invalid and set its value to 0.
- */
-
- if ((pnum & 0200) == 0 && CurrentX29Parms[pnum] < 0) {
- if (errors == 0) {
- log ("x.29 error: invalid parameters in read parameter request:");
- LogPacket ((char *)bp, len);
- }
- pnum |= 0200;
- errors++;
- }
- if (pnum & 0200)
- xp->x29_value = 0;
- else
- xp->x29_value = CurrentX29Parms[pnum];
- }
- ToNet (bp, len);
- }
- }
-
- Break (code)
- {
- register struct x29packet *bp;
- char brkmsg[4];
-
- bp = (struct x29packet *)brkmsg;
- switch (code) {
- case 1: /* interrupt */
- SendX25Interrupt ();
- ForwardPacket ();
- return;
-
- case 2: /* reset */
- ResetBufs ();
- return;
-
- case 4: /* send indication of break */
- ForwardPacket();
- bp->p_x29flag = Q_BIT;
- bp->p_x29code = X29_INDICATION_OF_BREAK;
- ToNet (bp, 2);
- return;
-
- case 5: /* send interrupt and indication of break */
- SendX25Interrupt ();
- ForwardPacket();
- bp->p_x29flag = Q_BIT;
- bp->p_x29code = X29_INDICATION_OF_BREAK;
- ToNet (bp, 2);
- return;
-
- case 8: /* enter command state */
- EnterCommandState ();
- return;
-
- case 16: /* discard output */
- ForwardPacket();
- bp->p_x29flag = Q_BIT;
- bp->p_x29code = X29_PARAMETER_INDICATION;
- bp->p_x29param[0].x29_pnum = X29_DISCARD_OUTPUT_CODE;
- bp->p_x29param[0].x29_value = 1;
- ToNet (bp, 4);
- CurrentX29Parms[X29_DISCARD_OUTPUT_CODE] = 1;
- return;
-
- case 21: /* INT + BR indication + discard output */
- SendX25Interrupt ();
- ForwardPacket ();
- bp->p_x29flag = Q_BIT;
- bp->p_x29code = X29_INDICATION_OF_BREAK;
- bp->p_x29param[0].x29_pnum = X29_DISCARD_OUTPUT_CODE;
- bp->p_x29param[0].x29_value = 1;
- ToNet (bp, 4);
- CurrentX29Parms[X29_DISCARD_OUTPUT_CODE] = 1;
- return;
- }
- }
-
- /*
- * Change data pointed to by 'start' to be
- * even parity. Note that with the 1980 standard
- * there is no way to force an 8 bit data path,
- * but by convention, we do not set parity iff
- * data forwarding occurs only on timer expiry.
- */
-
- AddParity(start, len)
- register char *start;
- {
- register char *end;
-
- if(CurrentX29Parms[X29_FORWARDING_SIGNAL_CODE] == 0)
- return;
- end = start + len;
- while(start < end) {
- *start &= 0177;
- *start |= chartab[*start] & 0200;
- start++;
- }
- }
-