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

📄 rsvp_trans.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
{	int status = SYS_NOERROR;	/* Receive Multicast RSVP/UDP/IPv6 (Specified Interface) */	if (FAILED(drop_multicast_ipv6(fd6_pu,inf,g)))		status = SYS_ERROR;	if (!rawmode) {		if (FAILED(drop_multicast_ipv6(fd6_pup,inf,g)))			status = SYS_ERROR;	}	return(status);}#endif	/* USE_IPV6 */#else	/* IP_DSTOPTS *//* *	These routines get complex for systems which cannot accept *	ancillary data to sendmsg() to control the interface or vif to *	use during the sending of a datagram in addition to router *	alert options and hop limits. */static int nvifs = 0;static int port_pu,port_pup,pmax = 0;static int plist[NET_ADDR_SIZE][FD_SETSIZE];static int vlist[NET_ADDR_SIZE];static int ipproto_udp = IPPROTO_UDP;static int set_hop_limit(int fd,int proto,int opt,void *option,int size);static int set_router_alert(int fd,int proto,int opt,void *options,int size);static int set_interface_ipv4(net_addr_type type,net_if *inf);static int socket_send_udp_ipv4(int proto);#ifdef	USE_IPV6static int set_interface_ipv6(net_addr_type type,net_if *inf);static int socket_send_udp_ipv6(int proto);#endif	/* USE_IPV6 */#ifndef	IP_PKTINFO/* *	This function receives the packets using recvfrom(). */staticintreceive(int fd,net_addr *from,void *msg,int len,net_if *inf){	int n,sz;	sz = sizeof(NET_GET_ADDR(from));	n = recvfrom(fd,msg,len,0,		(struct sockaddr *) &NET_GET_ADDR(from),&sz);	if (FAILED(n))		return(n);	adjust(from,protocol_type[fd]);	*inf = interface[fd];	return(n);}#endif	/* IP_PKTINFO *//* *	Specific outgoing network interface, source address, hop count, *	and router alert option.  This function returns the file *	descriptor to use for the send operation. */staticintset_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){	int fd,opt,size;	struct udphdr uh;	static struct iovec iov[2];	struct sockaddr_in sin;	static u_char ra_ipv4[4] = {148, 4, 0, 0};	if (inf != NULL)		fd = set_interface_ipv4(type,inf);	else		fd = ulist[type];	if (FAILED(fd))		return(fd);	if (to != NULL) {		if (IN_IS_ADDR_MULTICAST(&to->sin_addr)) {			opt = IP_MULTICAST_TTL;#ifdef	SET_IP_TTL		}		else			opt = IP_TTL;#endif	/* SET_IP_TTL */		if (FAILED(set_hop_limit(fd,IPPROTO_IP,opt,				&hops,sizeof(hops))))			return(SYS_ERROR);#ifndef	SET_IP_TTL		}#endif	/* SET_IP_TTL */	}	if (FAILED(set_router_alert(fd,IPPROTO_IP,IP_OPTIONS,ra_ipv4,			(ra ? sizeof(ra_ipv4) : 0))))		return(SYS_ERROR);	hdr->msg_iov = iov;	if ((type == NET_ADDR_UDP_IPv4) && rawmode) {		if (from != NULL)			uh.uh_sport = from->sin_port;		else {			size = sizeof(sin);			if (FAILED(getsockname(fd,(struct sockaddr *) &sin,					&size)))				uh.uh_sport = 0;			else				uh.uh_sport = sin.sin_port;		}		uh.uh_dport = to->sin_port;		uh.uh_ulen = htons(len + sizeof(uh));		uh.uh_sum = htons(0);		/* RSVP checksum is enough */		iov[0].iov_base = (void *) &uh;		iov[0].iov_len = sizeof(uh);		iov[1].iov_base = msg;		iov[1].iov_len = len;		hdr->msg_iovlen = 2;	}	else {		iov[0].iov_base = msg;		iov[0].iov_len = len;		hdr->msg_iovlen = 1;	}	return(fd);}/* *	We must create a RAW socket to send RSVP traffic on a per *	phyical interface basis.  This is due to the fact that the *	socket can only be bound once and cannot to rebound to another *	interface dynamically.  This is also true for UDP/IP traffic. */staticintadd_if_ipv4(net_if *inf,struct in_addr *g){	int fd,status = SYS_NOERROR;	struct in_addr in;	struct sockaddr_in sin;	in = NET_GET_ADDR_IPv4(&NET_GET_IF_PHY_ADDR(inf));	NET_SOCKADDR_IPv4(&sin,in);	/* Send Raw RSVP/IPv4 to this Interface	 */	fd = socket_ipv4(SOCK_RAW,ipproto_rsvp,NET_ADDR_IPv4);	if (FAILED(fd)) {		if (rawmode)			status = SYS_ERROR;	}	else {		interface[fd] = *inf;		if (FAILED(bind(fd,(struct sockaddr *) &sin,sizeof(sin)))) {			net_error(NET_ERROR_SYSTEM,"bind");			failed(fd);			fd = SYS_ERROR;			status = SYS_ERROR;		}		/* Set to send raw multicast packet to this interface.		 * (Ignore errors on non-multicast interfaces)		 */		setsockopt(fd,IPPROTO_IP,IP_MULTICAST_IF,			(char *) &in,sizeof(in));	}	plist[NET_ADDR_IPv4][pmax] = fd;	/* Receive Multicast RSVP/UDP/IPv4 on this interface	 */	if (FAILED(join_multicast_ipv4(fd_pu,inf,g)))		status = SYS_ERROR;	if (!rawmode) {		if (FAILED(join_multicast_ipv4(fd_pup,inf,g)))			status = SYS_ERROR;	}	/* Receive Unicast RSVP/UDP/IPv4 on this interface	 */	NET_SOCKADDR_UDP_IPv4(&sin,in,rawmode ? port_pu : port_pup);	fd = socket_recv_udp_ipv4(&sin);	if (FAILED(fd))		status = SYS_ERROR;	else		interface[fd] = *inf;	if (rawmode) {		/* Send RSVP/UDP/IPv4 on this interface		 */		fd = socket_send_udp_ipv4(ipproto_udp);		if (FAILED(fd))			status = SYS_ERROR;		else			interface[fd] = *inf;	}	if (!FAILED(fd)) {		/* Ignore errors on non-multicast interfaces */		setsockopt(fd,IPPROTO_IP,IP_MULTICAST_IF,			(char *) &in,sizeof(in));		plist[NET_ADDR_UDP_IPv4][pmax++] = fd;	}	return(status);}staticintdel_if_ipv4(net_if *inf,struct in_addr *g){	/* FIX: Finish */	return(SYS_ERROR);}/* *	We can create a RAW socket to listen for RSVP traffic on a per *	vif basis.  This will let us to determine on which vif a *	datagram was received. */staticintadd_vif_ipv4(net_if *inf){	int fd;#ifdef	IP_RSVP_VIF_ON	int vif;#endif	/* IP_RSVP_VIF_ON */	if (!rawmode)		return(SYS_NOERROR);	if (nvifs++ == 0)		rsvp_off_ipv4(ulist[NET_ADDR_IPv4]);	/* Receive RSVP/IPv4 (Specified VIF) */	fd = socket_ipv4(SOCK_RAW,ipproto_rsvp,NET_ADDR_IPv4);	if (FAILED(fd))		return(fd);#ifdef	IP_RSVP_VIF_ON	vif = NET_GET_IF_VIF_ID(inf);	if (FAILED(setsockopt(fd,IPPROTO_IP,IP_RSVP_VIF_ON,			(char *) &vif,sizeof(vif)))) {		net_error(NET_ERROR_SYSTEM,"IP_RSVP_VIF_ON");		return(failed(fd));	}#endif	/* IP_RSVP_VIF_ON */	FD_SET(fd,&rset);	interface[fd] = *inf;	finalize[fd] = rsvp_vif_off_ipv4;	return(SYS_NOERROR);}staticintdel_vif_ipv4(net_if *inf){	if (!rawmode)		return(SYS_NOERROR);	if (--nvifs == 0)		rsvp_on_ipv4(ulist[NET_ADDR_IPv4]);	/* FIX: Finish */	return(SYS_ERROR);}staticintrsvp_vif_off_ipv4(int fd){#ifdef	IP_RSVP_VIF_OFF	int vif;	vif = NET_GET_IF_VIF_ID(&interface[fd]);	if (FAILED(setsockopt(fd,IPPROTO_IP,IP_RSVP_VIF_OFF,			(char *) &vif,sizeof(vif)))) {		net_error(NET_ERROR_SYSTEM,"IP_RSVP_VIF_OFF");		return(SYS_ERROR);	}#endif	/* IP_RSVP_VIF_OFF */	return(SYS_NOERROR);}/*	Sending a packet.  Map inf to file descriptor and sets to *	send multiast out specific interface. */staticintset_interface_ipv4(net_addr_type type, net_if *inf){	int i,fd,infn;	net_addr *addr;	struct in_addr in;	switch(NET_GET_TYPE(inf)) {		case NET_IF_PHY:			if (NET_GET_TYPE(&NET_GET_IF_PHY_ADDR(inf))					!= NET_ADDR_IPv4)				return(SYS_ERROR);			for (i = 0;i < pmax; i++) {				fd = plist[type][i];				if (FAILED(fd))					continue;				if (net_if_equal(inf,&interface[fd]))					return(fd);			}			return(SYS_ERROR);		case NET_IF_VIF:			addr = &NET_GET_IF_VIF_ADDR(inf);			if (NET_GET_TYPE(addr) != NET_ADDR_IPv4)				return(SYS_ERROR);			in = NET_GET_ADDR_IPv4(addr);			fd = vlist[type];			if (FAILED(setsockopt(fd,IPPROTO_IP,IP_MULTICAST_IF,					(char *) &in,sizeof(in)))) {				net_error(NET_ERROR_SYSTEM,"IP_MULTICAST_IF");				return(SYS_ERROR);			}#ifdef	SOLARIS			infn = 1;			if (FAILED(setsockopt(fd,SOL_SOCKET,SO_DONTROUTE,					(char *) &infn,sizeof(infn)))) {				net_error(NET_ERROR_SYSTEM,"SO_DONTROUTE");				return(failed(fd));			}#else	/* SOLARIS */			infn = NET_GET_IF_VIF_ID(inf);#ifndef	linux			if (FAILED(setsockopt(fd,IPPROTO_IP,IP_MULTICAST_VIF,					(char *) &infn,sizeof(infn)))) {				net_error(NET_ERROR_SYSTEM,"IP_MULTICAST_VIF");				return(SYS_ERROR);			}#endif	/* linux */#endif	/* SOLARIS */			return(fd);		default:			return(SYS_ERROR);	}}staticintsocket_send_udp_ipv4(int proto){	if (rawmode)		return(socket_ipv4(SOCK_RAW,proto,NET_ADDR_UDP_IPv4));	return(socket_ipv4(SOCK_DGRAM,PF_UNSPEC,NET_ADDR_UDP_IPv4));}/* *	Sending datagrams on physical interfaces and virtual interfaces *	is handled by differing interfaces.  Create a socket for *	sending on any virtual interface.  Sockets for sending on a *	physical interface will be done on a per interface basis *	below. */staticint#ifdef	USE_IPV6initialize(int pu,int pup,struct in_addr *g,struct in6_addr *g6)#else	/* USE_IPV6 */initialize(int pu,int pup,struct in_addr *g)#endif	/* USE_IPV6 */{	int fd,status = SYS_NOERROR;	struct protoent *p;	p = getprotobyname("udp");	if (p != NULL)		ipproto_udp = p->p_proto;	port_pu = pu;	port_pup = pup;	for (fd = 0;fd < FD_SETSIZE; fd++)		interface[fd] = unknown;	/* Send RSVP/UDP/IPv4 (Any Interface) */	if (rawmode) {		fd = socket_send_udp_ipv4(ipproto_udp);		if (FAILED(fd))			status = SYS_ERROR;		ulist[NET_ADDR_UDP_IPv4] = fd;	}	/* Send RSVP/IPv4 (Specified VIF) */	fd = socket_ipv4(SOCK_RAW,ipproto_rsvp,NET_ADDR_IPv4);	if (rawmode && FAILED(fd))		status = SYS_ERROR;	vlist[NET_ADDR_IPv4] = fd;	/* Send RSVP/UDP/IPv4 (Specified VIF) */	fd = socket_send_udp_ipv4(ipproto_udp);	vlist[NET_ADDR_UDP_IPv4] = fd;	if (FAILED(fd))		status = SYS_ERROR;#ifdef	USE_IPV6	/* Send RSVP/UDP/IPv6 (Any Interface) */	if (rawmode) {		fd = socket_send_udp_ipv6(ipproto_udp);		if (FAILED(fd))			status = SYS_ERROR;		ulist[NET_ADDR_UDP_IPv6] = fd;	}	/* Send RSVP/IPv6 (Specified VIF) */	fd = socket_ipv6(SOCK_RAW,ipproto_rsvp,NET_ADDR_IPv6);	if (rawmode && FAILED(fd))		status = SYS_ERROR;	vlist[NET_ADDR_IPv6] = fd;	/* Send RSVP/UDP/IPv6 (Specified VIF) */	fd = socket_send_udp_ipv6(ipproto_udp);	vlist[NET_ADDR_UDP_IPv6] = fd;	if (FAILED(fd))		status = SYS_ERROR;#endif	/* USE_IPV6 */	return(status);}/* *	Set the maximum hop limit.  Once set, it remains set until it *	is turned off. */staticintset_hop_limit(int fd,int proto,int opt,void *option,int size){	if (FAILED(setsockopt(fd,proto,opt,option,size))) {		net_error(NET_ERROR_SYSTEM,"hop count");		return(SYS_ERROR);	}	return(SYS_NOERROR);}/* *	Set the Router Alert Option.  Once set, it remains set until it *	is turned off. */staticintset_router_alert(int fd,int proto,int opt,void *options,int size){	if (FAILED(setsockopt(fd,proto,opt,options,size))) {		net_error(NET_ERROR_SYSTEM,"Router alert");		return(SYS_ERROR);	}	return(SYS_NOERROR);}#ifdef	USE_IPV6staticintset_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){	int fd,ihops = hops;	static struct iovec iov[2];	if (inf != NULL)		fd = set_interface_ipv6(type,inf);	else		fd = ulist[type];	if (FAILED(fd))		return(fd);	if (to != NULL) {		if (FAILED(set_hop_limit(fd,IPPROTO_IPV6,				(IN6_IS_ADDR_MULTICAST(&to->sin6_addr) ?				IPV6_MULTICAST_HOPS : IPV6_UNICAST_HOPS),				&ihops,sizeof(ihops)))) {#ifndef	WORKAROUNDS			return(SYS_ERROR);#endif	/* WORKAROUNDS */		}	}	/* FIX: v6 router alert */	hdr->msg_iov = iov;	/* FIX: v6 udp header *//*	if ((type == NET_ADDR_UDP_IPv6) && rawmode) {		return(SYS_ERROR);	}	else {*/		iov[0].iov_base = msg;		iov[0].iov_len = len;		hdr->msg_iovlen = 1;/*	}*/	return(fd);}staticintadd_if_ipv6(net_if *inf,struct in6_addr *g){	int fd,status = SYS_NOERROR;	unsigned int index;	struct in6_addr in;	struct sockaddr_in6 sin;	in = NET_GET_ADDR_IPv6(&NET_GET_IF_PHY_ADDR(inf));	NET_SOCKADDR_IPv6(&sin,in);	/* Send RSVP/IPv6 (Specified Interface) */	fd = socket_ipv6(SOCK_RAW,ipproto_rsvp,NET_ADDR_IPv6);	if (FAILED(fd)) {		if (rawmode)			status = SYS_ERROR;	}	else {		interface[fd] = *inf;		if (FAILED(bind(fd,(struct sockaddr *) &sin,sizeof(sin)))) {#ifndef	WORKAROUNDS			net_error(NET_ERROR_SYSTEM,"bind");			failed(fd);			fd = SYS_ERROR;			status = SYS_ERROR;#endif	/* WORKAROUNDS */		}		index = NET_GET_IF_PHY_ID(inf);		/* Ignore errors on non-multicast interfaces */		setsockopt(fd,IPPROTO_IPV6,IPV6_MULTICAST_IF,			(char *) &index,sizeof(index));	}	plist[NET_ADDR_IPv6][pmax] = fd;	/* Receive Multicast RSVP/UDP/IPv6 (Specified Interface) */	if (FAILED(join_multicast_ipv6(fd6_pu,inf,g)))		status = SYS_ERROR;	if (!rawmode) {		if (FAILED(join_multicast_ipv6(fd6_pup,inf,g)))			status = SYS_ERROR;	}	/* Receive Unicast RSVP/UDP/IPv6 (Specified Interface) */	NET_SOCKADDR_UDP_IPv6(&sin,in,rawmode ? port_pu : port_pup);	fd = socket_recv_udp_ipv6(&sin);	if (FAILED(fd))		status = SYS_ERROR;	else		interface[fd] = *inf;/*	if (rawmode) {*/		/* Send RSVP/UDP/IPv6 (Specified Interface) *//*		fd = socket_send_udp_ipv6(ipproto_udp);		if (FAILED(fd))			status = SYS_ERROR;		else			interface[fd] = *inf;	}*/	plist[NET_ADDR_UDP_IPv6][pmax++] = fd;	index = NET_GET_IF_PHY_ID(inf);	/* Ignore errors on non-multicast interfaces */	setsockopt(fd,IPPROTO_IPV6,IPV6_MULTICAST_IF,		(char *) &index,sizeof(index));	return(status);}staticintdel_if_ipv6(net_if *inf,struct in6_addr *g){	/* FIX: Finish */	return(SYS_ERROR);}staticintset_interface_ipv6(net_addr_type type,net_if *inf){	int i,fd;	switch(NET_GET_TYPE(inf)) {		case NET_IF_PHY:			if (NET_GET_TYPE(&NET_GET_IF_PHY_ADDR(inf))					!= NET_ADDR_IPv6)				return(SYS_ERROR);			for (i = 0;i < pmax; i++) {				fd = plist[type][i];				if (FAILED(fd))					continue;				if (net_if_equal(inf,&interface[fd]))					return(fd);			}			return(SYS_ERROR);		default:			return(SYS_ERROR);	}}staticintsocket_send_udp_ipv6(int proto){	/* FIX: v6 udp header *//*	if (rawmode)		return(socket_ipv6(SOCK_RAW,proto,NET_ADDR_UDP_IPv6));*/	return(socket_ipv6(SOCK_DGRAM,PF_UNSPEC,NET_ADDR_UDP_IPv6));}#endif	/* USE_IPV6 */#endif	/* IP_DSTOPTS *//*	Print out active file descriptors */void   fds_print(FILE *fo, char *title) {	int	fd, type = 0;	const char *inf_str, *net_if_print(const net_if *);	char    *netif_type_name[] = {"unk", "PHY", "VIF", "ID ", "STR"};	char	*netaddr_type_name[] = {"Raw IPv4", "UDP IPv4",					"Raw IPv6", "UDP IPv6"};	if (fo == NULL)		return;	fprintf(fo, "Network File Descriptors: %s\n", title);	for (fd = 0;fd < FD_SETSIZE; fd++) {	    if (FD_ISSET(fd, &fset)) {		inf_str = net_if_print(&interface[fd]);							fprintf(fo, "fd=%d  net_ifType=%s Inf=%s", fd, 				netif_type_name[protocol_type[fd]], inf_str);		if (fd == fd_pu)			fprintf(fo, " UDP Pu");		if (fd == fd_pup)			fprintf(fo, " UDP Pu'");		if (FD_ISSET(fd, &rset))			fprintf(fo, " RECV");		#if !defined(IP_DSTOPTS)		for (type=0; type < NET_ADDR_SIZE; type++) {			int i;			for (i=0; i < pmax; i++) {				if (fd == plist[type][i])					fprintf(fo, " SEND %s",						netaddr_type_name[type]);			}			if (fd == vlist[type])				fprintf(fo, " VIF Addr %s", 						netaddr_type_name[type]);		}#endif /* IP_DSTOPTS */			fprintf(fo, "\n");	    }	}}

⌨️ 快捷键说明

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