try this:
# block expensive area codes if (uri=~"^sip:00355[0-9].*@.*" | uri=~"^sip:00358830[0-9].*@.*" | uri=~"^sip:001670.*@.*" | uri=~"^sip:001671.*@.*" | uri=~"^sip:00247[0-9].*@.*" ) { sl_send_reply("409", "Country not in plan"); break; };
regards Christian
Hi, thanks for the response. The problem i have is a lot of this destinations to block. Does someone knows a scalable method to do it? . I think that writing a hundred of this entry should be slow at lookup time?..
2006/7/10, CM0002@aol.com CM0002@aol.com:
try this:
# block expensive area codes if (uri=~"^sip:00355[0-9].*@.*" | uri=~"^sip:00358830[0-9].*@.*" | uri=~"^sip:001670.*@.*" | uri=~"^sip:001671.*@.*" | uri=~"^sip:00247[0-9].*@.*" ) { sl_send_reply("409", "Country not in plan"); break; };
regards Christian
You can do it with the avpops module and a little crafty-ness. I did something similar using this general logic.
Store patterns in the database that will satisfy the fm style matching of the avpops module (ie. "sip:00355*"), then load them with avp_db_load and then run over it with avp_check on $ruri/username using the fm operator and the g flag to check them all. If the avp_check succeeds then you block the call, if not let the call through.
-Evan
Robert Zorop wrote:
Hi, thanks for the response. The problem i have is a lot of this destinations to block. Does someone knows a scalable method to do it? . I think that writing a hundred of this entry should be slow at lookup time?..
2006/7/10, CM0002@aol.com CM0002@aol.com:
try this:
# block expensive area codes if (uri=~"^sip:00355[0-9].*@.*" | uri=~"^sip:00358830[0-9].*@.*" | uri=~"^sip:001670.*@.*" | uri=~"^sip:001671.*@.*" | uri=~"^sip:00247[0-9].*@.*" ) { sl_send_reply("409", "Country not in plan"); break; };
regards Christian
Serusers mailing list Serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Hi, thanks a lot for this clue. Can u please paste some of the ser.cfg where u do this!? I don't have an idea of how this work. I'll read about, but u'll help me a lot with some cfg example.
Thanks in advance. R
2006/7/10, Evan Borgström evan.borgstrom@ca.mci.com:
You can do it with the avpops module and a little crafty-ness. I
did something similar using this general logic.
Store patterns in the database that will satisfy the fm style
matching of the avpops module (ie. "sip:00355*"), then load them with avp_db_load and then run over it with avp_check on $ruri/username using the fm operator and the g flag to check them all. If the avp_check succeeds then you block the call, if not let the call through.
-Evan
Robert Zorop wrote:
Hi, thanks for the response. The problem i have is a lot of this destinations to block. Does someone knows a scalable method to do it? .
I
think that writing a hundred of this entry should be slow at lookup
time?..
2006/7/10, CM0002@aol.com CM0002@aol.com:
try this:
# block expensive area codes if (uri=~"^sip:00355[0-9].*@.*" | uri=~"^sip:00358830[0-9].*@.*" | uri=~"^sip:001670.*@.*" | uri=~"^sip:001671.*@.*" | uri=~"^sip:00247[0-9].*@.*" ) { sl_send_reply("409", "Country not in plan"); break; };
regards Christian
Serusers mailing list Serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Please note that current ser 0.9.x does not have the fm style matching. This was a small mod that was done to openser 0.9.4 (was it?) right before releasing (and that was never commited to ser). However, the ser 0.9.x avpops module can be replaced with the openser 0.9.4 avpops version. g-)
Evan Borgström wrote:
You can do it with the avpops module and a little crafty-ness. I did something similar using this general logic.
Store patterns in the database that will satisfy the fm style matching of the avpops module (ie. "sip:00355*"), then load them with avp_db_load and then run over it with avp_check on $ruri/username using the fm operator and the g flag to check them all. If the avp_check succeeds then you block the call, if not let the call through.
-Evan
Robert Zorop wrote:
Hi, thanks for the response. The problem i have is a lot of this destinations to block. Does someone knows a scalable method to do it? . I think that writing a hundred of this entry should be slow at lookup time?..
2006/7/10, CM0002@aol.com CM0002@aol.com:
try this:
# block expensive area codes if (uri=~"^sip:00355[0-9].*@.*" | uri=~"^sip:00358830[0-9].*@.*" | uri=~"^sip:001670.*@.*" | uri=~"^sip:001671.*@.*" | uri=~"^sip:00247[0-9].*@.*" ) { sl_send_reply("409", "Country not in plan"); break; };
regards Christian
Serusers mailing list Serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Serusers mailing list Serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Hi, please can someone post how the avp module could help with this?.
Christian, i think your idea works as well, but my problem is how to get diferent destinations blocked depending on the user, or IP the call is from.
2006/7/11, Greger V. Teigre greger@teigre.com:
Please note that current ser 0.9.x does not have the fm style matching. This was a small mod that was done to openser 0.9.4 (was it?) right before releasing (and that was never commited to ser). However, the ser 0.9.x avpops module can be replaced with the openser 0.9.4 avpops version. g-)
Evan Borgström wrote:
You can do it with the avpops module and a little crafty-ness. I did something similar using this general logic.
Store patterns in the database that will satisfy the fm style matching of the avpops module (ie. "sip:00355*"), then load them with avp_db_load and then run over it with avp_check on $ruri/username using the fm operator and the g flag to check them all. If the avp_check succeeds then you block the call, if not let the call through.
-Evan
Robert Zorop wrote:
Hi, thanks for the response. The problem i have is a lot of this destinations to block. Does someone knows a scalable method to do it? . I think that writing a hundred of this entry should be slow at lookup time?..
2006/7/10, CM0002@aol.com CM0002@aol.com CM0002@aol.com:
try this:
# block expensive area codes if (uri=~"^sip:00355[0-9].*@.*" <%5Esip:00355%5B0-9%5D.*@.*> | uri=~"^sip:00358830[0-9].*@.*" <%5Esip:00358830%5B0-9%5D.*@.*> | uri=~"^sip:001670.*@.*" <%5Esip:001670.*@.*> | uri=~"^sip:001671.*@.*" <%5Esip:001671.*@.*> | uri=~"^sip:00247[0-9].*@.*" <%5Esip:00247%5B0-9%5D.*@.*> ) { sl_send_reply("409", "Country not in plan"); break; };
regards Christian
Serusers mailing list Serusers@lists.iptel.orghttp://lists.iptel.org/mailman/listinfo/serusers
Serusers mailing list Serusers@lists.iptel.orghttp://lists.iptel.org/mailman/listinfo/serusers
To get the fm style matching you need to apply the attached patch before building the avpops module (it also adds the ability to check dst_ip, an unrelated but useful addition). Then in your usr_preferences table add a new item like so:
INSERT INTO usr_preferences (uuid, attribute, value) VALUES ('prefix_list', 'deny', '00355*');
Next add the following modparam to the avpops module:
modparam("avpops", "avp_aliases", "plval=i:100;plfm=i:101")
If you already have other aliases simply append these new ones to your existing list, finally when you want to check if you should block the call do the following:
if (avp_db_load("prefix_list", "s:deny")) { avp_write("$ruri/username", "$plval"); avp_copy("s:deny", "$plfm"); if (avp_check("$plval", "fm/$plfm/g")) { sl_send_reply("488", "Call Denied By Prefix List"); break; }; };
Writing $ruri/username & copying s:deny into aliases is the trick here and what took me the most time digging through the avp_check code to figure out. Once they're copied into aliases avp_check gladly checks them where as it spits out errors if you try to use either of the values as-is.
-Evan
Robert Zorop wrote:
Hi, please can someone post how the avp module could help with this?.
Christian, i think your idea works as well, but my problem is how to get diferent destinations blocked depending on the user, or IP the call is from.
2006/7/11, Greger V. Teigre greger@teigre.com:
Please note that current ser 0.9.x does not have the fm style matching. This was a small mod that was done to openser 0.9.4 (was it?) right before releasing (and that was never commited to ser). However, the ser 0.9.x avpops module can be replaced with the openser 0.9.4 avpops version. g-)
Evan Borgström wrote:
You can do it with the avpops module and a little crafty-ness. I did
something similar using this general logic.
Store patterns in the database that will satisfy the fm style
matching of the avpops module (ie. "sip:00355*"), then load them with avp_db_load and then run over it with avp_check on $ruri/username using the fm operator and the g flag to check them all. If the avp_check succeeds then you block the call, if not let the call through.
-Evan
Robert Zorop wrote:
Hi, thanks for the response. The problem i have is a lot of this destinations to block. Does someone knows a scalable method to do it? . I think that writing a hundred of this entry should be slow at lookup time?..
2006/7/10, CM0002@aol.com CM0002@aol.com CM0002@aol.com:
try this:
# block expensive area codes if (uri=~"^sip:00355[0-9].*@.*" <%5Esip:00355%5B0-9%5D.*@.*> | uri=~"^sip:00358830[0-9].*@.*" <%5Esip:00358830%5B0-9%5D.*@.*> | uri=~"^sip:001670.*@.*" <%5Esip:001670.*@.*> | uri=~"^sip:001671.*@.*" <%5Esip:001671.*@.*> | uri=~"^sip:00247[0-9].*@.*" <%5Esip:00247%5B0-9%5D.*@.*> ) { sl_send_reply("409", "Country not in plan"); break; };
regards Christian
Serusers mailing list Serusers@lists.iptel.orghttp://lists.iptel.org/mailman/listinfo/serusers
Serusers mailing list Serusers@lists.iptel.orghttp://lists.iptel.org/mailman/listinfo/serusers
--- rel_0_9_0/sip_router/modules/avpops/README 2004-11-15 05:19:39.000000000 -0500 +++ HEAD//sip_router/modules/avpops/README 2005-07-28 11:07:40.000000000 -0400 @@ -44,7 +44,8 @@ 1.4.5. avp_delete(name) 1.4.6. avp_pushto(destination,name) 1.4.7. avp_check(name,op_value) - 1.4.8. avp_print() + 1.4.8. avp_copy(old_name,new_name) + 1.4.9. avp_print()
1.5. Installation & Running
@@ -70,7 +71,8 @@ 1-16. avp_delete usage 1-17. avp_pushto usage 1-18. avp_check usage - 1-19. avp_print usage + 1-19. avp_copy usage + 1-20. avp_print usage _________________________________________________________
Chapter 1. User's Guide @@ -316,7 +318,7 @@ * value - the value to be written into the AVP. Parameter syntax: + value = (variable) | (fix_value) - + variable = '$src_ip' | + + variable = '$src_ip' | '$dst_ip' | '$hdr[name]' | (sip_uri)['/'('username'|'domain')]) + sip_uri = '$from' | '$to' | '$ruri' + fix_value = 'i:'integer | 's:'string | string @@ -329,6 +331,7 @@ avp_write("$to","i:678"); avp_write("$ruri/username","$email"); avp_write("$src_ip","s:ip"); +avp_write("$hdr[call-id]","i:11"); avp_write("i:333","i:6"); ... _________________________________________________________ @@ -363,7 +366,7 @@ SIP message. Parameter syntax: + destination = ruri_dst | hdr_dst + ruri_dst = '$ruri'['/'('username'|'domain')] - + hdr_dst = 'hdr_name'['/'('request'|'reply')] + + hdr_dst = '$hdr_name'['/'('request'|'reply')] * name - which AVP(s) should be pushed into the SIP message. Parameter syntax is: + name = ( avp_name | avp_alias )['/'flags] @@ -373,8 +376,8 @@ ... avp_pushto("$ruri","i:678"); avp_pushto("$ruri/domain","s:backup_domains/g"); -avp_pushto("Email/reply","s:email"); -avp_pushto("Foo","$bar/g"); +avp_pushto("$Email/reply","s:email"); +avp_pushto("$Foo","$bar/g"); ... _________________________________________________________
@@ -390,10 +393,10 @@ * op_value - define the operator, the value and flags for checking. Parameter syntax is: + op_value = operator '/' value ['/'flags] - + operator = 'eq' | 'lt' | 'gt' | 're' + + operator = 'eq' | 'lt' | 'gt' | 're' | 'fm' + value = variable | fix_value + variable = - '$from'|'$ruri'|'$from'|'$src_ip'|avp_alias + '$from'|'$ruri'|'$from'|'$src_ip'|'$dst_ip'|avp_alias + fix_value = 'i:'integer | 's:'string | string + flags = 'g' | 'G' | 'i' | 'I'
@@ -403,15 +406,37 @@ avp_check("s:person","eq/$from/I"); avp_check("s:foo","gt/$bar/g"); avp_check("s:foo","re/sip:.*@bar.net/g"); +avp_check("s:foo","fm/$fm_avp/g"); ... _________________________________________________________
-1.4.8. avp_print() +1.4.8. avp_copy(old_name,new_name) + + Copy / move an avp under a new name. + + Meaning of the parameters is as follows: + + * name1 - which AVP(s) should be copied/moved. Parameter + syntax is: + + name = ( avp_name | avp_alias ) + * name2 - the new name of the copied/moved AVP(s). Parameter + syntax is: + + name = ( avp_name | avp_alias ) ['/'flags] + + flags = 'g' | 'G' | 'd' | 'D' + + Example 1-19. avp_copy usage +... +avp_copy("i:678", "s:345/g"); +avp_copy("$old","$new/gd"); +... + _________________________________________________________ + +1.4.9. avp_print()
Prints the list with all the AVPs from memory. This is only a helper/debug function.
- Example 1-19. avp_print usage + Example 1-20. avp_print usage ... avp_print(); ... --- rel_0_9_0/sip_router/modules/avpops/avpops.c 2005-01-20 05:01:37.000000000 -0500 +++ HEAD//sip_router/modules/avpops/avpops.c 2005-07-28 11:07:40.000000000 -0400 @@ -1,5 +1,5 @@ /* - * $Id: avpops.c,v 1.6.2.1 2005/01/20 10:01:37 ramona Exp $ + * $Id: avpops.c,v 1.10 2005/07/04 10:44:38 ramona Exp $ * * Copyright (C) 2004 Voice Sistem SRL * @@ -29,6 +29,8 @@ * 2004-10-04 first version (ramona) * 2004-11-15 added support for db schemes for avp_db_load (ramona) * 2004-11-17 aligned to new AVP core global aliases (ramona) + * 2005-01-30 "fm" (fast match) operator added (ramona) + * 2005-01-30 avp_copy (copy/move operation) added (ramona) */
@@ -40,6 +42,7 @@
#include "../../mem/shm_mem.h" #include "../../mem/mem.h" +#include "../../parser/parse_hname2.h" #include "../../sr_module.h" #include "../../str.h" #include "../../dprint.h" @@ -70,6 +73,7 @@ static int fixup_delete_avp(void** param, int param_no); static int fixup_pushto_avp(void** param, int param_no); static int fixup_check_avp(void** param, int param_no); +static int fixup_copy_avp(void** param, int param_no);
static int w_dbload_avps(struct sip_msg* msg, char* source, char* param); static int w_dbstore_avps(struct sip_msg* msg, char* source, char* param); @@ -78,6 +82,7 @@ static int w_delete_avps(struct sip_msg* msg, char* param, char *foo); static int w_pushto_avps(struct sip_msg* msg, char* destination, char *param); static int w_check_avps(struct sip_msg* msg, char* param, char *check); +static int w_copy_avps(struct sip_msg* msg, char* param, char *check); static int w_print_avps(struct sip_msg* msg, char* foo, char *bar);
@@ -100,6 +105,8 @@ REQUEST_ROUTE|FAILURE_ROUTE}, {"avp_check", w_check_avps, 2, fixup_check_avp, REQUEST_ROUTE|FAILURE_ROUTE}, + {"avp_copy", w_copy_avps, 2, fixup_copy_avp, + REQUEST_ROUTE|FAILURE_ROUTE}, {"avp_print", w_print_avps, 0, 0, REQUEST_ROUTE|FAILURE_ROUTE}, {0, 0, 0, 0, 0} @@ -351,8 +358,10 @@
static int fixup_write_avp(void** param, int param_no) { + struct hdr_field hdr; struct fis_param *ap; int flags; + int len; char *s; char *p;
@@ -368,7 +377,7 @@ if ((++s)==0) { LOG(L_ERR,"ERROR:avops:fixup_write_avp: bad param 1; " - "expected : $[from|to|ruri] or int/str value\n"); + "expected : $[from|to|ruri|hdr] or int/str value\n"); return E_UNSPEC; } if ( (p=strchr(s,'/'))!=0) @@ -376,7 +385,9 @@ if ( (!strcasecmp( "from", s) && (flags|=AVPOPS_USE_FROM)) || (!strcasecmp( "to", s) && (flags|=AVPOPS_USE_TO)) || (!strcasecmp( "ruri", s) && (flags|=AVPOPS_USE_RURI)) - || (!strcasecmp( "src_ip", s) && (flags|=AVPOPS_USE_SRC_IP)) ) + || (!strcasecmp( "src_ip", s) && (flags|=AVPOPS_USE_SRC_IP)) + || (!strcasecmp( "dst_ip", s) && (flags|=AVPOPS_USE_DST_IP)) + || (!strncasecmp( "hdr", s, 3) && (flags|=AVPOPS_USE_HDRREQ)) ) { ap = (struct fis_param*)pkg_malloc(sizeof(struct fis_param)); if (ap==0) @@ -387,14 +398,52 @@ } memset( ap, 0, sizeof(struct fis_param)); /* any falgs ? */ - if ( p && !( (flags&AVPOPS_USE_SRC_IP)==0 && ( - (!strcasecmp("username",p) && (flags|=AVPOPS_FLAG_USER)) || + if(p && !((flags& + (AVPOPS_USE_SRC_IP|AVPOPS_USE_DST_IP|AVPOPS_USE_HDRREQ))==0 + && ((!strcasecmp("username",p) && (flags|=AVPOPS_FLAG_USER)) || (!strcasecmp("domain", p) && (flags|=AVPOPS_FLAG_DOMAIN)))) ) { LOG(L_ERR,"ERROR:avpops:fixup_write_avp: flag "%s"" " unknown!\n", p); return E_UNSPEC; } + if (flags&AVPOPS_USE_HDRREQ) + { + len = strlen(s); + if (len<6 || s[3]!='[' || s[len-1]!=']') + { + LOG(L_ERR,"ERROR:avpops:fixup_write_avp: invalid hdr " + "specificatoin "%s"\n",s); + return E_UNSPEC; + } + s[len-1] = ':'; + /* parse header name */ + if (parse_hname2( s+4, s+len, &hdr)==0) { + LOG(L_ERR,"BUG:avpops:fixup_write_avp: parse header " + "failed\n"); + return E_UNSPEC; + } + if (hdr.type==HDR_OTHER) { + /* duplicate hdr name */ + len -= 5; /*hdr[]*/ + ap->val.s = (str*)pkg_malloc(sizeof(str)+len+1); + if (ap->val.s==0) + { + LOG(L_ERR,"ERROR:avpops:fixup_write_avp: no more " + "pkg mem\n"); + return E_OUT_OF_MEM; + } + ap->val.s->s = ((char*)(ap->val.s)) + sizeof(str); + ap->val.s->len = len; + memcpy( ap->val.s->s, s+4, len); + ap->val.s->s[len] = 0; + DBG("DEBUF:avpops:fixup_write_avp: hdr=<%s>\n", + ap->val.s->s); + } else { + ap->val.n = hdr.type; + flags |= AVPOPS_VAL_INT; + } + } ap->flags = flags|AVPOPS_VAL_NONE; } else { LOG(L_ERR,"ERROR:avpops:fixup_write_avp: source "%s"" @@ -617,7 +666,7 @@ { if ( (ap->flags&AVPOPS_VAL_STR)==0 ) { - LOG(L_ERR,"ERROR:avpops:fixup_check_avp: regexp operation" + LOG(L_ERR,"ERROR:avpops:fixup_check_avp: regexp operation " "requires string value\n"); return E_UNSPEC; } @@ -639,6 +688,74 @@ /* free the string and link the regexp */ pkg_free(ap->val.s); ap->val.s = (str*)re; + } else if (ap->flags&AVPOPS_OP_FM) { + if ( !( ap->flags&AVPOPS_VAL_AVP || + (!(ap->flags&AVPOPS_VAL_AVP) && ap->flags&AVPOPS_VAL_STR) ) ) + { + LOG(L_ERR,"ERROR:avpops:fixup_check_avp: fast_match operation " + "requires string value or avp name/alias (%d)\n", + ap->flags); + return E_UNSPEC; + } + } + } + + pkg_free(*param); + *param=(void*)ap; + return 0; +} + + +static int fixup_copy_avp(void** param, int param_no) +{ + struct fis_param *ap; + char *s; + char *p; + + s = (char*)*param; + ap = 0; + p = 0; + + if (param_no==2) + { + /* avp / flags */ + if ( (p=strchr(s,'/'))!=0 ) + *(p++)=0; + } + + if ( (ap=get_attr_or_alias(s))==0 ) + { + LOG(L_ERR,"ERROR:avpops:fixup_copy_avp: bad attribute name" + "/alias <%s>\n", (char*)*param); + return E_UNSPEC; + } + /* attr name is mandatory */ + if (ap->flags&AVPOPS_VAL_NONE) + { + LOG(L_ERR,"ERROR:avpops:fixup_copy_avp: you must specify " + "a name for the AVP\n"); + return E_UNSPEC; + } + + if (param_no==2) + { + /* flags */ + for( ; p&&*p ; p++ ) + { + switch (*p) { + case 'g': + case 'G': + ap->flags|=AVPOPS_FLAG_ALL; + break; + case 'd': + case 'D': + ap->flags|=AVPOPS_FLAG_DELETE; + break; + default: + LOG(L_ERR,"ERROR:avpops:fixup_copy_avp: bad flag " + "<%c>\n",*p); + return E_UNSPEC; + } } }
@@ -695,6 +812,12 @@ (struct fis_param*)check); }
+static int w_copy_avps(struct sip_msg* msg, char* name1, char *name2) +{ + return ops_copy_avp ( msg, (struct fis_param*)name1, + (struct fis_param*)name2); +} + static int w_print_avps(struct sip_msg* msg, char* foo, char *bar) { return ops_print_avp(); --- rel_0_9_0/sip_router/modules/avpops/avpops_impl.c 2004-11-15 05:19:39.000000000 -0500 +++ HEAD//sip_router/modules/avpops/avpops_impl.c 2005-07-28 11:07:40.000000000 -0400 @@ -1,5 +1,5 @@ /* - * $Id: avpops_impl.c,v 1.5 2004/11/15 10:19:39 ramona Exp $ + * $Id: avpops_impl.c,v 1.11 2005/07/04 10:44:38 ramona Exp $ * * Copyright (C) 2004 Voice Sistem SRL * @@ -27,12 +27,15 @@ * History: * --------- * 2004-10-04 first version (ramona) + * 2005-01-30 "fm" (fast match) operator added (ramona) + * 2005-01-30 avp_copy (copy/move operation) added (ramona) */
#include <stdlib.h> #include <string.h> #include <sys/types.h> #include <regex.h> +#include <fnmatch.h>
#include "../../ut.h" #include "../../dprint.h" @@ -546,6 +549,34 @@ }
+static inline str *search_hdr(struct sip_msg* msg, struct fis_param *hdr_def) +{ + static str body; + struct hdr_field *hdr; + + /* parse all HDRs */ + if (parse_headers( msg, HDR_EOH, 0)!=0) { + LOG(L_ERR,"ERROR:tm:append2buf: parsing hdrs failed\n"); + return 0; + } + /* search the HDR */ + if (hdr_def->flags&AVPOPS_VAL_INT) { + for(hdr=msg->headers;hdr;hdr=hdr->next) + if (hdr_def->val.n==hdr->type) + goto found; + } else { + for(hdr=msg->headers;hdr;hdr=hdr->next) + if (hdr_def->val.s->len==hdr->name.len && + strncasecmp( hdr_def->val.s->s, hdr->name.s, hdr->name.len)==0) + goto found; + } + return 0; +found: + /* trim the body */ + trim_len( body.len, body.s, hdr->body ); + return &body; +} +
int ops_write_avp(struct sip_msg* msg, struct fis_param *src, struct fis_param *ap) @@ -567,6 +598,21 @@ } s_ip.len = strlen(s_ip.s); avp_val.s = &s_ip; + } else if (src->flags&AVPOPS_USE_DST_IP) { + /* get data from dst ip */ + if ( (s_ip.s=ip_addr2a( &msg->rcv.dst_ip ))==0) + { + LOG(L_ERR,"ERROR:avpops:write_avp: cannot get dst_ip\n"); + goto error; + } + s_ip.len = strlen(s_ip.s); + avp_val.s = &s_ip; + } else if (src->flags&(AVPOPS_USE_HDRREQ|AVPOPS_USE_HDRRPL)) { + /* get data from hdr */ + if ( (avp_val.s=search_hdr(msg,src))==0 ) { + DBG("DEBUG:avpops:write_avp: hdr not found\n"); + goto error; + } } else { /* get data from uri (from,to,ruri) */ if (src->flags&(AVPOPS_FLAG_USER|AVPOPS_FLAG_DOMAIN)) @@ -780,7 +826,7 @@ { /* if is not the first modification, push the current uri as * branch */ - if (append_branch( msg, 0, 0, 0, 0, 0)!=1 ) + if (append_branch( msg, 0, 0, 0, 0, Q_UNSPECIFIED)!=1 ) { LOG(L_ERR,"ERROR:avpops:pushto_avp: append_branch action" " failed\n"); @@ -865,6 +911,11 @@ /* the 2nd operator is an avp name -> get avp val */ name_type = (((val->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR); avp2 = search_first_avp( name_type, val->val, &ck_val); + if (avp2==0) + { + DBG("DEBUG:avpops:check_avp: no avp2 found to check\n"); + goto error; + } ck_flg = avp2->flags&AVP_VAL_STR?AVPOPS_VAL_STR:AVPOPS_VAL_INT; } else { ck_val = val->val; @@ -898,6 +949,15 @@ } s_ip.len = strlen(s_ip.s); ck_val.s = &s_ip; + } else if (val->flags&AVPOPS_USE_DST_IP) { + /* get value from dst ip */ + if ( (s_ip.s=ip_addr2a( &msg->rcv.dst_ip ))==0) + { + LOG(L_ERR,"ERROR:avpops:check_avp: cannot get dst_ip\n"); + goto error; + } + s_ip.len = strlen(s_ip.s); + ck_val.s = &s_ip; } else { /* get value from uri */ if ( (ck_val.s=get_source_uri(msg,val->flags))==0 ) @@ -936,6 +996,9 @@ } else if (val->flags&AVPOPS_OP_RE) { if (regexec((regex_t*)ck_val.s, avp_val.s->s, 1, &pmatch, 0)==0) return 1; + } else if (val->flags&AVPOPS_OP_FM){ + if (fnmatch( ck_val.s->s, avp_val.s->s, 0)==0) + return 1; } else { LOG(L_CRIT,"BUG:avpops:check_avp: unknown operation " "(flg=%d)\n",val->flags); @@ -981,6 +1044,55 @@
+int ops_copy_avp( struct sip_msg* msg, struct fis_param* name1, + struct fis_param* name2) +{ + struct usr_avp *avp; + struct usr_avp *prev_avp; + int_str avp_val; + unsigned short name_type1; + unsigned short name_type2; + int n; + + n = 0; + prev_avp = 0; + + /* avp name is known ->search by name */ + name_type1 = (((name1->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR); + name_type2 = (((name2->flags&AVPOPS_VAL_INT))?0:AVP_NAME_STR); + + avp = search_first_avp( name_type1, name1->val, &avp_val); + while ( avp ) + { + /* build a new avp with new name, but old value */ + if ( add_avp( name_type2|(avp->flags&AVP_VAL_STR), name2->val, + avp_val)==-1 ) { + LOG(L_ERR,"ERROR:avpops:copy_avp: failed to create new avp\n"); + goto error; + } + n++; + /* copy all avps? */ + if ( !(name2->flags&AVPOPS_FLAG_ALL) ) { + /* delete the old one? */ + if (name2->flags&AVPOPS_FLAG_DELETE) + destroy_avp( avp ); + break; + } else { + prev_avp = avp; + avp = search_next_avp( prev_avp, &avp_val); + /* delete the old one? */ + if (name2->flags&AVPOPS_FLAG_DELETE) + destroy_avp( prev_avp ); + } + } + + return n?1:-1; +error: + return -1; +} + + + int ops_print_avp() { struct usr_avp **avp_list; --- rel_0_9_0/sip_router/modules/avpops/avpops_impl.h 2004-11-15 05:19:39.000000000 -0500 +++ HEAD//sip_router/modules/avpops/avpops_impl.h 2005-07-28 11:07:40.000000000 -0400 @@ -1,5 +1,5 @@ /* - * $Id: avpops_impl.h,v 1.3 2004/11/15 10:19:39 ramona Exp $ + * $Id: avpops_impl.h,v 1.5 2005/07/04 10:44:38 ramona Exp $ * * Copyright (C) 2004 Voice Sistem SRL * @@ -64,18 +64,21 @@ #define AVPOPS_USE_HDRREQ (1<<10) #define AVPOPS_USE_HDRRPL (1<<11) #define AVPOPS_USE_SRC_IP (1<<12) +#define AVPOPS_USE_DST_IP (1<<13)
/* flags about operation 16..23 */ #define AVPOPS_OP_EQ (1<<16) #define AVPOPS_OP_LT (1<<17) #define AVPOPS_OP_GT (1<<18) #define AVPOPS_OP_RE (1<<19) +#define AVPOPS_OP_FM (1<<20)
/* flags for flags 24..31 */ #define AVPOPS_FLAG_ALL (1<<24) #define AVPOPS_FLAG_CI (1<<25) #define AVPOPS_FLAG_USER (1<<26) #define AVPOPS_FLAG_DOMAIN (1<<27) +#define AVPOPS_FLAG_DELETE (1<<28)
/* container structer for Flag+Int_Str_value parameter */ @@ -117,6 +120,9 @@ int ops_check_avp( struct sip_msg* msg, struct fis_param* param, struct fis_param* check);
+int ops_copy_avp( struct sip_msg* msg, struct fis_param* name1, + struct fis_param* name2); + int ops_print_avp();
#endif --- rel_0_9_0/sip_router/modules/avpops/avpops_parse.c 2005-01-12 08:41:47.000000000 -0500 +++ HEAD//sip_router/modules/avpops/avpops_parse.c 2005-07-28 11:07:40.000000000 -0400 @@ -1,5 +1,5 @@ /* - * $Id: avpops_parse.c,v 1.8.2.1 2005/01/12 13:41:47 ramona Exp $ + * $Id: avpops_parse.c,v 1.11 2005/07/04 10:44:38 ramona Exp $ * * Copyright (C) 2004 Voice Sistem SRL * @@ -234,7 +234,7 @@ { LOG(L_ERR,"ERROR:avpops:parse_avp_db: scheme <%s> not found\n", tmp.s); - goto error;; + goto error; } /* update scheme flags with AVP name type*/ dbp->scheme->db_flags|=dbp->a.flags&AVPOPS_VAL_STR?AVP_NAME_STR:0; @@ -244,7 +244,7 @@ if (dbp->table==0) { LOG(L_ERR,"ERROR:avpops:parse_avp_db: no more pkg mem\n"); - goto error; + goto error;; } memcpy( dbp->table, tmp.s, tmp.len); dbp->table[tmp.len] = 0; @@ -355,6 +355,8 @@ flags |= AVPOPS_OP_GT; } else if (strncasecmp(s,"re",2)==0) { flags |= AVPOPS_OP_RE; + } else if (strncasecmp(s,"fm",2)==0) { + flags |= AVPOPS_OP_FM; } else { LOG(L_ERR,"ERROR:avpops:parse_check_value: unknown operation " "<%.*s>\n",2,s); @@ -383,7 +385,8 @@ if ( (strncasecmp(p,"ruri" ,len)==0 && (flags|=AVPOPS_USE_RURI)) || (strncasecmp(p,"from" ,len)==0 && (flags|=AVPOPS_USE_FROM)) || (strncasecmp(p,"to" ,len)==0 && (flags|=AVPOPS_USE_TO)) - || (strncasecmp(p,"src_ip",len)==0 && (flags|=AVPOPS_USE_SRC_IP))) + || (strncasecmp(p,"src_ip",len)==0 && (flags|=AVPOPS_USE_SRC_IP)) + || (strncasecmp(p,"dst_ip",len)==0 && (flags|=AVPOPS_USE_DST_IP))) { flags |= AVPOPS_VAL_NONE; } else {