int sd_lookup(struct sip_msg* _msg, char* _index, char* _str2) { int i; str user_s, uid, did; db_res_t* res = NULL; db_rec_t* rec; /* init */ i = (int)(long)_index; /* Retrieve the owner of the record */ if (get_from_uid(&uid, _msg) < 0) { LOG(L_ERR, "sd_lookup: Unable to get user identity\n"); return -1; } /* Retrieve the called domain id */ if (get_to_did(&did, _msg) < 0) { LOG(L_ERR, "sd_lookup: Destination domain ID not known\n"); return -1; } tables[i].lookup_num->match[0].v.lstr = uid; tables[i].lookup_num->match[1].v.lstr = did; /* Get the called username */ if (parse_sip_msg_uri(_msg) < 0) { LOG(L_ERR, "sd_lookup: Error while parsing Request-URI\n"); goto err_badreq; } tables[i].lookup_num->match[2].v.lstr = _msg->parsed_uri.user; DBG("speeddial: Looking up (uid:%.*s,username:%.*s,did:%.*s)\n", uid.len, uid.s, _msg->parsed_uri.user.len, _msg->parsed_uri.user.s, did.len, did.s); if (db_exec(&res, tables[i].lookup_num) < 0) { ERR("speeddial: Error while executing database command\n"); goto err_server; } if (res == NULL) { DBG("speeddial: No SIP URI found for speeddial (num:%.*s, uid:%.*s," " did:%.*s)\n", _msg->parsed_uri.user.len, _msg->parsed_uri.user.s, uid.len, uid.s, did.len, did.s); return -1; } user_s.s = useruri_buf + 4; rec = db_first(res); while(rec) { if (rec->fld[0].flags & DB_NULL) goto skip; strncpy(user_s.s, rec->fld[0].v.lstr.s, rec->fld[0].v.lstr.len); user_s.len = rec->fld[0].v.lstr.len; user_s.s[user_s.len] = '\0'; goto out; skip: rec = db_next(res); } if (rec == NULL) { DBG("speeddial: No usable SIP URI found for (num:%.*s, uid:%.*s," " did:%.*s)\n", _msg->parsed_uri.user.len, _msg->parsed_uri.user.s, uid.len, uid.s, did.len, did.s); db_res_free(res); return -1; } out: /* check 'sip:' */ if(user_s.len<4 || strncmp(user_s.s, "sip:", 4)) { memcpy(useruri_buf, "sip:", 4); user_s.s -= 4; user_s.len += 4; } db_res_free(res); /* set the URI */ DBG("sd_lookup: URI of sd from R-URI [%s]\n", user_s.s); if(rewrite_uri(_msg, &user_s)<0) { LOG(L_ERR, "sd_lookup: Cannot replace the R-URI\n"); goto err_server; } return 1; err_server: if (slb.zreply(_msg, 500, "Server Internal Error") == -1) { LOG(L_ERR, "sd_lookup: Error while sending reply\n"); } return 0; err_badreq: if (slb.zreply(_msg, 400, "Bad Request") == -1) { LOG(L_ERR, "sd_lookup: Error while sending reply\n"); } return 0; }
/* create an array of str's for accounting using a formatting string; * this is the heart of the accounting module -- it prints whatever * requested in a way, that can be used for syslog, radius, * sql, whatsoever * tm sip_msg_clones does not clone (shmmem-zed) parsed fields, other then Via1,2. Such fields clone now or use from rq_rp */ static int fmt2strar(char *fmt, /* what would you like to account ? */ struct sip_msg *rq, /* accounted message */ str* ouri, /* Outbound Request-URI */ struct hdr_field *to, unsigned int code, time_t req_time) /* Timestamp of the request */ { int cnt; struct to_body* from, *pto; str *cr, *at; struct cseq_body *cseq; cnt = 0; /* we don't care about parsing here; either the function * was called from script, in which case the wrapping function * is supposed to parse, or from reply processing in which case * TM should have preparsed from REQUEST_IN callback; what's not * here is replaced with NA */ while(*fmt) { if (cnt == ALL_LOG_FMT_LEN) { LOG(L_ERR, "ERROR:acc:fmt2strar: Formatting string is too long\n"); return 0; } switch(*fmt) { case 'a': /* attr */ at = print_attrs(avps, avps_n, 0); if (!at) { vals[cnt].nul = 1; } else { vals[cnt].val.str_val = *at; } break; case 'c': /* sip_callid */ if (rq->callid && rq->callid->body.len) { vals[cnt].val.str_val = rq->callid->body; } else { vals[cnt].nul = 1; } break; case 'd': /* to_tag */ if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) { vals[cnt].val.str_val = pto->tag_value; } else { vals[cnt].nul = 1; } break; case 'f': /* sip_from */ if (rq->from && rq->from->body.len) { vals[cnt].val.str_val = rq->from->body; } else { vals[cnt].nul = 1; } break; case 'g': /* flags */ vals[cnt].val.int_val = rq->flags; break; case 'i': /* inbound_ruri */ vals[cnt].val.str_val = rq->first_line.u.request.uri; break; case 'm': /* sip_method */ vals[cnt].val.str_val = rq->first_line.u.request.method; break; case 'n': /* sip_cseq */ if (rq->cseq && (cseq = get_cseq(rq)) && cseq->number.len) { str2int(&cseq->number, (unsigned int*)&vals[cnt].val.int_val); } else { vals[cnt].nul = 1; } break; case 'o': /* outbound_ruri */ vals[cnt].val.str_val = *ouri; break; case 'p': vals[cnt].val.int_val = rq->rcv.src_ip.u.addr32[0]; break; break; case 'r': /* from_tag */ if (rq->from && (from = get_from(rq)) && from->tag_value.len) { vals[cnt].val.str_val = from->tag_value; } else { vals[cnt].nul = 1; } break; case 't': /* sip_to */ if (to && to->body.len) vals[cnt].val.str_val = to->body; else vals[cnt].nul = 1; break; case 'u': /* digest_username */ cr = cred_user(rq); if (cr) vals[cnt].val.str_val = *cr; else vals[cnt].nul = 1; break; case 'x': /* request_timestamp */ vals[cnt].val.time_val = req_time; break; case 'D': /* to_did */ vals[cnt].nul = 1; break; case 'F': /* from_uri */ if (rq->from && (from = get_from(rq)) && from->uri.len) { vals[cnt].val.str_val = from->uri; } else vals[cnt].nul = 1; break; case 'I': /* from_uid */ if (get_from_uid(&vals[cnt].val.str_val, rq) < 0) { vals[cnt].nul = 1; } break; case 'M': /* from_did */ vals[cnt].nul = 1; break; case 'P': /* source_port */ vals[cnt].val.int_val = rq->rcv.src_port; break; case 'R': /* digest_realm */ cr = cred_realm(rq); if (cr) vals[cnt].val.str_val = *cr; else vals[cnt].nul = 1; break; case 'S': /* sip_status */ if (code > 0) vals[cnt].val.int_val = code; else vals[cnt].nul = 1; break; case 'T': /* to_uri */ if (rq->to && (pto = get_to(rq)) && pto->uri.len) vals[cnt].val.str_val = pto->uri; else vals[cnt].nul = 1; break; case 'U': /* to_uid */ if (get_to_uid(&vals[cnt].val.str_val, rq) < 0) { vals[cnt].nul = 1; } break; case 'X': /* response_timestamp */ vals[cnt].val.time_val = time(0); break; default: LOG(L_CRIT, "BUG:acc:fmt2strar: unknown char: %c\n", *fmt); return 0; } /* switch (*fmt) */ fmt++; cnt++; } /* while (*fmt) */ return cnt; }
int rls_create_subscription(struct sip_msg *m, rl_subscription_t **dst, flat_list_t *flat, xcap_query_params_t *params) { rl_subscription_t *s; str from_uid = STR_NULL; int res; if (!dst) return RES_INTERNAL_ERR; *dst = NULL; s = rls_alloc_subscription(rls_external_subscription); if (!s) { LOG(L_ERR, "rls_create_new(): can't allocate memory\n"); return RES_MEMORY_ERR; } generate_db_id(&s->dbid, s); res = sm_init_subscription_nolock(rls_manager, &s->u.external, m); if (res != RES_OK) { rls_free(s); return res; } if (params) { if (dup_xcap_params(&s->xcap_params, params) < 0) { ERR("can't duplicate xcap_params\n"); rls_free(s); return -1; } } /* store pointer to this RL subscription as user data * of (low level) subscription */ s->u.external.usr_data = s; if (get_from_uid(&from_uid, m) < 0) str_clear(&s->from_uid); else str_dup(&s->from_uid, &from_uid); /* res = set_rls_info(m, s, xcap_root); if (res != 0) { rls_free(s); return res; }*/ res = add_virtual_subscriptions(s, flat, max_list_nesting_level); if (res != 0) { rls_free(s); return res; } if (use_db) { if (rls_db_add(s) != 0) { rls_free(s); return RES_INTERNAL_ERR; /* FIXME RES_DB_ERR */ } } *dst = s; return RES_OK; }
/* create an array of str's for accounting using a formatting string; * this is the heart of the accounting module -- it prints whatever * requested in a way, that can be used for syslog, radius, * sql, whatsoever * tm sip_msg_clones does not clone (shmmem-zed) parsed fields, other then Via1,2. Such fields clone now or use from rq_rp */ static int fmt2rad(char *fmt, struct sip_msg *rq, str* ouri, struct hdr_field *to, unsigned int code, VALUE_PAIR** send, time_t req_time) /* Timestamp of the request */ { static unsigned int cseq_num, src_port, src_ip; static time_t rq_time, rs_time; int cnt; struct to_body* from, *pto; str val, *cr, *at; struct cseq_body *cseq; struct attr* attr; int dir; cnt = 0; dir = -2; /* we don't care about parsing here; either the function * was called from script, in which case the wrapping function * is supposed to parse, or from reply processing in which case * TM should have preparsed from REQUEST_IN callback. */ while(*fmt) { if (cnt == ALL_LOG_FMT_LEN) { LOG(L_ERR, "ERROR:acc:fmt2rad: Formatting string is too long\n"); return 0; } attr = 0; switch(*fmt) { case 'a': /* attr */ at = print_attrs(avps, avps_n, 0); if (at) { attr = &attrs[A_SER_ATTR]; val = *at; } break; case 'c': /* sip_callid */ if (rq->callid && rq->callid->body.len) { attr = &attrs[A_ACCT_SESSION_ID]; val = rq->callid->body; } break; case 'd': /* to_tag */ if (swap_dir && dir == -2) dir = get_direction(rq); if (dir <= 0) { if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) { attr = &attrs[A_SIP_TO_TAG]; val = pto->tag_value; } } else { if (rq->from && (from = get_from(rq)) && from->tag_value.len) { attr = &attrs[A_SIP_TO_TAG]; val = from->tag_value; } } break; case 'f': /* sip_from */ if (rq->from && rq->from->body.len) { attr = &attrs[A_SER_FROM]; val = rq->from->body; } break; case 'g': /* flags */ attr = &attrs[A_SER_FLAGS]; val.s = (char*)&rq->flags; val.len = sizeof(unsigned int); break; case 'i': /* inbound_ruri */ attr = &attrs[A_SER_ORIGINAL_REQUEST_ID]; val = rq->first_line.u.request.uri; break; case 'm': /* sip_method */ attr = &attrs[A_SIP_METHOD]; val = rq->first_line.u.request.method; break; case 'n': /* sip_cseq */ if (rq->cseq && (cseq = get_cseq(rq)) && cseq->number.len) { attr = &attrs[A_SIP_CSEQ]; str2int(&cseq->number, &cseq_num); val.s = (char*)&cseq_num; val.len = sizeof(unsigned int); } break; case 'o': /* outbound_ruri */ attr = &attrs[A_SIP_TRANSLATED_REQUEST_ID]; val = *ouri; break; case 'p': /* Source IP address */ attr = &attrs[A_SIP_SOURCE_IP_ADDRESS]; src_ip = ntohl(rq->rcv.src_ip.u.addr32[0]); val.s = (char*)&src_ip; val.len = sizeof(src_ip); break; case 'r': /* from_tag */ if (swap_dir && dir == -2) dir = get_direction(rq); if (dir <= 0) { if (rq->from && (from = get_from(rq)) && from->tag_value.len) { attr = &attrs[A_SIP_FROM_TAG]; val = from->tag_value; } } else { if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) { attr = &attrs[A_SIP_FROM_TAG]; val = pto->tag_value; } } break; case 's': /* server_id */ attr = &attrs[A_SER_SERVER_ID]; val.s = (char*)&server_id; val.len = sizeof(int); break; case 't': /* sip_to */ if (to && to->body.len) { attr = &attrs[A_SER_TO]; val = to->body; } break; case 'u': /* digest_username */ cr = cred_user(rq); if (cr) { attr = &attrs[A_SER_DIGEST_USERNAME]; val = *cr; } break; case 'x': /* request_timestamp */ attr = &attrs[A_SER_REQUEST_TIMESTAMP]; rq_time = req_time; val.s = (char*)&rq_time; val.len = sizeof(time_t); break; case 'D': /* to_did */ break; case 'F': /* from_uri */ if (swap_dir && dir == -2) dir = get_direction(rq); if (dir <= 0) { if (rq->from && (from = get_from(rq)) && from->uri.len) { attr = &attrs[A_CALLING_STATION_ID]; val = from->uri; } } else { if (rq->to && (pto = get_to(rq)) && pto->uri.len) { attr = &attrs[A_CALLING_STATION_ID]; val = pto->uri; } } break; case 'I': /* from_uid */ if (get_from_uid(&val, rq) < 0) { attr = &attrs[A_SER_FROM_UID]; } break; case 'M': /* from_did */ break; case 'P': /* Source port */ attr = &attrs[A_SIP_SOURCE_PORT]; src_port = rq->rcv.src_port; val.s = (char*)&src_port; val.len = sizeof(unsigned int); break; case 'R': /* digest_realm */ cr = cred_realm(rq); if (cr) { attr = &attrs[A_SER_DIGEST_REALM]; val = *cr; } break; case 'S': /* sip_status */ attr = &attrs[A_SIP_RESPONSE_CODE]; val.s = (char*)&code; val.len = sizeof(unsigned int); break; case 'T': /* to_uri */ if (swap_dir && dir == -2) dir = get_direction(rq); if (dir <= 0) { if (rq->to && (pto = get_to(rq)) && pto->uri.len) { attr = &attrs[A_CALLED_STATION_ID]; val = pto->uri; } } else { if (rq->from && (from = get_from(rq)) && from->uri.len) { attr = &attrs[A_CALLED_STATION_ID]; val = from->uri; } } break; case 'U': /* to_uid */ if (get_from_uid(&val, rq) < 0) { attr = &attrs[A_SER_TO_UID]; } break; case 'X': /* response_timestamp */ attr = &attrs[A_SER_RESPONSE_TIMESTAMP]; rs_time = time(0); val.s = (char*)&rs_time; val.len = sizeof(time_t); break; default: LOG(L_CRIT, "BUG:acc:fmt2rad: unknown char: %c\n", *fmt); return -1; } /* switch (*fmt) */ if (attr) { if (!rc_avpair_add(rh, send, ATTRID(attr->v), val.s, val.len, VENDOR(attr->v))) { LOG(L_ERR, "ERROR:acc:fmt2rad: Failed to add attribute %s\n", attr->n); return -1; } } fmt++; cnt++; } /* while (*fmt) */ return 0; }