Intercepting/Rerouting Tcp Syn Packets to C++ Program in Linux

Intercepting/Rerouting TCP SYN packets to C++ program in linux

If you merely want to see the packets, use libpcap and packet filtering - that'll work on most any UNIX variant.

If you want to somehow intercept and rewrite the packets, please supply more information about what you're trying to do, and what's supposed to happen to the packets afterwards.

As you suggest, that might be an application for netfilter and its queue module, although that requires a 2.6.14 or later kernel:

Main Features

  • receiving queued packets from the kernel nfnetlink_queue subsystem
  • issuing verdicts and/or reinjecting altered packets to the kernel
    nfnetlink_queue subsystem

Intercept traffic above the transport layer

Hijack the connections through an HTTP proxy. Google up a good way to do this if you can't just set HTTP_PROXY on the client, or set up your filter running with the IP and port number of the current server, moving the real server to another IP.

So the actual TCP connections are between the client and you, then from you to the server. Then you don't have to deal with ACKs, because TCP always sees mission accomplished.

edit: I see the comments on the original already came up with this idea using iptables to redirect the traffic through your transparent proxy process on the same machine.

How to reconstruct TCP stream from multiple IP packets?

It is likely functionality you need will be always tightly coupled with packet dissection. Good protocol dissectors are really needed to extract required information. So my suggestion is to use best open source tool available - wireshark.org

It provides "Follow TCP stream" functionality:

Sample Image

I doesn't look like you can easily extract part of Wireshark dissection logic, but at least there is a good example packet-tcp:

typedef struct _tcp_flow_t {
guint32 base_seq; /* base seq number (used by relative sequence numbers)
* or 0 if not yet known.
*/
tcp_unacked_t *segments;
guint32 fin; /* frame number of the final FIN */
guint32 lastack; /* last seen ack */
nstime_t lastacktime; /* Time of the last ack packet */
guint32 lastnondupack; /* frame number of last seen non dupack */
guint32 dupacknum; /* dupack number */
guint32 nextseq; /* highest seen nextseq */
guint32 maxseqtobeacked;/* highest seen continuous seq number (without hole in the stream) from the fwd party,
* this is the maximum seq number that can be acked by the rev party in normal case.
* If the rev party sends an ACK beyond this seq number it indicates TCP_A_ACK_LOST_PACKET contition */
guint32 nextseqframe; /* frame number for segment with highest
* sequence number
*/

Basically, there is separate conversation extraction logic, please notice find_conversation usage:

/* Attach process info to a flow */
/* XXX - We depend on the TCP dissector finding the conversation first */
void
add_tcp_process_info(guint32 frame_num, address *local_addr, address *remote_addr, guint16 local_port, guint16 remote_port, guint32 uid, guint32 pid, gchar *username, gchar *command) {
conversation_t *conv;
struct tcp_analysis *tcpd;
tcp_flow_t *flow = NULL;

conv = find_conversation(frame_num, local_addr, remote_addr, PT_TCP, local_port, remote_port, 0);
if (!conv) {
return;
}

The actual logic is well documented and available here:

/*
* Given two address/port pairs for a packet, search for a conversation
* containing packets between those address/port pairs. Returns NULL if
* not found.
*
* We try to find the most exact match that we can, and then proceed to
* try wildcard matches on the "addr_b" and/or "port_b" argument if a more
* exact match failed.
* ...
*/
conversation_t *
find_conversation(const guint32 frame_num, const address *addr_a, const address *addr_b, const port_type ptype,
const guint32 port_a, const guint32 port_b, const guint options)
{
conversation_t *conversation;

/*
* First try an exact match, if we have two addresses and ports.
*/
if (!(options & (NO_ADDR_B|NO_PORT_B))) {

So what I'm actually suggesting is to use EPAN library. It is possible to extract this library and use it independently. Please be careful with the license.

Is there an option or command that I can used to disable/unload/ or stop the tcp/IP stack in linux. Need it to implement user space tcp in server app

Well, you could compile yourself a kernel without networking :)

A couple of options

  1. Check out the DPDK project (https://www.linuxjournal.com/content/userspace-networking-dpdk). DPDK passes the Physical NIC to User space via UIO driver to igb_uio|uio_pci_generic|vfio-pci. Thus eliminates Kernel Stack.
  2. Use XDP supported NIC with either Zero-Copy or Driver-mode. with eBPF running one can push the received packets directly to User space bypassing the kernel stack.

Unless this is a homework project, remember: don't invent, reuse.

[EDIT-based on comment] Userspace TCP-IP stack have custom sock-API to read/write into the socket. So with either LD_PRELOAD or source file change, one can use the same application.

Packets looping forever in libnetfilter_queue

Use skb->mark. It's a marking which only exists within the IP stack of your host. It does not affect anything in the network packet itself.

You can filter it using iptables using the '--mark' filter. Use it to return from your delay chain so that your re-inserted packets are not delayed again.

iptables -A DELAY -m mark --mark 0xE -j RETURN
iptables -A DELAY -j DELAY

You can configure the raw socket to apply a mark, using setsockopt(fd, SOL_SOCKET, SO_MARK, ...). You only need to do this once after opening the socket. The mark value will be automatically applied to each packet you send through the socket.

how to modify packet header(IP header, TCP Header) before the host send them into the network

Razorback is an open source API for deep packet injection.
You can find the source at:

http://sourceforge.net/projects/razorbacktm/files/Razorback/

You can also request them for the source code for their proposed system.

http://www.icir.org/vern/papers/pktd-pam03.pdf



Related Topics



Leave a reply



Submit