📄 netppp.c
字号:
else {
nGet(pc->fd, &curNBuf, MAXKILLDELAY);
avRandomize();
if (curNBuf != NULL) {
pppInput((int)pd, curNBuf);
/* curNBuf is invalid now so we don't need to free it. */
}
pc->if_up = 1; // for debugging only
}
}
#ifdef OS_DEPENDENT
OSTaskDel(OS_PRIO_SELF);
#endif
}
/*
* Pass the processed input packet to the appropriate handler.
*/
static void pppDispatch(int pd, NBuf *nb, u_int protocol)
{
if (nb != NULL) {
switch(protocol) {
case PPP_LCP: /* Link Control Protocol */
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: lcp in %d:%.*H", pd, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: lcp in nBuf len=%d", pd, nb->len));
/* XXX Assume that LCP packet fits in single nBuf. */
lcp_protent.input(pd, nb->data, nb->len);
nFreeChain(nb);
break;
case PPP_IPCP: /* IP Control Protocol */
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: ipcp in %d:%.*H", pd, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: ipcp in nBuf len=%d", pd, nb->len));
/* XXX Assume that IPCP packet fits in single nBuf. */
ipcp_protent.input(pd, nb->data, nb->len);
nFreeChain(nb);
break;
case PPP_PAP: /* Password Authentication Protocol */
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: pap in %d:%.*H", pd, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: pap in nBuf len=%d", pd, nb->len));
pap_protent.input(pd, nb->data, nb->len);
nFreeChain(nb);
break;
case PPP_VJC_COMP: /* VJ compressed TCP */
#if VJ_SUPPORT > 0
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: vj_comp in %d:%.*H", pd, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: vj_comp in nBuf len=%d", pd, nb->len));
/*
* Clip off the VJ header and prepend the rebuilt TCP/IP header and
* pass the result to IP.
*/
if (vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) {
ipInput(nb, IFT_PPP, pd);
} else {
/* Something's wrong so drop it. */
PPPDEBUG((pppControl[pd].traceOffset + LOG_WARNING, TL_PPP,
"pppDispatch[%d]: Dropping VJ compressed", pd));
nFreeChain(nb);
}
#else
/* No handler for this protocol so drop the packet. */
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: drop VJ Comp in %d:.*H", pd, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: drop VJ Comp in %d:%s", pd, nb->len, nb->data));
nFreeChain(nb);
#if STATS_SUPPORT > 0
pppStats.PPPderrors++;
#endif
#endif
break;
case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */
#if VJ_SUPPORT > 0
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: vj_un in %d:%.*H", pd, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: vj_un in nBuf len=%d", pd, nb->len));
/*
* Process the TCP/IP header for VJ header compression and then pass
* the packet to IP.
*/
if (vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) {
ipInput(nb, IFT_PPP, pd);
} else {
/* Something's wrong so drop it. */
PPPDEBUG((pppControl[pd].traceOffset + LOG_WARNING, TL_PPP,
"pppDispatch[%d]: Dropping VJ uncompressed", pd));
nFreeChain(nb);
}
#else
/* No handler for this protocol so drop the packet. */
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
"pppDispatch[%d]: drop VJ UnComp in %d:.*H",
pd, nb->len, MIN(nb->len * 2, 40), nb->data));
nFreeChain(nb);
#if STATS_SUPPORT > 0
pppStats.PPPderrors++;
#endif
#endif
break;
case PPP_IP: /* Internet Protocol */
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: ip in %d:%.*H", pd, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: ip in nBuf len=%d", pd, nb->len));
ipInput(nb, IFT_PPP, pd);
break;
case PPP_AT: /* AppleTalk Protocol */
case PPP_COMP: /* compressed packet */
case PPP_ATCP: /* AppleTalk Control Protocol */
case PPP_CCP: /* Compression Control Protocol */
case PPP_LQR: /* Link Quality Report protocol */
case PPP_CHAP: /* Cryptographic Handshake Auth. Protocol */
case PPP_CBCP: /* Callback Control Protocol */
default:
/* No handler for this protocol so drop the packet. */
PPPDEBUG((pppControl[pd].traceOffset + LOG_INFO, TL_PPP,
// "pppDispatch[%d]: drop 0x%X in %d:%.*H", pd, protocol, nb->len, MIN(nb->len * 2, 40), nb->data));
"pppDispatch[%d]: drop 0x%X in nBuf len=%d", pd, protocol, nb->len));
nFreeChain(nb);
#if STATS_SUPPORT > 0
pppStats.PPPderrors++;
#endif
break;
}
}
}
/*
* Drop the input packet.
*/
static void pppDrop(PPPControl *pc)
{
if (pc->inHead != NULL) {
// PPPDEBUG((LOG_INFO, TL_PPP, "pppDrop: %d:%.*H", pc->inHead->len, min(60, pc->inHead->len * 2), pc->inHead->data));
PPPDEBUG((LOG_INFO, TL_PPP, "pppDrop: nBuf len=%d", pc->inHead->len));
nFreeChain(pc->inHead);
pc->inHead = NULL;
pc->inTail = NULL;
}
#if VJ_SUPPORT > 0
vj_uncompress_err(&pc->vjComp);
#endif
}
/*
* Process a received octet string.
*/
static void pppInProc(int pd, u_char *s, int l)
{
PPPControl *pc = &pppControl[pd];
NBuf *nextNBuf;
u_char curChar;
while (l-- > 0) {
curChar = *s++;
/* Handle special characters. */
if (ESCAPE_P(pc->inACCM, curChar)) {
/* 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 ']'
* and there is no reason that I know of to escape it, I won't complicate
* the code to handle this case. GLL */
if (curChar == PPPESCAPE)
pc->inEscaped = !0;
/* Check for the flag character. */
else if (curChar == PPPFLAG) {
/* If this is just an extra flag character, ignore it. */
if (pc->inState == PDADDRESS)
;
/* If we haven't received the packet header, drop what has come in. */
else if (pc->inState < PDDATA) {
PPPDEBUG((pc->traceOffset + LOG_WARNING, TL_PPP,
"pppInProc[%d]: Dropping incomplete packet %d",
pd, pc->inState));
pppDrop(pc);
}
/* If the fcs is invalid, drop the packet. */
else if (pc->inFCS != PPP_GOODFCS) {
PPPDEBUG((pc->traceOffset + LOG_INFO, TL_PPP,
"pppInProc[%d]: Dropping bad fcs 0x%X proto=x%X",
pd, pc->inFCS, pc->inProtocol));
pppDrop(pc);
#if STATS_SUPPORT > 0
pppStats.PPPierrors++;
#endif
}
/* Otherwise it's a good packet so pass it on. */
else {
/* Trim off the checksum. */
pc->inTail->len -= 2;
pc->inLen -= 2;
/* Update the packet header. */
pc->inHead->chainLen = pc->inLen;
/* Dispatch the packet thereby consuming it. */
pppDispatch(pd, pc->inHead, pc->inProtocol);
pc->inHead = NULL;
pc->inTail = NULL;
#if STATS_SUPPORT > 0
pppStats.PPPipackets++;
#endif
}
/* 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((pc->traceOffset + LOG_WARNING, TL_PPP,
"pppInProc[%d]: Dropping ACCM char <%d>", pd, curChar));
}
}
/* Process other characters. */
else {
/* Unencode escaped characters. */
if (pc->inEscaped) {
pc->inEscaped = 0;
curChar ^= PPPESCMASK;
}
/* Having removed transparency encoding and physical layer control characters,
* we can update the frame check sequence nunber. */
pc->inFCS = PPP_FCS(pc->inFCS, curChar);
/* Process character relative to current state. */
switch(pc->inState) {
case PDIDLE: /* Idle state - waiting. */
/* Drop the character. */
break;
case PDSTART: /* Process start flag. */
/* Drop the character - we would have processed a flag character
* above. */
break;
case PDCONTROL: /* Process control field. */
/* If we don't get a valid control code, restart. */
if (curChar == PPPCONTROL) {
pc->inState = PDPROTOCOL1;
}
else {
PPPDEBUG((pc->traceOffset + LOG_WARNING, TL_PPP,
"pppInProc[%d]: Invalid control <%d>", pd, curChar));
pc->inState = PDSTART;
}
break;
case PDADDRESS: /* Process address field. */
if (curChar == PPPADDRESS) {
pc->inState = PDCONTROL;
break;
}
/* Else assume compressed address and control fields so
* fall through to get the protocol... */
case PDPROTOCOL1: /* Process protocol field 1. */
/* If the lower bit is set, this is the end of the protocol
* field. */
if (curChar & 1) {
pc->inProtocol = curChar;
pc->inState = PDDATA;
}
else {
pc->inProtocol = (u_int)curChar << 8;
pc->inState = PDPROTOCOL2;
}
break;
case PDPROTOCOL2: /* Process protocol field 2. */
pc->inProtocol |= curChar;
pc->inState = PDDATA;
break;
case PDDATA: /* Process data byte. */
/* Make space to receive processed data. */
if (pc->inTail == NULL || nTRAILINGSPACE(pc->inTail) <= 0) {
/* If we haven't started a packet, we need a packet header. */
nGET(nextNBuf);
if (nextNBuf == NULL) {
/* No free buffers. Drop the input packet and let the
* higher layers deal with it. Continue processing
* the received nBuf chain in case a new packet starts. */
PPPDEBUG((LOG_ERR, TL_PPP, "pppInProc[%d]: NO FREE MBUFS!", pd));
pppDrop(pc);
pc->inState = PDSTART; /* Wait for flag sequence. */
pc->inFCS = PPP_INITFCS;
} else {
*(nextNBuf->data) = curChar;
nextNBuf->len = 1;
nextNBuf->nextBuf = NULL;
if (pc->inHead == NULL) {
pc->inHead = nextNBuf;
pc->inLen = 1;
}
else { /* Since if inHead is not NULL, then neither is inTail! */
pc->inTail->nextBuf = nextNBuf;
pc->inLen++;
}
pc->inTail = nextNBuf;
}
}
/* Load character into buffer. */
else {
pc->inTail->data[pc->inTail->len++] = curChar;
pc->inLen++;
}
break;
}
}
}
}
/*
* pppMPutC - append given character to end of given nBuf. If the character
* needs to be escaped, do so. If nBuf is full, append another.
* Return the current nBuf.
*/
static NBuf *pppMPutC(u_char c, ext_accm *outACCM, NBuf *nb)
{
NBuf *tb = nb;
/* Make sure there is room for the character and an escape code.
* Sure we don't quite fill the buffer if the character doesn't
* get escaped but is one character worth complicating this? */
/* Note: We assume no packet header. */
if (nb && (&nb->body[NBUFSZ] - (nb->data + nb->len)) < 2) {
nGET(tb);
if (tb) {
nb->nextBuf = tb;
tb->len = 0;
}
nb = tb;
}
if (nb) {
if (ESCAPE_P(*outACCM, c)) {
*(nb->data + nb->len++) = PPP_ESCAPE;
*(nb->data + nb->len++) = c ^ PPP_TRANS;
}
else
*(nb->data + nb->len++) = c;
}
return tb;
}
/*
* pppMPutRaw - append given character to end of given nBuf without escaping
* it. If nBuf is full, append another.
* This is normally used to add the flag character to a packet.
* Return the current nBuf.
*/
static NBuf *pppMPutRaw(u_char c, NBuf *nb)
{
NBuf *tb = nb;
/* Make sure there is room for the character and an escape code.
* Sure we don't quite fill the buffer if the character doesn't
* get escaped but is one character worth complicating this? */
/* Note: We assume no packet header. */
if (nb && (&nb->body[NBUFSZ] - (nb->data + nb->len)) < 2) {
nGET(tb);
if (tb) {
nb->nextBuf = tb;
tb->len = 0;
}
nb = tb;
}
if (nb) {
*(nb->data + nb->len++) = c;
}
return tb;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -