Пример #1
0
char *parse_arglist(dbref player, dbref cause, char *dstr, char delim,
					dbref eval, char *fargs[], dbref nfargs, char *cargs[],
					dbref ncargs)
{
	char *rstr, *tstr, *bp, *str;
	int arg, peval;

	for(arg = 0; arg < nfargs; arg++)
		fargs[arg] = NULL;
	if(dstr == NULL)
		return NULL;
	rstr = parse_to(&dstr, delim, 0);
	arg = 0;

	peval = (eval & ~EV_EVAL);

	while ((arg < nfargs) && rstr) {
		if(arg < (nfargs - 1))
			tstr = parse_to(&rstr, ',', peval);
		else
			tstr = parse_to(&rstr, '\0', peval);
		if(eval & EV_EVAL) {
			bp = fargs[arg] = alloc_lbuf("parse_arglist");
			str = tstr;
			exec(fargs[arg], &bp, 0, player, cause, eval | EV_FCHECK, &str,
				 cargs, ncargs);
			*bp = '\0';
		} else {
			fargs[arg] = alloc_lbuf("parse_arglist");
			StringCopy(fargs[arg], tstr);
		}
		arg++;
	}
	return dstr;
}
Пример #2
0
static int NAT_target_parse(char c,char *to_address,struct ipt_natinfo **target)
{

    switch (c) {
    case 'S':
        *target = parse_to(to_address, *target);
        return 1;
    case 'Z':
        *target = parse_to(to_address, *target);
        return 1;
    default:
        return 0;
    }
}
Пример #3
0
static void DNAT_parse(struct xt_option_call *cb)
{
	const struct ipt_entry *entry = cb->xt_entry;
	struct ipt_natinfo *info = (void *)(*cb->target);
	int portok;

	if (entry->ip.proto == IPPROTO_TCP
	    || entry->ip.proto == IPPROTO_UDP
	    || entry->ip.proto == IPPROTO_SCTP
	    || entry->ip.proto == IPPROTO_DCCP
	    || entry->ip.proto == IPPROTO_ICMP)
		portok = 1;
	else
		portok = 0;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_TO_DEST:
		if (cb->xflags & F_X_TO_DEST) {
			if (!kernel_version)
				get_kernel_version();
			if (kernel_version > LINUX_VERSION(2, 6, 10))
				xtables_error(PARAMETER_PROBLEM,
					   "DNAT: Multiple --to-destination not supported");
		}
		*cb->target = parse_to(cb->arg, portok, info);
		cb->xflags |= F_X_TO_DEST;
		break;
	case O_PERSISTENT:
		info->mr.range[0].flags |= NF_NAT_RANGE_PERSISTENT;
		break;
	}
}
Пример #4
0
static inline str* extract_mangled_fromuri(str *mangled_from_hdr)
{
	struct to_body from_b;
	struct hdr_field hdr;
	char *tmp,*end;

	if (mangled_from_hdr->len == 0 || mangled_from_hdr->s == NULL)
		return NULL;

	end = mangled_from_hdr->s+mangled_from_hdr->len;

	tmp=parse_hname2(mangled_from_hdr->s,end,&hdr);
	if (hdr.type==HDR_ERROR_T) {
		LM_ERR("bad from header\n");
		return NULL;
	}

	tmp=eat_lws_end(tmp, end);
	if (tmp >= end) {
		LM_ERR("empty header\n");
		return NULL;
	}

	parse_to(tmp,end,&from_b);
	if (from_b.error == PARSE_ERROR) {
		LM_ERR("bad from header [%.*s]\n",mangled_from_hdr->len,mangled_from_hdr->s);
		return NULL;
	}

	extracted_from_uri = from_b.uri;
	free_to_params(&from_b);

	LM_DBG("extracted from uri [%.*s]\n",extracted_from_uri.len,extracted_from_uri.s);
	return &extracted_from_uri;
}
static void DNAT_parse(struct xt_option_call *cb)
{
	const struct ip6t_entry *entry = cb->xt_entry;
	struct nf_nat_range *range = cb->data;
	int portok;

	if (entry->ipv6.proto == IPPROTO_TCP ||
	    entry->ipv6.proto == IPPROTO_UDP ||
	    entry->ipv6.proto == IPPROTO_SCTP ||
	    entry->ipv6.proto == IPPROTO_DCCP ||
	    entry->ipv6.proto == IPPROTO_ICMP)
		portok = 1;
	else
		portok = 0;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_TO_DEST:
		if (cb->xflags & F_X_TO_DEST) {
			if (!kernel_version)
				get_kernel_version();
			if (kernel_version > LINUX_VERSION(2, 6, 10))
				xtables_error(PARAMETER_PROBLEM,
					   "DNAT: Multiple --to-source not supported");
		}
		parse_to(cb->arg, portok, range);
		break;
	case O_PERSISTENT:
		range->flags |= NF_NAT_RANGE_PERSISTENT;
		break;
	}
}
Пример #6
0
/*! \brief
 * This method is used to parse DIVERSION header.
 *
 * params: msg : sip msg
 * returns 0 on success,
 *        -1 on failure.
 */
int parse_diversion_header(struct sip_msg *msg)
{
 	struct to_body* diversion_b;
	
 	if (!msg->diversion && (parse_headers(msg, HDR_DIVERSION_F, 0) == -1 ||
				!msg->diversion)) {
 		goto error;
 	}
 
 	/* maybe the header is already parsed! */
 	if (msg->diversion->parsed)
 		return 0;
 
 	/* bad luck! :-( - we have to parse it */
 	/* first, get some memory */
 	diversion_b = pkg_malloc(sizeof(struct to_body));
 	if (diversion_b == 0) {
 		LOG(L_ERR, "ERROR:parse_diversion_header: out of pkg_memory\n");
 		goto error;
 	}
 
 	/* now parse it!! */
 	memset(diversion_b, 0, sizeof(struct to_body));
 	parse_to(msg->diversion->body.s, msg->diversion->body.s + msg->diversion->body.len + 1, diversion_b);
 	if (diversion_b->error == PARSE_ERROR) {
 		LOG(L_ERR, "ERROR:parse_diversion_header: bad diversion header\n");
 		free_to(diversion_b);
 		goto error;
 	}
 	msg->diversion->parsed = diversion_b;
	
 	return 0;
 error:
 	return -1;
}
Пример #7
0
/**
 * Returns the Public Identity extracted from the From header
 * @param msg - the SIP message
 * @returns the str containing the public id, no mem dup
 */
