Trying to capture unidirectional tcp data on a server - linux

I'm trying to test linux behavior for unidirectional tcp capture using tcpdump.
The scenario is that Server A is sending packets to destination Y through a switch M. At the same time, M will also be sending the same packets to destination Z, where I'd like to capture all packets. The connection A to Y is a tcp connection.
In order to synthesize the above scenario, I have 3 terminals open on server Z running the following commands:
nc -l 0.0.0.8 4444
telnet -b 0.0.0.10 0.0.0.8 4444
tcpdump -i <interface name associated with 0.0.0.8> port 4444
0.0.0.8 and 0.0.0.10 are separate NIC cards in separate slots, slot 1 and slot 6 in this case.
From the telnet session, i'm successful in sending data, however, tcpdump isn't capturing any packets. If I remove the port 4444 from the terminal 3, I'm seeing data from within my network, but never anything from the telnet session. I should also note that I'm not receiving an error message either.
I'm assuming, b/c I read it on the internet, that telnet creates a tcp connection, which is why I believe that tcpdump should work. Am I wrong here? Should I be doing something else? Can't use WireShark or the like on this server.
Also, on terminal 3 I've also tried tcpdump host 0.0.0.8 port 4444 to no avail. Many thanks for any suggestions.

If node M is truly a switch and not a hub, then node Z should never receive the TCP packets destined for node Y.
TCP is a connection based protocol. That is to say that when node A wants to talk to node Y, it will first broadcast an ARP request asking for node Y's MAC address (note that all nodes attached to the switch will see this packet). When node Y responds directly to node A with it's MAC address, then node A will initiate a TCP connection directly to node Y.
If node M is a switch, it will only forward packets destined for MAC address F directly to the port which it knows to be attached to the node having MAC address F. It will never forward that packet to all ports, but only to the destination node's port.
On the other hand, if node M is a hub, it will always forward all packets to all ports regardless of destination.

Related

DOES router or linux kernel change the tcp headers and ip headers of packets

