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

📄 rsvp_netio.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * @(#) $Id: rsvp_netio.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_netio.c  ****************************** *                                                                   * *                   Network I/O routines                            * *                                                                   * *********************************************************************//****************************************************************************            RSVPD -- ReSerVation Protocol Daemon                USC Information Sciences Institute                Marina del Rey, California		Original Version: Shai Herzog, Nov. 1993.		Current Version:  Steven Berson & Bob Braden, May 1996.  Copyright (c) 1996 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 "rsvp_daemon.h"#include "rsvp_api.h"#include "rapi_lib.h"#include <sys/stat.h>#include <fcntl.h>#if	(defined(linux) && defined(USE_IPV6))#include <netinet/ip6.h>#endif	/* (defined(linux) && defined(USE_IPV6)) */#if	(defined(SOLARIS) && defined(USE_IPV6))struct ip6_hdr {	union {		struct ip6_hdrctl {			u_int32_t	ip6_un1_flow;	/* 24 bits of flow-ID */			u_int16_t	ip6_un1_plen;	/* payload length */			u_int8_t	ip6_un1_nxt;	/* next header */			u_int8_t	ip6_un1_hlim;	/* hop limit */		} ip6_un1;		u_int8_t	ip6_un2_vfc;	/* 4 bits version, 4 bits priority */	} ip6_ctlun;	struct in6_addr	ip6_src;	/* source address */	struct in6_addr	ip6_dst;	/* destination address */};#define	ip6_vfc		ip6_ctlun.ip6_un2_vfc#define	ip6_flow	ip6_ctlun.ip6_un1.ip6_un1_flow#define	ip6_plen	ip6_ctlun.ip6_un1.ip6_un1_plen#define	ip6_nxt		ip6_ctlun.ip6_un1.ip6_un1_nxt#define	ip6_hlim	ip6_ctlun.ip6_un1.ip6_un1_hlim#define	ip6_hops	ip6_ctlun.ip6_un1.ip6_un1_hlim#endif	/* (defined(SOLARIS) && defined(USE_IPV6)) */#if	(defined(freebsd) && defined(USE_IPV6))#define	STEVENS_API#include <netinet/ip6.h>#endif	/* (defined(freebsd) && defined(USE_IPV6)) */#define UCAST_TTL	63/* Sockets and addresses */struct in_addr		encap_group;			/* Gu */u_int16_t		encap_port;			/* Pu  */u_int16_t		encap_portp;			/* Pu' */net_addr		*encap_router;net_addr		encap_mc_addr;#ifdef	USE_IPV6struct in6_addr		encap_group6;			/* Gu */net_addr		encap_mc_addr6;#endif	/* USE_IPV6 *//* External declarations */extern char *Type_name[];extern int Test_mode;extern net_addr *tsttun_vec;extern int shift;extern int bmptoif(bitmap *);extern int rsrr_route_query(void*,void *,net_addr *,net_addr *,int,int *,bitmap *);/* forward declarations */static int send_pkt(net_addr *to,net_addr *from,void *msg,int len,		int vif,int infn,int hops,int ra);static int	IsLocal(net_addr *,int *);static net_addr * udp_addr(net_addr *to,int port);static net_addr * encap_addr(net_addr *to);static int	rsvp_pkt_process_1(struct packet *, net_addr *, int);static int	udp_input(net_addr *from,char *msg,int len,net_if *inf);static int	consume_input(struct packet *packet,net_addr *from,net_if *inf);static int	raw_input_ipv4(net_addr *from,char *msg,int len,net_if *inf);#ifdef	USE_IPV6static int	raw_input_ipv6(net_addr *from,char *msg,int len,net_if *inf);#endif	/* USE_IPV6 *//* *  send_pkt_out_if(): Send (unicast) RSVP packet to specified previous *		hop via specified physical interface (or -1). * *		[The outgoing interface is not strictly required to send *		unicast messages, but do need it to choose encryption key.] */intsend_pkt_out_if(	int		 outif,	RSVP_HOP	*hopp,	struct packet	*pkt)	{	net_addr *to;	net_addr *src = NULL;	int		 mode = 0;	assert(!IsHopAPI(hopp)); 	to = hop_addr(hopp);	pkt->pkt_ttl = UCAST_TTL;	if (outif >= 0)		src = get_if(outif);	Incr_ifstats(outif, rsvpstat_msgs_out[pkt->pkt_map->rsvp_msgtype]);	mode = build_send_pkt(outif, to, src, pkt);	if (IsDebug(DEBUG_ALL)) {		char	tmp[32];		if (outif >= 0)			sprintf(tmp, "%d=>%s > %.16s/%d\n",					outif, IF_NAME(outif),					net_addr_host(to), pkt->pkt_ttl);		else			sprintf(tmp, "> %.16s/%d\n",					net_addr_host(to), pkt->pkt_ttl);		log_event(LOGEV_Send_UDP+mode-1,			Type_name[pkt->pkt_map->rsvp_msgtype],			pkt->pkt_map->rsvp_session, tmp);		if (IsDebug(DEBUG_IO))	    		print_rsvp(pkt);	}	return(0);}/* *  send_pkt_to():  *              Send an RSVP packet to specified inet_addr:port entity.  *              This is typically used for UDP diagnostics. *              Rsvptrace uses this to send UDP DREQ packets. *              outif is typically -1. For multicast destinations, it has *              the usual meaning.       */                             intsend_pkt_to(        int              outif,        net_addr	*toaddr,        struct packet   *pkt)        {        net_addr	*srcaddrp = NULL;        int            	mode = 0;        switch(NET_GET_TYPE(toaddr)) {	      case NET_ADDR_UDP_IPv4:		assert((NET_GET_ADDR_IPv4(toaddr)).s_addr != INADDR_ANY);		assert((NET_GET_ADDR_UDP_IPv4(toaddr)).sin_port != 0);        /*      TTL setup is only for unicast packets. If this was a diagnostics reply to  *      a multicast address, ttl would have already been set. */     		if(!IN_IS_ADDR_MULTICAST(&NET_GET_ADDR_IPv4(toaddr)))		  pkt->pkt_ttl = UCAST_TTL;		if (outif >= 0)		  srcaddrp = get_if(outif);		break ;	      case NET_ADDR_UDP_IPv6:/* 	IPv6 is currently not yet expected to be used by diagnostics */		break ;			      default:		break ;	}                 /* 	The PKTFLG_NOENCAP helps override the RSVP UDP encapsulation rules  * 	for the diagnostics reply scenario. In this case, a UDP DREP has to * 	be sent to the diagnostic requester's ephemeral UDP port  */	pkt->pkt_flags |= PKTFLG_NOENCAP ;	Incr_ifstats(outif, rsvpstat_msgs_out[pkt->pkt_map->rsvp_msgtype]);        mode = build_send_pkt(outif, toaddr, srcaddrp, pkt);        if (IsDebug(DEBUG_ALL)) {                char    tmp[32];                if (outif >= 0)                        sprintf(tmp, "%d> %.16s/%d\n", outif,                                        net_addr_host(toaddr), pkt->pkt_ttl);                else                        sprintf(tmp, "> %.16s/%d\n",                                        net_addr_host(toaddr), pkt->pkt_ttl);                log_event(LOGEV_Send_UDP+mode-1,                        Type_name[pkt->pkt_map->rsvp_msgtype],                        pkt->pkt_map->rsvp_session, tmp);                if (IsDebug(DEBUG_IO))                        print_rsvp(pkt);        }        if (mode < 0)          return(-1) ;        return(0);}/* * send_pkt_out_vif(): Send Path, PathTear, or ResvErr msg with specific *		dest and src addresses to specified vif. * *	XXX???  If encap_router address is defined, unicast a unicast UDP *	XXX???	copy to that address; this is to allow hosts inside a *	XXX???	firewall to send a Path message to the first-hop router. */intsend_pkt_out_vif(	int		 vif,	Session		*destp,	FILTER_SPEC	*filtp,	struct packet	*pkt)	{	net_addr	*to;	net_addr	*src;	int		mode = 0;		assert(!IsNumAPI(vif));		/* Not API */	src = filterspec_addr(filtp);	to = session_addr(destp->d_session);	if (encap_router != NULL) {		/* If a -R cmd-line option was given to specify the address		 * of an RSVP-capable router, unicast a UDP copy of pkt to		 * address.  Note: this could be generalized to a list.		 */		pkt->pkt_flags = PKTFLG_USE_UDP;	}	Incr_ifstats(vif, rsvpstat_msgs_out[pkt->pkt_map->rsvp_msgtype]);	mode = build_send_pkt(vif, to, src, pkt);	if (mode < 0)		return -1;	if (IsDebug(DEBUG_ALL)) {		char	tmp[32];		sprintf(tmp, "%d=>%s > %.16s/%d\n", vif, IF_NAME(vif),					net_addr_host(to), pkt->pkt_ttl);		log_event(LOGEV_Send_UDP+mode-1,			Type_name[pkt->pkt_map->rsvp_msgtype],			pkt->pkt_map->rsvp_session, tmp);		if (IsDebug(DEBUG_IO))	    		print_rsvp(pkt);	}	return(0);}/* *	do_sendmsg(): Send buffer containing RSVP message: *		* To specified vif; -1 => unspecified (Resv msgs) *		* To destination (addr,port) = *to *		* From IP source address = *src; NULL => unspecified *		* tp specified TTL (unless UDP encaps is used) * *	This routine figures out whether UDP and/or raw encapsualated copies *	are needed, and chooses the appropriate socket.  The socket choice *	is quite system-dependent. */intdo_sendmsg(	int vif,	net_addr	*to,	net_addr	*src,	int		 flags,	u_char		 ttl,	u_char		*data,	int		 len)	{	u_char		encap_ttl;	int mc,local,mode = 0;	net_addr *addr;	local = IsLocal(to,&mc);	if (vif >= 0) {		if (!(IF_FLAGS(vif)&IF_FLAG_IFF_UP))			return(0); /* Should never happen? */		if (mc && !(IF_FLAGS(vif)&IF_FLAG_IFF_MC))			return(0); /* Should never happen? */		encap_ttl = if_vec[IF_UNICAST(vif)].if_udpttl;	} else	        encap_ttl = RSVP_TTL_MAX;	if (flags & PKTFLG_NOENCAP) {/* 	send packet to a UDP target with a port that is not Pu or Pu' */		if (mc)		  encap_ttl = ttl ;		if (FAILED(send_pkt(to,src,data,len,mc,vif,encap_ttl,FALSE)))			log(LOG_ERR,errno,"send_pkt");		return(1);	}	if (!net_has_rawmode()) {		/*	UDP-only host.		 */		if (mc) {			/*	Multicast Path msg: => (G*, P)			 */			addr = encap_addr(to);		}		else if (vif >= 0 && !local) {			/*	Unicast Path msg to non-local D => (Ra, Pu)			 */			if (encap_router == NULL) {				log(LOG_ERR,0,					"No UDP Encapsulation Router (Ra)");				return(0);			}			addr = udp_addr(encap_router,encap_port);		}		else {			/* 	Unicast Path/Resv msg to local D => (D, Pu)			 */			addr = udp_addr(to,encap_port);		}		if (FAILED(send_pkt(addr,src,data,len,mc,vif,				encap_ttl,FALSE)))			log(LOG_ERR,errno,"send_pkt");		return(1);	}	else {		/*		 *	Send raw encapsulation		 */		if (mc && (vif > shift) && (ttl < 			vif_list[if_vec[vif].if_index].threshold)) {			/*			 * if it's multicast packet, and vif			 * is in the virtual interface space,			 * also the ttl value is less than the			 * threshold value for that virtual			 * interface, then we drop the packet			 * and return			 */			Incr_ifstats(vif, rsvpstat_path_threshold);			return (0);		}		if (FAILED(send_pkt(to,src,data,len,mc,vif,ttl,				(flags & PKTFLG_Send_RA))))			log(LOG_ERR,errno,"send_pkt");		mode = 2;	}	if (((vif >= 0 && (IF_FLAGS(vif) & IF_FLAG_UseUDP)) ||			(flags & PKTFLG_USE_UDP)) && local) {		/*		 *	Need UDP encapsulation on this interface, but		 *	we are capable of sending raw packets => (D, Pu')		 */

⌨️ 快捷键说明

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