Understanding tpcdump -d option - linux

I'm new to the forum, so apologies if I'm breaking any rules here (feel free to correct and/or re-direct)
That said: I'm trying to understand what the "-d" option does in tpcdump
(i.e. tcpdump -i any -d)
Running the example command above, it's clear that the output is different than without -d, but I'm not understanding the output or its purpose
The man page states
"Dump the compiled packet-matching code in a human readable form to standard output and stop."
but I'm having trouble parsing the meaning - What does it mean by packet-matching code? And what are some of the purposes of using this output?
Many thanks for any responses

When you use a capture filter with tcpdump like tcpdump -i <any> tcp port 443, you are filtering out packets that are not TCP packets or that aren't sent on port 443. But how, you ask, does tcpdump know how to do this?
Packet-matching code here refers to BPF (Berkeley Packet Filter) syntax code. In other words, what does tcp port 443 break down into at a lower level? If we run tcpdump -i <any> tcp port 443, we can see:
$ tcpdump -i en0 -d tcp port 443
(000) ldh [12]
(001) jeq #0x86dd jt 2 jf 8
(002) ldb [20]
(003) jeq #0x6 jt 4 jf 19
(004) ldh [54]
(005) jeq #0x1bb jt 18 jf 6
(006) ldh [56]
(007) jeq #0x1bb jt 18 jf 19
(008) jeq #0x800 jt 9 jf 19
(009) ldb [23]
(010) jeq #0x6 jt 11 jf 19
(011) ldh [20]
(012) jset #0x1fff jt 19 jf 13
(013) ldxb 4*([14]&0xf)
(014) ldh [x + 14]
(015) jeq #0x1bb jt 18 jf 16
(016) ldh [x + 16]
(017) jeq #0x1bb jt 18 jf 19
(018) ret #262144
(019) ret #0
For an information about what people use tcpdump -d for, there are articles on it. For a thorough breakdown of how BPF code works, tshark.dev has an article on it.

Related

In ss -s, what is the kernel counter actually counting?

