Exemple #1
0
static int fixup_subst(void** param, int param_no)
{
	struct subst_expr* se;
	str subst;
	struct fis_param *ap;
	struct fis_param **av;
	char *s;
	char *p;

	if (param_no==1) {
		s = (char*)*param;
		ap = 0;
		p = 0;
		av = (struct fis_param**)pkg_malloc(2*sizeof(struct fis_param*));
		if(av==NULL)
		{
			LM_ERR("no more pkg memory\n");
			return E_UNSPEC;
		}
		memset(av, 0, 2*sizeof(struct fis_param*));

		/* avp src / avp dst /flags */
		if ( (p=strchr(s,'/'))!=0 )
			*(p++)=0;
		ap = avpops_parse_pvar(s);
		if (ap==0)
		{
			LM_ERR("unable to get pseudo-variable in param 2 [%s]\n", s);
			return E_OUT_OF_MEM;
		}
		if (ap->u.sval.type!=PVT_AVP)
		{
			LM_ERR("bad attribute name <%s>\n", (char*)*param);
			pkg_free(av);
			return E_UNSPEC;
		}
		/* attr name is mandatory */
		if (ap->opd&AVPOPS_VAL_NONE)
		{
			LM_ERR("you must specify a name for the AVP\n");
			return E_UNSPEC;
		}
		av[0] = ap;
		if(p==0 || *p=='\0')
		{
			*param=(void*)av;
			return 0;
		}

		/* dst || flags */
		s = p;
		if(*s==PV_MARKER)
		{
			if ( (p=strchr(s,'/'))!=0 )
				*(p++)=0;
			if(p==0 || (p!=0 && p-s>1))
			{
				ap = avpops_parse_pvar(s);
				if (ap==0)
				{
					LM_ERR("unable to get pseudo-variable in param 2 [%s]\n",s);
					return E_OUT_OF_MEM;
				}

				if (ap->u.sval.type!=PVT_AVP)
				{
					LM_ERR("bad attribute name <%s>!\n", s);
					pkg_free(av);
					return E_UNSPEC;
				}
				/* attr name is mandatory */
				if (ap->opd&AVPOPS_VAL_NONE)
				{
					LM_ERR("you must specify a name for the AVP!\n");
					return E_UNSPEC;
				}
				av[1] = ap;
			}
			if(p==0 || *p=='\0')
			{
				*param=(void*)av;
				return 0;
			}
		}

		/* flags */
		for( ; p&&*p ; p++ )
		{
			switch (*p) {
				case 'g':
				case 'G':
					av[0]->ops|=AVPOPS_FLAG_ALL;
					break;
				case 'd':
				case 'D':
					av[0]->ops|=AVPOPS_FLAG_DELETE;
					break;
				default:
					LM_ERR("bad flag <%c>\n",*p);
					return E_UNSPEC;
			}
		}
		*param=(void*)av;
	} else if (param_no==2) {
		LM_DBG("%s fixing %s\n", exports.name, (char*)(*param));
		subst.s=*param;
		subst.len=strlen(*param);
		se=subst_parser(&subst);
		if (se==0){
			LM_ERR("%s: bad subst re %s\n",exports.name, (char*)*param);
			return E_BAD_RE;
		}
		/* don't free string -- needed for specifiers */
		/* pkg_free(*param); */
		/* replace it with the compiled subst. re */
		*param=se;
	}

	return 0;
}
Exemple #2
0
static int fixup_op_avp(void** param, int param_no)
{
	struct fis_param *ap;
	struct fis_param **av;
	char *s;
	char *p;

	s = (char*)*param;
	ap = 0;

	if (param_no==1)
	{
		av = (struct fis_param**)pkg_malloc(2*sizeof(struct fis_param*));
		if(av==NULL)
		{
			LM_ERR("no more pkg memory\n");
			return E_UNSPEC;
		}
		memset(av, 0, 2*sizeof(struct fis_param*));
		/* avp src / avp dst */
		if ( (p=strchr(s,'/'))!=0 )
			*(p++)=0;

		av[0] = avpops_parse_pvar(s);
		if (av[0]==0)
		{
			LM_ERR("unable to get pseudo-variable in param 1\n");
			return E_OUT_OF_MEM;
		}
		if (av[0]->u.sval.type!=PVT_AVP)
		{
			LM_ERR("bad attribute name <%s>\n", (char*)*param);
			pkg_free(av);
			return E_UNSPEC;
		}
		if(p==0 || *p=='\0')
		{
			*param=(void*)av;
			return 0;
		}

		s = p;
		ap = avpops_parse_pvar(s);
		if (ap==0)
		{
			LM_ERR("unable to get pseudo-variable in param 1 (2)\n");
			return E_OUT_OF_MEM;
		}
		if (ap->u.sval.type!=PVT_AVP)
		{
			LM_ERR("bad attribute name/alias <%s>!\n", s);
			pkg_free(av);
			return E_UNSPEC;
		}
		av[1] = ap;
		*param=(void*)av;
		return 0;
	} else if (param_no==2) {
		if ( (ap=parse_op_value(s))==0 )
		{
			LM_ERR("failed to parse the value \n");
			return E_UNSPEC;
		}
		/* only integer values or avps */
		if ( (ap->opd&AVPOPS_VAL_STR)!=0 && (ap->opd&AVPOPS_VAL_PVAR)==0)
		{
			LM_ERR("operations requires integer values\n");
			return E_UNSPEC;
		}
		*param=(void*)ap;
		return 0;
	}
	return -1;
}
Exemple #3
0
static int fixup_pushto_avp(void** param, int param_no)
{
	struct fis_param *ap;
	char *s;
	char *p;

	s = (char*)*param;
	ap = 0;

	if (param_no==1)
	{
		if ( *s!='$')
		{
			LM_ERR("bad param 1; expected : $ru $du ...\n");
			return E_UNSPEC;
		}
		/* compose the param structure */

		if ( (p=strchr(s,'/'))!=0 )
			*(p++)=0;
		ap = avpops_parse_pvar(s);
		if (ap==0)
		{
			LM_ERR("unable to get pseudo-variable in param 1\n");
			return E_OUT_OF_MEM;
		}

		switch(ap->u.sval.type) {
			case PVT_RURI:
				ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_RURI;
				if ( p && !(
					(!strcasecmp("username",p)
							&& (ap->opd|=AVPOPS_FLAG_USER0)) ||
					(!strcasecmp("domain",p)
							&& (ap->opd|=AVPOPS_FLAG_DOMAIN0)) ))
				{
					LM_ERR("unknown ruri flag \"%s\"!\n",p);
					return E_UNSPEC;
				}
			break;
			case PVT_DSTURI:
				if ( p!=0 )
				{
					LM_ERR("unknown duri flag \"%s\"!\n",p);
					return E_UNSPEC;
				}
				ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_DURI;
			break;
			case PVT_HDR:
				/* what's the hdr destination ? request or reply? */
				LM_ERR("push to header is obsolete - use append_hf() "
						"or append_to_reply() from textops module!\n");
				return E_UNSPEC;
			break;
			case PVT_BRANCH:
				if ( p!=0 )
				{
					LM_ERR("unknown branch flag \"%s\"!\n",p);
					return E_UNSPEC;
				}
				ap->opd = AVPOPS_VAL_NONE|AVPOPS_USE_BRANCH;
			break;
			default:
				LM_ERR("unsupported destination \"%s\"; "
						"expected $ru,$du,$br\n",s);
				return E_UNSPEC;
		}
	} else if (param_no==2) {
		/* attribute name*/
		if ( *s!='$')
		{
			LM_ERR("bad param 1; expected :$pseudo-variable ...\n");
			return E_UNSPEC;
		}
		/* compose the param structure */

		if ( (p=strchr(s,'/'))!=0 )
			*(p++)=0;
		ap = avpops_parse_pvar(s);
		if (ap==0)
		{
			LM_ERR("unable to get pseudo-variable in param 2\n");
			return E_OUT_OF_MEM;
		}
		if (ap->u.sval.type==PVT_NULL)
		{
			LM_ERR("bad param 2; expected : $pseudo-variable ...\n");
			pkg_free(ap);
			return E_UNSPEC;
		}
		ap->opd |= AVPOPS_VAL_PVAR;

		/* flags */
		for( ; p&&*p ; p++ )
		{
			switch (*p) {
				case 'g':
				case 'G':
					ap->ops|=AVPOPS_FLAG_ALL;
					break;
				default:
					LM_ERR("bad flag <%c>\n",*p);
					pkg_free(ap);
					return E_UNSPEC;
			}
		}
	}

	*param=(void*)ap;
	return 0;
}
Exemple #4
0
static int fixup_check_avp(void** param, int param_no)
{
	struct fis_param *ap;
	regex_t* re;
	char *s;

	s = (char*)*param;
	ap = 0;

	if (param_no==1)
	{
		ap = avpops_parse_pvar(s);
		if (ap==0)
		{
			LM_ERR(" unable to get pseudo-variable in P1\n");
			return E_OUT_OF_MEM;
		}
		/* attr name is mandatory */
		if (ap->u.sval.type==PVT_NULL)
		{
			LM_ERR("null pseudo-variable in P1\n");
			return E_UNSPEC;
		}
	} else if (param_no==2) {
		if ( (ap=parse_check_value(s))==0 )
		{
			LM_ERR(" failed to parse checked value \n");
			return E_UNSPEC;
		}
		/* if REGEXP op -> compile the expresion */
		if (ap->ops&AVPOPS_OP_RE)
		{
			if ( (ap->opd&AVPOPS_VAL_STR)==0 )
			{
				LM_ERR(" regexp operation requires string value\n");
				return E_UNSPEC;
			}
			re = pkg_malloc(sizeof(regex_t));
			if (re==0)
			{
				LM_ERR(" no more pkg mem\n");
				return E_OUT_OF_MEM;
			}
			LM_DBG("compiling regexp <%.*s>\n", ap->u.s.len, ap->u.s.s);
			if (regcomp(re, ap->u.s.s,
						REG_EXTENDED|REG_ICASE|REG_NEWLINE))
			{
				pkg_free(re);
				LM_ERR("bad re <%.*s>\n", ap->u.s.len, ap->u.s.s);
				return E_BAD_RE;
			}
			/* free the string and link the regexp */
			// pkg_free(ap->sval.p.s);
			ap->u.s.s = (char*)re;
		} else if (ap->ops&AVPOPS_OP_FM) {
			if ( !( ap->opd&AVPOPS_VAL_PVAR ||
			(!(ap->opd&AVPOPS_VAL_PVAR) && ap->opd&AVPOPS_VAL_STR) ) )
			{
				LM_ERR(" fast_match operation requires string value or "
						"avp name/alias (%d/%d)\n",	ap->opd, ap->ops);
				return E_UNSPEC;
			}
		}
	}

	*param=(void*)ap;
	return 0;
}
Exemple #5
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;
	}

	ap = avpops_parse_pvar(s);
	if (ap==0)
	{
		LM_ERR("unable to get pseudo-variable in P%d\n", param_no);
		return E_OUT_OF_MEM;
	}

	/* attr name is mandatory */
	if (ap->u.sval.type!=PVT_AVP)
	{
		LM_ERR("you must specify only AVP as parameter\n");
		return E_UNSPEC;
	}

	if (param_no==2)
	{
		/* flags */
		for( ; p&&*p ; p++ )
		{
			switch (*p) {
				case 'g':
				case 'G':
					ap->ops|=AVPOPS_FLAG_ALL;
					break;
				case 'd':
				case 'D':
					ap->ops|=AVPOPS_FLAG_DELETE;
					break;
				case 'n':
				case 'N':
					ap->ops|=AVPOPS_FLAG_CASTN;
					break;
				case 's':
				case 'S':
					ap->ops|=AVPOPS_FLAG_CASTS;
					break;
				default:
					LM_ERR("bad flag <%c>\n",*p);
					return E_UNSPEC;
			}
		}
	}

	*param=(void*)ap;
	return 0;
}
Exemple #6
0
static int fixup_delete_avp(void** param, int param_no)
{
	struct fis_param *ap=NULL;
	char *p;
	char *s;
	unsigned int flags;
	str s0;

	s = (char*)(*param);
	if (param_no==1) {
		/* attribute name / alias */
		if ( (p=strchr(s,'/'))!=0 )
			*(p++)=0;

		if(*s=='$')
		{
			/* is variable */
			ap = avpops_parse_pvar(s);
			if (ap==0)
			{
				LM_ERR("unable to get"
					" pseudo-variable in param \n");
				return E_UNSPEC;
			}
			if (ap->u.sval.type!=PVT_AVP)
			{
				LM_ERR("bad param; expected : $avp(name)\n");
				return E_UNSPEC;
			}
			ap->opd|=AVPOPS_VAL_PVAR;
			ap->type = AVPOPS_VAL_PVAR;
		} else {
			if(strlen(s)<1)
			{
				LM_ERR("bad param - expected : $avp(name), *, s or i value\n");
				return E_UNSPEC;
			}
			ap = (struct fis_param*)pkg_malloc(sizeof(struct fis_param));
			if (ap==0)
			{
				LM_ERR(" no more pkg mem\n");
				return E_OUT_OF_MEM;
			}
			memset(ap, 0, sizeof(struct fis_param));
			ap->opd|=AVPOPS_VAL_NONE;
			switch(*s) {
				case 's': case 'S':
					ap->opd = AVPOPS_VAL_NONE|AVPOPS_VAL_STR;
				break;
				case 'i': case 'I':
					ap->opd = AVPOPS_VAL_NONE|AVPOPS_VAL_INT;
				break;
				case '*': case 'a': case 'A':
					ap->opd = AVPOPS_VAL_NONE;
				break;
				default:
					LM_ERR(" bad param - expected : *, s or i AVP flag\n");
					pkg_free(ap);
					return E_UNSPEC;
			}
			/* flags */
			flags = 0;
			if(*(s+1)!='\0')
			{
				s0.s = s+1;
				s0.len = strlen(s0.s);
				if(str2int(&s0, &flags)!=0)
				{
					LM_ERR("bad avp flags\n");
					pkg_free(ap);
					return E_UNSPEC;
				}
			}
			ap->type = AVPOPS_VAL_INT;
			ap->u.n = flags<<8;
		}

		/* flags */
		for( ; p&&*p ; p++ )
		{
			switch (*p)
			{
				case 'g':
				case 'G':
					ap->ops|=AVPOPS_FLAG_ALL;
					break;
				default:
					LM_ERR(" bad flag <%c>\n",*p);
					if(ap!=NULL)
						pkg_free(ap);
					return E_UNSPEC;
			}
		}
		/* force some flags: if no avp name is given, force "all" flag */
		if (ap->opd&AVPOPS_VAL_NONE)
			ap->ops |= AVPOPS_FLAG_ALL;

		*param=(void*)ap;
	}

	return 0;
}
Exemple #7
0
static int fixup_is_avp_set(void** param, int param_no)
{
	struct fis_param *ap;
	char *p;
	char *s;

	s = (char*)(*param);
	if (param_no==1) {
		/* attribute name | alias / flags */
		if ( (p=strchr(s,'/'))!=0 )
			*(p++)=0;

		ap = avpops_parse_pvar(s);
		if (ap==0)
		{
			LM_ERR("unable to get pseudo-variable in param\n");
			return E_OUT_OF_MEM;
		}

		if (ap->u.sval.type!=PVT_AVP)
		{
			LM_ERR("bad attribute name <%s>\n", (char*)*param);
			return E_UNSPEC;
		}
		if(p==0 || *p=='\0')
			ap->ops|=AVPOPS_FLAG_ALL;

		/* flags */
		for( ; p&&*p ; p++ )
		{
			switch (*p) {
				case 'e':
				case 'E':
					ap->ops|=AVPOPS_FLAG_EMPTY;
					break;
				case 'n':
				case 'N':
					if(ap->ops&AVPOPS_FLAG_CASTS)
					{
						LM_ERR("invalid flag combination <%c> and 's|S'\n",*p);
						return E_UNSPEC;
					}
					ap->ops|=AVPOPS_FLAG_CASTN;
					break;
				case 's':
				case 'S':
					if(ap->ops&AVPOPS_FLAG_CASTN)
					{
						LM_ERR("invalid flag combination <%c> and 'n|N'\n",*p);
						return E_UNSPEC;
					}
					ap->ops|=AVPOPS_FLAG_CASTS;
					break;
				default:
					LM_ERR("bad flag <%c>\n",*p);
					return E_UNSPEC;
			}
		}

		*param=(void*)ap;
	}

	return 0;
}
struct fis_param* parse_op_value(char *s)
{
	struct fis_param *vp;
	int  ops;
	int  opd;
	char *p;
	char *t;
	int len;

