netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Caching packets with libipq
@ 2009-01-16  1:41 David Murray
  2009-01-16  7:22 ` Eric Leblond
  0 siblings, 1 reply; 5+ messages in thread
From: David Murray @ 2009-01-16  1:41 UTC (permalink / raw)
  To: netfilter-devel

Hi,

I am trying to build a TCP proxy that is capable of reordering out of 
order TCP segments before delivering them to the end machine. I plan on 
doing this by analyzing the TCP sequence numbers but for now I am just 
trying to get familiar with netfilter.

I am currently writing this using libipq. The reason that I am not 
using the newer libnetfilter is because there seems to be way more 
documentation and examples for libipq rather than libnetfilter. Using 
libipq I am able to print out packet details and NF_ACCEPT or NF_DROP, 
however, the problem I am having is with copying and storing packets.

The program plan is to anticipate the next sequence number for a each 
flow so: nxt_seq_num  = curr_pkt_seq_num + curr_pkt_data_payload. If I 
detect that one packet is missing I want to buffer up to ten packets 
waiting for the delayed packet.

If a segment is missing from the sequence I want to copy packets into 
memory and NF_DROP until the correct segment arrives. We can then 
replay our buffered packets, and the TCP receiver will receive the 
packets in order.

Currently, I am just trying to see if this is possible in libipq 
because I have not found any similar examples of caching packets in 
libipq. So, in the code snippet below I am trying to cache the 50th 
packet, and then NF_DROP it from the queue. The program should then 
NF_ACCEPT packet 51 and inject packet 50. So if the program was working 
correctly, I would be rearranging the sequence of frames such that 
packets would arrive: 48, 49, 51, 50, 52

The problem is that it appears that packet 50 is never being replayed 
and from the terminal I am getting  a ?Received error message 2?. I 
have been unable to get further information on what this error message 
means. Interestingly, when replaying the cached packet I am still able 
to print out information from it, eg TCP sequence number and 
destination IP address.

Can anyone provide any advice as to how I can narrow this problem down 
further.

Thanks for your time
Dave

status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
     if (status < 0)
    die(h);
        do {
    status = ipq_read(h, buf, BUFSIZE, 0);
    if (status < 0)
      die(h);
                  switch (ipq_message_type(buf)) {
                 case NLMSG_ERROR: {
        fprintf(stderr, "Received error message %d\n",
        ipq_get_msgerr(buf));
        break;
        }

        case IPQM_PACKET: /* got a packet */ {

        ipq_packet_msg_t *m = ipq_get_packet(buf);
                       struct iphdr *ip = (struct iphdr*) m->payload;
        struct tcphdr *tcp = (struct tcphdr*) (m->payload + (4 * ip->ihl));

        int unsigned payload_length = (unsigned int) ntohs(ip->tot_len) 
- ((ip->ihl << 2) + (tcp->doff << 2));
                       if (payload_length > 0) {
                         if (count != 50) {

            printf("This is frame %d dest port %u and seq num %u, size 
%d\n", count, htons(tcp->dest), ntohl(tcp->seq), m->data_len);
            status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
                    }
                           if (count == 50) {

            printf("Not sending 50th packet\n");
            printf("The frame was %d dest port %u and seq num %u, size 
%d\n", count, htons(tcp->dest), ntohl(tcp->seq), m->data_len);
            printf("Chaching instead!\n");

            free(store);            store = (ipq_packet_msg_t 
*)calloc(1, BUFSIZE);
             store->packet_id = m->packet_id;        /* ID of queued packet */
            store->mark = m->mark;                  /* Netfilter mark value */
            store->timestamp_sec = m->timestamp_sec;               
store->timestamp_usec = m->timestamp_usec;                store->hook = 
m->hook;           /* Netfilter hook we rode in on */
            store->hw_protocol = m->hw_protocol;              
store->hw_type = m->hw_type;       /* Hardware type */
            store->data_len = m->data_len;         /* Length of packet data */
            memcpy(store->payload, m->payload, m->data_len);

            status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL);
            printf("Status: %d\n", status);             }
           if (count == 51) {

            struct iphdr *ip = (struct iphdr*) store->payload;
            struct tcphdr *tcp = (struct tcphdr*) (store->payload + (4 
* ip->ihl));
            printf("Replaying missed frame 50 dest port %u and seq num 
%u, size %d\n", htons(tcp->dest), ntohl(tcp->seq), store->data_len);

            printf("Payload: %s\n", store->payload);
            status = ipq_set_verdict(h, store->packet_id, NF_ACCEPT, 
store->data_len, store->payload);
            printf("Status: %d\n", status);
            }

          count++;
          }

        else {
          status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
          }

        break;
        }
                             default:
        fprintf(stderr, "Unknown message type!\n");
        break;
      }     } while (1);



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Caching packets with libipq
  2009-01-16  1:41 Caching packets with libipq David Murray
@ 2009-01-16  7:22 ` Eric Leblond
  2009-01-19  0:31   ` David Murray
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Leblond @ 2009-01-16  7:22 UTC (permalink / raw)
  To: David Murray; +Cc: netfilter-devel

H,

Le vendredi 16 janvier 2009 à 10:41 +0900, David Murray a écrit :
> Hi,
>
> I am currently writing this using libipq. The reason that I am not 
> using the newer libnetfilter is because there seems to be way more 
> documentation and examples for libipq rather than libnetfilter. Using 
> libipq I am able to print out packet details and NF_ACCEPT or NF_DROP, 
> however, the problem I am having is with copying and storing packets.

What about:
	http://www.nufw.org/doc/libnetfilter_queue/

Real question: what is missing here ?

BR,
-- 
Eric Leblond <eleblond@inl.fr>
INL: http://www.inl.fr/
NuFW: http://www.nufw.org/
EdenWall: http://www.edenwall.com/

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Caching packets with libipq
  2009-01-16  7:22 ` Eric Leblond
