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

📄 rsrr_unicast.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
		return(0);	}	NoUnicast = 0;	return(1);}intunicast_route1(u_long addr) {	int i;	struct sockaddr_in sin;	if (init_failed)		return(-1);	if (read_routes() == -1)		return(-1);	memset(&sin, 0, sizeof(sin));	sin.sin_family = AF_INET;	sin.sin_addr.s_addr = addr;	i = rtfindx(&sin);	if (i == -1 && have_default) {		if (IsDebug(DEBUG_ROUTE)) {			log(LOG_DEBUG, 0, "Using default route ...\n");			log(LOG_DEBUG, 0, "route out interface %s\n", 						default_route.ifname);		}		return(ifname_to_if(default_route.ifname));	} else if (i == -1) {		if (IsDebug(DEBUG_ROUTE))			log(LOG_DEBUG, 0, "No route\n");		return(-1);	}	if (IsDebug(DEBUG_ROUTE))		log(LOG_DEBUG, 0, "route out interface %s\n", routes[i].ifname);	return(ifname_to_if(routes[i].ifname));}intunicast_route(net_addr *addr){	switch (NET_GET_TYPE(addr)) {		case NET_ADDR_IPv4:			return(unicast_route1(NET_GET_ADDR_IPv4(addr).s_addr));		case NET_ADDR_UDP_IPv4:			return(unicast_route1(NET_GET_ADDR_UDP_IPv4(addr)				.sin_addr.s_addr));#ifdef	USE_IPV6#ifdef	WORKAROUNDS		case NET_ADDR_IPv6:			return(local_v6);		case NET_ADDR_UDP_IPv6:			return(local_v6);#endif	/* WORKAROUNDS */#endif	/* USE_IPV6 */		default:			return(-1);	}}intifname_to_if(char *name) {	int i;	for (i = 0; i < if_num; i++)		if (strncmp(if_vec[i].if_name, name, IFNAMSIZ) == 0)			return(i);	log(LOG_ERR, 0, "Couldn't find interface %s\n", name);	return(-1);}intread_routes() {	struct mbuf mbf, *mbfp = &mbf;	register struct mbuf *m;	struct mbuf **rhash;	int i, doinghost = 1;	int hashsize;	struct ifreq ifrbuf, *ifr = &ifrbuf;	int status;	kread(nl[N_RTHASHSIZE].n_value, (char *)&hashsize, sizeof (hashsize));	rhash = (struct mbuf **)malloc( hashsize*sizeof (struct mbuf *) );	kread(nl[N_RTHOST].n_value, (char *)rhash, hashsize*sizeof (struct mbuf *));	nroute = 0;again:	for (i = 0; i < hashsize; i++) {		if (rhash[i] == 0)			continue;		m = rhash[i];		while (m) {			struct ifnet ifz, *ifp = &ifz;			struct rtentry *rt;			struct ifaddr ifx, *ifxp = &ifx;			char ifbuf[IFNAMSIZ];			kread((u_long)m, (char *)mbfp, sizeof(struct mbuf));			rt = mtod(mbfp, struct rtentry *);			assert(rt->rt_ifp);			routes[nroute].dst = *(struct sockaddr_in *)&rt->rt_dst;			routes[nroute].gw = *(struct sockaddr_in *)&rt->rt_gateway;			kread((u_long)rt->rt_ifp, (char *)ifp, sizeof(struct ifnet));			assert(ifp->if_addrlist);			kread((u_long)ifp->if_addrlist, (char *)ifxp, sizeof(struct ifaddr));			assert(ifxp->ifa_addr.sa_family == AF_INET);			routes[nroute].out_if = *(struct sockaddr_in *)&ifx.ifa_addr;			kread((u_long)ifp->if_name, ifbuf, IFNAMSIZ);			sprintf(routes[nroute].ifname, "%s%d", ifbuf, 				ifp->if_unit);			memcpy(ifr->ifr_name, routes[nroute].ifname, IFNAMSIZ);			status = ioctl(unicast_fd, SIOCGIFNETMASK, ifr);			if (status < 0) {				perror("ioctl");				return(-1);			}			routes[nroute].netmask = *(struct sockaddr_in *)&ifr->ifr_addr;			if (routes[nroute].dst.sin_addr.s_addr == INADDR_ANY) {				default_route = routes[nroute];				have_default = 1;			} else				nroute++;			assert(nroute < 256);			m = mbfp->m_next;		}	}	if (doinghost) {		kread(nl[N_RTNET].n_value, (char *)rhash, hashsize*sizeof (struct mbuf *));		nhost = nroute;		doinghost = 0;		goto again;	}	free(rhash);	return(1);}intkread(unsigned long addr, char *buf, unsigned nbytes) {	return kvm_read(kd, addr, buf, nbytes);}/* * Find a route to dst as the kernel would. */intrtfindx(struct sockaddr_in *dst) {	int i;	for (i = 0; i < nhost; i++)		if (memcmp(&routes[i].dst, dst, sizeof(struct sockaddr)) == 0)			return(i);	for (i = nhost; i < nroute; i++)		if (net_match(dst, &routes[i]))			return(i);	return(-1);}intnet_match(struct sockaddr_in *dst, struct xroute *rp) {	u_long nm = rp->netmask.sin_addr.s_addr;	if (inet_netmatch(dst, &rp->dst)) {		u_long ip1 = dst->sin_addr.s_addr;		u_long ip2 = rp->dst.sin_addr.s_addr;		if (inet_netmatch(dst, &rp->out_if)) {			if ((ip1 & nm) == ip2)				return(1);			else				return(0);		} else			return(1);	}	return(0);}intinet_netmatch(struct sockaddr_in *sin1, struct sockaddr_in *sin2) {	return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr));}#endif /* ! sgi */#endif /* ! SOLARIS */#endif /* ! PF_ROUTE */#ifdef SOLARIS/* * Copyright (c) Sun Microsystems, Inc.  1994. All rights reserved. * * License is granted to copy, to use, and to make and to use derivative works * for research and evaluation purposes, provided that Sun Microsystems is * acknowledged in all documentation pertaining to any such copy or * derivative work. Sun Microsystems grants no other licenses expressed or * implied. The Sun Microsystems  trade name should not be used in any * advertising without its written permission. * * SUN MICROSYSTEMS MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS * SOFTWARE FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this software. *//* Portions of this code were dereived from Solaris route.c and netstat.c */#include <fcntl.h>#include <sys/stropts.h>#include <sys/socket.h>#include <net/route.h>#include <netinet/in.h>#include <inet/ip.h>#include <sys/tihdr.h>#include <sys/tiuser.h>#include <inet/mib2.h>/* * Following Solaris code was supplied by Don Hoffman of Sun Microsystems. *//* * Defines */#define MAX_ROUTES	(4 * 512)#ifndef T_CURRENT#define T_CURRENT       MI_T_CURRENT#endif#define SOLARIS_2_6	6static int t_current = T_CURRENT;/* * Structure definitions */typedef struct mib_item_s {	struct mib_item_s *next_item;	long group;	long mib_id;	long length;	char *valp;} mib_item_t;struct xroute {	char ifname[IFNAMSIZ];	struct sockaddr_in netmask;	struct sockaddr_in out_if;	struct sockaddr_in dst;	struct sockaddr_in gw;};/* * Forward function declarations */static mib_item_t *mibget(int sd);static void mibfree(mib_item_t *);static int is_host(mib2_ipRouteEntry_t * rp);static int is_gateway(mib2_ipRouteEntry_t * rp);int putmsg(int, struct strbuf *, struct strbuf *, int);int getmsg(int, struct strbuf *, struct strbuf *, int *);/* * Globals */static int sd;static struct xroute routes[MAX_ROUTES];static struct xroute default_route;static int have_default = 0;static int nhost = 0;static int nroute = 0;static intifname_to_if(char *name){	int i;	if (name)		fprintf(stderr, "ifname is %s\n", name);	for (i = 0; i < if_num; i++)		if (strncmp(if_vec[i].if_name, name, IFNAMSIZ) == 0)			return (i);	log(LOG_ERR, 0, "Couldn't find interface %s\n", name);#ifdef SUNMOD	return (0);#else	return (-1);#endif}#ifdef SBMu_longunicast_route_gw_specific(u_long addr){	int i;	struct sockaddr_in sin;	if (read_routes() == -1)		return (-1);	memset(&sin, 0, sizeof (sin));	sin.sin_family = AF_INET;	sin.sin_addr.s_addr = addr;	i = rtfindx(&sin);	if (i == -1 && have_default) {		if (IsDebug(DEBUG_ROUTE)) {			log(LOG_DEBUG, 0, "Using default route ...\n");			log(LOG_DEBUG, 0, "route out interface %s\n",				default_route.ifname);		}		return (default_route.gw.sin_addr.s_addr);	} else if (i >= 0)		return (routes[i].gw.sin_addr.s_addr);	else		return -1;}#endifstatic intinet_netmatch(struct sockaddr_in * sin1, struct sockaddr_in * sin2){	return (inet_netof(sin1->sin_addr) == inet_netof(sin2->sin_addr));}static intnet_match(struct sockaddr_in * dst, struct xroute * rp){	u_long nm = rp->netmask.sin_addr.s_addr;	if (inet_netmatch(dst, &rp->dst)) {		u_long ip1 = dst->sin_addr.s_addr;		u_long ip2 = rp->dst.sin_addr.s_addr;		if (inet_netmatch(dst, &rp->out_if)) {			if ((ip1 & nm) == ip2)				return (1);			else				return (0);		} else			return (1);	}	return (0);}/* * Find a route to dst as the kernel would. */static intrtfindx(struct sockaddr_in *dst){	struct sockaddr_in	*sockp;	int 			i;	for (i = 0; i < nhost; i++) {		sockp = &(routes[i].dst);#ifdef notdef		log(LOG_DEBUG, 0, "routes[%d].dst, dst is %x,%x\n", 			i, sockp->sin_addr.s_addr, dst->sin_addr.s_addr); #endif		if (memcmp(sockp, dst, sizeof (struct sockaddr)) == 0)			return (i); 	} 	for (i = nhost; i < nroute; i++)		if (net_match(dst, &routes[i]))			return (i);	return (-1);}static intread_routes(){	mib_item_t *item;	mib_item_t *first_item = nilp(mib_item_t);	mib2_ipRouteEntry_t *rp;	int ret_code = 1;	int doinghost;	int i;	/* Get the route list. */	/*	 * TBD: don't need to do this every time.  Only to a new mibget every X	 * seconds?	 */	if ((first_item = mibget(sd)) == nilp(mib_item_t)) {		close(sd);		ret_code = -1;		goto leave;	}	/* Look up the entry */	have_default = 0;	nroute = 0;	nhost = 0;	/* host routes first */	doinghost = 1;again:	for (item = first_item; item; item = item->next_item) {		/* skip all the other trash that comes up the mib stream */		if ((item->group != MIB2_IP) || (item->mib_id != MIB2_IP_21))			continue;		rp = (mib2_ipRouteEntry_t *) item->valp;		for (; (u_long) rp < (u_long)(item->valp + item->length);				rp++) {			/* skip routes that aren't what we want this pass */			if (doinghost) {				if (!is_host(rp))					continue;			} else {				if (!is_gateway(rp))					continue;			}			/* fill in the blanks */			memset(&routes[nroute], 0, sizeof (struct xroute));			routes[nroute].dst.sin_family = AF_INET;			routes[nroute].dst.sin_addr.s_addr = rp->ipRouteDest;			routes[nroute].gw.sin_family = AF_INET;			routes[nroute].gw.sin_addr.s_addr = rp->ipRouteNextHop;			routes[nroute].netmask.sin_family = AF_INET;			routes[nroute].netmask.sin_addr.s_addr =				rp->ipRouteMask;			routes[nroute].out_if.sin_family = AF_INET;			routes[nroute].out_if.sin_addr.s_addr =				rp->ipRouteInfo.re_src_addr;			if (rp->ipRouteIfIndex.o_length >= IFNAMSIZ)				rp->ipRouteIfIndex.o_length = IFNAMSIZ - 1;			for (i = 0; i < rp->ipRouteIfIndex.o_length; i++)				routes[nroute].ifname[i] =					rp->ipRouteIfIndex.o_bytes[i];			routes[nroute].ifname[i] = '\0';			if (routes[nroute].dst.sin_addr.s_addr == INADDR_ANY) {				default_route = routes[nroute];				have_default = 1;			} else				nroute++;		}	}	/* net routes next */	if (doinghost) {		nhost = nroute;		doinghost = 0;		goto again;	}leave:	mibfree(first_item);	first_item = nilp(mib_item_t);	return ret_code;}static intis_host(mib2_ipRouteEntry_t * rp){	if (rp->ipRouteMask == (IpAddress) - 1)		return 1;	else		return 0;}static intis_gateway(mib2_ipRouteEntry_t * rp){#ifndef  PF_ROUTE	if (rp->ipRouteInfo.re_ire_type == IRE_GATEWAY ||		rp->ipRouteInfo.re_ire_type == IRE_NET ||		rp->ipRouteInfo.re_ire_type == IRE_ROUTE_ASSOC ||		rp->ipRouteInfo.re_ire_type == IRE_ROUTE_REDIRECT)		return 1;	else		return 0;#else	if (rp->ipRouteInfo.re_ire_type == IRE_DEFAULT ||		rp->ipRouteInfo.re_ire_type == IRE_PREFIX ||		rp->ipRouteInfo.re_ire_type == IRE_HOST ||		rp->ipRouteInfo.re_ire_type == IRE_HOST_REDIRECT)		return 1;	else		return 0;#endif}static mib_item_t * mibget (int sd){	char			buf[512];	int			flags;	int			i, j, getcode;	struct strbuf		ctlbuf, databuf;	struct T_optmgmt_req	*tor = (struct T_optmgmt_req *)buf;	struct T_optmgmt_ack	*toa = (struct T_optmgmt_ack *)buf;	struct T_error_ack	*tea = (struct T_error_ack *)buf;	struct opthdr		*req;	mib_item_t		*first_item = nilp(mib_item_t);	mib_item_t		*last_item  = nilp(mib_item_t);	mib_item_t		*temp;	int debug = 0;		tor->PRIM_type = T_OPTMGMT_REQ;	tor->OPT_offset = sizeof(struct T_optmgmt_req);	tor->OPT_length = sizeof(struct opthdr);	tor->MGMT_flags = t_current;	req = (struct opthdr *)&tor[1];	req->level = MIB2_IP;		/* any MIB2_xxx value ok here */	req->name  = 0;	req->len   = 0;	ctlbuf.buf = buf;	ctlbuf.len = tor->OPT_length + tor->OPT_offset;	flags = 0;	if (putmsg(sd, &ctlbuf, nilp(struct strbuf), flags) == -1) {		perror("mibget: putmsg(ctl) failed");		goto error_exit;	}	/*	 * each reply consists of a ctl part for one fixed structure	 * or table, as defined in mib2.h.  The format is a T_OPTMGMT_ACK,	 * containing an opthdr structure.  level/name identify the entry,	 * len is the size of the data part of the message.	 */	req = (struct opthdr *)&toa[1];	ctlbuf.maxlen = sizeof(buf);	for (j=1; ; j++) {		flags = 0;		getcode = getmsg(sd, &ctlbuf, nilp(struct strbuf), &flags);		if (getcode == -1) {			perror("mibget getmsg(ctl) failed");			if (debug) {				fprintf(stderr, "#   level   name    len\n");				i = 0;				for (last_item = first_item; last_item; 					last_item = last_item->next_item)					printf("%d  %4ld   %5ld   %ld\n", ++i,						last_item->group, 						last_item->mib_id, 						last_item->length);			}			goto error_exit;		}		if (getcode == 0		&& ctlbuf.len >= sizeof(struct T_optmgmt_ack)		&& toa->PRIM_type == T_OPTMGMT_ACK		&& toa->MGMT_flags == T_SUCCESS		&& req->len == 0) {			if (debug)				printf("mibget getmsg() %d returned EOD (level %ld, name %ld)\n", 				       j, req->level, req->name);			return first_item;		/* this is EOD msg */		}		if (ctlbuf.len >= sizeof(struct T_error_ack)		&& tea->PRIM_type == T_ERROR_ACK) {			fprintf(stderr, 			"mibget %d gives (%d) T_ERROR_ACK: TLI_error = 0x%lx, UNIX_error = 0x%lx\n",				j, getcode, tea->TLI_error, tea->UNIX_error);			errno = (tea->TLI_error == TSYSERR)				? tea->UNIX_error : EPROTO;			goto error_exit;		}					if (getcode != MOREDATA		|| ctlbuf.len < sizeof(struct T_optmgmt_ack)		|| toa->PRIM_type != T_OPTMGMT_ACK		|| toa->MGMT_flags != T_SUCCESS) {			printf(			"mibget getmsg(ctl) %d returned %d, ctlbuf.len = %d, PRIM_type = %ld\n",				 j, getcode, ctlbuf.len, toa->PRIM_type);			if (toa->PRIM_type == T_OPTMGMT_ACK)				printf(				"T_OPTMGMT_ACK: MGMT_flags = 0x%lx, req->len = %ld\n", 					toa->MGMT_flags, req->len);			errno = ENOMSG;			goto error_exit;		}		temp = (mib_item_t *)malloc(sizeof(mib_item_t));		if (!temp) {			perror("mibget malloc failed");			goto error_exit;		}		if (last_item)			last_item->next_item = temp;		else			first_item = temp;		last_item = temp;		last_item->next_item = nilp(mib_item_t);		last_item->group = req->level;		last_item->mib_id = req->name;		last_item->length = req->len;		last_item->valp = (char *)malloc(req->len);		if (debug)			printf(			"msg %d:  group = %4ld   mib_id = %5ld   length = %ld\n", 				j, last_item->group, last_item->mib_id, 				last_item->length);		databuf.maxlen = last_item->length;		databuf.buf    = last_item->valp;		databuf.len    = 0;		flags = 0;		getcode = getmsg(sd, nilp(struct strbuf), &databuf, &flags);		if (getcode == -1) {			perror("mibget getmsg(data) failed");			goto error_exit;		} else if (getcode != 0) {			printf(			"mibget getmsg(data) returned %d, databuf.maxlen = %d, databuf.len = %d\n",				 getcode, databuf.maxlen, databuf.len);			goto error_exit;		}	}error_exit:;	while (first_item) {		last_item = first_item;		first_item = first_item->next_item;		free(last_item);	}	return first_item;}static voidmibfree(mib_item_t * first_item){	mib_item_t *last_item;	while (first_item) {		last_item = first_item;		first_item = first_item->next_item;		free(last_item);	}}intunicast_init_specific(void){	int	release;	release = getSolarisRelease();	if (release < SOLARIS_2_6) {		t_current = 0x100;	}	sd = open("/dev/ip", O_RDWR);	if (sd == -1) {		log(LOG_INFO, 0, "Unicast routing information unavailable\n");		init_failed = 1;		NoUnicast = 1;		return 0;	}	return (1);}intunicast_route_specific(u_long addr){	int i;	struct sockaddr_in sin;	if (init_failed)		return (-1);	if (read_routes() == -1)		return (-1);	memset(&sin, 0, sizeof (sin));	sin.sin_family = AF_INET;	sin.sin_addr.s_addr = addr;	i = rtfindx(&sin);	if (i == -1 && have_default) {		if (strlen(default_route.ifname) == 0) {			/*			 * The interface name is not set on def route.  Look it			 * up.			 */			if ((i = rtfindx(&default_route.gw)) == -1)				return (-1);		}		if (IsDebug(DEBUG_ROUTE)) {			log(LOG_DEBUG, 0, "Using default route ...\n");			log(LOG_DEBUG, 0, "route out interface %s\n",				default_route.ifname);		}		return (ifname_to_if(default_route.ifname));	} else if (i == -1) {		if (IsDebug(DEBUG_ROUTE))			log(LOG_DEBUG, 0, "No route\n");		return (-1);	}	if (strlen(routes[i].ifname) == 0) {		/*		 * The interface name is not set on GW routes.  Look it up.		 */		if ((i = rtfindx(&routes[i].gw)) == -1)			return (-1);	}	if (IsDebug(DEBUG_ROUTE))		log(LOG_DEBUG, 0, "route out interface %s\n", routes[i].ifname);	return (ifname_to_if(routes[i].ifname));}#endif

⌨️ 快捷键说明

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