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

📄 rapi_lib.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 4 页
字号:
	fltr = (API_FilterSpec *) resp->resp_flows;	for (i = 0; i < resp->resp_nflwd; i++) {		copy_filterspec_d2i(fltr, tapi_filt, eapi_filt);		tapi_filt = (rapi_filter_t *) After_RAPIObj(tapi_filt);		n_filter++;		flow = (API_Flowspec *) After_APIObj(fltr);		if (API_IsPath(resp)) {#ifdef USE_NET_BO			NTOH_RAPIhdr(flow);			if (ntoh_rapi_flowspec(				    &((API_TSpec *)flow)->tspecbody_IS) < 0) {				rapi_errno = RAPI_ERR_INVAL;				goto err_exit;			}#endif /* USE_NET_BO */			copy_tspec_d2i((API_TSpec*)flow,					(rapi_tspec_t *)tapi_spec, eapi_spec,					sidp->flags&RAPI_USE_INTSERV);			tapi_spec= (rapi_flowspec_t *) After_RAPIObj(tapi_spec);			n_flowspec++;		}		else if (n_flowspec < 1) {#ifdef USE_NET_BO			NTOH_RAPIhdr(flow);			if (ntoh_rapi_flowspec(&flow->specbody_IS) < 0) {				rapi_errno = RAPI_ERR_INVAL;				goto err_exit;			}#endif /* USE_NET_BO */			copy_flowspec_d2i(flow, tapi_spec, eapi_spec,					sidp->flags&RAPI_USE_INTSERV);			tapi_spec = (rapi_flowspec_t *) After_RAPIObj(tapi_spec);			n_flowspec++;		}					fltr = (API_FilterSpec *) After_APIObj(flow);	}	if (API_IsPath(resp) && (char *)fltr - resp_buf < len){		/*		 *	For path event, list of adspecs follows sender		 *	descriptor list.  (We make sure there really is		 *	an adspec list, for backwards compatibility).		 */		size = (MAX_ADSPEC_LEN+sizeof(rapi_hdr_t)) * resp->resp_nflwd;		api_adspec = malloc(size);		if (api_adspec == NULL) {			rapi_errno = RAPI_ERR_MEMFULL;			goto err_exit;		}		eapi_adspp = (char *)api_adspec + size;		tapi_adspp = api_adspec;		adspp = (rapi_adspec_t *) fltr;		for (i = 0; i < resp->resp_nflwd; i++) {#ifdef USE_NET_BO			NTOH_RAPIhdr(adspp);			if (ntoh_rapi_adspec(&adspp->adspecbody_IS) < 0) {				rapi_errno = RAPI_ERR_INVAL;				goto err_exit;			}#endif /* USE_NET_BO */			copy_adspec_d2i(adspp, tapi_adspp, eapi_adspp,					sidp->flags&RAPI_USE_INTSERV);			if (adspp->form != RAPI_EMPTY_OTYPE)				n_adspec++; /* Count non-empties */			adspp = (API_Adspec *)After_APIObj(adspp);			tapi_adspp = (rapi_adspec_t *) 						After_RAPIObj(tapi_adspp);		}		/* If list contained only empty objects, pass 0 for n_adspec;		 * otherwise, pass resp_nflwd.		 */		if (n_adspec)			n_adspec = resp->resp_nflwd;	}				if (n_filter == 0) {		free(api_filter);		api_filter = NULL;	}	if (n_flowspec == 0) {		free(api_flowspec);		api_flowspec = NULL;	}	if (n_adspec == 0) {		if (api_adspec)			free(api_adspec);		api_adspec = NULL;	}	/* Invoke the client's upcall routine	 */	sockaddr_assign((struct sockaddr *) &enode,&resp->resp_errnode);	if (sidp->event_rtn)	    (*(sidp->event_rtn)) (		(rapi_sid_t) resp->resp_a_sid,		(rapi_eventinfo_t) resp->resp_type,		resp->resp_style, 		resp->resp_errcode, resp->resp_errval,		(struct sockaddr *)&enode,		resp->resp_errflags,		n_filter, api_filter,		n_flowspec, api_flowspec,		n_adspec, api_adspec,		sidp->event_rtn_arg	    );	/*	 *	Upon return, free malloc'd areas	 */err_exit:	if (api_filter)		free(api_filter);	if (api_flowspec)		free(api_flowspec);	if (api_adspec)		free(api_adspec);	if (resp_buf)		free(resp_buf);	return (rapi_errno);}/*	Scan a given list of N RAPI objects, and compute upper bound on *	length after translation to API objects, for buffer allocation. */intList_Length(char *lcp, int N)	{	int		i;	int		len = 0;	for (i= 0; i < N; i++) {		switch (((rapi_hdr_t *)lcp)->form) {		    case RAPI_EMPTY_OTYPE:			break;		    case RAPI_FILTERFORM_BASE:			len += sizeof(rapi_filter_base_t);			break;		    case RAPI_FILTERFORM_GPI:			len += sizeof(rapi_filter_gpi_t);			break;#ifdef  USE_IPV6		    case RAPI_FILTERFORM_BASE6:			len += sizeof(rapi_filter_base6_t);			break;		    case RAPI_FILTERFORM_GPI6:			len += sizeof(rapi_filter_gpi6_t);			break;#endif  /* USE_IPV6 */		    case RAPI_FLOWSTYPE_Simplified:		    case RAPI_FLOWSTYPE_Intserv: /* IS: The Real Thing */			/* Use max Intserv flowspec size */			len += sizeof(IS_specbody_t);			break;		    default:			/* SHOULD NOT HAPPEN */			return -1;		}		len += sizeof(rapi_hdr_t);	/* Common part */		lcp = After_RAPIObj(lcp);	}	return len;}char *copy_sender_desc(	rapi_filter_t	*	i_filter,	rapi_tspec_t 	*	i_tspec,	rapi_adspec_t	*	i_adspec,	API_FlowDesc	* 	flwdp,	char		*	endp)	{	char		*cp;	if (!i_tspec) i_tspec = (rapi_tspec_t *) &Empty_APIObj;	cp = copy_filterspec_i2d(i_filter, (API_FilterSpec *) flwdp, endp);	if (!cp)		return NULL;	cp = copy_tspec_i2d(i_tspec, (API_TSpec *)cp, endp);	if (i_adspec)		cp = copy_adspec_i2d(i_adspec, (API_Adspec *)cp, endp);	return cp;}voidsockaddr2filterbase(struct sockaddr *sockp, rapi_filter_t *filtp)	{	switch(sockp->sa_family) {		case AF_INET:			filtp->form = RAPI_FILTERFORM_BASE;			filtp->len = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_base_t);			filtp->rapi_filt4 =				*(struct sockaddr_in *)sockp;			break;#ifdef	USE_IPV6		case AF_INET6:			filtp->form = RAPI_FILTERFORM_BASE6;			filtp->len = sizeof(rapi_hdr_t)				+ sizeof(rapi_filter_base6_t);			filtp->rapi_filt6 =				*(struct sockaddr_in6 *)sockp;			break;#endif	/* USE_IPV6 */	}}intvDstPort_OK(api_addr *addr, int flags)	{	if (!flags&RAPI_GPI_SESSION)		/* We don't do any checking of dest port unless is IPSEC;		 * the spec says we MAY, but we don't have to.		 */		return(1);	return(addr->port != 0);}/********************************************************************** *       COPY-AND-TRANSLATE ROUTINES * *	For flowspecs and adspecs, these routines may do serious translation, *	since the API protocol assumes Intserv data structure bodies. *	For filterspecs, these routines (currently) simply pass through the *	RAPI/API object, except they convert byte order if needed. * **********************************************************************//*	Translate flowspec from user interface format to daemon format, *	checking type, length, and for overflow of req message. *	Return ptr to next d_spec locn, or NULL if error. */static char *copy_flowspec_i2d(rapi_flowspec_t * i_spec, API_Flowspec * d_spec, char *endp)	{	int newL;	char *next;	switch (i_spec->form) {	    case RAPI_FLOWSTYPE_Simplified:		/*		 * Simplifed: translate into proper Int-Serv format.		 */		newL = sizeof(IS_specbody_t)+sizeof(rapi_hdr_t);		if ((char *)d_spec+ newL > endp) {			rapi_errno = RAPI_ERR_OVERFLOW;			return NULL;		}		if (RAPIObj_Size(i_spec) < 				sizeof(qos_flowspecx_t)+sizeof(rapi_hdr_t)) {			rapi_errno = RAPI_ERR_OBJLEN;			return NULL;		}		switch (i_spec->specbody_qosx.spec_type) {		case QOS_GUARANTEEDX:		    CSZXtoG_spec(&i_spec->specbody_qosx, 						&d_spec->specbody_IS);		    break;        	case QOS_CNTR_LOAD:		    CSZXtoCL_spec(&i_spec->specbody_qosx, 						&d_spec->specbody_IS);		    break;		default:		    rapi_errno = RAPI_ERR_INVAL;		    return NULL;		}		d_spec->form = RAPI_FLOWSTYPE_Intserv;		d_spec->len = IS2RAPI_len(d_spec->specbody_IS.ISmh_len32b);#ifdef USE_NET_BO		if (hton_rapi_flowspec(&d_spec->specbody_IS) < 0) {			rapi_errno = RAPI_ERR_INVAL;			return NULL;		}#endif /* USE_NET_BO */		break;	    case RAPI_FLOWSTYPE_Intserv:		newL = RAPIObj_Size(i_spec);		if ((char *)d_spec + newL > endp) {			rapi_errno = RAPI_ERR_OVERFLOW;			return NULL;		}			/*	Check length inside Intserv main header		 */		if (i_spec->specbody_IS.ISmh_len32b != RAPI2IS_len(newL)) {			rapi_errno = RAPI_ERR_OBJLEN;			return NULL;		}		memcpy((char *) d_spec, (char *) i_spec, newL);#ifdef USE_NET_BO		if (hton_rapi_flowspec(&d_spec->specbody_IS) < 0) {			rapi_errno = RAPI_ERR_INVAL;			return NULL;		}#endif /* USE_NET_BO */		break;	    case RAPI_EMPTY_OTYPE:		if ((char *)d_spec + sizeof(Empty_RObj) > endp) {			rapi_errno = RAPI_ERR_OVERFLOW;			return NULL;		}		memcpy((char *)d_spec, (char *)&Empty_RObj, sizeof(Empty_RObj));		break;	    default:		rapi_errno = RAPI_ERR_OBJTYPE;		return NULL;	}	next = After_RAPIObj(d_spec);#ifdef USE_NET_BO	HTON_RAPIhdr(d_spec);#endif /* USE_NET_BO */	return (next);}/*	Translate Tspec from user interface format to daemon format, *	checking type, length, and for overflow of req message. *	Return ptr to next d_spec locn, or NULL if error. */static char *copy_tspec_i2d(rapi_tspec_t * i_spec, API_TSpec * d_spec, char *endp)	{	int printf();	char *next;	if ((char *)d_spec + sizeof(rapi_tspec_t) > endp) {		rapi_errno = RAPI_ERR_OVERFLOW;		return NULL;	}	switch (i_spec->form) {	    case RAPI_FLOWSTYPE_Simplified:		printf("Obsolete Tspec form: should be RAPI_TSPECTYPE_Simplified\n");	    case RAPI_TSPECTYPE_Simplified:		/*		 * Simplified format: translate into proper Intserv		 * format.  In this case, don't have to supply any values.		 */		if (RAPIObj_Size(i_spec) < 				sizeof(qos_tspecx_t)+sizeof(rapi_hdr_t)) {			rapi_errno = RAPI_ERR_OBJLEN;			return NULL;		}		switch (i_spec->tspecbody_qosx.spec_type) {		case QOS_GUARANTEEDX:        	case QOS_CNTR_LOAD:		case QOS_TSPECX:			/* -> Generic Tspec */		    CSZXtoGen_tspec(&i_spec->tspecbody_qosx, 						&d_spec->tspecbody_IS);		    break;		default:		    rapi_errno = RAPI_ERR_INVAL;		    return NULL;		}		d_spec->form = RAPI_TSPECTYPE_Intserv;		d_spec->len =IS2RAPI_len(d_spec->tspecbody_IS.IStmh_len32b);#ifdef USE_NET_BO		if (hton_rapi_flowspec(&d_spec->tspecbody_IS) < 0) {			rapi_errno = RAPI_ERR_INVAL;			return NULL;		}#endif /* USE_NET_BO */		break;	    case RAPI_TSPECTYPE_Intserv:		/*	Set length in Intserv flowspec header		 */		if (RAPIObj_Size(i_spec) < sizeof(rapi_tspec_t)) {			rapi_errno = RAPI_ERR_OBJLEN;			return NULL;		}		i_spec->tspecbody_IS.IStmh_len32b = 					RAPI2IS_len(RAPIObj_Size(i_spec));		memcpy((char *) d_spec, (char *) i_spec, RAPIObj_Size(i_spec));#ifdef USE_NET_BO		if (hton_rapi_flowspec(&d_spec->tspecbody_IS) < 0) {			rapi_errno = RAPI_ERR_INVAL;			return NULL;		}#endif /* USE_NET_BO */		break;	    case RAPI_EMPTY_OTYPE:		memcpy((char *)d_spec, (char *)&Empty_RObj, sizeof(Empty_RObj));		break;	    default:		rapi_errno = RAPI_ERR_OBJTYPE;		return NULL;	}	next = After_RAPIObj(d_spec);#ifdef USE_NET_BO	HTON_RAPIhdr(d_spec);#endif /* USE_NET_BO */	return ( next );}/*	Copy adspec and convert to Intserv format with RAPI framing. *	Sets rapi_errno and returns NULL if it fails. */static char *copy_adspec_i2d(rapi_adspec_t *i_adsp, API_Adspec *d_adsp, char *endp)	{	char *next;	switch (i_adsp->form) {	    case RAPI_ADSTYPE_Simplified:		if ((char *)d_adsp + MAX_ADSPEC_LEN > endp) {			rapi_errno = RAPI_ERR_OVERFLOW;			return NULL;		}		if (CSZXtoIS_adspec(&i_adsp->adspecbody_qosx, 						&d_adsp->adspecbody_IS))			return NULL;		d_adsp->form = RAPI_ADSTYPE_Intserv;		d_adsp->len =		     IS2RAPI_len(d_adsp->adspecbody_IS.adspec_mh.ismh_len32b);#ifdef USE_NET_BO		if (hton_rapi_adspec(&d_adsp->adspecbody_IS) < 0) {			rapi_errno = RAPI_ERR_INVAL;			return NULL;		}#endif /* USE_NET_BO */		break;	    case RAPI_FLOWSTYPE_Intserv:		/*	Set length in Intserv flowspec header		 */		if (RAPIObj_Size(i_adsp) > MAX_ADSPEC_LEN) {			rapi_errno = RAPI_ERR_OVERFLOW;			return NULL;		}		i_adsp->adspecbody_IS.adspec_mh.ismh_len32b = 					RAPI2IS_len(RAPIObj_Size(i_adsp));		memcpy((char *) d_adsp, (char *) i_adsp, RAPIObj_Size(i_adsp));#ifdef USE_NET_BO		if (hton_rapi_adspec(&d_adsp->adspecbody_IS) < 0) {			rapi_errno = RAPI_ERR_INVAL;			return NULL;		}#endif /* USE_NET_BO */		break;	    case RAPI_EMPTY_OTYPE:		memcpy((char *)d_adsp, (char *)&Empty_RObj, sizeof(Empty_RObj));		break;	    default:		rapi_errno = RAPI_ERR_OBJTYPE;		return NULL;	}	next = After_RAPIObj(d_adsp);#ifdef USE_NET_BO	HTON_RAPIhdr(d_adsp);#endif /* USE_NET_BO */	return next;}/* *	Copy and convert RAPI-format filter spec into daemon format. */static char *copy_filterspec_i2d(rapi_filter_t * i_filter, API_FilterSpec * d_filter,								char *endp)	{	int newL;	char *next;	switch (i_filter->form) {	    case RAPI_FILTERFORM_BASE:		newL = sizeof(rapi_filter_base_t)+sizeof(rapi_hdr_t);		break;	    case RAPI_FILTERFORM_GPI:		newL = sizeof(rapi_filter_gpi_t)+sizeof(rapi_hdr_t);		break;#ifdef	USE_IPV6	    case RAPI_FILTERFORM_BASE6:		newL = sizeof(rapi_filter_base6_t)+sizeof(rapi_hdr_t);		break;	    case RAPI_FILTERFORM_GPI6:		newL = sizeof(rapi_filter_gpi6_t)+sizeof(rapi_hdr_t);		break;#endif	/* USE_IPV6 */	    case RAPI_EMPTY_OTYPE:		newL = sizeof(rapi_hdr_t);		break;	    default:		rapi_errno = RAPI_ERR_OBJTYPE;		return NULL;	}			if (RAPIObj_Size(i_filter) != newL) {		rapi_errno = RAPI_ERR_OBJLEN;		return NULL;	}	if ((char *)d_filter + RAPIObj_Size(i_filter) > endp) {		rapi_errno = RAPI_ERR_OVERFLOW;		return NULL;	}	memcpy((char *) d_filter, (char *) i_filter, RAPIObj_Size(i_filter));	next = After_RAPIObj(d_filter);#ifdef USE_NET_BO	HTON_RAPIhdr(d_filter);#endif /* USE_NET_BO */	return (next);}/*	Translate from daemon format to user interface format, checking *	for overflow of upcall area.  Sets rapi_errno and returns -1 if *	error, else returns zero. */static intcopy_flowspec_d2i(API_Flowspec * d_spec, rapi_flowspec_t * i_spec, char *endp,							int Use_Intserv)

⌨️ 快捷键说明

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