Esempio n. 1
0
static inline void parse_algo_hdr(struct hdr_field* algo_hdr, int* algo, int* b64_required)
{
	int rc;
	char* delim=NULL;

	str tok;
	str s_tok;

	s_tok.s = algo_hdr->body.s;
	s_tok.len = algo_hdr->body.len;

	do {
		delim = q_memchr(s_tok.s, ATTR_DELIM[0], s_tok.len);

		if (delim==NULL) {
			trim_spaces_lr(s_tok);
			rc = get_algo(&s_tok);
		} else {
			tok.s = s_tok.s;
			tok.len = delim - s_tok.s;

			s_tok.s = delim+1;
			s_tok.len = (delim-tok.s+1);

			trim_spaces_lr(tok);
			rc = get_algo(&tok);
		}

		if (rc < 2 && rc >=0)
			*algo = rc;
		else
			*b64_required = rc;
	} while(delim);
}
Esempio n. 2
0
static int strtime(const str *time, int *ihrs, int *imin)
{
	char *colon = q_memchr(time->s, FRD_TIME_SEP, time->len);
	if (colon == NULL)
		goto parse_error;

	str hrs = {time->s, colon - time->s};
	str min = {colon + 1, time->len - hrs.len - 1};
	if (hrs.len == 0 || min.len == 0)
		goto parse_error;

	unsigned int uhrs, umin;
	if (str2int(&hrs, &uhrs) || str2int(&min, &umin))
		goto parse_error;

	if (uhrs > 23 || umin >= 60)
		goto parse_error;

	*imin = umin;
	*ihrs = uhrs;

	return 0;
parse_error:
	LM_ERR("cannot parse time-value <%.*s>", time->len, time->s);
	return -1;
}
Esempio n. 3
0
static int parse_cmd(str* res, str* buffer)
{
	char* cmd_end;

	if (!res || !buffer) {
		LOG(L_ERR, "parse_cmd: Invalid parameter value\n");
		return -1;
	}

	if (buffer->len < 3) {
		LOG(L_ERR, "parse_cmd: Message too short\n");
		return -1;
	}

	if (buffer->s[0] != CMD_SEPARATOR) {
		LOG(L_ERR, "parse_cmd: Command must start with %c\n", 
		    CMD_SEPARATOR);
		return -1;
	}
	
	cmd_end = q_memchr(buffer->s + 1, CMD_SEPARATOR, buffer->len - 1);
	if (!cmd_end) {
		LOG(L_ERR, "parse_cmd: Closing '%c' missing\n", CMD_SEPARATOR);
		return -1;
	}

	res->s = buffer->s + 1;
	res->len = cmd_end - res->s;
	return 0;
} 
Esempio n. 4
0
int select_nameaddr_uri(str* res, select_t* s, struct sip_msg* msg)
{
	char *p;
	
	p=find_not_quoted(res, '<');
	if (!p) {
		LM_DBG("no < found, string up to first semicolon is uri\n");
		p = q_memchr(res->s, ';', res->len);
		if (p)
			res->len = p-res->s;
		return 0;
	}

	res->len=res->len - (p-res->s) -1;
	res->s=p +1;
	
	p=find_not_quoted(res, '>');
	if (!p) {
		LM_ERR("no > found, invalid nameaddr value\n");
		return -1;
	}

	res->len=p-res->s;
	return 0;
}
Esempio n. 5
0
static unsigned long long
do_acc_parse(str* in, do_acc_parser parser)
{

	char* found=NULL;
	str token;

	unsigned long long fret=0, ret;

	if (!in || !in->s || !in->len)
		return -1;

	do {
		found=q_memchr(in->s, DO_ACC_PARAM_DELIMITER, in->len);
		if (found) {
			token.s = in->s;
			token.len = found - in->s;

			in->len -= (found - in->s) + 1;
			in->s = found + 1;
		} else {
			token = *in;
		}

		if ((ret=parser(&token)) < 0) {
			LM_ERR("Invalid token <%.*s>!\n", token.len, token.s);
			return -1;
		}

		fret |= ret;
	} while(found);

	return fret;
}
Esempio n. 6
0
/*
 * Parse quoted string in a parameter body
 * return the string without quotes in r
 * parameter and update s to point behind the
 * closing quote
 */
static inline int parse_quoted(str* s, str* r)
{
	char* end_quote;

	/* The string must have at least surrounding quotes */
	if (s->len < 2) 
		return -1;

	/* Skip opening quote */
	s->s++;
	s->len--;

	/* Find closing quote */
	end_quote = q_memchr(s->s, '\"', s->len);

	/* Not found, return error */
	if (!end_quote) 
		return -2;

	/* Let r point to the string without surrounding quotes */
	r->s = s->s;
	r->len = end_quote - s->s;

	/* Update s parameter to point behind the closing quote */
	s->len -= (end_quote - s->s + 1);
	s->s = end_quote + 1;

	/* Everything went OK */
	return 0;
}
Esempio n. 7
0
/**
 * extract the node list from the body of a notification request SIP message
 * the SIP request will look something like:
 * 	KDMQ sip:10.0.0.0:5062
 * 	To: ...
 * 	From: ...
 * 	Max-Forwards: ...
 * 	Content-Length: 22
 * 	
 * 	sip:host1:port1;param1=value1
 * 	sip:host2:port2;param2=value2
 * 	...
 */
int extract_node_list(dmq_node_list_t* update_list, struct sip_msg* msg)
{
	int content_length, total_nodes = 0;
	str body;
	str tmp_uri;
	dmq_node_t *cur = NULL;
	char *tmp, *end, *match;
	if(!msg->content_length) {
		LM_ERR("no content length header found\n");
		return -1;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		return total_nodes;
	}
	body.s = get_body(msg);
	body.len = content_length;
	tmp = body.s;
	end = body.s + body.len;
	
	/* acquire big list lock */
	lock_get(&update_list->lock);
	while(tmp < end) {
		match = q_memchr(tmp, '\n', end - tmp);
		if(match) {
			match++;
		} else {
			/* for the last line - take all of it */
			match = end;
		}
		/* create the orig_uri from the parsed uri line and trim it */
		tmp_uri.s = tmp;
		tmp_uri.len = match - tmp - 1;
		tmp = match;
		/* trim the \r, \n and \0's */
		trim_r(tmp_uri);
		if(!find_dmq_node_uri(update_list, &tmp_uri)) {
			LM_DBG("found new node %.*s\n", STR_FMT(&tmp_uri));
			cur = build_dmq_node(&tmp_uri, 1);
			if(!cur) {
				LM_ERR("error creating new dmq node\n");
				goto error;
			}
			cur->next = update_list->nodes;
			update_list->nodes = cur;
			update_list->count++;
			total_nodes++;
		}
	}
	/* release big list lock */
	lock_release(&update_list->lock);
	return total_nodes;
error:
	lock_release(&update_list->lock);
	return -1;
}
Esempio n. 8
0
/*
 * Returns the class part of the URI
 */
str *parseurl(const str* url) {
	static str cn;

	cn.s = q_memchr(url->s,':',url->len);
	if (cn.s && ((cn.s+1)<(url->s+url->len)) ) {
		cn.s++;
		cn.len = url->len - (cn.s-url->s);
		return &cn;
	}
	return NULL;
}
Esempio n. 9
0
/** initializes a net structure from a string.
 * @param dst - net structure that will be filled
 * @param s - string of the form "ip", "ip/mask_len" or "ip/ip_mak".
 * @return -1 on error, 0 on succes
 */
int mk_net_str(struct net* dst, str* s)
{
	struct ip_addr* t;
	char* p;
	struct ip_addr ip;
	str addr;
	str mask;
	unsigned int bitlen;
	
	/* test for ip only */
	t = str2ip(s);
	if (unlikely(t == 0))
		t = str2ip6(s);
	if (likely(t))
		return mk_net_bitlen(dst, t, t->len*8);
	/* not a simple ip, maybe an ip/netmask pair */
	p = q_memchr(s->s, '/', s->len);
	if (likely(p)) {
		addr.s = s->s;
		addr.len = (int)(long)(p - s->s);
		mask.s = p + 1;
		mask.len = s->len - (addr.len + 1);
		/* allow '/' enclosed by whitespace */
		trim_trailing(&addr);
		trim_leading(&mask);
		t = str2ip(&addr);
		if (likely(t)) {
			/* it can be a number */
			if (str2int(&mask, &bitlen) == 0)
				return mk_net_bitlen(dst, t, bitlen);
			ip = *t;
			t = str2ip(&mask);
			if (likely(t))
				return mk_net(dst, &ip, t);
			/* error */
			return -1;
		}
		else {
			t = str2ip6(&addr);
			if (likely(t)) {
				/* it can be a number */
				if (str2int(&mask, &bitlen) == 0)
					return mk_net_bitlen(dst, t, bitlen);
				ip = *t;
				t = str2ip6(&mask);
				if (likely(t))
					return mk_net(dst, &ip, t);
				/* error */
				return -1;
			}
		}
	}
	return -1;
}
Esempio n. 10
0
static int check_ftag(struct sip_msg* msg, str* uri)
{
	param_hooks_t hooks;
	param_t* params;
	char* semi;
	struct to_body* from;
	str t;

	t = *uri;
	params = 0;
	semi = q_memchr(t.s, ';', t.len);
	if (!semi) {
		DBG("No ftag parameter found\n");
		return -1;
	}

	t.len -= semi - uri->s + 1;
	t.s = semi + 1;
	trim_leading(&t);

	if (parse_params(&t, CLASS_URI, &hooks, &params) < 0) {
		ERR("Error while parsing parameters\n");
		return -1;
	}

	if (!hooks.uri.ftag) {
		DBG("No ftag parameter found\n");
		goto err;
	}

	from = get_from(msg);

	if (!from || !from->tag_value.len || !from->tag_value.s) {
		DBG("No from tag parameter found\n");
		goto err;
	}

	if (from->tag_value.len == hooks.uri.ftag->body.len &&
	    !strncmp(from->tag_value.s, hooks.uri.ftag->body.s, hooks.uri.ftag->body.len)) {
		DBG("Route ftag and From tag are same\n");
		free_params(params);
		return 0;
	} else {
		DBG("Route ftag and From tag are NOT same\n");
		free_params(params);
		return 1;
	}

 err:
	if (params) free_params(params);
	return -1;
}
Esempio n. 11
0
/** @brief returns pointer to next line or after the end of buffer */
char* eat_line(char* buffer, unsigned int len)
{
	char* nl;

	/* jku .. replace for search with a library function; not conforming
 		  as I do not care about CR
	*/
	nl=(char *)q_memchr( buffer, '\n', len );
	if ( nl ) { 
		if ( nl + 1 < buffer+len)  nl++;
		if (( nl+1<buffer+len) && * nl=='\r')  nl++;
	} else  nl=buffer+len;
	return nl;
}
Esempio n. 12
0
/*
 * Parse username for user and domain parts
 */
