static int w_crypto_aes_decrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb) { str ins; str keys; pv_spec_t *dst; pv_value_t val; EVP_CIPHER_CTX *de=NULL; str etext; if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) { LM_ERR("cannot get input value\n"); return -1; } if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) { LM_ERR("cannot get key value\n"); return -1; } de = EVP_CIPHER_CTX_new(); if(de==NULL) { LM_ERR("cannot get new cipher context\n"); return -1; } dst = (pv_spec_t*)outb; /* gen key and iv. init the cipher ctx object */ if (crypto_aes_init((unsigned char *)keys.s, keys.len, (unsigned char*)((_crypto_salt_param)?_crypto_salt:0), NULL, de)) { EVP_CIPHER_CTX_free(de); LM_ERR("couldn't initialize AES cipher\n"); return -1; } memset(&val, 0, sizeof(pv_value_t)); etext.s = pv_get_buffer(); etext.len = base64_dec((unsigned char *)ins.s, ins.len, (unsigned char *)etext.s, pv_get_buffer_size()-1); if (etext.len < 0) { EVP_CIPHER_CTX_free(de); LM_ERR("base64 inpuy with encrypted value is too large (need %d)\n", -etext.len); return -1; } val.rs.len = etext.len; val.rs.s = (char *)crypto_aes_decrypt(de, (unsigned char *)etext.s, &val.rs.len); if(val.rs.s==NULL) { EVP_CIPHER_CTX_free(de); LM_ERR("AES decryption failed\n"); return -1; } LM_DBG("plain result: [%.*s]\n", val.rs.len, val.rs.s); val.flags = PV_VAL_STR; dst->setf(msg, &dst->pvp, (int)EQ_T, &val); free(val.rs.s); EVP_CIPHER_CTX_cleanup(de); EVP_CIPHER_CTX_free(de); return 1; }
int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { dlg_cell_t *dlg; str * value; str spv; if (param==NULL || param->pvn.type!=PV_NAME_INTSTR || param->pvn.u.isname.type!=AVP_NAME_STR || param->pvn.u.isname.name.s.s==NULL) { LM_CRIT("BUG - bad parameters\n"); return -1; } /* Retrieve the dialog for current message */ dlg=dlg_get_msg_dialog( msg); if (dlg) { /* Lock the dialog */ dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); } else { /* Verify the local list */ get_local_varlist_pointer(msg, 0); } /* dcm: todo - the value should be cloned for safe usage */ value = get_dlg_variable_unsafe(dlg, ¶m->pvn.u.isname.name.s); spv.s = NULL; if(value) { spv.len = pv_get_buffer_size(); if(spv.len<value->len+1) { LM_ERR("pv buffer too small (%d) - needed %d\n", spv.len, value->len); } else { spv.s = pv_get_buffer(); strncpy(spv.s, value->s, value->len); spv.len = value->len; spv.s[spv.len] = '\0'; } } print_lists(dlg); /* unlock dialog */ if (dlg) { dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); dlg_release(dlg); } if (spv.s) return pv_get_strval(msg, param, res, &spv); return pv_get_null(msg, param, res); }
static int w_crypto_aes_encrypt(sip_msg_t* msg, char* inb, char* keyb, char* outb) { str ins; str keys; pv_spec_t *dst; pv_value_t val; EVP_CIPHER_CTX en; str etext; if (fixup_get_svalue(msg, (gparam_t*)inb, &ins) != 0) { LM_ERR("cannot get input value\n"); return -1; } if (fixup_get_svalue(msg, (gparam_t*)keyb, &keys) != 0) { LM_ERR("cannot get key value\n"); return -1; } dst = (pv_spec_t*)outb; /* gen key and iv. init the cipher ctx object */ if (crypto_aes_init((unsigned char *)keys.s, keys.len, (unsigned char*)((_crypto_salt_param)?_crypto_salt:0), &en, NULL)) { LM_ERR("couldn't initialize AES cipher\n"); return -1; } etext.len = ins.len; etext.s = (char *)crypto_aes_encrypt(&en, (unsigned char *)ins.s, &etext.len); if(etext.s==NULL) { LM_ERR("AES encryption failed\n"); return -1; } memset(&val, 0, sizeof(pv_value_t)); val.rs.s = pv_get_buffer(); val.rs.len = base64_enc((unsigned char *)etext.s, etext.len, (unsigned char *)val.rs.s, pv_get_buffer_size()-1); if (val.rs.len < 0) { LM_ERR("base64 output of encrypted value is too large (need %d)\n", -val.rs.len); goto error; } LM_DBG("base64 encrypted result: [%.*s]\n", val.rs.len, val.rs.s); val.flags = PV_VAL_STR; dst->setf(msg, &dst->pvp, (int)EQ_T, &val); free(etext.s); EVP_CIPHER_CTX_cleanup(&en); return 1; error: free(etext.s); EVP_CIPHER_CTX_cleanup(&en); return -1; }
static int ki_xavp_params_implode(sip_msg_t *msg, str *sxname, str *svname) { pv_spec_t *vspec=NULL; pv_value_t val; if(sxname==NULL || sxname->s==NULL || sxname->len<=0) { LM_ERR("invalid xavp name\n"); return -1; } if(svname==NULL || svname->s==NULL || svname->len<=0) { LM_ERR("invalid output var name\n"); return -1; } vspec = pv_cache_get(svname); if(vspec==NULL) { LM_ERR("cannot get pv spec for [%.*s]\n", svname->len, svname->s); return -1; } if(vspec->setf==NULL) { LM_ERR("read only output variable [%.*s]\n", svname->len, svname->s); return -1; } val.rs.s = pv_get_buffer(); val.rs.len = xavp_serialize_fields(sxname, val.rs.s, pv_get_buffer_size()); if(val.rs.len<=0) { return -1; } val.flags = PV_VAL_STR; if(vspec->setf(msg, &vspec->pvp, EQ_T, &val)<0) { LM_ERR("setting PV failed [%.*s]\n", svname->len, svname->s); return -1; } return 1; }
int pv_get_xavp(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { pv_xavp_name_t *xname=NULL; sr_xavp_t *avp=NULL; int idxf = 0; int idx = 0; int count; char *p, *p_ini; int p_size; if(param==NULL) { LM_ERR("bad parameters\n"); return -1; } xname = (pv_xavp_name_t*)param->pvn.u.dname; if(xname->index.type==PVT_EXTRA) { /* get the index */ if(pv_get_spec_index(msg, &xname->index.pvp, &idx, &idxf)!=0) { LM_ERR("invalid index\n"); return -1; } } /* fix the index */ if(idx<0) { count = xavp_count(&xname->name, NULL); idx = count + idx; } avp = xavp_get_by_index(&xname->name, idx, NULL); if(avp==NULL) return pv_get_null(msg, param, res); if(xname->next==NULL) return pv_xavp_get_value(msg, param, res, avp); if(avp->val.type != SR_XTYPE_XAVP) return pv_get_null(msg, param, res); idx = 0; idxf = 0; if(xname->next->index.type==PVT_EXTRA) { /* get the index */ if(pv_get_spec_index(msg, &xname->next->index.pvp, &idx, &idxf)!=0) { LM_ERR("invalid index\n"); return -1; } } /* fix the index */ if(idx<0) { count = xavp_count(&xname->next->name, &avp->val.v.xavp); idx = count + idx; } avp = xavp_get_by_index(&xname->next->name, idx, &avp->val.v.xavp); if(avp==NULL) return pv_get_null(msg, param, res); /* get all values of second key */ if(idxf==PV_IDX_ALL) { p_ini = pv_get_buffer(); p = p_ini; p_size = pv_get_buffer_size(); do { if(p!=p_ini) { if(p-p_ini+PV_FIELD_DELIM_LEN+1>p_size) { LM_ERR("local buffer length exceeded\n"); return pv_get_null(msg, param, res); } memcpy(p, PV_FIELD_DELIM, PV_FIELD_DELIM_LEN); p += PV_FIELD_DELIM_LEN; } if(pv_xavp_get_value(msg, param, res, avp)<0) { LM_ERR("can get value\n"); return pv_get_null(msg, param, res); } if(p-p_ini+res->rs.len+1>p_size) { LM_ERR("local buffer length exceeded!\n"); return pv_get_null(msg, param, res); } memcpy(p, res->rs.s, res->rs.len); p += res->rs.len; } while ((avp=xavp_get_next(avp))!=0); res->rs.s = p_ini; res->rs.len = p - p_ini; return 0; } return pv_xavp_get_value(msg, param, res, avp); }
/** Get the function parameter value as string or/and integer (if possible). * @return 0 - Success * -1 - Cannot get value */ int get_is_fparam(int* i_dst, str* s_dst, struct sip_msg* msg, fparam_t* param, unsigned int *flags) { int_str val; int ret; avp_t* avp; str tmp; pv_value_t pv_val; *flags = 0; switch(param->type) { case FPARAM_INT: *i_dst = param->v.i; *flags |= PARAM_INT; return 0; case FPARAM_REGEX: case FPARAM_UNSPEC: case FPARAM_STRING: s_dst->s = param->v.asciiz; s_dst->len = strlen(param->v.asciiz); *flags |= PARAM_STR; break; case FPARAM_STR: *s_dst = param->v.str; *flags |= PARAM_STR; break; case FPARAM_AVP: avp = search_first_avp(param->v.avp.flags, param->v.avp.name, &val, 0); if (unlikely(!avp)) { LM_DBG("Could not find AVP from function parameter '%s'\n", param->orig); return -1; } if (avp->flags & AVP_VAL_STR) { *s_dst = val.s; *flags |= PARAM_STR; if (str2int(&val.s, (unsigned int*)i_dst) < 0) { LM_ERR("Could not convert AVP string value to int\n"); return -1; } } else { *i_dst = val.n; *flags |= PARAM_INT; } break; case FPARAM_SELECT: ret = run_select(&tmp, param->v.select, msg); if (unlikely(ret < 0 || ret > 0)) return -1; if (unlikely(str2int(&tmp, (unsigned int*)i_dst) < 0)) { LM_ERR("Could not convert select result to int\n"); return -1; } *flags |= PARAM_INT; break; case FPARAM_PVS: if (likely(pv_get_spec_value(msg, param->v.pvs, &pv_val)==0)) { if ((pv_val.flags&(PV_VAL_NULL|PV_VAL_INT))==PV_VAL_INT){ *i_dst=pv_val.ri; *flags |= PARAM_INT; } if ((pv_val.flags&(PV_VAL_NULL|PV_VAL_STR))==PV_VAL_STR){ *s_dst=pv_val.rs; *flags |= PARAM_STR; } }else{ LM_ERR("Could not get PV\n"); return -1; } break; case FPARAM_PVE: s_dst->s=pv_get_buffer(); s_dst->len=pv_get_buffer_size(); if (unlikely(pv_printf(msg, param->v.pve, s_dst->s, &s_dst->len)!=0)){ LM_ERR("Could not convert the PV-formated string to str\n"); s_dst->len=0; return -1; } *flags |= PARAM_STR; break; } /* Let's convert to int, if possible */ if (!(*flags & PARAM_INT) && (*flags & PARAM_STR) && str2sint(s_dst, i_dst) == 0) *flags |= PARAM_INT; if (!*flags) return -1; return 0; }
/** Get the function parameter value as string. * @return 0 - Success * -1 - Cannot get value */ int get_str_fparam(str* dst, struct sip_msg* msg, fparam_t* param) { int_str val; int ret; avp_t* avp; pv_value_t pv_val; switch(param->type) { case FPARAM_REGEX: case FPARAM_UNSPEC: case FPARAM_INT: return -1; case FPARAM_STRING: dst->s = param->v.asciiz; dst->len = strlen(param->v.asciiz); break; case FPARAM_STR: *dst = param->v.str; break; case FPARAM_AVP: avp = search_first_avp(param->v.avp.flags, param->v.avp.name, &val, 0); if (unlikely(!avp)) { LM_DBG("Could not find AVP from function parameter '%s'\n", param->orig); return -1; } if (likely(avp->flags & AVP_VAL_STR)) { *dst = val.s; } else { /* The caller does not know of what type the AVP will be so * convert int AVPs into string here */ dst->s = int2str(val.n, &dst->len); } break; case FPARAM_SELECT: ret = run_select(dst, param->v.select, msg); if (unlikely(ret < 0 || ret > 0)) return -1; break; case FPARAM_PVS: if (likely((pv_get_spec_value(msg, param->v.pvs, &pv_val)==0) && ((pv_val.flags&(PV_VAL_NULL|PV_VAL_STR))==PV_VAL_STR))){ *dst=pv_val.rs; }else{ LM_ERR("Could not convert PV to str\n"); return -1; } break; case FPARAM_PVE: dst->s=pv_get_buffer(); dst->len=pv_get_buffer_size(); if (unlikely(pv_printf(msg, param->v.pve, dst->s, &dst->len)!=0)){ LM_ERR("Could not convert the PV-formated string to str\n"); dst->len=0; return -1; }; break; } return 0; }
int pv_printf_s(struct sip_msg* msg, pv_elem_p list, str *s) { s->s = pv_get_buffer(); s->len = pv_get_buffer_size(); return pv_printf( msg, list, s->s, &s->len); }
int pv_get_msrp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) { msrp_frame_t *mf; msrp_hdr_t *hdr; str_array_t *sar; msrp_uri_t uri; str s; char *p; mf = msrp_get_current_frame(); if(mf==NULL || param==NULL) return -1; sar = NULL; hdr = NULL; switch(param->pvn.u.isname.name.n) { case 1: s.s = mf->buf.s; s.len = mf->buf.len; return pv_get_strval(msg, param, res, &s); case 2: if(mf->mbody.s==NULL) return pv_get_null(msg, param, res); s.s = mf->mbody.s; s.len = mf->mbody.len; return pv_get_strval(msg, param, res, &s); case 3: if(mf->fline.msgtypeid==MSRP_REQUEST) return pv_get_null(msg, param, res); return pv_get_intstrval(msg, param, res, MSRP_RPL_CODE(mf->fline.rtypeid), &mf->fline.rtype); case 4: if(mf->hbody.s==NULL) return pv_get_null(msg, param, res); s.s = mf->hbody.s; s.len = mf->hbody.len; return pv_get_strval(msg, param, res, &s); case 5: hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_MESSAGE_ID); if(hdr==NULL) return pv_get_null(msg, param, res); s.s = hdr->body.s; s.len = hdr->body.len; trim(&s); return pv_get_strval(msg, param, res, &s); case 6: if(mf->fline.msgtypeid==MSRP_REPLY) return pv_get_null(msg, param, res); return pv_get_strintval(msg, param, res, &mf->fline.rtype, mf->fline.rtypeid); case 7: return pv_get_uintval(msg, param, res, mf->buf.len); case 8: if(msrp_parse_hdr_to_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; s = sar->list[0]; trim(&s); if(msrp_parse_uri(s.s, s.len, &uri)<0 || uri.session.len<=0) return pv_get_null(msg, param, res); s = uri.session; trim(&s); return pv_get_strval(msg, param, res, &s); case 9: if(mf->fline.msgtypeid==MSRP_REQUEST || mf->fline.rtext.s==NULL) return pv_get_null(msg, param, res); return pv_get_strval(msg, param, res, &mf->fline.rtext); case 10: return pv_get_uintval(msg, param, res, mf->mbody.len); case 11: s = mf->fline.transaction; trim(&s); return pv_get_strval(msg, param, res, &s); case 12: if(msrp_parse_hdr_to_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; s = sar->list[0]; trim(&s); return pv_get_strval(msg, param, res, &s); case 13: if(msrp_parse_hdr_from_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; s = sar->list[0]; trim(&s); return pv_get_strval(msg, param, res, &s); case 14: if(msrp_parse_hdr_to_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; if(sar->size<2) return pv_get_null(msg, param, res); s = sar->list[1]; trim(&s); return pv_get_strval(msg, param, res, &s); case 15: if(msrp_parse_hdr_to_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; s = sar->list[sar->size-1]; trim(&s); return pv_get_strval(msg, param, res, &s); case 16: if(msrp_parse_hdr_from_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; s = sar->list[sar->size-1]; trim(&s); return pv_get_strval(msg, param, res, &s); case 17: if(msrp_parse_hdr_from_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; return pv_get_uintval(msg, param, res, sar->size); case 18: if(msrp_parse_hdr_to_path(mf)<0) return pv_get_null(msg, param, res); hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH); if(hdr==NULL) return pv_get_null(msg, param, res); sar = (str_array_t*)hdr->parsed.data; return pv_get_uintval(msg, param, res, sar->size-1); case 19: if(pv_get_buffer_size()<100) return pv_get_null(msg, param, res); s.s = pv_get_buffer(); p = s.s; if(mf->tcpinfo->rcv->proto==PROTO_TLS) { memcpy(p, "msrps://", 8); p+=8; } else { memcpy(p, "msrp://", 7); p+=7; } strcpy(p, ip_addr2a(&mf->tcpinfo->rcv->src_ip)); strcat(p, ":"); strcat(p, int2str(mf->tcpinfo->rcv->src_port, NULL)); s.len = strlen(s.s); return pv_get_strval(msg, param, res, &s); case 20: return pv_get_strval(msg, param, res, &mf->tcpinfo->rcv->bind_address->sock_str); case 21: if(mf->tcpinfo->con==NULL) return pv_get_null(msg, param, res); return pv_get_sintval(msg, param, res, mf->tcpinfo->con->id); default: return pv_get_null(msg, param, res); } return 0; }
int pv_get_dlg(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { dlg_cell_t *dlg = NULL; int res_type = 0; str sv = { 0 }; unsigned int ui = 0; if(param==NULL) return -1; if(_dlg_ctx.iuid.h_id==0) { /* Retrieve the dialog for current message */ dlg=dlg_get_msg_dialog(msg); } else { /* Retrieve the dialog for current context */ dlg=dlg_get_by_iuid(&_dlg_ctx.iuid); } if(dlg == NULL) return pv_get_null(msg, param, res); switch(param->pvn.u.isname.name.n) { case 1: res_type = 1; ui = (unsigned int)dlg->h_id; break; case 2: res_type = 1; ui = (unsigned int)dlg->state; break; case 3: if(dlg->route_set[DLG_CALLEE_LEG].s==NULL || dlg->route_set[DLG_CALLEE_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->route_set[DLG_CALLEE_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->route_set[DLG_CALLEE_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 4: res_type = 1; ui = (unsigned int)dlg->dflags; break; case 5: res_type = 1; ui = (unsigned int)dlg->sflags; break; case 6: if(dlg->callid.s==NULL || dlg->callid.len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->callid.len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->callid.s, sv.len); sv.s[sv.len] = '\0'; break; case 7: if(dlg->to_uri.s==NULL || dlg->to_uri.len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->to_uri.len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->to_uri.s, sv.len); sv.s[sv.len] = '\0'; break; case 8: if(dlg->tag[DLG_CALLEE_LEG].s==NULL || dlg->tag[DLG_CALLEE_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->tag[DLG_CALLEE_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->tag[DLG_CALLEE_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 9: res_type = 1; ui = (unsigned int)dlg->toroute; break; case 10: if(dlg->cseq[DLG_CALLEE_LEG].s==NULL || dlg->cseq[DLG_CALLEE_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->cseq[DLG_CALLEE_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->cseq[DLG_CALLEE_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 11: if(dlg->route_set[DLG_CALLER_LEG].s==NULL || dlg->route_set[DLG_CALLER_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->route_set[DLG_CALLER_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->route_set[DLG_CALLER_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 12: if(dlg->from_uri.s==NULL || dlg->from_uri.len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->from_uri.len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->from_uri.s, sv.len); sv.s[sv.len] = '\0'; break; case 13: if(dlg->tag[DLG_CALLER_LEG].s==NULL || dlg->tag[DLG_CALLER_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->tag[DLG_CALLER_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->tag[DLG_CALLER_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 14: res_type = 1; ui = (unsigned int)dlg->lifetime; break; case 15: res_type = 1; ui = (unsigned int)dlg->start_ts; break; case 16: if(dlg->cseq[DLG_CALLER_LEG].s==NULL || dlg->cseq[DLG_CALLER_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->cseq[DLG_CALLER_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->cseq[DLG_CALLER_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 17: if(dlg->contact[DLG_CALLEE_LEG].s==NULL || dlg->contact[DLG_CALLEE_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->contact[DLG_CALLEE_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->contact[DLG_CALLEE_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 18: if(dlg->bind_addr[DLG_CALLEE_LEG]==NULL) goto done; sv.s = pv_get_buffer(); sv.len = dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.s, sv.len); sv.s[sv.len] = '\0'; break; case 19: if(dlg->contact[DLG_CALLER_LEG].s==NULL || dlg->contact[DLG_CALLER_LEG].len<=0) goto done; sv.s = pv_get_buffer(); sv.len = dlg->contact[DLG_CALLER_LEG].len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->contact[DLG_CALLER_LEG].s, sv.len); sv.s[sv.len] = '\0'; break; case 20: if(dlg->bind_addr[DLG_CALLER_LEG]==NULL) goto done; sv.s = pv_get_buffer(); sv.len = dlg->bind_addr[DLG_CALLER_LEG]->sock_str.len; if(pv_get_buffer_size()<sv.len) goto done; res_type = 2; strncpy(sv.s, dlg->bind_addr[DLG_CALLER_LEG]->sock_str.s, sv.len); sv.s[sv.len] = '\0'; break; case 21: res_type = 1; ui = (unsigned int)dlg->h_entry; break; default: res_type = 1; ui = (unsigned int)dlg->ref; } done: dlg_release(dlg); switch(res_type) { case 1: return pv_get_uintval(msg, param, res, ui); case 2: return pv_get_strval(msg, param, res, &sv); default: return pv_get_null(msg, param, res); } }