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

📄 route.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	int mib[6];	char *buf, *lim, *next;	register struct rt_msghdr *rtm;	mib[0] = CTL_NET;	mib[1] = PF_ROUTE;	mib[2] = 0;		/* protocol */	mib[3] = 0;		/* wildcard address family */	mib[4] = NET_RT_IFLIST;	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 interface table");	lim = buf + needed;	for (next = buf; next < lim; next += rtm->rtm_msglen) {		rtm = (struct rt_msghdr *)next;		print_rtmsg(rtm, rtm->rtm_msglen);	}}voidmonitor(){	int n;	char msg[2048];	verbose = 1;	if (debugonly) {		interfaces();		exit(0);	}	for(;;) {		n = read(s, msg, 2048);		(void) printf("got message of size %d\n", n);		print_rtmsg((struct rt_msghdr *)msg, n);	}}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;		if (so_ifp.sa.sa_family == 0) {			so_ifp.sa.sa_family == AF_LINK;			so_ifp.sa.sa_len == sizeof(struct sockaddr_dl);			rtm_addrs |= RTA_IFP;		}	} 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);}voidmask_addr(){	int olen = so_mask.sa.sa_len;	register char *cp1 = olen + (char *)&so_mask, *cp2;	for (so_mask.sa.sa_len = 0; cp1 > (char *)&so_mask; )		if (*--cp1 != 0) {			so_mask.sa.sa_len = 1 + cp1 - (char *)&so_mask;			break;		}	if ((rtm_addrs & RTA_DST) == 0)		return;	switch (so_dst.sa.sa_family) {	case AF_NS:	case AF_INET:	case AF_CCITT:	case 0:		return;	case AF_ISO:		olen = MIN(so_dst.siso.siso_nlen,			   MAX(so_mask.sa.sa_len - 6, 0));		break;	}	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;		break;	}}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",	"RTM_RESOLVE: Route created by cloning",	"RTM_NEWADDR: address being added to iface",	"RTM_DELADDR: address being removed from iface",	"RTM_IFINFO: iface status change",	0,};char metricnames[] ="\011pksent\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu";char routeflags[] ="\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE\013LLINFO\014STATIC\017PROTO2\020PROTO1";char ifnetflags[] ="\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6NOTRAILERS\7RUNNING\010NOARP\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1\017LINK2\020MULTICAST";char addrnames[] ="\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR\010BRD";voidprint_rtmsg(rtm, msglen)	register struct rt_msghdr *rtm;	int msglen;{	struct if_msghdr *ifm;	struct ifa_msghdr *ifam;	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: len %d, ", msgtypes[rtm->rtm_type], rtm->rtm_msglen);	switch (rtm->rtm_type) {	case RTM_IFINFO:		ifm = (struct if_msghdr *)rtm;		(void) printf("if# %d, flags:", ifm->ifm_index);		bprintf(stdout, ifm->ifm_flags, ifnetflags);		pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs);		break;	case RTM_NEWADDR:	case RTM_DELADDR:		ifam = (struct ifa_msghdr *)rtm;		(void) printf("metric %d, flags:", ifam->ifam_metric);		bprintf(stdout, ifam->ifam_flags, routeflags);		pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs);		break;	default:		(void) printf("pid: %d, seq %d, errno %d, flags:",			rtm->rtm_pid, 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;{	struct sockaddr *dst = NULL, *gate = NULL, *mask = NULL;	struct sockaddr_dl *ifp = NULL;	register struct sockaddr *sa;	register char *cp;	register int i;	(void) printf("   route to: %s\n", routename(&so_dst));	if (rtm->rtm_version != RTM_VERSION) {		(void)fprintf(stderr,		    "routing message version %d not understood\n",		    rtm->rtm_version);		return;	}	if (rtm->rtm_msglen > msglen) {		(void)fprintf(stderr,		    "message length mismatch, in packet %d, returned %d\n",		    rtm->rtm_msglen, msglen);	}	if (rtm->rtm_errno)  {		(void) fprintf(stderr, "RTM_GET: %s (errno %d)\n",		    strerror(rtm->rtm_errno), rtm->rtm_errno);		return;	}	cp = ((char *)(rtm + 1));	if (rtm->rtm_addrs)		for (i = 1; i; i <<= 1)			if (i & rtm->rtm_addrs) {				sa = (struct sockaddr *)cp;				switch (i) {				case RTA_DST:					dst = sa;					break;				case RTA_GATEWAY:					gate = sa;					break;				case RTA_NETMASK:					mask = sa;					break;				case RTA_IFP:					if (sa->sa_family == AF_LINK &&					   ((struct sockaddr_dl *)sa)->sdl_nlen)						ifp = (struct sockaddr_dl *)sa;					break;				}				ADVANCE(cp, sa);			}	if (dst && mask)		mask->sa_family = dst->sa_family;	/* XXX */	if (dst)		(void)printf("destination: %s\n", routename(dst));	if (mask) {		int savenflag = nflag;		nflag = 1;		(void)printf("       mask: %s\n", routename(mask));		nflag = savenflag;	}	if (gate && rtm->rtm_flags & RTF_GATEWAY)		(void)printf("    gateway: %s\n", routename(gate));	if (ifp)		(void)printf("  interface: %.*s\n",		    ifp->sdl_nlen, ifp->sdl_data);	(void)printf("      flags: ");	bprintf(stdout, rtm->rtm_flags, routeflags);#define lock(f)	((rtm->rtm_rmx.rmx_locks & __CONCAT(RTV_,f)) ? 'L' : ' ')#define msec(u)	(((u) + 500) / 1000)		/* usec to msec */	(void) printf("\n%s\n", "\ recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire");	printf("%8d%c ", rtm->rtm_rmx.rmx_recvpipe, lock(RPIPE));	printf("%8d%c ", rtm->rtm_rmx.rmx_sendpipe, lock(SPIPE));	printf("%8d%c ", rtm->rtm_rmx.rmx_ssthresh, lock(SSTHRESH));	printf("%8d%c ", msec(rtm->rtm_rmx.rmx_rtt), lock(RTT));	printf("%8d%c ", msec(rtm->rtm_rmx.rmx_rttvar), lock(RTTVAR));	printf("%8d%c ", rtm->rtm_rmx.rmx_hopcount, lock(HOPCOUNT));	printf("%8d%c ", rtm->rtm_rmx.rmx_mtu, lock(MTU));	if (rtm->rtm_rmx.rmx_expire)		rtm->rtm_rmx.rmx_expire -= time(0);	printf("%8d%c\n", rtm->rtm_rmx.rmx_expire, lock(EXPIRE));#undef lock#undef msec#define	RTA_IGN	(RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD)	if (verbose)		pmsg_common(rtm);	else if (rtm->rtm_addrs &~ RTA_IGN) {		(void) printf("sockaddrs: ");		bprintf(stdout, rtm->rtm_addrs, addrnames);		putchar('\n');	}#undef	RTA_IGN}voidpmsg_common(rtm)	register struct rt_msghdr *rtm;{	(void) printf("\nlocks: ");	bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);	(void) printf(" inits: ");	bprintf(stdout, rtm->rtm_inits, metricnames);	pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);}voidpmsg_addrs(cp, addrs)	char	*cp;	int	addrs;{	register struct sockaddr *sa;	int i;	if (addrs == 0)		return;	(void) printf("\nsockaddrs: ");	bprintf(stdout, addrs, addrnames);	(void) putchar('\n');	for (i = 1; i; i <<= 1)		if (i & 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);	cp++;	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 + -