static inline void parse_username(struct username* _u)
{
	char* d;

	_u->user = _u->whole;
	if (_u->whole.len <= 2) return;

	d = q_memchr(_u->whole.s, '@', _u->whole.len);

	if (d) {
		_u->domain.s = d + 1;
		_u->domain.len = _u->whole.len - (d - _u->whole.s) - 1;
		_u->user.len = d - _u->user.s;
	}
}
Esempio n. 13
0
int db_delete_urecord(urecord_t* _r)
{
	char b[256];
	db_key_t keys[2];
	db_val_t vals[2];
	char* dom;

	keys[0] = user_col;
	keys[1] = domain_col;
	vals[0].type = DB_STR;
	vals[0].nul = 0;
	vals[0].val.str_val.s = _r->aor.s;
	vals[0].val.str_val.len = _r->aor.len;

	if (use_domain) {
		dom = q_memchr(_r->aor.s, '@', _r->aor.len);
		if (!dom) {
			LOG(L_ERR, "db_delete_urecord(): You forgot to set modparam(\"registrar\", \"use_domain\", 1) in ser.cfg!\n");
			vals[0].val.str_val.len = _r->aor.len;
			
			vals[1].type = DB_STR;
			vals[1].nul = 0;
			vals[1].val.str_val.s = _r->aor.s;
			vals[1].val.str_val.len = 0;
		} else {
			vals[0].val.str_val.len = dom - _r->aor.s;
			
			vals[1].type = DB_STR;
			vals[1].nul = 0;
			vals[1].val.str_val.s = dom + 1;
			vals[1].val.str_val.len = _r->aor.s + _r->aor.len - dom - 1;
		}
	}

	     /* FIXME */
	memcpy(b, _r->domain->s, _r->domain->len);
	b[_r->domain->len] = '\0';
	db_use_table(db, b);

	if (db_delete(db, keys, 0, vals, (use_domain) ? (2) : (1)) < 0) {
		LOG(L_ERR, "db_delete_urecord(): Error while deleting from database\n");
		return -1;
	}

	return 0;
}
Esempio n. 14
0
/*
 * Parse username for user and domain parts
 */
static inline void parse_username(struct username* u)
{
	char* d;

	u->user = u->whole;
	if (u->whole.len <= 2) 
			return;

	d = q_memchr(u->whole.s, '@', u->whole.len);

	if (d) 
	{
		u->domain.s = d + 1;
		u->domain.len = u->whole.len - (d - u->whole.s) - 1;
		u->user.len = d - u->user.s;
	}
}
Esempio n. 15
0
/*! \brief
 * Parse quoted string in a parameter body
 * return the string without quotes in _r
 * parameter and update _s to point behind the
 * closing quote
 */
static inline int parse_quoted_param(str *_s, str *_r)
{
	char *end_quote;
	char quote;

	/* The string must have at least
	 * surrounding quotes
	 */
	if(_s->len < 2) {
		return -1;
	}

	/* Store the kind of quoting (single or double)
	 * which we're handling with
	 */
	quote = (_s->s)[0];

	/* Skip opening quote */
	_s->s++;
	_s->len--;


	/* Find closing quote */
	end_quote = q_memchr(_s->s, quote, _s->len);

	/* Not found, return error */
	if(!end_quote) {
		return -2;
	}

	/* Let _r point to the string without
	 * surrounding quotes
	 */
	_r->s = _s->s;
	_r->len = end_quote - _s->s;

	/* Update _s parameter to point
	 * behind the closing quote
	 */
	_s->len -= (end_quote - _s->s + 1);
	_s->s = end_quote + 1;

	/* Everything went OK */
	return 0;
}
Esempio n. 16
0
int parse_param_name(str* _s, dig_par_t* _type)
{
        register char* p;
        register int val;
	char* end;
	
	end = _s->s + _s->len;
	
	p = _s->s;
	val = READ(p);
	
	if (_s->len < 4) {
		goto other;
	}
	
        switch(LOWER_DWORD(val)) {
	FIRST_QUATERNIONS;
	default:
		PARSE_SHORT;
		goto other;
        }

 end:
	_s->len -= p - _s->s;
	_s->s = p;

	trim_leading(_s);
	if (_s->s[0] == '=') {
		return 0;
	}
	
 other:
	p = q_memchr(p, '=', end - p);
	if (!p) {
		return -1; /* Parse error */
	} else {
		*_type = PAR_OTHER;
		_s->len -= p - _s->s;
		_s->s = p;
		return 0;
	}
}
Esempio n. 17
0
/*
 * Delete contact from the database
 */
int db_delete_ucontact(ucontact_t* _c)
{
	char b[256];
	char* dom;
	db_key_t keys[3];
	db_val_t vals[3];

	keys[0] = user_col;
	keys[1] = contact_col;
	keys[2] = domain_col;

	vals[0].type = DB_STR;
	vals[0].nul = 0;
	vals[0].val.str_val = *_c->aor;

	vals[1].type = DB_STR;
	vals[1].nul = 0;
	vals[1].val.str_val = _c->c;

	if (use_domain) {
		dom = q_memchr(_c->aor->s, '@', _c->aor->len);
		vals[0].val.str_val.len = dom - _c->aor->s;

		vals[2].type = DB_STR;
		vals[2].nul = 0;
		vals[2].val.str_val.s = dom + 1;
		vals[2].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
	}

	     /* FIXME */
	memcpy(b, _c->domain->s, _c->domain->len);
	b[_c->domain->len] = '\0';
	db_use_table(db, b);

	if (db_delete(db, keys, 0, vals, (use_domain) ? (3) : (2)) < 0) {
		LOG(L_ERR, "db_del_ucontact(): Error while deleting from database\n");
		return -1;
	}

	return 0;
}
Esempio n. 18
0
int check_addr_param1(str *s, struct part_var *pv)
{
	char *end;
	unsigned int gid;
	int ret;
	str spart, sval;

	ret=0;

	spart.s = s->s;

	end = q_memchr(s->s, ':', s->len);

	ret = -1;
	if (end == NULL) {
		ret = str2int(s, &gid);
		pv->u.parsed_part.partition.s = NULL;
		if (0 == ret)
			pv->u.parsed_part.v.ival = gid;
		else {
			pv->u.parsed_part.v.sval.s = s->s;
			pv->u.parsed_part.v.sval.len = s->len;
		}
	} else {
		spart.len = end - spart.s;
		sval.s = end + 1;
		sval.len = (s->s + s->len) - sval.s;

		str_trim_spaces_lr(sval);
		str_trim_spaces_lr(spart);

		pv->u.parsed_part.partition = spart;
		ret = str2int(&sval, &gid);
		if (0 == ret)
			pv->u.parsed_part.v.ival = gid;
		else
			pv->u.parsed_part.v.sval = sval;
	}

	return 0;
}
Esempio n. 19
0
/*
 * Parse Digest credentials parameter, one by one
 */
