コード例 #1
0
ファイル: nf_nat_helper.c プロジェクト: macbury/linux-2.6
/* Generic function for mangling variable-length address changes inside
 * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
 * command in the Amanda protocol)
 *
 * Takes care about all the nasty sequence number changes, checksumming,
 * skb enlargement, ...
 *
 * XXX - This function could be merged with nf_nat_mangle_tcp_packet which
 *       should be fairly easy to do.
 */
int
nf_nat_mangle_udp_packet(struct sk_buff *skb,
			 struct nf_conn *ct,
			 enum ip_conntrack_info ctinfo,
			 unsigned int match_offset,
			 unsigned int match_len,
			 const char *rep_buffer,
			 unsigned int rep_len)
{
	struct iphdr *iph;
	struct udphdr *udph;
	int datalen, oldlen;

	/* UDP helpers might accidentally mangle the wrong packet */
	iph = ip_hdr(skb);
	if (skb->len < iph->ihl*4 + sizeof(*udph) +
			       match_offset + match_len)
		return 0;

	if (!skb_make_writable(skb, skb->len))
		return 0;

	if (rep_len > match_len &&
	    rep_len - match_len > skb_tailroom(skb) &&
	    !enlarge_skb(skb, rep_len - match_len))
		return 0;

	iph = ip_hdr(skb);
	udph = (void *)iph + iph->ihl*4;

	oldlen = skb->len - iph->ihl*4;
	mangle_contents(skb, iph->ihl*4 + sizeof(*udph),
			match_offset, match_len, rep_buffer, rep_len);

	/* update the length of the UDP packet */
	datalen = skb->len - iph->ihl*4;
	udph->len = htons(datalen);

	/* fix udp checksum if udp checksum was previously calculated */
	if (!udph->check && skb->ip_summed != CHECKSUM_PARTIAL)
		return 1;

	nf_nat_csum(skb, iph, udph, datalen, &udph->check, oldlen);

	return 1;
}
コード例 #2
0
int
nf_nat_mangle_udp_packet(struct sk_buff *skb,
			 struct nf_conn *ct,
			 enum ip_conntrack_info ctinfo,
			 unsigned int match_offset,
			 unsigned int match_len,
			 const char *rep_buffer,
			 unsigned int rep_len)
{
	struct iphdr *iph;
	struct udphdr *udph;
	int datalen, oldlen;

	if (!skb_make_writable(skb, skb->len))
		return 0;

	if (rep_len > match_len &&
	    rep_len - match_len > skb_tailroom(skb) &&
	    !enlarge_skb(skb, rep_len - match_len))
		return 0;

	iph = ip_hdr(skb);
	udph = (void *)iph + iph->ihl*4;

	oldlen = skb->len - iph->ihl*4;
	mangle_contents(skb, iph->ihl*4 + sizeof(*udph),
			match_offset, match_len, rep_buffer, rep_len);

	
	datalen = skb->len - iph->ihl*4;
	udph->len = htons(datalen);

	
	if (!udph->check && skb->ip_summed != CHECKSUM_PARTIAL)
		return 1;

	nf_nat_csum(skb, iph, udph, datalen, &udph->check, oldlen);

	return 1;
}
コード例 #3
0
int __nf_nat_mangle_tcp_packet(struct sk_buff *skb,
			       struct nf_conn *ct,
			       enum ip_conntrack_info ctinfo,
			       unsigned int match_offset,
			       unsigned int match_len,
			       const char *rep_buffer,
			       unsigned int rep_len, bool adjust)
{
	struct iphdr *iph;
	struct tcphdr *tcph;
	int oldlen, datalen;

	if (!skb_make_writable(skb, skb->len))
		return 0;

	if (rep_len > match_len &&
	    rep_len - match_len > skb_tailroom(skb) &&
	    !enlarge_skb(skb, rep_len - match_len))
		return 0;

	SKB_LINEAR_ASSERT(skb);

	iph = ip_hdr(skb);
	tcph = (void *)iph + iph->ihl*4;

	oldlen = skb->len - iph->ihl*4;
	mangle_contents(skb, iph->ihl*4 + tcph->doff*4,
			match_offset, match_len, rep_buffer, rep_len);

	datalen = skb->len - iph->ihl*4;
	nf_nat_csum(skb, iph, tcph, datalen, &tcph->check, oldlen);

	if (adjust && rep_len != match_len)
		nf_nat_set_seq_adjust(ct, ctinfo, tcph->seq,
				      (int)rep_len - (int)match_len);

	return 1;
}