00001
00054 #include "diameter.h"
00055 #include "diameter_api.h"
00056
00057
00058 #include <stdlib.h>
00059 #include <string.h>
00060 #include <netinet/in.h>
00061
00062 #include "utils.h"
00063 #include "globals.h"
00064
00065 #include "config.h"
00066 #include "peermanager.h"
00067
00068 extern dp_config *config;
00078 AAAReturnCode AAABuildMsgBuffer( AAAMessage *msg )
00079 {
00080 unsigned char *p;
00081 AAA_AVP *avp;
00082
00083
00084 msg->buf.len = AAA_MSG_HDR_SIZE;
00085
00086 for(avp=msg->avpList.head;avp;avp=avp->next) {
00087 msg->buf.len += AVP_HDR_SIZE(avp->flags)+ to_32x_len( avp->data.len );
00088 }
00089
00090 DBG("AAABuildMsgBuffer(): len=%d\n",msg->buf.len);
00091
00092 msg->buf.s = (char*)shm_malloc( msg->buf.len );
00093 if (!msg->buf.s) {
00094 LOG(L_ERR,"ERROR:AAABuildMsgBuffer: no more free memory!\n");
00095 goto error;
00096 }
00097 memset(msg->buf.s, 0, msg->buf.len);
00098
00099
00100 p = (unsigned char*)msg->buf.s;
00101
00102
00103 ((unsigned int*)p)[0] =htonl(msg->buf.len);
00104
00105 *p = 1;
00106 p += VER_SIZE + MESSAGE_LENGTH_SIZE;
00107
00108 ((unsigned int*)p)[0] = htonl(msg->commandCode);
00109
00110 *p = (unsigned char)msg->flags;
00111 p += FLAGS_SIZE + COMMAND_CODE_SIZE;
00112
00113 ((unsigned int*)p)[0] = htonl(msg->applicationId);
00114 p += APPLICATION_ID_SIZE;
00115
00116 ((unsigned int*)p)[0] = htonl(msg->hopbyhopId);
00117 p += HOP_BY_HOP_IDENTIFIER_SIZE;
00118
00119 ((unsigned int*)p)[0] = htonl(msg->endtoendId);
00120 p += END_TO_END_IDENTIFIER_SIZE;
00121
00122
00123 for(avp=msg->avpList.head;avp;avp=avp->next) {
00124
00125
00126 set_4bytes(p,avp->code);
00127 p +=4;
00128
00129 (*p++) = (unsigned char)avp->flags;
00130
00131 set_3bytes(p, (AVP_HDR_SIZE(avp->flags)+avp->data.len) );
00132 p += 3;
00133
00134 if ((avp->flags&0x80)!=0) {
00135 set_4bytes(p,avp->vendorId);
00136 p +=4;
00137 }
00138
00139 memcpy( p, avp->data.s, avp->data.len);
00140 p += to_32x_len( avp->data.len );
00141 }
00142
00143 if ((char*)p-msg->buf.s!=msg->buf.len) {
00144 LOG(L_ERR,"BUG: build_buf_from_msg: mismatch between len and buf!\n");
00145 shm_free( msg->buf.s );
00146 msg->buf.s = 0;
00147 msg->buf.len = 0;
00148 goto error;
00149 }
00150
00151 return 1;
00152 error:
00153 return -1;
00154 }
00155
00156
00157
00158
00169 AAAMessage *AAANewMessage(
00170 AAACommandCode commandCode,
00171 AAAApplicationId applicationId,
00172 AAASessionId *sessionId,
00173 AAAMessage *request)
00174 {
00175 AAAMessage *msg;
00176 AAA_AVP *avp;
00177 AAA_AVP *avp_t;
00178 #if 0
00179 unsigned int code;
00180 #endif
00181 str dest_host={"?",1};
00182 str dest_realm={"?",1};
00183
00184 msg = 0;
00185
00186 if (!sessionId||!sessionId->s) {
00187 if (request && request->sessionId){
00188
00189 avp = request->sessionId;
00190 if (avp) {
00191 sessionId = &(avp->data);
00192 }
00193 }else{
00194
00195
00196
00197 }
00198 }
00199
00200
00201 msg = (AAAMessage*)shm_malloc(sizeof(AAAMessage));
00202 if (!msg) {
00203 LOG(L_ERR,"ERROR:AAANewMessage: no more free memory!!\n");
00204 goto error;
00205 }
00206 memset(msg,0,sizeof(AAAMessage));
00207
00208
00209 msg->commandCode = commandCode;
00210
00211 msg->applicationId = applicationId;
00212
00213
00214 if (sessionId){
00215 avp = AAACreateAVP( 263, 0, 0, sessionId->s, sessionId->len,
00216 AVP_DUPLICATE_DATA);
00217 if ( !avp || AAAAddAVPToMessage(msg,avp,0)!=AAA_ERR_SUCCESS) {
00218 LOG(L_ERR,"ERROR:AAANewMessage: cannot create/add Session-Id avp\n");
00219 if (avp) AAAFreeAVP( &avp );
00220 goto error;
00221 }
00222 msg->sessionId = avp;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232 avp = AAACreateAVP( 264, 0, 0, config->fqdn.s, config->fqdn.len,
00233 AVP_DUPLICATE_DATA);
00234 if (!avp||AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) {
00235 LOG(L_ERR,"ERROR:AAANewMessage: cannot create/add Origin-Host avp\n");
00236 if (avp) AAAFreeAVP( &avp );
00237 goto error;
00238 }
00239 msg->orig_host = avp;
00240
00241 avp = AAACreateAVP( 296, 0, 0, config->realm.s, config->realm.len,
00242 AVP_DUPLICATE_DATA);
00243 if (!avp||AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) {
00244 LOG(L_ERR,"ERROR:AAANewMessage: cannot create/add Origin-Realm avp\n");
00245 if (avp) AAAFreeAVP( &avp );
00246 goto error;
00247 }
00248 msg->orig_realm = avp;
00249
00250 if (!request) {
00251
00252 msg->flags = 0x80;
00253
00254 msg->sId = sessionId;
00255 } else {
00256
00257 msg->sId = request->sId;
00258
00259 msg->in_peer = request->in_peer;
00260
00261 msg->flags |= request->flags&0x40;
00262
00263 msg->endtoendId = request->endtoendId;
00264 msg->hopbyhopId = request->hopbyhopId;
00265
00266
00267 avp = AAAFindMatchingAVP(request,0,AVP_Origin_Host,0,0);
00268 if (avp) dest_host = avp->data;
00269
00270 avp = AAACreateAVP(AVP_Destination_Host,AAA_AVP_FLAG_MANDATORY,0,
00271 dest_host.s,dest_host.len,AVP_DUPLICATE_DATA);
00272 if (!avp) {
00273 LOG(L_ERR,"ERR:AAANewMessage: Failed creating Destination Host avp\n");
00274 return 0;
00275 }
00276 if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) {
00277 LOG(L_ERR,"ERR:AAANewMessage: Failed adding Destination Host avp to message\n");
00278 AAAFreeAVP(&avp);
00279 return 0;
00280 }
00281 avp = AAAFindMatchingAVP(request,0,AVP_Origin_Realm,0,0);
00282 if (avp) dest_realm = avp->data;
00283
00284 avp = AAACreateAVP(AVP_Destination_Realm,AAA_AVP_FLAG_MANDATORY,0,
00285 dest_realm.s,dest_realm.len,AVP_DUPLICATE_DATA);
00286 if (!avp) {
00287 LOG(L_ERR,"ERR:AAANewMessage: Failed creating Destination Realm avp\n");
00288 return 0;
00289 }
00290 if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) {
00291 LOG(L_ERR,"ERR:AAANewMessage: Failed adding Destination Realm avp to message\n");
00292 AAAFreeAVP(&avp);
00293 return 0;
00294 }
00295
00296
00297 msg->res_code=0;
00298
00299 avp_t = request->avpList.head;
00300 while ( (avp_t=AAAFindMatchingAVP
00301 (request,avp_t,284,0,AAA_FORWARD_SEARCH))!=0 ) {
00302 if ( (avp=AAACloneAVP(avp_t,1))==0 || AAAAddAVPToMessage( msg, avp,
00303 msg->avpList.tail)!=AAA_ERR_SUCCESS )
00304 goto error;
00305 }
00306 }
00307
00308 return msg;
00309 error:
00310 LOG(L_ERR,"ERROR:AAANewMessage: failed to create a new AAA message!\n");
00311 AAAFreeMessage(&msg);
00312 return 0;
00313 }
00314
00323 AAAMessage *AAACreateRequest(AAAApplicationId app_id,
00324 AAACommandCode command_code,
00325 AAAMsgFlag flags,
00326 AAASessionId *sessId)
00327 {
00328 AAAMessage *msg;
00329 msg = AAANewMessage(command_code,app_id,sessId,0);
00330 if (!msg) return 0;
00331 msg->hopbyhopId = next_hopbyhop();
00332 msg->endtoendId = next_endtoend();
00333 msg->flags |= flags;
00334 return msg;
00335 }
00336
00342 AAAMessage *AAACreateResponse(AAAMessage *request)
00343 {
00344 AAAMessage *msg;
00345 msg = AAANewMessage(request->commandCode,request->applicationId,request->sId,request);
00346
00347 return msg;
00348 }
00349
00350
00356 AAAReturnCode AAAFreeAVPList(AAA_AVP_LIST *avpList)
00357 {
00358 AAA_AVP *avp_t;
00359 AAA_AVP *avp;
00360
00361 avp = avpList->head;
00362 while (avp) {
00363 avp_t = avp;
00364 avp = avp->next;
00365
00366 AAAFreeAVP(&avp_t);
00367 }
00368 avpList->head = 0;
00369 avpList->tail = 0;
00370 return AAA_ERR_SUCCESS;
00371 }
00372
00378 AAAReturnCode AAAFreeMessage(AAAMessage **msg)
00379 {
00380 LOG(L_DBG,"DBG:AAAFreeMessage: Freeing message (%p) %d\n",*msg,(*msg)->commandCode);
00381
00382 if (!msg || !(*msg))
00383 goto done;
00384
00385
00386 AAAFreeAVPList(&((*msg)->avpList));
00387
00388
00389 if ( (*msg)->buf.s )
00390 shm_free( (*msg)->buf.s );
00391
00392
00393 shm_free(*msg);
00394 *msg = 0;
00395
00396 done:
00397 return AAA_ERR_SUCCESS;
00398 }
00399
00407 AAAResultCode AAASetMessageResultCode(
00408 AAAMessage *message,
00409 AAAResultCode resultCode)
00410 {
00411 if ( !is_req(message) && message->res_code) {
00412 *((unsigned int*)(message->res_code->data.s)) = htonl(resultCode);
00413 return AAA_ERR_SUCCESS;
00414 }
00415 return AAA_ERR_FAILURE;
00416 }
00417
00418
00419
00428 AAAMessage* AAATranslateMessage( unsigned char* source, unsigned int sourceLen,
00429 int attach_buf)
00430 {
00431 unsigned char *ptr;
00432 AAAMessage *msg;
00433 unsigned char version;
00434 unsigned int msg_len;
00435 AAA_AVP *avp;
00436 unsigned int avp_code;
00437 unsigned char avp_flags;
00438 unsigned int avp_len;
00439 unsigned int avp_vendorID;
00440 unsigned int avp_data_len;
00441
00442
00443 if( !source || !sourceLen || sourceLen<AAA_MSG_HDR_SIZE) {
00444 LOG(L_ERR,"ERROR:AAATranslateMessage: invalid buffered received!\n");
00445 goto error;
00446 }
00447
00448
00449 msg = 0;
00450 avp = 0;
00451 ptr = source;
00452
00453
00454 msg = (AAAMessage*)shm_malloc(sizeof(AAAMessage));
00455 if (!msg) {
00456 LOG(L_ERR,"ERROR:AAATranslateMessage: no more free memory!!\n");
00457 goto error;
00458 }
00459 memset(msg,0,sizeof(AAAMessage));
00460
00461
00462 version = (unsigned char)*ptr;
00463 ptr += VER_SIZE;
00464 if (version!=1) {
00465 LOG(L_ERR,"ERROR:AAATranslateMessage: invalid version [%d]in "
00466 "AAA msg\n",version);
00467 goto error;
00468 }
00469
00470
00471 msg_len = get_3bytes( ptr );
00472 ptr += MESSAGE_LENGTH_SIZE;
00473 if (msg_len>sourceLen) {
00474 LOG(L_ERR,"ERROR:AAATranslateMessage: AAA message len [%d] bigger then"
00475 " buffer len [%d]\n",msg_len,sourceLen);
00476 goto error;
00477 }
00478
00479
00480 msg->flags = *ptr;
00481 ptr += FLAGS_SIZE;
00482
00483
00484 msg->commandCode = get_3bytes( ptr );
00485 ptr += COMMAND_CODE_SIZE;
00486
00487
00488 msg->applicationId = get_4bytes( ptr );
00489 ptr += APPLICATION_ID_SIZE;
00490
00491
00492 msg->hopbyhopId = ntohl(*((unsigned int*)ptr));
00493 ptr += HOP_BY_HOP_IDENTIFIER_SIZE;
00494
00495
00496 msg->endtoendId = ntohl(*((unsigned int*)ptr));
00497 ptr += END_TO_END_IDENTIFIER_SIZE;
00498
00499
00500 while (ptr < source+msg_len) {
00501 if (ptr+AVP_HDR_SIZE(0x80)>source+msg_len){
00502 LOG(L_ERR,"ERROR:AAATranslateMessage: source buffer to short!! "
00503 "Cannot read the whole AVP header!\n");
00504 goto error;
00505 }
00506
00507 avp_code = get_4bytes( ptr );
00508 ptr += AVP_CODE_SIZE;
00509
00510 avp_flags = (unsigned char)*ptr;
00511 ptr += AVP_FLAGS_SIZE;
00512
00513 avp_len = get_3bytes( ptr );
00514 ptr += AVP_LENGTH_SIZE;
00515 if (avp_len<1) {
00516 LOG(L_ERR,"ERROR:AAATranslateMessage: invalid AVP len [%d]\n",
00517 avp_len);
00518 goto error;
00519 }
00520
00521 avp_vendorID = 0;
00522 if (avp_flags&AAA_AVP_FLAG_VENDOR_SPECIFIC) {
00523 avp_vendorID = get_4bytes( ptr );
00524 ptr += AVP_VENDOR_ID_SIZE;
00525 }
00526
00527 avp_data_len = avp_len-AVP_HDR_SIZE(avp_flags);
00528
00529 if ( source+msg_len<ptr+avp_data_len) {
00530 LOG(L_ERR,"ERROR:AAATranslateMessage: source buffer to short!! "
00531 "Cannot read a whole data for AVP!\n");
00532 goto error;
00533 }
00534
00535
00536 avp = AAACreateAVP( avp_code, avp_flags, avp_vendorID, (char*) ptr,
00537 avp_data_len, AVP_DONT_FREE_DATA);
00538 if (!avp)
00539 goto error;
00540
00541
00542 AAAAddAVPToMessage( msg, avp, msg->avpList.tail);
00543
00544 ptr += to_32x_len( avp_data_len );
00545 }
00546
00547
00548 if (attach_buf) {
00549 msg->buf.s = (char*) source;
00550 msg->buf.len = msg_len;
00551 }
00552
00553
00554 return msg;
00555 error:
00556 LOG(L_ERR,"ERROR:AAATranslateMessage: message conversion droped!!\n");
00557 AAAFreeMessage(&msg);
00558 return 0;
00559 }
00560
00561
00562
00568 void AAAPrintMessage( AAAMessage *msg)
00569 {
00570 char buf[1024];
00571 AAA_AVP *avp;
00572
00573
00574 DBG("DEBUG: AAA_MESSAGE - %p\n",msg);
00575 DBG("\tCode = %u\n",msg->commandCode);
00576 DBG("\tFlags = %x\n",msg->flags);
00577
00578
00579 avp = msg->avpList.head;
00580 while (avp) {
00581 AAAConvertAVPToString(avp,buf,1024);
00582 DBG("\n%s\n",buf);
00583 avp=avp->next;
00584 }
00585 }
00586
00587
00588