static inline int parse_digest_params(str* _s, dig_cred_t* _c)
{
	char* comma;

	do {
		     /* Parse the first parameter */
		if (parse_digest_param(_s, _c) < 0) {
			return -1;
		}
		
		     /* Try to find the next parameter */
		comma = q_memchr(_s->s, ',', _s->len);
		if (comma) {
			     /* Yes, there is another, 
			      * remove any leading white-spaces
			      * and let _s point to the next
			      * parameter name
			      */
			_s->len -= comma - _s->s + 1;
			_s->s = comma + 1;
			trim_leading(_s);
		}
	} while(comma); /* Repeat while there are next parameters */

	     /* Parse QOP body if the parameter was present */
	if (_c->qop.qop_str.s != 0) {
		parse_qop(&_c->qop);
	}

	     /* Parse algorithm body if the parameter was present */
	if (_c->alg.alg_str.s != 0) {
		parse_algorithm(&_c->alg);
	}

	if (_c->username.whole.s != 0) {
		parse_username(&_c->username);
	}

	return 0;
}
Esempio n. 20
0
/**
 * parse_hname2_short() - safer version to parse header name stored in short buffers
 *   - parse_hanem2() reads 4 bytes at once, expecting to walk through a buffer
 *   that contains more than the header name (e.g., sip msg buf, full header buf
 *   with name and body)
 */
char* parse_hname2_short(char* const begin, const char* const end, struct hdr_field* const hdr)
{
#define HBUF_MAX_SIZE 256
	char hbuf[HBUF_MAX_SIZE];
	char *p;

	if(end-begin>=HBUF_MAX_SIZE-4) {
		p = q_memchr(begin, ':', end - begin);
		if(p && p-4> begin) {
			/* header name termination char found and enough space in buffer after it */
			return parse_hname2(begin, end, hdr);
		}
		/* not enough space */
		return NULL;
	}
	/* pad with whitespace - tipycal char after the ':' of the header name */
	memset(hbuf, ' ', HBUF_MAX_SIZE);
	memcpy(hbuf, begin, end-begin);
	p = parse_hname2(hbuf, hbuf + 4 + (end-begin), hdr);
	if(!p) return NULL;
	return begin + (p-hbuf);
}
Esempio n. 21
0
/*
 * Parse quoted string in a parameter body
 * return the string without quotes in _r
 * parameter and update _s to point behind the
 * closing quote
 */
