message.c
Go to the documentation of this file.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 #include <stdlib.h>
00027 #include <string.h>
00028 #include <sys/types.h>
00029 #include <netinet/in.h>
00030
00031
00032 #include "../../mem/shm_mem.h"
00033 #include "../../dprint.h"
00034 #include "diameter_msg.h"
00035
00036 #define get_3bytes(_b) \
00037 ((((unsigned int)(_b)[0])<<16)|(((unsigned int)(_b)[1])<<8)|\
00038 (((unsigned int)(_b)[2])))
00039
00040 #define get_4bytes(_b) \
00041 ((((unsigned int)(_b)[0])<<24)|(((unsigned int)(_b)[1])<<16)|\
00042 (((unsigned int)(_b)[2])<<8)|(((unsigned int)(_b)[3])))
00043
00044 #define set_3bytes(_b,_v) \
00045 {(_b)[0]=((_v)&0x00ff0000)>>16;(_b)[1]=((_v)&0x0000ff00)>>8;\
00046 (_b)[2]=((_v)&0x000000ff);}
00047
00048 #define set_4bytes(_b,_v) \
00049 {(_b)[0]=((_v)&0xff000000)>>24;(_b)[1]=((_v)&0x00ff0000)>>16;\
00050 (_b)[2]=((_v)&0x0000ff00)>>8;(_b)[3]=((_v)&0x000000ff);}
00051
00052 #define to_32x_len( _len_ ) \
00053 ( (_len_)+(((_len_)&3)?4-((_len_)&3):0) )
00054
00055
00056
00057
00058 AAAReturnCode AAABuildMsgBuffer( AAAMessage *msg )
00059 {
00060 unsigned char *p;
00061 AAA_AVP *avp;
00062
00063
00064 msg->buf.len = AAA_MSG_HDR_SIZE;
00065
00066 for(avp=msg->avpList.head;avp;avp=avp->next) {
00067 msg->buf.len += AVP_HDR_SIZE(avp->flags)+ to_32x_len( avp->data.len );
00068 }
00069
00070
00071
00072 msg->buf.s = (char*)ad_malloc( msg->buf.len );
00073 if (!msg->buf.s) {
00074 LM_ERR(" no more pkg memory!\n");
00075 goto error;
00076 }
00077 memset(msg->buf.s, 0, msg->buf.len);
00078
00079
00080 p = (unsigned char*)msg->buf.s;
00081
00082
00083 ((unsigned int*)p)[0] =htonl(msg->buf.len);
00084
00085 *p = 1;
00086 p += VER_SIZE + MESSAGE_LENGTH_SIZE;
00087
00088 ((unsigned int*)p)[0] = htonl(msg->commandCode);
00089
00090 *p = (unsigned char)msg->flags;
00091 p += FLAGS_SIZE + COMMAND_CODE_SIZE;
00092
00093 ((unsigned int*)p)[0] = htonl(msg->applicationId);
00094 p += APPLICATION_ID_SIZE;
00095
00096 ((unsigned int*)p)[0] = msg->hopbyhopId;
00097 p += HOP_BY_HOP_IDENTIFIER_SIZE;
00098
00099 ((unsigned int*)p)[0] = msg->endtoendId;
00100 p += END_TO_END_IDENTIFIER_SIZE;
00101
00102
00103 for(avp=msg->avpList.head;avp;avp=avp->next) {
00104
00105
00106 set_4bytes(p,avp->code);
00107 p +=4;
00108
00109 (*p++) = (unsigned char)avp->flags;
00110
00111 set_3bytes(p, (AVP_HDR_SIZE(avp->flags)+avp->data.len) );
00112 p += 3;
00113
00114 if ((avp->flags&0x80)!=0) {
00115 set_4bytes(p,avp->vendorId);
00116 p +=4;
00117 }
00118
00119 memcpy( p, avp->data.s, avp->data.len);
00120 p += to_32x_len( avp->data.len );
00121 }
00122
00123 if ((char*)p-msg->buf.s!=msg->buf.len) {
00124 LM_ERR("mismatch between len and buf!\n");
00125 ad_free( msg->buf.s );
00126 msg->buf.s = 0;
00127 msg->buf.len = 0;
00128 goto error;
00129 }
00130
00131 return AAA_ERR_SUCCESS;
00132 error:
00133 return -1;
00134 }
00135
00136
00137
00138
00139
00140 AAAReturnCode AAAFreeMessage(AAAMessage **msg)
00141 {
00142 AAA_AVP *avp_t;
00143 AAA_AVP *avp;
00144
00145
00146 if (!msg || !(*msg))
00147 goto done;
00148
00149
00150 avp = (*msg)->avpList.head;
00151 while (avp) {
00152 avp_t = avp;
00153 avp = avp->next;
00154
00155 AAAFreeAVP(&avp_t);
00156 }
00157
00158
00159 if ( (*msg)->buf.s )
00160 ad_free( (*msg)->buf.s );
00161
00162
00163 ad_free(*msg);
00164 msg = 0;
00165
00166 done:
00167 return AAA_ERR_SUCCESS;
00168 }
00169
00170
00171
00172
00173
00174 AAAReturnCode AAASetMessageResultCode(
00175 AAAMessage *message,
00176 AAAResultCode resultCode)
00177 {
00178 if ( !is_req(message) && message->res_code) {
00179 *((unsigned int*)(message->res_code->data.s)) = htonl(resultCode);
00180 return AAA_ERR_SUCCESS;
00181 }
00182 return AAA_ERR_FAILURE;
00183 }
00184
00185
00186
00187
00188 AAAMessage* AAATranslateMessage( unsigned char* source, unsigned int sourceLen,
00189 int attach_buf)
00190 {
00191 unsigned char *ptr;
00192 AAAMessage *msg;
00193 unsigned char version;
00194 unsigned int msg_len;
00195 AAA_AVP *avp;
00196 unsigned int avp_code;
00197 unsigned char avp_flags;
00198 unsigned int avp_len;
00199 unsigned int avp_vendorID;
00200 unsigned int avp_data_len;
00201
00202
00203 if( !source || !sourceLen || sourceLen<AAA_MSG_HDR_SIZE) {
00204 LM_ERR(" invalid buffered received!\n");
00205 goto error;
00206 }
00207
00208
00209 msg = 0;
00210 avp = 0;
00211 ptr = source;
00212
00213
00214 msg = (AAAMessage*)ad_malloc(sizeof(AAAMessage));
00215 if (!msg) {
00216 LM_ERR(" no more free memory!!\n");
00217 goto error;
00218 }
00219 memset(msg,0,sizeof(AAAMessage));
00220
00221
00222 version = (unsigned char)*ptr;
00223 ptr += VER_SIZE;
00224 if (version!=1) {
00225 LM_ERR(" invalid version [%d]in AAA msg\n",version);
00226 goto error;
00227 }
00228
00229
00230 msg_len = get_3bytes( ptr );
00231 ptr += MESSAGE_LENGTH_SIZE;
00232 if (msg_len>sourceLen) {
00233 LM_ERR(" AAA message len [%d] bigger then"
00234 " buffer len [%d]\n",msg_len,sourceLen);
00235 goto error;
00236 }
00237
00238
00239 msg->flags = *ptr;
00240 ptr += FLAGS_SIZE;
00241
00242
00243 msg->commandCode = get_3bytes( ptr );
00244 ptr += COMMAND_CODE_SIZE;
00245
00246
00247 msg->applicationId = get_4bytes( ptr );
00248 ptr += APPLICATION_ID_SIZE;
00249
00250
00251 msg->hopbyhopId = *((unsigned int*)ptr);
00252 ptr += HOP_BY_HOP_IDENTIFIER_SIZE;
00253
00254
00255 msg->endtoendId = *((unsigned int*)ptr);
00256 ptr += END_TO_END_IDENTIFIER_SIZE;
00257
00258
00259 while (ptr < source+msg_len) {
00260 if (ptr+AVP_HDR_SIZE(0x80)>source+msg_len){
00261 LM_ERR(" source buffer to short!! "
00262 "Cannot read the whole AVP header!\n");
00263 goto error;
00264 }
00265
00266 avp_code = get_4bytes( ptr );
00267 ptr += AVP_CODE_SIZE;
00268
00269 avp_flags = (unsigned char)*ptr;
00270 ptr += AVP_FLAGS_SIZE;
00271
00272 avp_len = get_3bytes( ptr );
00273 ptr += AVP_LENGTH_SIZE;
00274 if (avp_len<1) {
00275 LM_ERR(" invalid AVP len [%d]\n", avp_len);
00276 goto error;
00277 }
00278
00279 avp_vendorID = 0;
00280 if (avp_flags&AAA_AVP_FLAG_VENDOR_SPECIFIC) {
00281 avp_vendorID = get_4bytes( ptr );
00282 ptr += AVP_VENDOR_ID_SIZE;
00283 }
00284
00285 avp_data_len = avp_len-AVP_HDR_SIZE(avp_flags);
00286
00287 if ( source+msg_len<ptr+avp_data_len) {
00288 LM_ERR(" source buffer to short!! "
00289 "Cannot read a whole data for AVP!\n");
00290 goto error;
00291 }
00292
00293
00294 avp = AAACreateAVP( avp_code, avp_flags, avp_vendorID, (char*)ptr,
00295 avp_data_len, AVP_DONT_FREE_DATA);
00296 if (!avp)
00297 goto error;
00298
00299
00300 AAAAddAVPToMessage( msg, avp, msg->avpList.tail);
00301
00302 ptr += to_32x_len( avp_data_len );
00303 }
00304
00305
00306 if (attach_buf) {
00307 msg->buf.s = (char*)source;
00308 msg->buf.len = msg_len;
00309 }
00310
00311
00312 return msg;
00313 error:
00314 LM_ERR(" message conversion droped!!\n");
00315 AAAFreeMessage(&msg);
00316 return 0;
00317 }
00318
00319
00320 AAAMessage* AAAInMessage(AAACommandCode commandCode, AAAApplicationId appId)
00321 {
00322 AAAMessage *msg;
00323
00324
00325 msg = (AAAMessage*)ad_malloc(sizeof(AAAMessage));
00326 if (!msg)
00327 {
00328 LM_ERR("no more pkg memory!\n");
00329 return NULL;
00330 }
00331 memset(msg, 0, sizeof(AAAMessage));
00332
00333
00334 msg->commandCode = commandCode;
00335
00336
00337 msg->applicationId = appId;
00338
00339
00340 msg->flags = 0x80;
00341
00342 return msg;
00343 }
00344
00345
00346
00347
00348 void AAAPrintMessage( AAAMessage *msg)
00349 {
00350 char buf[1024];
00351 AAA_AVP *avp;
00352
00353
00354 LM_DBG("AAA_MESSAGE - %p\n",msg);
00355 LM_DBG("\tCode = %u\n",msg->commandCode);
00356 LM_DBG("\tFlags = %x\n",msg->flags);
00357
00358
00359 avp = msg->avpList.head;
00360 while (avp) {
00361 AAAConvertAVPToString(avp,buf,1024);
00362 LM_DBG("\n%s\n",buf);
00363 avp=avp->next;
00364 }
00365 }