str cscf_get_public_identity_from(struct sip_msg *msg)
{
	str pu={0,0};
	struct to_body *from;
	int i;

	if (parse_headers(msg,HDR_FROM_F,0)!=0) {
		return pu;
	}

	if ( get_from(msg) == NULL ) {
		from = (struct to_body*) pkg_malloc(sizeof(struct to_body));
		parse_to( msg->from->body.s, msg->from->body.s + msg->from->body.len, from );
		msg->from->parsed = from;
	}
	else from=(struct to_body *) msg->from->parsed;

	pu = from->uri;

	/* truncate to sip:username@host or tel:number */
	for(i=4;i<pu.len;i++)
		if (pu.s[i]==';' || pu.s[i]=='?' ||pu.s[i]==':'){
			pu.len = i;
		}

	return pu;
}
Пример #8
0
/*! \brief
 * This method is used to parse RPID header.
 *
 * params: msg : sip msg
 * returns 0 on success,
 *        -1 on failure.
 */
int parse_rpid_header( struct sip_msg *msg )
{
	struct to_body* rpid_b;
	
 	if ( !msg->rpid && (parse_headers(msg, HDR_RPID_F, 0)==-1 || !msg->rpid)) {
 		goto error;
 	}
 
 	/* maybe the header is already parsed! */
 	if (msg->rpid->parsed)
 		return 0;
 
 	/* bad luck! :-( - we have to parse it */
 	/* first, get some memory */
 	rpid_b = pkg_malloc(sizeof(struct to_body));
 	if (rpid_b == 0) {
 		LOG(L_ERR, "ERROR:parse_rpid_header: out of pkg_memory\n");
 		goto error;
 	}
 
 	/* now parse it!! */
 	memset(rpid_b, 0, sizeof(struct to_body));
 	parse_to(msg->rpid->body.s,msg->rpid->body.s+msg->rpid->body.len+1,rpid_b);
 	if (rpid_b->error == PARSE_ERROR) {
 		LOG(L_ERR, "ERROR:parse_rpid_header: bad rpid header\n");
 		free_to(rpid_b);
 		goto error;
 	}
 	msg->rpid->parsed = rpid_b;
 
 	return 0;
 error:
 	return -1;
}
Пример #9
0
struct to_body* get_appearance_name_addr(struct sip_msg* msg)
{
	int len = 0;

	if(appearance_name_addr_spec_param.s)
	{
		memset(&appearance_name_addr_tok, 0, sizeof(pv_value_t));
		if(pv_get_spec_value(msg, &appearance_name_addr_spec, &appearance_name_addr_tok) < 0)
		{
			LM_ERR("Failed to get appearance_name_addr value\n");
			return NULL;
		}
		//LM_DBG("got appearance_name_addr_spec_param flags [%d]\n", appearance_name_addr_tok.flags);
		if(!(appearance_name_addr_tok.flags&PV_VAL_INT) &&
			(appearance_name_addr_tok.flags&PV_VAL_STR))
		{
			//LM_DBG("got PV_SPEC appearance_name_addr [%.*s]\n",
			//	appearance_name_addr_tok.rs.len, appearance_name_addr_tok.rs.s);
			if(appearance_name_addr_tok.rs.len+CRLF_LEN > APPEARANCE_NAME_ADDR_BUF_LEN) {
				LM_ERR("Buffer overflow\n");
				return NULL;
			}
			trim(&appearance_name_addr_tok.rs);
			memcpy(appearance_name_addr_buf, appearance_name_addr_tok.rs.s,
				appearance_name_addr_tok.rs.len);
			len = appearance_name_addr_tok.rs.len;
			if(strncmp(appearance_name_addr_tok.rs.s + len - CRLF_LEN, CRLF, CRLF_LEN)) {
				memcpy(appearance_name_addr_buf + len, CRLF, CRLF_LEN);
				len+= CRLF_LEN;
			}

			parse_to(appearance_name_addr_buf, appearance_name_addr_buf+len,
				&appearance_name_addr);
			if (appearance_name_addr.error != PARSE_OK) {
				LM_ERR("Failed to parse PV_SPEC appearance_name_addr [%.*s]\n",
					len, appearance_name_addr_buf);
				return NULL;
			}
			if (parse_uri(appearance_name_addr.uri.s, appearance_name_addr.uri.len,
					&appearance_name_addr.parsed_uri)<0) {
				LM_ERR("failed to parse PV_SPEC appearance_name_addr uri [%.*s]\n",
					appearance_name_addr.uri.len, appearance_name_addr.uri.s);
				return NULL;
			}
			return &appearance_name_addr;
		}
	}

	/* If the appearance_name_addr_spec_param is not set, use the From uri */
	/*
	if (msg->from->parsed == NULL) {
		if (parse_from_header(msg)<0) {
			LM_ERR("cannot parse From header\n");
			return NULL;
		}
	}
	*/

	return msg->from->parsed;
}
Пример #10
0
    int
sca_get_msg_to_header( sip_msg_t *msg, struct to_body **to )
{
    struct to_body	parsed_to;
    struct to_body	*t = NULL;

    assert( msg != NULL );
    assert( to != NULL );

    if ( SCA_HEADER_EMPTY( msg->to )) {
	LM_ERR( "Empty To header" );
	return( -1 );
    }
    t = get_to( msg );
    if ( t == NULL ) {
	parse_to( msg->to->body.s,
		  msg->to->body.s + msg->to->body.len + 1, /* end of buffer */
		  &parsed_to );
	if ( parsed_to.error != PARSE_OK ) {
	    LM_ERR( "Bad To header" );
	    return( -1 );
	}
	t = &parsed_to;
    }

    /* ensure the URI is parsed for future use */
    if ( parse_uri( t->uri.s, t->uri.len, GET_TO_PURI( msg )) < 0 ) {
	LM_ERR( "Failed to parse To URI %.*s", STR_FMT( &t->uri ));
	return( -1 );
    }

    *to = t;

    return( 0 );
}
Пример #11
0
struct to_body* get_b2bl_from(struct sip_msg* msg)
{
	int len = 0;

	if(b2bl_from_spec_param.s)
	{
		memset(&b2bl_from_tok, 0, sizeof(pv_value_t));
		if(pv_get_spec_value(msg, &b2bl_from_spec, &b2bl_from_tok) < 0)
		{
			LM_ERR("Failed to get b2bl_from value\n");
			return NULL;
		}
		//LM_DBG("got b2bl_from_spec_param flags [%d]\n", b2bl_from_tok.flags);
		if(b2bl_from_tok.flags&PV_VAL_INT)
		{
			/* the PV might be empty */
			return NULL;
		}
		if(b2bl_from_tok.flags&PV_VAL_STR)
		{
			//LM_DBG("got PV_SPEC b2bl_from [%.*s]\n",
			//	b2bl_from_tok.rs.len, b2bl_from_tok.rs.s);
			if(b2bl_from_tok.rs.len+CRLF_LEN > B2BL_FROM_BUF_LEN) {
				LM_ERR("Buffer overflow\n");
				return NULL;
			}
			trim(&b2bl_from_tok.rs);
			memcpy(b2bl_from_buf, b2bl_from_tok.rs.s,
				b2bl_from_tok.rs.len);
			len = b2bl_from_tok.rs.len;
			if(strncmp(b2bl_from_tok.rs.s + len - CRLF_LEN, CRLF, CRLF_LEN)) {
				memcpy(b2bl_from_buf + len, CRLF, CRLF_LEN);
				len+= CRLF_LEN;
			}

			parse_to(b2bl_from_buf, b2bl_from_buf+len,
				&b2bl_from);
			if (b2bl_from.error != PARSE_OK) {
				LM_ERR("Failed to parse PV_SPEC b2bl_from [%.*s]\n",
					len, b2bl_from_buf);
				return NULL;
			}
			if (parse_uri(b2bl_from.uri.s, b2bl_from.uri.len,
					&b2bl_from.parsed_uri)<0) {
				LM_ERR("failed to parse PV_SPEC b2bl_from uri [%.*s]\n",
					b2bl_from.uri.len, b2bl_from.uri.s);
				return NULL;
			}

			/* side effect of parsing - nobody should need them later on,
			 * so free them right now */
			free_to_params(&b2bl_from);
			return &b2bl_from;
		}
	}

