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

📄 avp.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/* * $Id: avp.c,v 1.3 2004/08/24 08:58:25 janakj Exp $ * * Copyright (C) 2002-2003 FhG Fokus * * This file is part of disc, a free diameter server/client. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include "../../mem/shm_mem.h"#include "../../dprint.h"#include "diameter_msg.h"/* * each AVP type has some default set/reset flags and a proper data type. * All this default values (for flags and data-type) are correct/set by this * function. */inline void set_avp_fields( AAA_AVPCode code, AAA_AVP *avp){	switch (code) {		case   1: /*AVP_User_Name*/		case  25: /*AVP_Class*/		case 263: /*AVP_Session_Id*/		case 283: /*AVP_Destination_Realm*/		case 293: /*AVP Destination Host*/		case 264: /*AVP_Origin_Host*/		case 296: /*AVP Origin_Realm*/		case 400: /* AVP_Resource */			case 401: /* AVP_Response */			case 402: /* AVP_Chalenge */			case 403: /* AVP_Method */		case 404: /* Service_Type AVP */		case 405: /* User_Group AVP*/			avp->flags = 0x40|(0x20&avp->flags);			avp->type = AAA_AVP_STRING_TYPE;			break;		case  27: /*AVP_Session_Timeout*/		case 258: /*AVP_Auth_Aplication_Id*/		case 262: /*AVP_Redirect_Max_Cache_Time*/		case 265: /*AVP_Supported_Vendor_Id*/		case 266: /*AVP_Vendor_Id*/		case 268: /*AVP_Result_Code*/		case 270: /*AVP_Session_Binding*/		case 276: /*AVP_Auth_Grace_Period*/		case 278: /*AVP_Origin_State_Id*/		case 291: /*AVP_Authorization_Lifetime*/			avp->flags = 0x40|(0x20&avp->flags);			avp->type = AAA_AVP_INTEGER32_TYPE;			break;		case 33: /*AVP_Proxy_State*/			avp->flags = 0x40;			avp->type = AAA_AVP_STRING_TYPE;			break;		case 257: /*AVP_Host_IP_Address*/			avp->flags = 0x40|(0x20&avp->flags);			avp->type = AAA_AVP_ADDRESS_TYPE;			break;		case 269: /*AVP_Product_Name*/			avp->flags = 0x00;			avp->type = AAA_AVP_STRING_TYPE;			break;		case 281: /*AVP_Error_Message*/			avp->flags = (0x20&avp->flags);			avp->type = AAA_AVP_STRING_TYPE;			break;		default:			avp->type = AAA_AVP_DATA_TYPE;	};}/* This function creates an AVP and returns a pointer to it; */AAA_AVP*  AAACreateAVP(	AAA_AVPCode code,	AAA_AVPFlag flags,	AAAVendorId vendorId,	char   *data,	unsigned int length,	AVPDataStatus data_status){	AAA_AVP *avp;	/* first check the params */	if( data==0 || length==0) {		LOG(L_ERR,"ERROR:AAACreateAndAddAVPToList: NULL value received for"			" param data/length !!\n");		return 0;	}	/* allocated a new AVP struct */	avp = 0;	avp = (AAA_AVP*)ad_malloc(sizeof(AAA_AVP));	if (!avp)		goto error;	memset( avp, 0, sizeof(AAA_AVP) );	/* set some fields */	//avp->free_it = free_it;	avp->packetType = AAA_DIAMETER;	avp->code=code;	avp->flags=flags;	avp->vendorId=vendorId;	set_avp_fields( code, avp);	if ( data_status==AVP_DUPLICATE_DATA ) {		/* make a duplicate for data */		avp->data.len = length;		avp->data.s = (void*)ad_malloc(length);		if(!avp->data.s)			goto error;		memcpy( avp->data.s, data, length);		avp->free_it = 1;	} else {		avp->data.s = data;		avp->data.len = length;		avp->free_it = (data_status==AVP_FREE_DATA)?1:0;	}	return avp;error:	LOG(L_ERR,"ERROR:AAACreateAVP: no more free memory!\n");	return 0;}/* Insert the AVP avp into this avpList of a message after position */AAAReturnCode  AAAAddAVPToMessage(	AAAMessage *msg,	AAA_AVP *avp,	AAA_AVP *position){	AAA_AVP *avp_t;	if ( !msg || !avp ) {		LOG(L_ERR,"ERROR:AAAAddAVPToList: param msg or avp passed null"			" or *avpList=NULL and position!=NULL !!\n");		return AAA_ERR_PARAMETER;	}	if (!position) {		/* insert at the beginning */		avp->next = msg->avpList.head;		avp->prev = 0;		msg->avpList.head = avp;		if (avp->next)			avp->next->prev = avp;		else			msg->avpList.tail = avp;	} else {		/* look after avp from position */		for(avp_t=msg->avpList.head;avp_t&&avp_t!=position;avp_t=avp_t->next);		if (!avp_t) {			LOG(L_ERR,"ERROR: AAACreateAVP: the \"position\" avp is not in"				"\"msg\" message!!\n");			return AAA_ERR_PARAMETER;		}		/* insert after position */		avp->next = position->next;		position->next = avp;		if (avp->next)			avp->next->prev = avp;		else			msg->avpList.tail = avp;		avp->prev = position;	}	/* update the short-cuts */	switch (avp->code) {		case AVP_Session_Id: msg->sessionId = avp;break;		case AVP_Origin_Host: msg->orig_host = avp;break;		case AVP_Origin_Realm: msg->orig_realm = avp;break;		case AVP_Destination_Host: msg->dest_host = avp;break;		case AVP_Destination_Realm: msg->dest_realm = avp;break;		case AVP_Result_Code: msg->res_code = avp;break;		case AVP_Auth_Session_State: msg->auth_ses_state = avp;break;	}	return AAA_ERR_SUCCESS;}/* This function finds an AVP with matching code and vendor id */AAA_AVP  *AAAFindMatchingAVP(	AAAMessage *msg,	AAA_AVP *startAvp,	AAA_AVPCode avpCode,	AAAVendorId vendorId,	AAASearchType searchType){	AAA_AVP *avp_t;	/* param checking */	if (!msg) {		LOG(L_ERR,"ERROR:FindMatchingAVP: param msg passed null !!\n");		goto error;	}	/* search the startAVP avp */	for(avp_t=msg->avpList.head;avp_t&&avp_t!=startAvp;avp_t=avp_t->next);	if (!avp_t && startAvp) {		LOG(L_ERR,"ERROR: AAAFindMatchingAVP: the \"position\" avp is not in"			"\"avpList\" list!!\n");		goto error;	}	/* where should I start searching from ? */	if (!startAvp)		avp_t=(searchType==AAA_FORWARD_SEARCH)?(msg->avpList.head):			(msg->avpList.tail);	else		avp_t=startAvp;	/* start searching */	while(avp_t) {		if (avp_t->code==avpCode && avp_t->vendorId==vendorId)			return avp_t;		avp_t = (searchType==AAA_FORWARD_SEARCH)?(avp_t->next):(avp_t->prev);	}error:	return 0;}/* This function removes an AVP from a list of a message */AAAReturnCode  AAARemoveAVPFromMessage(	AAAMessage *msg,	AAA_AVP *avp){	AAA_AVP *avp_t;	/* param check */	if ( !msg || !avp ) {		LOG(L_ERR,"ERROR:AAAAddAVPToList: param AVP_LIST \"avpList\" or AVP "			"\"avp\" passed null !!\n");		return AAA_ERR_PARAMETER;	}	/* search the "avp" avp */	for(avp_t=msg->avpList.head;avp_t&&avp_t!=avp;avp_t=avp_t->next);	if (!avp_t) {		LOG(L_ERR,"ERROR: AAACreateAVP: the \"avp\" avp is not in "			"\"avpList\" avp list!!\n");		return AAA_ERR_PARAMETER;	}	/* remove the avp from list */	if (msg->avpList.head==avp)		msg->avpList.head = avp->next;	else		avp->prev->next = avp->next;	if (avp->next)		avp->next->prev = avp->prev;	else		msg->avpList.tail = avp->prev;	avp->next = avp->prev = 0;	/* update short-cuts */	switch (avp->code) {		case AVP_Session_Id: msg->sessionId = 0;break;		case AVP_Origin_Host: msg->orig_host = 0;break;		case AVP_Origin_Realm: msg->orig_realm = 0;break;		case AVP_Destination_Host: msg->dest_host = 0;break;		case AVP_Destination_Realm: msg->dest_realm = 0;break;		case AVP_Result_Code: msg->res_code = 0;break;		case AVP_Auth_Session_State: msg->auth_ses_state = 0;break;	}	return AAA_ERR_SUCCESS;}/* The function frees an AVP */AAAReturnCode  AAAFreeAVP(AAA_AVP **avp){	/* some checks */	if (!avp || !(*avp)) {		LOG(L_ERR,"ERROR:AAAFreeAVP: param avp cannot be null!!\n");		return AAA_ERR_PARAMETER;	}	/* free all the mem */	if ( (*avp)->free_it && (*avp)->data.s )		ad_free((*avp)->data.s);	ad_free( *avp );	*avp = 0;	return AAA_ERR_SUCCESS;}/* This function returns a pointer to the first AVP in the list */AAA_AVP*  AAAGetFirstAVP(AAA_AVP_LIST *avpList){	return avpList->head;}/* This function returns a pointer to the last AVP in the list */AAA_AVP*  AAAGetLastAVP(AAA_AVP_LIST *avpList){	return avpList->tail;}/* This function returns a pointer to the next AVP in the list */AAA_AVP*  AAAGetNextAVP(AAA_AVP *avp){	return avp->next;}/* This function returns a pointer to the previous AVP in the list */AAA_AVP*  AAAGetPrevAVP(AAA_AVP *avp){	return avp->prev;}/* This function converts the data in the AVP to a format suitable for * log or display functions. */char*  AAAConvertAVPToString(AAA_AVP *avp, char *dest, unsigned int destLen){	int l;	int i;	if (!avp || !dest || !destLen) {		LOG(L_ERR,"ERROR:AAAConvertAVPToString: param AVP, DEST or DESTLEN "			"passed as null!!!\n");		return 0;	}	l = snprintf(dest,destLen,"AVP(%p < %p >%p):packetType=%u;code=%u,"		"flags=%x;\nDataType=%u;VendorID=%u;DataLen=%u;\n",		avp->prev,avp,avp->next,avp->packetType,avp->code,avp->flags,		avp->type,avp->vendorId,avp->data.len);	switch(avp->type) {		case AAA_AVP_STRING_TYPE:			l+=snprintf(dest+l,destLen-l,"String: <%.*s>",avp->data.len,				avp->data.s);			break;		case AAA_AVP_INTEGER32_TYPE:			l+=snprintf(dest+l,destLen-l,"Int32: <%u>(%x)",				(unsigned int)htonl(*((unsigned int*)avp->data.s)),				(unsigned int)htonl(*((unsigned int*)avp->data.s)));			break;		case AAA_AVP_ADDRESS_TYPE:			i = 1;			switch (avp->data.len) {				case 4: i=i*0;				case 6: i=i*2;					l+=snprintf(dest+l,destLen-l,"Address IPv4: <%d.%d.%d.%d>",						(unsigned char)avp->data.s[i+0],						(unsigned char)avp->data.s[i+1],						(unsigned char)avp->data.s[i+2],						(unsigned char)avp->data.s[i+3]);					break;				case 16: i=i*0;				case 18: i=i*2;					l+=snprintf(dest+l,destLen-l,						"Address IPv6: <%x.%x.%x.%x.%x.%x.%x.%x>",						((avp->data.s[i+0]<<8)+avp->data.s[i+1]),						((avp->data.s[i+2]<<8)+avp->data.s[i+3]),						((avp->data.s[i+4]<<8)+avp->data.s[i+5]),						((avp->data.s[i+6]<<8)+avp->data.s[i+7]),						((avp->data.s[i+8]<<8)+avp->data.s[i+9]),						((avp->data.s[i+10]<<8)+avp->data.s[i+11]),						((avp->data.s[i+12]<<8)+avp->data.s[i+13]),						((avp->data.s[i+14]<<8)+avp->data.s[i+15]));					break;			break;			}			break;		//case AAA_AVP_INTEGER64_TYPE:		case AAA_AVP_TIME_TYPE:		default:			LOG(L_WARN,"WARNING:AAAConvertAVPToString: don't know how to print"				" this data type [%d] -> tryng hexa\n",avp->type);		case AAA_AVP_DATA_TYPE:			for (i=0;i<avp->data.len&&l<destLen-1;i++)			l+=snprintf(dest+l,destLen-l-1,"%x",				((unsigned char*)avp->data.s)[i]);	}	return dest;}AAA_AVP* AAACloneAVP( AAA_AVP *avp , unsigned char clone_data){	AAA_AVP *n_avp;	if (!avp || !(avp->data.s) || !(avp->data.len) )		goto error;	/* clone the avp structure */	n_avp = (AAA_AVP*)ad_malloc( sizeof(AAA_AVP) );	if (!n_avp) {		LOG(L_ERR,"ERROR:clone_avp: cannot get free memory!!\n");		goto error;	}	memcpy( n_avp, avp, sizeof(AAA_AVP));	n_avp->next = n_avp->prev = 0;	if (clone_data) {		/* clone the avp data */		n_avp->data.s = (char*)ad_malloc( avp->data.len );		if (!(n_avp->data.s)) {			LOG(L_ERR,"ERROR:clone_avp: cannot get free memory!!\n");			ad_free( n_avp );			goto error;		}		memcpy( n_avp->data.s, avp->data.s, avp->data.len);		n_avp->free_it = 1;	} else {		/* link the clone's data to the original's data */		n_avp->data.s = avp->data.s;		n_avp->data.len = avp->data.len;		n_avp->free_it = 0;	}	return n_avp;error:	return 0;}

⌨️ 快捷键说明

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