While troubleshooting a problem on an OEL 7 server (3.10.0-1062.9.1.el7.x86_64), I ran the command
sudo ss -s
Which gave me the output of:
Total: 601 (kernel 1071)
TCP: 8 (estab 2, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0
Transport Total IP IPv6
1071 - -
RAW 2 0 2
UDP 6 4 2
TCP 8 5 3
INET 16 9 7
FRAG 0 0 0
Doing an ss -a | wc -l came back with 225 entries.
It leads me to the question, what is kernel 1071 actually counting?
Looking through the various man pages did not provide an answer.
Using strace, I can see where ss reads:
/proc/net/sockstat
/proc/net/sockstat6
/proc/net/snmp
/proc/slabinfo
Looking through those files and the docs, it looks like the value is coming from /proc/slabinfo.
Grepping through /proc/slabinfo for 1071 came back with one entry:
sock_inode_cache 1071 1071 640 51 8 : tunables 0 0 0 : slabdata 21 21 0
Looking through the files and docs on sock_inode_cache has not helped so far. I am hoping someone here knows what the kernel counter is actually counting, or can point me in the right direction.
what is kernel 1071 actually counting?
sock_inode_cache represents Linux kernel Slab statistics. It shows how many socket inodes (active objects) are there.
struct socket_alloc corresponds to the sock_inode_cache slab cache and contains the struct socket and struct inode, so it is connected to VFS.

PXEBOOT, TFTPD-HPA and Firewall

I have setup a pxeboot which basically works fine. I can run any configured linux image.
Then I have enabled the firewall, released UDP port 69 for TFTP
~# iptables -L |grep tftp
ACCEPT udp -- anywhere anywhere udp dpt:tftp
ACCEPT udp -- anywhere anywhere udp dpt:tftp
~# netstat -tulp|grep tftp
udp 0 0 0.0.0.0:tftp 0.0.0.0:* 15869/in.tftpd
udp6 0 0 [::]:tftp [::]:* 15869/in.tftpd
~# cat /etc/services|grep tftp
tftp 69/udp
and now I get a timeout when pxeboot is pulling tftp://192.168.0.220/images/pxelinux.0 (rc = 4c126035).
Anywhere is ok here for now as there is another firewall running between the pxeserver and the router which blocks everything unwanted from/to WAN
The funny part is that tcpdump shows that the request is incoming on the pxeboot server:
~# tcpdump port 69
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp5s0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:00:47.062723 IP 192.168.0.136.1024 > mittelerde.tftp: 47 RRQ "images/pxelinux.0" octet blksize 1432 tsize 0
14:00:47.415412 IP 192.168.0.136.1024 > mittelerde.tftp: 47 RRQ "images/pxelinux.0" octet blksize 1432 tsize 0
14:00:48.184506 IP 192.168.0.136.1024 > mittelerde.tftp: 47 RRQ "images/pxelinux.0" octet blksize 1432 tsize 0
14:00:49.722630 IP 192.168.0.136.1024 > mittelerde.tftp: 47 RRQ "images/pxelinux.0" octet blksize 1432 tsize 0
14:00:52.798136 IP 192.168.0.136.1024 > mittelerde.tftp: 47 RRQ "images/pxelinux.0" octet blksize 1432 tsize 0
Once I stop the firewall service pxeboot works fine again. Of course the conntrack module is loaded:
~# lsmod|grep conntrack
nf_conntrack_tftp 16384 0
nf_conntrack_ftp 20480 0
xt_conntrack 16384 4
nf_conntrack_ipv4 16384 20
nf_defrag_ipv4 16384 1 nf_conntrack_ipv4
nf_conntrack 131072 9 xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4,nf_nat,nf_conntrack_tftp,ipt_MASQUERADE,nf_nat_ipv4,xt_nat,nf_conntrack_ftp
libcrc32c 16384 2 nf_conntrack,nf_nat
x_tables 40960 8 xt_conntrack,iptable_filter,xt_multiport,xt_tcpudp,ipt_MASQUERADE,xt_nat,xt_comment,ip_tables
What I am missing here?
Problem solved. For tftpd-hpa the following UDP ports must be open as well:
1024
49152:49182

Linux: where to find the "segments retransmited" from /proc?

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

NTPD on arm box version 4.2.6p5

i have managed to cross compile ntpd 4.2.6p5 for my arm box. I have a custom toolchain provided by the manufacturer.
Box is running busybox + some variant of debian linux.
So I have no installation of ntp and did a manual copy, created a conf file for the ntpd and tried to run it.
ntpd always returns this when in debug mode:
~/ntp # ./ntpd -c ntp.conf -d
ntpd 4.2.6p5#1.2349 Mon Apr 7 19:58:25 UTC 2014 (1)
9 Apr 07:39:44 ntpd[3592]: signal_no_reset: signal 13 had flags 4000000
9 Apr 07:39:44 ntpd[3592]: proto: precision = 91.000 usec event at 0 0.0.0.0 c01d 0d
kern kernel time sync enabled
Finished Parsing!!
9 Apr 07:39:44 ntpd[3592]: ntp_io: estimated max descriptors: 1024, initial socket
boundary: 16
9 Apr 07:39:44 ntpd[3592]: Listen and drop on 0 v4wildcard 0.0.0.0 UDP 123
9 Apr 07:39:44 ntpd[3592]: unable to bind to wildcard address :: - another process
may be running - EXITING
before that I had to add into /etc/services also
ntp 123/udp
my ntp.conf looks like:
~/ntp # cat ntp.conf
server 193.2.4.6
server 193.2.4.2
driftfile ntp.drift
So I have checked netstat and nothing is running on port 123, no ntpdate etc...
~/ntp # netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.3.1 0.0.0.0 UG 0 0 0 eth0
192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
~ # netstat -a | grep 123
~ #
Therefore it must be something with the config, or this arm box does not have something configured...
Oh and running manually ntpdate works:
~/ntp # ./ntpdate 193.2.4.6
9 Apr 07:49:16 ntpdate[3614]: step time server 193.2.4.6 offset -0.755704 sec
~/ntp #
So yes i could use ntpdate in cron, but this is not my intent!
Any idea?
Thank you and best regards!
The following error indicates that ntp had trouble binding to the ipv6 wildcard:
9 Apr 07:39:44 ntpd[3592]: unable to bind to wildcard address :: - another process
may be running - EXITING
I think your problem is ipv6 but it is hard to tell because your diagnosticinformation was not very good. Your netstat -a |grep 123 command is useless because netstat would substitute ntp for port 123. Try it again with:
netstat -a -n | grep 123
Along those lines netstat -rn only works with ipv4, try it again with -6:
netstat -r -n -6
Your test ntpdate used an ipv4 host. Does your server support ipv6? What happens when you run:
$ sntp -d -6 time.nist.gov
I used sntp because I do not know if ntpdate has a -6option and sntp does.

Efficiently test if a port is open on Linux?

From a bash script how can I quickly find out whether a port 445 is open/listening on a server.
I have tried a couple of options, but I want something quick:
1. lsof -i :445 (Takes seconds)
2. netstat -an |grep 445 |grep LISTEN (Takes seconds)
3. telnet (it doesn't return)
4. nmap, netcat are not available on the server
It will be nice to know of a way that doesn't enumerate first and greps after that.
A surprise I found out recently is that Bash natively supports tcp connections as file descriptors. To use:
exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6
I'm using 6 as the file descriptor because 0,1,2 are stdin, stdout, and stderr. 5 is sometimes used by Bash for child processes, so 3,4,6,7,8, and 9 should be safe.
As per the comment below, to test for listening on a local server in a script:
exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection
To determine if someone is listening, attempt to connect by loopback. If it fails, then the port is closed or we aren't allowed access. Afterwards, close the connection.
Modify this for your use case, such as sending an email, exiting the script on failure, or starting the required service.
There's a very short with "fast answer" here : How to test if remote TCP port is opened from Shell script?
nc -z <host> <port>; echo $?
I use it with 127.0.0.1 as "remote" address.
this returns "0" if the port is open and "1" if the port is closed
e.g.
nc -z 127.0.0.1 80; echo $?
-z Specifies that nc should just scan for listening daemons,
without sending any data to them. It is an error to use this option
in conjunc-
tion with the -l option.
You can use netstat this way for much faster results:
On Linux:
netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'
On Mac:
netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'
This will output a list of processes listening on the port (445 in this example) or it will output nothing if the port is free.
You can use netcat for this.
nc ip port < /dev/null
connects to the server and directly closes the connection again. If netcat is not able to connect, it returns a non-zero exit code. The exit code is stored in the variable $?. As an example,
nc ip port < /dev/null; echo $?
will return 0 if and only if netcat could successfully connect to the port.
Based on Spencer Rathbun's answer, using bash:
true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed
they're listed in /proc/net/tcp.
it's the second column, after the ":", in hex:
> cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 10863 1 ffff88020c785400 99 0 0 10 -1
1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 7983 1 ffff88020eb7b3c0 99 0 0 10 -1
2: 0500010A:948F 0900010A:2328 01 00000000:00000000 02:00000576 00000000 1000 0 10562454 2 ffff88010040f7c0 22 3 30 5 3
3: 0500010A:E077 5F2F7D4A:0050 01 00000000:00000000 02:00000176 00000000 1000 0 10701021 2 ffff880100474080 41 3 22 10 -1
4: 0500010A:8773 16EC97D1:0050 01 00000000:00000000 02:00000BDC 00000000 1000 0 10700849 2 ffff880104335440 57 3 18 10 -1
5: 0500010A:8772 16EC97D1:0050 01 00000000:00000000 02:00000BF5 00000000 1000 0 10698952 2 ffff88010040e440 46 3 0 10 -1
6: 0500010A:DD2C 0900010A:0016 01 00000000:00000000 02:0006E764 00000000 1000 0 9562907 2 ffff880104334740 22 3 30 5 4
7: 0500010A:AAA4 6A717D4A:0050 08 00000000:00000001 02:00000929 00000000 1000 0 10696677 2 ffff880106cc77c0 45 3 0 10 -1
so i guess one of those :50 in the third column must be stackoverflow :o)
look in man 5 proc for more details. and picking that apart with sed etc is left as an exercise for the gentle reader...
ss -tl4 '( sport = :22 )'
2ms is quick enough ?
Add the colon and this works on Linux
nc -l 8000
Where 8000 is the port number. If the port is free, it will start a server that you can close easily. If it isn't it will throw an error:
nc: Address already in use
Here's one that works for both Mac and Linux:
netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'
I wanted to check if a port is open on one of our linux test servers.
I was able to do that by trying to connect with telnet from my dev machine to the test server. On you dev machine try to run:
$ telnet test2.host.com 8080
Trying 05.066.137.184...
Connected to test2.host.com
In this example I want to check if port 8080 is open on host test2.host.com
You can use netcat command as well
[location of netcat]/netcat -zv [ip] [port]
or
nc -zv [ip] [port]
-z – sets nc to simply scan for listening daemons, without actually sending any data to them.
-v – enables verbose mode.
tcping is a great tool with a very low overhead.It also has a timeout argument to make it quicker:
[root#centos_f831dfb3 ~]# tcping 10.86.151.175 22 -t 1
10.86.151.175 port 22 open.
[root#centos_f831dfb3 ~]# tcping 10.86.150.194 22 -t 1
10.86.150.194 port 22 user timeout.
[root#centos_f831dfb3 ~]# tcping 1.1.1.1 22 -t 1
1.1.1.1 port 22 closed.
nmap is the right tool.
Simply use nmap example.com -p 80
You can use it from local or remote server.
It also helps you identify if a firewall is blocking the access.
If you're using iptables try:
iptables -nL
or
iptables -nL | grep 445

Resources