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

📄 ppp.c

📁 PPP协议C语言源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <string.h>
#include "net.h"
#include "local.h"
#include "support.h"

#ifndef PPP
#error Please do not undefine PPP in local.h
#endif

#include "ppp.h"

#if DIALD
#include "dialapi.h"
#endif

extern struct NET nets[];
extern struct CONNECT connblo[];
extern struct NETCONF netconf[];
extern PTABLE ussIPTable;
extern PTABLE ussTCPTable;
extern PTABLE ussUDPTable;
extern PTABLE ussLQRPTable;

static int ioctl(void *handle, enum ioctlreq request, void *arg, size_t size);

struct Ihdr {                   /* Internet header */
    char message_header[MESSH_SZ];
    char link_header[LHDRSZ];
    unsigned char verlen;     /* header version, length in 32 bit words */
    unsigned char tservice;   /* type of service */
    unsigned short tlen;       /* total packet length including header */
    unsigned short frid;       /* ID for fragmentation */
    unsigned short fragm;      /* fragment flags, offset */
    unsigned char time;       /* time to live (hops) */
    unsigned char prot;       /* protocol */
    unsigned short chksum;     /* header checksum */
    unsigned char from[Iid_SZ];       /* source name */
    unsigned char to[Iid_SZ]; /* destination name */
};
#define IP_H(mb) ((struct Ihdr *)mb)
#define NOMIPHDRSZ 20

struct Thdr {                   /* TCP header */
    char message_header[MESSH_SZ];
    char link_header[LHDRSZ];
    char ip_header[NOMIPHDRSZ];
    unsigned short myport;     /* source port */
    unsigned short herport;    /* dest port */
    unsigned NLONG seqno[4 / sizeof(NLONG)];   /* sequence number */
    unsigned NLONG ackno[4 / sizeof(NLONG)];   /* acknowledgement number */
    unsigned char hdrlen;     /* tcp header length in high 4 bits */
    unsigned char flags;      /* message flags, see below */
    unsigned short window;     /* window */
    unsigned short chksum;     /* checksum */
    unsigned short urgp;       /* urgent pointer */
};
#define TCP_H(mb) ((struct Thdr *)mb)

struct Uhdr {                   /* UDP header */
    char message_header[MESSH_SZ];
    char link_header[LHDRSZ];
    char ip_header[NOMIPHDRSZ];
    unsigned short myport;     /* source port */
    unsigned short herport;    /* dest port */
    unsigned short tlen;
    unsigned short chksum;     /* checksum */
};
#define UDP_H(mb) ((struct Uhdr *)mb)

#define IP_TCP 6
#define IP_UDP 17

/* table for fast checksum sequence calculation */
static const unsigned short fcstab[256] = {
    0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
    0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
    0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
    0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
    0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
    0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
    0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
    0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
    0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
    0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
    0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
    0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
    0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
    0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
    0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
    0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
    0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
    0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
    0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
    0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
    0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
    0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
    0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
    0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
    0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
    0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
    0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
    0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
    0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
    0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
    0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
    0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
};

static const char pppterm[]={5,0,0,10,0,0,0,0,0,0};

unsigned char ppp_hstat[NNETS];


/*
** * * * * * *
** ussGetPasswd()   Get password from user id
**
** char *ussGetPasswd(int n, char ul, char *u);
**
** PARAMETERS:
**   (in) int n                A network interface index
**   (in) char ul              Length of user ID
**   (in) char *u              Pointer to user ID
**
** RETURNS:
**   char *passwd              Success
**   0                         Failure
**
** DESCRIPTION:
**   This function is an internal function for PPP to see if a password
**   exists for a given userid.
**
*/
char *ussGetPasswd(int netno, char ul, char *uid)
{
    char *pw;
    struct NET *netp;

    netp = &nets[netno];
    if (strncmp(uid, netp->hw.userid, ul) == 0)
        pw = netp->hw.passwd;
    else
        pw = 0;

    return pw;
}


/*
** * * * * * *
** pppDQ()   Dequeue any lingering messages in PPP future queue
**
** static void pppDQ(netno)
**
** PARAMETERS:
**   (in) int netno            A network interface index
**
** DESCRIPTION:
**   This function is an internal function for PPP that dequeues any
**   remaining messages in the PPP future queue so that the upper
**   layers may deal with them (as if they were sent but no replies
**   have been received).
**
** * * * * * *
*/
#if DBUFFER
static void pppDQ(int netno)
{
    MESS *mess;
    struct NET *netp;
    int i1, i2;

    netp = &nets[netno];
    i1 = 0;
   /* Empty future queue for future links */
    while (!QUEUE_EMPTY(netp, future)) {
        QUEUE_OUT(netp, future, mess);
        mess->offset = boTXDONE;    /* Message is "sent" */
        if (mess->id <= bWACK) {
            if (mess->id == bRELEASE) {
                mess->id = bALLOC;
                Nrelbuf(mess);
            }
        }
        else {
            WAITNOMORE(SIG_WN(netno));
        }
        i1++;
    }
#if NTRACE >= 5
    if (i1)
        Nprintf("PPP: %d Datagram%c tossed from future queue!\n",
            i1, ((i1 == 1)?'!':'s'));
#endif
    netp->hw.opt8 = 0;
}
#else
#define pppDQ(netno) (nets[netno].hw.opt8 = 0)
#endif


