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

📄 ppp.c

📁 PPPoE协议在Psos中的实现源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************/
/*                                                                      */
/*   MODULE:  ppp.c                                                     */
/*   PRODUCT: pNA+,  OpEN TCP/IP PPP driver                             */
/*   PURPOSE: PPP module                                                */
/*   DATE:    28 February, 1996                                         */
/*                                                                      */
/*----------------------------------------------------------------------*/
/*                                                                      */
/*              Copyright 1996, Integrated Systems, Inc.                */
/*                      ALL RIGHTS RESERVED                             */
/*                                                                      */
/*   Permission is hereby granted to licensees of Integrated Systems,   */
/*   Inc. products to use or abstract this computer program for the     */
/*   sole purpose of implementing a product based on Integrated         */
/*   Systems, Inc. products.   No other rights to reproduce, use,       */
/*   or disseminate this computer program, whether in part or in        */
/*   whole, are granted.                                                */
/*                                                                      */
/*   Integrated Systems, Inc. makes no representation or warranties     */
/*   with respect to the performance of this computer program, and      */
/*   specifically disclaims any responsibility for any damages,         */
/*   special or consequential, connected with the use of this program.  */
/*                                                                      */
/************************************************************************/

#include <string.h>

#include "bsp.h"
#include "pna.h"
#include "configs.h"
#include "ppp.h"
#include "fsm.h"
#include "lcp.h"
#include "ipcp.h"
#include "upap.h"
#include "chap.h"
#include "syslog.h"
#include "ni_ppp.h"
#include "magic.h"
#include "pppmisc.h"
#include "pppoe.h"

#define ioctl ioctlsocket /*for TM port of pNA. JRC*/
#define close closesocket

struct protent prottbl[] = {
    { PPP_LCP, lcp_init, lcp_input, lcp_protrej,
    lcp_printpkt, (void (*)())NULL, "LCP" },
    { PPP_IPCP, ipcp_init, ipcp_input, ipcp_protrej,
    ipcp_printpkt, NULL, "IPCP" },
#if UPAPNEEDED
    { PPP_PAP, upap_init, upap_input, upap_protrej,
    upap_printpkt, NULL, "PAP" },
#endif
#if CHAPNEEDED
    { PPP_CHAP, ChapInit, ChapInput, ChapProtocolReject,
    ChapPrintPkt, NULL, "CHAP" },
#endif
};

#define N_PROTO     (sizeof(prottbl) / sizeof(prottbl[0]))

#if OPENTCPIP
#define socket s_socket
#define close s_close
#define ioctl s_ioctl
#endif

extern PCI pcis[NUM_PPP];                 /*  */
extern struct ppp_pccb PPPpccb[NUM_PPP]; /* Per channel control blocks */
extern unsigned long psos_up_flag; /* Flag to show if pSOS is up     */
extern void AsyncInput(u_long, mblk_t *);

extern NODE_CT NodeCfg;
#define SEC2TICKS(sec) (NodeCfg.psosct->kc_ticks2sec * sec)

/*======================================================================*/
/* Globals used by the driver                                           */
/*======================================================================*/
int debug;
int pppunit;        /* ppp unit identifier */
int pppsocket;          /* socket descriptor for ioctl() */
unsigned long Tid;              /* of the calling task */
unsigned long Qid;              /* PPPQ */
PAI pais[NUM_PPP];                  /* async control structures */
mblk_t *PPPoEHdPool;
Lid lowerid[NPPP];
IFcfg ifcfg[NPPP];
int peer_mru[NPPP];
unsigned long msgbuf[4];
int lcp_echo_fails = 0;
int lcp_echo_interval = 0;  /* Interval between LCP echo-requests */
unsigned long default_baud; /* default baud rate passed by psos */
struct callout *CalloutPool;
mblk_t  PPPoEHdMblks[NPPPHEADERS];
struct callout Callouts[NCALLOUTS]; /* Callout entries */
u_char outpacket_buf[1502]; /* PPP_MRU+PPP_HDRLEN  buffer for outgoing packet */
PPPoEHeader PPPoEHeaders[NPPPHEADERS];


int start_ppp(void); /*OPENTCPIP*/
void ppp_timer(void);
void ppp_chinit(int);
static void pppoed_task(void);      /* pppd task entry */
void AsyncDataInd(Uid uid, mblk_t *mp, unsigned long flags);
void PPPcallback(Uid uid,  unsigned long command, void *arg);