	ops = 0;
	opd = 0;
	vp = 0;

	if ( (p=strchr(s,'/'))==0 || (p-s!=2&&p-s!=3) )
		goto parse_error;
	/* get the operation */
	if (strncasecmp(s,"add",3)==0) {
		ops |= AVPOPS_OP_ADD;
	} else if (strncasecmp(s,"sub",3)==0) {
		ops |= AVPOPS_OP_SUB;
	} else if (strncasecmp(s,"mul",3)==0) {
		ops |= AVPOPS_OP_MUL;
	} else if (strncasecmp(s,"div",3)==0) {
		ops |= AVPOPS_OP_DIV;
	} else if (strncasecmp(s,"mod",3)==0) {
		ops |= AVPOPS_OP_MOD;
	} else if (strncasecmp(s,"and",3)==0) {
		ops |= AVPOPS_OP_BAND;
	} else if (strncasecmp(s,"or",2)==0) {
		ops |= AVPOPS_OP_BOR;
	} else if (strncasecmp(s,"xor",3)==0) {
		ops |= AVPOPS_OP_BXOR;
	} else if (strncasecmp(s,"not",3)==0) {
		ops |= AVPOPS_OP_BNOT;
	} else {
		LM_ERR("unknown operation <%.*s>\n",2,s);
		goto error;
	}
	/* get the value */
	if (*(++p)==0)
		goto parse_error;
	if ( (t=strchr(p,'/'))==0)
		len = strlen(p);
	else
		len = t-p;