	return NULL;
}
Пример #12
0
/*
 * Get user part from P-Charge-Info header
 * param msg SIP message
 * param user User part of P-Charge-Info header
 * param bufsize Size of fromuser buffer
 * return 0 success, 1 without P-Charge-Info, -1 failure
 */
int ospGetPChargeInfoUserpart(
    struct sip_msg* msg,
    char* pciuser,
    int bufsize)
{
    static const char* header = "P-Charge-Info";
    struct to_body body;
    struct to_body* pci=NULL;
    struct hdr_field *hf;
    struct sip_uri uri;
    int result = -1;

    if ((pciuser != NULL) && (bufsize > 0)) {
        pciuser[0] = '\0';
        if (parse_headers(msg, HDR_EOH_F, 0) < 0) {
            LM_ERR("failed to parse message\n");
            return -1;
        }
        for (hf = msg->headers; hf; hf = hf->next) {
            if ((hf->type == HDR_OTHER_T) &&
                (hf->name.len == strlen(header)) &&
                (strncasecmp(hf->name.s, header, hf->name.len) == 0))
            {
                if (!(pci = hf->parsed)) {
                    pci = &body;
                    parse_to(hf->body.s, hf->body.s + hf->body.len + 1, pci);
                }
                if (pci->error != PARSE_ERROR) {
                    if (parse_uri(pci->uri.s, pci->uri.len, &uri) == 0) {
                        ospCopyStrToBuffer(&uri.user, pciuser, bufsize);
                        ospSkipUserParam(pciuser);
                        result = 0;
                    } else {
                        LM_ERR("failed to parse P-Charge-Info uri\n");
                    }
                    if (pci == &body) {
                        free_to_params(pci);
                    }
                } else {
                    LM_ERR("bad P-Charge-Info header\n");
                }
                break;
            }
        }
        if (!hf) {
            LM_DBG("without P-Charge-Info header\n");
            result = 1;
        }
    } else {
        LM_ERR("bad parameters to parse user part from PAI\n");
    }

    return result;
}
Пример #13
0
static int SNAT_parse(int c, char **argv, int invert, unsigned int *flags,
                      const void *e, struct xt_entry_target **target)
{
	const struct ipt_entry *entry = e;
	struct ipt_natinfo *info = (void *)*target;
	int portok;

	if (entry->ip.proto == IPPROTO_TCP
	    || entry->ip.proto == IPPROTO_UDP
	    || entry->ip.proto == IPPROTO_SCTP
	    || entry->ip.proto == IPPROTO_DCCP
	    || entry->ip.proto == IPPROTO_ICMP)
		portok = 1;
	else
		portok = 0;

	switch (c) {
	case '1':
		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
			xtables_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --to-source");

		if (*flags & IPT_SNAT_OPT_SOURCE) {
			if (!kernel_version)
				get_kernel_version();
			if (kernel_version > LINUX_VERSION(2, 6, 10))
				xtables_error(PARAMETER_PROBLEM,
					   "Multiple --to-source not supported");
		}
		*target = parse_to(optarg, portok, info);
		/* WTF do we need this for?? */
		if (*flags & IPT_SNAT_OPT_RANDOM)
			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
		*flags |= IPT_SNAT_OPT_SOURCE;
		return 1;

	case '2':
		if (*flags & IPT_SNAT_OPT_SOURCE) {
			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
			*flags |= IPT_SNAT_OPT_RANDOM;
		} else
			*flags |= IPT_SNAT_OPT_RANDOM;
		return 1;

	case '3':
		info->mr.range[0].flags |= IP_NAT_RANGE_PERSISTENT;
		return 1;

	default:
		return 0;
	}
}
Пример #14
0
// ---------------------------------------------------------------------------
// do_query: Command interface to sql_que
//
void do_query
(
    dbref executor,
    dbref caller,
    dbref enactor,
    int   eval,
    int   key,
    char *dbref_attr,
    char *dbname_query,
    char *cargs[],
    int   ncargs
)
{
    if (key & QUERY_SQL)
    {
        // SQL Query.
        //
        dbref thing;
        ATTR *pattr;

        if (!( parse_attrib(executor, dbref_attr, &thing, &pattr)
            && pattr))
        {
            notify_quiet(executor, "No match.");
            return;
        }

        if (!Controls(executor, thing))
        {
            notify_quiet(executor, NOPERM_MESSAGE);
            return;
        }

        char *pQuery = dbname_query;
        char *pDBName = parse_to(&pQuery, '/', 0);

        if (NULL == pQuery)
        {
            notify(executor, "QUERY: No Query.");
            return;
        }

        STARTLOG(LOG_ALWAYS, "CMD", "QUERY");
        Log.tinyprintf("Thing=#%d, Attr=%s, dbname=%s, query=%s", thing, pattr->name, pDBName, pQuery);
        ENDLOG;
    }
    else
    {
        notify_quiet(executor, "At least one query option is required.");
    }
}
Пример #15
0
/* Function which parses command options; returns true if it
   ate an option */