int pppoe_init()
{
    int i;
    unsigned long rc, tid;
         
    /*
     * check whether PPPD is created. If it is created then the task 
     * is already initialized                                        
     */

    rc = t_ident(PPPOED_NAME, 0, &tid);  /*0 on success ,error code on failure*/

    if (rc == ERR_OBJNF)        /* named task(PPPD_NAME) was not found */
    {
        debug = DEBUG;         /* turn on debugging */
        TimeoutList.next= TimeoutList.prev = &TimeoutList;       /* no timers */
        TimeoutList.wait = 0;
        CalloutPool = 0;

                       
        pppunit = 0;    /* start from unit 0 */
        /*------------------------------------------------------------*/
        /* init the statistics at run time                            */
        /*------------------------------------------------------------*/
        bzero((char *)pcis, sizeof(pcis));
        bzero((char *)pais, sizeof(pais));
        psos_up_flag = 0;

        /*
         * Initialize the channel specific data structure table
         */
        for (i = 0; i < NPPP; i++)
        {
            bzero((char *)&PPPpccb[i], sizeof(struct ppp_pccb));
        }

        /*------------------------------------------------------------*/
        /* Create the list of free PPP header buffers                 */
        /*------------------------------------------------------------*/
        for (i = 0;  i < NPPPHEADERS; i++)
        {
            PPPoEHdMblks[i].b_rptr = (unsigned char *)&PPPoEHeaders[i];
            PPPoEHdMblks[i].b_wptr = (unsigned char *)&PPPoEHeaders[i];
            ENQUE(&PPPoEHdPool, &PPPoEHdMblks[i]);
        }

        /*-------------------------------------------------------------*/
        /* Create a list of free callouts.                             */
        /*-------------------------------------------------------------*/
        for (i = 0;  i < NCALLOUTS; i++)
        {
            ENQUE(&CalloutPool, &Callouts[i]);
        }

        /*--------------------------------------------------------------*/
        /* create 'PPPD' to handle the PPP negotiation                  */
        /*--------------------------------------------------------------*/
        if (t_create(PPPOED_NAME, PPPD_PRIO, 
            PPPD_SYSSTACK, PPPD_USRSTACK, PPPD_FLAGS, &Tid) != 0)
        {
            syslog(LOG_ERR, "Task creation error");
            return -1;
        }

#if (!OPENTCPIP)
        if (t_start(Tid, PPPD_INITMODE, pppoed_task, 0) != 0)
        {
            syslog(LOG_ERR, "Task start error");
            return -1;
        }
#endif

        /*-------------------------------------------------------------*/
        /* Create a message queue for ISR to communicate with us.      */
        /*-------------------------------------------------------------*/
        if (rc = q_create("PPPQ", 0, Q_LOCAL|Q_FIFO|Q_NOLIMIT|Q_SYSBUF, &Qid))
        {
            syslog(LOG_EMERG, "q_create() returns %x", rc);
            return(-1);
        }
        return(0);
    }
    else if (rc != 0)
       return(-1);
}

#if OPENTCPIP
int start_ppp()
{
    if (t_start(Tid, PPPD_INITMODE, pppoed_task, 0) != 0)
    {
        syslog(LOG_ERR, "Task start error");
        return -1;
    }

    /* send initialize event to the pppd task */
    if (ev_send(Tid, PEV_QEVENT))
        return(-1);

    return 0;
}
#endif