	if (*p=='$')
	{
		/* is variable */
		vp = avpops_parse_pvar(p);
		if (vp==0)
		{
			LM_ERR("unable to get pseudo-variable\n");
			goto error;
		}
		if (vp->u.sval.type==PVT_NULL)
		{
			LM_ERR("bad param; expected : $pseudo-variable or int/str value\n");
			goto error;
		}
		opd |= AVPOPS_VAL_PVAR;
		LM_DBG("flag==%d/%d\n", opd, ops);
	} else {
		/* value is explicitly given */
		if ( (vp=parse_intstr_value(p,len))==0) {
			LM_ERR("unable to parse value\n");
			goto error;
		}
		if((vp->opd&AVPOPS_VAL_INT)==0) {
			LM_ERR("value must be int\n");
			goto error;
		}
	}

	/* any flags */
	p = t;
	if (p!=0 && *p!=0 )
	{
		if (*p!='/' || *(++p)==0)
			goto parse_error;
		while (*p)
		{
			switch (*p)
			{
				case 'g':
				case 'G':
					ops|=AVPOPS_FLAG_ALL;
					break;
				case 'd':
				case 'D':
					ops|=AVPOPS_FLAG_DELETE;
					break;
				default:
					LM_ERR("unknown flag <%c>\n",*p);
					goto error;
			}
			p++;
		}
	}