static int SAME_parse(int c, char **argv, int invert, unsigned int *flags,
                      const void *entry, struct xt_entry_target **target)
{
	struct ipt_same_info *mr
		= (struct ipt_same_info *)(*target)->data;
	unsigned int count;

	switch (c) {
	case '1':
		if (mr->rangesize == IPT_SAME_MAX_RANGE)
			exit_error(PARAMETER_PROBLEM,
				   "Too many ranges specified, maximum "
				   "is %i ranges.\n",
				   IPT_SAME_MAX_RANGE);
		if (check_inverse(optarg, &invert, NULL, 0))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --to");

		parse_to(optarg, &mr->range[mr->rangesize]);
		/* WTF do we need this for? */
		if (*flags & IPT_SAME_OPT_RANDOM)
			mr->range[mr->rangesize].flags 
				|= IP_NAT_RANGE_PROTO_RANDOM;
		mr->rangesize++;
		*flags |= IPT_SAME_OPT_TO;
		break;
		
	case '2':
		if (*flags & IPT_SAME_OPT_NODST)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --nodst twice");
		
		mr->info |= IPT_SAME_NODST;
		*flags |= IPT_SAME_OPT_NODST;
		break;

	case '3':	
		*flags |= IPT_SAME_OPT_RANDOM;
		for (count=0; count < mr->rangesize; count++)
			mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM;
		break;

	default:
		return 0;
	}
	
	return 1;
}
Пример #16
0
/*
 * This method is used to parse the from header. It was decided not to parse
 * anything in core that is not *needed* so this method gets called by
 * rad_acc module and any other modules that needs the FROM header.
 *
 * params: msg : sip msg
 * returns =0 on success,
 *         <0 on failure.
 */
int parse_from_header( struct sip_msg *msg)
{
    struct to_body* from_b;

    if ( !msg->from && ( parse_headers(msg,HDR_FROM_F,0)==-1 || !msg->from)) {
        LM_ERR("bad msg or missing FROM header\n");
        goto error;
    }

    /* maybe the header is already parsed! */
    if (msg->from->parsed)
        return 0;

    /* bad luck! :-( - we have to parse it */
    /* first, get some memory */
    from_b = pkg_malloc(sizeof(struct to_body));
    if (from_b == 0) {
        LM_ERR("out of pkg_memory\n");
        goto error;
    }

    /* now parse it!! */
    memset(from_b, 0, sizeof(struct to_body));
    parse_to(msg->from->body.s,msg->from->body.s+msg->from->body.len+1,from_b);
    if (from_b->error == PARSE_ERROR) {
        LM_ERR("bad from header\n");
        pkg_free(from_b);
        /*TODO - error
        set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
        	"error parsing From header");
        set_err_reply(400, "bad header");
         * */
        goto error;
    }
    /* REGISTER doesn't have a from tag :( -bogdan
    if (from_b->tag_value.len==0 || from_b->tag_value.s==0) {
    	LM_ERR("missing TAG value\n");
    	free_to(from_b);
    	goto error;
    }
    */
    msg->from->parsed = from_b;

    return 0;
error:
    return -1;
}
Пример #17
0
/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ipt_entry *entry,
      struct ipt_entry_target **target)
{
	struct ipt_natinfo *info = (void *)*target;
	int portok;

	if (entry->ip.proto == IPPROTO_TCP
	    || entry->ip.proto == IPPROTO_UDP
	    || entry->ip.proto == IPPROTO_ICMP)
		portok = 1;
	else
		portok = 0;

	switch (c) {
	case '1':
		if (check_inverse(optarg, &invert, NULL, 0))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --to-destination");

		if (*flags) {
			if (!kernel_version)
				get_kernel_version();
			if (kernel_version > LINUX_VERSION(2, 6, 10))
				exit_error(PARAMETER_PROBLEM,
					   "Multiple --to-destination not supported");
		}
		*target = parse_to(optarg, portok, info);
		/* WTF do we need this for?? */
		if (*flags & IPT_DNAT_OPT_RANDOM)
			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
		*flags |= IPT_DNAT_OPT_DEST;
		return 1;

	case '2':
		if (*flags & IPT_DNAT_OPT_DEST) {
			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
			*flags |= IPT_DNAT_OPT_RANDOM;
		} else
			*flags |= IPT_DNAT_OPT_RANDOM;
		return 1;
	default:
		return 0;
	}
}
Пример #18
0
/*
 * This method is used to parse P-Asserted-Identity header (RFC 3325).
 *
 * Currently only one name-addr / addr-spec is supported in the header
 * and it must contain a sip or sips URI.
 *
 * params: msg : sip msg
 * returns 0 on success,
 *        -1 on failure.
 */
int parse_pai_header( struct sip_msg *msg )
{
    struct to_body* pai_b;
    
    if ( !msg->pai &&
	 (parse_headers(msg, HDR_PAI_F,0)==-1 || !msg->pai)) {
	goto error;
    }
 
    /* maybe the header is already parsed! */
    if (msg->pai->parsed)
	return 0;
 
    /* bad luck! :-( - we have to parse it */
    /* first, get some memory */
    pai_b = pkg_malloc(sizeof(struct to_body));
    if (pai_b == 0) {
	LM_ERR("out of pkg_memory\n");
	goto error;
    }
 
    /* now parse it!! */
    memset(pai_b, 0, sizeof(struct to_body));
    parse_to(msg->pai->body.s,
	     msg->pai->body.s + msg->pai->body.len+1,
	     pai_b);
    if (pai_b->error == PARSE_ERROR) {
	LM_ERR("bad P-Asserted-Identity header\n");
	pkg_free(pai_b);
	/* TODO - error
	set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
		"error parsing PAI header");
	set_err_reply(400, "bad header");
	 * */
	goto error;
    }
 	msg->pai->parsed = pai_b;
 
 	return 0;
 error:
 	return -1;
}
Пример #19
0
static void SAME_parse(struct xt_option_call *cb)
{
    struct ipt_same_info *mr = cb->data;

    xtables_option_parse(cb);
    switch (cb->entry->id) {
    case O_TO_ADDR:
        if (mr->rangesize == IPT_SAME_MAX_RANGE)
            xtables_error(PARAMETER_PROBLEM,
                          "Too many ranges specified, maximum "
                          "is %i ranges.\n",
                          IPT_SAME_MAX_RANGE);
        parse_to(cb->arg, &mr->range[mr->rangesize]);
        mr->rangesize++;
        break;
    case O_NODST:
        mr->info |= IPT_SAME_NODST;
        break;
    }
}
static int NETMAP_parse(int c, char **argv, int invert, unsigned int *flags,
                        const void *entry, struct xt_entry_target **target)
{
	struct nf_nat_multi_range *mr
		= (struct nf_nat_multi_range *)(*target)->data;

	switch (c) {
	case '1':
		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
			xtables_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --%s", NETMAP_opts[0].name);

		parse_to(optarg, &mr->range[0]);
		*flags = 1;
		return 1;

	default:
		return 0;
	}
}
Пример #21
0
/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ipt_entry *entry,
      struct ipt_entry_target **target)
{
	struct ipt_same_info *mr
		= (struct ipt_same_info *)(*target)->data;

	switch (c) {
	case '1':
		if (mr->rangesize == IPT_SAME_MAX_RANGE)
			exit_error(PARAMETER_PROBLEM,
				   "Too many ranges specified, maximum "
				   "is %i ranges.\n",
				   IPT_SAME_MAX_RANGE);
		if (check_inverse(optarg, &invert, NULL, 0))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --to");

		parse_to(optarg, &mr->range[mr->rangesize]);
		mr->rangesize++;
		*flags |= IPT_SAME_OPT_TO;
		break;
		
	case '2':
		if (*flags & IPT_SAME_OPT_NODST)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --nodst twice");
		
		mr->info |= IPT_SAME_NODST;
		*flags |= IPT_SAME_OPT_NODST;
		break;
		
	default:
		return 0;
	}
	
