Esempio n. 1
0
static int mangle_content_len(struct sk_buff *skb, unsigned int dataoff,
			      const char **dptr, unsigned int *datalen)
{
	enum ip_conntrack_info ctinfo;
	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
	unsigned int matchoff, matchlen;
	char buffer[sizeof("65536")];
	int buflen, c_len;

	/* Get actual SDP length */
	if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
				  SDP_HDR_VERSION, SDP_HDR_UNSPEC,
				  &matchoff, &matchlen) <= 0)
		return 0;
	c_len = *datalen - matchoff + strlen("v=");

	/* Now, update SDP length */
	if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CONTENT_LENGTH,
			      &matchoff, &matchlen) <= 0)
		return 0;

	buflen = sprintf(buffer, "%u", c_len);
	return mangle_packet(skb, dataoff, dptr, datalen, matchoff, matchlen,
			     buffer, buflen);
}
Esempio n. 2
0
static int get_callid(const char *dptr, unsigned int dataoff,
		      unsigned int datalen,
		      unsigned int *matchoff, unsigned int *matchlen)
{
	/* Find callid */
	while (1) {
		int ret = ct_sip_get_header(NULL, dptr, dataoff, datalen,
					    SIP_HDR_CALL_ID, matchoff,
					    matchlen);
		if (ret > 0)
			break;
		if (!ret)
			return -EINVAL;
		dataoff += *matchoff;
	}

	/* Too large is useless */
	if (*matchlen > IP_VS_PEDATA_MAXLEN)
		return -EINVAL;

	/* SIP headers are always followed by a line terminator */
	if (*matchoff + *matchlen == datalen)
		return -EINVAL;

	/* RFC 2543 allows lines to be terminated with CR, LF or CRLF,
	 * RFC 3261 allows only CRLF, we support both. */
	if (*(dptr + *matchoff + *matchlen) != '\r' &&
	    *(dptr + *matchoff + *matchlen) != '\n')
		return -EINVAL;

	IP_VS_DBG_BUF(9, "SIP callid %s (%d bytes)\n",
		      IP_VS_DEBUG_CALLID(dptr + *matchoff, *matchlen),
		      *matchlen);
	return 0;
}
static int get_callid(const char *dptr, unsigned int dataoff,
		      unsigned int datalen,
		      unsigned int *matchoff, unsigned int *matchlen)
{
	
	while (1) {
		int ret = ct_sip_get_header(NULL, dptr, dataoff, datalen,
					    SIP_HDR_CALL_ID, matchoff,
					    matchlen);
		if (ret > 0)
			break;
		if (!ret)
			return 0;
		dataoff += *matchoff;
	}

	
	if (!*matchlen)
		return -EINVAL;

	
	if (*matchlen > IP_VS_PEDATA_MAXLEN)
		return -EINVAL;

	
	if (*matchoff + *matchlen == datalen)
		return -EINVAL;

	if (*(dptr + *matchoff + *matchlen) != '\r' &&
	    *(dptr + *matchoff + *matchlen) != '\n')
		return -EINVAL;

	IP_VS_DBG_BUF(9, "SIP callid %s (%d bytes)\n",
		      IP_VS_DEBUG_CALLID(dptr + *matchoff, *matchlen),
		      *matchlen);
	return 0;
}