static inline int parse_quoted(str* _s, str* _r)
{
	char* end_quote;

	     /* The string must have at least
	      * surrounding quotes
	      */
	if (_s->len < 2) {
		return -1;
	}

	     /* Skip opening quote */
	_s->s++;
	_s->len--;


	     /* Find closing quote */
	end_quote = q_memchr(_s->s, '\"', _s->len);

	     /* Not found, return error */
	if (!end_quote) {
		return -2;
	}

	     /* Let _r point to the string without
	      * surrounding quotes
	      */
	_r->s = _s->s;
	_r->len = end_quote - _s->s;

	     /* Update _s parameter to point
	      * behind the closing quote
	      */
	_s->len -= (end_quote - _s->s + 1);
	_s->s = end_quote + 1;

	     /* Everything went OK */
	return 0;
}
Esempio n. 22
0
int aaa_parse_url(str* aaa_url, aaa_prot_config* aaa_config) {

	char* p;
	int len;

	if (!aaa_url || !aaa_config) {
		LM_ERR("null arguments\n");
		return -1;
	}

	p = q_memchr(aaa_url->s, ':', aaa_url->len);

	if (!p) {
		LM_ERR("invalid aaa url\n");
		return -1;
	}

	len = p - aaa_url->s;

	aaa_config->prot_name = (str*) pkg_malloc (sizeof(str));
	if (!aaa_config->prot_name) {
		LM_ERR("no pkg memory left\n");
		return -1;
	}

	aaa_config->prot_name->s = (char*) pkg_malloc (len * sizeof(char));
	if (!aaa_config->prot_name->s) {
		LM_ERR("no pkg memory left\n");
		return -1;
	}

	aaa_config->prot_name->len = len;
	aaa_config->rest = p + 1;

	strncpy(aaa_config->prot_name->s, aaa_url->s, len);

	return 0;
}
Esempio n. 23
0
static int fixup_partition_sets_null(void **param)
{
	str s_param = {(char*)*param, strlen(*param)};
	str part_name = {NULL, 0};

	char *delim = q_memchr(s_param.s, DS_PARTITION_DELIM, s_param.len);

	if (delim) {
		part_name.s = s_param.s;
		part_name.len = delim - s_param.s;
		s_param.s = delim + 1;
		s_param.len -= part_name.len + 1;
		trim(&part_name);
	}

	trim(&s_param);

	ds_param_t *final_param = shm_malloc(sizeof (ds_param_t));

	if (final_param == NULL) {
		LM_CRIT ("no more shared memory!\n");
		return -1;
	}

	if (get_gpart(&part_name, &final_param->partition) != 0) {
		shm_free(final_param);
		return -1;
	}

	if ((set_list_from_string(s_param, &final_param->sets)) != 0){
		shm_free(final_param);
		return -1;
	}

	*param = (void*)final_param;
	return 0;
}
Esempio n. 24
0
char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
{
	register char* p;
	register unsigned int val;

	if ((end - begin) < 4) {
		hdr->type = HDR_ERROR_T;
		return begin;
	}

	p = begin;

	val = LOWER_DWORD(READ(p));
	hdr->name.s = begin;

	switch(val) {
	FIRST_QUATERNIONS;

	default:
		switch(LOWER_BYTE(*p)) {
		case 't':
			switch(LOWER_BYTE(*(p + 1))) {
			case 'o':
			case ' ':
				hdr->type = HDR_TO_T;
				p += 2;
				goto dc_end;

			case ':':
				hdr->type = HDR_TO_T;
				hdr->name.len = 1;
				return (p + 2);
			}
			break;

		case 'v': PARSE_COMPACT(HDR_VIA_T);           break;
		case 'f': PARSE_COMPACT(HDR_FROM_T);          break;
		case 'i': PARSE_COMPACT(HDR_CALLID_T);        break;
		case 'm': PARSE_COMPACT(HDR_CONTACT_T);       break;
		case 'l': PARSE_COMPACT(HDR_CONTENTLENGTH_T); break;
		case 'k': PARSE_COMPACT(HDR_SUPPORTED_T);     break;
		case 'c': PARSE_COMPACT(HDR_CONTENTTYPE_T);   break;
		case 'o': PARSE_COMPACT(HDR_EVENT_T);         break;
		case 'x': PARSE_COMPACT(HDR_SESSIONEXPIRES_T);break;
		case 'a': PARSE_COMPACT(HDR_ACCEPTCONTACT_T); break;
		case 'u': PARSE_COMPACT(HDR_ALLOWEVENTS_T);   break;
		case 'e': PARSE_COMPACT(HDR_CONTENTENCODING_T); break;
		case 'b': PARSE_COMPACT(HDR_REFERREDBY_T);    break;
		case 'j': PARSE_COMPACT(HDR_REJECTCONTACT_T); break;
		case 'd': PARSE_COMPACT(HDR_REQUESTDISPOSITION_T); break;
		case 's': PARSE_COMPACT(HDR_SUBJECT_T);       break;
		case 'r': PARSE_COMPACT(HDR_REFER_TO_T);      break;
		}
		goto other;
        }

	     /* Double colon hasn't been found yet */
 dc_end:
       	p = skip_ws(p, end - p);
	if (*p != ':') {
	        goto other;
	} else {
		hdr->name.len = p - hdr->name.s;
		return (p + 1);
	}

	     /* Unknown header type */
 other:
	p = q_memchr(p, ':', end - p);
	if (!p) {        /* No double colon found, error.. */
		hdr->type = HDR_ERROR_T;
		hdr->name.s = 0;
		hdr->name.len = 0;
		return 0;
	} else {
		hdr->type = HDR_OTHER_T;
		hdr->name.len = p - hdr->name.s;
		return (p + 1);
	}
}
Esempio n. 25
0
/* returns pointer to next header line, and fill hdr_f ;
 * if at end of header returns pointer to the last crlf  (always buf)*/
