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

📄 netipcp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************

* netipcp.c - Network PPP IP Control Protocol program file.

*

* portions Copyright (c) 1997 by Global Election Systems Inc.

*

* The authors hereby grant permission to use, copy, modify, distribute,

* and license this software and its documentation for any purpose, provided

* that existing copyright notices are retained in all copies and that this

* notice and the following disclaimer are included verbatim in any 

* distributions. No written agreement, license, or royalty fee is required

* for any of the authorized uses.

*

* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR

* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 

* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT

* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY

* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF

* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*

******************************************************************************

* REVISION HISTORY

*

* 97-12-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.

*	Original.

*****************************************************************************/

/*

 * ipcp.c - PPP IP Control Protocol.

 *

 * Copyright (c) 1989 Carnegie Mellon University.

 * All rights reserved.

 *

 * Redistribution and use in source and binary forms are permitted

 * provided that the above copyright notice and this paragraph are

 * duplicated in all such forms and that any documentation,

 * advertising materials, and other materials related to such

 * distribution and use acknowledge that the software was developed

 * by Carnegie Mellon University.  The name of the

 * University may not be used to endorse or promote products derived

 * from this software without specific prior written permission.

 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR

 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED

 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

 */



#include "netconf.h"

#include <string.h>

#include "net.h"

#include "netbuf.h"

#include "netip.h"

#include "netppp.h"

#include "netauth.h"

#include "netfsm.h"

#include "netiphdr.h"		/* Required for netvj.h. */

#include "netvj.h"

#include "netipcp.h"



#include <stdio.h>

#include "netdebug.h"





/*************************/

/*** LOCAL DEFINITIONS ***/

/*************************/

/* #define OLD_CI_ADDRS 1 */	/* Support deprecated address negotiation. */



/*

 * Lengths of configuration options.

 */

#define CILEN_VOID	2

#define CILEN_COMPRESS	4	/* min length for compression protocol opt. */

#define CILEN_VJ	6	/* length for RFC1332 Van-Jacobson opt. */

#define CILEN_ADDR	6	/* new-style single address option */

#define CILEN_ADDRS	10	/* old-style dual address option */







/***********************************/

/*** LOCAL FUNCTION DECLARATIONS ***/

/***********************************/

/*

 * Callbacks for fsm code.  (CI = Configuration Information)

 */

static void ipcp_resetci __P((fsm *));	/* Reset our CI */

static int  ipcp_cilen __P((fsm *));	        /* Return length of our CI */

static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */

static int  ipcp_ackci __P((fsm *, u_char *, int));	/* Peer ack'd our CI */

static int  ipcp_nakci __P((fsm *, u_char *, int));	/* Peer nak'd our CI */

static int  ipcp_rejci __P((fsm *, u_char *, int));	/* Peer rej'd our CI */

static int  ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */

static void ipcp_up __P((fsm *));		/* We're UP */

static void ipcp_down __P((fsm *));		/* We're DOWN */

#ifdef XXX

static void ipcp_script __P((fsm *, char *)); /* Run an up/down script */

#endif

static void ipcp_finished __P((fsm *));	/* Don't need lower layer */



/*

 * Protocol entry points from main code.

 */

static void ipcp_init __P((int));

static void ipcp_open __P((int));

static void ipcp_close __P((int, char *));

static void ipcp_lowerup __P((int));

static void ipcp_lowerdown __P((int));

static void ipcp_input __P((int, u_char *, int));

static void ipcp_protrej __P((int));

static int  ipcp_printpkt __P((u_char *, int,

			       void (*) __P((void *, char *, ...)), void *));

static void ip_check_options __P((void));

static int  ip_active_pkt __P((u_char *, int));



static void ipcp_clear_addrs __P((int));



#define CODENAME(x)	((x) == CONFACK ? "ACK" : \
			 (x) == CONFNAK ? "NAK" : "REJ")







/******************************/

/*** PUBLIC DATA STRUCTURES ***/

/******************************/

/* global vars */

ipcp_options ipcp_wantoptions[NUM_PPP];	/* Options that we want to request */

ipcp_options ipcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */

ipcp_options ipcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */

ipcp_options ipcp_hisoptions[NUM_PPP];	/* Options that we ack'd */



fsm ipcp_fsm[NUM_PPP];		/* IPCP fsm structure */



struct protent ipcp_protent = {

    PPP_IPCP,

    ipcp_init,

    ipcp_input,

    ipcp_protrej,

    ipcp_lowerup,

    ipcp_lowerdown,

    ipcp_open,

    ipcp_close,

    ipcp_printpkt,

    NULL,

    1,

    "IPCP",

    ip_check_options,

    NULL,

    ip_active_pkt

};







/*****************************/                                                  

/*** LOCAL DATA STRUCTURES ***/

/*****************************/

/* local vars */

static int cis_received[NUM_PPP];		/* # Conf-Reqs received */

static int default_route_set[NUM_PPP];	/* Have set up a default route */



static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */

    ipcp_resetci,		/* Reset our Configuration Information */

    ipcp_cilen,			/* Length of our Configuration Information */

    ipcp_addci,			/* Add our Configuration Information */

    ipcp_ackci,			/* ACK our Configuration Information */

    ipcp_nakci,			/* NAK our Configuration Information */

    ipcp_rejci,			/* Reject our Configuration Information */

    ipcp_reqci,			/* Request peer's Configuration Information */

    ipcp_up,			/* Called when fsm reaches OPENED state */

    ipcp_down,			/* Called when fsm leaves OPENED state */

    NULL,				/* Called when we want the lower layer up */

    ipcp_finished,		/* Called when we want the lower layer down */

    NULL,				/* Called when Protocol-Reject received */

    NULL,				/* Retransmission is necessary */

    NULL,				/* Called to handle protocol-specific codes */

    "IPCP"				/* String name of protocol */

};







/**********************************/                                         /*0001*/

/*** LOCAL FUNCTION DEFINITIONS ***/

/**********************************/



/*

 * ipcp_init - Initialize IPCP.

 */

static void ipcp_init(int unit)

{

	fsm *f = &ipcp_fsm[unit];                                                                                    

	ipcp_options *wo = &ipcp_wantoptions[unit];

	ipcp_options *ao = &ipcp_allowoptions[unit];

	

	f->unit = unit;

	f->protocol = PPP_IPCP;

	f->callbacks = &ipcp_callbacks;

	fsm_init(&ipcp_fsm[unit]);

	

	memset(wo, 0, sizeof(*wo));

	memset(ao, 0, sizeof(*ao));

	

	wo->neg_addr = 1;

	wo->ouraddr = 0;

#if VJ_SUPPORT > 0

	wo->neg_vj = 1;

#else

	wo->neg_vj = 0;

#endif

	wo->vj_protocol = IPCP_VJ_COMP;

	wo->maxslotindex = MAX_SLOTS - 1;

	wo->cflag = 0;

	

	wo->default_route = 1;

	

	ao->neg_addr = 1;

#if VJ_SUPPORT > 0

	ao->neg_vj = 1;

#else

	ao->neg_vj = 0;

#endif

	ao->maxslotindex = MAX_SLOTS - 1;

	ao->cflag = 1;

	

	ao->default_route = 1;

}



                                                                           /*0047*/

/*

 * ipcp_open - IPCP is allowed to come up.

 */

static void ipcp_open(int unit)

{

	fsm_open(&ipcp_fsm[unit]);

}



                                                                           /*0056*/

/*

 * ipcp_close - Take IPCP down.

 */

static void ipcp_close(int unit, char *reason)

{

	fsm_close(&ipcp_fsm[unit], reason);

}



                                                                           /*0065*/

/*

 * ipcp_lowerup - The lower layer is up.

 */

static void ipcp_lowerup(int unit)

{

	fsm_lowerup(&ipcp_fsm[unit]);

}





/*

 * ipcp_lowerdown - The lower layer is down.

 */

static void ipcp_lowerdown(int unit)

{

	fsm_lowerdown(&ipcp_fsm[unit]);

}



                                                                            /*0083*/

/*

 * ipcp_input - Input IPCP packet.

 */

static void ipcp_input(int unit, u_char *p, int len)

{

	fsm_input(&ipcp_fsm[unit], p, len);

}



                                                                            /*0092*/