/*
** * * * * * *
** pppWrite()  Internal write for negotiation protocols
**
** static int pppWrite(MESS *mess);
**
** PARAMETERS:
**   (in/out) mess             Pointer to a buffer to write out interface
**
** DESCRIPTION:
**   This function is an internal function for PPP that will create
**   the appropriate framing and write a message out the link.
**
** * * * * * *
*/
static int pppWrite(MESS *mess)
{
    int i1;
    unsigned short us1;
    unsigned char *cp;
    struct NET *netp;

#if NTRACE > 2 && PPP_DEBUG
    pppDebug(0, mess);  /* Print out packet */
#endif

    netp = &nets[mess->netno];

   /* The '- 2' skips the PPP protocol field */
    cp = (unsigned char *)mess + MESSH_SZ + LHDRSZ - 2;

    PH(mess)->MACtype = 0;  /* No compression for WRAP driver */

   /* Make async framing */
    if (netp->ifType == 23) {
       /* Add AHDLC framing */
        *--cp = 0x03;   /* Control */
        *--cp = 0xff;   /* Address */

       /* Set driver offset */
        PH(mess)->poffset = cp - (unsigned char *)mess;
        i1 = mess->mlen - PH(mess)->poffset;

       /* Calculate and append AHDLC checksum */
        us1 = 0xffff;
        while (i1--)
            us1 = (us1 >> 8) ^ fcstab[(us1 ^ *cp++) & 0xff];
        us1 ^= 0xffff;
        cp[1] = us1 >> 8;
        cp[0] = us1;
    }

#ifdef MIB2
    netp->ifOutOctets += mess->mlen - PH(mess)->poffset + 2;
    netp->ifOutUcastPkts++;
#endif


    us1 = mess->id;

   /* Write out the packet by calling the driver */
    i1 = netp->protoc[1]->writE(mess->netno, mess);
    if (i1 != 0 || us1 <= bWACK)
        return i1;
    WAITFOR(mess->offset == boTXDONE, SIG_WN(mess->netno), netp->tout, i1);
    return 1;
}


/*
** * * * * * *
** pppStart()  Internal function to make PPP ready for negotiations
**
** static void pppStart(int netno);
**
** PARAMETERS:
**   (in) netno                A yfnet network number
**   (in) apflag               Active/Passive flag (1/0)
**
** DESCRIPTION:
**   This function will set PPP's data to initial values for negotiations.
**   It neither checks nor changes the state.  The apflag is there because
**   active links usually do not request authentication, but passive ones
**   usually do.
**
** * * * * * *
*/
static void pppStart(int netno, int apflag)
{
    struct NET *netp;

    netp = &nets[netno];
    netp->state = 0;

#if NTRACE >= 3
    Nprintf("PPP: Starting on network %d\n", netno);
#endif

#ifdef LQRP
    memset(netp->lastins, 0, 44); /* OutLQRs, InLQRs, InGoodOctets also */
#endif

   /* Options used in first configure request for LCP */
    netp->hw.locopts = 0
#if PPP_MRU
        + 0x02
#endif
#if ASYNC
        + 0x04
#endif
#if REQAUTH
        + (apflag ? 0 : 0x08)
#endif
#if QUALITY
        + 0x10
#endif
#if MAGICNUM
        + 0x20
#endif
#if COMPRESSION & 1
        + 0x0180
#endif
    ;

    netp->hw.remopts = 0;

#if MP
    mpStart(netno);
#endif

#if VJ
    TXslots[netno] = RXslots[netno] = MAXSLOTS-1;
    TXixcomp[netno] = 1;
#endif

   /* What authentication did host request if passive? */
    if (!apflag) {
#if REQAUTH == PROTpap
        netp->hw.opt4 = AUTHhpap;
#elif REQAUTH == PROTchap && AUTH_ALG == CHAPalg_MD5
        netp->hw.opt4 = AUTHhchp;
#elif REQAUTH == PROTchap && AUTH_ALG == CHAPalg_MD4
        netp->hw.opt4 = AUTHhmsc;
#else
        netp->hw.opt4 = 0;
#endif
    }

#if ASYNC
    netp->hw.ul1 = 0;   /* Escape no characters if possible */
#endif

    netp->hw.opt1 = netp->hw.opt2 =  netp->hw.opt6 = netp->hw.opt8 = 0;
    netp->hw.opt7 = MAXCONF;        /* Initialize restart counter */
    netp->hw.timems = TimeMS();     /* Initialize timer */
    netp->hw.idle_time = netp->hw.echo_time = netp->hw.timems;
}


/*
** * * * * * *
** pppNegotiate()   Internal packet writing function.
**
** static void pppNegotiate(MESS *mess);
**
** PARAMETERS:
**   (in/out) mess              A buffer to write with
**
** DESCRIPTION:
**   This function will check the state and create any necessary
**   packet to negotiate with.
**
** * * * * * *
*/
static void pppNegotiate(MESS *mess)
{
    int i1;
    unsigned char *cp, *cp2;
    struct NET *netp;

    netp = &nets[mess->netno];
    if (netp->state != PPPclsd && netp->state != PPPopen) {
        cp = (unsigned char *)mess + MESSH_SZ + LHDRSZ;
        cp2 = cp + 4;
        if (netp->state == PPPclsng) {
            Nmemcpy((char *)mess+MESSH_SZ+LHDRSZ, pppterm, sizeof(pppterm));
            PH(mess)->protocol = NC2(PROTlcp);
            cp2 = cp + sizeof(pppterm);
            goto write;
        }
        else if ((netp->state & LCPopen) == LCPopen) {

#if AUTHENT & 1
           /* If peer requested PAP, we send Auth-req */
            if (netp->hw.opt4 & AUTHppap) {
                if(netp->hw.opt4 & AUTHpwat)
                    return;
                netp->hw.opt4 |= AUTHpwat;
                PH(mess)->protocol = NC2(PROTpap);
                *cp = PAPauth_req;
                cp[2] = 0;
                *cp2 = (unsigned char)strlen(netp->hw.userid);

⌨️ 快捷键说明

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