home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / contrib / usr.x25 / nimd / x29.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-13  |  11.8 KB  |  515 lines

  1. /*
  2.  * X.29 specific code for
  3.  * Network Interface Machine server
  4.  *
  5.  * Frank Pronk
  6.  * Copyright (c) 1984
  7.  */
  8.  
  9. #include <sys/types.h>
  10. #include "../h/x29.h"
  11.  
  12. #include "nim.h"
  13.  
  14. short     pnums[NX29_PARMS] = {
  15.     1,2,3,4,5,6,7,8,9,10,11,12,    /* 1978+1980 params */
  16.     13, 14, 15, 16, 17, 18        /* 1980 only */
  17. };
  18.  
  19. char chartab[] = {    /* EVEN parity and forwarding code table */
  20.     0000,0200,0200,0000,0200,0000,0000,0200,
  21.     0200,0000,0000,0200,0000,0200,0200,0000,
  22.     0200,0000,0000,0200,0000,0200,0200,0000,
  23.     0000,0200,0200,0000,0200,0000,0000,0200,
  24.     0200,0000,0000,0200,0000,0200,0200,0000,
  25.     0000,0200,0200,0000,0200,0000,0000,0200,
  26.     0000,0200,0200,0000,0200,0000,0000,0200,
  27.     0200,0000,0000,0200,0000,0200,0200,0000,
  28.     0200,0000,0000,0200,0000,0200,0200,0000,
  29.     0000,0200,0200,0000,0200,0000,0000,0200,
  30.     0000,0200,0200,0000,0200,0000,0000,0200,
  31.     0200,0000,0000,0200,0000,0200,0200,0000,
  32.     0000,0200,0200,0000,0200,0000,0000,0200,
  33.     0200,0000,0000,0200,0000,0200,0200,0000,
  34.     0200,0000,0000,0200,0000,0200,0200,0000,
  35.     0000,0200,0200,0000,0200,0000,0000,0200,
  36. };
  37.  
  38. char    profiles[NPROFILES+1][NX29_PARMS] = {
  39. /*    1  2    3   4  5  6   7  8  9 10 11 12/13 14 15   16   17   18 */
  40.     { 1, 1, 126,  0, 0, 1, 21, 0, 2, 0, 0, 1, 4, 0, 1,   8,  21,  18 },
  41.     { 1, 0, 126,  0, 1, 1,  2, 0, 0, 0, 0, 1, 0, 0, 0,   0,   0,   0 },
  42.     { 1, 0,   2,  0, 0, 1, 21, 0, 2, 0, 0, 1, 4, 0, 1,   8,  21,  18 },
  43.     { 0, 0,   0, 20, 0, 0,  2, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0 },
  44.     { 1, 0,   2,  0, 0, 1, 21, 0, 2, 0, 0, 0, 0, 0, 0,   0,   0,   0 },
  45.     { 1, 0,   2,  0, 0, 1,  2, 0, 2, 0, 1, 0, 0, 0, 0,   0,   0,   0 },
  46.     { 0, 0,   0,  4, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0 }
  47. };
  48.  
  49. /*
  50.  * Initialize user's profile
  51.  */
  52.  
  53. InitProfile(profile)
  54. {
  55.     register int i;
  56.  
  57.     for(i = 0; i < 128; i++)
  58.         CurrentX29Parms[i] = INVALID;
  59.     for(i = 0; i < NetInfo.n_nparms; i++)
  60.         CurrentX29Parms[pnums[i]] = profiles[profile][i];
  61.     SetSpecialChars();
  62.     CurrentProfile = profile;
  63. }
  64.  
  65. SetSpecialChars()
  66. {
  67.     register int c, code;
  68.  
  69.     for(c = 0; c < 128; c++)
  70.         chartab[c] &= 0200;
  71.  
  72.     code = CurrentX29Parms[X29_FORWARDING_SIGNAL_CODE];
  73.     if (code & 01) {    /* A-Z, a-z, 0-9 */
  74.         for (c = 'A'; c <= 'Z'; c++)
  75.             chartab[c] |= C_FORWARD;
  76.         for (c = 'a'; c <= 'z'; c++)
  77.             chartab[c] |= C_FORWARD;
  78.         for (c = '0'; c <= '9'; c++)
  79.             chartab[c] |= C_FORWARD;
  80.     }
  81.     if (code & 02)        /* CR */
  82.         chartab['\r'] |= C_FORWARD;
  83.     if (code & 04) {    /* ESC, BEL, ENQ, ACK */
  84.         chartab[033] |= C_FORWARD;
  85.         chartab[07] |= C_FORWARD;
  86.         chartab[05] |= C_FORWARD;
  87.         chartab[06] |= C_FORWARD;
  88.     }
  89.     if (code & 8) {        /* DEL, CAN, DC2 */
  90.         chartab[0177] |= C_FORWARD;
  91.         chartab[030] |= C_FORWARD;
  92.         chartab[022] |= C_FORWARD;
  93.     }
  94.     if (code & 16) {    /* ETX, EOT */
  95.         chartab[03] |= C_FORWARD;
  96.         chartab[04] |= C_FORWARD;
  97.     }
  98.     if (code & 32) {    /* HT, LF, VT, FF */
  99.         chartab[011] |= C_FORWARD;
  100.         chartab[012] |= C_FORWARD;
  101.         chartab[013] |= C_FORWARD;
  102.         chartab[014] |= C_FORWARD;
  103.     }
  104.     if (code & 64) {    /* control codes not in the above list */
  105.         chartab[01] |= C_FORWARD;
  106.         chartab[02] |= C_FORWARD;
  107.         chartab[010] |= C_FORWARD;
  108.         chartab[016] |= C_FORWARD;
  109.         chartab[017] |= C_FORWARD;
  110.         chartab[020] |= C_FORWARD;
  111.         chartab[021] |= C_FORWARD;
  112.         chartab[023] |= C_FORWARD;
  113.         chartab[024] |= C_FORWARD;
  114.         chartab[025] |= C_FORWARD;
  115.         chartab[026] |= C_FORWARD;
  116.         chartab[027] |= C_FORWARD;
  117.         chartab[031] |= C_FORWARD;
  118.         chartab[032] |= C_FORWARD;
  119.         chartab[034] |= C_FORWARD;
  120.         chartab[035] |= C_FORWARD;
  121.         chartab[036] |= C_FORWARD;
  122.         chartab[037] |= C_FORWARD;
  123.     }
  124.  
  125.     if ((c = CurrentX29Parms[X29_ESCAPE_TO_CMD_CODE]) > 0)
  126.         chartab[c==1 ? ('P' & 037) : c] |= C_ESCAPE;
  127.  
  128.     if (CurrentX29Parms[X29_EDITING]) {
  129.         if ((c = CurrentX29Parms[X29_CHARACTER_DELETE]) > 0)
  130.             chartab[c] |= C_ERASE;
  131.         if ((c = CurrentX29Parms[X29_LINE_DELETE]) > 0)
  132.             chartab[c] |= C_KILL;
  133.         if ((c = CurrentX29Parms[X29_LINE_DISPLAY]) > 0)
  134.             chartab[c] |= C_DISPLAY;
  135.     }
  136. }
  137.  
  138. X29ControlMessage (bp, len)
  139. register struct x29packet *bp;
  140. {
  141.  
  142.     ForwardPacket ();
  143.     switch (bp->p_x29code) {
  144.     case X29_SET_PARMS:
  145.         if (SetNIM (bp, len))
  146.             ReadNIM (bp, len);
  147.         break;
  148.  
  149.     case X29_READ_PARMS:
  150.         ReadNIM (bp, len);
  151.         break;
  152.  
  153.     case X29_SET_AND_READ_PARMS:
  154.         (void) SetNIM (bp, len);
  155.         ReadNIM (bp, len);
  156.         break;
  157.  
  158.     case X29_INVITATION_TO_CLEAR:
  159.         ExitDataState ("remote directive");
  160.         break;
  161.  
  162.     case X29_INDICATION_OF_BREAK:
  163.         break;
  164.  
  165.     case X29_ERROR:
  166.         log ("x.29 error indication from remote host");
  167.         LogPacket ((char *)bp, len);
  168.         break;
  169.         
  170.     default:
  171.         X29Error ("Unknown X.29 request", bp, len, 1);
  172.     }
  173. }
  174.  
  175. /*
  176.  * Bad news - we received an invalid or an
  177.  * unknown packet.  Send an error indication
  178.  * to the remote host and dump the contents
  179.  * of the packet in the log file.
  180.  */
  181.  
  182. X29Error (why, bp, len, code)
  183. struct x29packet *bp;
  184. char *why;
  185. {
  186.     register struct x29packet *pp;
  187.     char errmsg[4];
  188.  
  189.     log ("x.29 error: %s: packet contents:", why);
  190.     LogPacket ((char *)bp, len);
  191.     pp = (struct x29packet *)errmsg;
  192.     pp->p_x29flag = Q_BIT;
  193.     pp->p_x29code = X29_ERROR;
  194.     pp->p_x29errno = code;
  195.     pp->p_x29mtype = bp->p_x29code;
  196.     ToNet (pp, sizeof (errmsg));
  197. }
  198.  
  199. SetX29Parm (pnum, value)
  200. u_char pnum, value;
  201. {
  202.     register int special = 0;
  203.  
  204.     if (pnum >= 128 || CurrentX29Parms[pnum] < 0)
  205.         return (1);
  206.     switch (pnum) {
  207.     case X29_ESCAPE_TO_CMD_CODE:
  208.         if (value > 1 && value != 033 && (value < 32 || value > 126))
  209.             return (1);
  210.         special++;
  211.         break;
  212.  
  213.     case X29_ECHO_CODE:
  214.     case X29_DISCARD_OUTPUT_CODE:
  215.     case X29_XON_XOFF_CODE:
  216.         if (value > 1)
  217.             return (1);
  218.         break;
  219.  
  220.     case X29_AUX_DEV_CONTROL_CODE:
  221.         if (value > 1)
  222.             return (1);
  223.         OutputBlocked = 0;
  224.         break;
  225.  
  226.     case X29_RECEIVE_NET_MSGS_CODE:
  227.         if (value > 1 && value != 5)
  228.             return (1);
  229.         break;
  230.  
  231.     case X29_FORWARDING_SIGNAL_CODE:
  232.         if (value > 127)
  233.             return (1);
  234.         special++;
  235.         break;
  236.  
  237.     case X29_IDLE_TIMER_CODE:
  238.         break;
  239.  
  240.     case X29_BREAK_PROCEDURE_CODE:
  241.         if (value != 0 && value != 1 && value != 2 && value != 4 &&
  242.             value != 5 && value != 8 && value != 16 && value != 21)
  243.             return (1);
  244.         break;
  245.  
  246.     case X29_PADDING_CODE:
  247.         if (value > 7)
  248.             return (1);
  249.         break;
  250.  
  251.     case X29_LINE_FOLDING_CODE:
  252.         break;
  253.  
  254.     case X29_TRANSMISSION_SPEED_CODE:
  255.     /*
  256.      * Trying to change the line speed is illegal.
  257.      * This seems to be a defect in many PADs.
  258.      * Rather than log an error and send a complaint back
  259.      * to the remote PAD, we will quietly ignore the problem.
  260.      */
  261. /*        return (1);    /* read-only variable */
  262.         return (0);
  263.  
  264.     /* Parameters specific to 1980 CCITT recommendation */
  265.  
  266.     case X29_LF_AFTER_CR:
  267.         if (value > 1 && (value < 4 || value > 7))
  268.             return (1);
  269.         break;
  270.  
  271.     case X29_PADDING_AFTER_LF:
  272.         if (value > 7)
  273.             return (1);
  274.         break;
  275.  
  276.     case X29_EDITING:
  277.         if (value > 1)
  278.             return (1);
  279.         special++;
  280.         break;
  281.  
  282.     case X29_CHARACTER_DELETE:
  283.     case X29_LINE_DELETE:
  284.     case X29_LINE_DISPLAY:
  285.         if (value > 127)
  286.             return (1);
  287.         special++;
  288.         break;
  289.  
  290.     default:
  291.         return (1);
  292.     }
  293.     CurrentX29Parms[pnum] = value;
  294.     if (special)
  295.         SetSpecialChars ();
  296.     return (0);
  297. }
  298.  
  299. SetNIM (bp, len)
  300. register struct x29packet *bp;
  301. {
  302.     register int nparms;
  303.  
  304.     nparms = (struct x29param *)((char *)bp + len) - bp->p_x29param;
  305.     if ((char *)&bp->p_x29param[nparms] != (char *)bp + len) {
  306.         X29Error ("incomplete set parameter request", bp, len, 3);
  307.         return (0);
  308.     }
  309.  
  310.     /*
  311.      * if no parameters then reset to subscription profile
  312.      */
  313.  
  314.     if (nparms == 0) {
  315.         register int i;
  316.  
  317.         nparms = NetInfo.n_nparms;
  318.         for (i = 0; i < nparms; i++)
  319.             (void) SetX29Parm (pnums[i], profiles[CurrentProfile][i]);
  320.             return (0);
  321.     } else {
  322.         register struct x29param *xp;
  323.         register int errors = 0;
  324.  
  325.         for (xp = bp->p_x29param; xp < &bp->p_x29param[nparms]; xp++) {
  326.  
  327.             /*
  328.              * Stop processing parameters if we find a national
  329.              * parameter marker.  We don't support any network
  330.              * specific private parameters.  Rather than logging
  331.              * an error and bouncing back a complaint to the
  332.              * remote PAD, we will just give up.
  333.              */
  334.  
  335.             if (xp->x29_pnum == X29_NATIONAL_PARAMETER_MARKER)
  336.                 break;
  337.  
  338.             /*
  339.              * if attempt to set illegal parameter or legal
  340.              * parameter to illegal value then mark parameter
  341.              * as invalid.
  342.              */
  343.  
  344.             if (SetX29Parm(xp->x29_pnum, xp->x29_value)) {
  345.                 if (errors == 0) {
  346.                     log ("x.29 error: invalid parameters in set parameter request:");
  347.                     LogPacket ((char *)bp, len);
  348.                 }
  349.                 xp->x29_pnum |= 0200;
  350.                 errors++;
  351.             }
  352.         }
  353.         return (errors);
  354.     }
  355. }
  356.  
  357. ReadNIM (bp, len)
  358. register struct x29packet *bp;
  359. {
  360.     register int nparms;
  361.  
  362.     nparms = (struct x29param *)((char *)bp + len) - bp->p_x29param;
  363.     if ((char *)&bp->p_x29param[nparms] != (char *)bp + len) {
  364.         X29Error ("incomplete read parameter request", bp, len, 3);
  365.         return;
  366.     }
  367.  
  368.     /*
  369.      * if no parameters specified then send
  370.      * all parameters.
  371.      */
  372.  
  373.     if (nparms == 0) {
  374.         register int i;
  375.         register struct x29packet *pp;
  376.         char reply[128];
  377.  
  378.         pp = (struct x29packet *)reply;
  379.         pp->p_x29flag = Q_BIT;
  380.         pp->p_x29code = X29_PARAMETER_INDICATION;
  381.  
  382.         nparms = NetInfo.n_nparms;
  383.         for (i = 0; i < nparms; i++) {
  384.             pp->p_x29param[i].x29_pnum = pnums[i];
  385.             pp->p_x29param[i].x29_value = CurrentX29Parms[pnums[i]];
  386.         }
  387.         ToNet (pp, (char *)&pp->p_x29param[nparms] - (char *)pp);
  388.     } else {
  389.         register int pnum, errors = 0;
  390.         register struct x29param *xp;
  391.  
  392.         /*
  393.          * Scribble over the original Read Parameter request
  394.          * replacing the message code and filling in the values
  395.          * for the requested parameters.
  396.          */
  397.  
  398.         bp->p_x29code = X29_PARAMETER_INDICATION;
  399.         for (xp = bp->p_x29param; xp < &bp->p_x29param[nparms]; xp++) {
  400.             pnum = xp->x29_pnum;
  401.  
  402.             /*
  403.              * Parameters private to specific networks generate
  404.              * lots of errors because we don't support any of them.
  405.              * We'll set the errors flag to avoid filling our
  406.              * log file with messages related to this limitation.
  407.              */
  408.  
  409.             if (pnum == X29_NATIONAL_PARAMETER_MARKER)
  410.                 errors++;
  411.             /*
  412.              * If the requested parameter is invalid and has
  413.              * not already been marked as invalid (by SetNIM()
  414.              * in a set and read parameter request) then mark
  415.              * the parameter as invalid and set its value to 0.
  416.              */
  417.  
  418.             if ((pnum & 0200) == 0 && CurrentX29Parms[pnum] < 0) {
  419.                 if (errors == 0) {
  420.                     log ("x.29 error: invalid parameters in read parameter request:");
  421.                     LogPacket ((char *)bp, len);
  422.                 }
  423.                 pnum |= 0200;
  424.                 errors++;
  425.             }
  426.             if (pnum & 0200)
  427.                 xp->x29_value = 0;
  428.             else
  429.                 xp->x29_value = CurrentX29Parms[pnum];
  430.         }
  431.         ToNet (bp, len);
  432.     }
  433. }
  434.  
  435. Break (code)
  436. {
  437.     register struct x29packet *bp;
  438.     char brkmsg[4];
  439.  
  440.     bp = (struct x29packet *)brkmsg;
  441.     switch (code) {
  442.     case 1:        /* interrupt */
  443.         SendX25Interrupt ();
  444.         ForwardPacket ();
  445.         return;
  446.  
  447.     case 2:        /* reset */
  448.         ResetBufs ();
  449.         return;
  450.  
  451.     case 4:        /* send indication of break */
  452.         ForwardPacket();
  453.         bp->p_x29flag = Q_BIT;
  454.         bp->p_x29code = X29_INDICATION_OF_BREAK;
  455.         ToNet (bp, 2);
  456.         return;
  457.  
  458.     case 5:        /* send interrupt and indication of break */
  459.         SendX25Interrupt ();
  460.         ForwardPacket();
  461.         bp->p_x29flag = Q_BIT;
  462.         bp->p_x29code = X29_INDICATION_OF_BREAK;
  463.         ToNet (bp, 2);
  464.         return;
  465.  
  466.     case 8:        /* enter command state */
  467.         EnterCommandState ();
  468.         return;
  469.  
  470.     case 16:    /* discard output */
  471.         ForwardPacket();
  472.         bp->p_x29flag = Q_BIT;
  473.         bp->p_x29code = X29_PARAMETER_INDICATION;
  474.         bp->p_x29param[0].x29_pnum = X29_DISCARD_OUTPUT_CODE;
  475.         bp->p_x29param[0].x29_value = 1;
  476.         ToNet (bp, 4);
  477.         CurrentX29Parms[X29_DISCARD_OUTPUT_CODE] = 1;
  478.         return;
  479.  
  480.     case 21:    /* INT + BR indication + discard output */
  481.         SendX25Interrupt ();
  482.         ForwardPacket ();
  483.         bp->p_x29flag = Q_BIT;
  484.         bp->p_x29code = X29_INDICATION_OF_BREAK;
  485.         bp->p_x29param[0].x29_pnum = X29_DISCARD_OUTPUT_CODE;
  486.         bp->p_x29param[0].x29_value = 1;
  487.         ToNet (bp, 4);
  488.         CurrentX29Parms[X29_DISCARD_OUTPUT_CODE] = 1;
  489.         return;
  490.     }
  491. }
  492.  
  493. /*
  494.  * Change data pointed to by 'start' to be
  495.  * even parity.  Note that with the 1980 standard
  496.  * there is no way to force an 8 bit data path,
  497.  * but by convention, we do not set parity iff
  498.  * data forwarding occurs only on timer expiry.
  499.  */
  500.  
  501. AddParity(start, len)
  502. register char *start;
  503. {
  504.     register char *end;
  505.  
  506.     if(CurrentX29Parms[X29_FORWARDING_SIGNAL_CODE] == 0)
  507.         return;
  508.     end = start + len;
  509.     while(start < end) {
  510.         *start &= 0177;
  511.         *start |= chartab[*start] & 0200;
  512.         start++;
  513.     }
  514. }
  515.