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

📄 netipcp.c

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

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad len"));

				orc = CONFREJ;				/* Reject CI */

				break;

			}

			

			/*

			 * If he has no address, or if we both have his address but

			 * disagree about it, then NAK it with our idea.

			 * In particular, if we don't know his address, but he does,

			 * then accept it.

			 */

			GETLONG(tl, p);	/* Parse source address (his) */

			ciaddr1 = htonl(tl);

			if (ciaddr1 != wo->hisaddr

					&& (ciaddr1 == 0 || !wo->accept_remote)) {

				orc = CONFNAK;

				if (!reject_if_disagree) {

					DECPTR(sizeof(u_int32_t), p);

					tl = ntohl(wo->hisaddr);

					PUTLONG(tl, p);

				}

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %s", ip_ntoa(ciaddr1)));

			} else if (ciaddr1 == 0 && wo->hisaddr == 0) {

				/*

				 * Don't ACK an address of 0.0.0.0 - reject it instead.

				 */

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %s", ip_ntoa(ciaddr1)));

				orc = CONFREJ;

				wo->req_addr = 0;	/* don't NAK with 0.0.0.0 later */

				break;

			}



			ho->neg_addr = 1;

			ho->hisaddr = ciaddr1;

			IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %s", ip_ntoa(ciaddr1)));

			break;

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

		case CI_MS_DNS1:

		case CI_MS_DNS2:

			/* Microsoft primary or secondary DNS request */

			d = citype == CI_MS_DNS2;

			

			/* If we do not have a DNS address then we cannot send it */

			if (ao->dnsaddr[d] == 0 ||

					cilen != CILEN_ADDR) {	/* Check CI length */

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Request ", d+1));

				orc = CONFREJ;				/* Reject CI */

				break;

			}

			GETLONG(tl, p);

			if (htonl(tl) != ao->dnsaddr[d]) {

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %d",

							d+1, ip_ntoa(tl)));

				DECPTR(sizeof(u_int32_t), p);

				tl = ntohl(ao->dnsaddr[d]);

				PUTLONG(tl, p);

				orc = CONFNAK;

			}

			IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Request ", d+1));

			break;

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

		case CI_MS_WINS1:

		case CI_MS_WINS2:

			/* Microsoft primary or secondary WINS request */

			d = citype == CI_MS_WINS2;

			IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Request ", d+1));

			

			/* If we do not have a DNS address then we cannot send it */

			if (ao->winsaddr[d] == 0 ||

				cilen != CILEN_ADDR) {	/* Check CI length */

				orc = CONFREJ;			/* Reject CI */

				break;

			}

			GETLONG(tl, p);

			if (htonl(tl) != ao->winsaddr[d]) {

				DECPTR(sizeof(u_int32_t), p);

				tl = ntohl(ao->winsaddr[d]);

				PUTLONG(tl, p);

				orc = CONFNAK;

			}

			break;

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

		case CI_COMPRESSTYPE:

			if (!ao->neg_vj) {

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowed"));

				orc = CONFREJ;

				break;

			} else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%d", cilen));

				orc = CONFREJ;

				break;

			}

			GETSHORT(cishort, p);

			

			if (!(cishort == IPCP_VJ_COMP ||

					(cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %d", cishort));

				orc = CONFREJ;

				break;

			}

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

			ho->neg_vj = 1;

			ho->vj_protocol = cishort;

			if (cilen == CILEN_VJ) {

				GETCHAR(maxslotindex, p);

				if (maxslotindex > ao->maxslotindex) { 

					IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %d", maxslotindex));

					orc = CONFNAK;

					if (!reject_if_disagree){

						DECPTR(1, p);

						PUTCHAR(ao->maxslotindex, p);

					}

				}

				GETCHAR(cflag, p);

				if (cflag && !ao->cflag) {

					IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %d", cflag));

					orc = CONFNAK;

					if (!reject_if_disagree){

						DECPTR(1, p);

						PUTCHAR(wo->cflag, p);

					}

				}

				ho->maxslotindex = maxslotindex;

				ho->cflag = cflag;

			} else {

				ho->old_vj = 1;

				ho->maxslotindex = MAX_SLOTS - 1;

				ho->cflag = 1;

			}

			IPCPDEBUG((LOG_INFO, 

						"ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d",

						ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));

			break;

			

		default:

			IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %d", citype));

			orc = CONFREJ;

			break;

		}

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

endswitch:

		if (orc == CONFACK &&		/* Good CI */

				rc != CONFACK)		/*  but prior CI wasnt? */

			continue;				/* Don't send this one */

		

		if (orc == CONFNAK) {		/* Nak this CI? */

			if (reject_if_disagree) {	/* Getting fed up with sending NAKs? */

				IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naks"));

				orc = CONFREJ;		/* Get tough if so */

			} else {

				if (rc == CONFREJ)	/* Rejecting prior CI? */

					continue;		/* Don't send this one */

				if (rc == CONFACK) {	/* Ack'd all prior CIs? */

					rc = CONFNAK;	/* Not anymore... */

					ucp = inp;		/* Backup */

				}

			}

		}

		

		if (orc == CONFREJ &&		/* Reject this CI */

				rc != CONFREJ) {	/*  but no prior ones? */

			rc = CONFREJ;

			ucp = inp;				/* Backup */

		}

		

		/* Need to move CI? */

		if (ucp != cip)

			BCOPY(cip, ucp, cilen);	/* Move it */

		

		/* Update output pointer */

		INCPTR(cilen, ucp);

	}

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

	/*

	 * If we aren't rejecting this packet, and we want to negotiate

	 * their address, and they didn't send their address, then we

	 * send a NAK with a CI_ADDR option appended.  We assume the

	 * input buffer is long enough that we can append the extra

	 * option safely.

	 */

	if (rc != CONFREJ && !ho->neg_addr &&

			wo->req_addr && !reject_if_disagree) {

		IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer address"));

		if (rc == CONFACK) {

			rc = CONFNAK;

			ucp = inp;				/* reset pointer */

			wo->req_addr = 0;		/* don't ask again */

		}

		PUTCHAR(CI_ADDR, ucp);

		PUTCHAR(CILEN_ADDR, ucp);

		tl = ntohl(wo->hisaddr);

		PUTLONG(tl, ucp);

	}

	

	*len = (int)(ucp - inp);		/* Compute output length */

	IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%s", CODENAME(rc)));

	return (rc);			/* Return final code */

}



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

