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

📄 rsvp_trans.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * @(#) $Id: rsvp_trans.c,v 1.8 2000/06/21 00:51:49 wenqing Exp $ *//*********************** rsvp_trans.c ******************************** *                                                                   * *    System Independent Interface to Network and Transport Layers   * *                                                                   * *********************************************************************//****************************************************************************            RSVPD -- ReSerVation Protocol Daemon                USC Information Sciences Institute                Marina del Rey, California		Original Version: Shai Herzog, Nov. 1993.		Current Version:  Bob Lindell, July 1997.  Copyright (c) 1999 by the University of Southern California  All rights reserved.  Permission to use, copy, modify, and distribute this software and its  documentation in source and binary forms for any purpose and without  fee is hereby granted, provided that both the above copyright notice  and this permission notice appear in all copies, and that any  documentation, advertising materials, and other materials related to  such distribution and use acknowledge that the software was developed  in part by the University of Southern California, Information  Sciences Institute.  The name of the University may not be used to  endorse or promote products derived from this software without  specific prior written permission.  THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about  the suitability of this software for any purpose.  THIS SOFTWARE IS  PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Other copyrights might apply to parts of this software and are so  noted when applicable.********************************************************************/#include <sys/param.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <net/if.h>#include <netinet/udp.h>#include <sys/time.h>#include <sys/uio.h>#include <sys/file.h>#include <sys/resource.h>#include <stdio.h>#include <errno.h>#include <unistd.h>#include <memory.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <signal.h>#ifdef	__FreeBSD__#include <net/if_dl.h>#endif	/* __FreeBSD__ */#include "rsvp_socks.h"#include "rsvp_trans.h"#ifndef	IPPROTO_RSVP#define	IPPROTO_RSVP	46#endif	/* IPPROTO_RSVP */#ifdef	SO_REUSEPORT#define	SO_REUSEXXXX	SO_REUSEPORT#else	/* SO_REUSEPORT */#define	SO_REUSEXXXX	SO_REUSEADDR#endif	/* SO_REUSEPORT *//* support old spec */#ifdef	USE_IPV6#ifndef IPV6_ADD_MEMBERSHIP#define IPV6_ADD_MEMBERSHIP	IPV6_JOIN_GROUP#define IPV6_DROP_MEMBERSHIP	IPV6_LEAVE_GROUP#endif /* IPV6_ADD_MEMBERSHIP */#endif	/* USE_IPV6 */#ifndef	IP_PKTINFO#ifdef	IP_RECVIF#define	in_pktinfo	sockaddr_dl#define	ipi_ifindex	sdl_index#define	IP_PKTINFO	IP_RECVIF#endif	/* IP_RECVIF */#endif	/* IP_PKTINFO */#ifndef	IPV6_PKTINFO#ifdef	IPV6_RECVIF#define	in6_pktinfo	sockaddr_dl#define	ipi6_ifindex	sdl_index#define	IPV6_PKTINFO	IPV6_RECVIF#endif	/* IPV6_RECVIF */#endif	/* IPV6_PKTINFO *//* FreeBSD workaround for broken IPV6_PKTINFO */#ifdef	__FreeBSD__#ifdef	IPV6_RECVIF#define	in6_pktinfo	sockaddr_dl#define	ipi6_ifindex	sdl_index#undef	IPV6_PKTINFO#define	IPV6_PKTINFO	IPV6_RECVIF#endif	/* IPV6_RECVIF */#endif	/* __FreeBSD__ */#ifdef	sun#if	(defined(__SVR4) || defined(__svr4__))#define	SOLARIS#else	/* (defined(__SVR4) || defined(__svr4__)) */#define	SunOS#endif	/* (defined(__SVR4) || defined(__svr4__)) */#endif	/* sun */#ifdef	SunOSextern int ioctl(int,int,caddr_t);extern int socket(int,int,int);extern int setsockopt(int,int,int,char *,int);extern int getsockname(int,struct sockaddr *,int *);extern int bind(int,struct sockaddr *,int);extern int recvfrom(int,char *,int,int,struct sockaddr *,int *);extern int select(int,fd_set *,fd_set *,fd_set *,struct timeval *);extern void bzero(char *,int);extern int on_exit(void (*procp)(),caddr_t);extern int sendmsg(int,struct msghdr *,int);extern int getrlimit(int,struct rlimit *);extern int setrlimit(int,struct rlimit *);#endif	/* SunOS *//* *	This module exports an interface for performing network I/O of *	datagrams over different protocols.  All system specific *	implementations of this functionality are opaque to the layers *	above this module.  This module could be further divided into *	generic IP protocol support and the actual system dependent *	network I/O functionaliy.  There does not seem to be any *	benefit at this point since IP is the only network protocol *	defined for RSVP. */#if	sun#define	msg_control	msg_accrights#define	msg_controllen	msg_accrightslen#endif	/* sun */#ifdef	linux/* The following definition might need to be uncommented if /bits/in.h or   other similar files in your linux system not defining this struct.struct in_pktinfo{	int		ipi_ifindex;	struct in_addr	ipi_spec_dst;	struct in_addr	ipi_addr;};*/#define	uh_sport source#define	uh_dport dest#define	uh_ulen len#define	uh_sum check#endif	/* linux */typedef int (*callback)(int);FILE *debug_file = NULL ;#ifdef ISI_TEST/*** FILE  *debug_file = stdout; ***/#endif/*	Static variables: record state local to this module. * *	 o interface[fd]: Vector of net_if structs; per fd. *	 o finalize[fd]: Addr to be called to delete fd, or null; per fd *	 o fset[]: bit vector specifying full set of send or receive sockets. *	 o rset[]: Select bit vector for receive *	 o protocol_type[fd]: net_addr type corresponding to fd; per fd. *	 o ulist[net_addr type] = fd to use for sending on default interface *	 o fd_pu, fd_pup: fds to receive on RSVP Pu, Pu' UDP encaps ports * *	There are additional static variables if !defined(IP_DSTOPTS) */static fd_set 		rset, fset;static int		ulist[NET_ADDR_SIZE];static net_addr_type	protocol_type[FD_SETSIZE];static net_if		interface[FD_SETSIZE];static callback		finalize[FD_SETSIZE];static int 		rawmode = TRUE;static int 		closed = TRUE;static int 		ipproto_rsvp = IPPROTO_RSVP;static net_if 		unknown;static int		pid = SYS_ERROR;static int		fd_pu, fd_pup;static struct		in_addr maddr;	/* RSVP G* multicast address *//*	Forward Declarations * */static int failed(int fd);static void init();static void final();static void adjust(net_addr *addr,net_addr_type type);static int receive(int fd,net_addr *from,void *msg,int len,net_if *inf);static int add_interface(net_if *inf);static int del_interface(net_if *inf);static void fds_print(FILE *, char *);static int send_ipv4(net_addr_type type,struct sockaddr_in *to,	struct sockaddr_in *from,void *msg,int len,net_if *inf,	u_char hops,int ra);static int set_ancillary_data_ipv4(struct msghdr *hdr,net_addr_type type,	struct sockaddr_in *to,struct sockaddr_in *from,	void *msg,int len,net_if *inf,u_char hops,int ra);static int init_ancillary_data_ipv4(int fd);static int socket_ipv4(int type,int proto,net_addr_type atype);static int socket_recv_rsvp_ipv4(int proto);static int socket_recv_udp_ipv4(struct sockaddr_in *addr);static int join_multicast_ipv4(int fd,net_if *inf,struct in_addr *g);static int drop_multicast_ipv4(int fd,net_if *inf,struct in_addr *g);static int drop_all_multicast_ipv4(int fd);static int rsvp_on_ipv4(int fd);static int rsvp_off_ipv4(int fd);static int add_if_ipv4(net_if *inf,struct in_addr *g);static int del_if_ipv4(net_if *inf,struct in_addr *g);static int add_vif_ipv4(net_if *inf);static int del_vif_ipv4(net_if *inf);static int rsvp_vif_off_ipv4(int fd);#ifdef	USE_IPV6static int fd6_pu,fd6_pup;static struct in6_addr maddr6;static int send_ipv6(net_addr_type type,struct sockaddr_in6 *to,	struct sockaddr_in6 *from,void *msg,int len,net_if *inf,	u_char hops,int ra);static int set_ancillary_data_ipv6(struct msghdr *hdr,net_addr_type type,	struct sockaddr_in6 *to,struct sockaddr_in6 *from,	void *msg,int len,net_if *inf,u_char hops,int ra);static int init_ancillary_data_ipv6(int fd);static int socket_ipv6(int type,int proto,net_addr_type atype);static int socket_recv_rsvp_ipv6(int proto);static int socket_recv_udp_ipv6(struct sockaddr_in6 *addr);static int join_multicast_ipv6(int fd,net_if *inf,struct in6_addr *g);static int drop_multicast_ipv6(int fd,net_if *inf,struct in6_addr *g);static int drop_all_multicast_ipv6(int fd);static int rsvp_on_ipv6(int fd);static int rsvp_off_ipv6(int fd);static int add_if_ipv6(net_if *inf,struct in6_addr *g);static int del_if_ipv6(net_if *inf,struct in6_addr *g);static int initialize(int pu,int pup,struct in_addr *g,struct in6_addr *g6);#else	/* USE_IPV6 */static int initialize(int pu,int pup,struct in_addr *g);#endif	/* USE_IPV6 *//* *	Special case initialization: only UDP. (This routine is not *						currently used) */intnet_init_udp_only(net_addr *addr4){	int fd,size,status = SYS_NOERROR;	net_addr *iaddr;	struct sockaddr_in addr;#ifdef	USE_IPV6	struct sockaddr_in6 addr6;#endif	/* USE_IPV6 */	init();	rawmode = FALSE;	/* Receive RSVP/UDP/IPv4 (Any Interface) */	iaddr = net_get_default_interface();	if ((iaddr != NULL) && (NET_GET_TYPE(iaddr) == NET_ADDR_IPv4)) {		NET_SOCKADDR_IPv4(&addr,NET_GET_ADDR_IPv4(iaddr));	}	else {		NET_SOCKADDR_IPv4(&addr,inaddr_any);	}	fd = socket_recv_udp_ipv4(&addr);	/* Send RSVP/UDP/IPv4 (Any Interface) */	ulist[NET_ADDR_UDP_IPv4] = fd;	if (FAILED(fd))		status = SYS_ERROR;	else {		size = sizeof(addr);		if (!FAILED(getsockname(fd,(struct sockaddr *) &addr,&size)))			NET_SET_ADDR_UDP_IPv4(addr4,addr);	}#ifdef	USE_IPV6	/* Receive RSVP/UDP/IPv6 (Any Interface) */	NET_SOCKADDR_IPv6(&addr6,in6addr_any);	fd = socket_recv_udp_ipv6(&addr6);	/* Send RSVP/UDP/IPv6 (Any Interface) */	ulist[NET_ADDR_UDP_IPv6] = fd;	if (FAILED(fd))		status = SYS_ERROR;#endif	/* USE_IPV6 */	return(status);}/*	Standard initialization.   *		Set up receive sockets and fds, then call initialize() *		to set up send sockets and fds. */int#ifdef	USE_IPV6net_init(int pu,int pup,struct in_addr *g,struct in6_addr *g6,int async)#else	/* USE_IPV6 */net_init(int pu,int pup,struct in_addr *g,int async)#endif	/* USE_IPV6 */{	int fd,status = SYS_NOERROR;	struct sockaddr_in addr;	struct protoent *p;#ifdef	USE_IPV6	struct sockaddr_in6 addr6;#endif	/* USE_IPV6 */	init();	maddr = *g;	p = getprotobyname("rsvp");	if (p != NULL)		ipproto_rsvp = p->p_proto;	if (async) {		pid = getpid();		if (FAILED(pid))			return(SYS_ERROR);	}	/*	 *	Send and Receive Raw RSVP/IPv4 (Any Interface)	 *	If Raw socket call fails, sets rawmode == FALSE	 *	Enable RSVP intercept for receiving raw.	 */	fd = socket_recv_rsvp_ipv4(ipproto_rsvp);	ulist[NET_ADDR_IPv4] = fd;	if (rawmode && FAILED(fd))		status = SYS_ERROR;	/*	 * Send and Receive Multicast RSVP/UDP/IPv4 [Pu] (Any Interface) 	 */	NET_SOCKADDR_UDP_IPv4(&addr, inaddr_any, pu);	fd_pu = socket_recv_udp_ipv4(&addr);	ulist[NET_ADDR_UDP_IPv4] = fd_pu;	if (FAILED(fd_pu))		status = SYS_ERROR;	/*	 * Receive Multicast RSVP/UDP/IPv4 [Pu'] (Any Interface)	 */	if (!rawmode) {		NET_SOCKADDR_UDP_IPv4(&addr, inaddr_any, pup);		fd_pup = socket_recv_udp_ipv4(&addr);		if (FAILED(fd_pup))			status = SYS_ERROR;	}#ifdef	USE_IPV6	maddr6 = *g6;	/* Receive RSVP/IPv6 (Any Interface) */	fd = socket_recv_rsvp_ipv6(ipproto_rsvp);	/* Send RSVP/IPv6 (Any Interface) */	ulist[NET_ADDR_IPv6] = fd;	if (rawmode && FAILED(fd))		status = SYS_ERROR;	/* Receive Multicast RSVP/UDP/IPv6 [Pu] (Any Interface) */	NET_SOCKADDR_UDP_IPv6(&addr6,in6addr_any,pu);	fd6_pu = socket_recv_udp_ipv6(&addr6);	/* Send RSVP/UDP/IPv6 (Any Interface) */	ulist[NET_ADDR_UDP_IPv6] = fd6_pu;	if (FAILED(fd6_pu))		status = SYS_ERROR;	/* Receive Multicast RSVP/UDP/IPv6 [Pu'] (Any Interface) */	if (!rawmode) {		NET_SOCKADDR_UDP_IPv6(&addr6,in6addr_any,pup);		fd6_pup = socket_recv_udp_ipv6(&addr6);		if (FAILED(fd6_pup))			status = SYS_ERROR;	}	/*	 * Now call initialize() to set up send sockets and fds.	 */	if (FAILED(initialize(pu,pup,g,g6)))		status = SYS_ERROR;#else	/* USE_IPV6 */	if (FAILED(initialize(pu,pup,g)))		status = SYS_ERROR;#endif	/* USE_IPV6 */	return(status);}/* *	Shutdown network I/O subsystem. */intnet_final(){	int fd,status = SYS_NOERROR;	if(closed)		return(SYS_NOERROR);	for (fd = 0;fd < FD_SETSIZE; fd++)		if (FD_ISSET(fd,&fset)) {			if (finalize[fd] != NULL)				if(FAILED((*finalize[fd])(fd)))					status = SYS_ERROR;			FD_CLR(fd,&fset);			if(FAILED(close(fd)))				status = SYS_ERROR;		}	closed = TRUE;	pid = SYS_ERROR;	return(status);}intnet_has_rawmode(){	return(rawmode);}intnet_poll_list(fd_set *set){	if (debug_file)		fds_print(debug_file, "@ net_poll_list");	*set = rset;	return(SYS_NOERROR);}/* *	This is how the application tells us which multicast interfaces *	to listen for UDP datagrams to G*. */intnet_add_interfaces(int n,net_if *list){	int i,status = SYS_NOERROR;	for (i = 0;i < n; i++)		if (FAILED(add_interface(&list[i])))			status = SYS_ERROR;	return(status);}intnet_del_interfaces(int n,net_if *list){	int i,status = SYS_NOERROR;	for (i = 0;i < n; i++)		if (FAILED(del_interface(&list[i])))			status = SYS_ERROR;	return(status);}/*	Some receive bit has appeared in select; do another select() to *	find it, and then call receive(fd,...) to read msg and len and to *	set inf and from. */intnet_recv(net_addr *from,void *msg,int len,net_if *inf){	int fd,n;	fd_set lrset;	struct timeval zero;	timerclear(&zero);	lrset = rset;	n = select(FD_SETSIZE,&lrset,(fd_set *) NULL,(fd_set *) NULL,&zero);	if (n < 1)		return(n);	for (fd = 0;fd < FD_SETSIZE; fd++)		if (FD_ISSET(fd,&lrset))			return(receive(fd,from,msg,len,inf));	return(0);}/* *	Send datagram using the appropriate transport protocol, which *	is inferred from the address type.  Flags interpretation are *	protocol specific.  Parameters "from" and "inf" can be *	optionally set to NULL. */intnet_send(net_addr *to,net_addr *from,void *msg,int len,	net_if *inf,u_char hops,int ra){	net_addr_type type;	struct sockaddr_in st,sf,*fp = NULL;#ifdef	USE_IPV6	struct sockaddr_in6 st6,sf6,*fp6 = NULL;#endif	/* USE_IPV6 */	if ((from != NULL) && NET_UNEQUAL_TYPE(to,from))		return(SYS_ERROR);	type = NET_GET_TYPE(to);	switch (type) {		case NET_ADDR_IPv4:			NET_SOCKADDR_IPv4(&st,NET_GET_ADDR_IPv4(to));			if (from != NULL) {				NET_SOCKADDR_IPv4(&sf,					NET_GET_ADDR_IPv4(from));				fp = &sf;			}			return(send_ipv4(type,&st,fp,msg,len,inf,hops,ra));		case NET_ADDR_UDP_IPv4:			st = NET_GET_ADDR_UDP_IPv4(to);			if (from != NULL)				fp = &NET_GET_ADDR_UDP_IPv4(from);			return(send_ipv4(type,&st,fp,msg,len,inf,hops,ra));#ifdef	USE_IPV6		case NET_ADDR_IPv6:			NET_SOCKADDR_IPv6(&st6,NET_GET_ADDR_IPv6(to));			if (from != NULL) {				NET_SOCKADDR_IPv6(&sf6,					NET_GET_ADDR_IPv6(from));				fp6 = &sf6;			}			return(send_ipv6(type,&st6,fp6,msg,len,inf,hops,ra));		case NET_ADDR_UDP_IPv6:			st6 = NET_GET_ADDR_UDP_IPv6(to);			if (from != NULL)				fp6 = &NET_GET_ADDR_UDP_IPv6(from);			return(send_ipv6(type,&st6,fp6,msg,len,inf,hops,ra));#endif	/* USE_IPV6 */		default:			return(SYS_ERROR);	}}staticintfailed(int fd){	FD_CLR(fd,&fset);	close(fd);	return(SYS_ERROR);}staticvoidinit(){	static struct rlimit limits;	static int noexit = TRUE;	if (noexit) {#ifdef	SunOS		on_exit(final,0);#else	/* SunOS */		atexit(final);#endif	/* SunOS */		noexit = FALSE;	}	if (FAILED(getrlimit(RLIMIT_NOFILE,&limits)))		net_error(NET_ERROR_SYSTEM,"getrlimit");	else {		limits.rlim_cur = limits.rlim_max;		if (FAILED(setrlimit(RLIMIT_NOFILE,&limits)))			net_error(NET_ERROR_SYSTEM,"setrlimit");	}	FD_ZERO(&rset);	FD_ZERO(&fset);	NET_SET_TYPE(&unknown,NET_IF_UNKNOWN);	closed = FALSE;}staticvoidfinal(){	net_final();}/*	adjust(): This little routine "casts" a net_addr into specified type. *		Used to set *from net_addr in receive(). *		 */staticvoidadjust(net_addr *addr,net_addr_type type){	NET_SET_TYPE(addr,type);	switch(type) {		case NET_ADDR_IPv4:			NET_SET_ADDR_IPv4(addr,				NET_GET_ADDR_UDP_IPv4(addr).sin_addr);			break;#ifdef	USE_IPV6		case NET_ADDR_IPv6:			NET_SET_ADDR_IPv6(addr,				NET_GET_ADDR_UDP_IPv6(addr).sin6_addr);			break;#endif	/* USE_IPV6 */		default:			break;	}}staticintadd_interface(net_if *inf){	int rc;	switch(NET_GET_TYPE(inf)) {		case NET_IF_PHY:			switch (NET_GET_TYPE(&NET_GET_IF_PHY_ADDR(inf))) {				case NET_ADDR_IPv4:					rc = add_if_ipv4(inf,&maddr);					break;#ifdef	USE_IPV6				case NET_ADDR_IPv6:					rc = add_if_ipv6(inf,&maddr6);					break;#endif	/* USE_IPV6 */				default:					return(SYS_ERROR);			}			break;		case NET_IF_VIF:			switch (NET_GET_TYPE(&NET_GET_IF_VIF_ADDR(inf))) {				case NET_ADDR_IPv4:					rc = add_vif_ipv4(inf);					break;				default:					return(SYS_ERROR);			}			break;		default:			return(SYS_ERROR);	}	if (debug_file)		fds_print(debug_file, " after Add Interface");

⌨️ 快捷键说明

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