Count the number of network packets in realtime (CLI) - networking

I want to count the number of network incoming/outgoing packets in realtime and in the CLI (I want to use the count to write shell script)
I try to use 'tcpdump' and 'tsahrk' combined with pipeline, but it's doesn't work (I have little talent and learning).
Finally,I found the command 'dumpcap', it's almost close to my need, here is dumpcap stdout
[root#hostname ~]# dumpcap -i eth0
File: /tmp/wiresharkXXXXuTE8mU
Packets: 31
When i use this command combined with 'grep', like this 'dumpcap -i eth0 | grep -o '[0-9]*' to filter the number in stdout(31),but it's still doesn't work.
Is their any way to solve this or any idea for this ??
Thank you very much for your attention to this matter.

A packet capture program such as tcpdump, TShark, or dumpcap will probably put the interface into promiscuous mode, which means more packets will show up than would show up under normal circumstances.
The count in dumpcap goes to the standard error, not the standard output.
Dumpcap will write the packets to the file in question, which you may or may not want; if you have a lot of traffic, that file will keep getting bigger and bigger and take up more space on the file system /tmp is on.
You probably want to consider some tool that just gets statistics from the regular networking stack, such as ifconfig on Linux or netstat on various OSes:
$ netstat -w 1 -I en0
input (en0) output
packets errs bytes packets errs bytes colls
0 0 0 0 0 0 0
0 0 0 0 0 0 0
1 0 98 1 0 98 0
1 0 98 1 0 98 0
...

Based on the following output on my computer:
ifconfig eth0 | grep RX
RX packets:113995 errors:0 dropped:0 overruns:0 frame:0
RX bytes:62022831 (62.0 MB) TX bytes:11453699 (11.4 MB)
I can do the following to retrieve the number of RX packets:
ifconfig eth0 | grep "RX packets" | tr ":" " " | awk '{print $3}'
113995
Unfortunately it is not quite clear what exactly it is that you need. What do you mean by "count the number of packets in realtime"? Do you want a counter to be incremented and the value of the counter reported whenever a packet is seen? Or do you simply wish to count how many packets were seen within a given time period? Also what is the ultimate goal of your shell script?

Related

Are TCP/UDP IP packets with a source port below 1024 possible

I am analyzing some events against dns servers running unbound. In the course of this investigation I am running into traffic involving queries to the dns servers that are reported as having in some cases a source port between 1 and 1024. As far as my knowledge goes these are reserved for services so there should never be traffic originating / initiated from those to a server.
Since I also know this is a practice, not a law, that evolved over time, I know there is no technical limitation to put any number in the source port field of a packet. So my conclusion would be that these queries were generated by some tool in which the source port is filled with a random value (the frequency is about evenly divided over 0-65535, except for a peak around 32768) and that this is a deliberate attack.
Can someone confirm/deny the source port theory and vindicate my conclusion or declare me a total idiot and explain why?
Thanks in advance.
Edit 1: adding more precise info to settle some disputes below that arose due to my incomplete reporting.
It's definitely not a port scan. It was traffic arriving on port 53 UDP and unbound accepted it apparently as an (almost) valid dns query, while generating the following error messages for each packet:
notice: remote address is <ipaddress> port <sourceport>
notice: sendmsg failed: Invalid argument
$ cat raw_daemonlog.txt | egrep -c 'notice: remote address is'
256497
$ cat raw_daemonlog.txt | egrep 'notice: remote address is' | awk '{printf("%s\n",$NF)}' | sort -n | uniq -c > sourceportswithfrequency.txt
$ cat sourceportswithfrequency.txt | wc -l
56438
So 256497 messages, 56438 unique source ports used
$ cat sourceportswithfrequency.txt | head
5 4
3 5
5 6
So the lowest source port seen was 4 which was used 5 times
$ cat sourceportswithfrequency.txt | tail
8 65524
2 65525
14 65526
1 65527
2 65528
4 65529
3 65530
3 65531
3 65532
4 65534
So the highest source port seen was 65534 and it was used 4 times.
$ cat sourceportswithfrequency.txt | sort -n | tail -n 25
55 32786
58 35850
60 32781
61 32785
66 32788
68 32793
71 32784
73 32783
88 32780
90 32791
91 32778
116 2050
123 32779
125 37637
129 7077
138 32774
160 32777
160 57349
162 32776
169 32775
349 32772
361 32773
465 32769
798 32771
1833 32768
So the peak around 32768 is real.
My original question still stands: does this traffic pattern suggest an attack or is there an logical explanation for, for instance, the traffic with source ports < 1024?
As far as my knowledge goes these are reserved for services so there should never be traffic originating / initiated from those to a server.
It doesn't matter what the source port number is, as long as it's between 1 and 65,535. It's not like a source port of 53 means that there is a DNS server listening on the source machine.
The source port is just there to allow multiple connections / in-flight datagrams from one machine to another machine on the same destination port.
See also Wiki: Ephemeral port:
The Internet Assigned Numbers Authority (IANA) suggests the range 49152 to 65535 [...] for dynamic or private ports.[1]
That sounds like a port scan.
There are 65536 distinct and usable port numbers. (ibid.)
FYI: The TCP and UDP port 32768 is registered and used by IBM FileNet TMS.

ipvsadm -L -n suddenly showing no active connections

I have a very odd problem in a proxy cluster of four Squid proxies:
One of the machine is the master. The mater is running ldirectord which is checking the availability of all four machines, distributing new client connections.
All over a sudden, after years of operation I'm encountering this problem:
1) The machine serving the master role is not being assigned new connections, old connections are served until a new proxy is assigned to the clients.
2) The other machines are still processing requests, taking over the clients from the master (so far, so good)
3) "ipvsadm -L -n" shows ever-decreasing ActiveConn and InActConn values.
Once I migrate the master role to another machine, "ipvsadm -L -n" is showing lots of active and inactive connections, until after about an hour the same thing happens on the new master.
Datapoint: This happened again this afternoon, and now "ipvsadm -L -n" shows:
TCP 141.42.1.215:8080 wlc persistent 1800
-> 141.42.1.216:8080 Route 1 98 0
-> 141.42.1.217:8080 Route 1 135 0
-> 141.42.1.218:8080 Route 1 1 0
-> 141.42.1.219:8080 Route 1 2 0
No change in the numbers quite some time now.
Some more stats (ipvsadm -L --stats -n):
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 141.42.1.215:8080 1990351 87945600 0 13781M 0
-> 141.42.1.216:8080 561980 21850870 0 2828M 0
-> 141.42.1.217:8080 467499 23407969 0 3960M 0
-> 141.42.1.218:8080 439794 19364749 0 2659M 0
-> 141.42.1.219:8080 521378 23340673 0 4335M 0
Value for "Conns" is constant now for all realservers and the virtual server now. Traffic is still flowing (InPkts increasing).
I examined the output of "ipvsadm -L -n -c" and found:
25 FIN_WAIT
534 NONE
977 ESTABLISHED
Then I waited a minute and got:
21 FIN_WAIT
515 NONE
939 ESTABLISHED
It turns out that a local bird installation was injecting router for the IP of the virtual server and thus taking precedence over ARP.