@ 2009-01-19  0:31   ` David Murray
  2009-01-19  0:47     ` Pablo Neira Ayuso
  0 siblings, 1 reply; 5+ messages in thread
From: David Murray @ 2009-01-19  0:31 UTC (permalink / raw)
  To: Eric Leblond; +Cc: netfilter-devel

Eric Leblond wrote:
>
> What about:
> 	http://www.nufw.org/doc/libnetfilter_queue/
>
> Real question: what is missing here ?
>
> BR,
>   
Thanks for the reply Eric. In my own opinion (things that could be done 
to improve that documentation:

1. Navigation seems a little cluttered. I think it would be better to 
just have a link to documentation on the first page and then a link on 
every subsequent page to page x + 1.

2. On the main page it would be nice to have a description of why 
libnetfilter_queue is better than libipq

3. The page needs to be easier to find. Why is there not a link to it on 
the netfilter site?

4. You don't specify the compile time commands that must be used with 
libnet filter -lnfnetlink -lnetfilter_queue

5. The example code you give includes a callback function. Can you write 
a libnetfilter_queue program without a call back? It might be easier for 
people without lots of c experience to modify and start doing things.

All of these suggestions might not be correct / easy to implement. It is 
just my opinion that they might improve the site.

Thanks for your time
Dave

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Caching packets with libipq
  2009-01-19  0:31   ` David Murray
@ 2009-01-19  0:47     ` Pablo Neira Ayuso
  2009-01-19  3:06       ` David Murray
  0 siblings, 1 reply; 5+ messages in thread
From: Pablo Neira Ayuso @ 2009-01-19  0:47 UTC (permalink / raw)
  To: David Murray; +Cc: Eric Leblond, netfilter-devel

David Murray wrote:
> Eric Leblond wrote:
>>
>> What about:
>>     http://www.nufw.org/doc/libnetfilter_queue/
>>
>> Real question: what is missing here ?
>>
>> BR,
>>   
> Thanks for the reply Eric. In my own opinion (things that could be done
> to improve that documentation:
> 
> 1. Navigation seems a little cluttered. I think it would be better to
> just have a link to documentation on the first page and then a link on
> every subsequent page to page x + 1.
> 
> 2. On the main page it would be nice to have a description of why
> libnetfilter_queue is better than libipq
> 
> 3. The page needs to be easier to find. Why is there not a link to it on
> the netfilter site?

There will be one soon, I have no time to upload it. The patch to
convert documentation barely hit the git tree weeks ago. There was no
documentation months ago, so we're getting better in this field ;)

> 4. You don't specify the compile time commands that must be used with
> libnet filter -lnfnetlink -lnetfilter_queue
> 
> 5. The example code you give includes a callback function. Can you write
> a libnetfilter_queue program without a call back? It might be easier for
> people without lots of c experience to modify and start doing things.

IIRC nfq_handle_packet uses that callback internally.

> All of these suggestions might not be correct / easy to implement. It is
> just my opinion that they might improve the site.

They are welcome.

-- 
"Los honestos son inadaptados sociales" -- Les Luthiers

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Caching packets with libipq
  2009-01-19  0:47     ` Pablo Neira Ayuso
@ 2009-01-19  3:06       ` David Murray
  0 siblings, 0 replies; 5+ messages in thread
From: David Murray @ 2009-01-19  3:06 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Eric Leblond, netfilter-devel

Quoting Pablo Neira Ayuso <pablo@netfilter.org>:

>> 5. The example code you give includes a callback function. Can you write
>> a libnetfilter_queue program without a call back? It might be easier for
>> people without lots of c experience to modify and start doing things.
>
> IIRC nfq_handle_packet uses that callback internally.
>

Are you saying that libnetfilter_queue can be used without using 
nfq_create_queue. As far as I can tell (FYI I am a c novice), if you 
use nfq_create_queue it must contain the a link to the address of the 
callback function. All of the examples I can find do all the packet 
processing within this callback function. If this is the case, I cannot 
understand how you could keep ongoing statistics of packets or flows 
via libnetfilter_queue without using a lot of globals.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-01-19  3:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-16  1:41 Caching packets with libipq David Murray
2009-01-16  7:22 ` Eric Leblond
2009-01-19  0:31   ` David Murray
2009-01-19  0:47     ` Pablo Neira Ayuso
2009-01-19  3:06       ` David Murray

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).