How can I get the original destination address of a packet after dnat? - netfilter

I'm writing a packet filter module at userspace using libnetfilter_queue. But I don't know how to get the original destination address of a packet after it has gone through DNAT filter.
When using socket, I can do it by using SO_ORIGINAL_DST but I don't know how when using libnetfilter_queue.
Thanks.

Related

How to force rerouting of a packet after return to netfilter from NFQUEUE

I have a caching application that runs in userspace. Normally, it uses DPDK to interact with the NICs directly without kernel interaction, grabbing packets off of the wire, and either passing them through, generating a response from cache, or in some occasions blocking them. It's transparent to the endpoints, and is written to work on raw packet data straight from the NIC. Notably, I'm not doing normal socket programming here - everything's handled at the packet level, without interaction with the TCP/IP stack.
For reasons that are long and boring, I wanted to add some NAT functionality. As a proof of concept, I was hoping to put a front end on my application using iptables/netfilter. So I did the NAT parts with commands like these:
sudo iptables --table nat --append PREROUTING --in-interface seg1a -j DNAT --to-destination $SERVERIP
sudo iptables --table nat --append POSTROUTING --out-interface seg1b -j MASQUERADE
sudo route add $SERVERIP seg1b
This works well for my purposes. The clients now attach to an interface on my system, but their traffic gets redirected to the server. I'm guaranteed that their traffic passes through my system, so all's good.
But to be useful as a cache, I need to be able to respond to some requests that I get from clients. I had thought I could use NFQUEUE for this, with a small application that reads from the netfilter queue and passes packets to and from my application via IPC. I used an iptables rule like this:
sudo iptables --table mangle --append FORWARD -j NFQUEUE
This works OK as long as my application doesn't respond to anything. But when my cache attempts to respond to something from one of the endpoints, things go wrong. The cache reverses all of the L2-4 headers, manages sequence and ack numbers, etc. But the packets don't get back to the client.
I think what's happening is that routing decisions for the packet were made before it was sent to NFQUEUE. So even though the cache returns something whose source and destination IP addresses are reversed, that's irrelevant for the routing of the packet.
I've tried a number of things to change the routing of my response packets, but nothing seems to work. How does one go about changing the routing on a packet read from netfilter queues? Failing that, is there a good way to just inject packets onto the wire from netfilter queues? If that were doable, I could block the original request and then send the cache's reply as an entirely new thing.
Thanks in advance for any suggestions.
The best answer I came up with for this problem was to open a raw socket and feed it my pre-built packets. Critically, you must create an iptables rule that matches your generated packets and tells netfilter not to do connection tracking. Otherwise, netfilter sees the injected packets and thinks there's a connection collision. It then does port forwarding, so the packets come out with a different port than you put in there!
I built the socket like this:
sid = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
Then, I turned on a couple of options (leaving failure handling out for brevity):
int one = 1;
const int *val = &one;
retval = setsockopt(sid, IPPROTO_IP, IP_HDRINCL, val, sizeof(one));
retval = setsockopt(sid, SOL_SOCKET, SO_MARK, val, sizeof(one));
The first of these tells the kernel that I have the headers already, so no need to try and create them. The second tells the kernel to put a mark value of 1 on every packet sent via the socket, which I can match against in routing or iptables rules.
Later, I built a destination address and used sendto() to send the packet:
retval = sendto(sid, pL3, len, 0, (struct sockaddr *)&daddr, sizeof(daddr));
Finally, I installed a rule telling netfilter not to do connection tracking on TCP packets marked with a 1. Since I had added the sockopt above so that all of my generated packets had this mark, this worked well:
sudo iptables -t raw -I OUTPUT -p tcp -m mark --mark 1 -j CT --notrack

import ip packet via hex dump

I have a hex dump generated using gdb. I have generated the dump that wireshark can understand using "od -Ax -tx1 -v". But when I open in the wireshark tool the packet doesn't get recognized properly. I think wireshark is trying to read the ethernet frame while the buffer has data from IP header. Is there a way to indicate wireshark to parse hexdump assuming fro IP header.
Have a look at text2pcap. There are 2 basic approaches you can take:
Add a dummy Ethernet header using the -e <l3pid> option, or
Set the encapsulation type of the converted pcap file to link-layer type LINKTYPE_RAW using the -l 101 option.

