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

📄 route.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983, 1989 The Regents of the University of California. * All rights reserved. * * %sccs.include.redist.c% */#ifndef lintchar copyright[] ="%Z% Copyright (c) 1983 The Regents of the University of California.\n\ All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "%W% (Berkeley) %G%";#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/kinfo.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;union sockunion *so_addrs[] =	{ &so_dst, &so_gate, &so_mask, &so_genmask, &so_ifp, &so_ifa, 0}; typedef union sockunion *sup;int	pid, rtm_addrs, uid;int	s;int	forcehost, forcenet, doflush, nflag, af, qflag, tflag, Cflag, keyword();int	iflag, verbose, aflen = sizeof (struct sockaddr_in);int	locking, lockrest, debugonly;struct	sockaddr_in sin = { sizeof(sin), AF_INET };struct	rt_metrics rt_metrics;u_long  rtm_inits;struct	in_addr inet_makeaddr();char	*routename(), *netname();void	flushroutes(), newroute(), monitor();void	print_getmsg(), print_rtmsg(), pmsg_common(), sodump(), bprintf();int	getaddr(), rtmsg();extern	char *inet_ntoa(), *iso_ntoa(), *link_ntoa();voidusage(cp)	char *cp;{	if (cp)		(void) fprintf(stderr, "route: botched keyword: %s\n", cp);	(void) fprintf(stderr,	    "usage: route [ -Cnqv ] 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))main(argc, argv)	int argc;	char **argv;{	extern int optind;	int ch;	char *argvp;	if (argc < 2)		usage((char *)NULL);	while ((ch = getopt(argc, argv, "Cnqtv")) != EOF)		switch(ch) {		case 'C':			Cflag = 1;	/* Use old ioctls. */			break;		case 'n':			nflag = 1;			break;		case 'q':			qflag = 1;			break;		case 'v':			verbose = 1;			break;		case 't':			tflag = 1;			break;		case '?':		default:			usage();		}	argc -= optind;	argv += optind;	pid = getpid();	uid = getuid();	if (tflag)		s = open("/dev/null", O_WRONLY, 0);	else if (Cflag)		s = socket(AF_INET, SOCK_RAW, 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:			if (Cflag)				usage("change or get with -C");			/* FALLTHROUGH */		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[];{	int needed, seqno, rlen;	char *buf, *next, *lim;	register struct rt_msghdr *rtm;	if (uid)		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);	}	if ((needed = getkerninfo(KINFO_RT_DUMP, 0, 0, 0)) < 0)		quit("route-getkerninfo-estimate");	if ((buf = malloc(needed)) == NULL)		quit("malloc");	if ((rlen = getkerninfo(KINFO_RT_DUMP, buf, &needed, 0)) < 0)		quit("actual retrieval of routing table");	lim = buf + rlen;	seqno = 0;		/* ??? */	for (next = buf; next < lim; next += rtm->rtm_msglen) {		rtm = (struct rt_msghdr *)next;		if ((rtm->rtm_flags & RTF_GATEWAY) == 0)			continue;		if (af) {			struct sockaddr *sa = (struct sockaddr *)(rtm + 1);			if (sa->sa_family != af)				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;	}	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)			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->sa_data;		u_short *slim = s + ((sa->sa_len + 1) >> 1);		char *cp = line + sprintf(line, "(%d)", sa->sa_family);		while (s < slim)			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;	int key;{	int flag = 0; 	u_long noval, *valp = &noval;	switch (key) {#define caseof(x, y, z)	case x: valp = &rt_metrics.z; flag = y; break	caseof(K_MTU, RTV_MTU, rmx_mtu);	caseof(K_HOPCOUNT, RTV_HOPCOUNT, rmx_hopcount);	caseof(K_EXPIRE, RTV_EXPIRE, rmx_expire);	caseof(K_RECVPIPE, RTV_RPIPE, rmx_recvpipe);	caseof(K_SENDPIPE, RTV_SPIPE, rmx_sendpipe);	caseof(K_SSTHRESH, RTV_SSTHRESH, rmx_ssthresh);	caseof(K_RTT, RTV_RTT, rmx_rtt);	caseof(K_RTTVAR, RTV_RTTVAR, rmx_rttvar);	}	rtm_inits |= flag;	if (lockrest || locking)		rt_metrics.rmx_locks |= flag;	if (locking)		locking = 0;	*valp = atoi(value);}voidnewroute(argc, argv)	int argc;	register char **argv;{	char *cmd, *dest = "", *gateway = "", *err;	int ishost = 0, ret, attempts, oerrno, flags = 0;	int key;	struct hostent *hp = 0;	if (uid)		quit("must be root to alter routing table");	cmd = argv[0];	if (*cmd != 'g')		shutdown(s, 0); /* Don't want to read back our messages */	while (--argc > 0) {		if (**(++argv)== '-') {			switch (key = keyword(1 + *argv)) {			case K_LINK:				af = AF_LINK;				aflen = sizeof(struct sockaddr_dl);				break;			case K_OSI:			case K_ISO:				af = AF_ISO;				aflen = sizeof(struct sockaddr_iso);				break;			case K_INET:				af = AF_INET;				aflen = sizeof(struct sockaddr_in);				break;			case K_X25:				af = AF_CCITT;				aflen = sizeof(struct sockaddr_x25);				break;			case K_SA:				af = 0;				aflen = sizeof(union sockunion);				break;			case K_XNS:				af = AF_NS;				aflen = sizeof(struct sockaddr_ns);				break;			case K_IFACE:			case K_INTERFACE:				iflag++;				break;			case K_LOCK:				locking = 1;				break;			case K_LOCKREST:				lockrest = 1;				break;			case K_HOST:				forcehost++;				break;			case K_REJECT:				flags |= RTF_REJECT;				break;			case K_PROTO1:				flags |= RTF_PROTO1;				break;			case K_PROTO2:				flags |= RTF_PROTO2;				break;			case K_CLONING:				flags |= RTF_CLONING;				break;			case K_XRESOLVE:				flags |= RTF_XRESOLVE;				break;			case K_IFA:				argc--;				(void) getaddr(RTA_IFA, *++argv, 0);				break;			case K_IFP:				argc--;				(void) getaddr(RTA_IFP, *++argv, 0);				break;			case K_GENMASK:				argc--;				(void) getaddr(RTA_GENMASK, *++argv, 0);				break;			case K_GATEWAY:				argc--;				(void) getaddr(RTA_GATEWAY, *++argv, 0);				break;			case K_DST:				argc--;				ishost = getaddr(RTA_DST, *++argv, &hp);				dest = *argv;				break;			case K_NETMASK:				argc--;				(void) getaddr(RTA_NETMASK, *++argv, 0);				/* FALLTHROUGH */			case K_NET:				forcenet++;				break;			case K_MTU:			case K_HOPCOUNT:			case K_EXPIRE:			case K_RECVPIPE:			case K_SENDPIPE:			case K_SSTHRESH:			case K_RTT:			case K_RTTVAR:				argc--;				set_metric(*++argv, key);				break;			default:				usage(1+*argv);			}		} else {			if ((rtm_addrs & RTA_DST) == 0) {				dest = *argv;				ishost = getaddr(RTA_DST, *argv, &hp);			} else if ((rtm_addrs & RTA_GATEWAY) == 0) {				gateway = *argv;				(void) getaddr(RTA_GATEWAY, *argv, &hp);			} else {				int ret = atoi(*argv);				if (ret == 0) {				    printf("%s,%s", "old usage of trailing 0",					   "assuming route to if\n");				    iflag = 1;				    continue;				} else if (ret > 0 && ret < 10) {				    printf("old usage of trailing digit, ");				    printf("assuming route via gateway\n");				    iflag = 0;				    continue;				}				(void) getaddr(RTA_NETMASK, *argv, 0);			}		}

⌨️ 快捷键说明

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