	vp->ops |= ops;
	vp->opd |= opd;
	return vp;
parse_error:
	LM_ERR("parse error in <%s> pos %ld\n", s,(long)(p-s));
error:
	if (vp) pkg_free(vp);
	return 0;
}
struct fis_param* parse_check_value(char *s)
{
	struct fis_param *vp;
	int  ops;
	int  opd;
	char *p;
	char *t;
	int len;

	ops = 0;
	opd = 0;
	vp = 0;

	if ( (p=strchr(s,'/'))==0 || (p-s!=2&&p-s!=3) )
		goto parse_error;
	/* get the operation */
	if (strncasecmp(s,"eq",2)==0) {
		ops |= AVPOPS_OP_EQ;
	} else if (strncasecmp(s,"ne",2)==0) {
		ops |= AVPOPS_OP_NE;
	} else if (strncasecmp(s,"lt",2)==0) {
		ops |= AVPOPS_OP_LT;
	} else if (strncasecmp(s,"le",2)==0) {
		ops |= AVPOPS_OP_LE;
	} else if (strncasecmp(s,"gt",2)==0) {
		ops |= AVPOPS_OP_GT;
	} else if (strncasecmp(s,"ge",2)==0) {
		ops |= AVPOPS_OP_GE;
	} else if (strncasecmp(s,"re",2)==0) {
		ops |= AVPOPS_OP_RE;
	} else if (strncasecmp(s,"fm",2)==0) {
		ops |= AVPOPS_OP_FM;
	} else if (strncasecmp(s,"and",3)==0) {
		ops |= AVPOPS_OP_BAND;
	} else if (strncasecmp(s,"or",2)==0) {
		ops |= AVPOPS_OP_BOR;
	} else if (strncasecmp(s,"xor",3)==0) {
		ops |= AVPOPS_OP_BXOR;
	} else {
		LM_ERR("unknown operation <%.*s>\n",2,s);
		goto error;
	}
	/* get the value */
	if (*(++p)==0)
		goto parse_error;
	if ( (t=strchr(p,'/'))==0)
		len = strlen(p);
	else
		len = t-p;

