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_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. | |
| 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_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. | |
| 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_AVP * | AAAGetFirstAVP (AAA_AVP_LIST *avpList) |
| This function returns the first AVP in the list. | |
| AAA_AVP * | AAAGetLastAVP (AAA_AVP_LIST *avpList) |
| This function returns the last AVP in the list. | |
| AAA_AVP * | AAAGetNextAVP (AAA_AVP *avp) |
| This function returns the next AVP in the list that this AVP was extracted from. | |
| AAA_AVP * | AAAGetPrevAVP (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_AVP * | AAACloneAVP (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_AVP * | AAAFindMatchingAVPList (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. | |
| 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.
| code | - code of the AVP | |
| avp | - the actual AVP to set flags |
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.
| 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 |
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.
| 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. |
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.
| 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 |
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.
| msg | - the diameter message | |
| avp | - the AVP to remove |
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.
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.
| avpList | - the list |
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.
| avpList | - the list |
Definition at line 404 of file diameter_avp.c.
References _avp_list_t::tail.
00405 { 00406 return avpList->tail; 00407 }
This function returns the next AVP in the list that this AVP was extracted from.
Definition at line 418 of file diameter_avp.c.
References avp::next.
Referenced by load_cdp().
00419 { 00420 return avp->next; 00421 }
This function returns a the previous AVP in the list that this AVP was extracted from.
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.
| avp | - the AAA_AVP to print | |
| dest | - preallocated destination buffer. If too short, message will be truncated | |
| destLen | - length of the destipation buffer |
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 }
Duplicate a whole AAA_AVP.
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.
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.
| 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.
| buf | - payload to ungroup the list from |
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.
| 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 |
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.
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().