⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppp.c

📁 PPP协议C语言源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (netp->hw.opt3 == 3) {
            if (netp->hw.locopts & COMPpcmp && cc & 1) {
                PH(netp->bufbas)->MACtype |= 1;
               /* Adjust possible addr/cntl fields */
                *netp->hw.bufin = *(netp->hw.bufin - 1);
                *(netp->hw.bufin - 1) = *(netp->hw.bufin - 2);
                netp->hw.bufin++;
                netp->hw.opt3++;
            }
        }
#endif
    }
#if MP
    if (netp->hw.opt3 == 4) {
        netp->hw.opt3++;
       /*
        ** The Multilink Protocol header requires extra space at the
        ** start of the frame in order to avoid having to move the
        ** whole packet before passing it up to the network layer.
        ** Here we can quickly move three bytes, change a pointer and an
        ** offset instead.
        */
        if (netp->hw.opt5 & MPmrru && cc == PROTmp) {
            char *cp;
            if (netp->hw.opt5 & MPsnhf) {
                PH(netp->bufbas)->poffset -= 4;
                cp = netp->hw.bufin - 4;
            }
            else {
                PH(netp->bufbas)->poffset -= 6;
                cp = netp->hw.bufin - 6;
            }

           /*
            ** If the peer is using protocol compression, we skip the unused
            ** bytes for the network protocol (in the fragment).
            */
            if (PH(netp->bufbas)->MACtype & 1) {
                PH(netp->bufbas)->poffset++;
                cp++;
            }
            *--cp = *--netp->hw.bufin;
            *--cp = *--netp->hw.bufin;
            *--cp = *--netp->hw.bufin;
            netp->hw.bufin = cp + 3;
        }
    }
#endif
    if (netp->hw.bufin == netp->hw.buflim)
        netp->hw.bufin = (char *)netp->bufbas + MESSH_SZ + LHDRSZ;
lab4:
    *netp->hw.bufin++ = cc;
    return;
}


/*
** * * * * * *
** goingc()  Character output interrupt routine
**
** static int goingc(struct NET *netp);
**
** PARAMETERS:
**   (in/out) netp             A pointer to a network structure
**
** RETURNS (not implemented):
**  -1                         Finished or error
**   char                      A character to send
**
** DESCRIPTION:
**   This function determines the next character to send out from
**   the buffer based on HDLC framing.
**
** USAGE COMMENTS:
**   This is only for use with an interrupt set up by the driver.
**
**   Flags (hwflags) tell where in the message we are:
**     0 no message, we start a new one, if none return -1
**     2 CTL_ESC inserted
**     5 end of message
**     8 message in progress
**
** * * * * * *
**
** MODIFICATION HISTORY:
**
**   18-AUG-1999  BSK  Adjust offset for Multilink frame
**   22-OCT-1998  BSK  Created comment
**
** * * * * * *
*/
static int goingc(struct NET *netp)
{
    unsigned char cc;
    MESS *mess;

    if (netp->hwflags & 7) {
        if (netp->hwflags & 2) {
            netp->hwflags -= 2;
            return netp->hw.nxtout;
        }
        if (netp->hwflags & 1) {
            netp->hwflags -= 1;
            return FLAG;
        }
        netp->hwflags = 8;
        mess = netp->bufbaso;
        if (mess->offset == netp->netno) {
            mess->offset = boTXDONE;
            if (mess->id <= bWACK) {
                if (mess->id == bRELEASE) {
                    mess->id = bALLOC;
                    NrelbufIR(mess);
                }
            }
            else
            {
                WAITNOMORE_IR(SIG_WN(netp->netno));
            }
        }
    }
    if (netp->hw.chsout == 0) {
nxt:
        if (QUEUE_EMPTY(netp, depart)) {
            netp->hwflags = 0;
            return -1;
        }
        QUEUE_OUT(netp, depart, mess);
        if (mess->offset != netp->netno)
            goto nxt;
        netp->hwflags = 8;
        netp->bufbaso = mess;
       /* Point to start of PPP frame */
        netp->hw.bufout = (char *)mess + PH(mess)->poffset;
       /* Message length (plus 2 for checksum) */
        netp->hw.chsout = mess->mlen - PH(mess)->poffset + 2;
        return FLAG;
    }
    if (--netp->hw.chsout == 0)
        netp->hwflags = 0xd;
    cc = *netp->hw.bufout++;


   /*
    ** For asynchronous links, ASCII control characters take form
    ** CTL_ESC, cc+0x20 unless the other host has turned this off.
    ** Bit n zero in netp->hw.ul1 means that ASCII value n can be
    ** sent directly.  Direct binary values are only sent when the
    ** link is established.
    */
    if (cc < 0x20)
        if (netp->state != LCPopen || ((netp->hw.ul1 >> cc) & 1))
            goto lab8;
    if (cc == FLAG || cc == CTL_ESC) {
lab8:
        netp->hw.nxtout = cc ^ 0x20;
        netp->hwflags |= 2;
        cc = CTL_ESC;
    }
    return cc;
}


