static inline int push_ds_2_avps( ds_dest_t *ds ) { char buf[2+16+1]; /* a hexa string */ int_str avp_val; avp_val.s.len = 1 + sprintf( buf, "%p", ds->sock ); avp_val.s.s = buf; if(add_avp(AVP_VAL_STR|sock_avp_type, sock_avp_name, avp_val)!=0) { LM_ERR("failed to add SOCK avp\n"); return -1; } avp_val.s = ds->uri; if(add_avp(AVP_VAL_STR|dst_avp_type, dst_avp_name, avp_val)!=0) { LM_ERR("failed to add DST avp\n"); return -1; } if (attrs_avp_name >= 0) { avp_val.s = ds->attrs; if(add_avp(AVP_VAL_STR|attrs_avp_type,attrs_avp_name,avp_val)!=0) { LM_ERR("failed to add ATTR avp\n"); return -1; } } return 0; }
/* * Set Identity header * param trans Transaction handle * return 0 success, -1 failure */ static int ospSetIdentity( OSPTTRANHANDLE trans) { char encoded[OSP_SIGNBUF_SIZE]; unsigned encodedsize = sizeof(encoded); unsigned char sign[OSP_SIGNBUF_SIZE]; unsigned signsize = sizeof(sign); char alg[OSP_ALGBUF_SIZE]; char info[OSP_STRBUF_SIZE]; char type[OSP_STRBUF_SIZE]; unsigned char canon[OSP_STRBUF_SIZE]; unsigned canonsize = sizeof(canon); str value; int result = -1; if (OSPPTransactionGetIdentity(trans, &signsize, sign, sizeof(alg), alg, sizeof(info), info, sizeof(type), type, &canonsize, canon) == OSPC_ERR_NO_ERROR) { if (signsize != 0) { if (OSPPBase64Encode(sign, signsize, (unsigned char*)encoded, &encodedsize) == OSPC_ERR_NO_ERROR) { value.s = encoded; value.len = encodedsize; add_avp(_osp_idsign_avptype | AVP_VAL_STR, _osp_idsign_avpid, (int_str)value); } } if (alg[0] != '\0') { value.s = alg; value.len = strlen(alg); add_avp(_osp_idalg_avptype | AVP_VAL_STR, _osp_idalg_avpid, (int_str)value); } if (info[0] != '\0') { value.s = info; value.len = strlen(info); add_avp(_osp_idinfo_avptype | AVP_VAL_STR, _osp_idinfo_avpid, (int_str)value); } if (type[0] != '\0') { value.s = type; value.len = strlen(type); add_avp(_osp_idtype_avptype | AVP_VAL_STR, _osp_idtype_avpid, (int_str)value); } if (canonsize != 0) { if (OSPPBase64Encode(canon, canonsize, (unsigned char*)encoded, &encodedsize) == OSPC_ERR_NO_ERROR) { value.s = encoded; value.len = encodedsize; add_avp(_osp_idcanon_avptype | AVP_VAL_STR, _osp_idcanon_avpid, (int_str)value); } } result = 0; } return result; }
int mt_add_tvalues(struct sip_msg *msg, m_tree_t *pt, str *tomatch) { int l; mt_node_t *itn; int_str val, values_avp_name; unsigned short values_name_type; mt_is_t *tvalues; if (pt == NULL || tomatch == NULL || tomatch->s == NULL) { LM_ERR("bad parameters\n"); return -1; } if (pv_get_avp_name(msg, &pv_values.pvp, &values_avp_name, &values_name_type) < 0) { LM_ERR("cannot get values avp name\n"); return -1; } l = 0; itn = pt->head; while (itn != NULL && l < tomatch->len && l < MT_MAX_DEPTH) { /* check validity */ if(_mt_char_table[(unsigned int)tomatch->s[l]]==255) { LM_ERR("invalid char at %d in [%.*s]\n", l, tomatch->len, tomatch->s); return -1; } tvalues = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].tvalues; while (tvalues != NULL) { if (pt->type == MT_TREE_IVAL) { val.n = tvalues->tvalue.n; LM_DBG("adding avp <%.*s> with value <i:%d>\n", values_avp_name.s.len, values_avp_name.s.s, val.n); add_avp(values_name_type, values_avp_name, val); } else { /* pt->type == MT_TREE_SVAL */ val.s = tvalues->tvalue.s; LM_DBG("adding avp <%.*s> with value <s:%.*s>\n", values_avp_name.s.len, values_avp_name.s.s, val.s.len, val.s.s); add_avp(values_name_type|AVP_VAL_STR, values_avp_name, val); } tvalues = tvalues->next; } itn = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].child; l++; } return 0; }
static void stack_to_avp(struct avp_stack *stack) { int j; int avp_att; int_str avp_val; for(j=0; j< stack->i; j++) { /* AVP names can be integer or string based */ LM_DBG("process AVP: name='%s' value='%s'\n", stack->avp[j].att, stack->avp[j].val); /* we will only use string avps * so all names are strings */ avp_val.s.s = stack->avp[j].att; avp_val.s.len = strlen(avp_val.s.s); avp_att = get_avp_id(&avp_val.s); if (avp_att < 0) { LM_ERR("cannot find %s avp\n", avp_val.s.s); continue; } LM_DBG("create string named AVP <s:%.*s>\n", avp_val.s.len, ZSW(avp_val.s.s)); avp_val.s.s = stack->avp[j].val; avp_val.s.len = strlen(avp_val.s.s); /* string type explicitely forced with s: */ if(add_avp(AVP_VAL_STR, avp_att, avp_val)) LM_ERR("cannot add avp\n"); } }
/* * Check if an entry exists in hash table that has given src_ip and protocol * value and pattern that matches to From URI. If an entry exists and tag_avp * has been defined, tag of the entry is added as a value to tag_avp. * Returns number of matches or -1 if none matched. */ int match_hash_table(struct trusted_list** table, struct sip_msg* msg, char *src_ip_c_str, int proto) { str uri; char uri_string[MAX_URI_SIZE + 1]; regex_t preg; struct trusted_list *np; str src_ip; int_str val; int count = 0; src_ip.s = src_ip_c_str; src_ip.len = strlen(src_ip.s); if (IS_SIP(msg)) { if (parse_from_header(msg) < 0) return -1; uri = get_from(msg)->uri; if (uri.len > MAX_URI_SIZE) { LM_ERR("from URI too large\n"); return -1; } memcpy(uri_string, uri.s, uri.len); uri_string[uri.len] = (char)0; } for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) { if ((np->src_ip.len == src_ip.len) && (strncmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) && ((np->proto == PROTO_NONE) || (proto == PROTO_NONE) || (np->proto == proto))) { if (np->pattern && IS_SIP(msg)) { if (regcomp(&preg, np->pattern, REG_NOSUB)) { LM_ERR("invalid regular expression\n"); continue; } if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); continue; } regfree(&preg); } /* Found a match */ if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } if (!peer_tag_mode) return 1; count++; } } if (!count) return -1; else return count; }
/** * writes the next_domain avp using the rule list of route_tree * * @param failure_tree the current failure routing tree node * @param host last tried host * @param reply_code the last reply code * @param flags flags for the failure route rule * @param dstavp the name of the AVP where to store the next domain * * @return 0 on success, -1 on failure */ static int set_next_domain_on_rule(const struct failure_route_tree_item *failure_tree, const str *host, const str *reply_code, const flag_t flags, const struct multiparam_t *dstavp) { struct failure_route_rule * rr; int_str avp_val; assert(failure_tree != NULL); LM_DBG("searching for matching routing rules"); for (rr = failure_tree->rule_list; rr != NULL; rr = rr->next) { /* LM_DBG("rr.flags=%d rr.mask=%d flags=%d\n", rr->flags, rr->mask, flags); LM_DBG("rr.host.len=%d host.len=%d\n", rr->host.len, host->len); LM_DBG("rr.host.s='%.*s' host.s='%.*s'\n", rr->host.len, rr->host.s, host->len, host->s); LM_DBG("rr.reply_code.len=%d reply_code.len=%d\n", rr->reply_code.len, reply_code->len); LM_DBG("rr.reply_code.s='%.*s' reply_code.s='%.*s'\n", rr->reply_code.len, rr->reply_code.s, reply_code->len, reply_code->s); */ if (((rr->mask & flags) == rr->flags) && ((rr->host.len == 0) || (str_strcmp(host, &rr->host)==0)) && (reply_code_matcher(&(rr->reply_code), reply_code)==0)) { avp_val.n = rr->next_domain; if (add_avp(dstavp->u.a.flags, dstavp->u.a.name, avp_val)<0) { LM_ERR("set AVP failed\n"); return -1; } LM_INFO("next_domain is %d.\n", rr->next_domain); return 0; } } return -1; }
/* * Check if an entry exists in hash table that has given group, domain_name, and * port. Port 0 in hash table matches any port. */ int match_domain_name_table(struct domain_name_list** table, unsigned int group, str *domain_name, unsigned int port) { struct domain_name_list *np; avp_value_t val; for (np = table[perm_hash(*domain_name)]; np != NULL; np = np->next) { if ( (np->grp == group) && ((np->port == 0) || (np->port == port)) && np->domain.len == domain_name->len && strncmp(np->domain.s, domain_name->s, domain_name->len)==0 ) { if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } return 1; } } return -1; }
/** * Loads user carrier from subscriber table and stores it in an AVP. * * @param _msg the current SIP message * @param _user the user to determine the carrier data * @param _domain the domain to determine the domain data * @param _dstavp the name of the AVP where to store the carrier id * * @return 1 on success, -1 on failure */ int cr_load_user_carrier(struct sip_msg * _msg, gparam_t *_user, gparam_t *_domain, gparam_t *_dstavp) { str user, domain; int_str avp_val; if (fixup_get_svalue(_msg, _user, &user)<0) { LM_ERR("cannot print the user\n"); return -1; } if (fixup_get_svalue(_msg, _domain, &domain)<0) { LM_ERR("cannot print the domain\n"); return -1; } /* get carrier id */ if ((avp_val.n = load_user_carrier(&user, &domain)) < 0) { LM_ERR("error in load user carrier"); return -1; } else { /* set avp */ if (add_avp(_dstavp->v.pve->spec->pvp.pvn.u.isname.type, _dstavp->v.pve->spec->pvp.pvn.u.isname.name, avp_val)<0) { LM_ERR("add AVP failed\n"); return -1; } } return 1; }
/* * Check if an ip_addr/port entry exists in hash table in any group. * Returns first group in which ip_addr/port is found. * Port 0 in hash table matches any port. */ int find_group_in_addr_hash_table(struct addr_list** table, ip_addr_t *addr, unsigned int port) { struct addr_list *np; str addr_str; avp_value_t val; addr_str.s = (char*)addr->u.addr; addr_str.len = 4; for (np = table[perm_hash(addr_str)]; np != NULL; np = np->next) { if (((np->port == 0) || (np->port == port)) && ip_addr_cmp(&np->addr, addr)) { if (tag_avp.n && np->tag.s) { val.s = np->tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } return np->grp; } } return -1; }
static int w_get_profile_size(struct sip_msg *msg, char *profile, char *value, char *result) { pv_elem_t *pve; str val_s; pv_spec_t *sp_dest; unsigned int size; int_str res; int avp_name; unsigned short avp_type; script_var_t * sc_var; pve = (pv_elem_t *)value; sp_dest = (pv_spec_t *)result; if ( pve!=NULL && ((struct dlg_profile_table*)profile)->has_value) { if ( pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; } size = get_profile_size( (struct dlg_profile_table*)profile ,&val_s ); } else { size = get_profile_size( (struct dlg_profile_table*)profile, NULL ); } switch (sp_dest->type) { case PVT_AVP: if (pv_get_avp_name( msg, &(sp_dest->pvp), &avp_name, &avp_type)!=0){ LM_CRIT("BUG in getting AVP name\n"); return -1; } res.n = size; if (add_avp(avp_type, avp_name, res)<0){ LM_ERR("cannot add AVP\n"); return -1; } break; case PVT_SCRIPTVAR: if(sp_dest->pvp.pvn.u.dname == 0){ LM_ERR("cannot find svar name\n"); return -1; } res.n = size; sc_var = (script_var_t *)sp_dest->pvp.pvn.u.dname; if(!set_var_value(sc_var, &res, 0)){ LM_ERR("cannot set svar\n"); return -1; } break; default: LM_CRIT("BUG: invalid pvar type\n"); return -1; } return 1; }
/** * Loads user carrier from subscriber table and stores it in an AVP. * * @param _msg the current SIP message * @param _user the user to determine the route tree * @param _domain the domain to determine the route tree * @param _dstavp the name of the AVP where to store the carrier tree id * * @return 1 on success, -1 on failure */ int cr_load_user_carrier(struct sip_msg * _msg, pv_elem_t *_user, pv_elem_t *_domain, struct multiparam_t *_dstavp) { str user; str domain; int_str avp_val; if (pv_printf_s(_msg, _user, &user)<0) { LM_ERR("cannot print the user\n"); return -1; } if (pv_printf_s(_msg, _domain, &domain)<0) { LM_ERR("cannot print the domain\n"); return -1; } /* get carrier id */ if ((avp_val.n = load_user_carrier(&user, &domain)) < 0) { LM_ERR("error in load user carrier"); return -1; } else { /* set avp ! */ if (add_avp(_dstavp->u.a.flags, _dstavp->u.a.name, avp_val)<0) { LM_ERR("add AVP failed\n"); return -1; } } return 1; }
/* * Generate AVPs from the database result */ static int generate_avps(VALUE_PAIR* received) { str name_str, val_str; int_str name, val; VALUE_PAIR *vp; vp = received; while ((vp = rc_avpair_get(vp, attrs[A_SIP_AVP].v, 0))) { attr_name_value(vp, &name_str, &val_str); name.s = name_str; val.s = val_str; if (add_avp(AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) { LM_ERR("failed to create a new AVP\n"); } else { LM_DBG("AVP '%.*s'='%.*s' has been added\n", name_str.len, ZSW(name_str.s), val_str.len, ZSW(val_str.s)); } vp = vp->next; } return 0; }
static int l_siplua_AVP_set(lua_State *L) { int name; int_str val; str s; int retval; int flags = 0; luaL_checkany(L, 1); luaL_checkany(L, 2); s.s = (char *) lua_tostring(L, 1); s.len = strlen(s.s); name = get_avp_id(&s); if (lua_type(L, 2) == LUA_TNUMBER) val.n = luaL_checkinteger(L, 2); else { val.s.s = (char *)luaL_checkstring(L, 2); val.s.len = strlen(val.s.s); flags |= AVP_VAL_STR; } retval = add_avp(flags, name, val); if (!retval) lua_pushboolean(L, 1); else lua_pushnil(L); return 1; }
/* * Generate AVPs from the database result */ static int generate_avps(VALUE_PAIR* received) { int_str name, val; unsigned short flags; VALUE_PAIR *vp; LM_DBG("getting AVPs from RADIUS Reply\n"); vp = received; if ( ! ar_radius_avps_mode ) vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0); for( ; vp; vp=((ar_radius_avps_mode)?vp->next:rc_avpair_get(vp->next,attrs[A_SIP_AVP].v,0)) ) { flags = 0; if (!extract_avp( vp, &flags, &name, &val)){ LM_ERR("error while extracting AVP '%.*s'\n",(int)strlen(vp->name),vp->name); continue; } if (add_avp( flags, name, val) < 0) { LM_ERR("unable to create a new AVP\n"); } else { LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n", (flags&AVP_NAME_STR)?name.s.len:4, (flags&AVP_NAME_STR)?name.s.s:"null", (flags&AVP_NAME_STR)?0:name.n, (flags&AVP_VAL_STR)?val.s.len:4, (flags&AVP_VAL_STR)?val.s.s:"null", (flags&AVP_VAL_STR)?0:val.n ); } } return 0; }
/* Generate AVPs from Radius reply items */ static void generate_avps(struct attr *attrs, VALUE_PAIR* received) { int_str name, val; unsigned short flags; VALUE_PAIR *vp; vp = received; for( ; (vp=rc_avpair_get(vp,attrs[SA_SIP_AVP].v,0)) ; vp=vp->next) { flags = 0; if (extract_avp( vp, &flags, &name, &val)!=0 ) continue; if (add_avp( flags, name, val) < 0) { LM_ERR("unable to create a new AVP\n"); } else { LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n", (flags&AVP_NAME_STR)?name.s.len:4, (flags&AVP_NAME_STR)?name.s.s:"null", (flags&AVP_NAME_STR)?0:name.n, (flags&AVP_VAL_STR)?val.s.len:4, (flags&AVP_VAL_STR)?val.s.s:"null", (flags&AVP_VAL_STR)?0:val.n ); } } return; }
/* * Generate AVPs from the database result */ static int generate_avps(db_res_t* result) { struct aaa_avp *cred; int_str ivalue; str value; int i; for ( cred=credentials,i=1 ; cred ; cred=cred->next,i++ ) { value.s = (char*)VAL_STRING(&(result->rows[0].values[i])); if ( VAL_NULL(&(result->rows[0].values[i])) || value.s == NULL ) { continue; } value.len = strlen(value.s); ivalue.s = &value; if (add_avp( cred->avp_type|AVP_VAL_STR, cred->avp_name, ivalue)!=0) { LOG(L_ERR,"ERROR:auth_db:generate_avps: failed to add AVP\n"); return -1; } DBG("generate_avps: set string AVP \"%s\"/%d = \"%.*s\"\n", (cred->avp_type&AVP_NAME_STR)?cred->avp_name.s->s:"", (cred->avp_type&AVP_NAME_STR)?0:cred->avp_name.n, value.len, ZSW(value.s)); } return 0; }
/** * writes the next_domain avp using the rule list of failure_tree * * @param frr_head the head of the failure route rule list * @param host last tried host * @param reply_code the last reply code * @param flags flags for the failure route rule * @param dstavp the name of the AVP where to store the next domain * * @return 0 on success, -1 on failure */ static int set_next_domain_on_rule(struct failure_route_rule *frr_head, const str *host, const str *reply_code, const flag_t flags, const gparam_t *dstavp) { struct failure_route_rule * rr; int_str avp_val; assert(frr_head != NULL); LM_DBG("searching for matching routing rules"); for (rr = frr_head; rr != NULL; rr = rr->next) { /* LM_DBG("rr.flags=%d rr.mask=%d flags=%d\n", rr->flags, rr->mask, flags); LM_DBG("rr.host.len=%d host.len=%d\n", rr->host.len, host->len); LM_DBG("rr.host.s='%.*s' host.s='%.*s'\n", rr->host.len, rr->host.s, host->len, host->s); LM_DBG("rr.reply_code.len=%d reply_code.len=%d\n", rr->reply_code.len, reply_code->len); LM_DBG("rr.reply_code.s='%.*s' reply_code.s='%.*s'\n", rr->reply_code.len, rr->reply_code.s, reply_code->len, reply_code->s); */ if (((rr->mask & flags) == rr->flags) && ((rr->host.len == 0) || (str_strcmp(host, &rr->host)==0)) && (reply_code_matcher(&(rr->reply_code), reply_code)==0)) { avp_val.n = rr->next_domain; if (add_avp(dstavp->v.pve->spec->pvp.pvn.u.isname.type, dstavp->v.pve->spec->pvp.pvn.u.isname.name, avp_val)<0) { LM_ERR("set AVP failed\n"); return -1; } LM_INFO("next_domain is %d\n", rr->next_domain); return 0; } } LM_INFO("no matching rule for (flags=%d, host='%.*s', reply_code='%.*s') found\n", flags, host->len, host->s, reply_code->len, reply_code->s); return -1; }
/* * Check if an entry exists in subnet table that matches given ip_addr, * and port. Port 0 in subnet table matches any port. Return group of * first match or -1 if no match is found. */ int find_group_in_subnet_table(struct subnet* table, ip_addr_t *addr, unsigned int port) { unsigned int count, i; avp_value_t val; count = table[PERM_MAX_SUBNETS].grp; i = 0; while (i < count) { if ( ((table[i].port == port) || (table[i].port == 0)) && (ip_addr_match_net(addr, &table[i].subnet, table[i].mask)==0)) { if (tag_avp.n && table[i].tag.s) { val.s = table[i].tag; if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, val) != 0) { LM_ERR("setting of tag_avp failed\n"); return -1; } } return table[i].grp; } i++; } return -1; }
int ops_write_avp(struct sip_msg* msg, struct fis_param *src, struct fis_param *ap) { struct sip_uri uri; int_str avp_val; unsigned short flags; str s_ip; if (src->flags&AVPOPS_VAL_NONE) { if (src->flags&AVPOPS_USE_SRC_IP) { /* get data from src_ip */ if ( (s_ip.s=ip_addr2a( &msg->rcv.src_ip ))==0) { LOG(L_ERR,"ERROR:avpops:write_avp: cannot get src_ip\n"); goto error; } s_ip.len = strlen(s_ip.s); avp_val.s = &s_ip; } else { /* get data from uri (from,to,ruri) */ if (src->flags&(AVPOPS_FLAG_USER|AVPOPS_FLAG_DOMAIN)) { if (parse_source_uri( msg, src->flags, &uri)!=0 ) { LOG(L_ERR,"ERROR:avpops:write_avp: cannot parse uri\n"); goto error; } if (src->flags&AVPOPS_FLAG_DOMAIN) avp_val.s = &uri.host; else avp_val.s = &uri.user; } else { /* get whole uri */ if ( (avp_val.s=get_source_uri(msg,src->flags))==0 ) { LOG(L_ERR,"ERROR:avpops:write_avp: cannot get uri\n"); goto error; } } } flags = AVP_VAL_STR; } else { avp_val = src->val; flags = (src->flags&AVPOPS_VAL_INT)?0:AVP_VAL_STR; } /* set the proper flag */ flags |= (ap->flags&AVPOPS_VAL_INT)?0:AVP_NAME_STR; /* added the avp */ if (add_avp( flags, ap->val, avp_val)<0) goto error; return 1; error: return -1; }
int exec_getenv(struct sip_msg *msg, char *cmd, pvname_list_p avpl) { int_str avp_val; int_str avp_name; unsigned short avp_type; int ret; str res; pvname_list_t* crt; /* pessimist: assume error by default */ ret=-1; res.s=getenv(cmd); if (res.s==NULL) { goto error; } res.len=strlen(res.s); crt = avpl; avp_type = 0; if(crt==NULL) { avp_name.s.s = int2str(1, &avp_name.s.len); if (!avp_name.s.s) { LM_ERR("cannot convert 1 to string\n"); goto error; } avp_name.n = get_avp_id(&avp_name.s); if (avp_name.n < 0) { LM_ERR("cannot get avp id\n"); goto error; } } else { if(pv_get_avp_name(msg, &(crt->sname.pvp), &avp_name.n, &avp_type)!=0) { LM_ERR("can't get item name\n"); goto error; } } avp_type |= AVP_VAL_STR; avp_val.s = res; if(add_avp(avp_type, avp_name.n, avp_val)!=0) { LM_ERR("unable to add avp\n"); goto error; } /* success */ ret=1; error: return ret; }
/* * Set calling number if translated * param msg SIP message * param dest Destination structure * return 0 success, 1 calling number same or not support calling number translation, -1 failure */ static int ospSetCalling( struct sip_msg* msg, osp_dest* dest) { str rpid; int_str val; char calling[OSP_STRBUF_SIZE]; char buffer[OSP_STRBUF_SIZE]; int result; if (ospGetFromUserpart(msg, calling, sizeof(calling)) != 0) { LM_ERR("failed to extract calling number\n"); result = -1; } else if (strcmp(calling, dest->calling) == 0) { LM_DBG("calling number does not been translated\n"); result = 1; } else if (osp_auth.rpid_avp < 0) { LM_WARN("rpid_avp is not found, cannot set rpid avp\n"); result = -1; } else { snprintf(buffer, sizeof(buffer), "\"%s\" <sip:%s@%s>", dest->calling, dest->calling, dest->source); buffer[sizeof(buffer) - 1] = '\0'; rpid.s = buffer; rpid.len = strlen(buffer); add_avp(osp_auth.rpid_avp_type | AVP_VAL_STR, osp_auth.rpid_avp, (int_str)rpid); result = 0; } if (result == 0) { val.n = 1; } else { val.n = 0; } add_avp(0, _osp_calling_avpid, val); return result; }
/* * Create OSP cookie and insert it into Record-Route header * param msg SIP message * param tansid Transaction ID * param uac Source IP * param from * param to * param authtime Request authorization time * param isorig Originate / Terminate * param destinationCount Destination count */ static void ospRecordTransaction( struct sip_msg* msg, unsigned long long transid, char* uac, char* from, char* to, time_t authtime, int isorig, unsigned destinationCount) { const str* name; str cookie; char buffer[OSP_STRBUF_SIZE]; LOG(L_DBG, "osp: ospRecordTransaction\n"); cookie.s = buffer; if (isorig == 1) { cookie.len = snprintf( buffer, sizeof(buffer), "%c%llu_%c%s_%c%d_%c%d", OSP_COOKIE_TRANSID, transid, OSP_COOKIE_SRCIP, uac, OSP_COOKIE_AUTHTIME, (unsigned int)authtime, OSP_COOKIE_DSTCOUNT, destinationCount); } else { cookie.len = snprintf( buffer, sizeof(buffer), "%c%llu_%c%s_%c%d", OSP_COOKIE_TRANSID, transid, OSP_COOKIE_SRCIP, uac, OSP_COOKIE_AUTHTIME, (unsigned int)authtime); } if (cookie.len < 0) { LOG(L_ERR, "osp: ERROR: failed to create OSP cookie\n"); return; } /* SER uses AVP to add RR parameters */ LOG(L_DBG, "osp: adding RR parameter '%s' for '%s'\n", buffer, (isorig == 1) ? "orig" : "term"); name = (isorig == 1) ? &OSP_ORIGCOOKIE_NAME : &OSP_TERMCOOKIE_NAME; add_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)*name, (int_str)cookie); }
int w_fetch_dlg_value(struct sip_msg *msg, char *name, char *result) { struct dlg_cell *dlg; str val; pv_spec_t *sp_dest; int_str res; int avp_name; unsigned short avp_type; script_var_t * sc_var; sp_dest = (pv_spec_t *)result; if ( (dlg=get_current_dialog())==NULL ) return -1; if (fetch_dlg_value( dlg, (str*)name, &val, 0) ) { LM_DBG("failed to fetch dialog value <%.*s>\n", ((str*)name)->len, ((str*)name)->s); return -1; } switch (sp_dest->type) { case PVT_AVP: if (pv_get_avp_name( msg, &(sp_dest->pvp), &avp_name, &avp_type)!=0){ LM_CRIT("BUG in getting AVP name\n"); return -1; } res.s = val; if (add_avp(avp_type|AVP_VAL_STR, avp_name, res)<0){ LM_ERR("cannot add AVP\n"); return -1; } break; case PVT_SCRIPTVAR: if(sp_dest->pvp.pvn.u.dname == 0){ LM_ERR("cannot find svar name\n"); return -1; } res.s = val; sc_var = (script_var_t *)sp_dest->pvp.pvn.u.dname; if(!set_var_value(sc_var, &res, VAR_VAL_STR)){ LM_ERR("cannot set svar\n"); return -1; } break; default: LM_CRIT("BUG: invalid pvar type\n"); return -1; } return 1; }
static inline void store_user_in_avps(str* user) { avp_value_t val; if (user_part_avp_ident.name.s.s && user_part_avp_ident.name.s.len && user && user->s && user->len) { val.s = *user; add_avp(user_part_avp_ident.flags | AVP_NAME_STR | AVP_VAL_STR, user_part_avp_ident.name, val); } }
static inline void store_next_route_in_avps(str* uri) { avp_value_t val; if (next_route_avp_ident.name.s.s && next_route_avp_ident.name.s.len && uri && uri->s && uri->len) { val.s = *uri; add_avp(next_route_avp_ident.flags | AVP_NAME_STR | AVP_VAL_STR, next_route_avp_ident.name, val); } }
int ldap_filter_url_encode( struct sip_msg* _msg, pv_elem_t* _filter_component, pv_spec_t* _dst_avp_spec) { str filter_component_str, esc_str; int dst_avp_name; unsigned short dst_avp_type; /* * variable substitution for _filter_component */ if (_filter_component) { if (pv_printf_s(_msg, _filter_component, &filter_component_str) != 0) { LM_ERR("pv_printf_s failed\n"); return -1; } } else { LM_ERR("empty first argument\n"); return -1; } /* * get dst AVP name (dst_avp_name) */ if (pv_get_avp_name(_msg, &(_dst_avp_spec->pvp), &dst_avp_name, &dst_avp_type) != 0) { LM_ERR("error getting dst AVP name\n"); return -1; } /* * apply LDAP filter escaping rules */ esc_str.s = esc_buf; esc_str.len = ESC_BUF_SIZE; if (ldap_rfc4515_escape(&filter_component_str, &esc_str, 1) != 0) { LM_ERR("ldap_rfc4515_escape() failed\n"); return -1; } /* * add dst AVP */ if (add_avp(dst_avp_type|AVP_VAL_STR, dst_avp_name, (int_str)esc_str) != 0) { LM_ERR("failed to add new AVP\n"); return -1; } return 1; }
/* * Generate AVPs from the database result */ static int generate_avps(VALUE_PAIR* received) { int_str name, val; VALUE_PAIR *vp; vp = rc_avpair_get(received, ATTRID(attrs[A_SER_UID].v), VENDOR(attrs[A_SER_UID].v)); if (vp == NULL) { WARN("RADIUS server did not send SER-UID attribute in digest authentication reply\n"); return -1; } val.s.len = vp->lvalue; val.s.s = vp->strvalue; name.s.s = "uid"; name.s.len = 3; if (add_avp(AVP_TRACK_FROM | AVP_CLASS_USER | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) { ERR("Unable to create UID attribute\n"); return -1; } vp = received; while ((vp = rc_avpair_get(vp, ATTRID(attrs[A_SER_ATTR].v), VENDOR(attrs[A_SER_ATTR].v)))) { attr_name_value(&name.s, &val.s, vp); if (name.s.len == 0) { ERR("Missing attribute name\n"); return -1; } if (add_avp(AVP_TRACK_FROM | AVP_CLASS_USER | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) { LOG(L_ERR, "generate_avps: Unable to create a new AVP\n"); return -1; } else { DBG("generate_avps: AVP '%.*s'='%.*s' has been added\n", name.s.len, ZSW(name.s.s), val.s.len, ZSW(val.s.s)); } vp = vp->next; } return 0; }
/* * Set calling number if translated * param msg SIP message * param inbound Inbound info * param dest Destination structure * return 0 success, 1 calling number same or not support calling number translation, -1 failure */ static int ospSetCalling( struct sip_msg* msg, osp_inbound* inbound, osp_dest* dest) { str rpid; int_str val; char buffer[2 * sizeof dest->calling + sizeof inbound->source + 11]; int result; if (strcmp(inbound->calling, dest->calling) == 0) { LM_DBG("calling number does not been translated\n"); result = 1; } else if (osp_auth.rpid_avp < 0) { LM_WARN("rpid_avp is not found, cannot set rpid avp\n"); result = -1; } else { snprintf(buffer, sizeof(buffer), "\"%s\" <sip:%s@%s>", dest->calling, dest->calling, inbound->source); rpid.s = buffer; rpid.len = strlen(buffer); add_avp(osp_auth.rpid_avp_type | AVP_VAL_STR, osp_auth.rpid_avp, (int_str)rpid); result = 0; } if (result == 0) { val.n = 1; } else { val.n = 0; } add_avp(0, _osp_calling_avpid, val); return result; }
static int w_sdp_get(sip_msg_t* msg, char *avp) { sdp_info_t *sdp = NULL; int_str avp_val; int_str avp_name; static unsigned short avp_type = 0; str s; pv_spec_t *avp_spec = NULL; int sdp_missing=1; s.s = avp; s.len = strlen(s.s); if (pv_locate_name(&s) != s.len) { LM_ERR("invalid parameter\n"); return -1; } if (((avp_spec = pv_cache_get(&s)) == NULL) || avp_spec->type!=PVT_AVP) { LM_ERR("malformed or non AVP %s AVP definition\n", avp); return -1; } if(pv_get_avp_name(0, &avp_spec->pvp, &avp_name, &avp_type)!=0) { LM_ERR("[%s]- invalid AVP definition\n", avp); return -1; } sdp_missing = parse_sdp(msg); if(sdp_missing < 0) { LM_ERR("Unable to parse sdp\n"); return -1; } sdp = (sdp_info_t*)msg->body; if (sdp==NULL) { LM_DBG("No SDP\n"); return -2; } avp_val.s.s = sdp->raw_sdp.s; avp_val.s.len = sdp->raw_sdp.len; LM_DBG("Found SDP %.*s\n", sdp->raw_sdp.len, sdp->raw_sdp.s); if (add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0) { LM_ERR("Failed to add SDP avp"); return -1; } return 1; }
static void trace_transaction(struct dlg_cell* dlg, int type, struct dlg_cb_params * params) { unsigned char n; static int_str avp_value; str *name; if (params->msg==NULL) return; /* restore the AVPs from the dialog values */ n = 0; do { name = generate_val_name(n); if (dlgb.fetch_dlg_value( dlg, name, &avp_value.s, 0)!=0) break; add_avp( traced_user_avp_type|AVP_VAL_STR, traced_user_avp, avp_value); n++; }while(1); /* set the flag */ if ( dlgb.fetch_dlg_value( dlg, &st_flag_val, &avp_value.s, 0)==0 ) params->msg->flags |= trace_flag; params->msg->msg_flags |= FL_USE_SIPTRACE; /* trace current request */ sip_trace(params->msg); if(tmb.register_tmcb( params->msg, 0, TMCB_REQUEST_BUILT, trace_onreq_out, 0, 0) <=0) { LM_ERR("can't register trace_onreq_out\n"); return; } /* doesn't make sense to register the reply callbacks for ACK or PRACK */ if (params->msg->REQ_METHOD & (METHOD_ACK | METHOD_PRACK)) return; if(tmb.register_tmcb( params->msg, 0, TMCB_RESPONSE_IN, trace_onreply_in, 0, 0) <=0) { LM_ERR("can't register trace_onreply_in\n"); return; } if(tmb.register_tmcb( params->msg, 0, TMCB_RESPONSE_OUT, trace_onreply_out, 0, 0) <=0) { LM_ERR("can't register trace_onreply_out\n"); return; } }