/** * Decode a ipsec from a binary data structure * @param x - binary data to decode from * @param ipsec - ** to write into * @returns 1 on success or 0 on failure */ int bin_decode_ipsec(bin_data *x,r_ipsec **ipsec) { int len; str s; char c; if (!bin_decode_char(x, &c)) goto error; if (c==0) { *ipsec = 0; return 1; } len = sizeof(r_ipsec); *ipsec = (r_ipsec*) shm_malloc(len); if (!*ipsec) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_ipsec: Error allocating %d bytes.\n",len); goto error; } memset(*ipsec,0,len); if (!bin_decode_uint(x, &(*ipsec)->spi_uc)) goto error; if (!bin_decode_uint(x, &(*ipsec)->spi_us)) goto error; if (!bin_decode_uint(x, &(*ipsec)->spi_pc)) goto error; if (!bin_decode_uint(x, &(*ipsec)->spi_ps)) goto error; if (!bin_decode_ushort(x, &(*ipsec)->port_uc)) goto error; if (!bin_decode_ushort(x, &(*ipsec)->port_us)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->ealg),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->r_ealg),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->ck),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->alg),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->r_alg),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->ik),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->prot),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&((*ipsec)->mod),&s)) goto error; return 1; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_ipsec: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (*ipsec) { if ((*ipsec)->ealg.s) shm_free((*ipsec)->ealg.s); if ((*ipsec)->r_ealg.s) shm_free((*ipsec)->r_ealg.s); if ((*ipsec)->ck.s) shm_free((*ipsec)->ck.s); if ((*ipsec)->alg.s) shm_free((*ipsec)->alg.s); if ((*ipsec)->r_alg.s) shm_free((*ipsec)->r_alg.s); if ((*ipsec)->ik.s) shm_free((*ipsec)->ik.s); shm_free(*ipsec); *ipsec = 0; } return 0; }
/** * Decode a tls from a binary data structure * @param x - binary data to decode from * @param tls - ** to write into * @returns 1 on success or 0 on failure */ int bin_decode_tls(bin_data *x,r_tls **tls) { int len; char c; if (!bin_decode_char(x, &c)) goto error; if (c==0) { *tls = 0; return 1; } len = sizeof(r_tls); *tls = (r_tls*) shm_malloc(len); if (!*tls) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_tls: Error allocating %d bytes.\n",len); goto error; } memset(*tls,0,len); if (!bin_decode_ushort(x, &(*tls)->port_tls)) goto error; return 1; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_tls: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (*tls) { shm_free(*tls); *tls = 0; } return 0; }
/** * Decode an authentication userdata from a binary data structure * @param x - binary data to decode from * @returns the auth_userdata* where the data has been decoded */ auth_userdata* bin_decode_auth_userdata(bin_data *x) { auth_userdata *u=0; auth_vector *v=0,*vn=0; int i,len; unsigned short k; str s; len = sizeof(auth_userdata); u = (auth_userdata*) shm_malloc(len); if (!u) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_auth_userdata: Error allocating %d bytes.\n",len); goto error; } memset(u,0,len); if (!bin_decode_str(x,&s)||!str_shm_dup(&(u->private_identity),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(u->public_identity),&s)) goto error; u->hash = get_hash_auth(u->private_identity,u->public_identity); if (!bin_decode_time_t(x, &(u->expires))) goto error; if (!bin_decode_ushort(x, &k)) goto error; for(i=0;i<k;i++){ v = bin_decode_auth_vector(x); if (!v) goto error; v->prev = u->tail; v->next = 0; if (!u->head) u->head = v; if (u->tail) u->tail->next = v; u->tail = v; } return u; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_auth_userdata: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (u) { if (u->private_identity.s) shm_free(u->private_identity.s); if (u->public_identity.s) shm_free(u->public_identity.s); while(u->head){ v = u->head; vn = v->next; 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); u->head = v; } shm_free(u); } return 0; }
/** * Decode a contact from a binary data structure * @param x - binary data to decode from * @returns the r_contact* where the data has been decoded */ r_contact* bin_decode_r_contact(bin_data *x) { r_contact *c=0; unsigned short cpn=0; r_contact_param *cp; int len; str s,name,value; len = sizeof(r_contact); c = (r_contact*) shm_malloc(len); if (!c) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error allocating %d bytes.\n",len); goto error; } memset(c,0,len); if (!bin_decode_str(x,&s)||!str_shm_dup(&(c->uri),&s)) goto error; if (!bin_decode_time_t(x,&c->expires)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(c->ua),&s)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(c->path),&s)) goto error; if (!bin_decode_ushort(x,&(cpn))) goto error; while(cpn){ if (!bin_decode_str(x,&name)) goto error; if (!bin_decode_str(x,&value)) goto error; if (!add_r_contact_param(c,name,value)) goto error; cpn--; } return c; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (c) { if (c->uri.s) shm_free(c->uri.s); if (c->ua.s) shm_free(c->ua.s); if (c->path.s) shm_free(c->path.s); while(c->parameters){ cp = c->parameters->next; free_r_contact_param(cp); c->parameters = cp; } shm_free(c); } return 0; }
/** * Decode a binary string from a binary data structure * @param x - binary data to decode from * @returns the ims_subscription* where the data has been decoded */ ims_subscription *bin_decode_ims_subscription(bin_data *x) { ims_subscription *imss=0; int i,len; str s; imss = (ims_subscription*) shm_malloc(sizeof(ims_subscription)); if (!imss) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_ims_subscription: Error allocating %d bytes.\n",sizeof(ims_subscription)); goto error; } memset(imss,0,sizeof(ims_subscription)); if (!bin_decode_str(x,&s)||!str_shm_dup(&(imss->private_identity),&s)) goto error; if (!bin_decode_ushort(x, &(imss->service_profiles_cnt))) goto error; len = sizeof(ims_service_profile)*imss->service_profiles_cnt; imss->service_profiles = (ims_service_profile*)shm_malloc(len); if (!imss->service_profiles) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_ims_subscription: Error allocating %d bytes.\n",len); goto error; } memset(imss->service_profiles,0,len); for(i=0;i<imss->service_profiles_cnt;i++) if (!bin_decode_service_profile(x,imss->service_profiles+i)) goto error; imss->lock = lock_alloc(); imss->lock = lock_init(imss->lock); imss->ref_count = 1; return imss; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_ims_subscription: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (imss) { if (imss->private_identity.s) shm_free(imss->private_identity.s); if (imss->service_profiles) shm_free(imss->service_profiles); shm_free(imss); } return 0; }
/** * Decode a pinhole from a binary data structure * @param x - binary data to decode from * @param pinhole - ** to write into * @returns 1 on success or 0 on failure */ int bin_decode_pinhole(bin_data *x,r_nat_dest **pinhole) { int len; char c; if (!bin_decode_char(x, &c)) goto error; if (c==0) { *pinhole = 0; return 1; } len = sizeof(r_nat_dest); *pinhole = (r_nat_dest*) shm_malloc(len); if (!*pinhole) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_pinhole: Error allocating %d bytes.\n",len); goto error; } memset(*pinhole,0,len); if (!bin_decode_uint(x, &(*pinhole)->nat_addr.af)) goto error; if (!bin_decode_uint(x, &(*pinhole)->nat_addr.len)) goto error; if (!bin_decode_uint(x, &(*pinhole)->nat_addr.u.addr32[0])) goto error; if (!bin_decode_uint(x, &(*pinhole)->nat_addr.u.addr32[1])) goto error; if (!bin_decode_uint(x, &(*pinhole)->nat_addr.u.addr32[2])) goto error; if (!bin_decode_uint(x, &(*pinhole)->nat_addr.u.addr32[3])) goto error; if (!bin_decode_ushort(x, &(*pinhole)->nat_port)) goto error; return 1; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_pinhole: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (*pinhole) { shm_free(*pinhole); *pinhole = 0; } return 0; }
/** * Decode a r_public from a binary data structure * @param x - binary data to decode from * @returns the r_public* where the data has been decoded */ r_public* bin_decode_r_public(bin_data *x) { r_public *p=0; r_contact *c=0,*cn=0; r_subscriber *s,*sn=0; int len,i; unsigned short k; char ch; str st; len = sizeof(r_public); p = (r_public*) shm_malloc(len); if (!p) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_public: Error allocating %d bytes.\n",len); goto error; } memset(p,0,len); if (!bin_decode_str(x,&st)||!str_shm_dup(&(p->aor),&st)) goto error; if (!bin_decode_str(x,&st)||!str_shm_dup(&(p->early_ims_ip),&st)) goto error; p->hash = get_aor_hash(p->aor,r_hash_size); if (!bin_decode_char(x,&ch)) goto error; p->reg_state = ch; p->s = bin_decode_ims_subscription(x); if (!p->s) goto error; if (!bin_decode_ushort(x,&k)) goto error; for(i=0;i<k;i++){ c = bin_decode_r_contact(x); if (!c) goto error; c->prev = p->tail; c->next = 0; if (!p->head) p->head = c; if (p->tail) p->tail->next = c; p->tail = c; } if (!bin_decode_ushort(x,&k)) goto error; for(i=0;i<k;i++){ s = bin_decode_r_subscriber(x); if (!s) goto error; s->prev = p->stail; s->next = 0; if (!p->shead) p->shead = s; if (p->stail) p->stail->next = s; p->stail = s; } return p; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_public: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (p) { if (p->aor.s) shm_free(p->aor.s); while(p->head){ c = p->head; cn = c->next; free_r_contact(c); p->head = cn; } while(p->shead){ s = p->shead; sn = s->next; free_r_subscriber(s); p->shead = sn; } shm_free(p); } 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 r_contact from a binary data structure * @param x - binary data to decode from * @returns the r_contact* where the data has been decoded */ r_contact* bin_decode_r_contact(bin_data *x) { r_contact *c=0; r_public *p=0,*pn=0; int len,i; char k; unsigned short us; str st; len = sizeof(r_contact); c = (r_contact*) shm_malloc(len); if (!c) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error allocating %d bytes.\n",len); goto error; } memset(c,0,len); if (!bin_decode_str(x,&st)||!str_shm_dup(&(c->host),&st)) goto error; if (!bin_decode_ushort(x,&c->port)) goto error; if (!bin_decode_char(x,&c->transport)) goto error; c->hash = get_contact_hash(c->host,c->port,c->transport,r_hash_size); if (!bin_decode_r_security(x,&(c->security_temp))) goto error; if (!bin_decode_r_security(x,&(c->security))) goto error; if (!bin_decode_str(x,&st)||!str_shm_dup(&(c->uri),&st)) goto error; if (!bin_decode_char(x,&k)) goto error; c->reg_state = k; if (!bin_decode_time_t(x,&c->expires)) goto error; if (!bin_decode_ushort(x, &c->service_route_cnt)) goto error; len = sizeof(str)*c->service_route_cnt; c->service_route = (str*) shm_malloc(len); if (!c->service_route) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error allocating %d bytes.\n",len); goto error; } memset(c->service_route,0,len); for(i=0;i<c->service_route_cnt;i++) if (!bin_decode_str(x,&st)||!str_shm_dup(c->service_route+i,&st)) goto error; if (!bin_decode_pinhole(x,&(c->pinhole ))) goto error; if (!bin_decode_char(x,&k)) goto error; c->sos_flag = k; if (!bin_decode_str(x,&st)||!str_shm_dup(&(c->pcc_session_id),&st)) goto error; if (!bin_decode_ushort(x,&us)) goto error; for(i=0;i<us;i++){ p = bin_decode_r_public(x); if (!p) goto error; p->prev = c->tail; p->next = 0; if (c->tail) c->tail->next = p; c->tail = p; if (!c->head) c->head = p; } return c; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (c) { if (c->host.s) shm_free(c->host.s); if (c->security_temp) free_r_security(c->security_temp); if (c->security) free_r_security(c->security); if (c->uri.s) shm_free(c->uri.s); if (c->pinhole) shm_free(c->pinhole); while(c->head){ p = c->head; pn = p->next; free_r_public(p); c->head = pn; } shm_free(c); } 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; }