	if (*p=='$')
	{
		/* is variable */
		vp = avpops_parse_pvar(p);
		if (vp==0)
		{
			LM_ERR("unable to get pseudo-variable\n");
			goto error;
		}
		if (vp->u.sval.type==PVT_NULL)
		{
			LM_ERR("bad param; expected : $pseudo-variable or int/str value\n");
			goto error;
		}
		opd |= AVPOPS_VAL_PVAR;
		LM_DBG("flag==%d/%d\n", opd, ops);
	} else {
		/* value is explicitly given */
		if ( (vp=parse_intstr_value(p,len))==0) {
			LM_ERR("unable to parse value\n");
			goto error;
		}
	}

	p = t;
	/* any flags */
	if (p!=NULL && *p!=0)
	{
		if (*p!='/' || *(++p)==0)
			goto parse_error;
		while (*p)
		{
			switch (*p)
			{
				case 'g':
				case 'G':
					ops|=AVPOPS_FLAG_ALL;
					break;
				case 'i':
				case 'I':
					ops|=AVPOPS_FLAG_CI;
					break;
				default:
					LM_ERR("unknown flag <%c>\n",*p);
					goto error;
			}
			p++;
		}
	}

	vp->ops |= ops;
	vp->opd |= opd;
	return vp;
parse_error:
	LM_ERR("parse error in <%s> pos %ld\n", s,(long)(p-s));
error:
	if (vp) pkg_free(vp);
	return 0;
}