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

📄 scrapi.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "scrapi.h"#include <sys/time.h>#ifdef	linux#include <linux/sockios.h>#else	/* linux */#include <sys/sockio.h>#endif	/* linux */#include <arpa/inet.h>#include <net/if.h>#include <netdb.h>#include <strings.h>#include <limits.h>#include <unistd.h>#include <rapi_err.h>/* * @(#) $Id: scrapi.c,v 1.2 2000/08/17 02:11:09 bogawa Exp $ *//****************************************************************************		SCRAPI: A Simplied RSVP API                USC Information Sciences Institute                Marina del Rey, California		Original Version:  Bob Lindell, March 1998.  Copyright (c) 1998 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.********************************************************************////  XXX this doesn't compile w/ IPV6 set#undef USE_IPV6/****************************************************************************** * *	Strictly RFC 2133 * *****************************************************************************/#ifndef	INET_ADDRSTRLEN#define	INET_ADDRSTRLEN		sizeof("XXX.XXX.XXX.XXX")#endif	/* INET_ADDRSTRLEN */#ifdef	USE_IPV6extern const struct in6_addr in6addr_any;#endif	/* USE_IPV6 */#ifdef	sunstatic const char * inet_ntop(int af,const void *src,char *dst,size_t size);static int inet_pton(int af,const char *src,void *dst);static struct hostent * gethostbyname2(const char *name,int af);#endif	/* sun *//****************************************************************************** * *	Extensions to RFC 2133 * *****************************************************************************/#ifdef	USE_IPV6#define	MAX_ADDRSTRLEN		INET6_ADDRSTRLEN#else	/* USE_IPV6 */#define	MAX_ADDRSTRLEN		INET_ADDRSTRLEN#endif	/* USE_IPV6 */#define	MAX_ADDRPORTSTRLEN	(MAX_ADDRSTRLEN + sizeof("/XXXXX"))#define	MAX_HOSTSTRLEN		MAXHOSTNAMELEN#define	MAX_HOSTPORTSTRLEN	(MAX_HOSTSTRLEN + sizeof("/XXXXX"))#define	IN_IS_ADDR_MULTICAST(x)		IN_MULTICAST(ntohl((x)->s_addr))#define	IN_ARE_ADDR_EQUAL(x,y)		((x)->s_addr == (y)->s_addr)static const struct in_addr inaddr_any;/****************************************************************************** * *	Macros and functions for socket structures. * *****************************************************************************/#ifdef	__FreeBSD__#define	NET_SOCKADDR_SIZE_IPv4(x) \	{ \		(x)->sin_len = sizeof(struct sockaddr_in); \	}#define	NET_SOCKADDR_SIZE_IPv6(x) \	{ \		(x)->sin6_len = sizeof(struct sockaddr_in6); \	}#else	/* __FreeBSD__ */#define	NET_SOCKADDR_SIZE_IPv4(x)#define	NET_SOCKADDR_SIZE_IPv6(x)#endif	/* __FreeBSD__ */#define NET_SOCKADDR_IPv4(x,addr)	NET_SOCKADDR_UDP_IPv4(x,addr,htons(0))#define	NET_SOCKADDR_UDP_IPv4(x,addr,port) { \		memset((char *) (x),0,sizeof(struct sockaddr_in)); \		(x)->sin_family = AF_INET; \		(x)->sin_addr = addr; \		(x)->sin_port = port; \		NET_SOCKADDR_SIZE_IPv4(x); \	}#ifdef	USE_IPV6#define NET_SOCKADDR_IPv6(x,addr)	NET_SOCKADDR_UDP_IPv6(x,addr,htons(0))#define	NET_SOCKADDR_UDP_IPv6(x,addr,port) { \		memset((char *) (x),0,sizeof(struct sockaddr_in6)); \		(x)->sin6_family = AF_INET6; \		(x)->sin6_addr = addr; \		(x)->sin6_port = port; \		NET_SOCKADDR_SIZE_IPv6(x); \	}#endif	/* USE_IPV6 */#define	SAP(x)		((struct sockaddr *) (x))#define	SAP4(x)		((struct sockaddr_in *) (x))#define	SAP6(x)		((struct sockaddr_in6 *) (x))static int sockaddr_equal(const struct sockaddr *x,	const struct sockaddr *y);static int sockaddr_equal_wild(const struct sockaddr *x,	const struct sockaddr *y);static int sockaddr_assign(struct sockaddr *x,const struct sockaddr *y);/****************************************************************************** * *	Useful Definitions and Macros * *****************************************************************************/#ifndef	TRUE#define	TRUE (0 == 0)#endif	/* TRUE */#ifndef	FALSE#define	FALSE (0 != 0)#endif	/* FALSE */#define	SYS_ERROR		(-1)#define	SYS_NOERROR		0#define	FAILED(x)		((x) == SYS_ERROR)#define C_MAX(x,y)		(((x) >= (y)) ? (x) : (y))#define C_MIN(x,y)		(((x) <= (y)) ? (x) : (y))/****************************************************************************** * *	SCRAPI and RAPI Definitions and Macros * *****************************************************************************/#define	MAXSESSIONS		256#define	Object_Type(x)		(((rapi_hdr_t *) (x))->form)#define	Object_Length(x)	(((rapi_hdr_t *) (x))->len)#define	Object_Next(type,x)	((type *) (((char *) (x)) + Object_Length(x)))#define	MAX_INTERFACES		32#define	MIN_PACKET_SIZE		64#define	MAX_PACKET_SIZE		576/* *	Status bits */#define	S_NONE			0x00000000#define	S_RESV			0x00000001#define	S_SEND_STATES		0x0000000f#define	S_PATH			0x00000010#define	S_CONFIRM		0x00000020#define	S_RECV_STATES		0x000000f0#define	S_STATES		0x000000ff#define	S_PATH_REQUEST		0x00000100#define	S_SEND_REQUESTS		0x00000f00#define	S_RESV_REQUEST		0x00001000#define	S_RECV_REQUESTS		0x0000f000#define	S_REQUESTS		0x0000ff00#define	S_PATH_ERROR		0x00010000#define	S_SEND_ERRORS		0x000f0000#define	S_RESV_ERROR		0x00100000#define	S_RECV_ERRORS		0x00f00000#define	S_ERRORS		0x00ff0000#define	S_OPEN			0x01000000#define	S_SEND_NOT_REQUESTS	(S_SEND_STATES | S_SEND_ERRORS)#define	S_RECV_NOT_REQUESTS	(S_RECV_STATES | S_RECV_ERRORS)#define	S_SEND_ALL	(S_SEND_STATES | S_SEND_REQUESTS | S_SEND_ERRORS)#define	S_RECV_ALL	(S_RECV_STATES | S_RECV_REQUESTS | S_RECV_ERRORS)struct sender {	unsigned long status;	rapi_filter_t src;	rapi_flowspec_t spec;	struct sender *next;};typedef struct sender sender;struct session {	unsigned long status;	struct SOCKADDR dst;	int proto;	struct SOCKADDR src;	scrapi_style style;	enum qos_service_type service;	int errno;	sender *flows;};typedef struct session session;static FILE *eout = NULL;static FILE *dout = NULL;static session sessions[MAXSESSIONS];static int nsessions = 0;staticchar *errlist[] = {	"No error",				/* 0 */	"Syscall error, see errno",		/* 1 */	"Memory allocation error",		/* 2 */	"Invalid parameters",			/* 3 */	"Internal SCRAPI error",		/* 4 */	"Bad destination address",		/* 5 */	"Bad destination port",			/* 6 */	"Bad protocol number",			/* 7 */	"Bad source address",			/* 8 */	"Bad source port",			/* 9 */	"Request timed out",			/* 10 */	"No RSVP support",			/* 11 */	"Too many sessions"			/* 12 */};staticint map_errno[] = {	SCRAPI_ERRNO_NONE,		/* No error */	SCRAPI_ERRNO_PARAM,		/* Invalid parameter */	SCRAPI_ERRNO_SESSION,		/* Too many sessions */	SCRAPI_ERRNO_INTERNAL,		/* Sid out of legal range */	SCRAPI_ERRNO_INTERNAL,		/* Wrong n_filter/n_flow for style */	SCRAPI_ERRNO_INTERNAL,		/* Illegal reservation style */	SCRAPI_ERRNO_SYSCALL,		/* Some sort of syscall error */	SCRAPI_ERRNO_INTERNAL,		/* Parm list overflo */	SCRAPI_ERRNO_MEMORY,		/* Not enough memory */	SCRAPI_ERRNO_NORSVP,		/* Daemon doesn't respond */	SCRAPI_ERRNO_INTERNAL,		/* Object type error */	SCRAPI_ERRNO_INTERNAL,		/* Object length error */	SCRAPI_ERRNO_INTERNAL,		/* No sender tspec in rapi_sender */	SCRAPI_ERRNO_INTERNAL,		/* Intserv format error */	SCRAPI_ERRNO_INTERNAL,		/* IPSEC: Conflicting C-type */	SCRAPI_ERRNO_PROTO,		/* IPSEC: Protocol not AH|ESP */	SCRAPI_ERRNO_DSTPORT,		/* IPSEC: vDstPort is zero */	SCRAPI_ERRNO_PARAM,		/* IPSEC: Other parm error */	SCRAPI_ERRNO_INTERNAL,		/* Not defined */	SCRAPI_ERRNO_INTERNAL,		/* Not defined */	SCRAPI_ERRNO_INTERNAL,		/* Not defined */	SCRAPI_ERRNO_SRCADDR,		/* Sender addr not my interface */	SCRAPI_ERRNO_INTERNAL,		/* Recv addr not my interface */	SCRAPI_ERRNO_DSTPORT		/* Sport !=0 but Dport == 0 */};/****************************************************************************** * *	Utility functions for filter structures and the like. * *****************************************************************************/#ifdef	ISI_TESTstatic int flow_labels = FALSE;voidscrapi_internal_use_flow_labels(int on){	flow_labels = on;}static int gpi = FALSE;voidscrapi_internal_use_gpi(int on){	gpi = on;}#endif	/* ISI_TEST */#ifdef	USE_IPV6staticintsource_has_label(const struct sockaddr *s,unsigned long *port){#ifdef	ISI_TEST	if (flow_labels) {		*port = htonl(ntohs(scrapi_sockaddr_get_port(s)));		return(TRUE);	}#endif	/* ISI_TEST */	*port = htonl(0);	return(FALSE);}#endif	/* USE_IPV6 */staticintsource_has_gpi(const struct sockaddr *s,unsigned long *port){#ifdef	ISI_TEST	if (gpi) {		*port = htonl(ntohs(scrapi_sockaddr_get_port(s)));		return(TRUE);	}#endif	/* ISI_TEST */	*port = htonl(0);	return(FALSE);}staticrapi_filter_t *filter_from_sockaddr(const struct sockaddr *s){	unsigned long port;	static rapi_filter_t f;	if (s == NULL)		return(NULL);	switch (s->sa_family) {		case AF_INET:			if (source_has_gpi(s,&port)) {				Object_Type(&f) = RAPI_FILTERFORM_GPI;				Object_Length(&f) = sizeof(rapi_hdr_t)					+ sizeof(rapi_filter_gpi_t);				f.rapi_filtgpi4_addr = SAP4(s)->sin_addr;				f.rapi_filtgpi4_gpi = port;				return(&f);			}			Object_Type(&f) = RAPI_FILTERFORM_BASE;			Object_Length(&f) = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_base_t);			f.rapi_filt4 = *SAP4(s);			return(&f);#ifdef	USE_IPV6		case AF_INET6:			if (source_has_gpi(s,&port)) {				Object_Type(&f) = RAPI_FILTERFORM_GPI6;				Object_Length(&f) = sizeof(rapi_hdr_t)					+ sizeof(rapi_filter_gpi6_t);				f.rapi_filtgpi6_addr = SAP6(s)->sin6_addr;				f.rapi_filtgpi6_gpi = port;				return(&f);			}			if (source_has_label(s,&port)) {				Object_Type(&f) = RAPI_FILTERFORM_FL6;				Object_Length(&f) = sizeof(rapi_hdr_t)					+ sizeof(rapi_filter_fl6_t);				f.rapi_filtfl6_addr = SAP6(s)->sin6_addr;				f.rapi_filtfl6_fl = port;				return(&f);			}			Object_Type(&f) = RAPI_FILTERFORM_BASE6;			Object_Length(&f) = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_base6_t);			f.rapi_filt6 = *SAP6(s);			return(&f);#endif	/* USE_IPV6 */		default:			return(NULL);	}}staticintfilter_any(rapi_filter_t *f,int type){	struct SOCKADDR s;	Object_Type(f) = type;	switch (type) {		case RAPI_FILTERFORM_BASE:			Object_Length(f) = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_base_t);			NET_SOCKADDR_UDP_IPv4(SAP4(&s),inaddr_any,htons(0));			f->rapi_filt4 = *SAP4(&s);			return(TRUE);		case RAPI_FILTERFORM_GPI:			Object_Length(f) = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_gpi_t);			f->rapi_filtgpi4_addr = inaddr_any;			f->rapi_filtgpi4_gpi = htonl(0);			return(TRUE);#ifdef	USE_IPV6		case RAPI_FILTERFORM_BASE6:			Object_Length(f) = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_base6_t);			NET_SOCKADDR_UDP_IPv6(SAP6(&s),in6addr_any,htons(0));			f->rapi_filt6 = *SAP6(&s);			return(TRUE);		case RAPI_FILTERFORM_GPI6:			Object_Length(f) = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_gpi6_t);			f->rapi_filtgpi6_addr = in6addr_any;			f->rapi_filtgpi6_gpi = htonl(0);			return(TRUE);		case RAPI_FILTERFORM_FL6:			Object_Length(f) = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_fl6_t);			f->rapi_filtfl6_addr = in6addr_any;			f->rapi_filtfl6_fl = htonl(0);			return(TRUE);#endif	/* USE_IPV6 */		default:			return(FALSE);	}}staticintfilter_equal(const rapi_filter_t *x,const rapi_filter_t *y){	if (Object_Type(x) != Object_Type(y))		return(FALSE);	switch (Object_Type(x)) {		case RAPI_FILTERFORM_BASE:			return(sockaddr_equal(SAP(&x->rapi_filt4),				SAP(&y->rapi_filt4)));		case RAPI_FILTERFORM_GPI:			if (!IN_ARE_ADDR_EQUAL(&x->rapi_filtgpi4_addr,					&y->rapi_filtgpi4_addr))				return(FALSE);			return(x->rapi_filtgpi4_gpi == y->rapi_filtgpi4_gpi);#ifdef	USE_IPV6		case RAPI_FILTERFORM_BASE6:			return(sockaddr_equal(SAP(&x->rapi_filt6),				SAP(&y->rapi_filt6)));		case RAPI_FILTERFORM_GPI6:			if (!IN6_ARE_ADDR_EQUAL(&x->rapi_filtgpi6_addr,					&y->rapi_filtgpi6_addr))				return(FALSE);			return(x->rapi_filtgpi6_gpi == y->rapi_filtgpi6_gpi);		case RAPI_FILTERFORM_FL6:			if (!IN6_ARE_ADDR_EQUAL(&x->rapi_filtfl6_addr,					&y->rapi_filtfl6_addr))				return(FALSE);			return(x->rapi_filtfl6_fl == y->rapi_filtfl6_fl);#endif	/* USE_IPV6 */		default:			return(FALSE);	}}staticintfilter_equal_wild(const rapi_filter_t *x,const rapi_filter_t *y){	if (Object_Type(x) != Object_Type(y))		return(FALSE);	switch (Object_Type(x)) {		case RAPI_FILTERFORM_BASE:			return(sockaddr_equal_wild(SAP(&x->rapi_filt4),				SAP(&y->rapi_filt4)));		case RAPI_FILTERFORM_GPI:			if (!IN_ARE_ADDR_EQUAL(&x->rapi_filtgpi4_addr,					&y->rapi_filtgpi4_addr))				return(FALSE);			if (x->rapi_filtgpi4_gpi == htonl(0))				return(TRUE);			if (y->rapi_filtgpi4_gpi == htonl(0))				return(TRUE);			return(x->rapi_filtgpi4_gpi == y->rapi_filtgpi4_gpi);#ifdef	USE_IPV6		case RAPI_FILTERFORM_BASE6:			return(sockaddr_equal_wild(SAP(&x->rapi_filt6),				SAP(&y->rapi_filt6)));		case RAPI_FILTERFORM_GPI6:			if (!IN6_ARE_ADDR_EQUAL(&x->rapi_filtgpi6_addr,					&y->rapi_filtgpi6_addr))				return(FALSE);			if (x->rapi_filtgpi6_gpi == htonl(0))				return(TRUE);			if (y->rapi_filtgpi6_gpi == htonl(0))				return(TRUE);			return(x->rapi_filtgpi6_gpi == y->rapi_filtgpi6_gpi);		case RAPI_FILTERFORM_FL6:			if (!IN6_ARE_ADDR_EQUAL(&x->rapi_filtfl6_addr,					&y->rapi_filtfl6_addr))				return(FALSE);			if (x->rapi_filtfl6_fl == htonl(0))				return(TRUE);			if (y->rapi_filtfl6_fl == htonl(0))				return(TRUE);			return(x->rapi_filtfl6_fl == y->rapi_filtfl6_fl);#endif	/* USE_IPV6 */		default:			return(FALSE);	}}/****************************************************************************** * *	Utility functions for sender information. * *****************************************************************************/staticsender *get_sender(rapi_sid_t sid,const rapi_filter_t *src){	rapi_filter_t host;	session *sp;	sender *s,*w;	sp = &sessions[sid];	for (s = sp->flows;s != NULL;s = s->next)		if (filter_equal(&s->src,src))			return(s);	s = (sender *) malloc(sizeof(sender));	s->src = *src;	s->status = S_NONE;	/*	 *	Apply wild src status.	 */	filter_any(&host,Object_Type(src));	for (w = sp->flows;w != NULL;w = w->next) {		/*		 *	Wild src ports take precedence over wild srcs.		 */		if (filter_equal_wild(src,&w->src)) {			s->status |= w->status & S_REQUESTS;			break;		}		if (filter_equal(&host,&w->src))			s->status |= w->status & S_REQUESTS;	}	s->next = sp->flows;	sp->flows = s;	return(s);}staticvoidset_sender(rapi_sid_t sid,rapi_filter_t *src,rapi_flowspec_t *spec){	rapi_flowspec_t *r;	qos_flowspecx_t *q;	qos_tspecx_t *t;	session *sp;	sender *s;	t = &((rapi_tspec_t *) spec)->tspecbody_qosx;	if (t->spec_type != QOS_TSPEC)		return;	sp = &sessions[sid];	s = get_sender(sid,src);	r = &s->spec;	Object_Type(r) = RAPI_FLOWSTYPE_Simplified;	Object_Length(r) = sizeof(rapi_flowspec_t);	q = &r->specbody_qosx;	q->spec_type = sp->service;	q->xspec_r = t->xtspec_r;	q->xspec_R = t->xtspec_r;	q->xspec_S = 0;	q->xspec_b = t->xtspec_b;	q->xspec_p = t->xtspec_p;	q->xspec_m = t->xtspec_m;	q->xspec_M = t->xtspec_M;	s->status |= S_PATH;}staticvoidmod_sender(sender *s,enum qos_service_type service,unsigned long status){	if (status == S_NONE) {		/*		 *	Must retain PATH state status when we turn off		 *	a reservation.		 */		s->status &= ~S_RECV_ALL | S_PATH;		return;

⌨️ 快捷键说明

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