/*

 * ip_check_options - check that any IP-related options are OK,

 * and assign appropriate defaults.

 */

static void ip_check_options(void)

{

	ipcp_options *wo = &ipcp_wantoptions[0];



	/*

	 * Load our default IP address but allow the remote host to give us

	 * a new address.

	 */

	if (wo->ouraddr == 0 && !disable_defaultip) {

		wo->accept_local = 1;	/* don't insist on this default value */

		wo->ouraddr = htonl(localHost);

	}

}



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

/*

 * ipcp_up - IPCP has come UP.

 *

 * Configure the IP network interface appropriately and bring it up.

 */

static void ipcp_up(fsm *f)

{

	u_int32_t mask;

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

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

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

	

	np_up(f->unit, PPP_IP);

	IPCPDEBUG((LOG_INFO, "ipcp: up"));

	

	/*

	 * We must have a non-zero IP address for both ends of the link.

	 */

	if (!ho->neg_addr)

		ho->hisaddr = wo->hisaddr;

	

	if (ho->hisaddr == 0) {

		trace(LOG_ERR, "Could not determine remote IP address");

		ipcp_close(f->unit, "Could not determine remote IP address");

		return;

	}

	if (go->ouraddr == 0) {

		trace(LOG_ERR, "Could not determine local IP address");

		ipcp_close(f->unit, "Could not determine local IP address");

		return;

	}

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

	/*

	 * Check that the peer is allowed to use the IP address it wants.

	 */

	if (!auth_ip_addr(f->unit, ho->hisaddr)) {

		trace(LOG_ERR, "Peer is not authorized to use remote address %s",

				ip_ntoa(ho->hisaddr));

		ipcp_close(f->unit, "Unauthorized remote IP address");

		return;

	}

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

	/* set tcp compression */

	sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);

	

	/*

	 * Set IP addresses and (if specified) netmask.

	 */

	mask = GetMask(go->ouraddr);

	

