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

📄 ppp.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Verify the table pointer and ensure that the line is * still in PPP discipline. */	if (ppp->magic != PPP_MAGIC) {		if (ppp->flags & SC_DEBUG)			printk (KERN_DEBUG				"PPP: handler called but couldn't find "				"PPP struct.\n");		return;	}	CHECK_PPP_VOID ();/* * Print the buffer if desired */	if (ppp->flags & SC_LOG_RAWIN)		ppp_print_buffer ("receive buffer", data, count);/* * Collect the character and error condition for the character. Set the toss * flag for the first character error. */	while (count-- > 0) {		ppp->bytes_rcvd++;		chr = *data++;		if (flags) {			if (*flags && ppp->toss == 0)				ppp->toss = *flags;			++flags;		}/* * Set the flags for 8 data bits and no parity. * * Actually, it sets the flags for d7 being 0/1 and parity being even/odd * so that the normal processing would have all flags set at the end of the * session. A missing flag bit would denote an error condition. */#ifdef CHECK_CHARACTERS		if (chr & 0x80)			ppp->flags |= SC_RCV_B7_1;		else			ppp->flags |= SC_RCV_B7_0;		if (paritytab[chr >> 5] & (1 << (chr & 0x1F)))			ppp->flags |= SC_RCV_ODDP;		else			ppp->flags |= SC_RCV_EVNP;#endif/* * Branch on the character. Process the escape character. The sequence ESC ESC * is defined to be ESC. */		switch (chr) {		case PPP_ESCAPE: /* PPP_ESCAPE: invert bit in next character */			ppp->escape = PPP_TRANS;			break;/* * FLAG. This is the end of the block. If the block terminated by ESC FLAG, * then the block is to be ignored. In addition, characters before the very * first FLAG are also tossed by this procedure. */		case PPP_FLAG:	/* PPP_FLAG: end of frame */			ppp->stats.ppp_ibytes += ppp->rbuf->count;			if (ppp->escape)				ppp->toss |= 0x80;/* * Process frames which are not to be ignored. If the processing failed, * then clean up the VJ tables. */			if ((ppp->toss & 0x80) != 0 ||			    ppp_doframe (ppp) == 0) {				slhc_toss (ppp->slcomp);			}/* * Reset all indicators for the new frame to follow. */			buf->count  = 0;			buf->fcs    = PPP_INITFCS;			ppp->escape = 0;			ppp->toss   = 0;			break;/* * All other characters in the data come here. If the character is in the * receive mask then ignore the character. */		default:			if (in_rmap (ppp, chr))				break;/* * Adjust the character and if the frame is to be discarded then simply * ignore the character until the ending FLAG is received. */			chr ^= ppp->escape;			ppp->escape = 0;			if (ppp->toss != 0)				break;/* * If the count sent is within reason then store the character, bump the * count, and update the FCS for the character. */			if (buf->count < buf->size) {				buf_base (buf)[buf->count++] = chr;				buf->fcs = PPP_FCS (buf->fcs, chr);				break;			}/* * The peer sent too much data. Set the flags to discard the current frame * and wait for the re-synchronization FLAG to be sent. */			ppp->stats.ppp_ierrors++;			ppp->toss |= 0xC0;			break;		}	}}/* * Put the input frame into the networking system for the indicated protocol */static intppp_rcv_rx (struct ppp *ppp, __u16 proto, __u8 * data, int count){	sk_buff *skb = dev_alloc_skb (count);/* * Generate a skb buffer for the new frame. */	if (skb == NULL) {		if (ppp->flags & SC_DEBUG)			printk (KERN_ERR			 "ppp_do_ip: packet dropped on %s (no memory)!\n",			 ppp2dev (ppp)->name);		return 0;	}/* * Move the received data from the input buffer to the skb buffer. */	skb->dev      = ppp2dev (ppp);	/* We are the device */	skb->protocol = proto;	skb->mac.raw  = skb_data(skb);	memcpy (skb_put(skb,count), data, count);	/* move data *//* * Tag the frame and kick it to the proper receive routine */	skb->free = 1;	ppp->ddinfo.recv_idle = jiffies;	netif_rx (skb);	return 1;}/* * Process the receipt of an IP frame */static intrcv_proto_ip (struct ppp *ppp, __u16 proto, __u8 * data, int count){	if ((ppp2dev (ppp)->flags & IFF_UP) && (count > 0))		if (ppp->sc_npmode[NP_IP] == NPMODE_PASS)			return ppp_rcv_rx (ppp, htons (ETH_P_IP), data, count);	return 0;}/* * Process the receipt of an IPX frame */static intrcv_proto_ipx (struct ppp *ppp, __u16 proto, __u8 * data, int count){	if (((ppp2dev (ppp)->flags & IFF_UP) != 0) && (count > 0))		return ppp_rcv_rx (ppp, htons (ETH_P_IPX), data, count);	return 0;}/* * Process the receipt of an VJ Compressed frame */static intrcv_proto_vjc_comp (struct ppp *ppp, __u16 proto,		    __u8 *data, int count){	if ((ppp->flags & SC_REJ_COMP_TCP) == 0) {		int new_count = slhc_uncompress (ppp->slcomp, data, count);		if (new_count >= 0) {			return rcv_proto_ip (ppp, PPP_IP, data, new_count);		}		if (ppp->flags & SC_DEBUG)			printk (KERN_NOTICE				"ppp: error in VJ decompression\n");	}	return 0;}/* * Process the receipt of an VJ Un-compressed frame */static intrcv_proto_vjc_uncomp (struct ppp *ppp, __u16 proto,		      __u8 *data, int count){	if ((ppp->flags & SC_REJ_COMP_TCP) == 0) {		if (slhc_remember (ppp->slcomp, data, count) > 0) {			return rcv_proto_ip (ppp, PPP_IP, data, count);		}		if (ppp->flags & SC_DEBUG)			printk (KERN_NOTICE				"ppp: error in VJ memorizing\n");	}	return 0;}/* * Receive all unclassified protocols. */static intrcv_proto_unknown (struct ppp *ppp, __u16 proto,		   __u8 *data, int len){	int totlen;	register int current_idx;#define PUTC(c)						 \{							 \    buf_base (ppp->ubuf) [current_idx++] = (__u8) (c); \    current_idx &= ppp->ubuf->size;			 \    if (current_idx == ppp->ubuf->tail)			 \	    goto failure;				 \}/* * The total length includes the protocol data. * Lock the user information buffer. */	if (set_bit (0, &ppp->ubuf->locked)) {		if (ppp->flags & SC_DEBUG)			printk (KERN_DEBUG				"ppp_us_queue: can't get lock\n");	} else {		current_idx = ppp->ubuf->head;/* * Insert the buffer length (not counted), the protocol, and the data */		totlen = len + 2;		PUTC (totlen >> 8);		PUTC (totlen);		PUTC (proto >> 8);		PUTC (proto);		totlen -= 2;		while (totlen-- > 0) {			PUTC (*data++);		}#undef PUTC/* * The frame is complete. Update the head pointer and wakeup the pppd * process. */		ppp->ubuf->head = current_idx;		clear_bit (0, &ppp->ubuf->locked);		wake_up_interruptible (&ppp->read_wait);		if (ppp->tty->fasync != NULL)			kill_fasync (ppp->tty->fasync, SIGIO);		if (ppp->flags & SC_DEBUG)			printk (KERN_INFO				"ppp: successfully queued %d bytes, flags = %x\n",				len + 2, ppp->flags);		return 1;/* * The buffer is full. Unlock the header */failure:		clear_bit (0, &ppp->ubuf->locked);		if (ppp->flags & SC_DEBUG)			printk (KERN_INFO				"ppp_us_queue: ran out of buffer space.\n");	}/* * Discard the frame. There are no takers for this protocol. */	if (ppp->flags & SC_DEBUG)		printk (KERN_WARNING			"ppp: dropping packet on the floor.\n");	slhc_toss (ppp->slcomp);	return 0;}/* * Handle a CCP packet. * * The CCP packet is passed along to the pppd process just like any * other PPP frame. The difference is that some processing needs to be * immediate or the compressors will become confused on the peer. */static void ppp_proto_ccp (struct ppp *ppp, __u8 *dp, int len, int rcvd){	int slen    = CCP_LENGTH(dp);	__u8 *opt = dp   + CCP_HDRLEN;	int opt_len = slen - CCP_HDRLEN;	if (slen > len)		return;	switch (CCP_CODE(dp)) {	case CCP_CONFREQ:	case CCP_TERMREQ:	case CCP_TERMACK:/* * CCP must be going down - disable compression */		if (ppp->flags & SC_CCP_UP) {			ppp->flags &= ~(SC_CCP_UP   |					SC_COMP_RUN |					SC_DECOMP_RUN);		}		break;	case CCP_CONFACK:		if ((ppp->flags & SC_CCP_OPEN) == 0)			break;		if (ppp->flags & SC_CCP_UP)			break;		if (slen < (CCP_HDRLEN + CCP_OPT_MINLEN))			break;		if (slen < (CCP_OPT_LENGTH (opt) + CCP_HDRLEN))			break;/* * we're agreeing to send compressed packets. */		if (!rcvd) {			if (ppp->sc_xc_state == NULL)				break;			if ((*ppp->sc_xcomp->comp_init)			    (ppp->sc_xc_state,			     opt,			     opt_len,			     ppp2dev (ppp)->base_addr,			     0,			     ppp->flags))				ppp->flags |= SC_COMP_RUN;			break;		}/* * peer is agreeing to send compressed packets. */		if (ppp->sc_rc_state == NULL)			break;		if ((*ppp->sc_rcomp->decomp_init)		    (ppp->sc_rc_state,		     opt,		     opt_len,		     ppp2dev (ppp)->base_addr,		     0,		     ppp->mru,		     ppp->flags)) {			ppp->flags |= SC_DECOMP_RUN;			ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR);		}		break;/* * The protocol sequence is complete at this end */	case CCP_RESETACK:		if ((ppp->flags & SC_CCP_UP) == 0)			break;		if (!rcvd) {			if (ppp->sc_xc_state && (ppp->flags & SC_COMP_RUN))				(*ppp->sc_xcomp->comp_reset)(ppp->sc_xc_state);		} else {			if (ppp->sc_rc_state && (ppp->flags & SC_DECOMP_RUN)) {			      (*ppp->sc_rcomp->decomp_reset)(ppp->sc_rc_state);				ppp->flags &= ~SC_DC_ERROR;			}		}		break;	}}static intrcv_proto_ccp (struct ppp *ppp, __u16 proto, __u8 *dp, int len){	ppp_proto_ccp (ppp, dp, len, 1);	return rcv_proto_unknown (ppp, proto, dp, len);}/* * Handle a LQR packet. */static intrcv_proto_lqr (struct ppp *ppp, __u16 proto, __u8 * data, int len){	return rcv_proto_unknown (ppp, proto, data, len);}/* on entry, a received frame is in ppp->rbuf.bufr   check it and dispose as appropriate */static void ppp_doframe_lower (struct ppp *ppp, __u8 *data, int count){	__u16		proto = PPP_PROTOCOL (data);	ppp_proto_type  *proto_ptr;/* * Ignore empty frames */	if (count <= 4)		return;/* * Count the frame and print it */	++ppp->stats.ppp_ipackets;	if (ppp->flags & SC_LOG_INPKT)		ppp_print_buffer ("receive frame", data, count);/* * Find the procedure to handle this protocol. The last one is marked * as a protocol 0 which is the 'catch-all' to feed it to the pppd daemon. */	proto_ptr = proto_list;	while (proto_ptr->proto != 0 && proto_ptr->proto != proto)		++proto_ptr;/* * Update the appropriate statistic counter. */	if ((*proto_ptr->func) (ppp, proto,				&data[PPP_HARD_HDR_LEN],				count - PPP_HARD_HDR_LEN))		ppp->stats.ppp_ioctects += count;	else		++ppp->stats.ppp_discards;}/* on entry, a received frame is in ppp->rbuf.bufr   check it and dispose as appropriate */static intppp_doframe (struct ppp *ppp){	__u8	*data = buf_base (ppp->rbuf);	int	count = ppp->rbuf->count;	int	addr, ctrl, proto;	int	new_count;	__u8 *new_data;#ifndef NO_RMK_TEMP_FIX	int	malloced_data;#endif/* * If there is a pending error from the receiver then log it and discard * the damaged frame. */	if (ppp->toss) {		if (ppp->flags & SC_DEBUG)			printk (KERN_WARNING				"ppp_toss: tossing frame, reason = %d\n",				ppp->toss);		ppp->stats.ppp_ierrors++;		return 0;	}/* * An empty frame is ignored. This occurs if the FLAG sequence precedes and * follows each frame. */	if (count == 0)		return 1;/* * Generate an error if the frame is too small. */	if (count < PPP_HARD_HDR_LEN) {		if (ppp->flags & SC_DEBUG)			printk (KERN_WARNING				"ppp: got runt ppp frame, %d chars\n", count);		slhc_toss (ppp->slcomp);		ppp->stats.ppp_ierrors++;		return 1;	}/* * Verify the CRC of the frame and discard the CRC characters from the * end of the buffer. */	if (ppp->rbuf->fcs != PPP_GOODFCS) {		if (ppp->flags & SC_DEBUG)			printk (KERN_WARNING				"ppp: frame with bad fcs, excess = %x\n",				ppp->rbuf->fcs ^ PPP_GOODFCS);		ppp->stats.ppp_ierrors++;		return 0;	}	count -= 2;		/* ignore the fcs characters *//* * Ignore the leading ADDRESS and CONTROL fields in the frame. */	addr   = PPP_ALLSTATIONS;	ctrl   = PPP_UI;	if ((data[0] == PPP_ALLSTATIONS) && (data[1] == PPP_UI)) {		data  += 2;		count -= 2;	}/* * Obtain the protocol from the frame */	proto = (__u16) *data++;	if ((proto & 1) == 0) {		proto = (proto << 8) | (__u16) *data++;		--count;	}/* * Rewrite the header with the full information. This may encroach upon * the 'filler' area in the buffer header. This is the purpose for the * filler. */	*(--data) = proto;	*(--data) = proto >> 8;	*(--data) = ctrl;	*(--data) = addr;	count    += 3;#ifndef NO_RMK_TEMP_FIX	/*	 * rmk: should make sure that the packet received is on a word boundary.	 * this is a temporary fix!!!	 */	if ((int)data & 3) {		new_data = kmalloc (ppp->mru + 4, GFP_ATOMIC); /* would like to have 'count' here */		memcpy (new_data, data, count);		data = new_data;

⌨️ 快捷键说明

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