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

📄 input.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic	char	*sccsid = "@(#)input.c	4.4		(ULTRIX)	10/15/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984,1988 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. *//* *  12 June 90 - Peter Grehan, TaN, Sydney, Australia *           Changed input response processing to take into account the *      fact that an input packet contains a portid field *//*#ifndef lintstatic char sccsid[] = "@(#)input.c	4.2 (Berkeley) 10/10/90";#endif not lint*//* * Routing Table Management Daemon */#include "defs.h"#include <syslog.h>/* * Process a newly received packet. */rip_input(from, size)	struct sockaddr *from;	int size;{	register struct rt_entry *rt;	register struct netinfo *n;	register struct interface *ifp;	struct interface *if_ifwithdstaddr();	int newsize;	register struct afswitch *afp;	static struct sockaddr badfrom;	static struct sockaddr temp;	struct sockaddr *which;	ifp = 0;	TRACE_INPUT(ifp, from, size);	if (from->sa_family >= af_max ||	    (afp = &afswitch[from->sa_family])->af_hash == (int (*)())0) {		syslog(LOG_INFO,	 "\"from\" address in unsupported address family (%d), cmd %d\n",		    from->sa_family, msg->rip_cmd);		return;	}	switch (msg->rip_cmd) {	case RIPCMD_REQUEST:		newsize = 0;		size -= 4 * sizeof (char);		n = msg->rip_nets;		while (size > 0) {			if (size < sizeof (struct netinfo))				break;			size -= sizeof (struct netinfo);			if (msg->rip_vers > 0) {				n->rip_dst.sa_family =					ntohs(n->rip_dst.sa_family);				n->rip_metric = ntohl(n->rip_metric);			}			/* 			 * A single entry with sa_family == AF_UNSPEC and			 * metric ``infinity'' means ``all routes''.			 * We respond to routers only if we are acting			 * as a supplier, or to anyone other than a router			 * (eg, query).			 */			if (n->rip_dst.sa_family == AF_UNSPEC &&			    n->rip_metric == HOPCNT_INFINITY && size == 0) {			    	if (supplier || (*afp->af_portmatch)(from) == 0)					supply(from, 0, 0);				return;			}			if (n->rip_dst.sa_family < af_max &&			    afswitch[n->rip_dst.sa_family].af_hash)				rt = rtlookup(&n->rip_dst);			else				rt = 0;			n->rip_metric = rt == 0 ? HOPCNT_INFINITY :				min(rt->rt_metric + 1, HOPCNT_INFINITY);			if (msg->rip_vers > 0) {				n->rip_dst.sa_family =					htons(n->rip_dst.sa_family);				n->rip_metric = htonl(n->rip_metric);			}			n++, newsize += sizeof (struct netinfo);		}		if (newsize > 0) {			msg->rip_cmd = RIPCMD_RESPONSE;			newsize += sizeof (int);			(*afp->af_output)(s, 0, from, newsize);		}		return;	case RIPCMD_TRACEON:	case RIPCMD_TRACEOFF:		/* verify message came from a privileged port */		if ((*afp->af_portcheck)(from) == 0)			return;		if ((ifp = if_iflookup(from)) == 0 || (ifp->int_flags &		    (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0 ||		    ifp->int_flags & IFF_PASSIVE) {			syslog(LOG_ERR, "trace command from unknown router, %s",			    (*afswitch[from->sa_family].af_format)(from));			return;		}		packet[size] = '\0';		if (msg->rip_cmd == RIPCMD_TRACEON)			traceon(msg->rip_tracefile);		else			traceoff();		return;	case RIPCMD_RESPONSE:		/* verify message came from a router */		if ((*afp->af_portmatch)(from) == 0)			return;		(*afp->af_canon)(from);		/* are we talking to ourselves? */		ifp = if_ifwithaddr(from);		if (ifp) {			rt = rtfind(from);			if (rt == 0 || ((rt->rt_state & RTS_INTERFACE) == 0) &&			    rt->rt_metric >= ifp->int_metric) 				addrouteforif(ifp);			else				rt->rt_timer = 0;			return;		}		/*		 * Update timer for interface on which the packet arrived.		 * If from other end of a point-to-point link that isn't		 * in the routing tables, (re-)add the route.		 */                if(ifp = if_ifwithdstaddr(from))		  {			bcopy((caddr_t) &ifp->int_dstaddr,				(caddr_t) &temp, sizeof(struct sockaddr));			which = &temp;		  }		else		  {			which = from;		  }		if ((rt = rtfind(which)) &&		    (rt->rt_state & (RTS_INTERFACE | RTS_REMOTE)))			rt->rt_timer = 0;		else if ((ifp = if_ifwithdstaddr(from)) &&		    (rt == 0 || rt->rt_metric >= ifp->int_metric))			addrouteforif(ifp);		/*		 * "Authenticate" router from which message originated.		 * We accept routing packets from routers directly connected		 * via broadcast or point-to-point networks,		 * and from those listed in /etc/gateways.		 */		if ((ifp = if_iflookup(from)) == 0 || (ifp->int_flags &		    (IFF_BROADCAST | IFF_POINTOPOINT | IFF_REMOTE)) == 0 ||		    ifp->int_flags & IFF_PASSIVE) {#ifndef 43BSD	/* Call init routine in case an interface just became real */	/* Force initialization in case we are now a supplier */			if(supplier == 0)				supplier = -1;			ifinit();#endif			if (bcmp((char *)from, (char *)&badfrom,			    sizeof(badfrom)) != 0) {				syslog(LOG_ERR,				  "packet from unknown router, %s",				  (*afswitch[from->sa_family].af_format)(from));				badfrom = *from;			}			return;		}		size -= 4 * sizeof (char);		n = msg->rip_nets;		for (; size > 0; size -= sizeof (struct netinfo), n++) {			if (size < sizeof (struct netinfo))				break;			if (msg->rip_vers > 0) {				n->rip_dst.sa_family =					ntohs(n->rip_dst.sa_family);				n->rip_metric = ntohl(n->rip_metric);			}			if (n->rip_dst.sa_family >= af_max ||			    (afp = &afswitch[n->rip_dst.sa_family])->af_hash ==			    (int (*)())0) {				syslog(LOG_INFO,		"route in unsupported address family (%d), from %s (af %d)\n",				   n->rip_dst.sa_family,				   (*afswitch[from->sa_family].af_format)(from),				   from->sa_family);				continue;			}			if (((*afp->af_checkhost)(&n->rip_dst)) == 0) {				syslog(LOG_DEBUG,				    "bad host in route from %s (af %d)\n",				   (*afswitch[from->sa_family].af_format)(from),				   from->sa_family);				continue;			}			/*			 * Adjust metric according to incoming interface.			 */			if ((unsigned) n->rip_metric < HOPCNT_INFINITY)				n->rip_metric += ifp->int_metric;			if ((unsigned) n->rip_metric > HOPCNT_INFINITY)				n->rip_metric = HOPCNT_INFINITY;			rt = rtlookup(&n->rip_dst);			if (rt == 0 ||			    (rt->rt_state & (RTS_INTERNAL|RTS_INTERFACE)) ==			    (RTS_INTERNAL|RTS_INTERFACE)) {				/*				 * If we're hearing a logical network route				 * back from a peer to which we sent it,				 * ignore it.				 */				if (rt && rt->rt_state & RTS_SUBNET &&				    (*afp->af_sendroute)(rt, from))					continue;				/*				 * Look for an equivalent route that includes				 * this one before adding this route.				 */				rt = rtfind(&n->rip_dst);				if (rt && equal(from, &rt->rt_router))					continue;				if (n->rip_metric < HOPCNT_INFINITY)				    rtadd(&n->rip_dst, from, n->rip_metric, 0);				continue;			}			/*			 * Update if from gateway and different,			 * shorter, or getting stale and equivalent.			 */		if(rt->rt_flags & RTF_GATEWAY) {			if (equal(from, &rt->rt_router)) {				if (n->rip_metric != rt->rt_metric) {					rtchange(rt, from, n->rip_metric);					if (rt->rt_metric >= HOPCNT_INFINITY)						rt->rt_timer =						    GARBAGE_TIME - EXPIRE_TIME;				} else if (rt->rt_metric < HOPCNT_INFINITY)					rt->rt_timer = 0;			} else if ((unsigned) n->rip_metric < rt->rt_metric ||			    (rt->rt_timer > (EXPIRE_TIME/2) &&			    rt->rt_metric == n->rip_metric &&			    (unsigned) n->rip_metric < HOPCNT_INFINITY)) {				rtchange(rt, from, n->rip_metric);				rt->rt_timer = 0;			}		}		}		return;	}}

⌨️ 快捷键说明

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