/*
** * * * * * *
** screen()  Screen a message from the network.
**
** static int screen(MESS *mess);
**
** PARAMETERS:
**   (in/out) mess             A pointer to a buffer to screen
**
** RETURNS:
**  -4                         Do not delete buffer
**  -3                         Call write
**  -2                         No further action
**  -1                         Error occured
**   n                         Enter in queue number n
**
** DESCRIPTION:
**   This function takes in a buffer and filters it up the stack if
**   necessary or deals with PPP-oriented frames.
**
** * * * * * *
*/
static int screen(MESS *mess)
{
    int i1, i2, i3, netno, naklen, rejlen;
    unsigned short protocol, us1, us2;
    unsigned char prevstate, *cp, *cp2, *cp3, *cp4;
    unsigned long ul1;
    MESS *mp;
    struct NET *netp;

    netno = mess->netno;    /* Get the net number from message buf */
    netp = &nets[netno];    /* Point to proper network connection */

    mess->netno = netno;
    mess->conno = 0;        /* bcast indicator */

#ifdef MIB2
    netp->ifInOctets += mess->mlen - MESSH_SZ - LHDRSZ;
    netp->ifInUcastPkts++;
#endif

    cp = (unsigned char *)mess + PH(mess)->poffset;

   /*
    ** Check the async framing:
    ** - address and control,
    ** - protocol,
    ** - checksum.
    */
    if (netp->ifType == 23) {
        cp2 = cp;
        i3 = 0;
#if COMPRESSION & 1
        if ((PH(mess)->MACtype & 2) == 0)
#endif
        {
            if (cp2[0] != 0xff || cp2[1] != 0x03)
                i3++;
            cp2 += 2;
        }

#if COMPRESSION & 1
        if (PH(mess)->MACtype & 1) {
            if ((*cp2 & 1) != 1)
                i3++;
#ifdef LITTLE
            protocol = *cp2++ << 8;
#else
            protocol = *cp2++;
#endif
        }
        else
#endif
        {
            if (*cp2 & 1 || (cp2[1] & 1) == 0)
                i3++;
            protocol = *(short *)cp2;
            cp2 += 2;
        }

       /* If we couldn't get the address/control or protocol fields, error */
        if (i3)
            goto rej1;

        us1 = 0xffff;
        i1 = mess->mlen - (cp - (unsigned char *)mess);
        while (i1--)
            us1 = (us1 >> 8) ^ fcstab[(us1 ^ *cp++) & 0xff];
        us1 ^= 0xffff;
        us2 = ((unsigned short)cp[1] << 8) | cp[0];
        if (us1 != us2)
            goto rej1;
    }
    else
        protocol = PH(mess)->protocol;

#ifdef LQRP
    netp->InGoodOctets += mess->mlen - MESSH_SZ - LHDRSZ;
#endif

    prevstate = netp->state;        /* Previous state of PPP */
    if (prevstate == PPPhold) {     /* If holding for user action */
#if NTRACE >= 5
        Nprintf("PPP: State holding, packet ignored\n");
#endif
        return -2;                  /*  do nothing */
    }


#if MP
   /* Get PPP frame out of MP fragment */
    if (protocol == NC2(PROTmp)) {
        if ((prevstate & LCPopen) != LCPopen)
            goto rej1;
       /* Point to data after address/control and protocol */
        mess->offset = cp2 - (unsigned char *)mess;
        protocol = mpScreen(mess);
        if (protocol == (unsigned short)(int)-1)
            goto rej1;
        if (protocol == 0)
            return -2;
    }
#endif


   /* Handle network layer traffic first */
    mess->offset = MESSH_SZ + LHDRSZ;   /* Network data is always here */

    if (prevstate == PPPopen) {
        if (protocol == NC2(PROTip)) {
#if VJ
ipprot:
#endif
#if IDLE_TOUT
            netp->hw.idle_time = TimeMS();  /* Link still active */
#endif
            i1 = ussIPTable.screen(mess);
            if (i1 == -3)
                writE(mess->confix, mess);
            return i1;
        }
#if VJ
        else if (protocol == NC2(PROTcomp) || protocol == NC2(PROTuncomp)) {
            i1 = vjScreen(mess, protocol);
            if (i1 < 0)
                goto rej1;                  /* Reject unhandled message */
            goto ipprot;
        }
#endif
#if defined(LQRP) && QUALITY == PROTlqp
        else if (protocol == NC2(PROTlqp)) {
            i1 = ussLQRPTable.screen(mess);
            if (i1 == -3)
                writE(mess->confix, mess);
            return i1;
        }
#endif
    }

   /* Handle PPP traffic next */

#if NTRACE > 2 && PPP_DEBUG
    pppDebug(1, mess);
#endif

   /* Set up helpful pointers and other values for LCP, Auth and IPCP */

    cp = (unsigned char *)mess + mess->offset;  /* Point to PPP info. */
    us1 = cp[0];                                /* code */
    us2 = cp[1];                                /* identifier */
    i1 = ((int)cp[2] << 8) + cp[3] - 4;         /* length */
    cp2 = cp + 4;                               /* Point to data */
    naklen = rejlen = 0;                        /* No nak/rej yet */

    if (protocol == NC2(PROTlcp)) {
        if (prevstate == PPPclsng && us1 != LCPterm_req && us1 != LCPterm_ack)
            goto rej1;

        switch (us1) {
        case LCPconf_req:
            if ((prevstate & LCPopen) == LCPopen || prevstate == PPPclsd)
                pppStart(netno, 0);         /* tld, restart LCP */
            *cp = LCPconf_ack;              /* set code to ACK (2) */
            i2 = 0;                         /* Check for authentication */
            for (; i1 > 0; cp2 += us2) {    /* Cycle through options */
                us1 = cp2[0];               /* point to option code */
                us2 = cp2[1];               /* length of option request */
                if (us2 < 2)                /* length must be >= 2 */
                    break;
                i1 -= us2;
                switch (us1) {
                case LCPopt_RES0:
                    goto rej3;
                case LCPopt_MRU:
#if MP
                case LCPopt_MRRU:
#endif
                    us1 = ((unsigned short)cp2[2] << 8) + cp2[3];
                    if (us1 <= MAXBUF - MESSH_SZ - LHDRSZ && us1 > 0)
                        netp->maxblo = us1;
                    else {
                        cp2[2] = netp->maxblo >> 8;
                        cp2[3] = netp->maxblo;
nak1:
                        Nmemcpy((char *)mess + 200 + naklen, cp2, us2);
                        naklen += us2;
                    }
                    break;
                case LCPopt_ASYC:
                    netp->hw.ul1 = cp2[2] << 24 +
                                   cp2[3] << 16 +
                                   cp2[4] << 8 +
                                   cp2[5];
                    break;
                case LCPopt_AUTH:
#if AUTHENT & 1
                    if (cp2[2] == 0xc0 && cp2[3] == 0x23)
                        netp->hw.opt4 |= AUTHppap;
#endif
#if AUTHENT & 6
                    if (cp2[2] == 0xc2 && cp2[3] == 0x23) {
#if AUTHENT & 4
                        if (cp2[4] == CHAPalg_MD4)
                            netp->hw.opt4 |= AUTHpmsc;
#endif
#if AUTHENT & 2
                        if (cp2[4] == CHAPalg_MD5)
                            netp->hw.opt4 |= AUTHpchp;
#endif
                    }
#endif
                    if ((netp->hw.opt4 & 7) == 0) {
#if AUTHENT & 1
                       /* If authentication isn't supported, suggest PAP */
                        cp2[1] = 4, cp2[2] = 0xc0, cp2[3] = 0x23;
                        us2 = 4;
                        goto nak1;
#else
                        goto rej3;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -