diameter_avp.c File Reference


Detailed Description

CDiameterPeer - Diameter API interface.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

Umut Emin umut dot emin -at- fokus dot fraunhofer dot de

15-09-2006 Changed arg 'unsigned int length' to 'size_t length' at function AAACreateAVP , line 82 (Umut Emin aka jsbach)

Definition in file diameter_avp.c.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include "diameter.h"
#include "utils.h"

Go to the source code of this file.

Functions

void set_avp_fields (AAA_AVPCode code, AAA_AVP *avp)
 Takes care that each AVP type has the default flags set/reset and a proper data type.
AAA_AVPAAACreateAVP (AAA_AVPCode code, AAA_AVPFlag flags, AAAVendorId vendorId, char *data, size_t length, AVPDataStatus data_status)
 This function creates an AVP and returns a pointer to it.
AAAReturnCode AAAAddAVPToMessage (AAAMessage *msg, AAA_AVP *avp, AAA_AVP *position)
 Insert the AVP avp into the avpList of a message, after a certain position.
AAA_AVPAAAFindMatchingAVP (AAAMessage *msg, AAA_AVP *startAvp, AAA_AVPCode avpCode, AAAVendorId vendorId, AAASearchType searchType)
 This function finds an AVP with matching code and vendor id.
AAAReturnCode AAARemoveAVPFromMessage (AAAMessage *msg, AAA_AVP *avp)
 This function removes an AVP from a message.
AAAReturnCode AAAFreeAVP (AAA_AVP **avp)
 The function frees the memory allocated to an AVP.
AAA_AVPAAAGetFirstAVP (AAA_AVP_LIST *avpList)
 This function returns the first AVP in the list.
AAA_AVPAAAGetLastAVP (AAA_AVP_LIST *avpList)
 This function returns the last AVP in the list.
AAA_AVPAAAGetNextAVP (AAA_AVP *avp)
 This function returns the next AVP in the list that this AVP was extracted from.
AAA_AVPAAAGetPrevAVP (AAA_AVP *avp)
 This function returns a the previous AVP in the list that this AVP was extracted from.
char * AAAConvertAVPToString (AAA_AVP *avp, char *dest, unsigned int destLen)
 This function converts the data in the AVP to a format suitable for print, log or display.
AAA_AVPAAACloneAVP (AAA_AVP *avp, unsigned char clone_data)
 Duplicate a whole AAA_AVP.
void AAAAddAVPtoList (AAA_AVP_LIST *list, AAA_AVP *avp)
 Adds an AVP to a list of AVPs, at the end.
str AAAGroupAVPS (AAA_AVP_LIST avps)
 Groups a list of avps into a data buffer.
AAA_AVP_LIST AAAUngroupAVPS (str buf)
 Ungroup from a data buffer a list of avps.
AAA_AVPAAAFindMatchingAVPList (AAA_AVP_LIST avpList, AAA_AVP *startAvp, AAA_AVPCode avpCode, AAAVendorId vendorId, AAASearchType searchType)
 Find an avp into a list of avps.
void AAAAddAVPToAVPList (AAA_AVP_LIST *list, AAA_AVP *avp)
 Add an AVP to a list of AVPs.


Function Documentation

void set_avp_fields ( AAA_AVPCode  code,
AAA_AVP avp 
) [inline]

Takes care that each AVP type has the default flags set/reset and a proper data type.

All this default values (for flags and data-type) are correct/set by this function.

Parameters:
code - code of the AVP
avp - the actual AVP to set flags
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 77 of file diameter_avp.c.

References AAA_AVP_ADDRESS_TYPE, AAA_AVP_DATA_TYPE, AAA_AVP_INTEGER32_TYPE, AAA_AVP_STRING_TYPE, avp::flags, and avp::type.

Referenced by AAACreateAVP().

00078 {
00079     switch (code) {
00080         case   1: /*AVP_User_Name*/
00081         case  25: /*AVP_Class*/
00082         case 263: /*AVP_Session_Id*/
00083         case 283: /*AVP_Destination_Realm*/
00084         case 293: /*AVP Destination Host*/
00085         case 264: /*AVP_Origin_Host*/
00086         case 296: /*AVP Origin_Realm*/
00087             avp->flags = 0x40|(0x20&avp->flags);
00088             avp->type = AAA_AVP_STRING_TYPE;
00089             break;
00090         case  27: /*AVP_Session_Timeout*/
00091         case 258: /*AVP_Auth_Aplication_Id*/
00092         case 262: /*AVP_Redirect_Max_Cache_Time*/
00093         case 265: /*AVP_Supported_Vendor_Id*/
00094         case 266: /*AVP_Vendor_Id*/
00095         case 268: /*AVP_Result_Code*/
00096         case 270: /*AVP_Session_Binding*/
00097         case 276: /*AVP_Auth_Grace_Period*/
00098         case 278: /*AVP_Origin_State_Id*/
00099         case 291: /*AVP_Authorization_Lifetime*/
00100             avp->flags = 0x40|(0x20&avp->flags);
00101             avp->type = AAA_AVP_INTEGER32_TYPE;
00102             break;
00103         case 33: /*AVP_Proxy_State*/
00104             avp->flags = 0x40;
00105             avp->type = AAA_AVP_STRING_TYPE;
00106             break;
00107         case 257: /*AVP_Host_IP_Address*/
00108             avp->flags = 0x40|(0x20&avp->flags);
00109             avp->type = AAA_AVP_ADDRESS_TYPE;
00110             break;
00111         case 269: /*AVP_Product_Name*/
00112             avp->flags = 0x00;
00113             avp->type = AAA_AVP_STRING_TYPE;
00114             break;
00115         case 281: /*AVP_Error_Message*/
00116             avp->flags = (0x20&avp->flags);
00117             avp->type = AAA_AVP_STRING_TYPE;
00118             break;
00119         default:
00120             avp->type = AAA_AVP_DATA_TYPE;
00121     };
00122 }

AAA_AVP* AAACreateAVP ( AAA_AVPCode  code,
AAA_AVPFlag  flags,
AAAVendorId  vendorId,
char *  data,
size_t  length,
AVPDataStatus  data_status 
)

This function creates an AVP and returns a pointer to it.

Parameters:
code - the code of the new AVP
flags - the flags to set
vendorId - vendor id
data - the generic payload data
length - length of the payload
data_status - what to do with the payload: duplicate, free with the message, etc
Returns:
the AAA_AVP* or null on error
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 137 of file diameter_avp.c.

References AVP_DUPLICATE_DATA, AVP_FREE_DATA, avp::code, avp::data, avp::flags, avp::free_it, set_avp_fields(), and avp::vendorId.

Referenced by AAANewMessage(), AAATranslateMessage(), AAAUngroupAVPS(), load_cdp(), and Snd_CE_add_applications().

00144 {
00145     AAA_AVP *avp;
00146 
00147     /* first check the params */
00148     if( data==0 || length==0) {
00149         LOG(L_ERR,"ERROR:AAACreateAVP: NULL value received for"
00150             " param data/length !!\n");
00151         return 0;
00152     }
00153 
00154     /* allocated a new AVP struct */
00155     avp = 0;
00156     avp = (AAA_AVP*)shm_malloc(sizeof(AAA_AVP));
00157     if (!avp)
00158         goto error;
00159     memset( avp, 0, sizeof(AAA_AVP) );
00160 
00161     /* set some fields */
00162     //avp->free_it = free_it;
00163     avp->code=code;
00164     avp->flags=flags;
00165     avp->vendorId=vendorId;
00166     set_avp_fields( code, avp);
00167 
00168     if ( data_status==AVP_DUPLICATE_DATA ) {
00169         /* make a duplicate for data */
00170         avp->data.len = length;
00171         avp->data.s = (void*)shm_malloc(length);
00172         if(!avp->data.s)
00173             goto error;
00174         memcpy( avp->data.s, data, length);
00175         avp->free_it = 1;
00176     } else {
00177         avp->data.s = data;
00178         avp->data.len = length;
00179         avp->free_it = (data_status==AVP_FREE_DATA)?1:0;
00180     }
00181 
00182     return avp;
00183 error:
00184     LOG(L_ERR,"ERROR:AAACreateAVP: no more free memory!\n");
00185     return 0;
00186 }

AAAReturnCode AAAAddAVPToMessage ( AAAMessage msg,
AAA_AVP avp,
AAA_AVP position 
)

Insert the AVP avp into the avpList of a message, after a certain position.

Parameters:
msg - the AAAMessage to add to
avp - the AAA_AVP to add
position - AAA_AVP to add after. If NULL, will add at the beginning.
Returns:
AAA_ERR_SUCCESS on success or AAA_ERR_PARAMETER if the position is not found
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 198 of file diameter_avp.c.

References AAA_ERR_PARAMETER, AAA_ERR_SUCCESS, _message_t::auth_ses_state, AVP_Auth_Session_State, AVP_Destination_Host, AVP_Destination_Realm, AVP_Origin_Host, AVP_Origin_Realm, AVP_Result_Code, AVP_Session_Id, _message_t::avpList, avp::code, _message_t::dest_host, _message_t::dest_realm, _avp_list_t::head, avp::next, _message_t::orig_host, _message_t::orig_realm, avp::prev, _message_t::res_code, _message_t::sessionId, and _avp_list_t::tail.

Referenced by AAANewMessage(), AAATranslateMessage(), and load_cdp().

00202 {
00203     AAA_AVP *avp_t;
00204 
00205     if ( !msg || !avp ) {
00206         LOG(L_ERR,"ERROR:AAAAddAVPToList: param msg or avp passed null"
00207             " or *avpList=NULL and position!=NULL !!\n");
00208         return AAA_ERR_PARAMETER;
00209     }
00210 
00211     if (!position) {
00212         /* insert at the begining */
00213         avp->next = msg->avpList.head;
00214         avp->prev = 0;
00215         msg->avpList.head = avp;
00216         if (avp->next)
00217             avp->next->prev = avp;
00218         else
00219             msg->avpList.tail = avp;
00220     } else {
00221         /* look after avp from position */
00222         for(avp_t=msg->avpList.head;avp_t&&avp_t!=position;avp_t=avp_t->next);
00223         if (!avp_t) {
00224             LOG(L_ERR,"ERROR: AAACreateAVP: the \"position\" avp is not in"
00225                 "\"msg\" message!!\n");
00226             return AAA_ERR_PARAMETER;
00227         }
00228         /* insert after position */
00229         avp->next = position->next;
00230         position->next = avp;
00231         if (avp->next)
00232             avp->next->prev = avp;
00233         else
00234             msg->avpList.tail = avp;
00235         avp->prev = position;
00236     }
00237 
00238     /* update the short-cuts */
00239     switch (avp->code) {
00240         case AVP_Session_Id: msg->sessionId = avp;break;
00241         case AVP_Origin_Host: msg->orig_host = avp;break;
00242         case AVP_Origin_Realm: msg->orig_realm = avp;break;
00243         case AVP_Destination_Host: msg->dest_host = avp;break;
00244         case AVP_Destination_Realm: msg->dest_realm = avp;break;
00245         case AVP_Result_Code: msg->res_code = avp;break;
00246         case AVP_Auth_Session_State: msg->auth_ses_state = avp;break;
00247     }
00248 
00249     return AAA_ERR_SUCCESS;
00250 }

AAA_AVP* AAAFindMatchingAVP ( AAAMessage msg,
AAA_AVP startAvp,
AAA_AVPCode  avpCode,
AAAVendorId  vendorId,
AAASearchType  searchType 
)

This function finds an AVP with matching code and vendor id.

Parameters:
msg - message to look into
startAvp - where to start the search. Usefull when you want to find the next one. Even this one will be checked and can be returned if it fits.
avpCode - code of the AVP to match
vendorId - vendor id to match
searchType - whether to look forward or backward
Returns:
the AAA_AVP* if found, NULL if not
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 265 of file diameter_avp.c.

References AAA_FORWARD_SEARCH, _message_t::avpList, avp::code, _avp_list_t::head, avp::next, avp::prev, _avp_list_t::tail, and avp::vendorId.

Referenced by AAANewMessage(), Elect(), get_routing_peer(), load_cdp(), Process_CEA(), and receive_message().

00271 {
00272     AAA_AVP *avp_t;
00273 
00274     /* param checking */
00275     if (!msg) {
00276         LOG(L_ERR,"ERROR:FindMatchingAVP: param msg passed null !!\n");
00277         goto error;
00278     }
00279 
00280     /* where should I start searching from ? */
00281     if (startAvp) {
00282         /* double-check the startAVP avp */
00283         for(avp_t=msg->avpList.head;avp_t&&avp_t!=startAvp;avp_t=avp_t->next);
00284         if (!avp_t) {
00285             LOG(L_ERR,"ERROR: AAAFindMatchingAVP: the \"position\" avp is not "
00286                 "in \"avpList\" list!!\n");
00287             goto error;
00288         }
00289         avp_t=startAvp;
00290     } else {
00291         /* if no startAVP -> start from one of the ends */
00292         avp_t=(searchType==AAA_FORWARD_SEARCH)?(msg->avpList.head):
00293             (msg->avpList.tail);
00294     }
00295 
00296     /* start searching */
00297     while(avp_t) {
00298         if (avp_t->code==avpCode && avp_t->vendorId==vendorId)
00299             return avp_t;
00300         avp_t = (searchType==AAA_FORWARD_SEARCH)?(avp_t->next):(avp_t->prev);
00301     }
00302 
00303 error:
00304     return 0;
00305 }

AAAReturnCode AAARemoveAVPFromMessage ( AAAMessage msg,
AAA_AVP avp 
)

This function removes an AVP from a message.

Parameters:
msg - the diameter message
avp - the AVP to remove
Returns:
AAA_ERR_SUCCESS on success or AAA_ERR_PARAMETER if not found
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 316 of file diameter_avp.c.

References AAA_ERR_PARAMETER, AAA_ERR_SUCCESS, _message_t::auth_ses_state, AVP_Auth_Session_State, AVP_Destination_Host, AVP_Destination_Realm, AVP_Origin_Host, AVP_Origin_Realm, AVP_Result_Code, AVP_Session_Id, _message_t::avpList, avp::code, _message_t::dest_host, _message_t::dest_realm, _avp_list_t::head, avp::next, _message_t::orig_host, _message_t::orig_realm, avp::prev, _message_t::res_code, _message_t::sessionId, and _avp_list_t::tail.

00319 {
00320     AAA_AVP *avp_t;
00321 
00322     /* param check */
00323     if ( !msg || !avp ) {
00324         LOG(L_ERR,"ERROR:AAAAddAVPToList: param AVP_LIST \"avpList\" or AVP "
00325             "\"avp\" passed null !!\n");
00326         return AAA_ERR_PARAMETER;
00327     }
00328 
00329     /* search the "avp" avp */
00330     for(avp_t=msg->avpList.head;avp_t&&avp_t!=avp;avp_t=avp_t->next);
00331     if (!avp_t) {
00332         LOG(L_ERR,"ERROR: AAACreateAVP: the \"avp\" avp is not in "
00333             "\"avpList\" avp list!!\n");
00334         return AAA_ERR_PARAMETER;
00335     }
00336 
00337     /* remove the avp from list */
00338     if (msg->avpList.head==avp)
00339         msg->avpList.head = avp->next;
00340     else
00341         avp->prev->next = avp->next;
00342     if (avp->next)
00343         avp->next->prev = avp->prev;
00344     else
00345         msg->avpList.tail = avp->prev;
00346     avp->next = avp->prev = 0;
00347 
00348     /* update short-cuts */
00349     switch (avp->code) {
00350         case AVP_Session_Id: msg->sessionId = 0;break;
00351         case AVP_Origin_Host: msg->orig_host = 0;break;
00352         case AVP_Origin_Realm: msg->orig_realm = 0;break;
00353         case AVP_Destination_Host: msg->dest_host = 0;break;
00354         case AVP_Destination_Realm: msg->dest_realm = 0;break;
00355         case AVP_Result_Code: msg->res_code = 0;break;
00356         case AVP_Auth_Session_State: msg->auth_ses_state = 0;break;
00357     }
00358 
00359     return AAA_ERR_SUCCESS;
00360 }

AAAReturnCode AAAFreeAVP ( AAA_AVP **  avp  ) 

The function frees the memory allocated to an AVP.

Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 368 of file diameter_avp.c.

References AAA_ERR_PARAMETER, and AAA_ERR_SUCCESS.

Referenced by AAAFreeAVPList(), AAANewMessage(), and load_cdp().

00369 {
00370     /* some checks */
00371     if (!avp || !(*avp)) {
00372         LOG(L_ERR,"ERROR:AAAFreeAVP: param avp cannot be null!!\n");
00373         return AAA_ERR_PARAMETER;
00374     }
00375 
00376     /* free all the mem */
00377     if ( (*avp)->free_it && (*avp)->data.s )
00378         shm_free((*avp)->data.s);
00379 
00380     shm_free( *avp );
00381     avp = 0;
00382 
00383     return AAA_ERR_SUCCESS;
00384 }

AAA_AVP* AAAGetFirstAVP ( AAA_AVP_LIST avpList  ) 

This function returns the first AVP in the list.

Parameters:
avpList - the list
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 393 of file diameter_avp.c.

References _avp_list_t::head.

00393                                                {
00394     return avpList->head;
00395 }

AAA_AVP* AAAGetLastAVP ( AAA_AVP_LIST avpList  ) 

This function returns the last AVP in the list.

Parameters:
avpList - the list
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 404 of file diameter_avp.c.

References _avp_list_t::tail.

00405 {
00406     return avpList->tail;
00407 }

AAA_AVP* AAAGetNextAVP ( AAA_AVP avp  ) 

This function returns the next AVP in the list that this AVP was extracted from.

Parameters:
avp - reference avp
Returns:
the next AAA_AVP or NULL if this was the last one
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 418 of file diameter_avp.c.

References avp::next.

Referenced by load_cdp().

00419 {
00420     return avp->next;
00421 }

AAA_AVP* AAAGetPrevAVP ( AAA_AVP avp  ) 

This function returns a the previous AVP in the list that this AVP was extracted from.

Parameters:
avp - reference avp
Returns:
the next AAA_AVP or NULL if this was the first one
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 431 of file diameter_avp.c.

References avp::prev.

00432 {
00433     return avp->prev;
00434 }

char* AAAConvertAVPToString ( AAA_AVP avp,
char *  dest,
unsigned int  destLen 
)

This function converts the data in the AVP to a format suitable for print, log or display.

Parameters:
avp - the AAA_AVP to print
dest - preallocated destination buffer. If too short, message will be truncated
destLen - length of the destipation buffer
Returns:
dest on success, NULL on failure
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 447 of file diameter_avp.c.

References AAA_AVP_ADDRESS_TYPE, AAA_AVP_DATA_TYPE, AAA_AVP_INTEGER32_TYPE, AAA_AVP_STRING_TYPE, AAA_AVP_TIME_TYPE, avp::code, avp::data, avp::flags, avp::next, avp::prev, avp::type, and avp::vendorId.

Referenced by AAAPrintMessage().

00448 {
00449     int l;
00450     int i;
00451 
00452     if (!avp || !dest || !destLen) {
00453         LOG(L_ERR,"ERROR:AAAConvertAVPToString: param AVP, DEST or DESTLEN "
00454             "passed as null!!!\n");
00455         return 0;
00456     }
00457     l = snprintf(dest,destLen,"AVP(%p < %p >%p);code=%u,"
00458         "flags=%x;\nDataType=%u;VendorID=%u;DataLen=%u;\n",
00459         avp->prev,avp,avp->next,avp->code,avp->flags,
00460         avp->type,avp->vendorId,avp->data.len);
00461     switch(avp->type) {
00462         case AAA_AVP_STRING_TYPE:
00463             l+=snprintf(dest+l,destLen-l,"String: <%.*s>",avp->data.len,
00464                 avp->data.s);
00465             break;
00466         case AAA_AVP_INTEGER32_TYPE:
00467             l+=snprintf(dest+l,destLen-l,"Int32: <%u>(%x)",
00468                 htonl(*((unsigned int*)avp->data.s)),
00469                 htonl(*((unsigned int*)avp->data.s)));
00470             break;
00471         case AAA_AVP_ADDRESS_TYPE:
00472             i = 1;
00473             switch (avp->data.len) {
00474                 case 4: i=i*0;
00475                 case 6: i=i*2;
00476                     l+=snprintf(dest+l,destLen-l,"Address IPv4: <%d.%d.%d.%d>",
00477                         (unsigned char)avp->data.s[i+0],
00478                         (unsigned char)avp->data.s[i+1],
00479                         (unsigned char)avp->data.s[i+2],
00480                         (unsigned char)avp->data.s[i+3]);
00481                     break;
00482                 case 16: i=i*0;
00483                 case 18: i=i*2;
00484                     l+=snprintf(dest+l,destLen-l,
00485                         "Address IPv6: <%x.%x.%x.%x.%x.%x.%x.%x>",
00486                         ((avp->data.s[i+0]<<8)+avp->data.s[i+1]),
00487                         ((avp->data.s[i+2]<<8)+avp->data.s[i+3]),
00488                         ((avp->data.s[i+4]<<8)+avp->data.s[i+5]),
00489                         ((avp->data.s[i+6]<<8)+avp->data.s[i+7]),
00490                         ((avp->data.s[i+8]<<8)+avp->data.s[i+9]),
00491                         ((avp->data.s[i+10]<<8)+avp->data.s[i+11]),
00492                         ((avp->data.s[i+12]<<8)+avp->data.s[i+13]),
00493                         ((avp->data.s[i+14]<<8)+avp->data.s[i+15]));
00494                     break;
00495             break;
00496             }
00497             break;
00498         //case AAA_AVP_INTEGER64_TYPE:
00499         case AAA_AVP_TIME_TYPE:
00500         default:
00501             LOG(L_WARN,"WARNING:AAAConvertAVPToString: don't know how to print"
00502                 " this data type [%d] -> tryng hexa\n",avp->type);
00503         case AAA_AVP_DATA_TYPE:
00504             for (i=0;i<avp->data.len&&l<destLen-1;i++)
00505             l+=snprintf(dest+l,destLen-l-1,"%x",
00506                 ((unsigned char*)avp->data.s)[i]);
00507     }
00508     return dest;
00509 }

AAA_AVP* AAACloneAVP ( AAA_AVP avp,
unsigned char  clone_data 
)

Duplicate a whole AAA_AVP.

Parameters:
avp - original avp
clone_data - whether to duplicate also the data payload
Returns:
the new AAA_AVP* or NULL on error
Note:
This function is taken from DISC http://developer.berlios.de/projects/disc/

Definition at line 519 of file diameter_avp.c.

References avp::data, avp::free_it, avp::next, and avp::prev.

Referenced by AAANewMessage().

00520 {
00521     AAA_AVP *n_avp;
00522 
00523     if (!avp || !(avp->data.s) || !(avp->data.len) )
00524         goto error;
00525 
00526     /* clone the avp structure */
00527     n_avp = (AAA_AVP*)shm_malloc( sizeof(AAA_AVP) );
00528     if (!n_avp) {
00529         LOG(L_ERR,"ERROR:clone_avp: cannot get free memory!!\n");
00530         goto error;
00531     }
00532     memcpy( n_avp, avp, sizeof(AAA_AVP));
00533     n_avp->next = n_avp->prev = 0;
00534 
00535     if (clone_data) {
00536         /* clone the avp data */
00537         n_avp->data.s = (char*)shm_malloc( avp->data.len );
00538         if (!(n_avp->data.s)) {
00539             LOG(L_ERR,"ERROR:clone_avp: cannot get free memory!!\n");
00540             shm_free( n_avp );
00541             goto error;
00542         }
00543         memcpy( n_avp->data.s, avp->data.s, avp->data.len);
00544         n_avp->free_it = 1;
00545     } else {
00546         /* link the clone's data to the original's data */
00547         n_avp->data.s = avp->data.s;
00548         n_avp->data.len = avp->data.len;
00549         n_avp->free_it = 0;
00550     }
00551 
00552     return n_avp;
00553 error:
00554     return 0;
00555 }

void AAAAddAVPtoList ( AAA_AVP_LIST list,
AAA_AVP avp 
)

Adds an AVP to a list of AVPs, at the end.

Parameters:
list - the list to add to
avp - the avp to add

Definition at line 566 of file diameter_avp.c.

References _avp_list_t::head, avp::next, avp::prev, and _avp_list_t::tail.

00567 {
00568     if (list->tail) {
00569         avp->prev=list->tail;
00570         avp->next=0;    
00571         list->tail->next = avp;
00572         list->tail=avp;
00573     } else {
00574         list->head = avp;
00575         list->tail = avp;
00576         avp->next=0;
00577         avp->prev=0;
00578     }   
00579 }

str AAAGroupAVPS ( AAA_AVP_LIST  avps  ) 

Groups a list of avps into a data buffer.

Parameters:
avps 

Definition at line 585 of file diameter_avp.c.

References AVP_HDR_SIZE, avp::code, avp::data, avp::flags, _avp_list_t::head, avp::next, set_3bytes, set_4bytes, to_32x_len, and avp::vendorId.

Referenced by load_cdp(), and Snd_CE_add_applications().

00586  {
00587     AAA_AVP *avp;
00588     unsigned char *p;
00589     str buf={0,0};
00590 
00591     /* count and add the avps */
00592     for(avp=avps.head;avp;avp=avp->next) {
00593         buf.len += AVP_HDR_SIZE(avp->flags)+ to_32x_len( avp->data.len );
00594     }
00595 
00596     if (!buf.len) return buf;
00597     /* allocate some memory */
00598     buf.s = (char*)shm_malloc( buf.len );
00599     if (!buf.s) {
00600         LOG(L_ERR,"ERROR:hss3g_group_avps: no more free memory!\n");
00601         return buf;
00602     }
00603     memset(buf.s, 0, buf.len);
00604     /* fill in the buffer */
00605     p = (unsigned char*) buf.s;
00606     for(avp=avps.head;avp;avp=avp->next) {
00607         /* AVP HEADER */
00608         /* avp code */
00609         set_4bytes(p,avp->code);
00610         p +=4;
00611         /* flags */
00612         (*p++) = (unsigned char)avp->flags;
00613         /* avp length */
00614         set_3bytes(p, (AVP_HDR_SIZE(avp->flags)+avp->data.len) );
00615         p += 3;
00616         /* vendor id */
00617         if ((avp->flags&0x80)!=0) {
00618             set_4bytes(p,avp->vendorId);
00619             p +=4;
00620         }
00621         /* data */
00622         memcpy( p, avp->data.s, avp->data.len);
00623         p += to_32x_len( avp->data.len );
00624     }
00625     if ((char*)p-buf.s!=buf.len) {
00626         LOG(L_ERR,"BUG:hss3g_group_avps: mismatch between len and buf!\n");
00627         shm_free( buf.s );
00628         buf.s = 0;
00629         buf.len = 0;
00630         return buf;
00631     }
00632     return buf;
00633 }

AAA_AVP_LIST AAAUngroupAVPS ( str  buf  ) 

Ungroup from a data buffer a list of avps.

Parameters:
buf - payload to ungroup the list from
Returns:
the AAA_AVP_LIST or an empty one on error

Definition at line 640 of file diameter_avp.c.

References AAA_AVP_FLAG_VENDOR_SPECIFIC, AAACreateAVP(), AVP_CODE_SIZE, AVP_DONT_FREE_DATA, AVP_FLAGS_SIZE, AVP_HDR_SIZE, AVP_LENGTH_SIZE, AVP_VENDOR_ID_SIZE, get_3bytes, get_4bytes, _avp_list_t::head, avp::next, avp::prev, _avp_list_t::tail, and to_32x_len.

Referenced by get_routing_peer(), load_cdp(), Process_CER(), and save_peer_applications().