char* get_hdr_field(char* const buf, char* const end, struct hdr_field* const hdr)
{

    char *tmp = 0;
    char *match;
    struct via_body *vb;
    struct cseq_body* cseq_b;
    struct to_body* to_b;
    int integer, err;
    unsigned uval;

    if(!buf) {
        DBG("null buffer pointer\n");
        goto error;
    }

    if ((*buf)=='\n' || (*buf)=='\r') {
        /* double crlf or lflf or crcr */
        DBG("found end of header\n");
        hdr->type=HDR_EOH_T;
        return buf;
    }

    tmp=parse_hname(buf, end, hdr);
    if (hdr->type==HDR_ERROR_T) {
        LOG(L_ERR, "ERROR: get_hdr_field: bad header\n");
        goto error;
    }

    /* eliminate leading whitespace */
    tmp=eat_lws_end(tmp, end);
    if (tmp>=end) {
        LOG(L_ERR, "ERROR: get_hdr_field: HF empty\n");
        goto error;
    }

    /* if header-field well-known, parse it, find its end otherwise ;
     * after leaving the hdr->type switch, tmp should be set to the
     * next header field
     */
    switch(hdr->type) {
    case HDR_VIA_T:
        /* keep number of vias parsed -- we want to report it in
           replies for diagnostic purposes */
        via_cnt++;
        vb=pkg_malloc(sizeof(struct via_body));
        if (vb==0) {
            LOG(L_ERR, "get_hdr_field: out of memory\n");
            goto error;
        }
        memset(vb,0,sizeof(struct via_body));
        hdr->body.s=tmp;
        tmp=parse_via(tmp, end, vb);
        if (vb->error==PARSE_ERROR) {
            LOG(L_ERR, "ERROR: get_hdr_field: bad via\n");
            free_via_list(vb);
            goto error;
        }
        hdr->parsed=vb;
        vb->hdr.s=hdr->name.s;
        vb->hdr.len=hdr->name.len;
        hdr->body.len=tmp-hdr->body.s;
        break;
    case HDR_CSEQ_T:
        cseq_b=pkg_malloc(sizeof(struct cseq_body));
        if (cseq_b==0) {
            LOG(L_ERR, "get_hdr_field: out of memory\n");
            goto error;
        }
        memset(cseq_b, 0, sizeof(struct cseq_body));
        hdr->body.s=tmp;
        tmp=parse_cseq(tmp, end, cseq_b);
        if (cseq_b->error==PARSE_ERROR) {
            LOG(L_ERR, "ERROR: get_hdr_field: bad cseq\n");
            free_cseq(cseq_b);
            goto error;
        }
        hdr->parsed=cseq_b;
        hdr->body.len=tmp-hdr->body.s;
        DBG("get_hdr_field: cseq <%.*s>: <%.*s> <%.*s>\n",
            hdr->name.len, ZSW(hdr->name.s),
            cseq_b->number.len, ZSW(cseq_b->number.s),
            cseq_b->method.len, cseq_b->method.s);
        break;
    case HDR_TO_T:
        to_b=pkg_malloc(sizeof(struct to_body));
        if (to_b==0) {
            LOG(L_ERR, "get_hdr_field: out of memory\n");
            goto error;
        }
        memset(to_b, 0, sizeof(struct to_body));
        hdr->body.s=tmp;
        tmp=parse_to(tmp, end,to_b);
        if (to_b->error==PARSE_ERROR) {
            LOG(L_ERR, "ERROR: get_hdr_field: bad to header\n");
            free_to(to_b);
            goto error;
        }
        hdr->parsed=to_b;
        hdr->body.len=tmp-hdr->body.s;
        DBG("DEBUG: get_hdr_field: <%.*s> [%d]; uri=[%.*s] \n",
            hdr->name.len, ZSW(hdr->name.s),
            hdr->body.len, to_b->uri.len,ZSW(to_b->uri.s));
        DBG("DEBUG: to body [%.*s]\n",to_b->body.len,
            ZSW(to_b->body.s));
        break;
    case HDR_CONTENTLENGTH_T:
        hdr->body.s=tmp;
        tmp=parse_content_length(tmp,end, &integer);
        if (tmp==0) {
            LOG(L_ERR, "ERROR:get_hdr_field: bad content_length header\n");
            goto error;
        }
        hdr->parsed=(void*)(long)integer;
        hdr->body.len=tmp-hdr->body.s;
        DBG("DEBUG: get_hdr_body : content_length=%d\n",
            (int)(long)hdr->parsed);
        break;
    case HDR_RETRY_AFTER_T:
        hdr->body.s=tmp;
        tmp=parse_retry_after(tmp,end, &uval, &err);
        if (err) {
            LOG(L_ERR, "ERROR:get_hdr_field: bad retry_after header\n");
            goto error;
        }
        hdr->parsed=(void*)(unsigned long)uval;
        hdr->body.len=tmp-hdr->body.s;
        DBG("DEBUG: get_hdr_body : retry_after=%d\n",
            (unsigned)(long)hdr->parsed);
        break;
    case HDR_IDENTITY_T:
    case HDR_DATE_T:
    case HDR_IDENTITY_INFO_T:
    case HDR_SUPPORTED_T:
    case HDR_REQUIRE_T:
    case HDR_CONTENTTYPE_T:
    case HDR_FROM_T:
    case HDR_CALLID_T:
    case HDR_CONTACT_T:
    case HDR_ROUTE_T:
    case HDR_RECORDROUTE_T:
    case HDR_MAXFORWARDS_T:
    case HDR_AUTHORIZATION_T:
    case HDR_EXPIRES_T:
    case HDR_PROXYAUTH_T:
    case HDR_PROXYREQUIRE_T:
    case HDR_UNSUPPORTED_T:
    case HDR_ALLOW_T:
    case HDR_EVENT_T:
    case HDR_ACCEPT_T:
    case HDR_ACCEPTLANGUAGE_T:
    case HDR_ORGANIZATION_T:
    case HDR_PRIORITY_T:
    case HDR_SUBJECT_T:
    case HDR_USERAGENT_T:
    case HDR_SERVER_T:
    case HDR_CONTENTDISPOSITION_T:
    case HDR_DIVERSION_T:
    case HDR_RPID_T:
    case HDR_SIPIFMATCH_T:
    case HDR_REFER_TO_T:
    case HDR_SESSIONEXPIRES_T:
    case HDR_MIN_SE_T:
    case HDR_SUBSCRIPTION_STATE_T:
    case HDR_ACCEPTCONTACT_T:
    case HDR_ALLOWEVENTS_T:
    case HDR_CONTENTENCODING_T:
    case HDR_REFERREDBY_T:
    case HDR_REJECTCONTACT_T:
    case HDR_REQUESTDISPOSITION_T:
    case HDR_WWW_AUTHENTICATE_T:
    case HDR_PROXY_AUTHENTICATE_T:
    case HDR_PATH_T:
    case HDR_PRIVACY_T:
    case HDR_PAI_T:
    case HDR_PPI_T:
    case HDR_REASON_T:
    case HDR_OTHER_T:
        /* just skip over it */
        hdr->body.s=tmp;
        /* find end of header */
        /* find lf */
        do {
            match=q_memchr(tmp, '\n', end-tmp);
            if (match) {
                match++;
            } else {
                LOG(L_ERR,
                    "ERROR: get_hdr_field: bad body for <%s>(%d)\n",
                    hdr->name.s, hdr->type);
                /* abort(); */
                tmp=end;
                goto error;
            }
            tmp=match;
        } while( match<end &&( (*match==' ')||(*match=='\t') ) );
        tmp=match;
        hdr->body.len=match-hdr->body.s;
        break;
    default:
        LOG(L_CRIT, "BUG: get_hdr_field: unknown header type %d\n",
            hdr->type);
        goto error;
    }
    /* jku: if \r covered by current length, shrink it */
    trim_r( hdr->body );
    hdr->len=tmp-hdr->name.s;
    return tmp;
error:
    DBG("get_hdr_field: error exit\n");
    STATS_BAD_MSG_HDR();
    hdr->type=HDR_ERROR_T;
    hdr->len=tmp-hdr->name.s;
    return tmp;
}
Esempio n. 26
0
/*
 * parse acc extra element in form of
 * <backend>:<tag1>=<value1>;<tag2>=<value2>[;]
 * last semicolon may miss
 * all tags shall be added (if not present) to the tag list
 * and be linked to all extra structures in acc_extra lists by
 * the index in the vector
 *
 * @param string to be parsed(char*)
 * @return 0(success) / < 0 (error)
 */