Preventing TCP SYN retry in netcat (for port knocking)

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.

Strange behaviour of netcat with UDP

I noticed a strange behaviour working with netcat and UDP. I start an instance (instance 1) of netcat that listens on a UDP port:
nc -lu -p 10000
So i launch another instance of netcat (instance 2) and try to send datagrams to my process:
nc -u 127.0.0.1 10000
I see the datagrams. But if i close instance 2 and relaunch again netcat (instance 3):
nc -u 127.0.0.1 10000
i can't see datagrams on instance 1's terminal. Obsiously the operating system assigns a different UDP source port at the instance 3 respect to instance 2 and the problem is there: if i use the same instance'2 source port (example 50000):
nc -u -p 50000 127.0.0.1 10000
again the instance 1 of netcat receives the datagrams. UDP is a connection less protocol so, why? Is this a standard netcat behaviour?
When nc is listening to a UDP socket, it 'locks on' to the source port and source IP of the first packet it receives. Check out this trace:
socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recvfrom(3, "f\n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
Here you can see that it created a UDP socket, set it for address reuse, and bound it to port 10,000. As soon as it received its first datagram (from port 52,832), it issued a connect system call 'connecting' it to the 127.0.0.1:52,832. For UDP, a connect rejects all packets that don't match the IP and port in the connect.
Use the -k option:
nc -l -u -k 0.0.0.0 10000
-k means keep-alive, that netcat keeps listening after each connection
-u means UDP
-l listening on port 10000
Having given up on netcat on my OS version this is pretty short and gets the job done:
#!/usr/bin/ruby
# Receive UDP packets bound for a port and output them
require 'socket'
require 'yaml'
unless ARGV.count == 2
puts "Usage: #{$0} listen_ip port_number"
exit(1)
end
listen_ip = ARGV[0]
port = ARGV[1].to_i
u1 = UDPSocket.new
u1.bind(listen_ip, port)
while true
mesg, addr = u1.recvfrom(100000)
puts mesg
end
As the accepted answer explains, ncat appears not to support --keep-open with the UDP protocol. However, the error message which it prints hints at a workaround:
Ncat: UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec. QUITTING.
Simply adding --exec /bin/cat allows --keep-open to be used. Both input and output will be connected to /bin/cat, with the effect of turning it an "echo server" because whatever the client sends will be copied back to it.
To do something more useful with the input, we can use the shell's redirection operators (thus requiring --sh-exec instead of --exec). To see the data on the terminal, this works:
ncat -k -l -u -p 12345 --sh-exec "cat > /proc/$$/fd/1"
Caveat: the above example sends data to the stdout of ncat's parent shell, which could be confusing if combined with additional redirections. To simply append all output to a file is more straightforward:
ncat -k -l -u -p 12345 --sh-exec "cat >> ncat.out"

Exit status of ping command

My Perl script gets stuck with an exit status when trying to use the ping command.
According to this website:
If ping does not receive any reply packets at all it will exit with code 1. If a packet count and deadline are both specified, and fewer than count packets are received by the time the deadline has arrived, it will also exit with code 1. On other error it exits with code 2. Otherwise it exits with code 0. This makes it possible to use the exit code to see if a host is alive or not.
To list the results:
Success: code 0
No reply: code 1
Other errors: code 2
Note that the page I link to says "Linux/Unix ping command", but other systems, or perhaps even variants of Linux and Unix, might vary this value.
If possible, I would test on the system in question to make sure you have the right ones.
It's worth doing some testing on this on your OS. e.g on OSX
Resolvable host which is up
ping -c 1 google.com ; echo $?
Replies:
PING google.com (173.194.38.14): 56 data bytes
64 bytes from 173.194.38.14: icmp_seq=0 ttl=51 time=16.878 ms
--- google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 16.878/16.878/16.878/0.000 ms
Returns
0
Resolvable host which is down/does not respond to ping
ping -c 1 localhost ; echo $?
Replies:
PING stuart-woodward.local (127.0.0.1): 56 data bytes
--- stuart-woodward.local ping statistics ---
1 packets transmitted, 0 packets received, 100.0% packet loss
Returns:
2
Non Resolvable host
ping -c 1 sdhjfjsd ; echo $?
Replies:
ping: cannot resolve sdhjfjsd: Unknown host
Returns:
68
The ping utility returns an exit
status of zero if at least one
response was heard from the specified
host; a status of two if the
transmission was successful but no
responses were received; or another
value (from ) if an error
occurred.
http://www.manpagez.com/man/8/ping
The actual return values may depend on your system.
Successful connection will always return code 0, whilst failed connections will always return code 1 and above.
To test this out, try this snippet
#!/bin/bash
light_red='\e[1;91m%s\e[0m\n'
light_green='\e[1;92m%s\e[0m\n'
ping -c 4 -q google.comz
if [ "$?" -eq 0 ]; then
printf "$light_green" "[ CONNECTION AVAILABLE ]"
else
printf "$light_red" "[ HOST DISCONNECTED ]"
fi
You should also take into account that if the ping for example receives a 'network unreachable' icmp reply, it will be counted as reply an thus returns success status 0 (tested with cygwin ping on windows). So not really useful for testing if a host is alive and IMO a bug.
Try man ping from the command line. The return values are listed near the bottom.

Resources