static unsigned int mangle_sdp(struct sk_buff **pskb,
			       enum ip_conntrack_info ctinfo,
			       struct ip_conntrack *ct,
			       u_int32_t newip, u_int16_t port,
			       const char *dptr)
{
	char buffer[sizeof("nnn.nnn.nnn.nnn")];
	unsigned int dataoff, bufflen;

	dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);

	/* Mangle owner and contact info. */
	bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
	                       buffer, bufflen, &ct_sip_hdrs[POS_OWNER]))
		return 0;

	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
	                       buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION]))
		return 0;

	/* Mangle media port. */
	bufflen = sprintf(buffer, "%u", port);
	if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
	                       buffer, bufflen, &ct_sip_hdrs[POS_MEDIA]))
		return 0;

	return mangle_content_len(pskb, ctinfo, ct, dptr);
}
Exemple #2
0
static unsigned int mangle_sdp(struct sk_buff *skb,
			       enum ip_conntrack_info ctinfo,
			       struct nf_conn *ct,
			       __be32 newip, u_int16_t port,
			       const char *dptr)
{
	char buffer[sizeof("nnn.nnn.nnn.nnn")];
	unsigned int dataoff, bufflen;

	dataoff = ip_hdrlen(skb) + sizeof(struct udphdr);

	/* Mangle owner and contact info. */
	bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
	if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
			       buffer, bufflen, POS_OWNER_IP4))
		return 0;

	if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
			       buffer, bufflen, POS_CONNECTION_IP4))
		return 0;

	/* Mangle media port. */
	bufflen = sprintf(buffer, "%u", port);
	if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
			       buffer, bufflen, POS_MEDIA))
		return 0;

	return mangle_content_len(skb, ctinfo, ct, dptr);
}
static unsigned int ip_nat_sip(struct sk_buff **pskb,
			       enum ip_conntrack_info ctinfo,
			       struct ip_conntrack *ct,
			       const char **dptr)
{
	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
	char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
	unsigned int bufflen, dataoff;
	u_int32_t ip;
	u_int16_t port;

	dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);

	ip   = ct->tuplehash[!dir].tuple.dst.ip;
	port = ct->tuplehash[!dir].tuple.dst.u.udp.port;
	bufflen = sprintf(buffer, "%u.%u.%u.%u:%u", NIPQUAD(ip), ntohs(port));

	/* short packet ? */
	if (((*pskb)->len - dataoff) < (sizeof("SIP/2.0") - 1))
		return 0;

	/* Basic rules: requests and responses. */
	if (memcmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) == 0) {
		const char *aux;

		if ((ctinfo) < IP_CT_IS_REPLY) {
			mangle_sip_packet(pskb, ctinfo, ct, dptr,
			                  (*pskb)->len - dataoff,
			                  buffer, bufflen,
			                  &ct_sip_hdrs[POS_CONTACT]);
			return 1;
		}

		if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
				       (*pskb)->len - dataoff,
		                       buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
			return 0;

		/* This search should ignore case, but later.. */
		aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
		                    (*pskb)->len - dataoff);
		if (!aux)
			return 0;

		if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"),
		    ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff)))
			return 1;

		return mangle_sip_packet(pskb, ctinfo, ct, dptr,
					 (*pskb)->len - dataoff,
		                         buffer, bufflen,
					 &ct_sip_hdrs[POS_CONTACT]);
	}
	if ((ctinfo) < IP_CT_IS_REPLY) {
		if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
				       (*pskb)->len - dataoff,
		                       buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
			return 0;

		/* Mangle Contact if exists only. - watch udp_nat_mangle()! */
		mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
		                  buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
		return 1;
	}
	/* This mangle requests headers. */
	return mangle_sip_packet(pskb, ctinfo, ct, dptr,
	                         ct_sip_lnlen(*dptr,
				              *dptr + (*pskb)->len - dataoff),
	                         buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
}