static int parse_acc_list_generic(void* val, str2bkend str2bk,
		tag_t** tag_arr, int* tags_len)
{

	str sent={(char*)val, strlen((char*)val)};
	str tok_list_s, backend_s;

	str token, tag, value;

	struct acc_extra** bkend_list;

	char* end;


	if ((end=q_memchr(sent.s, ':', sent.len)) == NULL) {
		LM_ERR("Missing backend separator ':'!\n");
		return -1;
	}

	backend_s.s = sent.s;
	backend_s.len =  end-sent.s;
	str_trim_spaces_lr(backend_s);

	if ((bkend_list = str2bk(&backend_s)) == NULL) {
		LM_ERR("Invalid backend <%.*s>\n", backend_s.len, backend_s.s);
		return -1;
	}

	tok_list_s.s = end+1;
	tok_list_s.len = sent.len - (end - sent.s + 1);

	do {
		end=q_memchr(tok_list_s.s, ';', tok_list_s.len);

		/* get key=value parameter */
		token.s = tok_list_s.s;

		if (end != NULL) {
			token.len = end-tok_list_s.s;
			tok_list_s.len = tok_list_s.len - (end - tok_list_s.s + 1);
			tok_list_s.s = end + 1;
		} else {
			token.len = tok_list_s.len;
		}

		/* we reached the end or there are probably some trailing spaces
		 * after the last ';' */
		str_trim_spaces_lr(token);
		if (!token.len)
			break;

		if (parse_extra_token(&token, &tag, &value) < 0) {
			LM_ERR("failed to parse token!\n");
			return -1;
		}

		if (add_extra(&tag, &value, bkend_list, tag_arr, tags_len) < 0) {
			LM_ERR("failed to add extra!\n");
			return -1;
		}
	} while (end);

	return 0;
}
Esempio n. 27
0
static int set_partition_arguments(unsigned int type, void *val)
{
	static const char end_pair_delim = ';';
	static const char eq_val_delim = '=';
	static const str blacklist_param = str_init("ds_define_blacklist");
	unsigned int i;

	str raw_line = {(char*)val, strlen(val)};
	str arg, value;
	ds_db_head_t *head = NULL;

	if (raw_line.s[raw_line.len - 1] != end_pair_delim)
		raw_line.s[raw_line.len++] = end_pair_delim;

	if (parse_partition_argument(&raw_line, &head) != 0)
		return -1;

	char *first_pos = raw_line.s; /* just for error messages */
	char *end_pair_pos = q_memchr(raw_line.s, end_pair_delim, raw_line.len);
	char *eq_pos = q_memchr(raw_line.s, eq_val_delim, raw_line.len);

	while (end_pair_pos != NULL && eq_pos != NULL) {

		arg.s = raw_line.s;
		arg.len = eq_pos - arg.s;
		value.s = eq_pos + 1;
		value.len = end_pair_pos - eq_pos - 1;
		trim(&arg);
		trim(&value);

		if (arg.len <= 0 || value.len <= 0) {
			LM_ERR("Wrong format in partition arguments specifier at pos %d\n",
					(int)(arg.s - first_pos + 1));
			return -1;
		}

		for (i = 0; i < partition_param_count; ++i)
			if (str_strcmp(&arg, &partition_params[i].name) == 0) {
				*(partition_params[i].getter_func(head)) = value;
				break;
			}

		if ( i == partition_param_count) {
			if (str_strcmp(&blacklist_param, &arg) == 0) {
				value.s[value.len] = 0;
				if (set_ds_bl_partition(value.s, head->partition_name) != 0)
					return -1;
			}
			else{
				/* No paramater found */
				LM_ERR("No such parameter known: %.*s\n", arg.len, arg.s);
				return -1;
			}
		}

		raw_line.s = end_pair_pos + 1;
		end_pair_pos = q_memchr(raw_line.s, end_pair_delim, raw_line.len);
		eq_pos = q_memchr(raw_line.s, eq_val_delim, raw_line.len);
	}

	return 0;
}
Esempio n. 28
0
/* returns pointer to next header line, and fill hdr_f ;
 * if at end of header returns pointer to the last crlf  (always buf)*/