/************************************************************************/
/* pppoed_task: task entry for 'PPPOED'                                 */
/*  INPUTS:                                                             */
/* RETURNS:                                                             */
/* OUTPUTS:                                                             */
/* NOTE(S):                                                             */
/************************************************************************/
static void pppoed_task(void)
{
    unsigned long rc;
    int i;
    unsigned long events;
    unsigned long tmid;

    /*-----------------------------------------------------------------*/
    /* Create a pSOS timer to wake the PPPD task every 1 sec           */
    /* #define PEV_TIMER   0x00000002           Time event             */
    /*-----------------------------------------------------------------*/
    if (rc = tm_evevery(SEC2TICKS(1), PEV_TIMER, &tmid))
    {
        syslog(LOG_EMERG, "tm_evevery() returns %x", rc);
        goto error;
    }
    /*------------------------------------------------------------------*/
    /* Create a socket for ioctl() use.                                 */
    /*------------------------------------------------------------------*/
    if ((pppsocket = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        syslog(LOG_EMERG, "Ni_init(): socket() error");
error:
        q_delete(Qid);
        close(0);
        if (t_delete(0))
            t_suspend(0);
        return;
    }

    /*
     * Wait on PPP events . The daemon task waits forever processing various
     * events. It handles the channel initialization, Input on channel and
     * timer functions
     */

    while (1)           /* Process forever */ 
    {
    /*
     * Receive events - Timer, Input, Init
     * Process the received events by calling respective event 
     * handler
     */
        if (ev_receive(PEV_QEVENT|PEV_TIMER, EV_ANY, 0, &events))
            k_fatal(0x10000, 0); /* Need to change this XXXXX */

        if (events & PEV_TIMER) /* Timer event */
            ppp_timer();

        if (events & PEV_QEVENT) {
            while (1) {
                if (rc = q_receive(Qid, Q_NOWAIT, 0, msgbuf)) { /* Ni init */
                    if (rc == ERR_NOMSG)    /* no more messages */
                        break;
                    k_fatal(0x10000, 0); /* Need to change this XXXXX */
                }

                switch (msgbuf[0]) {
                case MSG_INIT:    /* Channel init message */
                    ppp_chinit((int)msgbuf[1]);
                    break;
                case MSG_INPUT:   /* Input from serial port */
                    AsyncInput(msgbuf[1], (mblk_t *)msgbuf[2]);
                    break;
                case MSG_FREE:
                    pfree((char *)msgbuf[1]);
                    break;
                case MSG_OUTPUT:  /* Output to serial port */
                    ppp_queue_output((int)msgbuf[1], (mblk_t *)msgbuf[2]);
                    break;
                case MSG_LINKUP:
                   /*{if(Connection.discoveryState == STATE_SESSION) {
                       lcp_lowerup((int)msgbuf[1]);
                       lcp_open((int)msgbuf[1]);
                    }else {*/
                    sendPADI(&Connection);
                    /*lcp_lowerup((int)msgbuf[1]);
                    lcp_open((int)msgbuf[1]);*/
                    
                    break;
                  
                case MSG_LINKCLOSE:
                    CloseLink((int)msgbuf[1]);
                    break;
                case MSG_LINKDOWN:
                    if (PPPpccb[(int)msgbuf[1]].pppstatus == PSUP)
                    {
                        lcp_lowerdown((int)msgbuf[1]);
                    }
                    (*pppcfgtab[(int)msgbuf[1]].ifinfo->genifclose)(lowerid[(int)msgbuf[1]]);
                    lowerid[(int)msgbuf[1]] = 0;
                    break;
                default:
                    break;

                }
            }
        }
    }
}

/*
 * ppp_chinit: Initializes th channel for PPP communication and initiates
 *             PPP communication 
 */

void
ppp_chinit(int unit)
{
    PCI *pc;
    unsigned long event = 0;
    struct ifreq ifr;
    struct ppp_cfg *ccp;
    struct ppp_pccb *ccb;
    int i;

    ccb = &PPPpccb[unit];
    ccp = &pppcfgtab[unit];
    pc = &pcis[unit];

    /*----------------------------------------------------------------------*/
    /* obtain user-configured MTU                                           */
    /*----------------------------------------------------------------------*/
    ifr.ifr_ifno = ccb->ifno;
    if (ioctl(pppsocket, SIOCGIFMTU, (char *) &ifr) < 0)
    {
        syslog(LOG_EMERG, "ioctl(SIOCGIFMTU): %x", errno);
        return;
    }
    ccb->usrmtu = ifr.ifr_mtu;
    ccb->mibstat.mtu = ifr.ifr_mtu;

    ccb->mibstat.ifDescr = "ISI PPP Network Interface";
    ccb->mibstat.ifadminstatus = 1;    /* up */
    ccb->mibstat.ifoperstatus = 2;     /* down */
    ccb->mibstat.speed = default_baud;

    ccb->pppstatus = PSNEGOTIATING;
    ccb->linkstatus = PDS_SETUP;

    interfaceinit(unit);
    /*if (interfaceinit(unit) == -1){
        syslog(LOG_ERR, "Interface init error");
        return;
    }*/
            
    /*----------------------------------------------------------------------*/
    /* Init the PCI structure.                                              */
    /*----------------------------------------------------------------------*/
    pc->pci_flags &= ~PCI_FLAGS_COMPPROT;   /* default no compprot */
    pc->pci_flags &= ~PCI_FLAGS_COMPAC;     /* default no compac */

    sl_compress_init(&pc->pci_comp);        /* VJCOMP */

    /*----------------------------------------------------------------------*/
    /* Init the magic number that's needed in LCP negotiation.              */
    /*----------------------------------------------------------------------*/
    magic_init();

    /*----------------------------------------------------------------------*/
    /* Initialize each protocol.                                            */
    /*----------------------------------------------------------------------*/
    for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
        (*prottbl[i].init)(unit);

    /* setup the link and noitify the upper layer */
    SetupLink(unit);

    return;
}


/*
 * demuxprotrej - Demultiplex a Protocol-Reject.
 */
void demuxprotrej(int unit, u_short protocol)
{
    int i;

    /*
     * Upcall the proper Protocol-Reject routine.
     */
    for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
        if (prottbl[i].protocol == protocol) {
            (*prottbl[i].protrej)(unit);
            return;
        }
    syslog(LOG_WARNING, "demuxprotrej: Unrecognized Protocol-Reject for protocol %d!", protocol);
}


int pindex(u_short protocol)
{
    int i;

    for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
        if (prottbl[i].protocol == protocol) return i;
}

/************************************************************************/
/* ppp_exit: quit ppp driver, turn off interrupts                       */
/*  INPUTS:                                                             */
/* RETURNS:                                                             */
/* OUTPUTS:                                                             */
/* NOTE(S):                                                             */
/************************************************************************/
void ppp_exit(int unit)

⌨️ 快捷键说明

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