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

📄 route.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * * Copyright (c) 1983, 1989, 1991, 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 copyright[] ="@(#) Copyright (c) 1983, 1989, 1991, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)route.c	8.3 (Berkeley) 3/19/94";#endif /* not lint */#include <sys/param.h>#include <sys/file.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/mbuf.h>#include <sys/sysctl.h>#include <net/if.h>#include <net/route.h>#include <net/if_dl.h>#include <netinet/in.h>#include <netns/ns.h>#include <netiso/iso.h>#include <netccitt/x25.h>#include <arpa/inet.h>#include <netdb.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <paths.h>struct keytab {	char	*kt_cp;	int	kt_i;} keywords[] = {#include "keywords.h"	{0, 0}};struct	ortentry route;union	sockunion {	struct	sockaddr sa;	struct	sockaddr_in sin;	struct	sockaddr_ns sns;	struct	sockaddr_iso siso;	struct	sockaddr_dl sdl;	struct	sockaddr_x25 sx25;} so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp;typedef union sockunion *sup;int	pid, rtm_addrs, uid;int	s;int	forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword();int	iflag, verbose, aflen = sizeof (struct sockaddr_in);int	locking, lockrest, debugonly;struct	rt_metrics rt_metrics;u_long  rtm_inits;struct	in_addr inet_makeaddr();char	*routename(), *netname();void	flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();void	print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();int	getaddr(), rtmsg(), x25_makemask();extern	char *inet_ntoa(), *iso_ntoa(), *link_ntoa();__dead voidusage(cp)	char *cp;{	if (cp)		(void) fprintf(stderr, "route: botched keyword: %s\n", cp);	(void) fprintf(stderr,	    "usage: route [ -nqv ] cmd [[ -<qualifers> ] args ]\n");	exit(1);	/* NOTREACHED */}voidquit(s)	char *s;{	int sverrno = errno;	(void) fprintf(stderr, "route: ");	if (s)		(void) fprintf(stderr, "%s: ", s);	(void) fprintf(stderr, "%s\n", strerror(sverrno));	exit(1);	/* NOTREACHED */}#define ROUNDUP(a) \	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))intmain(argc, argv)	int argc;	char **argv;{	extern int optind;	int ch;	if (argc < 2)		usage((char *)NULL);	while ((ch = getopt(argc, argv, "nqdtv")) != EOF)		switch(ch) {		case 'n':			nflag = 1;			break;		case 'q':			qflag = 1;			break;		case 'v':			verbose = 1;			break;		case 't':			tflag = 1;			break;		case 'd':			debugonly = 1;			break;		case '?':		default:			usage((char *)NULL);		}	argc -= optind;	argv += optind;	pid = getpid();	uid = getuid();	if (tflag)		s = open("/dev/null", O_WRONLY, 0);	else		s = socket(PF_ROUTE, SOCK_RAW, 0);	if (s < 0)		quit("socket");	if (*argv)		switch (keyword(*argv)) {		case K_GET:			uid = 0;			/* FALLTHROUGH */		case K_CHANGE:		case K_ADD:		case K_DELETE:			newroute(argc, argv);			exit(0);			/* NOTREACHED */		case K_MONITOR:			monitor();			/* NOTREACHED */		case K_FLUSH:			flushroutes(argc, argv);			exit(0);			/* NOTREACHED */		}	usage(*argv);	/* NOTREACHED */}/* * Purge all entries in the routing tables not * associated with network interfaces. */voidflushroutes(argc, argv)	int argc;	char *argv[];{	size_t needed;	int mib[6], rlen, seqno;	char *buf, *next, *lim;	register struct rt_msghdr *rtm;	if (uid) {		errno = EACCES;		quit("must be root to alter routing table");	}	shutdown(s, 0); /* Don't want to read back our messages */	if (argc > 1) {		argv++;		if (argc == 2 && **argv == '-')		    switch (keyword(*argv + 1)) {			case K_INET:				af = AF_INET;				break;			case K_XNS:				af = AF_NS;				break;			case K_LINK:				af = AF_LINK;				break;			case K_ISO:			case K_OSI:				af = AF_ISO;				break;			case K_X25:				af = AF_CCITT;			default:				goto bad;		} elsebad:			usage(*argv);	}	mib[0] = CTL_NET;	mib[1] = PF_ROUTE;	mib[2] = 0;		/* protocol */	mib[3] = 0;		/* wildcard address family */	mib[4] = NET_RT_DUMP;	mib[5] = 0;		/* no flags */	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)		quit("route-sysctl-estimate");	if ((buf = malloc(needed)) == NULL)		quit("malloc");	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)		quit("actual retrieval of routing table");	lim = buf + needed;	if (verbose)		(void) printf("Examining routing table from sysctl\n");	seqno = 0;		/* ??? */	for (next = buf; next < lim; next += rtm->rtm_msglen) {		rtm = (struct rt_msghdr *)next;		if (verbose)			print_rtmsg(rtm, rtm->rtm_msglen);		if ((rtm->rtm_flags & RTF_GATEWAY) == 0)			continue;		if (af) {			struct sockaddr *sa = (struct sockaddr *)(rtm + 1);			if (sa->sa_family != af)				continue;		}		if (debugonly)			continue;		rtm->rtm_type = RTM_DELETE;		rtm->rtm_seq = seqno;		rlen = write(s, next, rtm->rtm_msglen);		if (rlen < (int)rtm->rtm_msglen) {			(void) fprintf(stderr,			    "route: write to routing socket: %s\n",			    strerror(errno));			(void) printf("got only %d for rlen\n", rlen);			break;		}		seqno++;		if (qflag)			continue;		if (verbose)			print_rtmsg(rtm, rlen);		else {			struct sockaddr *sa = (struct sockaddr *)(rtm + 1);			(void) printf("%-20.20s ", rtm->rtm_flags & RTF_HOST ?			    routename(sa) : netname(sa));			sa = (struct sockaddr *)(sa->sa_len + (char *)sa);			(void) printf("%-20.20s ", routename(sa));			(void) printf("done\n");		}	}}char *routename(sa)	struct sockaddr *sa;{	register char *cp;	static char line[50];	struct hostent *hp;	static char domain[MAXHOSTNAMELEN + 1];	static int first = 1;	char *ns_print();	if (first) {		first = 0;		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&		    (cp = index(domain, '.')))			(void) strcpy(domain, cp + 1);		else			domain[0] = 0;	}	if (sa->sa_len == 0)		strcpy(line, "default");	else switch (sa->sa_family) {	case AF_INET:	    {	struct in_addr in;		in = ((struct sockaddr_in *)sa)->sin_addr;		cp = 0;		if (in.s_addr == INADDR_ANY || sa->sa_len < 4)			cp = "default";		if (cp == 0 && !nflag) {			hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),				AF_INET);			if (hp) {				if ((cp = index(hp->h_name, '.')) &&				    !strcmp(cp + 1, domain))					*cp = 0;				cp = hp->h_name;			}		}		if (cp)			strcpy(line, cp);		else {#define C(x)	((x) & 0xff)			in.s_addr = ntohl(in.s_addr);			(void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),			   C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));		}		break;	    }	case AF_NS:		return (ns_print((struct sockaddr_ns *)sa));	case AF_LINK:		return (link_ntoa((struct sockaddr_dl *)sa));	case AF_ISO:		(void) sprintf(line, "iso %s",		    iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));		break;	default:	    {	u_short *s = (u_short *)sa;		u_short *slim = s + ((sa->sa_len + 1) >> 1);		char *cp = line + sprintf(line, "(%d)", sa->sa_family);		while (++s < slim) /* start with sa->sa_data */			cp += sprintf(cp, " %x", *s);		break;	    }	}	return (line);}/* * Return the name of the network whose address is given. * The address is assumed to be that of a net or subnet, not a host. */char *netname(sa)	struct sockaddr *sa;{	char *cp = 0;	static char line[50];	struct netent *np = 0;	u_long net, mask;	register u_long i;	int subnetshift;	char *ns_print();	switch (sa->sa_family) {	case AF_INET:	    {	struct in_addr in;		in = ((struct sockaddr_in *)sa)->sin_addr;		i = in.s_addr = ntohl(in.s_addr);		if (in.s_addr == 0)			cp = "default";		else if (!nflag) {			if (IN_CLASSA(i)) {				mask = IN_CLASSA_NET;				subnetshift = 8;			} else if (IN_CLASSB(i)) {				mask = IN_CLASSB_NET;				subnetshift = 8;			} else {				mask = IN_CLASSC_NET;				subnetshift = 4;			}			/*			 * If there are more bits than the standard mask			 * would suggest, subnets must be in use.			 * Guess at the subnet mask, assuming reasonable			 * width subnet fields.			 */			while (in.s_addr &~ mask)				mask = (long)mask >> subnetshift;			net = in.s_addr & mask;			while ((mask & 1) == 0)				mask >>= 1, net >>= 1;			np = getnetbyaddr(net, AF_INET);			if (np)				cp = np->n_name;		}		if (cp)			strcpy(line, cp);		else if ((in.s_addr & 0xffffff) == 0)			(void) sprintf(line, "%u", C(in.s_addr >> 24));		else if ((in.s_addr & 0xffff) == 0)			(void) sprintf(line, "%u.%u", C(in.s_addr >> 24),			    C(in.s_addr >> 16));		else if ((in.s_addr & 0xff) == 0)			(void) sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),			    C(in.s_addr >> 16), C(in.s_addr >> 8));		else			(void) sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),			    C(in.s_addr >> 16), C(in.s_addr >> 8),			    C(in.s_addr));		break;	    }	case AF_NS:		return (ns_print((struct sockaddr_ns *)sa));		break;	case AF_LINK:		return (link_ntoa((struct sockaddr_dl *)sa));	case AF_ISO:		(void) sprintf(line, "iso %s",		    iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));		break;	default:	    {	u_short *s = (u_short *)sa->sa_data;		u_short *slim = s + ((sa->sa_len + 1)>>1);		char *cp = line + sprintf(line, "af %d:", sa->sa_family);		while (s < slim)			cp += sprintf(cp, " %x", *s++);		break;	    }	}	return (line);}voidset_metric(value, key)	char *value;

⌨️ 快捷键说明

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