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

📄 rsrr_unicast.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  @(#) $Id: rsrr_unicast.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_unicast.c  **************************** *                                                                   * *       System-dependent Unicast route lookup routine               * *                                                                   * *********************************************************************/#define	USYNCH 1#include "rsvp_daemon.h"#include <sys/param.h>#ifdef sun#ifdef SOLARIS#include <sys/stream.h>#include <inet/common.h>#undef IPOPT_EOL#undef IPOPT_NOP#undef IPOPT_LSRR#undef IPOPT_RR#undef IPOPT_SSRR#include <inet/ip.h>#else /* not SOLARIS */#include <sys/mbuf.h>#endif /* SOLARIS */#endif /* sun */u_long bmp_unicast;int unicast_result_ready;int unicast_query_waiting;int asynchronous = 1;static int init_failed = 0;int locate_LIH(unsigned int, net_addr *);intlocate_LIH(unsigned int ifidx, net_addr *addr){	int i;	for (i = 0; i < if_num; i++) {		if (IsNumAPI(i))			continue;		if (ifidx == if_vec[i].if_index) {			if (net_addr_equal(addr, &(NET_GET_IF_PHY_ADDR(&(if_vec[i].if_addr)))))				return i;		}	}	return -1;}#ifdef SOLARIS#include <sys/utsname.h>#define SOLARIS_2_6	6/* * Routing socket indicies */#define RTAX_DST	0#define RTAX_GATEWAY	1#define RTAX_NETMASK	2#define RTAX_GENMASK	3#define RTAX_IFP	4#define RTAX_IFA	5#define RTAX_AUTHOR	6#define RTAX_BRD	7#define RTAX_MAX	8static intgetSolarisRelease(void){	struct utsname	n;	int		major, minor;	char		*period, *release;	if (uname(&n) < 0) {		perror("uname");		return (-1);	}	release = strdup(n.release);	if ((period = strchr(release, '.'))) {		*period = '\0';		minor = atoi(period + 1);	}	major = atoi(release);	free (release);	if (major != 5)		return (-1);	else		return (minor);}#endif	/* SOLARIS */#if defined(PF_ROUTE)  && !defined(sgi_53) && !defined(linux)int seq;		/* routing socket sequence num */int rskt;		/* routing socket *//* * This code will assumes a routing socket and will work on many newer * BSD-like machines * *//* * Copyright 1995 Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that both the above copyright notice and this * permission notice appear in all copies, that both the above * copyright notice and this permission notice appear in all * supporting documentation, and that the name of M.I.T. not be used * in advertising or publicity pertaining to distribution of the * software without specific, written prior permission.  M.I.T. makes * no representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied * warranty. *  * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include <errno.h>#include <net/if.h>#include <net/if.h>#include <net/if_dl.h>#include <net/route.h>#include <netinet/in.h>/* * Round up 'a' to next multiple of 'size' */ #define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))  /* * Step to next socket address structure; * if sa_len is 0, assume it is sizeof(u_long). */#define NEXT_SA(ap) ap = (struct sockaddr *) \    ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (u_long)) : \                                    sizeof(u_long)))#ifdef SOLARISstatic int useRoutingSocket = 0;#endif/* * For now, we open a new socket every time we want to get a route, to * save some effort in parsing.  Eventually we should keep it open and * listen for changes.  For now, just open and close it to make sure that * we can. */intunicast_init(void){#ifdef SOLARIS	static int unicast_init_specific();	int	release;	if ((release = getSolarisRelease()) < 0) {		init_failed = 1;		NoUnicast = 1;		return (0);	}	if (release >= SOLARIS_2_6) {		rskt = socket(PF_ROUTE, SOCK_RAW, AF_INET);		if (rskt < 0) {			log(LOG_INFO, 0,				"Unicast routing information unavailable\n");			init_failed = 1;			NoUnicast = 1;			return (0);		}		useRoutingSocket++;	} else if (!unicast_init_specific()) {		init_failed = 1;		NoUnicast = 1;		return (0);	}#else	/* SOLARIS */	rskt = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);	if (rskt < 0) {		init_failed = 1;		NoUnicast = 1;		log(LOG_INFO, 0, "Unicast routing information unavailable\n");		return 0;	}#endif	/* SOLARIS */	NoUnicast = 0;	close(rskt);	return 1;}#define RTM_BUFLEN 2048		/* XXX should be in header file */#define WORD_BNDARY(x)  (((x)+sizeof(long)-1) & ~(sizeof(long)-1))#ifdef SBMu_longunicast_route_gw_routing_socket(u_long addr){	int			s, one = 1, i, len;	struct sockaddr		*sa;#ifdef SOLARIS	struct sockaddr		*rti_info[RTA_NUMBITS];#else	struct sockaddr		*rti_info[RTAX_MAX];#endif	struct sockaddr_in	*isa;	struct rt_msghdr	*mhp;	caddr_t			cp;	char			buf[RTM_BUFLEN];	if ((s = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {		perror("socket");		return (-1);	}	setsockopt(s, SOL_SOCKET, SO_USELOOPBACK, (char *)&one, sizeof (one));	/* Set up GET message */	memset(buf, 0, sizeof buf);	mhp = (struct rt_msghdr *)buf;	cp = buf + sizeof(struct rt_msghdr);	isa = (struct sockaddr_in *)cp;	isa->sin_family = AF_INET;	isa->sin_addr.s_addr = addr;	mhp->rtm_version = RTM_VERSION;	mhp->rtm_type = RTM_GET;	mhp->rtm_addrs = RTA_GATEWAY; 	mhp->rtm_seq = ++seq;	mhp->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);	/* Send the message */	if (write(s, buf, (size_t)mhp->rtm_msglen) < 0) {		log(LOG_ERR, errno, "writing message on routing socket\n");		close(s);		return -1;	}	/* Read the reply */	do {		len = read(s, buf, sizeof buf);	} while (len > 0 && mhp->rtm_seq != seq && mhp->rtm_pid != getpid());	close(s);	if (len < 0 || mhp->rtm_errno) {		if (IsDebug(DEBUG_ROUTE))			log(LOG_DEBUG, errno, "unicast route lookup failed");		return -1;	}	if (len == 0) {		log(LOG_ERR, 0, "unicast route lookup is confused");		return -1;	}	sa = (struct sockaddr *) (mhp + 1);	get_route_info(sa, rti_info, mhp);		isa = NULL;	for (i = 0; i < RTAX_MAX; i++) {		switch(mhp->rtm_addrs & (1 << i)) {		case RTA_GATEWAY:			isa = (struct sockaddr_in *)rti_info[i];			break;		}	}	if (!isa)		return (-1);	else		return (isa->sin_addr.s_addr);}u_longunicast_route_gw(u_long addr){#ifdef SOLARIS	if (useRoutingSocket)		return unicast_route_gw_routing_socket(addr);	else		return unicast_route_gw_specific(addr);#else	unicast_route_gw_routing_socket(addr);#endif}static voidget_route_info(struct sockaddr *sa, struct sockaddr **rti_info,	struct rt_msghdr *mhp){	int		i;#ifdef SOLARIS	caddr_t		cp;	cp  = (caddr_t)sa;	for (i = 0; i < RTA_NUMBITS; i++) {		switch (mhp->rtm_addrs & (1 << i)) {		case RTA_DST:		case RTA_GATEWAY:		case RTA_NETMASK:		case RTA_GENMASK:		case RTA_AUTHOR:		case RTA_IFA:			rti_info[i] = (struct sockaddr *)cp;			cp += sizeof (struct sockaddr_in);			break;		case RTA_IFP:			rti_info[i] = (struct sockaddr *)cp;			cp += sizeof (struct sockaddr_dl);			break;		}	}#else    	for (i = 0; i < RTAX_MAX; i++) {        	if (mhp->rtm_addrs & (1 << i)) {			rti_info[i] = sa;			NEXT_SA(sa);        	} else			rti_info[i] = NULL;    	}   #endif}#endif#ifdef SOLARISintunicast_route(net_addr *addr){	static int unicast_route_routing_socket(net_addr *);	static int unicast_route_specific(u_long);	switch (NET_GET_TYPE(addr)) {	case NET_ADDR_IPv4:		if (useRoutingSocket)			return (unicast_route_routing_socket(addr));		else			return(unicast_route_specific(				NET_GET_ADDR_IPv4(addr).s_addr));	case NET_ADDR_UDP_IPv4:		if (useRoutingSocket)			return (unicast_route_routing_socket(addr));		else			return(unicast_route_specific(				NET_GET_ADDR_UDP_IPv4(addr).sin_addr.s_addr));	default:		return(0);	}}#endif	/* SOLARIS *//* * Find the kernel's idea of the route to destination DEST (in host order) */int#ifdef SOLARISunicast_route_routing_socket(net_addr *addr)#elseunicast_route(net_addr *addr)#endif{	struct sockaddr *sp;	struct sockaddr_in *s4;	struct rt_msghdr *mhp;	net_addr *addr2;	char buf[RTM_BUFLEN];	int one, sz;	int sock;	int pid;#ifdef  USYNCH	int s;	int len;	struct sockaddr *sa;#ifdef SOLARIS	caddr_t		cp;	struct sockaddr *rti_info[RTA_NUMBITS];#else	struct sockaddr *rti_info[RTAX_MAX];#endif    net_addr nadr;    struct sockaddr_dl *sdlp;    char ifname[IFNAMSIZ];    int i;    int ifidx = 0;#endif  /* USYNCH */#ifdef	USE_IPV6	struct sockaddr_in6 *s6;#endif	/* USE_IPV6 */#ifdef	USYNCH	/* Open socket */	s = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);	if (s < 0) {		log(LOG_ERR, errno,		    "Could not open routing socket");		return -1;	}	else 		sock = s;#else	/* USYNCH */	sock = rskt;#endif	/* !USYNCH */	one = 1;	setsockopt(sock, SOL_SOCKET, SO_USELOOPBACK, (char *) &one, sizeof one);	/* Set up GET message */	memset(buf, 0, sizeof buf);	mhp = (struct rt_msghdr *)buf;	sp = (struct sockaddr *)               &buf[WORD_BNDARY(sizeof (struct rt_msghdr))];	addr2 = net_addr_ip(addr);	switch (NET_GET_TYPE(addr2)) {		case NET_ADDR_IPv4:			sz = sizeof(struct sockaddr_in);			s4 = (struct sockaddr_in *) sp;			s4->sin_family = AF_INET;			s4->sin_addr.s_addr = NET_GET_ADDR_IPv4(addr2).s_addr;			s4->sin_port = 0;#ifdef SOCKADDR_LEN			s4->sin_len = sz;#endif			break;#ifdef	USE_IPV6		case NET_ADDR_IPv6:			sz = sizeof(struct sockaddr_in6);			s6 = (struct sockaddr_in6 *) sp;			s6->sin6_family = AF_INET6;			s6->sin6_addr = NET_GET_ADDR_IPv6(addr2);			s6->sin6_port = 0;#ifdef SOCKADDR_LEN			s6->sin6_len = sz;#endif			break;#endif	/* USE_IPV6 */		default:			return(-1);	}	mhp->rtm_version = RTM_VERSION;	mhp->rtm_type = RTM_GET;	/* mhp->rtm_addrs = RTA_DST|RTA_IFP; */	mhp->rtm_addrs = RTA_DST|RTA_IFP|RTA_IFA;	mhp->rtm_seq = ++seq;	mhp->rtm_pid = pid = getpid();	mhp->rtm_msglen = ((char *)(sp)) + sz - buf;	/* Send the message */	if (write(sock, buf, (size_t)mhp->rtm_msglen) < 0) {		log(LOG_ERR, errno, "writing message on routing socket\n");#ifdef	USYNCH		close(sock);#endif	/* USYNCH */		return -1;	}#if !defined(USYNCH)	asynchronous = 1;	return 0;	#else	/* USYNCH */	/* Read the reply */	do {		len = read(sock, buf, sizeof buf);	} while (len > 0 && mhp->rtm_seq != seq && mhp->rtm_pid != pid);	close(sock);	if (len < 0 || mhp->rtm_errno) {		if (IsDebug(DEBUG_ROUTE))			log(LOG_DEBUG, errno, "unicast route lookup failed");		return -1;	}	if (len == 0) {		log(LOG_ERR, 0, "unicast route lookup is confused");		return -1;	}	sa = (struct sockaddr *) (mhp + 1);    #ifdef SOLARIS	cp  = (caddr_t)sa;	for (i = 0; i < RTA_NUMBITS; i++) {		switch (mhp->rtm_addrs & (1 << i)) {		case RTA_DST:		case RTA_GATEWAY:		case RTA_NETMASK:		case RTA_GENMASK:		case RTA_AUTHOR:		case RTA_IFA:			rti_info[i] = (struct sockaddr *)cp;			cp += sizeof (struct sockaddr_in);			break;		case RTA_IFP:			rti_info[i] = (struct sockaddr *)cp;			cp += sizeof (struct sockaddr_dl);			break;		}	}#else    for (i = 0; i < RTAX_MAX; i++) {        if (mhp->rtm_addrs & (1 << i)) {            rti_info[i] = sa;            NEXT_SA(sa);        } else            rti_info[i] = NULL;    }   #endif 	if ((sa = rti_info[RTAX_IFP]) != NULL) {		sdlp = (struct sockaddr_dl *)sa;		if (sdlp->sdl_family != AF_LINK || sdlp->sdl_nlen == 0) {			if (IsDebug(DEBUG_ROUTE))				log(LOG_DEBUG, 0, "unicast route through weird ifp");			return -1;		}		strncpy(ifname, sdlp->sdl_data, sdlp->sdl_nlen);		if (sdlp->sdl_nlen < IFNAMSIZ)			ifname[sdlp->sdl_nlen] = '\0';		ifidx = if_nametoindex(ifname);	}    if ((sa = rti_info[RTAX_IFA]) != NULL) {	switch (sa->sa_family) {		case AF_INET:			s4 = (struct sockaddr_in *)sa;			NET_SET_ADDR_IPv4(&nadr, s4->sin_addr);			break;#ifdef	USE_IPV6		case AF_INET6:			s6 = (struct sockaddr_in6 *)sa;			NET_SET_ADDR_IPv6(&nadr, s6->sin6_addr);			break;#endif	/* USE_IPV6 */		default:			return (-1);	}    }	else 		return -1;	asynchronous = 0;	return (locate_LIH(ifidx, &nadr));#endif	/* USYNCH */}# else/*  * ifndef PF_ROUTE - no routing socket. OS-specific code required, */#ifdef SOLARISstatic int unicast_init_specific();static int unicast_route_specific(u_long);intunicast_init(void){	return (unicast_init_specific());}#ifdef SBMstatic int unicast_route_gw_specific(u_long);u_longunicast_route_gw(u_long addr){	return (unicast_route_gw_specific(addr));}#endifintunicast_route(net_addr *addr){	switch (NET_GET_TYPE(addr)) {		case NET_ADDR_IPv4:			return(unicast_route_specific(				NET_GET_ADDR_IPv4(addr).s_addr));		case NET_ADDR_UDP_IPv4:			return(unicast_route_specific(				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);	}}#else /* end of SOLARIS */#ifdef	linuxint dst_route_oif(net_addr *);int dst_init();intunicast_init(void){	if (dst_init(NULL) < 0) {		init_failed = 1;		NoUnicast = 1;		log(LOG_INFO, 0, "Unicast routing information unavailable");		return 0;	}	NoUnicast = 0;	return 1;}/* * Find the kernel's idea of the route to destination DEST (in host order) */intunicast_route(net_addr *addr){	return dst_route_oif(addr);}/* ------------------------------------------------------------------------ *//* * libroute.c Interface to Linux routing engine. * *		This program is free software; you can redistribute it and/or *		modify it under the terms of the GNU General Public License *		as published by the Free Software Foundation; either version *		2 of the License, or (at your option) any later version. * * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <syslog.h>#include <fcntl.h>#include <linux/types.h>#include <sys/socket.h>#include <string.h>#include <errno.h>#include <sys/time.h>#include <linux/rtnetlink.h>#include "libnetlink.h"#include "libroute.h"#include "rsvp_daemon.h"#define MAXDSTENTRIES 128#define R_ASYNC_TMO	2#define R_CANCEL_TMO	20#define R_SYNC_TMO	5#define R_GC_TMO	300#define R_STALETIME	15#define R_LOAD		30#define MSG_TRUNC	0x20#define MSG_DONTWAIT	0x40	/* Nonblocking io		 */static struct rtnl_handle rt_nl;static const __u32 zerokey[KEYLEN];static struct dstentry *dsttable[256];static struct dstentry *dstqueue;static void (*dst_refresh)(struct dstentry*);

⌨️ 快捷键说明

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