00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036 #ifdef DIAM_ACC
00037
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <netinet/in.h>
00042
00043 #include "../../mem/shm_mem.h"
00044 #include "../../dprint.h"
00045 #include "diam_message.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054 inline void set_avp_fields( AAA_AVPCode code, AAA_AVP *avp)
00055 {
00056 switch (code) {
00057 case 1:
00058 case 25:
00059 case 263:
00060 case 283:
00061 case 293:
00062 case 264:
00063 case 296:
00064 case 400:
00065 case 401:
00066 case 402:
00067 case 403:
00068 case 404:
00069 case 405:
00070 case 279:
00071 avp->flags = 0x40|(0x20&avp->flags);
00072 avp->type = AAA_AVP_STRING_TYPE;
00073 break;
00074 case 27:
00075 case 258:
00076 case 262:
00077 case 265:
00078 case 266:
00079 case 268:
00080 case 270:
00081 case 276:
00082 case 278:
00083 case 291:
00084 avp->flags = 0x40|(0x20&avp->flags);
00085 avp->type = AAA_AVP_INTEGER32_TYPE;
00086 break;
00087 case 33:
00088 avp->flags = 0x40;
00089 avp->type = AAA_AVP_STRING_TYPE;
00090 break;
00091 case 257:
00092 avp->flags = 0x40|(0x20&avp->flags);
00093 avp->type = AAA_AVP_ADDRESS_TYPE;
00094 break;
00095 case 269:
00096 avp->flags = 0x00;
00097 avp->type = AAA_AVP_STRING_TYPE;
00098 break;
00099 case 281:
00100 avp->flags = (0x20&avp->flags);
00101 avp->type = AAA_AVP_STRING_TYPE;
00102 break;
00103 default:
00104 avp->type = AAA_AVP_DATA_TYPE;
00105 };
00106 }
00107
00108
00109
00110
00111
00112 AAA_AVP* AAACreateAVP(
00113 AAA_AVPCode code,
00114 AAA_AVPFlag flags,
00115 AAAVendorId vendorId,
00116 char *data,
00117 size_t length,
00118 AVPDataStatus data_status)
00119 {
00120 AAA_AVP *avp;
00121
00122
00123 if( data==0 || length==0) {
00124 LM_ERR("null value received for param data/length !!\n");
00125 return 0;
00126 }
00127
00128
00129 avp = 0;
00130 avp = (AAA_AVP*)ad_malloc(sizeof(AAA_AVP));
00131 if (!avp)
00132 goto error;
00133 memset( avp, 0, sizeof(AAA_AVP) );
00134
00135
00136
00137 avp->packetType = AAA_DIAMETER;
00138 avp->code=code;
00139 avp->flags=flags;
00140 avp->vendorId=vendorId;
00141 set_avp_fields( code, avp);
00142
00143 if ( data_status==AVP_DUPLICATE_DATA ) {
00144
00145 avp->data.len = length;
00146 avp->data.s = (void*)ad_malloc(length);
00147 if(!avp->data.s)
00148 goto error;
00149 memcpy( avp->data.s, data, length);
00150 avp->free_it = 1;
00151 } else {
00152 avp->data.s = data;
00153 avp->data.len = length;
00154 avp->free_it = (data_status==AVP_FREE_DATA)?1:0;
00155 }
00156
00157 return avp;
00158 error:
00159 LM_ERR("no more free memoryfor a new AVP!\n");
00160 return 0;
00161 }
00162
00163
00164
00165
00166 AAAReturnCode AAAAddAVPToMessage(
00167 AAAMessage *msg,
00168 AAA_AVP *avp,
00169 AAA_AVP *position)
00170 {
00171 AAA_AVP *avp_t;
00172
00173 if ( !msg || !avp ) {
00174 LM_ERR("param msg or avp passed null or *avpList=NULL "
00175 "and position!=NULL !!\n");
00176 return AAA_ERR_PARAMETER;
00177 }
00178
00179 if (!position) {
00180
00181 avp->next = msg->avpList.head;
00182 avp->prev = 0;
00183 msg->avpList.head = avp;
00184 if (avp->next)
00185 avp->next->prev = avp;
00186 else
00187 msg->avpList.tail = avp;
00188 } else {
00189
00190 for(avp_t=msg->avpList.head;avp_t&&avp_t!=position;avp_t=avp_t->next);
00191 if (!avp_t) {
00192 LM_ERR("the \"position\" avp is not in \"msg\" message!!\n");
00193 return AAA_ERR_PARAMETER;
00194 }
00195
00196 avp->next = position->next;
00197 position->next = avp;
00198 if (avp->next)
00199 avp->next->prev = avp;
00200 else
00201 msg->avpList.tail = avp;
00202 avp->prev = position;
00203 }
00204
00205
00206 switch (avp->code) {
00207 case AVP_Session_Id: msg->sessionId = avp;break;
00208 case AVP_Origin_Host: msg->orig_host = avp;break;
00209 case AVP_Origin_Realm: msg->orig_realm = avp;break;
00210 case AVP_Destination_Host: msg->dest_host = avp;break;
00211 case AVP_Destination_Realm: msg->dest_realm = avp;break;
00212 case AVP_Result_Code: msg->res_code = avp;break;
00213 case AVP_Auth_Session_State: msg->auth_ses_state = avp;break;
00214 }
00215
00216 return AAA_ERR_SUCCESS;
00217 }
00218
00219
00220
00221 AAA_AVP *AAAFindMatchingAVP(
00222 AAAMessage *msg,
00223 AAA_AVP *startAvp,
00224 AAA_AVPCode avpCode,
00225 AAAVendorId vendorId,
00226 AAASearchType searchType)
00227 {
00228 AAA_AVP *avp_t;
00229
00230
00231 if (!msg) {
00232 LM_ERR("param msg passed null !!\n");
00233 goto error;
00234 }
00235
00236 for(avp_t=msg->avpList.head;avp_t&&avp_t!=startAvp;avp_t=avp_t->next);
00237 if (!avp_t && startAvp) {
00238 LM_ERR("the \"position\" avp is not in \"avpList\" list!!\n");
00239 goto error;
00240 }
00241
00242
00243 if (!startAvp)
00244 avp_t=(searchType==AAA_FORWARD_SEARCH)?(msg->avpList.head):
00245 (msg->avpList.tail);
00246 else
00247 avp_t=startAvp;
00248
00249
00250 while(avp_t) {
00251 if (avp_t->code==avpCode && avp_t->vendorId==vendorId)
00252 return avp_t;
00253 avp_t = (searchType==AAA_FORWARD_SEARCH)?(avp_t->next):(avp_t->prev);
00254 }
00255
00256 error:
00257 return 0;
00258 }
00259
00260
00261
00262
00263
00264 AAAReturnCode AAARemoveAVPFromMessage(
00265 AAAMessage *msg,
00266 AAA_AVP *avp)
00267 {
00268 AAA_AVP *avp_t;
00269
00270
00271 if ( !msg || !avp ) {
00272 LM_ERR("param AVP_LIST \"avpList\" or AVP \"avp\" passed null !!\n");
00273 return AAA_ERR_PARAMETER;
00274 }
00275
00276
00277 for(avp_t=msg->avpList.head;avp_t&&avp_t!=avp;avp_t=avp_t->next);
00278 if (!avp_t) {
00279 LM_ERR("the \"avp\" avp is not in \"avpList\" avp list!!\n");
00280 return AAA_ERR_PARAMETER;
00281 }
00282
00283
00284 if (msg->avpList.head==avp)
00285 msg->avpList.head = avp->next;
00286 else
00287 avp->prev->next = avp->next;
00288 if (avp->next)
00289 avp->next->prev = avp->prev;
00290 else
00291 msg->avpList.tail = avp->prev;
00292 avp->next = avp->prev = 0;
00293
00294
00295 switch (avp->code) {
00296 case AVP_Session_Id: msg->sessionId = 0;break;
00297 case AVP_Origin_Host: msg->orig_host = 0;break;
00298 case AVP_Origin_Realm: msg->orig_realm = 0;break;
00299 case AVP_Destination_Host: msg->dest_host = 0;break;
00300 case AVP_Destination_Realm: msg->dest_realm = 0;break;
00301 case AVP_Result_Code: msg->res_code = 0;break;
00302 case AVP_Auth_Session_State: msg->auth_ses_state = 0;break;
00303 }
00304
00305 return AAA_ERR_SUCCESS;
00306 }
00307
00308
00309
00310
00311 AAAReturnCode AAAFreeAVP(AAA_AVP **avp)
00312 {
00313
00314 if (!avp || !(*avp)) {
00315 LM_ERR("param avp cannot be null!!\n");
00316 return AAA_ERR_PARAMETER;
00317 }
00318
00319
00320 if ( (*avp)->free_it && (*avp)->data.s )
00321 ad_free((*avp)->data.s);
00322
00323 ad_free( *avp );
00324 *avp = 0;
00325
00326 return AAA_ERR_SUCCESS;
00327 }
00328
00329
00330
00331
00332 AAA_AVP* AAAGetFirstAVP(AAA_AVP_LIST *avpList){
00333 return avpList->head;
00334 }
00335
00336
00337
00338
00339 AAA_AVP* AAAGetLastAVP(AAA_AVP_LIST *avpList)
00340 {
00341 return avpList->tail;
00342 }
00343
00344
00345
00346
00347
00348 AAA_AVP* AAAGetNextAVP(AAA_AVP *avp)
00349 {
00350 return avp->next;
00351 }
00352
00353
00354
00355
00356 AAA_AVP* AAAGetPrevAVP(AAA_AVP *avp)
00357 {
00358 return avp->prev;
00359 }
00360
00361
00362
00363
00364
00365 char* AAAConvertAVPToString(AAA_AVP *avp, char *dest, unsigned int destLen)
00366 {
00367 int l;
00368 int i;
00369
00370 if (!avp || !dest || !destLen) {
00371 LM_ERR("param AVP, DEST or DESTLEN passed as null!!!\n");
00372 return 0;
00373 }
00374 l = snprintf(dest,destLen,"AVP(%p < %p >%p):packetType=%u;code=%u,"
00375 "flags=%x;\nDataType=%u;VendorID=%u;DataLen=%u;\n",
00376 avp->prev,avp,avp->next,avp->packetType,avp->code,avp->flags,
00377 avp->type,avp->vendorId,avp->data.len);
00378 switch(avp->type) {
00379 case AAA_AVP_STRING_TYPE:
00380 l+=snprintf(dest+l,destLen-l,"String: <%.*s>",avp->data.len,
00381 avp->data.s);
00382 break;
00383 case AAA_AVP_INTEGER32_TYPE:
00384 l+=snprintf(dest+l,destLen-l,"Int32: <%u>(%x)",
00385 htonl(*((unsigned int*)avp->data.s)),
00386 htonl(*((unsigned int*)avp->data.s)));
00387 break;
00388 case AAA_AVP_ADDRESS_TYPE:
00389 i = 1;
00390 switch (avp->data.len) {
00391 case 4: i=i*0;
00392 case 6: i=i*2;
00393 l+=snprintf(dest+l,destLen-l,"Address IPv4: <%d.%d.%d.%d>",
00394 (unsigned char)avp->data.s[i+0],
00395 (unsigned char)avp->data.s[i+1],
00396 (unsigned char)avp->data.s[i+2],
00397 (unsigned char)avp->data.s[i+3]);
00398 break;
00399 case 16: i=i*0;
00400 case 18: i=i*2;
00401 l+=snprintf(dest+l,destLen-l,
00402 "Address IPv6: <%x.%x.%x.%x.%x.%x.%x.%x>",
00403 ((avp->data.s[i+0]<<8)+avp->data.s[i+1]),
00404 ((avp->data.s[i+2]<<8)+avp->data.s[i+3]),
00405 ((avp->data.s[i+4]<<8)+avp->data.s[i+5]),
00406 ((avp->data.s[i+6]<<8)+avp->data.s[i+7]),
00407 ((avp->data.s[i+8]<<8)+avp->data.s[i+9]),
00408 ((avp->data.s[i+10]<<8)+avp->data.s[i+11]),
00409 ((avp->data.s[i+12]<<8)+avp->data.s[i+13]),
00410 ((avp->data.s[i+14]<<8)+avp->data.s[i+15]));
00411 break;
00412 break;
00413 }
00414 break;
00415
00416 case AAA_AVP_TIME_TYPE:
00417 default:
00418 LM_WARN("don't know how to print"
00419 " this data type [%d] -> trying hexa\n",avp->type);
00420 case AAA_AVP_DATA_TYPE:
00421 for (i=0;i<avp->data.len&&l<destLen-1;i++)
00422 l+=snprintf(dest+l,destLen-l-1,"%x",
00423 ((unsigned char*)avp->data.s)[i]);
00424 }
00425 return dest;
00426 }
00427
00428
00429
00430 AAA_AVP* AAACloneAVP( AAA_AVP *avp , unsigned char clone_data)
00431 {
00432 AAA_AVP *n_avp;
00433
00434 if (!avp || !(avp->data.s) || !(avp->data.len) )
00435 goto error;
00436
00437
00438 n_avp = (AAA_AVP*)ad_malloc( sizeof(AAA_AVP) );
00439 if (!n_avp) {
00440 LM_ERR("cannot get free memory!!\n");
00441 goto error;
00442 }
00443 memcpy( n_avp, avp, sizeof(AAA_AVP));
00444 n_avp->next = n_avp->prev = 0;
00445
00446 if (clone_data) {
00447
00448 n_avp->data.s = (char*)ad_malloc( avp->data.len );
00449 if (!(n_avp->data.s)) {
00450 LM_ERR("cannot get free memory!!\n");
00451 ad_free( n_avp );
00452 goto error;
00453 }
00454 memcpy( n_avp->data.s, avp->data.s, avp->data.len);
00455 n_avp->free_it = 1;
00456 } else {
00457
00458 n_avp->data.s = avp->data.s;
00459 n_avp->data.len = avp->data.len;
00460 n_avp->free_it = 0;
00461 }
00462
00463 return n_avp;
00464 error:
00465 return 0;
00466 }
00467
00468 #endif