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

📄 netppp.c

📁 ucos操作系统下TCPIP实现代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	
	pc->vjEnabled = vjcomp;
	pc->vjComp.compressSlot = cidcomp;
	pc->vjComp.maxSlotIndex = maxcid;
	PPPDEBUG((LOG_INFO, TL_PPP, "sifvjcomp: VJ compress enable=%d slot=%d max slot=%d",
				vjcomp, cidcomp, maxcid));
#endif

	return 0;
}

/*
 * sifup - Config the interface up and enable IP packets to pass.
 */
#pragma argsused
int sifup(int pd)
{
	PPPControl *pc = &pppControl[pd];
	int st = 1;
	
	if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
		st = 0;
		PPPDEBUG((LOG_WARNING, TL_PPP, "sifup[%d]: bad parms", pd));
	} else {
	    pc->if_up = 1;
	    pc->errCode = 0;
	}
	return st;
}

/*
 * sifnpmode - Set the mode for handling packets for a given NP.
 */
#pragma argsused
int sifnpmode(int u, int proto, enum NPmode mode)
{
	return 0;
}

/*
 * sifdown - Config the interface down and disable IP.
 */
#pragma argsused
int sifdown(int pd)
{
	PPPControl *pc = &pppControl[pd];
	int st = 1;
	
	if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) {
		st = 0;
		PPPDEBUG((LOG_WARNING, TL_PPP, "sifup[%d]: bad parms", pd));
	} else
	    pc->if_up = 0;
	return st;
}

/*
 * sifaddr - Config the interface IP addresses and netmask.
 */
#pragma argsused
int sifaddr(
	int u,				/* Interface unit ??? */
	u_int32_t o,		/* Our IP address ??? */
	u_int32_t h,		/* IP subnet mask ??? */
	u_int32_t m			/* IP broadcast address ??? */
)
{
	return 1;
}

/*
 * cifaddr - Clear the interface IP addresses, and delete routes
 * through the interface if possible.
 */
#pragma argsused
int cifaddr(
	int u, 			/* Interface unit ??? */
	u_int32_t o,	/* Our IP address ??? */
	u_int32_t h		/* IP broadcast address ??? */
)
{
	return 1;
}

/*
 * sifdefaultroute - assign a default route through the address given.
 */
#pragma argsused
int sifdefaultroute(int u, u_int32_t l, u_int32_t g)
{
	ipSetDefault(l, g, IFT_PPP, u);
	return !0;
}

/*
 * cifdefaultroute - delete a default route through the address given.
 */
#pragma argsused
int cifdefaultroute(int u, u_int32_t l, u_int32_t g)
{
	ipClearDefault();
	return !0;
}

/**********************************/
/*** LOCAL FUNCTION DEFINITIONS ***/
/**********************************/
/* 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 *pd)
{
	PPPControl *pc = &pppControl[(int)pd];
	NBuf *curNBuf;
	
	/*
	 * Start the connection and handle incoming events (packet or timeout).
	 */
	trace(LOG_NOTICE, "Connecting %s <--> %s", pc->ifname, nameForDevice(pc->fd));
	lcp_lowerup((int)pd);
	lcp_open((int)pd);		/* Start protocol */
	while (lcp_phase[(int)pd] != PHASE_DEAD) {
		if (pc->kill_link) {
			/* This will leave us at PHASE_DEAD. */
			lcp_close(0, "User request");
			pc->kill_link = 0;
		}
		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. */
			}
		}
	}

	OSTaskDel(OS_PRIO_SELF);
}

/*
 * 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));
			/* 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));
			/* 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));
			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));
			/* 
			 * 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));
			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));
			/* 
			 * 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));
			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));
			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));
		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 + -