All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rennie deGraaf <degraaf@cpsc.ucalgary.ca>
To: netfilter-devel@lists.netfilter.org
Subject: ip_rt_bug in mangle/OUTPUT
Date: Wed, 23 May 2007 15:12:57 -0600	[thread overview]
Message-ID: <4654AE59.3090506@cpsc.ucalgary.ca> (raw)

[-- Attachment #1: Type: text/plain, Size: 3921 bytes --]

I seem to be getting the error message
    ip_rt_bug: 10.1.1.1 -> 10.0.1.2, ?
whenever I attempt to send a packet with a non-local source IP address
(my local IP address is 10.0.1.2) from libipq in mangle/OUTPUT.  I have
observed this behaviour under Linux kernels 2.6.20.7 and
2.6.18-1.2257.fc5smp (Fedora Core 5), and iptables versions 1.3.5 and
1.3.7.

I'm trying to simulate connections with remote hosts by redirecting
packets to servers listening on localhost.  My strategy is to send
packets to IP_QUEUE from rules in the mangle/OUTPUT chain: destination
addresses are re-written on packets that I want to redirect, source
addresses are re-written on packets on responses to redirected packets,
and other packets are passed without modification.  A simplified, highly
stripped down version of my program is attached.

To run my example program, you need rules in your mangle/OUTPUT chain
forwarding packets to 10.1.1.1:123/TCP and from 127.0.0.1:22/TCP to
QUEUE, and something listening on 127.0.0.1:22/TCP.  If it worked
properly, a connection could be successfully established to
127.0.0.1:22/TCP by connecting to 10.1.1.1:123/TCP (using telnet, for
instance).

Do any of the gurus on this list know how I might fix or work around
this issue?

This issue seems to have been discussed before (such as
http://www.ussg.iu.edu/hypermail/linux/kernel/0504.3/0159.html), but
doesn't seem to have been resolved.

Thanks,
Rennie deGraaf


-----------------
#include <linux/netfilter.h>
#include <libipq.h>
#include <stdio.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>


u_int16_t ip_checksum(u_int32_t init, const u_int8_t* buf, size_t len)
{
    u_int32_t sum = init;
    u_int16_t* shorts = (u_int16_t*)buf;

    while (len > 1)
    {
        sum += *shorts++;
        len -= 2;
    }

    if (len == 1)
        sum += *(u_int8_t*)shorts;

    while (sum >> 16)	
        sum = (sum >> 16) + (sum & 0xFFFF);

    return ~sum;
}

u_int16_t tcp_checksum(const struct iphdr* iph, const struct tcphdr*
tcph, size_t len)
{
    u_int32_t cksum = 0;

    cksum += (iph->saddr >> 16) & 0x0000ffff;
    cksum += iph->saddr & 0x0000ffff;
    cksum += (iph->daddr >> 16) & 0x0000ffff;
    cksum += iph->daddr & 0x0000ffff;
    cksum += htons(iph->protocol & 0x00ff);
    cksum += htons(len);
    return ip_checksum(cksum, (unsigned char*)tcph, len);
}


void handle_packet(unsigned char* pkt, size_t len)
{
    struct iphdr* iph = (struct iphdr*) pkt;
    struct tcphdr* tcph = (struct tcphdr*)(pkt+iph->ihl*4);

    if ((iph->daddr == htonl(0x0a010101)) && (tcph->dest == htons(123)))
    {
        printf("forward\n");
        iph->daddr = htonl(0x7f000001);
        tcph->dest = htons(22);

        iph->check = 0;
        iph->check = ip_checksum(0, pkt, iph->ihl*4);
        tcph->check = 0;
        tcph->check = tcp_checksum(iph, tcph, len-(iph->ihl*4));
    }
    else if ((iph->saddr == htonl(0x7f000001)) && (tcph->source ==
htons(22)))
    {
        printf("reverse\n");
        iph->saddr = htonl(0x0a010101);
        tcph->source = htons(123);

        iph->check = 0;
        iph->check = ip_checksum(0, pkt, iph->ihl*4);
        tcph->check = 0;
        tcph->check = tcp_checksum(iph, tcph, len-(iph->ihl*4));
    }
    else
        printf("wrong packet!\n");
}

int main()
{
    struct ipq_handle* handle;
    unsigned char buf[10000];
    ipq_packet_msg_t* pkt;

    handle = ipq_create_handle(0, PF_INET);
    ipq_set_mode(handle, IPQ_COPY_PACKET, 65535);

    while (1)
    {
        ipq_read(handle, buf, 10000, 0);
        pkt = ipq_get_packet(buf);
        handle_packet(pkt->payload, pkt->data_len);
        ipq_set_verdict(handle, pkt->packet_id, NF_ACCEPT,
pkt->data_len, pkt->payload);
    }

    ipq_destroy_handle(handle);
    return 0;
}


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

             reply	other threads:[~2007-05-23 21:12 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-23 21:12 Rennie deGraaf [this message]
2007-05-24 17:50 ` ip_rt_bug in mangle/OUTPUT Patrick McHardy
2007-05-24 21:22   ` Rennie deGraaf
2007-06-05 20:20   ` Rennie deGraaf
2007-06-06 11:36     ` Patrick McHardy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4654AE59.3090506@cpsc.ucalgary.ca \
    --to=degraaf@cpsc.ucalgary.ca \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.