	return 1;
}
Пример #22
0
/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ipt_entry *entry,
      struct ipt_entry_target **target)
{
	struct ip_nat_multi_range *mr
		= (struct ip_nat_multi_range *)(*target)->data;

	switch (c) {
	case '1':
		if (check_inverse(optarg, &invert, NULL, 0))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --%s", opts[0].name);

		parse_to(optarg, &mr->range[0]);
		*flags = 1;
		return 1;

	default:
		return 0;
	}
}
Пример #23
0
/*
 * This method is used to parse Refer-To header.
 *
 * params: msg : sip msg
 * returns 0 on success,
 *        -1 on failure.
 */
int parse_refer_to_header( struct sip_msg *msg )
{
	struct to_body* refer_to_b;
	
	if ( !msg->refer_to &&
	(parse_headers(msg, HDR_REFER_TO_F,0)==-1 || !msg->refer_to)) {
		goto error;
	}

	/* maybe the header is already parsed! */
	if (msg->refer_to->parsed)
		return 0;

	/* bad luck! :-( - we have to parse it */
	/* first, get some memory */
	refer_to_b = pkg_malloc(sizeof(struct to_body));
	if (refer_to_b == 0) {
		LM_ERR("out of pkg_memory\n");
		goto error;
	}

	/* now parse it!! */
	parse_to(msg->refer_to->body.s,
		msg->refer_to->body.s + msg->refer_to->body.len+1,
		refer_to_b);
	if (refer_to_b->error == PARSE_ERROR) {
		LM_ERR("bad Refer-To header\n");
		pkg_free(refer_to_b);
		set_err_info(OSER_EC_PARSER, OSER_EL_MEDIUM,
			"error parsing REFER-TO header");
		set_err_reply(400, "bad headers");
		goto error;
	}
	msg->refer_to->parsed = refer_to_b;

	return 0;
error:
	return -1;
}
Пример #24
0
/**
 * Returns the Public Identity extracted from the To header
 * @param msg - the SIP message
 * @returns the str containing the private id, no mem dup
 */
str cscf_get_public_identity(struct sip_msg *msg)
{
	str pu={0,0};
	struct to_body *to;
	
	if (parse_headers(msg,HDR_TO_F,0)!=0) {
		LOG(L_ERR,"ERR:"M_NAME":cscf_get_public_identity: Error parsing until header To: \n");
		return pu;
	}
	
	if ( get_to(msg) == NULL ) {
		to = (struct to_body*) pkg_malloc(sizeof(struct to_body));
		parse_to( msg->to->body.s, msg->to->body.s + msg->to->body.len, to );
		msg->to->parsed = to;
	}
		else to=(struct to_body *) msg->to->parsed;
	
	pu = to->uri;
	
	LOG(L_DBG,"DBG:"M_NAME":cscf_get_public_identity: <%.*s> \n",
		pu.len,pu.s);
	return pu;
}
Пример #25
0
/*!
 * \brief This method is used to parse P-Preferred-Identity header (RFC 3325).
 *
 * Currently only one name-addr / addr-spec is supported in the header
 * and it must contain a sip or sips URI.
 * \param msg sip msg
 * \return 0 on success, -1 on failure.
 */
int parse_ppi_header( struct sip_msg *msg )
{
    struct to_body* ppi_b;

    if ( !msg->ppi &&
	 (parse_headers(msg, HDR_PPI_F,0)==-1 || !msg->ppi)) {
	goto error;
    }
 
    /* maybe the header is already parsed! */
    if (msg->ppi->parsed)
	return 0;
 
    /* bad luck! :-( - we have to parse it */
    /* first, get some memory */
    ppi_b = pkg_malloc(sizeof(struct to_body));
    if (ppi_b == 0) {
	LM_ERR("out of pkg_memory\n");
	goto error;
    }
 
    /* now parse it!! */
    memset(ppi_b, 0, sizeof(struct to_body));
    parse_to(msg->ppi->body.s,
	     msg->ppi->body.s + msg->ppi->body.len+1,
	     ppi_b);
    if (ppi_b->error == PARSE_ERROR) {
	LM_ERR("bad P-Preferred-Identity header\n");
	pkg_free(ppi_b);
	goto error;
    }
 	msg->ppi->parsed = ppi_b;
 
 	return 0;
 error:
 	return -1;
}
Пример #26
0
/*! \brief
 * This method is used to parse the from header.
 *
 * \note It was decided not to parse
 * anything in core that is not *needed* so this method gets called by 
 * rad_acc module and any other modules that needs the FROM header.
 *
 * params: msg : sip msg
 * returns 0 on success,
 *        -1 on failure.
 */
int parse_from_header( struct sip_msg *msg)
{
	struct to_body* from_b;

	if ( !msg->from && ( parse_headers(msg,HDR_FROM_F,0)==-1 || !msg->from)) {
		LOG(L_ERR,"ERROR:parse_from_header: bad msg or missing FROM header\n");
		goto error;
	}

	/* maybe the header is already parsed! */
	if (msg->from->parsed)
		return 0;

	/* bad luck! :-( - we have to parse it */
	/* first, get some memory */
	from_b = pkg_malloc(sizeof(struct to_body));
	if (from_b == 0) {
		LOG(L_ERR, "ERROR:parse_from_header: out of pkg_memory\n");
		goto error;
	}

	/* now parse it!! */
	memset(from_b, 0, sizeof(struct to_body));
	parse_to(msg->from->body.s,msg->from->body.s+msg->from->body.len+1,from_b);
	if (from_b->error == PARSE_ERROR) {
		LOG(L_ERR, "ERROR:parse_from_header: bad from header [%.*s]\n",
				msg->from->body.len, msg->from->body.s);
		free_to(from_b);
		goto error;
	}
	msg->from->parsed = from_b;

	return 0;
error:
	return -1;
}
Пример #27
0
/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ipt_entry *entry,
      struct ipt_entry_target **target)
{
	struct ipt_natinfo *info = (void *)*target;
	int portok;

	if (entry->ip.proto == IPPROTO_TCP
	    || entry->ip.proto == IPPROTO_UDP
	    || entry->ip.proto == IPPROTO_ICMP)
		portok = 1;
	else
		portok = 0;

