00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <string.h>
00035 #include <stdlib.h>
00036 #ifdef EXTRA_DEBUG
00037 #include <assert.h>
00038 #endif
00039 #include "../../sr_module.h"
00040 #include "../../error.h"
00041 #include "../../lump_struct.h"
00042 #include "../../data_lump.h"
00043 #include "../../data_lump_rpl.h"
00044 #include "../../usr_avp.h"
00045 #include "../../mem/mem.h"
00046 #include "../../parser/parse_uri.h"
00047 #include "../../parser/msg_parser.h"
00048 #include "../../parser/parse_nameaddr.h"
00049 #include "../../ut.h"
00050 #include "../../dset.h"
00051 #include "../../trim.h"
00052 #include "../../str.h"
00053 #include "../../dprint.h"
00054 #include "../../re.h"
00055 #include "../../action.h"
00056
00057 #include "../../parser/parse_hname2.h"
00058 #include "../xlog/xl_lib.h"
00059 #define NO_SCRIPT -1
00060
00061 MODULE_VERSION
00062
00063
00064 #define HDR_ID 0
00065 #define HDR_STR 1
00066
00067 #define PARAM_DELIM '/'
00068 #define VAL_TYPE_INT (1<<0)
00069 #define VAL_TYPE_STR (1<<1)
00070
00071 struct hdr_name {
00072 enum {hdrId, hdrStr} kind;
00073 union {
00074 int n;
00075 str s;
00076 } name;
00077 char field_delimiter;
00078 char array_delimiter;
00079 int val_types;
00080 };
00081
00082 static int xlbuf_size=256;
00083 static char* xlbuf=NULL;
00084 static str* xl_nul=NULL;
00085 static xl_print_log_f* xl_print=NULL;
00086 static xl_parse_format_f* xl_parse=NULL;
00087 static xl_elog_free_all_f* xl_free=NULL;
00088 static xl_get_nulstr_f* xl_getnul=NULL;
00089
00090 static int mod_init();
00091 static int set_iattr(struct sip_msg* msg, char* p1, char* p2);
00092 static int set_sattr(struct sip_msg* msg, char* p1, char* p2);
00093 static int print_attr(struct sip_msg* msg, char* p1, char* p2);
00094 static int del_attr(struct sip_msg* msg, char* p1, char* p2);
00095 static int subst_attr(struct sip_msg* msg, char* p1, char* p2);
00096 static int flags2attr(struct sip_msg* msg, char* p1, char* p2);
00097 static int attr2uri(struct sip_msg* msg, char* p1, char* p2);
00098 static int dump_attrs(struct sip_msg* msg, char* p1, char* p2);
00099 static int attr_equals(struct sip_msg* msg, char* p1, char* p2);
00100 static int attr_exists(struct sip_msg* msg, char* p1, char* p2);
00101 static int attr_equals_xl(struct sip_msg* msg, char* p1, char* p2);
00102 static int xlset_attr(struct sip_msg* msg, char* p1, char* p2);
00103 static int xlfix_attr(struct sip_msg* msg, char* p1, char* p2);
00104 static int insert_req(struct sip_msg* msg, char* p1, char* p2);
00105 static int append_req(struct sip_msg* msg, char* p1, char* p2);
00106 static int replace_req(struct sip_msg* msg, char* p1, char* p2);
00107 static int append_reply(struct sip_msg* msg, char* p1, char* p2);
00108 static int attr_destination(struct sip_msg* msg, char* p1, char* p2);
00109 static int xlset_destination(struct sip_msg* msg, char* p1, char* p2);
00110 static int attr_hdr_body2attrs(struct sip_msg* msg, char* p1, char* p2);
00111 static int attr_hdr_body2attrs2(struct sip_msg* msg, char* p1, char* p2);
00112 static int del_attrs(struct sip_msg* msg, char* p1, char* p2);
00113
00114 static int set_iattr_fixup(void**, int);
00115 static int avpid_fixup(void**, int);
00116 static int subst_attr_fixup(void**, int);
00117 static int fixup_part(void**, int);
00118 static int fixup_xl_1(void**, int);
00119 static int fixup_attr_1_xl_2(void**, int);
00120 static int fixup_str_1_attr_2(void**, int);
00121 static int xlfix_attr_fixup(void** param, int param_no);
00122 static int attr_hdr_body2attrs_fixup(void**, int);
00123 static int attr_hdr_body2attrs2_fixup(void**, int);
00124 static int avpgroup_fixup(void**, int);
00125
00126
00127
00128
00129 static cmd_export_t cmds[] = {
00130 {"set_iattr", set_iattr, 2, set_iattr_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00131 {"set_sattr", set_sattr, 2, fixup_var_str_12, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00132 {"set_attr", set_sattr, 2, fixup_var_str_12, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00133 {"print_attr", print_attr, 1, avpid_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00134 {"del_attr", del_attr, 1, avpid_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00135 {"del_attrs", del_attrs, 1, avpgroup_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00136 {"subst_attr", subst_attr, 2, subst_attr_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00137 {"flags2attr", flags2attr, 1, avpid_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00138 {"attr2uri", attr2uri, 1, fixup_part, REQUEST_ROUTE | FAILURE_ROUTE},
00139 {"attr2uri", attr2uri, 2, fixup_part, REQUEST_ROUTE | FAILURE_ROUTE},
00140 {"dump_attrs", dump_attrs, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00141 {"dump_attrs", dump_attrs, 1, avpgroup_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00142 {"attr_equals", attr_equals, 2, fixup_var_str_12, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00143 {"attr_exists", attr_exists, 1 , fixup_var_str_1, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00144 {"attr_equals_xl", attr_equals_xl, 2, fixup_attr_1_xl_2, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00145 {"xlset_attr", xlset_attr, 2, fixup_attr_1_xl_2, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00146 {"xlfix_attr", xlfix_attr, 1, xlfix_attr_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00147 {"insert_attr_hf", insert_req, 2, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00148 {"insert_attr_hf", insert_req, 1, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00149 {"append_attr_hf", append_req, 2, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00150 {"append_attr_hf", append_req, 1, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00151 {"replace_attr_hf", replace_req, 2, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00152 {"replace_attr_hf", replace_req, 1, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00153 {"attr_to_reply", append_reply, 2, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00154 {"attr_to_reply", append_reply, 1, fixup_str_1_attr_2, REQUEST_ROUTE | FAILURE_ROUTE},
00155 {"attr_destination", attr_destination, 1, avpid_fixup, REQUEST_ROUTE | FAILURE_ROUTE},
00156 {"xlset_destination", xlset_destination, 1, fixup_xl_1, REQUEST_ROUTE},
00157 {"hdr_body2attrs", attr_hdr_body2attrs, 2, attr_hdr_body2attrs_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00158 {"hdr_body2attrs2", attr_hdr_body2attrs2, 2, attr_hdr_body2attrs2_fixup, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE},
00159 {0, 0, 0, 0, 0}
00160 };
00161
00162
00163
00164
00165
00166 static param_export_t params[] = {
00167 {"xlbuf_size", PARAM_INT, &xlbuf_size},
00168 {0, 0, 0}
00169 };
00170
00171
00172 struct module_exports exports = {
00173 "avp",
00174 cmds,
00175 0,
00176 params,
00177 mod_init,
00178 0,
00179 0,
00180 0,
00181 0
00182 };
00183
00184
00185 static int set_iattr_fixup(void** param, int param_no)
00186 {
00187 if (param_no == 1) {
00188 return fixup_var_str_12(param, param_no);
00189 } else {
00190 return fixup_var_int_12(param, param_no);
00191 }
00192 }
00193
00194
00195 static int get_avp_id(avp_ident_t* id, fparam_t* p, struct sip_msg* msg)
00196 {
00197 str str_id;
00198 avp_t* avp;
00199 avp_value_t val;
00200 int ret;
00201
00202 switch(p->type) {
00203 case FPARAM_AVP:
00204 avp = search_avp(p->v.avp, &val, 0);
00205 if (!avp) {
00206 DBG("get_avp_id: AVP %s does not exist\n", p->orig);
00207 return -1;
00208 }
00209 if ((avp->flags & AVP_VAL_STR) == 0) {
00210 DBG("get_avp_id: Not a string AVP\n");
00211 return -1;
00212 }
00213 str_id = val.s;
00214 break;
00215
00216 case FPARAM_SELECT:
00217 ret = run_select(&str_id, p->v.select, msg);
00218 if (ret < 0 || ret > 0) return -1;
00219 break;
00220
00221 case FPARAM_STR:
00222 str_id = p->v.str;
00223 break;
00224
00225 default:
00226 ERR("Invalid parameter type in get_avp_id\n");
00227 return -1;
00228 }
00229
00230 return parse_avp_ident(&str_id, id);
00231 }
00232
00233
00234 static int set_iattr(struct sip_msg* msg, char* p1, char* p2)
00235 {
00236 avp_ident_t avpid;
00237 int_str value;
00238
00239 if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) {
00240 return -1;
00241 }
00242
00243 if (get_int_fparam(&value.n, msg, (fparam_t*)p2) < 0) {
00244 ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p1)->orig);
00245 return -1;
00246 }
00247
00248 if (add_avp(avpid.flags | AVP_NAME_STR, avpid.name, value) != 0) {
00249 ERR("add_avp failed\n");
00250 return -1;
00251 }
00252 return 1;
00253 }
00254
00255
00256 static int set_sattr(struct sip_msg* msg, char* p1, char* p2)
00257 {
00258 avp_ident_t avpid;
00259 int_str value;
00260
00261 if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) {
00262 return -1;
00263 }
00264
00265 if (get_str_fparam(&value.s, msg, (fparam_t*)p2) < 0) {
00266 ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p2)->orig);
00267 return -1;
00268 }
00269
00270 if (add_avp(avpid.flags | AVP_NAME_STR | AVP_VAL_STR, avpid.name, value) != 0) {
00271 ERR("add_avp failed\n");
00272 return -1;
00273 }
00274
00275 return 1;
00276 }
00277
00278
00279 static int avpid_fixup(void** param, int param_no)
00280 {
00281 if (param_no == 1) {
00282 if (fix_param(FPARAM_AVP, param) == 0) return 0;
00283 ERR("Invalid AVP identifier: '%s'\n", (char*)*param);
00284 return -1;
00285 }
00286 return 0;
00287 }
00288
00289
00290 static int print_attr(struct sip_msg* msg, char* p1, char* p2)
00291 {
00292 fparam_t* fp;
00293 int_str value;
00294 avp_t *avp;
00295
00296 fp = (fparam_t*)p1;
00297
00298 avp = search_avp(fp->v.avp, &value, NULL);
00299 if (avp == 0) {
00300 LOG(L_INFO, "AVP '%s' not found\n", fp->orig);
00301 return -1;
00302 }
00303
00304 if (avp->flags & AVP_VAL_STR) {
00305 LOG(L_INFO, "AVP: '%s'='%.*s'\n",
00306 fp->orig, value.s.len, ZSW(value.s.s));
00307 } else {
00308 LOG(L_INFO, "AVP: '%s'=%d\n", fp->orig, value.n);
00309 }
00310 return 1;
00311 }
00312
00313
00314 static int del_attr(struct sip_msg* msg, char* p1, char* p2)
00315 {
00316 fparam_t* fp;
00317 avp_t* avp;
00318 struct search_state st;
00319
00320 fp = (fparam_t*)p1;
00321
00322 avp = search_avp(fp->v.avp, 0, &st);
00323 while (avp) {
00324 destroy_avp(avp);
00325 avp = search_next_avp(&st, 0);
00326 }
00327 return 1;
00328 }
00329
00330
00331 static int del_attrs(struct sip_msg* msg, char* p1, char* p2)
00332 {
00333 return (reset_avp_list((unsigned long)p1) == 0) ? 1 : -1;
00334 }
00335
00336
00337 static int subst_attr_fixup(void** param, int param_no)
00338 {
00339 if (param_no == 1) {
00340 return avpid_fixup(param, 1);
00341 }
00342 if (param_no == 2) {
00343 if (fix_param(FPARAM_SUBST, param) != 0) return -1;
00344 }
00345 return 0;
00346 }
00347
00348
00349 static int subst_attr(struct sip_msg* msg, char* p1, char* p2)
00350 {
00351 avp_t* avp;
00352 avp_value_t val;
00353 str *res = NULL;
00354 int count;
00355 avp_ident_t* name = &((fparam_t*)p1)->v.avp;
00356
00357 if ((avp = search_avp(*name, &val, NULL))) {
00358 if (avp->flags & AVP_VAL_STR) {
00359 res = subst_str(val.s.s, msg, ((fparam_t*)p2)->v.subst, &count);
00360 if (res == NULL) {
00361 ERR("avp_subst: error while running subst\n");
00362 goto error;
00363 }
00364
00365 DBG("avp_subst: %d, result %.*s\n", count, res->len, ZSW(res->s));
00366 val.s = *res;
00367
00368 if (add_avp_before(avp, name->flags | AVP_VAL_STR, name->name, val)) {
00369 ERR("avp_subst: error while adding new AVP\n");
00370 goto error;
00371 }
00372
00373 destroy_avp(avp);
00374 return 1;
00375 } else {
00376 ERR("avp_subst: AVP has numeric value\n");
00377 goto error;
00378 }
00379 } else {
00380 ERR("avp_subst: AVP[%.*s] index %d, flags %x not found\n",
00381 name->name.s.len, name->name.s.s,
00382 name->index, name->flags);
00383 goto error;
00384 }
00385
00386 error:
00387 if (res) pkg_free(res);
00388 return -1;
00389 }
00390
00391
00392 static int flags2attr(struct sip_msg* msg, char* p1, char* p2)
00393 {
00394 avp_ident_t* id;
00395 int_str value;
00396
00397 value.n = msg->flags;
00398
00399 id = &((fparam_t*)p1)->v.avp;
00400
00401 if (add_avp(id->flags, id->name, value) != 0) {
00402 ERR("add_avp failed\n");
00403 return -1;
00404 }
00405
00406 return 1;
00407 }
00408
00409
00410 static int fixup_part(void** param, int param_no)
00411 {
00412 int i;
00413 fparam_t* fp;
00414
00415 static struct {
00416 char* s;
00417 int i;
00418 } fixup_parse[] = {
00419 {"", SET_URI_T},
00420 {"prefix", PREFIX_T},
00421 {"uri", SET_URI_T},
00422 {"username", SET_USER_T},
00423 {"user", SET_USER_T},
00424 {"usernamepassword", SET_USERPASS_T},
00425 {"userpass", SET_USERPASS_T},
00426 {"domain", SET_HOST_T},
00427 {"host", SET_HOST_T},
00428 {"domainport", SET_HOSTPORT_T},
00429 {"hostport", SET_HOSTPORT_T},
00430 {"port", SET_PORT_T},
00431 {"strip", STRIP_T},
00432 {"strip_tail", STRIP_TAIL_T},
00433 {0, 0}
00434 };
00435
00436 if (param_no == 1) {
00437 return avpid_fixup(param, 1);
00438 } else if (param_no == 2) {
00439
00440 if (fix_param(FPARAM_STRING, param) != 0) return -1;
00441
00442
00443
00444
00445 fp = (fparam_t*)*param;
00446 fp->type = FPARAM_INT;
00447
00448 for(i = 0; fixup_parse[i].s; i++) {
00449 if (!strcasecmp(fp->orig, fixup_parse[i].s)) {
00450 fp->v.i = fixup_parse[i].i;
00451 return 1;
00452 }
00453 }
00454
00455 ERR("Invalid parameter value: '%s'\n", fp->orig);
00456 return -1;
00457 }
00458 return 0;
00459 }
00460
00461
00462 static int attr2uri(struct sip_msg* msg, char* p1, char* p2)
00463 {
00464 int_str value;
00465 avp_t* avp_entry;
00466 struct action act;
00467 struct run_act_ctx ra_ctx;
00468 int pnr;
00469 unsigned int u;
00470
00471 if (p2) {
00472 pnr = ((fparam_t*)p2)->v.i;
00473 } else {
00474 pnr = SET_URI_T;
00475 }
00476
00477 avp_entry = search_avp(((fparam_t*)p1)->v.avp, &value, NULL);
00478 if (avp_entry == 0) {
00479 ERR("attr2uri: AVP '%s' not found\n", ((fparam_t*)p1)->orig);
00480 return -1;
00481 }
00482
00483 memset(&act, 0, sizeof(act));
00484
00485 if ((pnr == STRIP_T) || (pnr == STRIP_TAIL_T)) {
00486
00487 if (avp_entry->flags & AVP_VAL_STR) {
00488 if (str2int(&value.s, &u)) {
00489 ERR("not an integer value: %.*s\n",
00490 value.s.len, value.s.s);
00491 return -1;
00492 }
00493 act.val[0].u.number = u;
00494 } else {
00495 act.val[0].u.number = value.n;
00496 }
00497 act.val[0].type = NUMBER_ST;
00498 } else {
00499
00500 if ((avp_entry->flags & AVP_VAL_STR) == 0) {
00501 act.val[0].u.string = int2str(value.n, NULL);
00502 } else {
00503 act.val[0].u.string = value.s.s;
00504 }
00505 act.val[0].type = STRING_ST;
00506 }
00507 act.type = pnr;
00508 init_run_actions_ctx(&ra_ctx);
00509 if (do_action(&ra_ctx, &act, msg) < 0) {
00510 ERR("failed to change ruri part.\n");
00511 return -1;
00512 }
00513 return 1;
00514 }
00515
00516
00517
00518
00519
00520
00521 static void dump_avp_reverse(avp_t* avp)
00522 {
00523 str* name;
00524 int_str val;
00525
00526 if (avp) {
00527
00528 dump_avp_reverse(avp->next);
00529
00530 name=get_avp_name(avp);
00531 get_avp_val(avp, &val);
00532 switch(avp->flags&(AVP_NAME_STR|AVP_VAL_STR)) {
00533 case 0:
00534
00535 LOG(L_INFO,"AVP[%d]=%d\n", avp->id, val.n);
00536 break;
00537
00538 case AVP_NAME_STR:
00539
00540 name=get_avp_name(avp);
00541 LOG(L_INFO,"AVP[\"%.*s\"]=%d\n", name->len, name->s, val.n);
00542 break;
00543
00544 case AVP_VAL_STR:
00545
00546 LOG(L_INFO,"AVP[%d]=\"%.*s\"\n", avp->id, val.s.len, val.s.s);
00547 break;
00548
00549 case AVP_NAME_STR|AVP_VAL_STR:
00550
00551 name=get_avp_name(avp);
00552 LOG(L_INFO,"AVP[\"%.*s\"]=\"%.*s\"\n", name->len, name->s, val.s.len, val.s.s);
00553 break;
00554 }
00555 }
00556 }
00557
00558
00559 static int dump_attrs(struct sip_msg* m, char* x, char* y)
00560 {
00561 avp_list_t avp_list;
00562 unsigned long flags;
00563
00564 if (x) {
00565 flags = (unsigned long)x;
00566 } else {
00567 flags = AVP_CLASS_ALL | AVP_TRACK_ALL;
00568 }
00569
00570
00571 if (flags & AVP_CLASS_GLOBAL) {
00572 avp_list = get_avp_list(AVP_CLASS_GLOBAL);
00573 INFO("class=GLOBAL\n");
00574 if (!avp_list) {
00575 LOG(L_INFO,"INFO: No AVP present\n");
00576 } else {
00577 dump_avp_reverse(avp_list);
00578 }
00579 }
00580
00581 if (flags & AVP_CLASS_DOMAIN && flags & AVP_TRACK_FROM) {
00582 avp_list = get_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_FROM);
00583 INFO("track=FROM class=DOMAIN\n");
00584 if (!avp_list) {
00585 LOG(L_INFO,"INFO: No AVP present\n");
00586 } else {
00587 dump_avp_reverse(avp_list);
00588 }
00589 }
00590
00591 if (flags & AVP_CLASS_DOMAIN && flags & AVP_TRACK_TO) {
00592 avp_list = get_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_TO);
00593 INFO("track=TO class=DOMAIN\n");
00594 if (!avp_list) {
00595 LOG(L_INFO,"INFO: No AVP present\n");
00596 } else {
00597 dump_avp_reverse(avp_list);
00598 }
00599 }
00600
00601 if (flags & AVP_CLASS_USER && flags & AVP_TRACK_FROM) {
00602 avp_list = get_avp_list(AVP_CLASS_USER | AVP_TRACK_FROM);
00603 INFO("track=FROM class=USER\n");
00604 if (!avp_list) {
00605 LOG(L_INFO,"INFO: No AVP present\n");
00606 } else {
00607 dump_avp_reverse(avp_list);
00608 }
00609 }
00610
00611 if (flags & AVP_CLASS_USER && flags & AVP_TRACK_TO) {
00612 avp_list = get_avp_list(AVP_CLASS_USER | AVP_TRACK_TO);
00613 INFO("track=TO class=USER\n");
00614 if (!avp_list) {
00615 LOG(L_INFO,"INFO: No AVP present\n");
00616 } else {
00617 dump_avp_reverse(avp_list);
00618 }
00619 }
00620
00621 if (flags & AVP_CLASS_URI && flags & AVP_TRACK_FROM) {
00622 avp_list = get_avp_list(AVP_CLASS_URI | AVP_TRACK_FROM);
00623 INFO("track=FROM class=URI\n");
00624 if (!avp_list) {
00625 LOG(L_INFO,"INFO: No AVP present\n");
00626 } else {
00627 dump_avp_reverse(avp_list);
00628 }
00629 }
00630
00631 if (flags & AVP_CLASS_URI && flags & AVP_TRACK_TO) {
00632 avp_list = get_avp_list(AVP_CLASS_URI | AVP_TRACK_TO);
00633 INFO("track=TO class=URI\n");
00634 if (!avp_list) {
00635 LOG(L_INFO,"INFO: No AVP present\n");
00636 } else {
00637 dump_avp_reverse(avp_list);
00638 }
00639 }
00640 return 1;
00641 }
00642
00643
00644
00645
00646
00647
00648 static int attr_equals(struct sip_msg* msg, char* p1, char* p2)
00649 {
00650 avp_ident_t avpid;
00651 int_str value, avp_value;
00652 avp_t* avp;
00653 struct search_state st;
00654
00655 if (get_avp_id(&avpid, (fparam_t*)p1, msg) < 0) {
00656 return -1;
00657 }
00658
00659 if (p2 && get_str_fparam(&value.s, msg, (fparam_t*)p2) < 0) {
00660 ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p2)->orig);
00661 return -1;
00662 }
00663
00664 avp = search_avp(avpid, &avp_value, &st);
00665 if (avp == 0) return -1;
00666
00667 if (!p2) return 1;
00668
00669 while (avp != 0) {
00670 if (avp->flags & AVP_VAL_STR) {
00671 if ((avp_value.s.len == value.s.len) &&
00672 !memcmp(avp_value.s.s, value.s.s, avp_value.s.len)) {
00673 return 1;
00674 }
00675 } else {
00676 if (avp_value.n == str2s(value.s.s, value.s.len, 0)) {
00677 return 1;
00678 }
00679 }
00680 avp = search_next_avp(&st, &avp_value);
00681 }
00682
00683 return -1;
00684 }
00685
00686
00687 static int attr_exists(struct sip_msg* msg, char* p1, char* p2)
00688 {
00689 return attr_equals(msg, p1, NULL);
00690 }
00691
00692
00693 static int xl_printstr(struct sip_msg* msg, xl_elog_t* format, char** res, int* res_len)
00694 {
00695 int len;
00696
00697 if (!format || !res) {
00698 LOG(L_ERR, "xl_printstr: Called with null format or res\n");
00699 return -1;
00700 }
00701
00702 if (!xlbuf) {
00703 xlbuf = pkg_malloc((xlbuf_size+1)*sizeof(char));
00704 if (!xlbuf) {
00705 LOG(L_CRIT, "xl_printstr: No memory left for format buffer\n");
00706 return -1;
00707 }
00708 }
00709
00710 len = xlbuf_size;
00711 if (xl_print(msg, format, xlbuf, &len)<0) {
00712 LOG(L_ERR, "xl_printstr: Error while formating result\n");
00713 return -1;
00714 }
00715
00716 if ((xl_nul) && (xl_nul->len == len) && !strncmp(xl_nul->s, xlbuf, len)) {
00717 return 0;
00718 }
00719
00720 *res = xlbuf;
00721 if (res_len) {
00722 *res_len=len;
00723 }
00724 return len;
00725 }
00726
00727
00728 static int attr_equals_xl(struct sip_msg* msg, char* p1, char* format)
00729 {
00730 avp_ident_t* avpid;
00731 avp_value_t avp_val;
00732 struct search_state st;
00733 str xl_val;
00734 avp_t* avp;
00735
00736 avpid = &((fparam_t*)p1)->v.avp;
00737
00738 if (xl_printstr(msg, (xl_elog_t*) format, &xl_val.s, &xl_val.len) > 0) {
00739 for (avp = search_avp(*avpid, &avp_val, &st); avp; avp = search_next_avp(&st, &avp_val)) {
00740 if (avp->flags & AVP_VAL_STR) {
00741 if ((avp_val.s.len == xl_val.len) &&
00742 !memcmp(avp_val.s.s, xl_val.s, avp_val.s.len)) return 1;
00743 } else {
00744 if (avp_val.n == str2s(xl_val.s, xl_val.len, 0)) return 1;
00745 }
00746 }
00747 return -1;
00748 }
00749
00750 ERR("avp_equals_xl:Error while expanding xl_format\n");
00751 return -1;
00752 }
00753
00754
00755 static int get_xl_functions(void)
00756 {
00757 if (!xl_print) {
00758 xl_print=(xl_print_log_f*)find_export("xprint", NO_SCRIPT, 0);
00759
00760 if (!xl_print) {
00761 LOG(L_CRIT,"ERROR: cannot find \"xprint\", is module xlog loaded?\n");
00762 return -1;
00763 }
00764 }
00765
00766 if (!xl_parse) {
00767 xl_parse=(xl_parse_format_f*)find_export("xparse", NO_SCRIPT, 0);
00768
00769 if (!xl_parse) {
00770 LOG(L_CRIT,"ERROR: cannot find \"xparse\", is module xlog loaded?\n");
00771 return -1;
00772 }
00773 }
00774
00775 if (!xl_free) {
00776 xl_free=(xl_elog_free_all_f*)find_export("xfree", NO_SCRIPT, 0);
00777
00778 if (!xl_free) {
00779 LOG(L_CRIT,"ERROR: cannot find \"xfree\", is module xlog loaded?\n");
00780 return -1;
00781 }
00782 }
00783
00784 if (!xl_nul) {
00785 xl_getnul=(xl_get_nulstr_f*)find_export("xnulstr", NO_SCRIPT, 0);
00786 if (xl_getnul) {
00787 xl_nul=xl_getnul();
00788 }
00789
00790 if (!xl_nul){
00791 LOG(L_CRIT,"ERROR: cannot find \"xnulstr\", is module xlog loaded?\n");
00792 return -1;
00793 } else {
00794 LOG(L_INFO,"INFO: xlog null is \"%.*s\"\n", xl_nul->len, xl_nul->s);
00795 }
00796
00797 }
00798
00799 return 0;
00800 }
00801
00802
00803
00804
00805 static int fixup_xl_1(void** param, int param_no)
00806 {
00807 xl_elog_t* model;
00808
00809 if (get_xl_functions()) return -1;
00810
00811 if (param_no == 1) {
00812 if(*param) {
00813 if(xl_parse((char*)(*param), &model)<0) {
00814 LOG(L_ERR, "ERROR: xl_fixup: wrong format[%s]\n", (char*)(*param));
00815 return E_UNSPEC;
00816 }
00817
00818 *param = (void*)model;
00819 return 0;
00820 } else {
00821 LOG(L_ERR, "ERROR: xl_fixup: null format\n");
00822 return E_UNSPEC;
00823 }
00824 }
00825
00826 return 0;
00827 }
00828
00829 static int fixup_attr_1_xl_2(void** param, int param_no)
00830 {
00831 if (param_no == 1) {
00832 return avpid_fixup(param, 1);
00833 } else if (param_no == 2) {
00834 return fixup_xl_1(param, 1);
00835 }
00836 return 0;
00837 }
00838
00839
00840 static int xlset_attr(struct sip_msg* msg, char* p1, char* format)
00841 {
00842 avp_ident_t* avpid;
00843 avp_value_t val;
00844
00845 avpid = &((fparam_t*)p1)->v.avp;
00846
00847 if (xl_printstr(msg, (xl_elog_t*)format, &val.s.s, &val.s.len) > 0) {
00848 if (add_avp(avpid->flags | AVP_VAL_STR, avpid->name, val)) {
00849 ERR("xlset_attr:Error adding new AVP\n");
00850 return -1;
00851 }
00852 return 1;
00853 }
00854
00855 ERR("xlset_attr:Error while expanding xl_format\n");
00856 return -1;
00857 }
00858
00859
00860
00861
00862 static int xlfix_attr_fixup(void** param, int param_no)
00863 {
00864 if (get_xl_functions()) return -1;
00865
00866 if (param_no == 1)
00867 return avpid_fixup(param, 1);
00868
00869 return 0;
00870 }
00871
00872
00873 static int xlfix_attr(struct sip_msg* msg, char* p1, char* p2)
00874 {
00875 avp_t* avp;
00876 avp_ident_t* avpid;
00877 avp_value_t val;
00878 xl_elog_t* format=NULL;
00879 int ret=-1;
00880
00881 avpid = &((fparam_t*)p1)->v.avp;
00882
00883
00884 avp = search_avp(*avpid, &val, 0);
00885 if (!avp) {
00886 DBG("xlfix_attr: AVP does not exist\n");
00887 goto error;
00888 }
00889 if ((avp->flags & AVP_VAL_STR) == 0) {
00890 DBG("xlfix_attr: Not a string AVP\n");
00891 goto error;
00892 }
00893
00894
00895
00896 if (xl_parse(val.s.s, &format)<0) {
00897 LOG(L_ERR, "ERROR: xlfix_attr: wrong format[%s]\n", val.s.s);
00898 goto error;
00899 }
00900
00901 if (xl_printstr(msg, format, &val.s.s, &val.s.len) > 0) {
00902
00903 destroy_avp(avp);
00904 if (add_avp(avpid->flags | AVP_VAL_STR, avpid->name, val)) {
00905 ERR("xlfix_attr:Error adding new AVP\n");
00906 goto error;
00907 }
00908
00909 ret = 1;
00910 }
00911
00912 error:
00913
00914 if (format) xl_free(format);
00915
00916 return ret;
00917 }
00918
00919
00920 static int request_hf_helper(struct sip_msg* msg, str* hf, avp_ident_t* ident, struct lump* anchor, struct search_state* st, int front, int reverse, int reply)
00921 {
00922 struct lump* new_anchor;
00923 static struct search_state state;
00924 avp_t* avp;
00925 char* s;
00926 str fin_val;
00927 int len, ret;
00928 int_str val;
00929 struct hdr_field* pos, *found = NULL;
00930
00931 if (!anchor && !reply) {
00932
00933 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
00934 LOG(L_ERR, "ERROR: request_hf_helper: Error while parsing message\n");
00935 return -1;
00936 }
00937
00938 pos = msg->headers;
00939 while (pos && (pos->type != HDR_EOH_T)) {
00940 if ((hf->len == pos->name.len)
00941 && (!strncasecmp(hf->s, pos->name.s, pos->name.len))) {
00942 found = pos;
00943 if (front) {
00944 break;
00945 }
00946 }
00947 pos = pos->next;
00948 }
00949
00950 if (found) {
00951 if (front) {
00952 len = found->name.s - msg->buf;
00953 } else {
00954 len = found->name.s + found->len - msg->buf;
00955 }
00956 } else {
00957 len = msg->unparsed - msg->buf;
00958 }
00959
00960 new_anchor = anchor_lump(msg, len, 0, 0);
00961 if (new_anchor == 0) {
00962 LOG(L_ERR, "ERROR: request_hf_helper: Can't get anchor\n");
00963 return -1;
00964 }
00965 } else {
00966 new_anchor = anchor;
00967 }
00968
00969 if (!st) {
00970 st = &state;
00971 avp = search_avp(*ident, NULL, st);
00972 ret = -1;
00973 } else {
00974 avp = search_next_avp(st, NULL);
00975 ret = 1;
00976 }
00977
00978 if (avp) {
00979 if (reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) {
00980 return -1;
00981 }
00982
00983 get_avp_val(avp, &val);
00984 if (avp->flags & AVP_VAL_STR) {
00985 fin_val = val.s;
00986 } else {
00987 fin_val.s = int2str(val.n, &fin_val.len);
00988 }
00989
00990 len = hf->len + 2 + fin_val.len + 2;
00991 s = (char*)pkg_malloc(len);
00992 if (!s) {
00993 LOG(L_ERR, "ERROR: request_hf_helper: No memory left for data lump\n");
00994 return -1;
00995 }
00996
00997 memcpy(s, hf->s, hf->len);
00998 memcpy(s + hf->len, ": ", 2 );
00999 memcpy(s + hf->len+2, fin_val.s, fin_val.len );
01000 memcpy(s + hf->len + 2 + fin_val.len, CRLF, CRLF_LEN);
01001
01002 if (reply) {
01003 if (add_lump_rpl( msg, s, len, LUMP_RPL_HDR | LUMP_RPL_NODUP) == 0) {
01004 LOG(L_ERR, "ERROR: request_hf_helper: Can't insert RPL lump\n");
01005 pkg_free(s);
01006 return -1;
01007 }
01008 } else {
01009 if ((front && (insert_new_lump_before(new_anchor, s, len, 0) == 0))
01010 || (!front && (insert_new_lump_after(new_anchor, s, len, 0) == 0))) {
01011 LOG(L_ERR, "ERROR: request_hf_helper: Can't insert lump\n");
01012 pkg_free(s);
01013 return -1;
01014 }
01015 }
01016 if (!reverse && (request_hf_helper(msg, hf, ident, new_anchor, st, front, reverse, reply) == -1)) {
01017 return -1;
01018 }
01019 return 1;
01020 };
01021
01022
01023
01024 return ret;
01025 }
01026
01027
01028 static int fixup_str_1_attr_2(void** param, int param_no)
01029 {
01030 if (param_no == 1) {
01031 return fixup_var_str_12(param, 1);
01032 } else if (param_no == 2) {
01033 return avpid_fixup(param, 1);
01034 }
01035 return 0;
01036 }
01037
01038
01039 static int insert_req(struct sip_msg* msg, char* p1, char* p2)
01040 {
01041 avp_ident_t ident, *avp;
01042 str hf;
01043
01044 if (get_str_fparam(&hf, msg, (fparam_t*)p1) < 0) {
01045 ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p1)->orig);
01046 return -1;
01047 }
01048
01049 if (p2) {
01050 avp = &((fparam_t*)p2)->v.avp;
01051 } else {
01052 ident.name.s = hf;
01053 ident.flags = AVP_NAME_STR;
01054 ident.index = 0;
01055 avp = &ident;
01056 }
01057 return (request_hf_helper(msg, &hf, avp, NULL, NULL, 1, 0, 0));
01058 }
01059
01060
01061 static int append_req(struct sip_msg* msg, char* p1, char* p2)
01062 {
01063 avp_ident_t ident, *avp;
01064 str hf;
01065
01066 if (get_str_fparam(&hf, msg, (fparam_t*)p1) < 0) {
01067 ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p1)->orig);
01068 return -1;
01069 }
01070
01071 if (p2) {
01072 avp = &((fparam_t*)p2)->v.avp;
01073 } else {
01074 ident.name.s = hf;
01075 ident.flags = AVP_NAME_STR;
01076 ident.index = 0;
01077 avp = &ident;
01078 }
01079 return (request_hf_helper(msg, &hf, avp, NULL, NULL, 0, 1, 0));
01080 }
01081
01082
01083 static int replace_req(struct sip_msg* msg, char* p1, char* p2)
01084 {
01085 struct hdr_field* pos;
01086 str hf;
01087
01088 if (get_str_fparam(&hf, msg, (fparam_t*)p1) < 0) {
01089 ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p1)->orig);
01090 return -1;
01091 }
01092
01093 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
01094 LOG(L_ERR, "ERROR: replace_req: Error while parsing message\n");
01095 return -1;
01096 }
01097
01098 pos = msg->headers;
01099 while (pos && (pos->type != HDR_EOH_T)) {
01100 if (hf.len == pos->name.len
01101 && !strncasecmp(hf.s, pos->name.s, pos->name.len)) {
01102 if (del_lump(msg, pos->name.s - msg->buf, pos->len, 0) == 0) {
01103 LOG(L_ERR,"ERROR: Can't insert del lump\n");
01104 return -1;
01105 }
01106 }
01107 pos = pos->next;
01108 }
01109 return append_req(msg, p1, p2);
01110 }
01111
01112
01113 static int append_reply(struct sip_msg* msg, char* p1, char* p2)
01114 {
01115 avp_ident_t ident, *avp;
01116 str hf;
01117
01118 if (get_str_fparam(&hf, msg, (fparam_t*)p1) < 0) {
01119 ERR("Error while obtaining attribute value from '%s'\n", ((fparam_t*)p1)->orig);
01120 return -1;
01121 }
01122
01123 if (p2) {
01124 avp = &((fparam_t*)p2)->v.avp;
01125 } else {
01126 ident.name.s = hf;
01127 ident.flags = AVP_NAME_STR;
01128 ident.index = 0;
01129 avp = &ident;
01130 }
01131 return (request_hf_helper(msg, &hf, avp, NULL, NULL, 0, 1, 1));
01132 }
01133
01134
01135 static int set_destination(struct sip_msg* msg, str* dest)
01136 {
01137 name_addr_t nameaddr;
01138
01139 if (!parse_nameaddr(dest, &nameaddr)) {
01140 return set_dst_uri(msg, &nameaddr.uri);
01141 } else {
01142
01143 return set_dst_uri(msg, dest);
01144 }
01145 }
01146
01147
01148 static int attr_destination(struct sip_msg* msg, char* p1, char* p2)
01149 {
01150 avp_t* avp;
01151 avp_value_t val;
01152
01153 if ((avp = search_avp(((fparam_t*)p1)->v.avp, &val, NULL))) {
01154 if (avp->flags & AVP_VAL_STR) {
01155 if (set_destination(msg, &val.s)) {
01156 LOG(L_ERR, "ERROR: avp_destination: Can't set dst uri\n");
01157 return -1;
01158 };
01159
01160
01161 ruri_mark_new();
01162 return 1;
01163 } else {
01164 ERR("avp_destination:AVP has numeric value\n");
01165 return -1;
01166 }
01167 }
01168 return -1;
01169 }
01170
01171
01172 static int xlset_destination(struct sip_msg* msg, char* format, char* p2)
01173 {
01174 str val;
01175
01176 if (xl_printstr(msg, (xl_elog_t*) format, &val.s, &val.len) > 0) {
01177 DBG("Setting dest to: '%.*s'\n", val.len, val.s);
01178 if (set_destination(msg, &val) == 0) {
01179 return 1;
01180 }
01181 }
01182
01183 return -1;
01184 }
01185
01186
01187 static int attr_hdr_body2attrs(struct sip_msg* m, char* header_, char* prefix_)
01188 {
01189 char name_buf[50];
01190 str *prefix = (str*) prefix_;
01191 struct hdr_name *header = (void*) header_;
01192 struct hdr_field *hf;
01193 str s, name, val;
01194 int_str name2, val2;
01195 int val_type, arr;
01196 if (header->kind == HDR_STR) {
01197 if (parse_headers(m, HDR_EOH_F, 0) == -1) {
01198 LOG(L_ERR, "ERROR: attr_hdr_body2attrs: Error while parsing message\n");
01199 return -1;
01200 }
01201
01202 for (hf=m->headers; hf; hf=hf->next) {
01203 if ( (header->name.s.len == hf->name.len)
01204 && (!strncasecmp(header->name.s.s, hf->name.s, hf->name.len)) ) {
01205 break;
01206 }
01207 }
01208 }
01209 else {
01210 if (parse_headers(m, header->name.n, 0) == -1) {
01211 LOG(L_ERR, "ERROR: attr_hdr_body2attrs: Error while parsing message\n");
01212 return -1;
01213 }
01214 switch (header->name.n) {
01215
01216 default:
01217 hf = NULL;
01218 break;
01219 }
01220 }
01221 if (!hf || !hf->body.len)
01222 return 1;
01223
01224
01225 s = hf->body;
01226 name_buf[0] = '\0';
01227 while (s.len) {
01228 trim_leading(&s);
01229 name.s = s.s;
01230 while ( s.len &&
01231 ( (s.s[0] >= 'a' && s.s[0] <= 'z') ||
01232 (s.s[0] >= 'A' && s.s[0] <= 'Z') ||
01233 (s.s[0] >= '0' && s.s[0] <= '9') ||
01234 s.s[0] == '_' || s.s[0] == '-'
01235 ) ) {
01236 s.s++;
01237 s.len--;
01238 }
01239 if (s.s == name.s)
01240 break;
01241 name.len = s.s - name.s;
01242 trim_leading(&s);
01243 if (!s.len)
01244 break;
01245 if (s.s[0] == '=') {
01246 s.s++;
01247 s.len--;
01248 arr = -1;
01249
01250 while (s.len) {
01251 trim_leading(&s);
01252 val_type = 0;
01253 if (!s.len)
01254 break;
01255 if (s.s[0] == '"') {
01256 s.s++;
01257 s.len--;
01258 val.s = s.s;
01259
01260 s.s = q_memchr(s.s, '\"', s.len);
01261 if (!s.s)
01262 break;
01263 val.len = s.s - val.s;
01264 val_type = AVP_VAL_STR;
01265 s.s++;
01266 s.len -= s.s - val.s;
01267 }
01268 else {
01269 int r;
01270 val.s = s.s;
01271 if (s.s[0] == '+' || s.s[0] == '-') {
01272 s.s++;
01273 s.len--;
01274 }
01275 val2.n = 0; r = 0;
01276 while (s.len) {
01277 if (s.s[0] == header->field_delimiter || (header->array_delimiter && header->array_delimiter == s.s[0]))
01278 goto token_end;
01279 switch (s.s[0]) {
01280 case ' ':
01281 case '\t':
01282 case '\n':
01283 case '\r':
01284 goto token_end;
01285 }
01286 if (!val_type && s.s[0] >= '0' && s.s[0]<= '9') {
01287 r++;
01288 val2.n *= 10;
01289 val2.n += s.s[0] - '0';
01290
01291 }
01292 else {
01293 val_type = AVP_VAL_STR;
01294 }
01295 s.s++;
01296 s.len--;
01297 }
01298 token_end:
01299 if (r == 0) val_type = AVP_VAL_STR;
01300 if (!val_type && val.s[0] == '-') {
01301 val2.n = -val2.n;
01302 }
01303 val.len = s.s - val.s;
01304 }
01305 trim_leading(&s);
01306 if (arr >= 0 || (s.len && header->array_delimiter && header->array_delimiter == s.s[0])) {
01307 arr++;
01308 if (arr == 100)
01309 LOG(L_ERR, "ERROR: avp index out of limit\n");
01310 }
01311 if (val.len && arr < 100) {
01312 if (prefix != NULL || arr >= 0) {
01313 if ((prefix?prefix->len:0)+name.len+1+((arr>=0)?3:0) > sizeof(name_buf)) {
01314 if (arr <= 0)
01315 LOG(L_ERR, "ERROR: avp name too long\n");
01316 goto cont;
01317 }
01318 name2.s.len = 0;
01319 name2.s.s = name_buf;
01320 if (prefix != NULL) {
01321 if (name_buf[0] == '\0') {
01322 memcpy(&name_buf[0], prefix->s, prefix->len);
01323 }
01324 name2.s.len += prefix->len;
01325 }
01326 if (arr <= 0) {
01327 memcpy(&name_buf[name2.s.len], name.s, name.len);
01328 }
01329 name2.s.len += name.len;
01330 if (arr >= 0) {
01331 name_buf[name2.s.len] = '#';
01332 name2.s.len++;
01333 if (arr >= 10) {
01334 name_buf[name2.s.len] = '0'+ (arr / 10);
01335 name2.s.len++;
01336 }
01337 name_buf[name2.s.len] = '0'+ (arr % 10);
01338 name2.s.len++;
01339 }
01340 }
01341 else {
01342 name2.s.s = name.s;
01343 name2.s.len = name.len;
01344 }
01345 if ( ((val_type & AVP_VAL_STR) && (header->val_types & VAL_TYPE_STR)) ||
01346 ((val_type & AVP_VAL_STR) == 0 && (header->val_types & VAL_TYPE_INT)) ) {
01347 if (val_type) {
01348 val2.s.s = val.s;
01349 val2.s.len = val.len;
01350 DBG("DEBUG: attr_hdr_body2attrs: adding avp '%.*s', sval: '%.*s'\n", name2.s.len, (char*) name2.s.s, val.len, val.s);
01351 } else {
01352 DBG("DEBUG: attr_hdr_body2attrs: adding avp '%.*s', ival: '%d'\n", name2.s.len, (char*) name2.s.s, val2.n);
01353 }
01354 if ( add_avp(AVP_NAME_STR | val_type, name2, val2)!=0) {
01355 LOG(L_ERR, "ERROR: attr_hdr_body2attrs: add_avp failed\n");
01356 return 1;
01357 }
01358 }
01359 }
01360 cont:
01361 if (s.len && header->array_delimiter && header->array_delimiter == s.s[0]) {
01362 s.s++;
01363 s.len--;
01364 }
01365 else {
01366 break;
01367 }
01368 };
01369 }
01370 if (s.len && s.s[0] == header->field_delimiter) {
01371 s.s++;
01372 s.len--;
01373 }
01374 else {
01375 break;
01376 }
01377 }
01378 return 1;
01379 }
01380
01381
01382 static int attr_hdr_body2attrs2(struct sip_msg* msg, char* header_, char* prefix_)
01383 {
01384 return attr_hdr_body2attrs(msg, header_, prefix_);
01385 }
01386
01387
01388 static int attr_hdr_body2attrs_fixup(void** param, int param_no) {
01389 char *c, *params;
01390 struct hdr_name *h;
01391 int n;
01392 str *s;
01393 if (param_no == 1) {
01394 c = *param;
01395 if (*c == '#') {
01396 c++;
01397 n = strtol(c, ¶ms, 10);
01398 switch (*params) {
01399 case PARAM_DELIM:
01400 break;
01401 case 0:
01402 params = 0;
01403 break;
01404 default:
01405 LOG(L_ERR, "attr_hdr_body2attrs_fixup: bad AVP value\n");
01406 return E_CFG;
01407 }
01408 switch (n) {
01409
01410
01411
01412 default:
01413 LOG(L_ERR, "attr_hdr_body2attrs_fixup: header name is not valid and supported HDR_xxx id '%s' resolved as %d\n", c, n);
01414 return E_CFG;
01415 }
01416 h = pkg_malloc(sizeof(*h));
01417 if (!h) {
01418 LOG(L_ERR, "attr_hdr_body2attrs_fixup: out of memory\n");
01419 return E_OUT_OF_MEM;
01420 }
01421
01422 h->kind = HDR_ID;
01423 h->name.n = n;
01424 pkg_free(*param);
01425
01426 }
01427 else {
01428 params = strchr(c, PARAM_DELIM);
01429 if (params)
01430 n = params-c;
01431 else
01432 n = strlen(c);
01433 if (n == 0) {
01434 LOG(L_ERR, "attr_hdr_body2attrs_fixup: header name is empty\n");
01435 return E_CFG;
01436 }
01437 h = pkg_malloc(sizeof(*h)+n+1);
01438 if (!h) {
01439 LOG(L_ERR, "attr_hdr_body2attrs_fixup: out of memory\n");
01440 return E_OUT_OF_MEM;
01441 }
01442 h->kind = HDR_STR;
01443 h->name.s.len = n;
01444 h->name.s.s = (char *) h + sizeof(*h);
01445 memcpy(h->name.s.s, c, n+1);
01446 }
01447 if (params) {
01448 h->val_types = 0;
01449 while (*params) {
01450 switch (*params) {
01451 case 'i':
01452 case 'I':
01453 h->val_types = VAL_TYPE_INT;
01454 break;
01455 case 's':
01456 case 'S':
01457 h->val_types = VAL_TYPE_STR;
01458 break;
01459 case PARAM_DELIM:
01460 break;
01461 default:
01462 LOG(L_ERR, "attr_hdr_body2attrs_fixup: bad field param modifier near '%s'\n", params);
01463 return E_CFG;
01464 }
01465 params++;
01466 }
01467 if (!h->val_types) {
01468 LOG(L_ERR, "attr_hdr_body2attrs_fixup: no field param modifier specified\n");
01469 return E_CFG;
01470 }
01471 }
01472 else {
01473 h->val_types = VAL_TYPE_INT|VAL_TYPE_STR;
01474 }
01475 pkg_free(*param);
01476 h->field_delimiter = ',';
01477 h->array_delimiter = '\0';
01478
01479 *param = h;
01480 }
01481 else if (param_no == 2) {
01482 n = strlen(*param);
01483 if (n == 0) {
01484 s = NULL;
01485 }
01486 else {
01487 s = pkg_malloc(sizeof(*s)+n+1);
01488 if (!s) {
01489 LOG(L_ERR, "attr_hdr_body2attrs_fixup: out of memory\n");
01490 return E_OUT_OF_MEM;
01491 }
01492 s->len = n;
01493 s->s = (char *) s + sizeof(*s);
01494 memcpy(s->s, *param, n+1);
01495 }
01496 pkg_free(*param);
01497 *param = s;
01498 }
01499 return 0;
01500 }
01501
01502 static int attr_hdr_body2attrs2_fixup(void** param, int param_no)
01503 {
01504 struct hdr_name *h;
01505 int res = attr_hdr_body2attrs_fixup(param, param_no);
01506 if (res == 0 && param_no == 1) {
01507 h = *param;
01508 h->field_delimiter = ';';
01509 h->array_delimiter = ',';
01510 }
01511 return res;
01512 }
01513
01514
01515
01516 static int avpgroup_fixup(void** param, int param_no)
01517 {
01518 unsigned long flags;
01519 char* s;
01520
01521 if (param_no == 1) {
01522
01523 s = (char*)*param;
01524 flags = 0;
01525 if (*s != '$' || (strlen(s) != 3 && strlen(s) != 2)) {
01526 ERR("Invalid parameter value, $xy expected\n");
01527 return -1;
01528 }
01529 switch((s[1] << 8) + s[2]) {
01530 case 0x4655:
01531 case 0x6675:
01532 case 0x4675:
01533 case 0x6655:
01534 flags = AVP_TRACK_FROM | AVP_CLASS_USER;
01535 break;
01536
01537 case 0x4652:
01538 case 0x6672:
01539 case 0x4672:
01540 case 0x6652:
01541 flags = AVP_TRACK_FROM | AVP_CLASS_URI;
01542 break;
01543
01544 case 0x5455:
01545 case 0x7475:
01546 case 0x5475:
01547 case 0x7455:
01548 flags = AVP_TRACK_TO | AVP_CLASS_USER;
01549 break;
01550
01551 case 0x5452:
01552 case 0x7472:
01553 case 0x5472:
01554 case 0x7452:
01555 flags = AVP_TRACK_TO | AVP_CLASS_URI;
01556 break;
01557
01558 case 0x4644:
01559 case 0x6664:
01560 case 0x4664:
01561 case 0x6644:
01562 flags = AVP_TRACK_FROM | AVP_CLASS_DOMAIN;
01563 break;
01564
01565 case 0x5444:
01566 case 0x7464:
01567 case 0x5464:
01568 case 0x7444:
01569 flags = AVP_TRACK_TO | AVP_CLASS_DOMAIN;
01570 break;
01571
01572 case 0x6700:
01573 case 0x4700:
01574 flags = AVP_CLASS_GLOBAL;
01575 break;
01576
01577 default:
01578 ERR("Invalid parameter value: '%s'\n", s);
01579 return -1;
01580 }
01581
01582 pkg_free(*param);
01583 *param = (void*)flags;
01584 return 1;
01585 }
01586 return 0;
01587 }
01588
01589
01590
01591 static int select_attr_fixup(str* res, select_t* s, struct sip_msg* msg)
01592 {
01593 avp_ident_t *avp_ident;
01594
01595 #define SEL_PARAM_IDX 1
01596
01597 if (! msg) {
01598 str attr_name;
01599
01600 if (s->params[SEL_PARAM_IDX].type != SEL_PARAM_STR) {
01601 ERR("attribute name expected.\n");
01602 return -1;
01603 }
01604
01605 attr_name = s->params[SEL_PARAM_IDX].v.s;
01606 DEBUG("fix up for attribute '%.*s'\n", STR_FMT(&attr_name));
01607
01608 if (! (avp_ident = pkg_malloc(sizeof(avp_ident_t)))) {
01609 ERR("out of mem; requested: %d.\n", (int)sizeof(avp_ident_t));
01610 return -1;
01611 }
01612 memset(avp_ident, 0, sizeof(avp_ident_t));
01613
01614
01615 if ((1 < attr_name.len) && (attr_name.s[0] == '$')) {
01616 attr_name.len --;
01617 attr_name.s ++;
01618 }
01619 if (parse_avp_ident(&attr_name, avp_ident) < 0) {
01620 ERR("failed to parse attribute name: `%.*s'.\n", STR_FMT(&attr_name));
01621 pkg_free(avp_ident);
01622 }
01623 s->params[SEL_PARAM_IDX].v.p = avp_ident;
01624 s->params[SEL_PARAM_IDX].type = SEL_PARAM_PTR;
01625 } else {
01626 avp_t *ret;
01627 avp_value_t val;
01628
01629 #ifdef EXTRA_DEBUG
01630 assert(s->params[SEL_PARAM_IDX].type == SEL_PARAM_PTR);
01631 #endif
01632 avp_ident = s->params[SEL_PARAM_IDX].v.p;
01633 ret = search_first_avp(avp_ident->flags, avp_ident->name, &val, NULL);
01634 if (ret && ret->flags & AVP_VAL_STR)
01635 *res = val.s;
01636 }
01637
01638 return 0;
01639
01640 #undef SEL_PARAM_IDX
01641 }
01642
01643 SELECT_F(select_any_nameaddr)
01644 ABSTRACT_F(select_attr);
01645
01646 select_row_t sel_declaration[] = {
01647 { NULL, SEL_PARAM_STR, STR_STATIC_INIT("avp"), select_attr, SEL_PARAM_EXPECTED},
01648 { NULL, SEL_PARAM_STR, STR_STATIC_INIT("attr"), select_attr, SEL_PARAM_EXPECTED},
01649 { NULL, SEL_PARAM_STR, STR_STATIC_INIT("attribute"), select_attr, SEL_PARAM_EXPECTED},
01650 { select_attr, SEL_PARAM_STR, STR_NULL, select_attr_fixup, FIXUP_CALL | CONSUME_NEXT_STR},
01651
01652 { select_attr_fixup, SEL_PARAM_STR, STR_STATIC_INIT("nameaddr"), select_any_nameaddr, NESTED},
01653
01654 { NULL, SEL_PARAM_INT, STR_NULL, NULL, 0}
01655 };
01656
01657 static int mod_init()
01658 {
01659 DBG("%s - initializing\n", exports.name);
01660 return register_select_table(sel_declaration);
01661 }