Initial version of PPP for NO_SYS==1, some TODOs are remaining, but it works...

This commit is contained in:
goldsimon 2009-12-31 17:56:51 +00:00
parent 9c51487d1a
commit 3269da52cc
3 changed files with 250 additions and 251 deletions

View File

@ -114,9 +114,6 @@
#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
#endif
#if (PPP_SUPPORT && (NO_SYS==1))
// #error "If you want to use PPP, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if (LWIP_NETIF_API && (NO_SYS==1))
#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
#endif

View File

@ -113,6 +113,21 @@
/*** LOCAL DEFINITIONS ***/
/*************************/
/** PPP_INPROC_MULTITHREADED==1 call pppInput using tcpip_callback().
* Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1.
* Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded).
*/
#ifndef PPP_INPROC_MULTITHREADED
#define PPP_INPROC_MULTITHREADED (NO_SYS==0)
#endif
/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session.
* Default is 0: call pppos_input() for received raw characters, charcater
* reception is up to the port */
#ifndef PPP_INPROC_OWNTHREAD
#define PPP_INPROC_OWNTHREAD 0
#endif
/*
* The basic PPP frame.
*/
@ -137,10 +152,47 @@ typedef enum {
/************************/
/*** LOCAL DATA TYPES ***/
/************************/
/** RX buffer size: this may be configured smaller! */
#ifndef PPPOS_RX_BUFSIZE
#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN)
#endif
typedef struct PPPControlRx_s {
/** unit number / ppp descriptor */
int pd;
/** the rx file descriptor */
sio_fd_t fd;
/** receive buffer - encoded data is stored here */
u_char rxbuf[PPPOS_RX_BUFSIZE];
/** number of bytes currently in receive buffer */
u16_t rxbuf_fill_level;
/** when using an rx-thread: tells the thread when to stop */
volatile int run;
/** when using an rx-thread: tell the main application when the thread is stopped */
volatile int running;
/** Set this to 1 if NO_SYS==0 and pppInProc() is called from a different
thread than tcpip_thread */
int multithreaded;
/* The input packet. */
struct pbuf *inHead, *inTail;
#if PPPOS_SUPPORT
u16_t inProtocol; /* The input protocol code. */
u16_t inFCS; /* Input Frame Check Sequence value. */
#endif /* PPPOS_SUPPORT */
PPPDevStates inState; /* The input process state. */
char inEscaped; /* Escape next character. */
ext_accm inACCM; /* Async-Ctl-Char-Map for input. */
} PPPControlRx;
/*
* PPP interface control block.
*/
typedef struct PPPControl_s {
PPPControlRx rx;
char openFlag; /* True when in use. */
#if PPPOE_SUPPORT
struct netif *ethif;
@ -150,19 +202,11 @@ typedef struct PPPControl_s {
int errCode; /* Code indicating why interface is down. */
#if PPPOS_SUPPORT
sio_fd_t fd; /* File device ID of port. */
int kill_link; /* Shut the link down. */
int sig_hup; /* Carrier lost. */
struct pbuf *inHead, *inTail; /* The input packet. */
PPPDevStates inState; /* The input process state. */
char inEscaped; /* Escape next character. */
u16_t inProtocol; /* The input protocol code. */
u16_t inFCS; /* Input Frame Check Sequence value. */
#endif /* PPPOS_SUPPORT */
int mtu; /* Peer's mru */
int pcomp; /* Does peer accept protocol compression? */
int accomp; /* Does peer accept addr/ctl compression? */
u_long lastXMit; /* Time of last transmission. */
ext_accm inACCM; /* Async-Ctl-Char-Map for input. */
ext_accm outACCM; /* Async-Ctl-Char-Map for output. */
#if PPPOS_SUPPORT && VJ_SUPPORT
int vjEnabled; /* Flag indicating VJ compression enabled. */
@ -194,9 +238,9 @@ struct npioctl {
/*** LOCAL FUNCTION DECLARATIONS ***/
/***********************************/
#if PPPOS_SUPPORT
static void pppMain(void *pd);
static void pppDrop(PPPControl *pc);
static void pppInProc(int pd, u_char *s, int l);
static void pppInputThread(PPPControlRx *pcrx);
static void pppDrop(PPPControlRx *pcrx);
static void pppInProc(PPPControlRx *pc, u_char *s, int l);
#endif /* PPPOS_SUPPORT */
@ -245,6 +289,7 @@ u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];
#if PPPOS_SUPPORT
/*
* FCS lookup table as calculated by genfcstab.
* @todo: smaller, slower implementation for lower memory footprint?
*/
static const u_short fcstab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
@ -294,11 +339,11 @@ static u_char pppACCMMask[] = {
0x80
};
/** Wake up the task blocked in reading from serial line (if any) */
void
pppMainWakeup(int pd)
pppRecvWakeup(int pd)
{
PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d\n", pd));
PPPDEBUG((LOG_DEBUG, "pppRecvWakeup: unit %d\n", pd));
sio_read_abort(pppControl[pd].fd);
}
#endif /* PPPOS_SUPPORT */
@ -309,13 +354,24 @@ pppLinkTerminated(int pd)
PPPDEBUG((LOG_DEBUG, "pppLinkTerminated: unit %d\n", pd));
#if PPPOE_SUPPORT
if(pppControl[pd].ethif) {
if (pppControl[pd].ethif) {
pppoe_disconnect(pppControl[pd].pppoe_sc);
} else
#endif /* PPPOE_SUPPORT */
{
#if PPPOS_SUPPORT
pppMainWakeup(pd);
PPPControl* pc;
pppRecvWakeup(pd);
/* @todo: move code from pppInputThread here:*/
pc = &pppControl[pd];
pppDrop(&pc->rx); /* bug fix #17726 */
PPPDEBUG((LOG_DEBUG, "pppInputThread: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
if(pc->linkStatusCB) {
pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
}
pc->openFlag = 0;/**/
#endif /* PPPOS_SUPPORT */
}
}
@ -326,13 +382,13 @@ pppLinkDown(int pd)
PPPDEBUG((LOG_DEBUG, "pppLinkDown: unit %d\n", pd));
#if PPPOE_SUPPORT
if(pppControl[pd].ethif) {
if (pppControl[pd].ethif) {
pppoe_disconnect(pppControl[pd].pppoe_sc);
} else
#endif /* PPPOE_SUPPORT */
{
#if PPPOS_SUPPORT
pppMainWakeup(pd);
pppRecvWakeup(pd);
#endif /* PPPOS_SUPPORT */
}
}
@ -344,29 +400,23 @@ pppLinkDown(int pd)
*/
static void
pppStartCB(void *arg)
pppStart(int pd)
{
int pd = (int)arg;
PPPDEBUG((LOG_DEBUG, "pppStartCB: unit %d\n", pd));
lcp_lowerup(pd);
lcp_open(pd); /* Start protocol */
}
static void
pppStopCB(void *arg)
pppStop(int pd)
{
int pd = (int)arg;
PPPDEBUG((LOG_DEBUG, "pppStopCB: unit %d\n", pd));
lcp_close(pd, "User request");
}
static void
pppHupCB(void *arg)
pppHup(int pd)
{
int pd = (int)arg;
PPPDEBUG((LOG_DEBUG, "pppHupCB: unit %d\n", pd));
lcp_lowerdown(pd);
link_terminated(pd);
@ -394,11 +444,7 @@ pppInit(void)
subnetMask = htonl(0xffffff00);
for (i = 0; i < NUM_PPP; i++) {
pppControl[i].openFlag = 0;
/*
* Initialize to the standard option set.
*/
/* Initialize to the standard option set. */
for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) {
(*protp->init)(i);
}
@ -481,44 +527,36 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
* connects to a modem, the modem connection must be
* established before calling this.
* Return a new PPP connection descriptor on success or
* an error code (negative) on failure. */
* an error code (negative) on failure.
*/
int
pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx)
{
PPPControl *pc;
int pd;
/* Find a free PPP session descriptor. Critical region? */
if (linkStatusCB == NULL) {
/* PPP is single-threaded: without a callback,
* there is no way to know when the link is up. */
return PPPERR_PARAM;
}
/* Find a free PPP session descriptor. */
for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
if (pd >= NUM_PPP) {
pd = PPPERR_OPEN;
} else {
pppControl[pd].openFlag = !0;
}
/* Launch a deamon thread. */
if (pd >= 0) {
pppControl[pd].openFlag = 1;
lcp_init(pd);
pc = &pppControl[pd];
/* @todo: is this correct or do I overwrite something? */
memset(pc, 0, sizeof(PPPControl));
pc->rx.pd = pd;
pc->rx.fd = fd;
pc->openFlag = 1;
pc->fd = fd;
#if PPPOE_SUPPORT
pc->ethif= NULL;
#endif /* PPPOE_SUPPORT */
pc->kill_link = 0;
pc->sig_hup = 0;
pc->if_up = 0;
pc->errCode = 0;
pc->inState = PDIDLE;
pc->inHead = NULL;
pc->inTail = NULL;
pc->inEscaped = 0;
pc->lastXMit = 0;
#if VJ_SUPPORT
pc->vjEnabled = 0;
vj_compress_init(&pc->vjComp);
#endif /* VJ_SUPPORT */
@ -526,28 +564,20 @@ pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void
* Default the in and out accm so that escape and flag characters
* are always escaped.
*/
memset(pc->inACCM, 0, sizeof(ext_accm));
pc->inACCM[15] = 0x60;
memset(pc->outACCM, 0, sizeof(ext_accm));
pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */
pc->outACCM[15] = 0x60;
pc->linkStatusCB = linkStatusCB;
pc->linkStatusCtx = linkStatusCtx;
sys_thread_new(PPP_THREAD_NAME, pppMain, (void*)pd, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO);
if(!linkStatusCB) {
while(pd >= 0 && !pc->if_up) {
sys_msleep(500);
if (lcp_phase[pd] == PHASE_DEAD) {
pppClose(pd);
if (pc->errCode) {
pd = pc->errCode;
} else {
pd = PPPERR_CONNECT;
}
}
}
}
/*
* Start the connection and handle incoming events (packet or timeout).
*/
PPPDEBUG((LOG_INFO, "pppInputThread: unit %d: Connecting\n", pd));
pppStart(pd);
#if PPP_INPROC_OWNTHREAD
sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)pd, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO);
#endif
}
return pd;
@ -576,20 +606,24 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha
LWIP_UNUSED_ARG(service_name);
LWIP_UNUSED_ARG(concentrator_name);
if (linkStatusCB == NULL) {
/* PPP is single-threaded: without a callback,
* there is no way to know when the link is up. */
return PPPERR_PARAM;
}
/* Find a free PPP session descriptor. Critical region? */
for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++);
if (pd >= NUM_PPP) {
pd = PPPERR_OPEN;
} else {
pppControl[pd].openFlag = !0;
}
pc = &pppControl[pd];
memset(pc, 0, sizeof(PPPControl));
pc->openFlag = 1;
pc->ethif = ethif;
/* PPP session descriptor found, start PPPoE */
if (pd >= 0) {
pppControl[pd].openFlag = 1;
lcp_init(pd);
pc->linkStatusCB = linkStatusCB;
pc->linkStatusCtx = linkStatusCtx;
lcp_wantoptions[pd].mru = PPPOE_MAXMTU;
lcp_wantoptions[pd].neg_asyncmap = 0;
@ -601,49 +635,12 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha
lcp_allowoptions[pd].neg_pcompression = 0;
lcp_allowoptions[pd].neg_accompression = 0;
pc = &pppControl[pd];
pc->if_up = 0;
pc->errCode = 0;
pc->lastXMit = 0;
#if PPPOS_SUPPORT
pc->kill_link = 0;
pc->sig_hup = 0;
pc->inState = PDIDLE;
pc->inHead = NULL;
pc->inTail = NULL;
pc->inEscaped = 0;
#if VJ_SUPPORT
pc->vjEnabled = 0;
#endif /* VJ_SUPPORT */
#endif /* PPPOS_SUPPORT */
pc->ethif= ethif;
memset(pc->inACCM, 0, sizeof(ext_accm));
memset(pc->outACCM, 0, sizeof(ext_accm));
pc->linkStatusCB = linkStatusCB;
pc->linkStatusCtx = linkStatusCtx;
if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) {
pc->openFlag = 0;
return PPPERR_OPEN;
}
pppoe_connect(pc->pppoe_sc);
if(!linkStatusCB) {
while(pd >= 0 && !pc->if_up) {
sys_msleep(500);
if (lcp_phase[pd] == PHASE_DEAD) {
pppClose(pd);
if (pc->errCode) {
pd = pc->errCode;
} else {
pd = PPPERR_CONNECT;
}
}
}
}
}
return pd;
@ -666,22 +663,25 @@ pppClose(int pd)
PPPDEBUG((LOG_DEBUG, "pppClose: unit %d kill_link -> pppStopCB\n", pd));
pc->errCode = PPPERR_USER;
/* This will leave us at PHASE_DEAD. */
tcpip_callback(pppStopCB, (void*)pd);
pppStop(pd);
} else
#endif /* PPPOE_SUPPORT */
{
#if PPPOS_SUPPORT
pc->kill_link = !0;
pppMainWakeup(pd);
PPPDEBUG((LOG_DEBUG, "pppClose: unit %d kill_link -> pppStopCB\n", pd));
pc->errCode = PPPERR_USER;
/* This will leave us at PHASE_DEAD. */
pppStop(pd);
pppRecvWakeup(pd);
#endif /* PPPOS_SUPPORT */
}
if(!pc->linkStatusCB) {
/*if(!pc->linkStatusCB) {
while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) {
sys_msleep(500);
break;
}
}
}*/
return st;
}
@ -690,18 +690,18 @@ pppClose(int pd)
void
pppSigHUP(int pd)
{
PPPControl *pc = &pppControl[pd];
#if PPPOE_SUPPORT
PPPControl *pc = &pppControl[pd];
if(pc->ethif) {
PPPDEBUG((LOG_DEBUG, "pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));
tcpip_callback(pppHupCB, (void*)pd);
pppHup(pd);
} else
#endif /* PPPOE_SUPPORT */
{
#if PPPOS_SUPPORT
pc->sig_hup = 1;
pppMainWakeup(pd);
PPPDEBUG((LOG_DEBUG, "pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));
pppHup(pd);
pppRecvWakeup(pd);
#endif /* PPPOS_SUPPORT */
}
}
@ -1177,18 +1177,22 @@ ppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp)
{
PPPControl *pc = &pppControl[unit];
int i;
SYS_ARCH_DECL_PROTECT(lev);
LWIP_UNUSED_ARG(accomp);
LWIP_UNUSED_ARG(pcomp);
LWIP_UNUSED_ARG(mru);
/* Load the ACCM bits for the 32 control codes. */
SYS_ARCH_PROTECT(lev);
for (i = 0; i < 32 / 8; i++) {
pc->inACCM[i] = (u_char)(asyncmap >> (i * 8));
/* @todo: does this work? ext_accm has been modified from pppd! */
pc->rx.inACCM[i] = (u_char)(asyncmap >> (i * 8));
}
SYS_ARCH_UNPROTECT(lev);
PPPDEBUG((LOG_INFO, "ppp_recv_config[%d]: inACCM=%X %X %X %X\n",
unit,
pc->inACCM[0], pc->inACCM[1], pc->inACCM[2], pc->inACCM[3]));
pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3]));
}
#if 0
@ -1490,72 +1494,42 @@ cifdefaultroute(int pd, u32_t l, u32_t g)
/* The main PPP process function. This implements the state machine according
* to section 4 of RFC 1661: The Point-To-Point Protocol. */
static void
pppMain(void *arg)
pppInputThread(PPPControlRx *pcrx)
{
int pd = (int)arg;
struct pbuf *p;
PPPControl* pc;
int c;
int count;
pc = &pppControl[pd];
p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM);
if (!p) {
LWIP_ASSERT("p != NULL", p);
pc->errCode = PPPERR_ALLOC;
goto out;
}
/*
* Start the connection and handle incoming events (packet or timeout).
*/
PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));
tcpip_callback(pppStartCB, arg);
while (lcp_phase[pd] != PHASE_DEAD) {
if (pc->kill_link) {
PPPDEBUG((LOG_DEBUG, "pppMain: unit %d kill_link -> pppStopCB\n", pd));
pc->errCode = PPPERR_USER;
/* This will leave us at PHASE_DEAD. */
tcpip_callback(pppStopCB, arg);
pc->kill_link = 0;
} else if (pc->sig_hup) {
PPPDEBUG((LOG_DEBUG, "pppMain: unit %d sig_hup -> pppHupCB\n", pd));
pc->sig_hup = 0;
tcpip_callback(pppHupCB, arg);
while (pcrx->run) {//lcp_phase[pcrx->pd] != PHASE_DEAD) {
count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE);
if(count > 0) {
pppInProc(pcrx, pcrx->rxbuf, count);
} else {
c = sio_read(pc->fd, p->payload, p->len);
if(c > 0) {
pppInProc(pd, p->payload, c);
} else {
/* nothing received, give other tasks a chance to run */
sys_msleep(1);
}
/* nothing received, give other tasks a chance to run */
sys_msleep(1);
}
}
PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_DEAD\n", pd));
pppDrop(pc); /* bug fix #17726 */
pbuf_free(p);
//PPPDEBUG((LOG_INFO, "pppInputThread: unit %d: PHASE_DEAD\n", pd));
//pppDrop(pc); /* bug fix #17726 */
/* @todo: where do we move the final call to linkStatusCB?
out:
PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
PPPDEBUG((LOG_DEBUG, "pppInputThread: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
if(pc->linkStatusCB) {
pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL);
}
pc->openFlag = 0;
pc->openFlag = 0;*/
}
#endif /* PPPOS_SUPPORT */
#if PPPOE_SUPPORT
void
pppOverEthernetInitFailed(void* arg)
pppOverEthernetInitFailed(int pd)
{
PPPControl* pc;
int pd = (int)arg;
pppHupCB(arg);
pppStopCB(arg);
pppHup(pd);
pppStop(pd);
pc = &pppControl[pd];
pppoe_destroy(&pc->netif);
@ -1570,12 +1544,10 @@ static void
pppOverEthernetLinkStatusCB(int pd, int up)
{
if(up) {
PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd));
tcpip_callback(pppStartCB, (void*)pd);
PPPDEBUG((LOG_INFO, "pppInputThread: unit %d: Connecting\n", pd));
pppStart(pd);
} else {
PPPControl* pc;
pc = &pppControl[pd];
tcpip_callback(pppOverEthernetInitFailed, (void*)pd);
pppOverEthernetInitFailed(pd);
}
}
#endif /* PPPOE_SUPPORT */
@ -1739,7 +1711,7 @@ out:
* Drop the input packet.
*/
static void
pppDrop(PPPControl *pc)
pppDrop(PPPControlRx *pc)
{
if (pc->inHead != NULL) {
#if 0
@ -1760,22 +1732,38 @@ pppDrop(PPPControl *pc)
LINK_STATS_INC(link.drop);
}
/** Pass received raw characters to PPPoS to be decoded. This function is
* thread-safe and can be called from a dedicated RX-thread or from a main-loop.
*
* @param pd PPP descriptor index, returned by pppOpen()
* @param data received data
* @param len length of received data
*/
void pppos_input(int pd, u_char* data, int len)
{
pppInProc(&pppControl[pd].rx, data, len);
}
/**
* Process a received octet string.
*/
static void
pppInProc(int pd, u_char *s, int l)
pppInProc(PPPControlRx *pc, u_char *s, int l)
{
PPPControl *pc = &pppControl[pd];
struct pbuf *nextNBuf;
u_char curChar;
u_char escaped;
SYS_ARCH_DECL_PROTECT(lev);
PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pd, l));
PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pc->pd, l));
while (l-- > 0) {
curChar = *s++;
SYS_ARCH_PROTECT(lev);
escaped = ESCAPE_P(pc->inACCM, curChar);
SYS_ARCH_UNPROTECT(lev);
/* Handle special characters. */
if (ESCAPE_P(pc->inACCM, curChar)) {
if (escaped) {
/* Check for escape sequences. */
/* XXX Note that this does not handle an escaped 0x5d character which
* would appear as an escape character. Since this is an ASCII ']'
@ -1785,61 +1773,65 @@ pppInProc(int pd, u_char *s, int l)
pc->inEscaped = 1;
/* Check for the flag character. */
} else if (curChar == PPP_FLAG) {
/* If this is just an extra flag character, ignore it. */
if (pc->inState <= PDADDRESS) {
/* ignore it */;
/* If we haven't received the packet header, drop what has come in. */
} else if (pc->inState < PDDATA) {
PPPDEBUG((LOG_WARNING,
"pppInProc[%d]: Dropping incomplete packet %d\n",
pd, pc->inState));
LINK_STATS_INC(link.lenerr);
pppDrop(pc);
/* If the fcs is invalid, drop the packet. */
} else if (pc->inFCS != PPP_GOODFCS) {
PPPDEBUG((LOG_INFO,
"pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n",
pd, pc->inFCS, pc->inProtocol));
LINK_STATS_INC(link.chkerr);
pppDrop(pc);
/* Otherwise it's a good packet so pass it on. */
} else {
/* Trim off the checksum. */
if(pc->inTail->len >= 2) {
pc->inTail->len -= 2;
/* If this is just an extra flag character, ignore it. */
if (pc->inState <= PDADDRESS) {
/* ignore it */;
/* If we haven't received the packet header, drop what has come in. */
} else if (pc->inState < PDDATA) {
PPPDEBUG((LOG_WARNING,
"pppInProc[%d]: Dropping incomplete packet %d\n",
pc->pd, pc->inState));
LINK_STATS_INC(link.lenerr);
pppDrop(pc);
/* If the fcs is invalid, drop the packet. */
} else if (pc->inFCS != PPP_GOODFCS) {
PPPDEBUG((LOG_INFO,
"pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n",
pc->pd, pc->inFCS, pc->inProtocol));
LINK_STATS_INC(link.chkerr);
pppDrop(pc);
/* Otherwise it's a good packet so pass it on. */
} else {
/* Trim off the checksum. */
if(pc->inTail->len >= 2) {
pc->inTail->len -= 2;
pc->inTail->tot_len = pc->inTail->len;
if (pc->inTail != pc->inHead) {
pbuf_cat(pc->inHead, pc->inTail);
}
} else {
pc->inTail->tot_len = pc->inTail->len;
if (pc->inTail != pc->inHead) {
pbuf_cat(pc->inHead, pc->inTail);
}
pc->inTail->tot_len = pc->inTail->len;
if (pc->inTail != pc->inHead) {
pbuf_cat(pc->inHead, pc->inTail);
}
} else {
pc->inTail->tot_len = pc->inTail->len;
if (pc->inTail != pc->inHead) {
pbuf_cat(pc->inHead, pc->inTail);
}
pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2);
}
pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2);
}
/* Dispatch the packet thereby consuming it. */
if(tcpip_callback(pppInput, pc->inHead) != ERR_OK) {
PPPDEBUG((LOG_ERR, "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pd));
pbuf_free(pc->inHead);
LINK_STATS_INC(link.drop);
}
pc->inHead = NULL;
pc->inTail = NULL;
}
/* Dispatch the packet thereby consuming it. */
#if PPP_INPROC_MULTITHREADED
if(tcpip_callback_with_block(pppInput, pc->inHead, 0) != ERR_OK) {
PPPDEBUG((LOG_ERR, "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pc->pd));
pbuf_free(pc->inHead);
LINK_STATS_INC(link.drop);
}
#else /* PPP_INPROC_MULTITHREADED */
pppInput(pc->inHead);
#endif /* PPP_INPROC_MULTITHREADED */
pc->inHead = NULL;
pc->inTail = NULL;
}
/* Prepare for a new packet. */
pc->inFCS = PPP_INITFCS;
pc->inState = PDADDRESS;
pc->inEscaped = 0;
/* Prepare for a new packet. */
pc->inFCS = PPP_INITFCS;
pc->inState = PDADDRESS;
pc->inEscaped = 0;
/* Other characters are usually control characters that may have
* been inserted by the physical layer so here we just drop them. */
} else {
PPPDEBUG((LOG_WARNING,
"pppInProc[%d]: Dropping ACCM char <%d>\n", pd, curChar));
"pppInProc[%d]: Dropping ACCM char <%d>\n", pc->pd, curChar));
}
/* Process other characters. */
} else {
@ -1880,7 +1872,7 @@ pppInProc(int pd, u_char *s, int l)
#if 0
else {
PPPDEBUG((LOG_WARNING,
"pppInProc[%d]: Invalid control <%d>\n", pd, curChar));
"pppInProc[%d]: Invalid control <%d>\n", pc->pd, curChar));
pc->inState = PDSTART;
}
#endif
@ -1914,7 +1906,7 @@ pppInProc(int pd, u_char *s, int l)
/* No free buffers. Drop the input packet and let the
* higher layers deal with it. Continue processing
* the received pbuf chain in case a new packet starts. */
PPPDEBUG((LOG_ERR, "pppInProc[%d]: NO FREE MBUFS!\n", pd));
PPPDEBUG((LOG_ERR, "pppInProc[%d]: NO FREE MBUFS!\n", pc->pd));
LINK_STATS_INC(link.memerr);
pppDrop(pc);
pc->inState = PDSTART; /* Wait for flag sequence. */
@ -1923,7 +1915,7 @@ pppInProc(int pd, u_char *s, int l)
if (pc->inHead == NULL) {
struct pppInputHeader *pih = nextNBuf->payload;
pih->unit = pd;
pih->unit = pc->pd;
pih->proto = pc->inProtocol;
nextNBuf->len += sizeof(*pih);
@ -1972,11 +1964,7 @@ pppInProcOverEthernet(int pd, struct pbuf *pb)
pih->proto = inProtocol;
/* Dispatch the packet thereby consuming it. */
if(tcpip_callback(pppInput, pb) != ERR_OK) {
PPPDEBUG((LOG_ERR, "pppInProcOverEthernet[%d]: tcpip_callback() failed, dropping packet\n", pd));
goto drop;
}
pppInput(pb);
return;
drop:

View File

@ -46,6 +46,20 @@
#include "lwip/mem.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/timers.h"
/** Some defines for code we skip compared to the original pppd.
* These are just here to minimise the use of the ugly "#if 0". */
#define PPP_ADDITIONAL_CALLBACKS 0
/** Some error checks to test for unsupported code */
#if CBCP_SUPPORT
#error "CBCP is not supported in lwIP PPP"
#endif
#if CCP_SUPPORT
#error "CCP is not supported in lwIP PPP"
#endif
/*
* pppd.h - PPP daemon global declarations.
@ -93,7 +107,7 @@
* OR MODIFICATIONS.
*/
#define TIMEOUT(f, a, t) sys_untimeout((f), (a)), sys_timeout((t)*1000, (f), (a))
#define TIMEOUT(f, a, t) sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a))
#define UNTIMEOUT(f, a) sys_untimeout((f), (a))
@ -276,24 +290,24 @@ struct protent {
void (*open) (int unit);
/* Close the protocol */
void (*close) (int unit, char *reason);
#if 0
#if PPP_ADDITIONAL_CALLBACKS
/* Print a packet in readable form */
int (*printpkt) (u_char *pkt, int len,
void (*printer) (void *, char *, ...),
void *arg);
/* Process a received data packet */
void (*datainput) (int unit, u_char *pkt, int len);
#endif
int enabled_flag; /* 0 iff protocol is disabled */
#endif /* PPP_ADDITIONAL_CALLBACKS */
int enabled_flag; /* 0 if protocol is disabled */
char *name; /* Text name of protocol */
#if 0
#if PPP_ADDITIONAL_CALLBACKS
/* Check requested options, assign defaults */
void (*check_options) (u_long);
/* Configure interface for demand-dial */
int (*demand_conf) (int unit);
/* Say whether to bring up link for this pkt */
int (*active_pkt) (u_char *pkt, int len);
#endif
#endif /* PPP_ADDITIONAL_CALLBACKS */
};
/*
@ -429,7 +443,7 @@ void pppLinkTerminated(int pd);
void pppLinkDown(int pd);
void pppMainWakeup(int pd);
void pppos_input(int pd, u_char* data, int len);
/* Configure i/f transmit parameters */
void ppp_send_config (int, int, u32_t, int, int);