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
00029
00030
00031
00032
00033
00034
00035
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