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

📄 tables.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1985, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS OR 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. */#ifndef lintstatic char sccsid[] = "@(#)tables.c	8.1 (Berkeley) 6/5/93";#endif /* not lint *//* * Routing Table Management Daemon */#include "defs.h"#include <sys/ioctl.h>#include <errno.h>#ifndef DEBUG#define	DEBUG	0#endifextern	char *xns_ntoa();#define FIXLEN(s) { if ((s)->sa_len == 0) (s)->sa_len = sizeof (*(s));}int	install = !DEBUG;		/* if 1 call kernel */int	delete = 1;/* * Lookup dst in the tables for an exact match. */struct rt_entry *rtlookup(dst)	struct sockaddr *dst;{	register struct rt_entry *rt;	register struct rthash *rh;	register u_int hash;	struct afhash h;	int doinghost = 1;	if (dst->sa_family >= AF_MAX)		return (0);	(*afswitch[dst->sa_family].af_hash)(dst, &h);	hash = h.afh_hosthash;	rh = &hosthash[hash & ROUTEHASHMASK];again:	for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {		if (rt->rt_hash != hash)			continue;		if (equal(&rt->rt_dst, dst))			return (rt);	}	if (doinghost) {		doinghost = 0;		hash = h.afh_nethash;		rh = &nethash[hash & ROUTEHASHMASK];		goto again;	}	return (0);}/* * Find a route to dst as the kernel would. */struct rt_entry *rtfind(dst)	struct sockaddr *dst;{	register struct rt_entry *rt;	register struct rthash *rh;	register u_int hash;	struct afhash h;	int af = dst->sa_family;	int doinghost = 1, (*match)();	if (af >= AF_MAX)		return (0);	(*afswitch[af].af_hash)(dst, &h);	hash = h.afh_hosthash;	rh = &hosthash[hash & ROUTEHASHMASK];again:	for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {		if (rt->rt_hash != hash)			continue;		if (doinghost) {			if (equal(&rt->rt_dst, dst))				return (rt);		} else {			if (rt->rt_dst.sa_family == af &&			    (*match)(&rt->rt_dst, dst))				return (rt);		}	}	if (doinghost) {		doinghost = 0;		hash = h.afh_nethash;		rh = &nethash[hash & ROUTEHASHMASK];		match = afswitch[af].af_netmatch;		goto again;	}	return (0);}rtadd(dst, gate, metric, state)	struct sockaddr *dst, *gate;	int metric, state;{	struct afhash h;	register struct rt_entry *rt;	struct rthash *rh;	int af = dst->sa_family, flags;	u_int hash;	FIXLEN(dst);	FIXLEN(gate);	if (af >= AF_MAX)		return;	(*afswitch[af].af_hash)(dst, &h);	flags = (*afswitch[af].af_ishost)(dst) ? RTF_HOST : 0;	if (flags & RTF_HOST) {		hash = h.afh_hosthash;		rh = &hosthash[hash & ROUTEHASHMASK];	} else {		hash = h.afh_nethash;		rh = &nethash[hash & ROUTEHASHMASK];	}	rt = (struct rt_entry *)malloc(sizeof (*rt));	if (rt == 0)		return;	rt->rt_hash = hash;	rt->rt_dst = *dst;	rt->rt_router = *gate;	rt->rt_metric = metric;	rt->rt_timer = 0;	rt->rt_flags = RTF_UP | flags;	rt->rt_state = state | RTS_CHANGED;	rt->rt_ifp = if_ifwithnet(&rt->rt_router);	if (metric)		rt->rt_flags |= RTF_GATEWAY;	insque(rt, rh);	TRACE_ACTION(ADD, rt);	/*	 * If the ioctl fails because the gateway is unreachable	 * from this host, discard the entry.  This should only	 * occur because of an incorrect entry in /etc/gateways.	 */	if (install && rtioctl(ADD, &rt->rt_rt) < 0) {		if (errno != EEXIST)			perror("SIOCADDRT");		if (errno == ENETUNREACH) {			TRACE_ACTION(DELETE, rt);			remque(rt);			free((char *)rt);		}	}}rtchange(rt, gate, metric)	struct rt_entry *rt;	struct sockaddr *gate;	short metric;{	int doioctl = 0, metricchanged = 0;	struct rtentry oldroute;	FIXLEN(gate);	if (!equal(&rt->rt_router, gate))		doioctl++;	if (metric != rt->rt_metric)		metricchanged++;	if (doioctl || metricchanged) {		TRACE_ACTION(CHANGE FROM, rt);		if (doioctl) {			oldroute = rt->rt_rt;			rt->rt_router = *gate;		}		rt->rt_metric = metric;		if ((rt->rt_state & RTS_INTERFACE) && metric) {			rt->rt_state &= ~RTS_INTERFACE;			syslog(LOG_ERR,				"changing route from interface %s (timed out)",				rt->rt_ifp->int_name);		}		if (metric)			rt->rt_flags |= RTF_GATEWAY;		else			rt->rt_flags &= ~RTF_GATEWAY;		rt->rt_state |= RTS_CHANGED;		TRACE_ACTION(CHANGE TO, rt);	}	if (doioctl && install) {#ifndef RTM_ADD		if (rtioctl(ADD, &rt->rt_rt) < 0)		  syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m",		   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr),		   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr));		if (delete && rtioctl(DELETE, &oldroute) < 0)			perror("rtioctl DELETE");#else		if (delete == 0) {			if (rtioctl(ADD, &rt->rt_rt) >= 0)				return;		} else {			if (rtioctl(CHANGE, &rt->rt_rt) >= 0)				return;		}	        syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m",		   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr),		   xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr));#endif	}}rtdelete(rt)	struct rt_entry *rt;{	struct sockaddr *sa = &(rt->rt_rt.rt_gateway);	FIXLEN(sa);#undef rt_dst	sa = &(rt->rt_rt.rt_dst);	FIXLEN(sa);	if (rt->rt_state & RTS_INTERFACE) {		syslog(LOG_ERR, "deleting route to interface %s (timed out)",			rt->rt_ifp->int_name);	}	TRACE_ACTION(DELETE, rt);	if (install && rtioctl(DELETE, &rt->rt_rt) < 0)		perror("rtioctl DELETE");	remque(rt);	free((char *)rt);}rtinit(){	register struct rthash *rh;	for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++)		rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;	for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++)		rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;}int seqno;rtioctl(action, ort)	int action;	struct ortentry *ort;{#ifndef RTM_ADD	switch (action) {	case ADD:		return (ioctl(s, SIOCADDRT, (char *)ort));	case DELETE:		return (ioctl(s, SIOCDELRT, (char *)ort));	default:		return (-1);	}#else /* RTM_ADD */	struct {		struct rt_msghdr w_rtm;		struct sockaddr w_dst;		struct sockaddr w_gate;		struct sockaddr_ns w_netmask;	} w;#define rtm w.w_rtm	bzero((char *)&w, sizeof(w));	rtm.rtm_msglen = sizeof(w);	rtm.rtm_version = RTM_VERSION;	rtm.rtm_type = (action == ADD ? RTM_ADD :				(action == DELETE ? RTM_DELETE : RTM_CHANGE));#undef rt_flags	rtm.rtm_flags = ort->rt_flags;	rtm.rtm_seq = ++seqno;	rtm.rtm_addrs = RTA_DST|RTA_GATEWAY;	bcopy((char *)&ort->rt_dst, (char *)&w.w_dst, sizeof(w.w_dst));	bcopy((char *)&ort->rt_gateway, (char *)&w.w_gate, sizeof(w.w_gate));	w.w_gate.sa_family = w.w_dst.sa_family = AF_NS;	w.w_gate.sa_len = w.w_dst.sa_len = sizeof(w.w_dst);	if (rtm.rtm_flags & RTF_HOST) {		rtm.rtm_msglen -= sizeof(w.w_netmask);	} else {		w.w_netmask = ns_netmask;		rtm.rtm_msglen -= 8;	}	errno = 0;	return write(r, (char *)&w, rtm.rtm_msglen);#endif  /* RTM_ADD */}

⌨️ 快捷键说明

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