/** * Decode a security from a binary data structure * @param x - binary data to decode from * @param sec - ** to write into * @returns 1 on success or 0 on failure */ int bin_decode_r_security(bin_data *x,r_security **sec) { int len; str s; char c; int y; if (!bin_decode_char(x, &c)) goto error; if (c==0) { *sec = 0; return 1; } len = sizeof(r_security); *sec = (r_security*) shm_malloc(len); if (!*sec) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_security: Error allocating %d bytes.\n",len); goto error; } memset(*sec,0,len); if (!bin_decode_str(x,&s)||!str_shm_dup(&((*sec)->sec_header),&s)) goto error; if (!bin_decode_int(x,&y)) goto error; (*sec)->type = y; switch ((*sec)->type){ case SEC_NONE: break; case SEC_TLS: if (!bin_decode_tls(x,&((*sec)->data.tls))) goto error; break; case SEC_IPSEC: if (!bin_decode_ipsec(x,&((*sec)->data.ipsec))) goto error; break; } if (!bin_decode_int(x, &y)) goto error; (*sec)->q = ((float)y)/1000.0; return 1; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_security: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (*sec) { if ((*sec)->sec_header.s) shm_free((*sec)->sec_header.s); switch ((*sec)->type){ case SEC_NONE: break; case SEC_TLS: if ((*sec)->data.tls) free_r_tls((*sec)->data.tls); break; case SEC_IPSEC: if ((*sec)->data.ipsec) free_r_ipsec((*sec)->data.ipsec); break; } shm_free(*sec); *sec = 0; } return 0; }
/** * Decode a dialog userdata from a binary data structure * @param x - binary data to decode from * @returns the s_dialog* where the data has been decoded */ s_dialog* bin_decode_s_dialog(bin_data *x) { s_dialog *d=0; int len; str s; char ch; len = sizeof(s_dialog); d = (s_dialog*) shm_malloc(len); if (!d) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_s_dialog: Error allocating %d bytes.\n",len); goto error; } memset(d,0,len); if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->call_id),&s)) goto error; if (!bin_decode_char(x, &ch)) goto error; d->direction = ch; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->aor),&s)) goto error; if (!bin_decode_char(x, &ch)) goto error; d->method = ch; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->method_str),&s)) goto error; if (!bin_decode_int(x, &d->first_cseq)) goto error; if (!bin_decode_int(x, &d->last_cseq)) goto error; if (!bin_decode_char(x, &ch)) goto error; d->state = ch; if (!bin_decode_time_t(x, &d->expires)) goto error; if (!bin_decode_time_t(x, &d->lr_session_expires)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->refresher),&s)) goto error; if (!bin_decode_uchar(x,&d->uac_supp_timer)) goto error; if (!bin_decode_uchar(x, &d->is_releasing)) goto error; if (!bin_decode_dlg_t(x,&(d->dialog_c))) goto error; if (!bin_decode_dlg_t(x,&(d->dialog_s))) goto error; d->hash = get_s_dialog_hash(d->call_id); return d; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_s_dialog: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (d) { if (d->call_id.s) shm_free(d->call_id.s); if (d->aor.s) shm_free(d->aor.s); if (d->method_str.s) shm_free(d->method_str.s); if (d->refresher.s) shm_free(d->refresher.s); shm_free(d); } return 0; }
/** * Decode a subscriber from a binary data structure * @param x - binary data to decode from * @returns the r_subscriber* where the data has been decoded */ r_subscriber* bin_decode_r_subscriber(bin_data *x) { r_subscriber *s=0; int len; str st; len = sizeof(r_subscriber); s = (r_subscriber*) shm_malloc(len); if (!s) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error allocating %d bytes.\n",len); goto error; } memset(s,0,len); if (!bin_decode_str(x,&st)||!str_shm_dup(&(s->subscriber),&st)) goto error; if (!bin_decode_char(x,&(s->event))) goto error; if (!bin_decode_time_t(x,&(s->expires))) goto error; if (!bin_decode_dlg_t(x,&(s->dialog))) goto error; if (!bin_decode_int(x,&(s->version))) goto error; return s; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (s) { if (s->subscriber.s) shm_free(s->subscriber.s); if (s->dialog) tmb.free_dlg(s->dialog); shm_free(s); } return 0; }
/** * Decode a r_subscription from a binary data structure * @param x - binary data to decode from * @returns the r_subscription* where the data has been decoded */ r_subscription* bin_decode_r_subscription(bin_data *x) { r_subscription *s=0; int len; str st; char c; len = sizeof(r_subscription); s = (r_subscription*) shm_malloc(len); if (!s) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_subscription: Error allocating %d bytes.\n",len); goto error; } memset(s,0,len); if (!bin_decode_str(x,&st)||!str_shm_dup(&(s->req_uri),&st)) goto error; if (!bin_decode_int(x,&s->duration)) goto error; if (!bin_decode_time_t(x,&s->expires)) goto error; if (!bin_decode_char(x,&c)) goto error; s->attempts_left = c; if (!bin_decode_dlg_t(x,&(s->dialog))) goto error; s->hash = get_subscription_hash(s->req_uri); return s; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_subscription: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (s) { if (s->req_uri.s) shm_free(s->req_uri.s); if (s->dialog) tmb.free_dlg(s->dialog); shm_free(s); } return 0; }
/** * Decode an SPT * @param x - binary data to decode from * @param spt - the service point trigger to decode into * @returns 1 on succcess or 0 on error */ static int bin_decode_spt(bin_data *x, ims_spt *spt) { unsigned char k; str s; if (!bin_decode_uchar(x,&k)) goto error; spt->type = k & 0x0F; spt->condition_negated = ((k & 0x80)!=0); spt->registration_type = ((k & 0x70)>>4); if (!bin_decode_int(x,&(spt->group))) goto error; switch (spt->type){ case 1: if (!bin_decode_str(x,&s)||!str_shm_dup(&(spt->request_uri),&s)) goto error; break; case 2: if (!bin_decode_str(x,&s)||!str_shm_dup(&(spt->method),&s)) goto error; break; case 3: if (!bin_decode_short(x,&(spt->sip_header.type))) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(spt->sip_header.header),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(spt->sip_header.content),&s)) goto error; break; case 4: if (!bin_decode_char(x,&(spt->session_case))) goto error; break; case 5: if (!bin_decode_str(x,&s)||!str_shm_dup(&(spt->session_desc.line),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(spt->session_desc.content),&s)) goto error; break; } return 1; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_spt: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (spt){ switch (spt->type){ case 1: if (spt->request_uri.s) shm_free(spt->request_uri.s); break; case 2: if (spt->method.s) shm_free(spt->method.s); break; case 3: if (spt->sip_header.header.s) shm_free(spt->sip_header.header.s); if (spt->sip_header.header.s) shm_free(spt->sip_header.content.s); break; case 4: break; case 5: if (spt->sip_header.header.s) shm_free(spt->session_desc.line.s); if (spt->sip_header.header.s) shm_free(spt->session_desc.content.s); break; } } return 0; }
/** * Decode an authentication vector from a binary data structure * @param x - binary data to decode from * @returns the auth_vector* where the data has been decoded */ auth_vector* bin_decode_auth_vector(bin_data *x) { auth_vector *v=0; int len; char ch; str s; len = sizeof(auth_vector); v = (auth_vector*) shm_malloc(len); if (!v) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_auth_vector: Error allocating %d bytes.\n",len); goto error; } memset(v,0,len); if (!bin_decode_int(x,&(v->item_number))) goto error; if (!bin_decode_uchar(x,&(v->type))) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(v->authenticate),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(v->authorization),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(v->ck),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(v->ik),&s)) goto error; if (!bin_decode_time_t(x, &(v->expires))) goto error; if (!bin_decode_char(x, &ch)) goto error; v->status=ch; return v; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_auth_vector: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (v) { if (v->authenticate.s) shm_free(v->authenticate.s); if (v->authorization.s) shm_free(v->authorization.s); if (v->ck.s) shm_free(v->ck.s); if (v->ik.s) shm_free(v->ik.s); shm_free(v); } return 0; }
/** * Decode a service profile * @param x - binary data to decode from * @param sp - service profile to decode into * @returns 1 on succcess or 0 on error */ static int bin_decode_service_profile(bin_data *x, ims_service_profile *sp) { int i,len; //public identities if (!bin_decode_ushort(x,&(sp->public_identities_cnt))) goto error; len = sizeof(ims_public_identity)*sp->public_identities_cnt; sp->public_identities = (ims_public_identity*)shm_malloc(len); if (!sp->public_identities) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_service_profile: Error allocating %d bytes.\n",len); goto error; } memset(sp->public_identities,0,len); for(i=0;i<sp->public_identities_cnt;i++) if (!bin_decode_public_identity(x,sp->public_identities+i)) goto error; // filter criteria if (!bin_decode_ushort(x,&(sp->filter_criteria_cnt))) goto error; len = sizeof(ims_filter_criteria)*sp->filter_criteria_cnt; sp->filter_criteria = (ims_filter_criteria*)shm_malloc(len); if (!sp->filter_criteria) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_service_profile: Error allocating %d bytes.\n",len); goto error; } memset(sp->filter_criteria,0,len); for(i=0;i<sp->filter_criteria_cnt;i++) if (!bin_decode_filter_criteria(x,sp->filter_criteria+i)) goto error; // cn service auth if (!bin_decode_int(x,&i)) goto error; if (i==0xFFFFFFFF) sp->cn_service_auth = 0; else { len = sizeof(ims_cn_service_auth); sp->cn_service_auth = (ims_cn_service_auth*)shm_malloc(len); if (!sp->cn_service_auth) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_service_profile: Error allocating %d bytes.\n",len); goto error; } sp->cn_service_auth->subscribed_media_profile_id=i; } //shared ifc if (!bin_decode_ushort(x,&(sp->shared_ifc_set_cnt))) goto error; len = sizeof(int)*sp->shared_ifc_set_cnt; sp->shared_ifc_set = (int*)shm_malloc(len); if (!sp->shared_ifc_set) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_service_profile: Error allocating %d bytes.\n",len); goto error; } memset(sp->shared_ifc_set,0,len); for(i=0;i<sp->shared_ifc_set_cnt;i++) if (!bin_decode_int(x,sp->shared_ifc_set+i)) goto error; return 1; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_service_profile: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (sp) { if (sp->public_identities) shm_free(sp->public_identities); if (sp->filter_criteria) shm_free(sp->filter_criteria); if (sp->cn_service_auth) shm_free(sp->cn_service_auth); if (sp->shared_ifc_set) shm_free(sp->shared_ifc_set); } return 0; }
/** * Decode a Filter Criteria * @param x - binary data to decode from * @param fc - filter criteria to decode into * @returns 1 on succcess or 0 on error */ static int bin_decode_filter_criteria(bin_data *x, ims_filter_criteria *fc) { int i,len; str s; char ppindicator,cnf; //priority if (!bin_decode_int(x,&(fc->priority))) goto error; // profile part indicator if (!bin_decode_char(x,&ppindicator)) goto error; if (!ppindicator){ fc->profile_part_indicator = 0; } else { fc->profile_part_indicator = (char*)shm_malloc(sizeof(char)); if (!fc->profile_part_indicator) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_filter_criteria: Error allocating %d bytes.\n",sizeof(int)); goto error; } *(fc->profile_part_indicator) = ppindicator-1; } //cnf if (!bin_decode_char(x,&cnf)) goto error; if (cnf==100) fc->trigger_point=NULL; else { ims_trigger_point *tp=0; //trigger point len = sizeof(ims_trigger_point); tp = (ims_trigger_point*)shm_malloc(len); fc->trigger_point = tp; if (!tp) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_filter_criteria: Error allocating %d bytes.\n",len); goto error; } memset(tp,0,len); tp->condition_type_cnf=cnf; if (!bin_decode_ushort(x,&tp->spt_cnt)) goto error; len = sizeof(ims_spt)*tp->spt_cnt; tp->spt = (ims_spt*)shm_malloc(len); if (!tp->spt) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_filter_criteria: Error allocating %d bytes.\n",len); goto error; } memset(tp->spt,0,len); for(i=0;i<tp->spt_cnt;i++) if (!bin_decode_spt(x,tp->spt+i)) goto error; } //app server uri if (!bin_decode_str(x,&s)||!str_shm_dup(&(fc->application_server.server_name),&s)) goto error; // app server default handling if (!bin_decode_char(x,&(fc->application_server.default_handling)))goto error; // app server service info if (!bin_decode_str(x,&s)||!str_shm_dup(&(fc->application_server.service_info),&s)) goto error; return 1; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_filter_criteria: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (fc){ if (fc->trigger_point){ if (fc->trigger_point){ if (fc->trigger_point->spt) shm_free(fc->trigger_point->spt); } shm_free(fc->trigger_point); } if (fc->application_server.server_name.s) shm_free(fc->application_server.server_name.s); if (fc->application_server.service_info.s) shm_free(fc->application_server.service_info.s); } return 0; }
/** * Decode a dialog from a binary data structure * @param x - binary data to decode from * @returns the p_dialog* where the data has been decoded */ p_dialog* bin_decode_p_dialog(bin_data *x) { p_dialog *d=0; int len,i; str s; char c; unsigned char uc; len = sizeof(p_dialog); d = (p_dialog*) shm_malloc(len); if (!d) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error allocating %d bytes.\n",len); goto error; } memset(d,0,len); if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->call_id),&s)) goto error; if (!bin_decode_uchar(x, &uc)) goto error; d->direction = uc; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->host),&s)) goto error; if (!bin_decode_ushort(x, &d->port)) goto error; if (!bin_decode_uchar(x, &uc)) goto error; d->transport = uc; if (!bin_decode_ushort(x, &d->routes_cnt)) goto error; len = sizeof(str)*d->routes_cnt; d->routes = (str*) shm_malloc(len); if (!d) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error allocating %d bytes.\n",len); goto error; } memset(d->routes,0,len); for(i=0;i<d->routes_cnt;i++) if (!bin_decode_str(x,&s)||!str_shm_dup(d->routes+i,&s)) goto error; if (!bin_decode_char(x, &c)) goto error; d->method = c; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->method_str),&s)) goto error; if (!bin_decode_int(x, &d->first_cseq)) goto error; if (!bin_decode_int(x, &d->last_cseq)) goto error; if (!bin_decode_char(x, &c)) goto error; d->state = c; if (!bin_decode_time_t(x, &d->expires)) goto error; if (!bin_decode_time_t(x, &d->lr_session_expires)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->refresher),&s)) goto error; if (!bin_decode_uchar(x,&d->uac_supp_timer)) goto error; if (!bin_decode_uchar(x, &d->is_releasing)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->pcc_session_id),&s)) goto error; if (!bin_decode_dlg_t(x,&(d->dialog_c))) goto error; if (!bin_decode_dlg_t(x,&(d->dialog_s))) goto error; d->hash = get_p_dialog_hash(d->call_id); return d; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (d) { if (d->call_id.s) shm_free(d->call_id.s); if (d->host.s) shm_free(d->host.s); if (d->routes_cnt){ for(i=0;i<d->routes_cnt;i++) if (d->routes[i].s) shm_free(d->routes[i].s); shm_free(d->routes); } if (d->method_str.s) shm_free(d->method_str.s); if (d->refresher.s) shm_free(d->refresher.s); shm_free(d); } return 0; }