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

📄 route.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	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 (Cflag && (af == AF_INET || af == AF_NS)) {			route.rt_flags = flags;			route.rt_dst = so_dst.sa;			route.rt_gateway = so_gate.sa;			if ((ret = ioctl(s, *cmd == 'a' ? SIOCADDRT : SIOCDELRT,			     (caddr_t)&route)) == 0)				break;		} else {		    if ((ret = rtmsg(*cmd, flags)) == 0)				break;		}		if (errno != ENETUNREACH && errno != ESRCH)			break;		if (af == AF_INET && hp && hp->h_addr_list[1]) {			hp->h_addr_list++;			bcopy(hp->h_addr_list[0], (caddr_t)&so_dst.sin.sin_addr,			    hp->h_length);		} else			break;	}	if (*cmd == 'g')		exit(0);	oerrno = errno;	(void) printf("%s %s %s: gateway %s", cmd, ishost? "host" : "net",		dest, gateway);	if (attempts > 1 && ret == 0)	    (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_addrs[0]; su->sa.sa_family = af; break;	case RTA_GATEWAY:	su = so_addrs[1]; su->sa.sa_family = af; break;	case RTA_NETMASK:	su = so_addrs[2]; break;	case RTA_GENMASK:	su = so_addrs[3]; break;	case RTA_IFP:		su = so_addrs[4]; su->sa.sa_family = af; break;	case RTA_IFA:		su = so_addrs[5]; 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;	}	if (af == AF_NS)		goto do_xns;	if (af == AF_OSI)		goto do_osi;	if (af == AF_LINK)		goto do_link;	if (af == AF_CCITT)		goto do_ccitt;	if (af == 0)		goto do_sa;	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);		out:	if (which == RTA_DST)				inet_makenetandmask(val, &su->sin);			return (0);		}	}	val = inet_network(s);	if (val != -1) {		goto out;	}	np = getnetbyname(s);	if (np) {		val = np->n_net;		goto out;	}	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);do_xns:	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));do_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);do_ccitt:	ccitt_addr(s, &su->sx25);	return (1);do_link:	link_addr(s, &su->sdl);	return (1);do_sa:	su->sa.sa_len = sizeof(*su);	sockaddr(s, &su->sa);	return (1);}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);}voidmonitor(){	int n;	char msg[2048];	verbose = 1;	for(;;) {		n = read(s, msg, 2048);		(void) printf("got message of size %d\n", n);		print_rtmsg((struct rt_msghdr *)msg);	}}struct {	struct	rt_msghdr m_rtm;	char	m_space[512];} m_rtmsg;intrtmsg(cmd, flags)	int cmd, flags;{	static int seq;	int rlen;	register char *cp = m_rtmsg.m_space;	register int l;#define NEXTADDR(w, u) \	if (rtm_addrs & (w)) {\	    l = ROUNDUP(u.sa.sa_len); bcopy((char *)&(u), cp, l); cp += l;\	    if (verbose) sodump(&(u),"u");\	}	errno = 0;	bzero((char *)&m_rtmsg, sizeof(m_rtmsg));	if (cmd == 'a')		cmd = RTM_ADD;	else if (cmd == 'c')		cmd = RTM_CHANGE;	else if (cmd == 'g')		cmd = RTM_GET;	else		cmd = RTM_DELETE;#define rtm m_rtmsg.m_rtm	rtm.rtm_type = cmd;	rtm.rtm_flags = flags;	rtm.rtm_version = RTM_VERSION;	rtm.rtm_seq = ++seq;	rtm.rtm_addrs = rtm_addrs;	rtm.rtm_rmx = rt_metrics;	rtm.rtm_inits = rtm_inits;	if (rtm_addrs & RTA_NETMASK)		mask_addr();	NEXTADDR(RTA_DST, so_dst);	NEXTADDR(RTA_GATEWAY, so_gate);	NEXTADDR(RTA_NETMASK, so_mask);	NEXTADDR(RTA_GENMASK, so_genmask);	NEXTADDR(RTA_IFP, so_ifp);	NEXTADDR(RTA_IFA, so_ifa);	rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;	if (verbose)		print_rtmsg(&rtm, l);	if (debugonly)		return 0;	if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {		perror("writing to routing socket");		return (-1);	}	if (cmd == RTM_GET) {		do {			l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));		} while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));		if (l < 0)			(void) fprintf(stderr,			    "route: read from routing socket: %s\n",			    strerror(errno));		else			print_getmsg(&rtm, l);	}#undef rtm	return (0);}mask_addr() {	register char *cp1, *cp2;	int olen;	if ((rtm_addrs & RTA_DST) == 0)		return;	switch(so_dst.sa.sa_family) {	case AF_NS: case AF_INET: case 0:		return;	case AF_ISO:		olen = MIN(so_dst.siso.siso_nlen, so_mask.sa.sa_len - 6);	}	cp1 = so_mask.sa.sa_len + 1 + (char *)&so_dst;	cp2 = so_dst.sa.sa_len + 1 + (char *)&so_dst;	while (cp2 > cp1)		*--cp2 = 0;	cp2 = so_mask.sa.sa_len + 1 + (char *)&so_mask;	while (cp1 > so_dst.sa.sa_data)		*--cp1 &= *--cp2;	switch(so_dst.sa.sa_family) {	case AF_ISO:		so_dst.siso.siso_nlen = olen;	}}char *msgtypes[] = {	"",	"RTM_ADD: Add Route",	"RTM_DELETE: Delete Route",	"RTM_CHANGE: Change Metrics or flags",	"RTM_GET: Report Metrics",	"RTM_LOSING: Kernel Suspects Partitioning",	"RTM_REDIRECT: Told to use different route",	"RTM_MISS: Lookup failed on this address",	"RTM_LOCK: fix specified metrics",	"RTM_OLDADD: caused by SIOCADDRT",	"RTM_OLDDEL: caused by SIOCDELRT",	0,};char metricnames[] ="\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu";char routeflags[] = "\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\017PROTO2\020PROTO1";voidprint_rtmsg(rtm, msglen)	register struct rt_msghdr *rtm;	int msglen;{	if (verbose == 0)		return;	if (rtm->rtm_version != RTM_VERSION) {		(void) printf("routing message version %d not understood\n",		    rtm->rtm_version);		return;	}	(void) printf("%s\npid: %d, len %d, seq %d, errno %d, flags:",		msgtypes[rtm->rtm_type], rtm->rtm_pid, rtm->rtm_msglen,		rtm->rtm_seq, rtm->rtm_errno); 	bprintf(stdout, rtm->rtm_flags, routeflags);	pmsg_common(rtm);}voidprint_getmsg(rtm, msglen)	register struct rt_msghdr *rtm;	int msglen;{	if (rtm->rtm_version != RTM_VERSION) {		(void)printf("routing message version %d not understood\n",		    rtm->rtm_version);		return;	}	if (rtm->rtm_msglen > msglen) {		(void)printf("get length mismatch, in packet %d, returned %d\n",		    rtm->rtm_msglen, msglen);	}	(void) printf("RTM_GET: errno %d, flags:", rtm->rtm_errno); 	bprintf(stdout, rtm->rtm_flags, routeflags);	(void) printf("\nmetric values:\n  ");#define metric(f, e)\    printf("%s: %d%s", __STRING(f), rtm->rtm_rmx.__CONCAT(rmx_,f), e)	metric(recvpipe, ", ");	metric(sendpipe, ", ");	metric(ssthresh, ", ");	metric(rtt, "\n  ");	metric(rttvar, ", ");	metric(hopcount, ", ");	metric(mtu, ", ");	metric(expire, "\n");#undef metric	pmsg_common(rtm);}voidpmsg_common(rtm)	register struct rt_msghdr *rtm;{	char *cp;	register struct sockaddr *sa;	int i;	(void) printf("\nlocks: ");	bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);	(void) printf(" inits: ");	bprintf(stdout, rtm->rtm_inits, metricnames);	(void) printf("\nsockaddrs: ");	bprintf(stdout, rtm->rtm_addrs,	    "\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR");	(void) putchar('\n');	cp = ((char *)(rtm + 1));	if (rtm->rtm_addrs)		for (i = 1; i; i <<= 1)			if (i & rtm->rtm_addrs) {				sa = (struct sockaddr *)cp;				(void) printf(" %s", routename(sa));				ADVANCE(cp, sa);			}	(void) putchar('\n');	(void) fflush(stdout);}voidbprintf(fp, b, s)	register FILE *fp;	register int b;	register u_char *s;{	register int i;	int gotsome = 0;	if (b == 0)		return;	while (i = *s++) {		if (b & (1 << (i-1))) {			if (gotsome == 0)				i = '<';			else				i = ',';			(void) putc(i, fp);			gotsome = 1;			for (; (i = *s) > 32; s++)				(void) putc(i, fp);		} else			while (*s > 32)				s++;	}	if (gotsome)		(void) putc('>', fp);}intkeyword(cp)	char *cp;{	register struct keytab *kt = keywords;	while (kt->kt_cp && strcmp(kt->kt_cp, cp))		kt++;	return kt->kt_i;}voidsodump(su, which)	register sup su;	char *which;{	switch (su->sa.sa_family) {	case AF_LINK:		(void) printf("%s: link %s; ",		    which, link_ntoa(&su->sdl));		break;	case AF_ISO:		(void) printf("%s: iso %s; ",		    which, iso_ntoa(&su->siso.siso_addr));		break;	case AF_INET:		(void) printf("%s: inet %s; ",		    which, inet_ntoa(su->sin.sin_addr));		break;	case AF_NS:		(void) printf("%s: xns %s; ",		    which, ns_ntoa(su->sns.sns_addr));		break;	}	(void) fflush(stdout);}/* States*/#define VIRGIN	0#define GOTONE	1#define GOTTWO	2/* Inputs */#define	DIGIT	(4*0)#define	END	(4*1)#define DELIM	(4*2)voidsockaddr(addr, sa)register char *addr;register struct sockaddr *sa;{	register char *cp = (char *)sa;	int size = sa->sa_len;	char *cplim = cp + size;	register int byte = 0, state = VIRGIN, new;	bzero(cp, size);	do {		if ((*addr >= '0') && (*addr <= '9')) {			new = *addr - '0';		} else if ((*addr >= 'a') && (*addr <= 'f')) {			new = *addr - 'a' + 10;		} else if ((*addr >= 'A') && (*addr <= 'F')) {			new = *addr - 'A' + 10;		} else if (*addr == 0) 			state |= END;		else			state |= DELIM;		addr++;		switch (state /* | INPUT */) {		case GOTTWO | DIGIT:			*cp++ = byte; /*FALLTHROUGH*/		case VIRGIN | DIGIT:			state = GOTONE; byte = new; continue;		case GOTONE | DIGIT:			state = GOTTWO; byte = new + (byte << 4); continue;		default: /* | DELIM */			state = VIRGIN; *cp++ = byte; byte = 0; continue;		case GOTONE | END:		case GOTTWO | END:			*cp++ = byte; /* FALLTHROUGH */		case VIRGIN | END:			break;		}		break;	} while (cp < cplim); 	sa->sa_len = cp - (char *)sa;}

⌨️ 快捷键说明

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