📄 ppp.c
字号:
/************************************************************************/
/* */
/* 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 + -