char* get_sdp_hdr_field(char* buf, char* end, struct hdr_field* hdr)
{

	char* tmp;
	char *match;

	if ((*buf)=='\n' || (*buf)=='\r'){
		/* double crlf or lflf or crcr */
		hdr->type=HDR_EOH_T;
		return buf;
	}

	tmp=parse_hname2(buf, end, hdr);
	if (hdr->type==HDR_ERROR_T){
		LM_ERR("bad header\n");
		goto error;
	}

	/* eliminate leading whitespace */
	tmp=eat_lws_end(tmp, end);
	if (tmp>=end) {
		LM_ERR("hf empty\n");
		goto error;
	}

	/* if header-field well-known, parse it, find its end otherwise ;
	 * after leaving the hdr->type switch, tmp should be set to the
	 * next header field
	 */
	switch(hdr->type){
		case HDR_CONTENTTYPE_T:
		case HDR_CONTENTDISPOSITION_T:
			/* just skip over it */
			hdr->body.s=tmp;
			/* find end of header */
			/* find lf */
			do{
				match=q_memchr(tmp, '\n', end-tmp);
				if (match){
					match++;
				}else {
					LM_ERR("bad body for <%s>(%d)\n", hdr->name.s, hdr->type);
					tmp=end;
					goto error;
				}
				tmp=match;
			}while( match<end &&( (*match==' ')||(*match=='\t') ) );
			tmp=match;
			hdr->body.len=match-hdr->body.s;
			break;
		default:
			LM_CRIT("unknown header type %d\n", hdr->type);
			goto error;
	}
	/* jku: if \r covered by current length, shrink it */
	trim_r( hdr->body );
	hdr->len=tmp-hdr->name.s;
	return tmp;
error:
	LM_DBG("error exit\n");
	hdr->type=HDR_ERROR_T;
	hdr->len=tmp-hdr->name.s;
	return tmp;
}
Esempio n. 29
0
/*
 * parse a partition parameter of type
 * <part_name> : attr1=val1; attr2=val2;
 */
int parse_partition(modparam_t t, void *val)
{
	str type, value, token;
	char *tok_end;
	struct pm_partition *el, *it;

	str decl = {(char*)val, strlen((char *)val)};

	if (get_partitions() == NULL) {
		if (alloc_partitions() == NULL)
				goto out_memfault;
		el=get_partitions();
	} else {
		el=pkg_malloc(sizeof(struct pm_partition));
		if (el == NULL)
			goto out_memfault;
		memset(el, 0, sizeof(struct pm_partition));

		for (it=get_partitions(); it->next; it=it->next);
		it->next = el;
	}

	tok_end = q_memchr(decl.s, ':', decl.len);
	if (tok_end == NULL)
		goto out_invdef;

	value.s = decl.s;
	value.len = tok_end - decl.s;

	str_trim_spaces_lr(value);

	el->name = value;

	decl.len = decl.len - (++tok_end - decl.s);
	decl.s = tok_end;

	while (decl.len > 0 && decl.s) {
		tok_end = q_memchr(decl.s, ';', decl.len);
		if (tok_end == NULL)
			break;

		token.s = decl.s;
		token.len = tok_end - token.s;

		tok_end = q_memchr(token.s, '=', token.len);
		if (tok_end == NULL)
			break;

		type.s = token.s;
		type.len = tok_end - type.s;

		value.s = tok_end + 1;
		value.len = (token.s + token.len) - value.s;

		decl.s += token.len + 1;
		decl.len -= (token.len + 1);

		str_trim_spaces_lr(type);
		str_trim_spaces_lr(value);

		if (!str_strcmp( &type, &part_db_url))
			el->url = value;
		 else if (!str_strcmp( &type, &part_table_name))
			el->table = value;
		else
			goto out_invdef;
	}

	if (el->url.s == NULL) {
		LM_ERR("you should define an URL for this partition %.*s\n",
				el->name.len, el->name.s);
		return -1;
	}

	return 0;

out_invdef:
	LM_ERR("invalid partition definition!\n");
	return -ERR;

out_memfault:
	LM_ERR("no more memory\n");
	return -ERR;
}
Esempio n. 30
0
int_list_t *set_list_from_pvs(struct sip_msg *msg, pv_spec_t *pvs, int_list_t *end)
{
	int_list_t *result = end, *new_el;
	pv_value_t value;

	if (pv_get_spec_value(msg, pvs, &value) != 0 || value.flags&PV_VAL_NULL
		|| (!(value.flags&PV_VAL_INT) && !(value.flags&PV_VAL_STR))) {

		LM_ERR("no valid PV value found (error in scripts)\n");
		return NULL;
	}

	if (value.flags & PV_VAL_INT) {
		/* Just one element */

		new_el = pkg_malloc(sizeof(int_list_t));
		if (new_el == NULL) {
			LM_ERR("no more shared memory\n");
			return NULL;
		}

		new_el->v.ival = value.ri;
		new_el->type = GPARAM_TYPE_INT;
		new_el->next = end;

		return new_el;
	}

	str sval = value.rs;

	if (sval.s == NULL)
		goto wrong_value;

	char * delim;
	do{
		delim = q_memchr(sval.s, LIST_DELIM, sval.len);
		str s_num = {sval.s, delim ? delim - sval.s : sval.len};
		sval.len -= s_num.len + 1;
		sval.s = delim + 1;
		trim(&s_num);

		int u_num;
		if (s_num.len == 0 || str2sint(&s_num, &u_num) != 0)
			goto wrong_value;

		new_el = pkg_malloc(sizeof(int_list_t));
		if (new_el == NULL) {
			goto no_memory;
		}

		new_el->v.ival = u_num;
		new_el->type = GPARAM_TYPE_INT;
		new_el->next = result;
		result = new_el;

	} while (delim);

	if (sval.len > 0)
		goto wrong_value;

return result;

no_memory:
	while(result != end) {
		if (result->type == GPARAM_TYPE_PVS)
			pkg_free(result->v.pvs);
		int_list_t *aux = result;
		result = result->next;
		pkg_free(aux);
	}
	LM_ERR("no more private memory\n");
	return NULL;

wrong_value:
	while(result != end) {
		if (result->type == GPARAM_TYPE_PVS)
			pkg_free(result->v.pvs);
		int_list_t *aux = result;
		result = result->next;
		pkg_free(aux);
	}
	LM_ERR("wrong var value <%.*s>\n", value.rs.len, value.rs.s);
	return NULL;

}