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