In my networking course, I studied that there are 11 tcp states, They are as follows:
Closed
Listen
Syn_Sent
Syn_Rcvd
Established
Fin_Wait_1
Fin_Wait_2
Closing
Time_Wait
Last_Ack
Close_Wait
I don't know exactly how many of these states are actually implemented in Linux Kernel Network Architecture.
I want to write a program using system calls which can capture all these states which are implemented in Linux Kernel.
Actually i want to use socket programming and system calls for just capturing these states like :
whenever I do netstat -taupen | grep tcp , I want to see all these connection's states in the State column for the same tcp connection at different times.
Somebody give me some idea on how to program such a code.
First of all, you'll need to implement both the the client and server sides of the connection and you'll probably need to run them from an external script so that they can be passed proper parameters and / or killed at the needed times to demonstrate the various states in a way viewable from netstat. The best reference for the details of doing something like this would be Steven's Unix Network Programming. If you browser through the book and the source code ( which can be downloaded here ) you'll see examples of ways to intentionally cause various TCP connection states in an observable manner. One thing you'll want to look at is the code for non-blocking connects and also look up SO_REUSEADDR, SO_LINGER, time-wait assassination. There's no substitute for reading Steven's when it comes to a subject like this.
They are all implemented but you can only observe these with socket API calls:
Closed
Listen
Syn_Sent (non-blocking only)
Established
Fin_Wait_1 (implicit)
Fin_Wait_2 (only by trying to read and getting EOF)
Closing (non-blocking only)
Last ACK (only by trying to reuse port)
If you're not happy Inferring the state from external observation (packet tracing), then you'll have to instrument the kernel code: add some log statements in the transition code, recompile the kernel ..
/usr/src/linux-source-2.6.32/net/ipv4# head -n 250 tcp.c | grep -n "^[^a-zA-Z0-9]*TCP_" | sed "s|^.*(TCP_[A-Z0-9_]).|\1|" | while read S ; do echo -e "\n $S :" ; grep -l $S ./* | tr '\n' ' '; done ; echo
TCP_SYN_SENT :
./af_inet.c ./tcp.c ./tcp_input.c ./tcp_ipv4.c ./tcp_output.c
TCP_SYN_RECV :
./inet_connection_sock.c ./inet_diag.c ./tcp.c ./tcp_input.c ./tcp_ipv4.c ./tcp_minisocks.c
TCP_ESTABLISHED :
./datagram.c ./raw.c ./tcp.c ./tcp_input.c ./tcp_ipv4.c ./udp.c
TCP_FIN_WAIT1 :
./tcp.c ./tcp_input.c
TCP_FIN_WAIT2 :
./tcp.c ./tcp_input.c ./tcp_minisocks.c ./tcp_timer.c
TCP_CLOSING :
./tcp.c ./tcp_input.c
TCP_TIME_WAIT :
./inet_diag.c ./inet_timewait_sock.c ./tcp.c ./tcp_input.c ./tcp_ipv4.c ./tcp_minisocks.c
TCP_CLOSE_WAIT :
./tcp.c ./tcp_input.c
TCP_LAST_ACK :
./tcp.c ./tcp_input.c
TCP_CLOSE :
./af_inet.c ./inet_connection_sock.c ./inet_hashtables.c ./raw.c ./tcp.c ./tcp_cong.c ./tcp_input.c ./tcp_ipv4.c ./tcp_output.c ./tcp_timer.c ./udp.c
Related
I have a process using https. I found its PID using ps and used the command lsof -Pan -p PID -i to get the port number it is running on.
I need iftop to see the data transfer. The filter I am using now is
iftop -f "port http 57787".
I don't think this is giving me the right output.
Can someone help me the right filter to use with iftop so that I know the traffic going through only this port?
I can see 2 problems here:
1/ Is that a typo? The correct option for filtering is -f (small "f"). -F (capital "F") option is for net/mask.
2/ Though not explicitly stated by iftop documentation, the syntax for filtering seems to be the pcap one from the few examples given (and using ldd I can see that yes, the iftop binary is linked with libpcap). So a filter with http is simply not valid. To see the doc for pcap filtering syntax, have a look at pcap-filter (7) - packet filter syntax man page. In your example, a filter such as "tcp port 57787" would be OK. pcap does not do layer 5 and above protocol dissection such as http (pcap filters are handled by BPF in the kernel, so above layer 4 you're on your own, because that's none of the kernel business).
All in all, these looks like iperf bugs. It should refuse your "-F" option, and even with "-f" instead exit with an error code because pcap will refuse the filter expression. No big deal, iftop is a modest program. See edit bellow.
EDIT:
I just checked iftop version 1.0pre4 source code, and there is no such obvious bug from a look at set_filter_code() and its caller packet_init() in iftop.c. It correctly exit with error, but...
Error 2, use the "-f" option, but your incorrect filter syntax:
jbm#sumo:~$ sudo iftop -f "port http 57787"
interface: eth0
IP address is: 192.168.1.67
MAC address is: 8c:89:a5:57:10:3c
set_filter_code: syntax error
That's OK.
Error 1, the "-F" instead of "-f", there is a problem:
jbm#sumo:~$ sudo iftop -F "port http 57787"
(everything seems more or less OK, but then quit the program)
Could not parse net/mask: port http 57787
interface: eth0
IP address is: 192.168.1.67
MAC address is: 8c:89:a5:57:10:3c
Oops! "Could not parse net/mask: port http 57787"! That's a bug: it should exit right away.
Environment:
Unix client and unix server.
Tool used : curl.
Client/Server should ignore the time wait time (2 *MSL ) when establishing connection.
This is done by executing the following commands :
sysctl net.ipv4.tcp_tw_reuse=1
sysctl net.ipv4.tcp_tw_recycle=1
Local port must be specified so that it can re-used.
Start the connection.
Example : while [ 1 ]; do curl --local-port 9056 192.168.40.2; sleep 30; done
I am still seeing the error even though it should have ignored time wait period.
Any idea why this is happening?
I'm trying to write the linux client script for a simple port knocking setup. My server has iptables configured to require a certain sequence of TCP SYN's to certain ports for opening up access. I'm able to successfully knock using telnet or manually invoking netcat (Ctrl-C right after running the command), but failing to build an automated knock script.
My attempt at an automated port knocking script consists simply of "nc -w 1 x.x.x.x 1234" commands, which connect to x.x.x.x port 1234 and timeout after one second. The problem, however, seems to be the kernel(?) doing automated SYN retries. Most of the time more than one SYN is being send during the 1 second nc tries to connect. I've checked this with tcpdump.
So, does anyone know how to prevent the SYN retries and make netcat simply send only one SYN per connection/knock attempt? Other solutions which do the job are also welcome.
Yeah, I checked that you may use nc too!:
$ nc -z example.net 1000 2000 3000; ssh example.net
The magic comes from (-z: zero-I/O mode)...
You may use nmap for port knocking (SYN). Just exec:
for p in 1000 2000 3000; do
nmap -Pn --max-retries 0 -p $p example.net;
done
try this (as root):
echo 1 > /proc/sys/net/ipv4/tcp_syn_retries
or this:
int sc = 1;
setsockopt(sock, IPPROTO_TCP, TCP_SYNCNT, &sc, sizeof(sc));
You can't prevent the TCP/IP stack from doing what it is expressly designed to do.
Basically I have an application that has opened a socket.
e.g.
int socket = socket(PF_LOCAL, SOCK_STREAM, 0);
Now I want to send an HTTP put request to that socket. I know I should be using libcurl but I just can't get that to work correctly. So I want a way to connect curl to my application.
Maybe something like??
curl -X PUT -d #myXmlFile.xml /var/run/myunixsocket
Is there no way besides using libcurl??? I can't get it to work or find an example of it actually writing to a socket rather than a URI.
It should go without saying that an HTTP server is listening on the other end of that socket.
You will be able to use UNIX sockets in cURL 7.40 with the addition of a new --unix-socket option:
curl -X PUT -d #myXmlFile.xml --unix-socket /var/run/myunixsocket
Under the hood, it will use the the CURLOPT_UNIX_SOCKET_PATH option of libcurl. If you would like to know how to program with libcurl, use the --libcurl option:
curl --unix-socket /var/run/myunixsocket http://localhost/ --libcurl example.c
The generated file example.c will look like:
#include <curl/curl.h>
int main(int argc, char *argv[]) {
CURLcode ret;
CURL *hnd;
hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_URL, "http://host/path");
curl_easy_setopt(hnd, CURLOPT_UNIX_SOCKET_PATH, "/var/run/myunixsocket");
ret = curl_easy_perform(hnd);
curl_easy_cleanup(hnd);
hnd = NULL;
return (int)ret;
}
You can setup a ncat proxy quickly.
Terminal A
# forward incoming 2375/tcp to unix socket
$ ncat -vlk 2375 -c 'ncat -U /var/run/docker.sock'
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Listening on :::2375
Ncat: Listening on 0.0.0.0:2375
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:55539.
Terminal B
# make a tcp request
$ curl http://localhost:2375/images/json
...
I tried grepping the curl source for AF_'s other than AF_INET(6) and found only a couple of references to AF_UNIX, which were in the libcurl part and were mostly technical, assuming that someone "else" fills the sockaddr structure. I'm afraid there's no way to make the curl executable do this directly.
Is it disallowed or undesired in your application to listen on a TCP socket (as an alternative, maybe)? If not, but you are not against listening to one on your machine (with proper access control, of course), you may create one simply as a tunnel to AF_LOCAL... I know this is a terrible workaround but it would work, at least.
I think your problem here is that curl has no idea how to communicate with a unix domain socket -- it expects a tcp socket.
OK, we all know how to use PING to test connectivity to an IP address. What I need to do is something similar but test if my outbound request to a given IP Address as well as a specif port (in the present case 1775) is successful. The test should be performed preferably from the command prompt.
Here is a small site I made allowing to test any outgoing port. The server listens on all TCP ports available.
http://portquiz.net
telnet portquiz.net XXXX
If there is a server running on the target IP/port, you could use Telnet. Any response other than "can't connect" would indicate that you were able to connect.
To automate the awesome service portquiz.net, I did write a bash script :
NB_CONNECTION=10
PORT_START=1
PORT_END=1000
for (( i=$PORT_START; i<=$PORT_END; i=i+NB_CONNECTION ))
do
iEnd=$((i + NB_CONNECTION))
for (( j=$i; j<$iEnd; j++ ))
do
#(curl --connect-timeout 1 "portquiz.net:$j" &> /dev/null && echo "> $j") &
(nc -w 1 -z portquiz.net "$j" &> /dev/null && echo "> $j") &
done
wait
done
If you're testing TCP/IP, a cheap way to test remote addr/port is to telnet to it and see if it connects. For protocols like HTTP (port 80), you can even type HTTP commands and get HTTP responses.
eg
Command IP Port
Telnet 192.168.1.1 80
The fastest / most efficient way I found to to this is with nmap and portquiz.net described here: http://thomasmullaly.com/2013/04/13/outgoing-port-tester/ This scans to top 1000 most used ports:
# nmap -Pn --top-ports 1000 portquiz.net
Starting Nmap 6.40 ( http://nmap.org ) at 2017-08-02 22:28 CDT
Nmap scan report for portquiz.net (178.33.250.62)
Host is up (0.072s latency).
rDNS record for 178.33.250.62: electron.positon.org
Not shown: 996 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
443/tcp open https
8080/tcp open http-proxy
Nmap done: 1 IP address (1 host up) scanned in 4.78 seconds
To scan them all (took 6 sec instead of 5):
# nmap -Pn -p1-65535 portquiz.net
The bash script example of #benjarobin for testing a sequence of ports did not work for me so I created this minimal not-really-one-line (command-line) example which writes the output of the open ports from a sequence of 1-65535 (all applicable communication ports) to a local file and suppresses all other output:
for p in $(seq 1 65535); do curl -s --connect-timeout 1 portquiz.net:$p >> ports.txt; done
Unfortunately, this takes 18.2 hours to run, because the minimum amount of connection timeout allowed integer seconds by my older version of curl is 1. If you have a curl version >=7.32.0 (type "curl -V"), you might try smaller decimal values, depending on how fast you can connect to the service. Or try a smaller port range to minimise the duration.
Furthermore, it will append to the output file ports.txt so if run multiple times, you might want to remove the file first.