/*

 * ipcp_protrej - A Protocol-Reject was received for IPCP.

 *

 * Pretend the lower layer went down, so we shut up.

 */

static void ipcp_protrej(int unit)

{

	fsm_lowerdown(&ipcp_fsm[unit]);

}



                                                                             /*0103*/

/*

 * ipcp_resetci - Reset our CI.

 */

static void ipcp_resetci(fsm *f)

{

	ipcp_options *wo = &ipcp_wantoptions[f->unit];

	

	wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;

	if (wo->ouraddr == 0)

		wo->accept_local = 1;

	if (wo->hisaddr == 0)

		wo->accept_remote = 1;

	ipcp_gotoptions[f->unit] = *wo;

	cis_received[f->unit] = 0;

}



                                                                                /*120*/

/*

 * ipcp_cilen - Return length of our CI.

 */

static int ipcp_cilen(fsm *f)

{

	ipcp_options *go = &ipcp_gotoptions[f->unit];

	ipcp_options *wo = &ipcp_wantoptions[f->unit];

	ipcp_options *ho = &ipcp_hisoptions[f->unit];

	

#define LENCIVJ(neg, old)	(neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)

#define LENCIADDR(neg, old)	(neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)

	

	/*

	 * First see if we want to change our options to the old

	 * forms because we have received old forms from the peer.

	 */

	if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {

		/* use the old style of address negotiation */

		go->neg_addr = 1;

		go->old_addrs = 1;

	}

	if (wo->neg_vj && !go->neg_vj && !go->old_vj) {

		/* try an older style of VJ negotiation */

		if (cis_received[f->unit] == 0) {

			/* keep trying the new style until we see some CI from the peer */

			go->neg_vj = 1;

		} else {

			/* use the old style only if the peer did */

			if (ho->neg_vj && ho->old_vj) {

				go->neg_vj = 1;

				go->old_vj = 1;

				go->vj_protocol = ho->vj_protocol;

			}

		}

	}

	

	return (LENCIADDR(go->neg_addr, go->old_addrs)

			+ LENCIVJ(go->neg_vj, go->old_vj));

}



/**************************************************************************00161**************/

/*

 * ipcp_addci - Add our desired CIs to a packet.

 */

static void ipcp_addci(fsm *f, u_char *ucp, int *lenp)

{

	ipcp_options *go = &ipcp_gotoptions[f->unit];

	int len = *lenp;

	

#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
	if (neg) { \
		int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
		if (len >= vjlen) { \
			PUTCHAR(opt, ucp); \
			PUTCHAR(vjlen, ucp); \
			PUTSHORT(val, ucp); \
			if (!old) { \
				PUTCHAR(maxslotindex, ucp); \
				PUTCHAR(cflag, ucp); \
			} \
			len -= vjlen; \
		} else \
			neg = 0; \
	}

	

#define ADDCIADDR(opt, neg, old, val1, val2) \
	if (neg) { \
		int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
		if (len >= addrlen) { \
			u_int32_t l; \
			PUTCHAR(opt, ucp); \
			PUTCHAR(addrlen, ucp); \
			l = ntohl(val1); \
			PUTLONG(l, ucp); \
			if (old) { \
				l = ntohl(val2); \
				PUTLONG(l, ucp); \
			} \
			len -= addrlen; \
		} else \
			neg = 0; \
	}

	

	ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
			  go->old_addrs, go->ouraddr, go->hisaddr);

	

	ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
			go->maxslotindex, go->cflag);

	

	*lenp -= len;
}



                                                                   /**********************************00213*****/

/*

 * ipcp_ackci - Ack our CIs.

 *

 * Returns:

 *	0 - Ack was bad.

 *	1 - Ack was good.

 */

static int ipcp_ackci(fsm *f, u_char *p, int len)

{

	ipcp_options *go = &ipcp_gotoptions[f->unit];

	u_short cilen, citype, cishort;

	u_int32_t cilong;

	u_char cimaxslotindex, cicflag;

	

	/*

	 * CIs must be in exactly the same order that we sent...

	 * Check packet length and CI length at each step.

	 * If we find any deviations, then this packet is bad.

	 */

	

#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \

⌨️ 快捷键说明

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