#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))

	if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {

		IPCPDEBUG((LOG_WARNING, "sifaddr failed"));

		ipcp_close(f->unit, "Interface configuration failed");

		return;

	}

#endif

	

	/* bring the interface up for IP */

	if (!sifup(f->unit)) {

		IPCPDEBUG((LOG_WARNING, "sifup failed"));

		ipcp_close(f->unit, "Interface configuration failed");

		return;

	}

	

#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))

	if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {

		IPCPDEBUG((LOG_WARNING, "sifaddr failed"));

		ipcp_close(f->unit, "Interface configuration failed");

		return;

	}

#endif

	sifnpmode(f->unit, PPP_IP, NPMODE_PASS);

	

	/* assign a default route through the interface if required */

	if (ipcp_wantoptions[f->unit].default_route) 

		if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))

			default_route_set[f->unit] = 1;

	

	trace(LOG_NOTICE, "local  IP address %s", ip_ntoa(go->ouraddr));

	trace(LOG_NOTICE, "remote IP address %s", ip_ntoa(ho->hisaddr));

}



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

/*

 * ipcp_down - IPCP has gone DOWN.

 *

 * Take the IP network interface down, clear its addresses

 * and delete routes through it.

 */

static void ipcp_down(fsm *f)

{

	IPCPDEBUG((LOG_INFO, "ipcp: down"));

	np_down(f->unit, PPP_IP);

	sifvjcomp(f->unit, 0, 0, 0);

	

	sifdown(f->unit);

	ipcp_clear_addrs(f->unit);

}





/*

 * ipcp_clear_addrs() - clear the interface addresses, routes, etc.

 */

static void ipcp_clear_addrs(int unit)

{

	u_int32_t ouraddr, hisaddr;

	

	ouraddr = ipcp_gotoptions[unit].ouraddr;

	hisaddr = ipcp_hisoptions[unit].hisaddr;

	if (default_route_set[unit]) {

		cifdefaultroute(unit, ouraddr, hisaddr);

		default_route_set[unit] = 0;

	}

	cifaddr(unit, ouraddr, hisaddr);

}



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

/*

 * ipcp_finished - possibly shut down the lower layers.

 */

static void ipcp_finished(fsm *f)

{

	np_finished(f->unit, PPP_IP);

}



//#pragma argsused
static int ipcp_printpkt(
	u_char *p,
	int plen,
	void (*printer) __P((void *, char *, ...)),
	void *arg
)
{
	return 0;
}

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

/*

 * ip_active_pkt - see if this IP packet is worth bringing the link up for.

 * We don't bring the link up for IP fragments or for TCP FIN packets

 * with no data.

 */

#define IP_HDRLEN	20	/* bytes */

#define IP_OFFMASK	0x1fff

#define IPPROTO_TCP	6

#define TCP_HDRLEN	20

#define TH_FIN		0x01



/*

 * We use these macros because the IP header may be at an odd address,

 * and some compilers might use word loads to get th_off or ip_hl.

 */



#define net_short(x)	(((x)[0] << 8) + (x)[1])

#define get_iphl(x)	(((unsigned char *)(x))[0] & 0xF)

#define get_ipoff(x)	net_short((unsigned char *)(x) + 6)

#define get_ipproto(x)	(((unsigned char *)(x))[9])

#define get_tcpoff(x)	(((unsigned char *)(x))[12] >> 4)

#define get_tcpflags(x)	(((unsigned char *)(x))[13])



static int ip_active_pkt(u_char *pkt, int len)

{

	u_char *tcp;

	int hlen;

	

	len -= PPP_HDRLEN;

	pkt += PPP_HDRLEN;

	if (len < IP_HDRLEN)

		return 0;

	if ((get_ipoff(pkt) & IP_OFFMASK) != 0)

		return 0;

	if (get_ipproto(pkt) != IPPROTO_TCP)

		return 1;

	hlen = get_iphl(pkt) * 4;

	if (len < hlen + TCP_HDRLEN)

		return 0;

	tcp = pkt + hlen;

	if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)

		return 0;

	return 1;

}

⌨️ 快捷键说明

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