We can use "netstat -s" to query "segments retransmitted". But:
1) Where does the original data from? /proc? Looks like /proc/net/netstat includes other retransmit counters but no "segments retransmitted".
2) How do I get this programmatically by C?
Thanks!
lisa#ubuntuClient:~/logs# netstat -s | grep trans
479025 segments retransmited
TCPLostRetransmit: 4934
252476 fast retransmits
103 forward retransmits
77435 retransmits in slow start
668 SACK retransmits failed
TCPRetransFail: 44
TCPSynRetrans: 2250
According to the netstat trace:
open("/proc/net/snmp", O_RDONLY) = 3
These values come from /proc/net/snmp.
Regarding to how to access these values programmatically [in C or any other language], I think netstat can answer that question: read the file and parse its contents :).
Notes:
netstat v1.42, net-tools 1.60
Related
I'm experiencing some problems with my internet connection so my provider told me to make a logfile for an evening (min. 3 Hours) to see when the connection drops out to see what's the cause of the problem.
When I'm losing connection, I still remain in the network but my Inernet is simply 0B/s. Is there a way to make a log for a certain Time interval that constantly checks the internet connection (and ideally the download/upload speed). I'm kinda beginner in the Linux world and it would be very helpful when the answer will be good explained and every step will be described.
Thanks in advance.
For checking every 10 seconds that your connection is available you could use
ping 8.8.8.8 -D -i 1 2>&1 | tee my.log
where 8.8.8.8 is a DNS server run by Google.
File my.log will receive entries like:
[1583495940.797787] 64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=17.9 ms
[1583495950.809658] 64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=18.7 ms
ping: sendmsg: Network is unreachable
The number in square brackets is the time in seconds since 1970-01-01T00:00:00Z. For our example:
1583495950 = 2020-03-06T11:59:10Z
If you want to really transfer data, you could use a script like:
#!/bin/sh
URL=https://example.com
while [ true ]
do
wget $URL -O /dev/null 2>&1 | grep 'saved' | tee my.log
sleep 10
done
But mind the traffic cost on both sides.
I am not able to find an answer to a simple thing I will try to achive:
once a tcp connection is established to my linux server, let's say ssh / tcp 22 or x11 / tcp 6000 display -> how do I close this connection without killing the process (sshd / x11 display server).
I saw also some suggestoin to use iptables, but it does not work for me, the connection is still visible in netstat -an.
would be good if someone can point me to the right direction.
what I tried so far
tcpkill: kills the process, not good for me
iptables: does not close the established connection, but prevent further connections.
Thanks in adavnce
DJ
Ok, I found at least one solution (killcx) which is working. Maybe we will be able to find an easier solution.
Also, i saw the comment from "zb" - thanks - which might also work, but I was not able to find a working syntax, since this tool seems to be really useful but complex.
So here is an example how to work with the 1. solution which is working for me:
netstat -anp | grep 22
output: tcp 0 0 192.168.0.82:22 192.168.0.77:33597 VERBUNDEN 25258/0
iptables -A INPUT -j DROP -s 192.168.0.77 (to prevent reconnect)
perl killcx.pl 192.168.0.77:33597 (to kill the tcp connection)
killcx can be found here: http://killcx.sourceforge.net/
it "steals" the connection from the foreign host (192.168.0.77) and close it. So that solution is working fine, but to complex to setup quickly if you are under stress. Here are the required packages:
apt-get install libnetpacket-perl libnet-pcap-perl libnet-rawip-perl
wget http://killcx.sourceforge.net/killcx.txt -O killcx.pl
however, would be good to have an easier solution.
tcpkill wont work, since it will only kill any new connection, it doesnt kill existing ESTABLISHED connections
heres how you remove an Established TCP connection
find the PID of the process and the IP of the client connecting,
lets say you are on serverA and someone is connecting from serverB
root#A> netstat -tulpan | grep ssh | grep serverB
should see something like,
tcp 0 0 <serverA IP>:<port> <serverB>:<port> ESTABLISHED 221955/sshd
use lsof utility to get the File Descriptor of this connection using the parent PID
root#A> lsof -np 221995 | grep serverB IP
should see something like this
sshd 221955 <user> 17u IPv4 2857516568 0t0 TCP <serverA IP>:<port>-><serverB IP>:<port> (ESTABLISHED)
get the File Descriptor number (4th column) = 17u
use GDB to shut down this connection, w/out killing sshd
root#A> gdb -p 211955 --batch -ex 'call shutdown(17u, 2)'
should see something similar,
0x00007f0b138c0b40 in __read_nocancel () from /usr/lib64/libc.so.6
$1 = 0
[Inferior 1 (process 211955) detached]
that TCP connection should now be closed
I'm trying to figure out what process is holding the other end of a unix domain socket. In some strace output I've identified a given file descriptor which is involved in the problem I'm currently debugging, and I'd like to know which process is on the other end of that. As there are multiple connections to that socket, simply going by path name won't work.
lsof provides me with the following information:
dbus-daem 4175 mvg 10u unix 0xffff8803e256d9c0 0t0 12828 #/tmp/dbus-LyGToFzlcG
So I know some address (“kernel address”?), I know some socket number, and I know the path. I can find that same information in other places:
$ netstat -n | grep 12828
unix 3 [ ] STREAM CONNECTED 12828 #/tmp/dbus-LyGToFzlcG
$ grep -E '12828|ffff8803e256d9c0' /proc/net/unix
ffff8803e256d9c0: 00000003 00000000 00000000 0001 03 12828 #/tmp/dbus-LyGToFzlcG
$ ls -l /proc/*/fd/* 2>/dev/null | grep 12828
lrwx------ 1 mvg users 64 10. Aug 09:08 /proc/4175/fd/10 -> socket:[12828]
However, none of this tells me what the other end of my socket connection is. How can I tell which process is holding the other end?
Similar questions have been asked on Server Fault and Unix & Linux. The accepted answer is that this information is not reliably available to the user space on Linux.
A common suggestion is to look at adjacent socket numbers, but ls -l /proc/*/fd/* 2>/dev/null | grep 1282[79] gave no results here. Perhaps adjacent lines in the output from netstat can be used. It seems like there was a pattern of connections with and without an associated socket name. But I'd like some kind of certainty, not just guesswork.
One answer suggests a tool which appears to be able to address this by digging through kernel structures. Using that option requires debug information for the kernel, as generated by the CONFIG_DEBUG_INFO option and provided as a separate package by some distributions. Based on that answer, using the address provided by lsof, the following solution worked for me:
# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer
This will print the address of the other end of the connection. Grepping lsof -U for that number will provide details like the process id and the file descriptor number.
If debug information is not available, it might be possible to access the required information by knowing the offset of the peer member into the unix_sock structure. In my case, on Linux 3.5.0 for x86_64, the following code can be used to compute the same address without relying on debugging symbols:
(gdb) p ((void**)0xffff8803e256d9c0)[0x52]
I won't make any guarantees about how portable that solution is.
Update: It's been possible to to do this using actual interfaces for a while now. Starting with Linux 3.3, the UNIX_DIAG feature provides a netlink-based API for this information, and lsof 4.89 and later support it. See https://unix.stackexchange.com/a/190606/1820 for more information.
I wish to capture tcpdump traffic on two different ports simultaneouly .
I tried this ..
$ tcpdump port 21 ; tcpdump port 22
Althoug it worked but problem is first it will wait for traffic on port 21 and when interrupted then it will wait for port 22.
Also another problem is it will not capture the traffic on port 22 untill traffic on port 21 will be captured.
I want an order free solution means in whatever order packet arrives if they are for port 21 or 22 they should be captured .
Please help me on this !!!
EDIT :
Sorry I did not specified it before the actual command I am trying to run is this ..
$ tcpdump -X -s0 protochain 50
and
$ tcpdump -X -s0 protochain 51
Now I need to use 50 and 51 both simultaneously ..
Hi, you just need to compose two ports like this:
tcpdump -n -i $INTERFACE port 21 or port 22
where -n will get numerical address without reverse resolving (faster)
and $INTERFACE is real interface where you sniff trafic
I am no tcpdump expert but found this in the tcpdump manpage:
tcpdump 'gateway snup and (port ftp or ftp-data)'
So try this
tcpdump '(port ftp or ftp-data)'
Problem solved it was actually very simple I should have tried it before ..
but thanks I got my idea just by looking at your answers.
I think it is the beauty of stackoverflow if we could find an exact answer , we can invent it through the discussion. ..
$ tcpdump -X -s0 protochain 50 or 51
Like other contributors said, you can use the and logical operator, but be aware than you can also use it in conjunction with other operators. To ensure that tcpdump sees them, and that the operator precedence is the one you want, use brackets, but only within single quotes, like in this example below:
sudo tcpdump -i eth0 '(port 465 or port 587)' and src 1.2.3.4, because if you omit the single quotes, your shell may interpret them before tcpdump does, and b), you will not be certain of what the operator precedence is to one another. Strong of this, you may now do any combination, just like in arithmetic.
Is there a way to tie a network connection to a PID (process ID) without forking to lsof or netstat?
Currently lsof is being used to poll what connections belong which process ID. However lsof or netstat can be quite expensive on a busy host and would like to avoid having to fork to these tools.
Is there someplace similar to /proc/$pid where one can look to find this information? I know what the network connections are by examining /proc/net but can't figure out how to tie this back to a pid. Over in /proc/$pid, there doesn't seem to be any network information.
The target hosts are Linux 2.4 and Solaris 8 to 10. If possible, a solution in Perl, but am willing to do C/C++.
additional notes:
I would like to emphasize the goal here is to tie a network connection to a PID. Getting one or the other is trivial, but putting the two together in a low cost manner appears to be difficult. Thanks for the answers to so far!
I don't know how often you need to poll, or what you mean with "expensive", but with the right options both netstat and lsof run a lot faster than in the default configuration.
Examples:
netstat -ltn
shows only listening tcp sockets, and omits the (slow) name resolution that is on by default.
lsof -b -n -i4tcp:80
omits all blocking operations, name resolution, and limits the selection to IPv4 tcp sockets on port 80.
On Solaris you can use pfiles(1) to do this:
# ps -fp 308
UID PID PPID C STIME TTY TIME CMD
root 308 255 0 22:44:07 ? 0:00 /usr/lib/ssh/sshd
# pfiles 308 | egrep 'S_IFSOCK|sockname: '
6: S_IFSOCK mode:0666 dev:326,0 ino:3255 uid:0 gid:0 size:0
sockname: AF_INET 192.168.1.30 port: 22
For Linux, this is more complex (gruesome):
# pgrep sshd
3155
# ls -l /proc/3155/fd | fgrep socket
lrwx------ 1 root root 64 May 22 23:04 3 -> socket:[7529]
# fgrep 7529 /proc/3155/net/tcp
6: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 7529 1 f5baa8a0 300 0 0 2 -1
00000000:0016 is 0.0.0.0:22. Here's the equivalent output from netstat -a:
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
Why don't you look at the source code of netstat and see how it get's the information? It's open source.
For Linux, have a look at the /proc/net directory
(for example, cat /proc/net/tcp lists your tcp connections). Not sure about Solaris.
Some more information here.
I guess netstat basically uses this exact same information so i don't know if you will be able to speed it up a whole lot. Be sure to try the netstat '-an' flags to NOT resolve ip-adresses to hostnames realtime (as this can take a lot of time due to dns queries).
The easiest thing to do is
strace -f netstat -na
On Linux (I don't know about Solaris). This will give you a log of all of the system calls made. It's a lot of output, some of which will be relevant. Take a look at the files in the /proc file system that it's opening. This should lead you to how netstat does it. Indecently, ltrace will allow you to do the same thing through the c library. Not useful for you in this instance, but it can be useful in other circumstances.
If it's not clear from that, then take a look at the source.
Take a look at these answers which thoroughly explore the options available:
How I can get ports associated to the application that opened them?
How to do like "netstat -p", but faster?