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

📄 route.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 = RTF_STATIC;	int key;	struct hostent *hp = 0;	if (uid) {		errno = EACCES;		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 = PF_ROUTE;				aflen = sizeof(union sockunion);				break;			case K_XNS:				af = AF_NS;				aflen = sizeof(struct sockaddr_ns);				break;			case K_IFACE:			case K_INTERFACE:				iflag++;			case K_NOSTATIC:				flags &= ~RTF_STATIC;				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_BLACKHOLE:				flags |= RTF_BLACKHOLE;				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_STATIC:				flags |= RTF_STATIC;				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) {				    if (strcmp(*argv, "0") == 0)				        printf("%s,%s",					    "old usage of trailing 0",					    "assuming route to if\n");				    else					usage((char *)NULL);				    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);			}		}	}	if (forcehost)		ishost = 1;	if (forcenet)		ishost = 0;	flags |= RTF_UP;	if (ishost)		flags |= RTF_HOST;	if (iflag == 0)		flags |= RTF_GATEWAY;	for (attempts = 1; ; attempts++) {		errno = 0;		if ((ret = rtmsg(*cmd, flags)) == 0)			break;		if (errno != ENETUNREACH && errno != ESRCH)			break;		if (af == AF_INET && *gateway && hp && hp->h_addr_list[1]) {			hp->h_addr_list++;			bcopy(hp->h_addr_list[0], &so_gate.sin.sin_addr,			    hp->h_length);		} else			break;	}	if (*cmd == 'g')		exit(0);	oerrno = errno;	(void) printf("%s %s %s", cmd, ishost? "host" : "net", dest);	if (*gateway) {		(void) printf(": gateway %s", gateway);		if (attempts > 1 && ret == 0 && af == AF_INET)		    (void) printf(" (%s)",			inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));	}	if (ret == 0)		(void) printf("\n");	else {		switch (oerrno) {		case ESRCH:			err = "not in table";			break;		case EBUSY:			err = "entry in use";			break;		case ENOBUFS:			err = "routing table overflow";			break;		default:			err = strerror(oerrno);			break;		}		(void) printf(": %s\n", err);	}}voidinet_makenetandmask(net, sin)	u_long net;	register struct sockaddr_in *sin;{	u_long addr, mask = 0;	register char *cp;	rtm_addrs |= RTA_NETMASK;	if (net == 0)		mask = addr = 0;	else if (net < 128) {		addr = net << IN_CLASSA_NSHIFT;		mask = IN_CLASSA_NET;	} else if (net < 65536) {		addr = net << IN_CLASSB_NSHIFT;		mask = IN_CLASSB_NET;	} else if (net < 16777216L) {		addr = net << IN_CLASSC_NSHIFT;		mask = IN_CLASSC_NET;	} else {		addr = net;		if ((addr & IN_CLASSA_HOST) == 0)			mask =  IN_CLASSA_NET;		else if ((addr & IN_CLASSB_HOST) == 0)			mask =  IN_CLASSB_NET;		else if ((addr & IN_CLASSC_HOST) == 0)			mask =  IN_CLASSC_NET;		else			mask = -1;	}	sin->sin_addr.s_addr = htonl(addr);	sin = &so_mask.sin;	sin->sin_addr.s_addr = htonl(mask);	sin->sin_len = 0;	sin->sin_family = 0;	cp = (char *)(&sin->sin_addr + 1);	while (*--cp == 0 && cp > (char *)sin)		;	sin->sin_len = 1 + cp - (char *)sin;}/* * Interpret an argument as a network address of some kind, * returning 1 if a host address, 0 if a network address. */intgetaddr(which, s, hpp)	int which;	char *s;	struct hostent **hpp;{	register sup su;	struct ns_addr ns_addr();	struct iso_addr *iso_addr();	struct hostent *hp;	struct netent *np;	u_long val;	if (af == 0) {		af = AF_INET;		aflen = sizeof(struct sockaddr_in);	}	rtm_addrs |= which;	switch (which) {	case RTA_DST:		su = &so_dst;		su->sa.sa_family = af;		break;	case RTA_GATEWAY:		su = &so_gate;		su->sa.sa_family = af;		break;	case RTA_NETMASK:		su = &so_mask;		break;	case RTA_GENMASK:		su = &so_genmask;		break;	case RTA_IFP:		su = &so_ifp;		su->sa.sa_family = af;		break;	case RTA_IFA:		su = &so_ifa;		su->sa.sa_family = af;		break;	default:		usage("Internal Error");		/*NOTREACHED*/	}	su->sa.sa_len = aflen;	if (strcmp(s, "default") == 0) {		switch (which) {		case RTA_DST:			forcenet++;			(void) getaddr(RTA_NETMASK, s, 0);			break;		case RTA_NETMASK:		case RTA_GENMASK:			su->sa.sa_len = 0;		}		return (0);	}	switch (af) {	case AF_NS:		if (which == RTA_DST) {			extern short ns_bh[3];			struct sockaddr_ns *sms = &(so_mask.sns);			bzero((char *)sms, sizeof(*sms));			sms->sns_family = 0;			sms->sns_len = 6;			sms->sns_addr.x_net = *(union ns_net *)ns_bh;			rtm_addrs |= RTA_NETMASK;		}		su->sns.sns_addr = ns_addr(s);		return (!ns_nullhost(su->sns.sns_addr));	case AF_OSI:		su->siso.siso_addr = *iso_addr(s);		if (which == RTA_NETMASK || which == RTA_GENMASK) {			register char *cp = (char *)TSEL(&su->siso);			su->siso.siso_nlen = 0;			do {--cp ;} while ((cp > (char *)su) && (*cp == 0));			su->siso.siso_len = 1 + cp - (char *)su;		}		return (1);	case AF_LINK:		link_addr(s, &su->sdl);		return (1);	case AF_CCITT:		ccitt_addr(s, &su->sx25);		return (which == RTA_DST ? x25_makemask() : 1);	case PF_ROUTE:		su->sa.sa_len = sizeof(*su);		sockaddr(s, &su->sa);		return (1);	case AF_INET:	default:		break;	}	if (hpp == NULL)		hpp = &hp;	*hpp = NULL;	if (((val = inet_addr(s)) != -1) &&	    (which != RTA_DST || forcenet == 0)) {		su->sin.sin_addr.s_addr = val;		if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY)			return (1);		else {			val = ntohl(val);			goto netdone;		}	}	if ((val = inet_network(s)) != -1 ||	    ((np = getnetbyname(s)) != NULL && (val = np->n_net) != 0)) {netdone:		if (which == RTA_DST)			inet_makenetandmask(val, &su->sin);		return (0);	}	hp = gethostbyname(s);	if (hp) {		*hpp = hp;		su->sin.sin_family = hp->h_addrtype;		bcopy(hp->h_addr, (char *)&su->sin.sin_addr, hp->h_length);		return (1);	}	(void) fprintf(stderr, "%s: bad value\n", s);	exit(1);}intx25_makemask(){	register char *cp;	if ((rtm_addrs & RTA_NETMASK) == 0) {		rtm_addrs |= RTA_NETMASK;		for (cp = (char *)&so_mask.sx25.x25_net;		     cp < &so_mask.sx25.x25_opts.op_flags; cp++)			*cp = -1;		so_mask.sx25.x25_len = (u_char)&(((sup)0)->sx25.x25_opts);	}	return 0;}short ns_nullh[] = {0,0,0};short ns_bh[] = {-1,-1,-1};char *ns_print(sns)	struct sockaddr_ns *sns;{	struct ns_addr work;	union { union ns_net net_e; u_long long_e; } net;	u_short port;	static char mybuf[50], cport[10], chost[25];	char *host = "";	register char *p;	register u_char *q;	work = sns->sns_addr;	port = ntohs(work.x_port);	work.x_port = 0;	net.net_e  = work.x_net;	if (ns_nullhost(work) && net.long_e == 0) {		if (!port)			return ("*.*");		(void) sprintf(mybuf, "*.%XH", port);		return (mybuf);	}	if (bcmp((char *)ns_bh, (char *)work.x_host.c_host, 6) == 0)		host = "any";	else if (bcmp((char *)ns_nullh, (char *)work.x_host.c_host, 6) == 0)		host = "*";	else {		q = work.x_host.c_host;		(void) sprintf(chost, "%02X%02X%02X%02X%02X%02XH",			q[0], q[1], q[2], q[3], q[4], q[5]);		for (p = chost; *p == '0' && p < chost + 12; p++)			/* void */;		host = p;	}	if (port)		(void) sprintf(cport, ".%XH", htons(port));	else		*cport = 0;	(void) sprintf(mybuf,"%XH.%s%s", ntohl(net.long_e), host, cport);	return (mybuf);}voidinterfaces(){	size_t needed;

⌨️ 快捷键说明

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