00641 {
00642     char *ptr;
00643     AAA_AVP       *avp;
00644     unsigned int  avp_code;
00645     unsigned char avp_flags;
00646     unsigned int  avp_len;
00647     unsigned int  avp_vendorID;
00648     unsigned int  avp_data_len;
00649     AAA_AVP_LIST    lh;
00650 
00651     lh.head=0;
00652     lh.tail=0;
00653     ptr = buf.s;
00654 
00655     /* start decoding the AVPS */
00656     while (ptr < buf.s+buf.len) {
00657         if (ptr+AVP_HDR_SIZE(0x80)>buf.s+buf.len){
00658             LOG(L_ERR,"ERROR:hss3g_ungroup_avps: source buffer to short!! "
00659                 "Cannot read the whole AVP header!\n");
00660             goto error;
00661         }
00662         /* avp code */
00663         avp_code = get_4bytes( ptr );
00664         ptr += AVP_CODE_SIZE;
00665         /* avp flags */
00666         avp_flags = (unsigned char)*ptr;
00667         ptr += AVP_FLAGS_SIZE;
00668         /* avp length */
00669         avp_len = get_3bytes( ptr );
00670         ptr += AVP_LENGTH_SIZE;
00671         if (avp_len<1) {
00672             LOG(L_ERR,"ERROR:hss3g_ungroup_avps: invalid AVP len [%d]\n",
00673                 avp_len);
00674             goto error;
00675         }
00676         /* avp vendor-ID */
00677         avp_vendorID = 0;
00678         if (avp_flags&AAA_AVP_FLAG_VENDOR_SPECIFIC) {
00679             avp_vendorID = get_4bytes( ptr );
00680             ptr += AVP_VENDOR_ID_SIZE;
00681         }
00682 
00683         /* data length */
00684         avp_data_len = avp_len-AVP_HDR_SIZE(avp_flags);
00685         /*check the data length */
00686         if ( buf.s+buf.len<ptr+avp_data_len) {
00687             LOG(L_ERR,"ERROR:hss3g_ungroup_avps: source buffer to short!! "
00688                 "Cannot read a whole data for AVP!\n");
00689             goto error;
00690         }
00691 
00692         /* create the AVP */
00693         avp = AAACreateAVP( avp_code, avp_flags, avp_vendorID, ptr,
00694             avp_data_len, AVP_DONT_FREE_DATA);
00695         if (!avp) {
00696             LOG(L_ERR,"ERROR:hss3g_ungroup_avps: can't create avp for member of list\n");
00697             goto error;
00698         }
00699 
00700         /* link the avp into aaa message to the end */
00701         avp->next = 0;
00702         avp->prev = lh.tail;
00703         if (lh.tail) {
00704             lh.tail->next=avp;
00705             lh.tail=avp;
00706         }
00707         else {
00708             lh.tail=avp;
00709             lh.head=avp;
00710         }
00711 
00712         ptr += to_32x_len( avp_data_len );
00713     }
00714     return lh;
00715 
00716 error:
00717     LOG(L_CRIT,"AVP:<%.*s>\n",buf.len,buf.s);
00718     return lh;
00719 }

AAA_AVP* AAAFindMatchingAVPList ( AAA_AVP_LIST  avpList,
AAA_AVP startAvp,
AAA_AVPCode  avpCode,
AAAVendorId  vendorId,
AAASearchType  searchType 
)

Find an avp into a list of avps.

Parameters:
avpList - the list to look into
startAvp - where to start the search. Usefull when you want to find the next one. Even this one will be checked and can be returned if it fits.
avpCode - the AVP code to match
vendorId - the vendor id to match
searchType - direction of search
Returns:
the AAA_AVP* if found, NULL if not

Definition at line 731 of file diameter_avp.c.

References AAA_FORWARD_SEARCH, avp::code, _avp_list_t::head, avp::next, avp::prev, _avp_list_t::tail, and avp::vendorId.

Referenced by get_routing_peer(), load_cdp(), Process_CER(), and save_peer_applications().

00737 {
00738     AAA_AVP *avp_t;
00739 
00740     /* param checking */
00741 
00742     /* where should I start searching from ? */
00743     if (startAvp) {
00744         /* double-check the startAVP avp */
00745         for(avp_t=avpList.head;avp_t&&avp_t!=startAvp;avp_t=avp_t->next);
00746         if (!avp_t) {
00747             LOG(L_ERR,"ERROR: AAAFindMatchingAVP: the \"position\" avp is not "
00748                 "in \"avpList\" list!!\n");
00749             goto error;
00750         }
00751         avp_t=startAvp;
00752     } else {
00753         /* if no startAVP -> start from one of the ends */
00754         avp_t=(searchType==AAA_FORWARD_SEARCH)?(avpList.head):
00755             (avpList.tail);
00756     }
00757 
00758     /* start searching */
00759     while(avp_t) {
00760         if (avp_t->code==avpCode && avp_t->vendorId==vendorId)
00761             return avp_t;
00762         avp_t = (searchType==AAA_FORWARD_SEARCH)?(avp_t->next):(avp_t->prev);
00763     }
00764 
00765 error:
00766     return 0;
00767 }

void AAAAddAVPToAVPList ( AAA_AVP_LIST list,
AAA_AVP avp 
)

Add an AVP to a list of AVPs.

Parameters:
list - the list to add to
avp - the avp to add

Definition at line 774 of file diameter_avp.c.

References _avp_list_t::head, avp::next, avp::prev, and _avp_list_t::tail.

Referenced by Snd_CE_add_applications().

00775 {
00776     if (list->tail) {
00777         avp->prev=list->tail;
00778         avp->