home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 525.L2C.C < prev    next >
Text File  |  1988-05-14  |  42KB  |  877 lines

  1. /**************************************************************************\
  2. *                                                                          *
  3. *                                                                          *
  4. *    *****                      *****                                      *
  5. *      *****                  *****                                        *
  6. *        *****              *****                                          *
  7. *          *****          *****                                            *
  8. *            *****      *****                                              *
  9. *              *****  *****                                                *
  10. *            *****      *****                                              *
  11. *          *****          *****          The Firmware. The Net.            *
  12. *        *****              *****        Portable. Compatible.             *
  13. *      *****                  *****      Public Domain.                    *
  14. *    *****                      *****    By NORD><LINK.                    *
  15. *                                                                          *
  16. *                                                                          *
  17. *                                                                          *
  18. *    L2C.C   -   Level 2, Teil 3                                           *
  19. *                                                                          *
  20. *    angelegt:      DC4OX                                                  *
  21. *    modifiziert:                                                          *
  22. *                                                                          *
  23. \**************************************************************************/
  24.  
  25.  
  26.  
  27.  
  28.  
  29. /*                                                             Includes   */
  30. /**************************************************************************/
  31.  
  32. #include "all.h"         /* allgemeine Festlegungen                       */
  33. #include "l2.h"          /* Festlegungen/Datenstrukturen fuer den Level 2 */
  34. #include "l2s.h"         /* Zugriff auf die State-Tabellen                */
  35. #include "l2ext.h"       /* globale Variable / nicht int-Funktionen       */
  36.  
  37.  
  38.  
  39.  
  40.  
  41. /**************************************************************************\
  42. *                                                                          *
  43. * action      :  Zustandsuebergangsfunktionen der Level-2-Statetable       *
  44. *                (x.../t...), Level-2-Timer setzen/aufloesen (setT./clrT.) *
  45. *                und Utilities fuer diese Funktionen.                      *
  46. *                                                                          *
  47. *   t2rrr()   -  Timer 2 setzen, nach Ablauf RR als Response zu senden     *
  48. *   t2rnrr()  -  Timer 2 setzen, nach Ablauf RNR als Response zu senden    *
  49. *   t2rejr()  -  Timer 2 setzen, nach Ablauf REJ als Response zu senden    *
  50. *                                                                          *
  51. *   xnull()   -  nichts tun                                                *
  52. *                                                                          *
  53. *   xrrc()    -  RR als Command senden                                     *
  54. *   xrrr()    -  RR als Response senden                                    *
  55. *   xrnrc()   -  RNR als Command senden                                    *
  56. *   xrnrr()   -  RNR als Response senden                                   *
  57. *   xrejr()   -  REJ als Response senden                                   *
  58. *                                                                          *
  59. *   xdm()     -  DM senden                                                 *
  60. *   xua()     -  UA senden                                                 *
  61. *   xsabm()   -  SABM senden                                               *
  62. *   xdisc()   -  DISC senden                                               *
  63. *                                                                          *
  64. *   xfrmr()   -  FRMR senden (-> L2E.C)                                    *
  65. *                                                                          *
  66. *   setT1()   -  Timer 1 setzen und Timer 3 loeschen                       *
  67. *   clrT1()   -  Timer 1 und tries loeschen, Timer 3 setzen                *
  68. *   setT2()   -  Timer 2 und nach Ablauf zu sendenden Frametyp setzen      *
  69. *   clrT2()   -  Timer 2 und nach Ablauf zu sendenden Frametyp loeschen    *
  70. *   setT3()   -  Timer 3 setzen, wenn Version 2 Protokoll benutzt wird     *
  71. *   clrT3()   -  Timer 3 loeschen                                          *
  72. *                                                                          *
  73. *   sendS()   -  Supervisory-Frame fuer Sendung aufbauen, Timer 2          *
  74. *                loeschen, Frame senden                                    *
  75. *   sdfrmr()  -  FRMR-Frame fuer Sendung aufbauen und senden (-> L2E.C)    *
  76. *                                                                          *
  77. \**************************************************************************/
  78.  
  79. VOID t2rrr()  { setT2(L2CRR);                                              }
  80.  
  81. VOID t2rnrr() { setT2(L2CRNR);                                             }
  82.  
  83. VOID t2rejr() { setT2(L2CREJ);                                             }
  84.  
  85. VOID setT1()  { lnkpoi->T1 = lnkpoi->initT1 + random(); clrT3();           }
  86.  
  87. VOID clrT1()  { lnkpoi->T1 = lnkpoi->tries = 0; setT3();                   }
  88.  
  89. VOID setT2(Stype) char Stype;
  90.               { lnkpoi->RStype = Stype; lnkpoi->T2 = T2par;                }
  91.  
  92. VOID clrT2()  { lnkpoi->T2 = 0; lnkpoi->RStype = 0;                        }
  93.  
  94. VOID setT3()  { if (lnkpoi->V2link == YES) lnkpoi->T3 = T3par;             }
  95.  
  96. VOID clrT3()  { lnkpoi->T3 = 0;                                            }
  97.  
  98. VOID xnull()  {                                                            }
  99.  
  100. VOID xrrc()   { stxcfr(); xrrr();                                          }
  101.  
  102. VOID xrrr()   { sendS(L2CRR);                                              }
  103.  
  104. VOID xrnrc()  { stxcfr(); xrnrr();                                         }
  105.  
  106. VOID xrnrr()  { sendS(L2CRNR);                                             }
  107.  
  108. VOID xrejr()  { sendS(L2CREJ);                                             }
  109.  
  110. VOID sendS(control) char control;
  111.               { clrT2(); txfctl=setNR(control);
  112.                 sdl2fr(makfhd(!txfCR ? L2FUS : (L2FUS | L2FT1ST))); }
  113.  
  114. VOID xdm()    { txfctl = L2CDM; sdl2fr(makfhd(L2FUS));                     }
  115.  
  116. VOID xua()    { txfctl = L2CUA; sdl2fr(makfhd(L2FUS));                     }
  117.  
  118. VOID xsabm()  { stxcfr(); txfctl = L2CSABM; sdl2fr(makfhd(L2FUS|L2FT1ST)); }
  119.  
  120. VOID xdisc()  { stxcfr(); txfctl = L2CDISC; sdl2fr(makfhd(L2FUS|L2FT1ST)); }
  121.  
  122.  
  123.  
  124.  
  125.  
  126. /**************************************************************************\
  127. *                                                                          *
  128. * "set tx command frame"                                                   *
  129. *                                                                          *
  130. * TX-Frame-Adressierung setzen (siehe stxfad()) und Frame zum Kommando-    *
  131. * frame machen mit gesetztem Pollbit (txfCR,txfPF).                        *
  132. *                                                                          *
  133. \**************************************************************************/
  134.  
  135. VOID stxcfr()
  136.   {
  137.     stxfad();                           /* Adressierung                   */
  138.     txfCR = L2CCR;                      /* Command !                      */
  139.     txfPF = L2CPF;                      /* Pollbit !                      */
  140.   }
  141.  
  142.  
  143.  
  144.  
  145.  
  146. /**************************************************************************\
  147. *                                                                          *
  148. * "set tx frame address"                                                   *
  149. *                                                                          *
  150. * Adressierung des aktuellen Sendeframes (txfhdr, txfprt) setzen aus den   *
  151. * im aktuellen Linkblock (lnkpoi) gegebenen Parametern (srcid, destid,     *
  152. * viaidl, liport).                                                         *
  153. *                                                                          *
  154. \**************************************************************************/
  155.  
  156. VOID stxfad()
  157.   {
  158.     cpyid(txfhdr + L2IDLEN,lnkpoi->srcid);        /* von ...              */
  159.     cpyid(txfhdr,lnkpoi->dstid);                  /* nach ...             */
  160.     cpyidl(txfhdr + L2ILEN,lnkpoi->viaidl);       /* ueber ...            */
  161.     txfprt = lnkpoi->liport;                      /* auf Port ...         */
  162.   }
  163.  
  164.  
  165.  
  166.  
  167.  
  168. /**************************************************************************\
  169. *                                                                          *
  170. * "set NR"                                                                 *
  171. *                                                                          *
  172. * Im aktuellen Linkblock (lnkpoi) die zuletzt gesendete N(R) (ltxdNR) auf  *
  173. * V(R) (VR) setzen und Framecontrolbyte control fuer Frameaussendung mit   *
  174. * der N(R) versehen und zurueckgeben.                                      *
  175. *                                                                          *
  176. * Return :  control mit N(R) versehen                                      *
  177. *                                                                          *
  178. \**************************************************************************/
  179.  
  180. unsigned setNR(control)
  181.  
  182. char control;
  183.  
  184.   {
  185.     lnkpoi->ltxdNR = lnkpoi->VR;             /* neue N(R)                 */
  186.     return((lnkpoi->VR << 5) | control);     /* N(R) ins Kontrollfeld     */
  187.   }
  188.  
  189.  
  190.  
  191.  
  192.  
  193. /**************************************************************************\
  194. *                                                                          *
  195. * "send level 2 frame"                                                     *
  196. *                                                                          *
  197. * Framebuffer, auf dessen Kopf fbp zeigt, rewinden und in die dem Port     *
  198. * (l2port) entsprechende Level-2-Sendeframeliste einhaengen, wenn noch     *
  199. * genug Buffer im System frei sind. Andernfalls nicht senden, sondern      *
  200. * sofort in die Gesendet-Liste (stfl) einhaengen. Bei TheNet die           *
  201. * Sendeaktiviatetsvariable (istraf) des entsprechenden Ports setzen.       *
  202. *                                                                          *
  203. \**************************************************************************/
  204.  
  205. VOID sdl2fr(fbp)
  206.  
  207. MBHEAD *fbp;
  208.  
  209.   {
  210.     unsigned port;                      /* Portnummer                     */
  211.     
  212.     port = fbp->l2port;                 /* Portnummer holen               */
  213.     if (nmbfre > 64)                    /* noch genug Buffer ?            */
  214.       {
  215.         rwndmb(fbp);                    /* ja   - Framebuffer rewinden    */
  216.         DIinc();                        /*        Listenkonsistenz !      */
  217.         relink(fbp,txl2fl[port].tail);  /*        Frame in Sendeliste     */
  218.         kicktx(port);                   /*        es ist was zu senden !  */
  219.         decEI();                        /*        Interrupts w. erlauben  */
  220.  
  221. #ifndef FIRMWARE
  222.         istraf[port] = YES;             /*        es ist Port-Traffic     */
  223. #endif
  224.  
  225.       }
  226.     else                                /* nein - Frame einfach sofort    */
  227.       relink(fbp,stfl.tail);            /*        als gesendet betrachten */
  228.   }
  229.  
  230.  
  231.  
  232.  
  233.  
  234. /**************************************************************************\
  235. *                                                                          *
  236. * "copy frame buffer"                                                      *
  237. *                                                                          *
  238. * Framebuffer, auf den fbp zeigt, komplett mit Inhalt kopieren. Dazu freie *
  239. * Buffer allokieren, Portnummer (l1port) wird kopiert, Bufferzeiger (mbbp) *
  240. * und Getcounter (mbgc) werden nicht kopiert, bleiben aber im Quellframe   *
  241. * erhalten.                                                                *
  242. *                                                                          *
  243. * Return :  Zeiger auf Kopf des kopierten Framebuffers                     *
  244. *                                                                          *
  245. \**************************************************************************/
  246.  
  247. #ifdef FIRMWARE
  248.  
  249. MBHEAD *cpyfb(fbp)
  250.  
  251. MBHEAD *fbp;
  252.  
  253.   {
  254.     char       *savmbbp;                /* mbbp-Sicherung                 */
  255.     unsigned    savmbgc;                /* mbgc-Sicherung                 */
  256.     MBHEAD     *newfbp;                 /* Zeiger auf die Kopie           */
  257.     
  258.     savmbbp = fbp->mbbp;                /* mbbp sichern                   */
  259.     savmbgc = fbp->mbgc;                /* mbgc sichern                   */
  260.     rwndmb(fbp);                        /* Quellframe rewinden            */
  261.     newfbp = allocb();                  /* Kopf der Kopie allokieren      */
  262.     while (fbp->mbgc < fbp->mbpc)       /* Daten byteweise kopieren       */
  263.       putchr(getchr(fbp),newfbp);
  264.     newfbp->l2port = fbp->l2port;       /* Portnummer kopieren            */
  265.     fbp->mbbp = savmbbp;                /* mbbp wieder auf alten Wert     */ 
  266.     fbp->mbgc = savmbgc;                /* mbgc wieder auf alten Wert     */
  267.     return (newfbp);                    /* Zeiger auf Kopf der Kopie      */
  268.   }
  269.  
  270. #endif
  271.  
  272.  
  273.  
  274.  
  275.  
  276. /**************************************************************************\
  277. *                                                                          *
  278. * "take frame head"                                                        *
  279. *                                                                          *
  280. * Adresskopf und Kontrollbyte des Frames aus dem Framebuffer, auf dessen   *
  281. * Kopf fbp zeigt, analysieren. Diese Funktion ist die erste, die auf ein   *
  282. * empfangenes Frame angewandt wird.                                        *
  283. *                                                                          *
  284. *                                                                          *
  285. * Folgende Parameter werden bei der Analyse gesetzt (siehe auch L2V.C) :   *
  286. *                                                                          *
  287. *    rxfhdr, rxfV2, rxfPF, rxfCR, rxfctl, rxfprt                           *
  288. *                                                                          *
  289. *                                                                          *
  290. * Folgende Parameter werden nach der Analyse gesetzt fuer ein moegliches   *
  291. * Antwortframe :                                                           *
  292. *                                                                          *
  293. *   txfhdr  = Quell- und Zielcall aus rxfhdr, aber vertauscht, plus        *
  294. *             reverse via-Liste aus rxfhdr                                 *
  295. *   txfV2   = rxfV2                                                        *
  296. *   txfPF   = rxfPF                                                        *
  297. *   txfCR   = 0, Response !                                                *
  298. *   txfprt  = rxfprt                                                       *
  299. *                                                                          *
  300. *                                                                          *
  301. * Return :  TRUE  - das Frame hat einen gueltigen AX.25-Framekopf          *
  302. *           FALSE - sonst                                                  *
  303. *                                                                          *
  304. \**************************************************************************/
  305.  
  306. BOOLEAN takfhd(fbp)
  307.  
  308. MBHEAD *fbp;
  309.  
  310.   {
  311.     char *viap;                                   /* Zeiger in via-Liste  */
  312.     char *source;                                 /* Quellzeiger Kopien   */
  313.     char *dest;                                   /* Zielzeiger Kopien    */
  314.  
  315.     rwndmb(fbp);                                  /* Frame von vorne      */
  316.     if (    !getfid(rxfhdr,fbp)                   /* Zielcall holen       */
  317.          || ((rxfhdr[L2IDLEN - 1] & L2CEOA) != 0) /* (Ende nach 1. Call ?)*/
  318.          || !getfid(rxfhdr + L2IDLEN,fbp)         /* Quellcall holen      */
  319.        ) return (FALSE);                          /* ... schon Fehler     */
  320.     viap = rxfhdr + L2ILEN;                       /* ab hier via-Liste    */
  321.     if (!(rxfhdr[L2ILEN - 1] & L2CEOA))           /* via-Liste da ?       */
  322.       LOOP
  323.         {                                               /* alle via's     */
  324.           if (!getfid(viap,fbp)) return (FALSE);        /* Call holen     */
  325.           viap += L2IDLEN;                              /* naechstes Call */
  326.           if ((*(viap - 1) & L2CEOA) != 0) break;       /* Ende der Liste */
  327.           if (viap >= rxfhdr + L2AFLEN) return (FALSE); /* zu lange Liste */
  328.         }
  329.     *viap = '\0';                                       /* Listenende !   */
  330.     if (fbp->mbgc == fbp->mbpc) return (FALSE);         /* Frame zu kurz  */
  331.     rxfctl = getchr(fbp);                               /* Controlbyte    */
  332.  
  333.  
  334.     /* Protokollversion feststellen und danach C/R und P/F festlegen */
  335.  
  336.     if ( (rxfV2 = ((rxfhdr[L2IDLEN - 1] ^ rxfhdr[L2ILEN - 1]) & L2CCR) != 0)
  337.          == YES
  338.        )
  339.       {                                           /* nur Version 2 :      */
  340.         rxfCR = rxfhdr[L2IDLEN - 1] & L2CCR;      /*   Command/Response   */
  341.         rxfPF = rxfctl & L2CPF;                   /*   Poll/Final         */
  342.       }
  343.     else                                          /* Version 1 :          */
  344.       rxfPF = rxfCR = 0;                          /* P/F u. C/R sinnlos   */
  345.  
  346.     rxfctl &= ~L2CPF;                             /* P/F Control loeschen */
  347.     rxfprt = fbp->l2port;                         /* Portnummer holen     */
  348.  
  349.  
  350.     /* Antwort-Sendeframeaufbau */
  351.  
  352.     txfCR = 0;                                    /* Response !           */
  353.     txfV2 = rxfV2;                                /* Version              */
  354.     txfPF = rxfPF;                                /* Poll/Final           */
  355.     txfprt = rxfprt;                              /* Portnummer           */
  356.     cpyid(txfhdr,rxfhdr + L2IDLEN);               /* TX-Ziel = RX-Quelle  */
  357.     cpyid(txfhdr + L2IDLEN,rxfhdr);               /* TX-Quelle = RX-Ziel  */
  358.     source = rxfhdr + L2ILEN;                     /* TX-Antwort-via-Liste */
  359.     dest = txfhdr + L2ILEN;                       /* ist, falls vorhanden */
  360.     while (*source != '\0') source += L2IDLEN;    /* reverse RX-via-Liste */
  361.     while (source != rxfhdr + L2ILEN)
  362.       {
  363.         source -= L2IDLEN;
  364.         cpyid(dest,source);
  365.         dest += L2IDLEN;
  366.       }
  367.     *dest = '\0';                                 /* Listenende !         */
  368.  
  369.     return (TRUE);                                /* Frame soweit okay !  */
  370.   }
  371.  
  372.  
  373.  
  374.  
  375.  
  376. /**************************************************************************\
  377. *                                                                          *
  378. * "get frame ID"                                                           *
  379. *                                                                          *
  380. * Die naechste ID nach dest (Call + SSID, SSID wie im Frame) holen aus dem *
  381. * Buffer (Call + SSID, beide wie im Frame), auf dessen Kopf mbhd zeigt.    *
  382. * Die geholte SSID enthaelt das End-Of-Address-Bit unveraendert.           *
  383. *                                                                          *
  384. * Return :  TRUE  - die naechste ID (Call + SSID) wurde richtig geholt     *
  385. *           FALSE - es hat sich ein Fehler ereignet                        *
  386. *                                                                          *
  387. \**************************************************************************/
  388.  
  389. BOOLEAN getfid(dest,mbhd)
  390.  
  391. char     *dest;
  392. MBHEAD   *mbhd;
  393.  
  394.   {
  395.     char       c;                       /* aktuelles Zeichen aus Buffer   */
  396.     unsigned   n;                       /* Zaehler Call-Laenge            */
  397.  
  398.     if (mbhd->mbpc - mbhd->mbgc < L2IDLEN)        /* im Buffer nicht mehr */
  399.       return (FALSE);                             /* genug Bytes fuer ID  */
  400.     for (n = 0; n < L2CALEN; ++n)                 /* Call byteweise holen */
  401.       {
  402.         if (((c = getchr(mbhd)) & L2CEOA) != 0)   /* Adressfeld zu frueh  */
  403.           return (FALSE);                         /* zuende               */
  404.         *dest++ = (c >> 1) & 0x7F;                /* Framecall -> ASCII   */
  405.       }
  406.     *dest = getchr(mbhd);               /* SSID holen, EOA bleibt         */
  407.     return (TRUE);
  408.   }
  409.  
  410.  
  411.  
  412.  
  413.  
  414. /**************************************************************************\
  415. *                                                                          *
  416. * "make frame head"                                                        *
  417. *                                                                          *
  418. * Neues Frame aufbauen aus den txf...-Parametern. Es werden neue Buffer    *
  419. * fuer das Frame allokiert, der aktuelle Linkblock (lnkpoi) wird           *
  420. * eingetragen und fflag fuer das Frameflag l2fflg.                         *
  421. *                                                                          *
  422. * Return :  Zeiger auf Framebufferkopf des neu erzeugten Frames            *
  423. *                                                                          *
  424. \**************************************************************************/
  425.  
  426. MBHEAD *makfhd(fflag)
  427.  
  428. unsigned fflag;
  429.  
  430.   {
  431.     MBHEAD *fbp;                                  /* Zeiger auf Kopf      */
  432.     
  433.     if (txfV2 == YES)                             /* wenn Version 2 ...   */
  434.       {
  435.         txfhdr[L2IDLEN - 1] |= txfCR;             /* ... C-Bits setzen    */
  436.         txfhdr[L2ILEN - 1] |= txfCR ^ L2CCR;
  437.       }
  438.     putfid(txfhdr,fbp = allocb());                /* neuer Buffer, Ziel   */
  439.     putfid(txfhdr + L2IDLEN,fbp);                 /* Quellcall            */
  440.     putvia(txfhdr + L2ILEN,fbp);                  /* via-Liste            */
  441.     putchr(!txfV2 ? txfctl : txfctl | txfPF,fbp); /* Control + P/F        */
  442.     fbp->l2link = lnkpoi;                         /* Verweis Linkblock    */
  443.     fbp->type = 2;                                /* Level 2 !            */
  444.     fbp->l2fflg = fflag;                          /* Frameflag            */
  445.     fbp->l2port = txfprt;                         /* Portnummer           */
  446.     return (fbp);                                 /* Kopfzeiger zurueck   */
  447.   }
  448.  
  449.  
  450.  
  451.  
  452.  
  453. /**************************************************************************\
  454. *                                                                          *
  455. * "put via"                                                                *
  456. *                                                                          *
  457. * Nullterminierte via-Liste, auf die idl zeigt, in den Framebuffer, auf    *
  458. * dessen Kopf mbhd zeigt, uebertragen. Die Nullterminierung nicht ueber-   *
  459. * tragen, aber am Ende der via-Liste das letzte Zeichen der via-Liste mit  *
  460. * dem HDLC End-Of-Address-Bit uebertragen.                                 *
  461. *                                                                          *
  462. \**************************************************************************/
  463.  
  464. VOID putvia(idl,mbhd)
  465.  
  466. char     *idl;
  467. MBHEAD   *mbhd;
  468.  
  469.   {
  470.     while (*idl != '\0')                /* gesamte via-Liste in den       */
  471.       {                                 /* Framebuffer uebertragen        */
  472.         putfid(idl,mbhd);
  473.         idl += L2IDLEN;
  474.       }                                 /* dann                           */
  475.     *(mbhd->mbbp - 1) |= L2CEOA;        /* EoA direkt im Buffer setzen    */
  476.   }
  477.  
  478.  
  479.  
  480.  
  481.  
  482. /**************************************************************************\
  483. *                                                                          *
  484. * "put frame id"                                                           *
  485. *                                                                          *
  486. * ID (Call und SSID, SSID wie im Frame), auf die id zeigt, in den          *
  487. * Framebuffer, auf dessen Kopf mbhd zeigt, uebertragen. Dabei Call von     *
  488. * ASCII in Frameformat (1 Bit linksgeschoben) umwandeln.                   *
  489. *                                                                          *
  490. \**************************************************************************/
  491.  
  492. VOID putfid(id,mbhd)
  493.  
  494. char     *id;
  495. MBHEAD   *mbhd;
  496.  
  497.   {
  498.     unsigned n;                         /* Zaehler Call-Laenge            */
  499.     
  500.     for (n = 0; n < L2CALEN; ++n)       /* Call uebertragen in Buffer,    */
  501.       putchr(*id++ << 1,mbhd);          /* 1 Bit linksgeschoben           */
  502.     putchr(*id,mbhd);                   /* SSID unveraendert uebertragen  */
  503.   }
  504.  
  505.  
  506.  
  507.  
  508.  
  509. /**************************************************************************\
  510. *                                                                          *
  511. * "is to me"                                                               *
  512. *                                                                          *
  513. * Pruefen, ob die ID (Call + SSID, SSID wie im Frame), auf die id zeigt,   *
  514. * mit der ID der eigenen Station (myid) uebereinstimmt (SSID wird ohne     *
  515. * Steuerbits verglichen), oder ob das Call, auf das id zeigt, mit dem      *
  516. * symbolischen Namen (alias) der eigenen Station uebereinstimmt.           *
  517. *                                                                          *
  518. * Return :  TRUE  - myid stimmt mit id ueberein oder alias mit dem         *
  519. *                   call in id                                             *
  520. *           FALSE - sonst                                                  *
  521. *                                                                          *
  522. \**************************************************************************/
  523.  
  524. BOOLEAN istome(id)
  525.  
  526. char *id;
  527.  
  528.   {
  529.     return (cmpid(myid,id) == TRUE || cmpcal(alias,id) == TRUE);
  530.   }
  531.  
  532.  
  533.  
  534.  
  535.  
  536. /**************************************************************************\
  537. *                                                                          *
  538. * "compare calls"                                                          *
  539. *                                                                          *
  540. * Calls miteinander vergleichen.                                           *
  541. *                                                                          *
  542. * Return :  TRUE  - die Calls stimmen ueberein                             *
  543. *           FALSE - die Calls stimmen nicht ueberein oder mindestens eins  *
  544. *                   der Calls beginnt mit einem Blank                      *
  545. *                                                                          *
  546. \**************************************************************************/
  547.  
  548. BOOLEAN cmpcal(call1,call2)
  549.  
  550. char *call1;
  551. char *call2;
  552.  
  553.   {
  554.     unsigned n;                                        /* Zaehler         */
  555.     
  556.     for (n = 0; n < L2CALEN; ++n)                      /* jedes Zeichen   */
  557.       if (    (!n && (*call2 == ' ' || *call1 == ' ')) /* 1. Zeich. ' ' ? */
  558.            || (*call2++ != *call1++)                   /* sonst gleich ?  */
  559.          ) return (NO);                                /* nein            */
  560.     return (YES);                                      /* ja, alle gleich */
  561.   }
  562.  
  563.  
  564.  
  565.  
  566.  
  567. /**************************************************************************\
  568. *                                                                          *
  569. * "compare ID list"                                                        *
  570. *                                                                          *
  571. * Nullterminierte ID-Listen (Calls + SSID's, SSID wie im Frame)            *
  572. * miteinander vergleichen (SSID nur reine SSID 0-15 vergleichen ohne       *
  573. * Steuerbits).                                                             *
  574. *                                                                          *
  575. * Return :  TRUE  - die ID-Listen stimmen ueberein                         *
  576. *           FALSE - sonst                                                  *
  577. *                                                                          *
  578. \**************************************************************************/
  579.  
  580. BOOLEAN cmpidl(idl1,idl2)
  581.  
  582. char *idl1;
  583. char *idl2;
  584.  
  585.   {
  586.     while (*idl2 != '\0')                         /* bis Liste 2 zuende   */
  587.       {
  588.         if (!cmpid(idl1,idl2)) return (NO);       /* ID's vergleichen     */
  589.         idl2 += L2IDLEN;                          /* Zeiger auf naechste  */
  590.         idl1 += L2IDLEN;                          /* ID's                 */
  591.       }                                           /* Listen gleich, wenn  */
  592.     return (!*idl1);                              /* beide zuende         */
  593.   }
  594.  
  595.  
  596.  
  597.  
  598.  
  599. /**************************************************************************\
  600. *                                                                          *
  601. * "compare ID's"                                                           *
  602. *                                                                          *
  603. * ID's (Call + SSID, SSID wie im Frame) miteinander vergleichen (SSID nur  *
  604. * reine SSID 0-15 vergleichen ohne Steuerbits).                            *
  605. *                                                                          *
  606. * Return :  TRUE  - die ID's stimmen ueberein                              *
  607. *           FALSE - sonst                                                  *
  608. *                                                                          *
  609. \**************************************************************************/
  610.  
  611. BOOLEAN cmpid(id1,id2)
  612.  
  613. char *id1;
  614. char *id2;
  615.  
  616.   {
  617.     unsigned n;                                   /* Zaehler              */
  618.     
  619.     for (n = 0; n < L2CALEN; ++n)                 /* Calls vergleichen    */
  620.       if (*id2++ != *id1++) return (NO);
  621.     return ((*id2 & 0x1E) == (*id1 & 0x1E));      /* reine SSID vergl.    */
  622.   }
  623.  
  624.  
  625.  
  626.  
  627.  
  628. /**************************************************************************\
  629. *                                                                          *
  630. * "copy ID list"                                                           *
  631. *                                                                          *
  632. * Nullterminierte ID-Liste (Calls + SSID's, SSID wie im Frame) von source  *
  633. * nach dest kopieren, Zielliste mit '\0' abschliessen.                     *
  634. *                                                                          *
  635. \**************************************************************************/
  636.  
  637. VOID cpyidl(dest,source)
  638.  
  639. char *dest;
  640. char *source;
  641.  
  642.   {
  643.     while (*source != '\0')             /* solange Liste nicht zuende     */
  644.       {
  645.         cpyid(dest,source);             /* ID kopieren                    */
  646.         source += L2IDLEN;              /* Zeiger um eine ID-Laenge       */
  647.         dest += L2IDLEN;                /* weiter                         */
  648.       }
  649.     *dest = '\0';                       /* Zielliste abschliessen         */
  650.   }
  651.  
  652.  
  653.  
  654.  
  655.  
  656. /**************************************************************************\
  657. *                                                                          *
  658. * "copy ID"                                                                *
  659. *                                                                          *
  660. * Komplette ID (Call + SSID, SSID wie im Frame), auf die source zeigt,     *
  661. * nach dest kopieren. In der kopierten SSID das End-Of-Address-Bit und das *
  662. * Command/Response/Has-Been-Repeated-Bit loeschen.                         *
  663. *                                                                          *
  664. \**************************************************************************/
  665.  
  666. VOID cpyid(dest,source)
  667.  
  668. char *dest;
  669. char *source;
  670.  
  671.   {
  672.     unsigned n;                           /* Laengenzaehler               */
  673.  
  674.     for (n = 0; n < L2CALEN; ++n)         /* Call kopieren                */
  675.       *dest++ = *source++;
  676.     *dest = *source & ~(L2CEOA | L2CCR);  /* SSID kopieren, Bits loeschen */
  677.   }
  678.  
  679.  
  680.  
  681.  
  682.  
  683. /**************************************************************************\
  684. *                                                                          *
  685. * "deallocate message list"                                                *
  686. *                                                                          *
  687. * Komplette Messageliste, auf deren Listenkopf mlp zeigt, deallokieren.    *
  688. * D.h. alle Messagespeicher (jeweils Kopf und daran haengende Datenbuffer) *
  689. * deallokieren.                                                            *
  690. *                                                                          *
  691. *                                                                          *
  692. *            +--------+    +--------+               +--------+             *
  693. *    mlp --->| head   |--->|        |--->       --->|        |---> mlp     *
  694. *            +--------+    +--------+      ...      +--------+             *
  695. *      b <---| tail   |<---|        |<---       <---|        |<--- b       *
  696. *            +--------+    +--------+               +--------+             *
  697. *                          |        |---> \         |        |---> \       *
  698. *                          +        +      |        +        +      |      *
  699. *                          |        |<--- /|        |        |<--- /|      *
  700. *                          +--------+      |        +--------+      |      *
  701. *                          |        |      |        |        |      |      *
  702. *                                          |                        |      *
  703. *      deallokieren                        |------------------------|      *
  704. *                                            siehe unten dealmb()          *
  705. *                                                                          *
  706. \**************************************************************************/
  707.  
  708. VOID dealml(mlp)
  709.  
  710. LEHEAD *mlp;
  711.  
  712.   {
  713.     MBHEAD *bp;                         /* Zeiger auf Messagebufferhead   */
  714.     
  715.     LOOP                                /* fuer alle Messagebufferheads   */
  716.       {                                 /* in Messagespeicherliste :      */
  717.         DIinc();                        /* Listenkonsistenz !             */
  718.         bp = mlp->nextle;               /* Zeiger auf naechsten Msgbhead  */
  719.         decEI();                        /* Interrupts wieder erlauben     */
  720.         if (mlp == bp) break;           /* Schwanz beisst Kopf -> fertig  */
  721.         dealmb(unlink(bp));             /* sonst Messagespeicher deallok. */
  722.       }
  723.   }
  724.  
  725.  
  726.  
  727.  
  728.  
  729. /**************************************************************************\
  730. *                                                                          *
  731. * "deallocate message buffer"                                              *
  732. *                                                                          *
  733. * Einen kompletten Messagespeicher, auf dessen Kopf mbhd zeigt,            *
  734. * deallokieren, d.h. sowohl den Messagebufferhead als auch alle an dessen  *
  735. * Messagebufferliste haengende Datenbuffer deallokieren.                   *
  736. *                                                                          *
  737. *                                                                          *
  738. *            +--------+           deallokieren                             *
  739. *    mbhd -->|        |                                                    *
  740. *            +--------+                                                    *
  741. *            |        |                                                    *
  742. *            +--------+      +--------+                +--------+          *
  743. *      a --->|        |----->|        |--->        --->|        |---> a    *
  744. *            +  mbl   +      +--------+      ...       +--------+          *
  745. *      b <---|        |<-----|        |<---        <---|        |<--- b    *
  746. *            +--------+      +--------+                +--------+          *
  747. *            |        |      |        |                |        |          *
  748. *                                                                          *
  749. \**************************************************************************/
  750.  
  751. VOID dealmb(mbhd)
  752.  
  753. MBHEAD *mbhd;
  754.  
  755.   {
  756.     MB *bp;                                       /* Datenbufferzeiger    */
  757.     
  758.     while ((bp = mbhd->mbl.head) != &mbhd->mbl)   /* alle Datenbuffer     */
  759.       dealoc(unlink(bp));
  760.     dealoc(mbhd);                                 /* am Ende den Kopf     */
  761.   }
  762.  
  763.  
  764.  
  765.  
  766.  
  767. /**************************************************************************\
  768. *                                                                          *
  769. * "deallocate"                                                             *
  770. *                                                                          *
  771. * Buffer, auf den bp zeigt, initialisieren als neuen Messagebufferhead     *
  772. * (rwndmb()) und deallokieren, d.h. in die Freiliste freel einhaengen und  *
  773. * den Freibufferzaehler nmbfre inkrementieren.                             *
  774. *                                                                          *
  775. *                                                                          *
  776. *            +--------+                                                    *
  777. *     bp --->|        |         deallokieren                               *
  778. *            +--------+                                                    *
  779. *            |        |                                                    *
  780. *            +--------+                                                    *
  781. *            |        |                                                    *
  782. *                                                                          *
  783. \**************************************************************************/
  784.  
  785. VOID dealoc(bp)
  786.  
  787. MBHEAD *bp;
  788.  
  789.   {
  790.       bp->mbl.head                      /* als Messagehead initialisieren */
  791.     = bp->mbl.tail                      /*   Bufferlistenkopf             */
  792.     = &bp->mbl;                         /*   initialisieren               */
  793.     bp->mbpc = 0;                       /*   Message leer                 */
  794.     rwndmb(bp);                         /*   Rest initialisieren          */
  795.     DIinc();                            /* Listenkonsistenz !             */
  796.     relink(bp,freel.tail);              /* Buffer an Freiliste anhaengen  */
  797.     ++nmbfre;                           /* 1 Freibuffer mehr              */
  798.     decEI();                            /* Interrupts wieder erlauben     */
  799.   }
  800.  
  801.  
  802.  
  803.  
  804.  
  805. /**************************************************************************\
  806. *                                                                          *
  807. * "initialize head"                                                        *
  808. *                                                                          *
  809. * Listenkopf, auf den hd zeigt, initialisieren :                           *
  810. *                                                                          *
  811. *                                                                          *
  812. *                                              +----------------------+    *
  813. *                                              | +------------------+ |    *
  814. *                                              | |                  | |    *
  815. *            +--------+                        v v   +--------+     | |    *
  816. *     hd --->|        |         ->        hd ------->|        |-----+ |    *
  817. *            +--------+                              +--------+       |    *
  818. *            |        |                              |        |-------+    *
  819. *            +--------+                              +--------+            *
  820. *            |        |                              |        |            *
  821. *                                                                          *
  822. \**************************************************************************/
  823.  
  824. VOID inithd(hd)
  825.  
  826. LHEAD *hd;
  827.  
  828.   {
  829.     hd->head = hd->tail = hd;
  830.   }
  831.  
  832.  
  833.  
  834.  
  835.  
  836. /**************************************************************************\
  837. *                                                                          *
  838. * "level 2 to level x"                                                     *
  839. *                                                                          *
  840. * Meldung msg (L2M...) an Layer 3 und hoehere Layer weitergeben.           *
  841. *                                                                          *
  842. \**************************************************************************/
  843.  
  844. VOID l2tolx(msg)
  845.  
  846. unsigned msg;
  847.  
  848.   {
  849.     l2tol3(msg);                        /* Layer 2  ->  Layer 3           */
  850.     l2tol7(msg,lnkpoi,2);               /* Layer 2  ->  Layer 7           */
  851.   }
  852.  
  853.  
  854.  
  855.  
  856.  
  857. /**************************************************************************\
  858. *                                                                          *
  859. * "uppercase"                                                              *
  860. *                                                                          *
  861. * Zeichen c in Grossbuchstabe umwandeln, wenn Kleinbuchstabe, und          *
  862. * zurueckgeben.                                                            *
  863. *                                                                          *
  864. \**************************************************************************/
  865.  
  866. upcase(c)
  867.  
  868. char c;
  869.  
  870.   {
  871.     return ( ('a' > c || 'z' < c) ? c : c - ('a' - 'A') );
  872.   }
  873.  
  874.  
  875.  
  876. /* Ende von L2C.C */
  877.