	switch (c) {
	case '1':
		if (check_inverse(optarg, &invert, NULL, 0))
			exit_error(PARAMETER_PROBLEM,
				   "Unexpected `!' after --to-source");

		if (*flags) {
			if (!kernel_version)
				get_kernel_version();
			if (kernel_version > LINUX_VERSION(2, 6, 10))
				exit_error(PARAMETER_PROBLEM,
					   "Multiple --to-source not supported");
		}
		*target = parse_to(optarg, portok, info);
		*flags = 1;
		return 1;

	default:
		return 0;
	}
}
Пример #28
0
int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
{
	struct to_body *pto, TO = {0}, *pfrom = NULL;
	str body= {0, 0};
	ua_pres_t dialog;
	str* res_id= NULL;
	db_key_t query_cols[8];
	db_val_t query_vals[8];
	int n_query_cols= 0;
	str auth_state= {0, 0};
	int found= 0;
	str reason = {0, 0};
	int auth_flag;
	struct hdr_field* hdr= NULL;
	int expires= -1;
	str content_type= {0, 0};
	int reply_code = 500;
	str reply_str = pu_500_rpl;

	LM_DBG("start\n");
	/* extract the dialog information and check if an existing dialog*/	
	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
				pto->uri.len, pto->uri.s );	
	}
	else
	{
		parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
		if(TO.uri.len <= 0) 
		{
			LM_ERR(" 'To' header NOT parsed\n");
			reply_code = 400;
			reply_str = pu_400_rpl;
			goto error;
		}
		pto = &TO;
	}
	memset(&dialog, 0, sizeof(ua_pres_t));
	dialog.watcher_uri= &pto->uri;
	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.from_tag= pto->tag_value;
	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("cannot find 'from' header!\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		LM_DBG("'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 ) 
		{
			LM_ERR("cannot parse From header\n");
			reply_code = 400;
			reply_str = pu_400_rpl;
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= RLS_SUBSCRIBE;

	dialog.event= get_event_flag(&msg->event->body);
	if(dialog.event< 0)
	{
		LM_ERR("unrecognized event package\n");
		reply_code = 489;
		reply_str = pu_489_rpl;
		goto error;
	}

	/* extract the subscription state */
	hdr = msg->headers;
	while (hdr!= NULL)
	{
		if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)  
		{
			found = 1;
			break;
		}
		hdr = hdr->next;
	}
	if(found==0 )
	{
		LM_ERR("'Subscription-State' header not found\n");
		goto error;
	}
	auth_state = hdr->body;

	/* extract state and reason */
	auth_flag= parse_subs_state(auth_state, &reason, &expires);
	if(auth_flag< 0)
	{
		LM_ERR("while parsing 'Subscription-State' header\n");
		goto error;
	}
	if(pua_get_record_id(&dialog, &res_id)< 0) /* verify if within a stored dialog */
	{
		LM_ERR("occured when trying to get record id\n");
		goto error;
	}
	if(res_id==0)
	{
		LM_DBG("presence dialog record not found\n");
		/* if it is a NOTIFY for a terminated SUBSCRIBE dialog in RLS, then
		 * the module might not have the dialog structure anymore
		 * - just send 200ok, it is harmless
		 */
		if(auth_flag==TERMINATED_STATE)
			goto done;
		LM_INFO("no presence dialog record for non-TERMINATED state uri pres_uri = %.*s watcher_uri = %.*s\n",
                dialog.pres_uri->len, dialog.pres_uri->s, dialog.watcher_uri->len, dialog.watcher_uri->s);
		reply_code = 481;
		reply_str = pu_481_rpl;
		goto error;
	}
		
	if(msg->content_type== NULL || msg->content_type->body.s== NULL)
	{
		LM_DBG("cannot find content type header header\n");
	}
	else
		content_type= msg->content_type->body;
					
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{	
		goto done;
	}	
	else
	{
		if(content_type.s== 0)
		{
			LM_ERR("content length != 0 and no content type header found\n");
			goto error;
		}
		body.s=get_body(msg);
		if (body.s== NULL) 
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
		body.len = get_content_length( msg );

	}
	/* update in rlpres_table where rlsusb_did= res_id and resource_uri= from_uri*/

	LM_DBG("body= %.*s\n", body.len, body.s);

	query_cols[n_query_cols]= &str_rlsubs_did_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *res_id; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_resource_uri_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *dialog.pres_uri; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_updated_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	if (dbmode == RLS_DB_ONLY)
		query_vals[n_query_cols].val.int_val=
			core_hash(res_id, NULL, 0) %
				(waitn_time * rls_notifier_poll_rate
					* rls_notifier_processes);
	else
		query_vals[n_query_cols].val.int_val = UPDATED_TYPE;
	n_query_cols++;
		
	query_cols[n_query_cols]= &str_auth_state_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= auth_flag; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_reason_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	if(reason.len > 0)
	{
		query_vals[n_query_cols].val.str_val.s= reason.s;
		query_vals[n_query_cols].val.str_val.len= reason.len;
	}	
	else
	{
		query_vals[n_query_cols].val.str_val.s = "";
		query_vals[n_query_cols].val.str_val.len = 0;
	}
	n_query_cols++;

	query_cols[n_query_cols]= &str_content_type_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= content_type;
	n_query_cols++;
			
	query_cols[n_query_cols]= &str_presence_state_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= body;
	n_query_cols++;
		
	query_cols[n_query_cols]= &str_expires_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= expires+ (int)time(NULL);
	n_query_cols++;

	if (rlpres_dbf.use_table(rlpres_db, &rlpres_table) < 0) 
	{
		LM_ERR("in use_table\n");
		goto error;
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.start_transaction)
	{
		if (rlpres_dbf.start_transaction(rlpres_db) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	if (rlpres_dbf.replace != NULL)
	{
		if(rlpres_dbf.replace(rlpres_db, query_cols, query_vals, n_query_cols,
					2, 0)< 0)
		{
			LM_ERR("in sql replace\n");
			goto error;
		}
		LM_DBG("Inserted/replace in database table new record\n");
	}
	else
	{
		if(rlpres_dbf.update(rlpres_db, query_cols, 0, query_vals, query_cols+2,
						query_vals+2, 2, n_query_cols-2)< 0)
		{
			LM_ERR("in sql update\n");
			goto error;
		}

		if (rlpres_dbf.affected_rows(rlpres_db) == 0)
		{
			if(rlpres_dbf.insert(rlpres_db, query_cols, query_vals, n_query_cols)< 0)
			{
				LM_ERR("in sql insert\n");
				goto error;
			}
			LM_DBG("Inserted in database table new record\n");
		}
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.end_transaction)
	{
		if (rlpres_dbf.end_transaction(rlpres_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}

	LM_DBG("Updated rlpres_table\n");	
	/* reply 200OK */
done:
	if(slb.freply(msg, 200, &su_200_rpl) < 0)
	{
		LM_ERR("while sending reply\n");
		goto error;
	}

	if(res_id!=NULL)
	{
		pkg_free(res_id->s);
		pkg_free(res_id);
	}

	if (reason.s) pkg_free(reason.s);

	free_to_params(&TO);
	return 1;

error:
	if(slb.freply(msg, reply_code, &reply_str) < 0)
	{
		LM_ERR("failed sending reply\n");
	}
	if(res_id!=NULL)
	{
		pkg_free(res_id->s);
		pkg_free(res_id);
	}

	if (reason.s) pkg_free(reason.s);

	free_to_params(&TO);

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.abort_transaction)
	{
		if (rlpres_dbf.abort_transaction(rlpres_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

	return -1;
}
Пример #29
0
void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps)
{
	struct sip_msg* msg= NULL;
	int lexpire= 0;
	unsigned int cseq;
	ua_pres_t* presentity= NULL, *hentity= NULL;
	struct to_body *pto = NULL, TO = {0}, *pfrom = NULL;
	int size= 0;
	unsigned int hash_code;
	int flag ;
	str record_route= {0, 0};
	int rt;
	str contact;
	int initial_request = 0;
	int end_transaction = 1;

	if( ps->param== NULL || *ps->param== NULL )
	{
		LM_ERR("null callback parameter\n");
		return;
	}

	if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction)
	{
		if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	LM_DBG("completed with status %d\n",ps->code) ;
	hentity= (ua_pres_t*)(*ps->param);
	hash_code= core_hash(hentity->pres_uri,hentity->watcher_uri,
				HASH_SIZE);
	flag= hentity->flag;
	if(hentity->flag & XMPP_INITIAL_SUBS)
		hentity->flag= XMPP_SUBSCRIBE;

	/* get dialog information from reply message: callid, to_tag, from_tag */
	msg= ps->rpl;
	if(msg == NULL)
	{
		LM_ERR("no reply message found\n ");
		goto error;
	}

	if(msg== FAKED_REPLY)
	{
		struct hdr_field *callid = NULL, *from = NULL;
		struct to_body FROM = {0};

		callid = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field));
		if (callid == NULL)
		{
			LM_ERR("Out of memory\n");
			goto faked_error;
		}
		memset(callid, 0, sizeof(struct hdr_field));
		get_hdr_field(t->callid.s, t->callid.s + t->callid.len, callid);
		hentity->call_id = callid->body;

		from = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field));
		if (from == NULL)
		{
			LM_ERR("Out of memory\n");
			goto faked_error;
		}
		memset(from, 0, sizeof(struct hdr_field));
		get_hdr_field(t->from.s, t->from.s + t->from.len, from);
		parse_to(from->body.s, from->body.s + from->body.len + 1, &FROM);
		if(FROM.uri.len <= 0) 
		{
			LM_ERR("'From' header NOT parsed\n");
			goto faked_error;
		}
	
		hentity->call_id = callid->body;
		hentity->from_tag = (&FROM)->tag_value;
		hentity->to_tag.s = NULL;
		hentity->to_tag.len = 0;

		find_and_delete_dialog(hentity, hash_code);
faked_error:
		if (callid) pkg_free(callid);
		free_to_params(&FROM);
		if (from) pkg_free(from);
		goto done;
	}
	
	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("when parsing headers\n");
		goto error;
	}

	if(ps->rpl->expires && msg->expires->body.len > 0)
	{
		if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
		{
			LM_ERR("cannot parse Expires header\n");
			goto error;
		}
		lexpire = ((exp_body_t*)msg->expires->parsed)->val;
		LM_DBG("lexpire= %d\n", lexpire);
	}

	/*if initial request */
	if(hentity->call_id.s== NULL)
	{
		initial_request = 1;

		if( msg->callid==NULL || msg->callid->body.s==NULL)
		{
			LM_ERR("cannot parse callid header\n");
			goto error;
		}
		
		if (!msg->from || !msg->from->body.s)
		{
			LM_ERR("cannot find 'from' header!\n");
			goto error;
		}
		if (msg->from->parsed == NULL)
		{
			if ( parse_from_header( msg )<0 ) 
			{
				LM_ERR("cannot parse From header\n");
				goto error;
			}
		}
		pfrom = (struct to_body*)msg->from->parsed;
	
		if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
		{
			LM_ERR("no from tag value present\n");
			goto error;
		}

		hentity->call_id=  msg->callid->body;
		hentity->from_tag= pfrom->tag_value;

		if(ps->code >= 300 || lexpire == 0)
		{
			hentity->to_tag.s = NULL;
			hentity->to_tag.len = 0;
			find_and_delete_dialog(hentity, hash_code);
			goto done;
		}

		if( msg->to==NULL || msg->to->body.s==NULL)
		{
			LM_ERR("cannot parse TO header\n");
			goto error;
		}			
		if(msg->to->parsed != NULL)
		{
			pto = (struct to_body*)msg->to->parsed;
			LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
		}
		else
		{
			parse_to(msg->to->body.s,msg->to->body.s +
				msg->to->body.len + 1, &TO);
			if(TO.uri.len <= 0) 
			{
				LM_ERR("'To' header NOT parsed\n");
				goto error;
			}
			pto = &TO;
		}			
		if( pto->tag_value.s ==NULL || pto->tag_value.len == 0)
		{
			LM_ERR("no to tag value present\n");
			goto error;
		}
		hentity->to_tag= pto->tag_value;
	}

	if(ps->code >= 300 )
	{	/* if an error code and a stored dialog delete it and try to send 
		   a subscription with type= INSERT_TYPE, else return*/	
		
		subs_info_t subs;

		hentity->to_tag.s = NULL;
		hentity->to_tag.len = 0;
		find_and_delete_dialog(hentity, hash_code);

		if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction)
		{
			if (pua_dbf.end_transaction(pua_db) < 0)
			{
				LM_ERR("in end_transaction\n");
				goto error;
			}
		}

		end_transaction = 0;

		/* Redirect if the response 3XX */
		memset(&subs, 0, sizeof(subs_info_t));
		subs.pres_uri= hentity->pres_uri; 
		subs.watcher_uri= hentity->watcher_uri;
		subs.contact= &hentity->contact;

		if(hentity->remote_contact.s)
			subs.remote_target= &hentity->remote_contact;

		if(hentity->desired_expires== 0)
			subs.expires= -1;
		else
		if(hentity->desired_expires< (int)time(NULL))
			subs.expires= 0;
		else
			subs.expires= hentity->desired_expires- (int)time(NULL)+ 3;

		subs.flag= INSERT_TYPE;
		subs.source_flag= flag;
		subs.event= hentity->event;
		subs.id= hentity->id;
		subs.outbound_proxy= hentity->outbound_proxy;
		subs.extra_headers= hentity->extra_headers;
		subs.cb_param= hentity->cb_param;
	
		if(send_subscribe(&subs)< 0)
		{
			LM_ERR("when trying to send SUBSCRIBE\n");
			goto error;
		}
		goto done;
	}

	if(lexpire== 0 )
	{
		LM_DBG("lexpire= 0 Delete from hash table");
		find_and_delete_dialog(hentity, hash_code);
		goto done;
	}

	/* extract the contact */
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		goto error;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		goto error;
	}
	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		goto error;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	if( msg->cseq==NULL || msg->cseq->body.s==NULL)
	{
		LM_ERR("cannot parse cseq header\n");
		goto error;
	}

	if( str2int( &(get_cseq(msg)->number), &cseq)< 0)
	{
		LM_ERR("while converting str to int\n");
		goto error;
	}

	if(initial_request == 0)
	{
		hentity->cseq = cseq;
		find_and_update_dialog(hentity, hash_code, lexpire, &contact);
		goto done;
	}

	/*process record route and add it to a string*/
	if (msg->record_route!=NULL)
	{
		rt = print_rr_body(msg->record_route, &record_route, 1, 0);
		if(rt != 0)
		{
			LM_ERR("parsing record route [%d]\n", rt);	
			record_route.s=NULL;
			record_route.len=0;
		}
	}

	size= sizeof(ua_pres_t)+ 2*sizeof(str)+( pto->uri.len+
		pfrom->uri.len+ pto->tag_value.len+ pfrom->tag_value.len
		+msg->callid->body.len+ record_route.len+ hentity->contact.len+
		hentity->id.len )*sizeof(char);

	if(hentity->extra_headers)
		size+= sizeof(str)+ hentity->extra_headers->len*sizeof(char);

	presentity= (ua_pres_t*)shm_malloc(size);
	if(presentity== NULL)
	{
		LM_ERR("no more share memory\n");
		goto error;
	}
	
	memset(presentity, 0, size);
	size= sizeof(ua_pres_t);

	presentity->pres_uri= (str*)( (char*)presentity+ size);
	size+= sizeof(str);
	presentity->pres_uri->s= (char*)presentity+ size;
	memcpy(presentity->pres_uri->s, pto->uri.s, pto->uri.len);
	presentity->pres_uri->len= pto->uri.len;
	size+= pto->uri.len;

	presentity->watcher_uri= (str*)( (char*)presentity+ size);
	size+= sizeof(str);
	presentity->watcher_uri->s= (char*)presentity+ size;
	memcpy(presentity->watcher_uri->s, pfrom->uri.s, pfrom->uri.len);
	presentity->watcher_uri->len= pfrom->uri.len;
	size+= pfrom->uri.len;

	presentity->call_id.s= (char*)presentity + size;
	memcpy(presentity->call_id.s,msg->callid->body.s, 
		msg->callid->body.len);
	presentity->call_id.len= msg->callid->body.len;
	size+= presentity->call_id.len;

	presentity->to_tag.s= (char*)presentity + size;
	memcpy(presentity->to_tag.s,pto->tag_value.s, 
			pto->tag_value.len);
	presentity->to_tag.len= pto->tag_value.len;
	size+= pto->tag_value.len;

	presentity->from_tag.s= (char*)presentity + size;
	memcpy(presentity->from_tag.s,pfrom->tag_value.s, 
			pfrom->tag_value.len);
	presentity->from_tag.len= pfrom->tag_value.len;
	size+= pfrom->tag_value.len;

	if(record_route.len && record_route.s)
	{
		presentity->record_route.s= (char*)presentity + size;
		memcpy(presentity->record_route.s, record_route.s, record_route.len);
		presentity->record_route.len= record_route.len;
		size+= record_route.len;
		pkg_free(record_route.s);
		record_route.s = NULL;
	}

	presentity->contact.s= (char*)presentity + size;
	memcpy(presentity->contact.s, hentity->contact.s, hentity->contact.len);
	presentity->contact.len= hentity->contact.len;
	size+= hentity->contact.len;

	if(hentity->id.s)
	{
		presentity->id.s=(char*)presentity+ size;
		memcpy(presentity->id.s, hentity->id.s, 
			hentity->id.len);
		presentity->id.len= hentity->id.len; 
		size+= presentity->id.len;
	}

	if(hentity->extra_headers)
	{
		presentity->extra_headers= (str*)((char*)presentity+ size);
		size+= sizeof(str);
		presentity->extra_headers->s=(char*)presentity+ size;
		memcpy(presentity->extra_headers->s, hentity->extra_headers->s, 
			hentity->extra_headers->len);
		presentity->extra_headers->len= hentity->extra_headers->len; 
		size+= hentity->extra_headers->len;
	}

	/* write the remote contact filed */
	presentity->remote_contact.s= (char*)shm_malloc(contact.len* sizeof(char));
	if(presentity->remote_contact.s==NULL)
	{
		ERR_MEM(SHARE_MEM);
	}
	memcpy(presentity->remote_contact.s, contact.s, contact.len);
	presentity->remote_contact.len= contact.len;

	presentity->event|= hentity->event;
	presentity->flag= hentity->flag;
	presentity->etag.s= NULL;
	presentity->cseq= cseq;
	presentity->desired_expires= hentity->desired_expires;
	presentity->expires= lexpire+ (int)time(NULL);
	if(BLA_SUBSCRIBE & presentity->flag)
	{
		LM_DBG("BLA_SUBSCRIBE FLAG inserted\n");
	}	
	LM_DBG("record for subscribe from %.*s to %.*s inserted in datatbase\n",
			presentity->watcher_uri->len, presentity->watcher_uri->s,
			presentity->pres_uri->len, presentity->pres_uri->s);

	if (dbmode==PUA_DB_ONLY)
	{
		if (pua_dbf.end_transaction)
		{
			if (pua_dbf.end_transaction(pua_db) < 0)
			{
				LM_ERR("in end_transaction\n");
				goto error;
			}
		}

		if (pua_dbf.start_transaction)
		{
			if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0)
			{
				LM_ERR("in start_transaction\n");
				goto error;
			}
		}

		if (convert_temporary_dialog_puadb(presentity) < 0)
		{
			LM_ERR("Could not convert temporary dialog into a dialog\n");
			goto error;
		}
	}
	else
	{
		if (convert_temporary_dialog(presentity) < 0)
		{
			LM_ERR("Could not convert temporary dialog into a dialog\n");
			goto error;
		}
	}

done:
	if(hentity->ua_flag == REQ_OTHER)
	{
		hentity->flag= flag;
		run_pua_callbacks( hentity, msg);
	}

	if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction && end_transaction)
	{
		if (pua_dbf.end_transaction(pua_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}

	goto end;

error:	
        if (presentity)
	{
		if (presentity->remote_contact.s) shm_free(presentity->remote_contact.s);
	 	shm_free(presentity);
	}

	if(record_route.s)
		pkg_free(record_route.s);

	if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction)
	{
		if (pua_dbf.abort_transaction(pua_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

end:

	if(hentity)
	{	
		shm_free(hentity);
		hentity= NULL;
	}

	free_to_params(&TO);
	return;
}
Пример #30
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;
}