How to obtain bluetooth port direction with pyserial?

I'm trying to connect to an RN42, module through python. When the RN42 pairs with W10 it creates two virtual COM ports(outgoing and incoming). I need to connect to the outgoing port.
I'm trying to do this automatically. I've tried:
import serial
import serial.tools.list_ports as port_lst
ports = list(port_lst.comports())
bluetooth_ports = []
for p in ports:
if 'Bluetooth' in p.description:
bluetooth_ports += [p.device]
bluetooth_com = serial.Serial(bluetooth_ports[0],115200)
I thought that the first port was usually the outgoing one, but I've paired the module to another computer, and this didn't apply (the second port was the outgoing one). Is there a way to find out the direction of the COM ports?
Thanks!!!
Although this is an antique question, I have been searching for the answer to this for some time myself and since I finally figured it out I wanted others to be able to find the answer. With help from a blog entry at in the hand and its accompanying gist:
The trick is to acquire the hwid using pySerial, then parse the address. The incoming port in a pair has an address of zero and the outgoing port has a nonzero address. Here is some ugly Python code that decodes it:
import serial.tools.list_ports
cp=serial.tools.list_ports.comports()
for p in cp:
if "BTHENUM" in p.hwid:
start_of_address=p.hwid.rfind("&")
end_of_address=p.hwid.rfind("_")
address=p.hwid[start_of_address+1:end_of_address]
if int(address,16)==0:
port_type="incoming"
else:
port_type="outgoing"
print(p.hwid)
print(p.name, address, port_type)
And the output:
BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\7&CC47540&0&000000000000_000000A8
COM4 000000000000 incoming
BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0002\7&CC47540&0&209BA5420081_C00000000
COM5 209BA5420081 outgoing

RadioTap headers in scapy

I'm trying to send and receive packets with scapy and read the RadioTap Header. The wireless adapter (and driver) is able to handle those headers, but I can't seem to get them.
Whenever I send a normal packet in scapy, is does not contain such a header (thus, sniffing packets and checking one with pkt.haslayer(RadioTap) returns 0, and I am not able to display the header like with pkt[RadioTap].show() ).
If I explicitly construct my packets with a RadioTap header (like in a
pkt = RadioTap() and view it, I can get a RadioTap header, but it is empty. After sending it and receiving it, I can get still nothing.
I read posts like this one. But I don't have the problem that the RadioTap header doesn't get decoded, it's simply not filled with anything.
I'm using scapy 2.3.1, if this makes any difference. Any ideas?
Please make sure that your wireless interface and the driver support monitor mode.
$ iw list
...
Supported interface modes:
* IBSS
* managed
* AP
* AP/VLAN
* monitor <-- here
* P2P-client
* P2P-GO
* P2P-device
And your interface is configured to monitor mode with a specific channel (e.g. ch=6).
$ sudo ip link set wlan0 down
$ sudo iw dev wlan0 set type monitor
$ sudo ip link set wlan0 up
$ sudo iw dev wlan0 set channel 6
It is also good idea to try with tools like wireshark first to see if RadioTap is visible.

Measuring data traffic flow over server/client socket in delphi?

i am making a program that sends data between a server program and its clients. They all use the server and client socket components found in Delphi! I have looked on the Internet and cannot find a way on how to measure how much data has been transferred through a socket!
Any help, especially some code (pascal/Delphi), would be very much appreciated!
here you have a full example http://delphi.about.com/od/fullcodeprojects/l/aa112903a.htm
If you use win/*nix API sockets (not a special libraries) you have to count returns from recv and send functions.
total_data = 0;
...
...
get_data = recv(...)
total_data = total_data + get_data
...
send_data = send(...)
total_data = total_data + send_data
Magenta Systems has a free set of components that can monitor network traffic using either raw sockets or WinPcap.
Update:
From your comment to RBA's response: The Magenta components let you identify and differentiate between different IP addresses and services (ports).
I keep stats on all my TCP traffic to the byte. Every time I send data I update the stats and every time I receieve data I update the stats. This is accurate to one byte and requires only a few lines of code. And it does not rely on any particular TCP components. Why is doing it this way so hard?

Resources