I was looking into raw sockets. so I created one raw socket client and other one is server. on two different computers. I am using ISP provided router. so I sent spoofed packet (with iphdr struct's saddr of different computer on same network) from client but when the packet received at the server the source ip in packet's ip header was correct (the real sender address=client address) plus the source port and destination port of tcphdr were something different too (which really didnt make sense). So I assumed that my ISP provided router is doing something funny -- OR I am completely wrong correct if this is a normal ip protocol. if I am correct then what steps should i take to configure my router so it does not mess up with tcp and ip headers of incoming packets plus the sync=1 at sender's end became sync=0 of tcphdr. I am using local IPs plus I am trying to implement tcp using raw socket server. I have configured iptables on server as well with sync allowed on my bounded port
iptables -I INPUT -p tcp --dport xxxx --syn -j ACCEPT
WHat settings do I need to do on server in iptables so my socket incoming packets wont be dropped nor any header be touched so I can get all packets required for tcp to keep coming in. plus what setting do I need to do on router so,if its cause problem then, it wont
Update 1:
after spending some time to the problem I found that one cause could be my kernel tcp stack dropping the incoming sync packets. so I looked around and found that in the tcp stack there is work done to make this happening. So I changed the sysctl.conf in /etc to allow sync packets to come in through by adding or uncommenting this line
net.ipv4.tcp_syncookies=1
Then I rebooted the system but still no difference. is it because somehow I have to reload my sysctl.conf file. if this is the case or any related case then please fill in.
Update 2
I have reloaded sysctl.conf after allowing syn packets and now I am getting syn packets from client application. but the destination port different. also along with syn=1, ack=1 is also coming in same packet. is this also something kernel is doing. please explain. as long as I know this is not how tcp works (tcp handshake) and I am connecting from client using stream socket

UDP send test fails on amazon ec2 - all outgoing traffic enabled

I'm running an ubuntu 14.04 instance on amazon ec2- I can't seem to send any udp packets from my instance to my local machine.
Running the followings commands:
On amazon ec2 instance:
echo "test" | netcat -vu m.y.i.p 5500
Connection to m.y.i.p 5500 port [udp/*] succeeded!
On my local machine:
netcat -luv 5500
Listening on [0.0.0.0] (family 0, port 5500)
So we successfully make a connection, but I never receive the test packet on my local machine.
Is there anything else I might need to configure with my instance for this to work?
A UDP transmission does not have a connection (as does TCP) so the message "Connection to m.y.i.p 5500 port [udp/*] succeeded!" doesn't really tell you much about the true success of the transmission of a packet from A to B. It might have never even left the originating machine (due to some firewall rule).
In my experience most common UDP problems are firewall blocks at the incoming machine so you certainly need to check on any firewall rules that might be blocking UDP incoming on port 5500.
If that looks ok, then the easiest way to debug is to use a packet sniffer (tcpdump, wireshark or similar). First confirm that a UDP packet is leaving your source machine, then try to see it incoming on the target machine.
tcpdump host m.y.i.p

how to test user space tcp/ip stack?

I am working on a user space tcp stack (mostly just for fun) and I am having some trouble testing it against the unix tcp stack. Currently the only form of testing is done via unit tests. However, I want to test my tcp stack against a real kernel tcp stack. I tried the following setups without much success.
using raw sockets: I wrote a simple echo tcp server that accepts connection using the kernel tcp socket. The tcp server listens to port 8080 on localhost. My tcp client uses the user space tcp stack. However, the kernel sends a tcp rst whenever the client sends a syn to the server. It kind of work after I modified iptable to drop all tcp rst packets. However, even though the 3 way syn, syn+ack, ack handshake is established, the server cannot recv any packet that my client sends. I eventually gave up on raw sockets.
using tun/tap: Similarly the echo server uses kernel tcp socket and listens on localhost port 8080. The client opens a tap device. The tap device has an ip of 10.0.0.1 and my client assumes an ip of 10.0.0.2. I am able to ping 10.0.0.2 from my computer. However, when my client sends a syn to the tcp server over the tap device, the server does not respond.
Note: I am using ubuntu 12.04.
You can use the conntrack tool to try getting more information on why it's not working with using raw sockets. If for some reason the kernel gets confused about the state of the tcp connection, it may be deciding to reset it. You could try telling the kernel not to track connections to rule this out by setting a notrack rule in the raw table. Something like
iptables -t raw -A PREROUTING -p tcp --port 8080 -j NOTRACK
Try using tcpdump on the tun/tap device and iptables counts to see where the packet gets dropped. I would also try tun devices instead so you only have to worry about layer 3.

linux tcp connection established on client, invisible on server

on one of my linux hosts, one tcp socket seems to be visible on one side and invisble on the other side. I mean netstat displays this socket when I am on one of the hosts and not when I am on the other (linux too):
# netstat -anp|grep 37674
udp 0 0 169.254.192.2:37674 169.254.192.1:8649 ESTABLISHED 22644/xxxxx
# ssh 169.254.192.1
Last login: Mon Jan 13 15:22:54 CET 2014 from xxxxxx on ssh
# netstat -anp|grep 8649
#
If I undestand correctly, netstat reads connections from /proc/net/tcp. Apparently, local ip address and ports are given as 0123ABCD:1234 in /proc/net/tcp in second column.
37674(10) = 932A(16)
Thus, I tried to find 932A in /proc/net/tcp, ignoring case but found nothing.
IP address is not truncated as I have no other 169.254.192.1xx host on my network.
This connection is still visible after three hours, thus I don't think it's timeout related.
The output of netstat says UDP. (Look in /proc/net/udp)
This means means 169.254.192.2 has called connect() to 169.254.192.1:8649. UDP is however connectionless, so this info is just recorded locally on a socket on the 169.254.192.2 machine.
Calling connect() on an UDP socket just enables you to call send() on that socket without specifying the destination address for each packet with sendto()/sendmsg() - no actual connection created between the two machines.
If the 169.254.192.1 machine isn't listening/receiving packets on port 8649, it isn't meaningful for the 169.254.192.1 machine to set up a socket that can send packets there though.

bi-directional socket to tcp communication

I have a software X listening and writing to TCP port. I.e. It creates a Server Socket and a client that reads and writes to TCP.
And I have a serial device ttyUSB0 which can accept data in a format that provides software X and send data back to serial.
I want to feed data from serial to TCP and vice versa, so that it looked transparent to software X and to a serial ttyUSB0.
I was trying to use socat. Like,
socat -d -d -d -d -x TCP-LISTEN:7758,fork,reuseaddr FILE:/dev/ttyUSB0,b9600,raw
But it seems that it does not work. Looks as if listener on TCP port blocks binding. I have
E bind(3, {AF=2 0.0.0.0:7758}, 16): Address already in use
Could someone please help me with my problem?
As some commenters already mentioned, you can't make a TCP connection with two listeners. For a TCP connection you always need a server (listener) and a client.
As your software is already a server (listening on port 7758) socat should be run in client mode (connecting to your server).
This can be done with the option TCP:<host>:<port>, for example like this (adapted your example, not tested!):
socat -d -d -d -d -x TCP:localhost:7758 FILE:/dev/ttyUSB0,b9600,raw
This is not possible for TCP. Note that you could specify SO_REUSSEADDR but this will not cause BOTH listening applications to receive the data: only one app (decided at "random" by the OS) will receive the data, while the other will "hear" nothing.
If you can use multicast UDP you can do this.
See Can two applications listen to the same port?

Resources