I am writing a pinging utility to check the connectivity. We have an IP range from X.X.X.0 - X.X.X.24
Ping X.X.X.08 - gives unknown host
Ping X.X.X.008- gives unknown host
Ping X.X.X.8 - gets successful response
How many digits should be there in the last octet?
But when I ping X.X.X.007 or X.X.X.07 or X.X.X.7 works, i get successful response.
Could some shade some light what i am missing?
This depends almost entirely on the implementation of your ping but the most likely cause is that the 08 is being treated as an octal number because it begins with 0.
And, since the valid octal digits are limited to 0..7, it assumes it's not a numeric IP address but instead a name to be looked up (in DNS, for example).
This octal behavior can be confirmed (under Windows) with the following transcript:
C:\Users\Pax> ping 192.168.1.061
Pinging 192.168.1.49 with 32 bytes of data:
Reply from 192.168.1.61: Destination host unreachable.
:
The 061 appears to have been treated as octal from the first line of the output, since 618 (6x8+1) = 4910. The subsequent lines, though they claim to be pinging the .61 address, are lying. That's because that's my actual machine and, if I do it without the leading zero, it works fine:
C:\Users\Pax>ping 192.168.1.61
Pinging 192.168.1.61 with 32 bytes of data:
Reply from 192.168.1.61: bytes=32 time<1ms TTL=128
:
If the octal bit contains a non-octal digit, that's when it starts complaining about the host itself rather than it just not being reachable (or, worse, pinging the wrong machine):
C:\Users\Pax>ping 192.168.1.61
Pinging 192.168.1.61 with 32 bytes of data:
Reply from 192.168.1.61: bytes=32 time<1ms TTL=128
:
C:\Users\Pax>ping 192.0168.1.61
Ping request could not find host 192.0168.1.61.
Please check the name and try again.
Normally, it doesn't matter if you have X.X.X.001 or .01 or .1 for the last octet.
See my ping results on 192.168.0.1 and .01 and .001 => they all result to .1
Related
I am using ::http::geturl -query to issue an HTTP POST request with a small json payload to an ESP8266 (a 3rd party commercial device) from a rPi. It works when sent over eth0 but fails when sent over wlan0. tcpdump shows that sent over eth0, the message is sent as a single packet but when sent over wlan0 the payload is being split from the headers and sent in a second packet. The ESP8266 most likely due to having overly simple implementation of its packet receivers and/or http server doesn't appear to handle this splitting. It issues a 200 OK response after receiving the packet containing the headers and doesn't process the payload part of the request.
Experimentally I composed the same request message text being sent by ::http::geturl and sent it over wlan0 using nc; it was sent as a single packet and was successfully processed by the ESP8266.
Does anyone happen to know why sending the request using ::http over wlan0 is ending up with this split message, and what if anything can be done to prevent it?
Code fragment:
set s [::http::geturl http://$ip/con?com=cli -query $data -type application/json]
set r [::http::ncode $s]
::http::cleanup $s
Raspbian package versions:
tcl8.6 8.6.9+dfsg-2
tcllib 1.19-dfsg-2
tcl_platform(engine) = Tcl
tcl_platform(machine) = armv7l
tcl_platform(os) = Linux
tcl_platform(osVersion) = 5.4.79-v7+
$ ifconfig wlan0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.101 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::ed38:71ab:13af:ae30 prefixlen 64 scopeid 0x20<link>
ether b8:27:eb:26:bf:94 txqueuelen 1000 (Ethernet)
From /proc/cpuinfo:
Hardware : BCM2835
Revision : a020d3
Model : Raspberry Pi 3 Model B Plus Rev 1.3
$ uname -a
Linux raspberrypi 5.4.79-v7+ #1373 SMP Mon Nov 23 13:22:33 GMT 2020 armv7l GNU/Linux
Tcl's http package flushes the headers to the socket (i.e., performs an actual write()/send()) between writing the headers and the body of a query. For any correct implementation of an HTTP server this is fineā¦ but you're not working with that. For some reason, the wlan and eth drivers in the OS kernel have different policies for what to do with that case, with the eth driver deciding to wait a bit before sending; Tcl definitely doesn't configure this aspect of sockets at all, staying with the system defaults. (I don't know how to configure the OS defaults.)
You can always take a copy of the http code and comment out the flush. It's this one:
https://core.tcl-lang.org/tcl/artifact/d9f8dc4bd7211a37?ln=1463
line 1463: flush $sock
There's a Download button/link at the top of the page for that exact version of that file (it's changed only very slightly from the one in your version of Tcl and should be compatible provided you source the file explicitly before doing any package require calls).
I am trying to get TCP. From TCP RFC 793 server and client select a random sequence numbers and after they increase it each time when it receives a new byte (it is wrong but just for example). To dump TCP packages I used tcpdump -n -i eth0 tcp:
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
04:32:20.732914 IP 10.10.0.2.43168 > 10.50.0.2.9: S 372254521:372254521(0)
win 5840 <mss 1460,sackOK,timestamp 3644068 0,nop,wscale 1>
04:32:20.766194 IP 10.50.0.2.9 > 10.10.0.2.43168: S 363863555:363863555(0)
ack 372254522 win 5792 <mss 536,sackOK,timestamp 3644074 3644068,nop,wscale 1>
04:32:20.766416 IP 10.10.0.2.43168 > 10.50.0.2.9: .
ack 1 win 2920 <nop,nop,timestamp 3644073 3644074>
04:32:25.502532 IP 10.10.0.2.43168 > 10.50.0.2.9: P 1:7(6)
ack 1 win 2920 <nop,nop,timestamp 3644548 3644074>
04:32:25.503272 IP 10.50.0.2.9 > 10.10.0.2.43168: .
ack 7 win 2896 <nop,nop,timestamp 3644548 3644548>
04:32:29.510131 IP 10.10.0.2.43168 > 10.50.0.2.9: F 7:7(0)
ack 1 win 2920 <nop,nop,timestamp 3644949 3644548>
04:32:29.513123 IP 10.50.0.2.9 > 10.10.0.2.43168: F 1:1(0)
ack 8 win 2896 <nop,nop,timestamp 3644949 3644949>
04:32:29.513356 IP 10.10.0.2.43168 > 10.50.0.2.9: .
ack 2 win 2920 <nop,nop,timestamp 3644949 3644949>
The first two packages look normally but from the third and so on it uses ack 1 instead of 363863556 and I can't get why?
It hasn't. You are running tcpdump without telling it that you want to see absolute sequence numbers (-S).
The default behavior for tcpdump is to translate sequence numbers to relative sequence numbers, which allow you to see how many bytes of data have transferred in either direction. In this specific case, you are seeing it go to 1 because, according to RFC-793, the SYN consumes one byte in the stream, so the proper response is SEQ+1. You will see the same thing happen going the other direction. (You will also find that the FIN consumes one byte). Following this, the ACK will increase by the number of bytes sent.
If you want to see the absolute sequence numbers, try again running tcpdump -n -i eth0 -S tcp
My issue is as follows: I want to implement a listen service using scapy to stimulate a honeypot (because honeypot uses a fake ip, so I can't use OS sockets) and I chose scapy.
I implemented a very simple TCP hand-shake procedure, however one thing frustrated me: one byte of the packet I use PSH to send is eaten.
For example I send "abc" out to a client, but the client's socket, for example netcat or wget, only receive "bc". Another example is "HTTP/1.1 200 OK" becomes "TTP/1.1 200 OK". I captured packet and wireshark can correctly recognize my hand-made packet as HTTP, but the client socket just lack 1 byte. I don't know why.
The code is as follows:
192.168.1.100 stands for server(my) ip addr,9999 is the port. For example, I run this python script on 192.168.1.100, then I use "nc 192.168.1.100 9999". I expect to get "abc", but I can only get "bc", but the packet seems no problem in Wireshark. it's so strange.
'''
Created on Jun 2, 2012
#author: root
'''
from scapy import all
from scapy.layers.inet import IP, ICMP, TCP
from scapy.packet import ls, Raw
from scapy.sendrecv import sniff, send
from scipy.signal.signaltools import lfilter
import scapy.all
HOSTADDR = "192.168.1.100"
TCPPORT = 9999 'port to listen for'
SEQ_NUM = 100
ADD_TEST = "abc"
def tcp_monitor_callback(pkt):
global SEQ_NUM
global TCPPORT
if(pkt.payload.payload.flags == 2):
'A syn situation, 2 for SYN'
print("tcp incoming connection")
ACK=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="SA",ack=pkt.payload.payload.seq + 1,seq=0)
send(IP(src=pkt.payload.dst,dst=pkt.payload.src)/ACK)
if(pkt.payload.payload.flags & 8 !=0):
'accept push from client, 8 for PSH flag'
print("tcp push connection")
pushLen = len(pkt.payload.payload.load)
httpPart=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="PA", ack=pkt.payload.payload.seq + pushLen)/Raw(load=ADD_TEST)
'PROBLEM HERE!!!! If I send out abc, the client socket only receive bc, one byte disappers!!!But the packet received by client is CORRECT'
send(IP(src=pkt.payload.dst,dst=pkt.payload.src)/httpPart)
if(pkt.payload.payload.flags & 1 !=0):
'accept fin from cilent'
print ("tcp fin connection")
FIN=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="FA", ack=pkt.payload.payload.seq +1, seq = pkt.payload.payload.ack)
send(IP(src=pkt.payload.dst,dst=pkt.payload.src)/FIN)
def dispatcher_callback(pkt):
print "packet incoming"
global HOSTADDR
global TCPPORT
if(pkt.haslayer(TCP) and (pkt.payload.dst == HOSTADDR) and (pkt.payload.dport == TCPPORT)):
tcp_monitor_callback(pkt)
else:
return
if __name__ == '__main__':
print "HoneyPot listen Module Test"
scapy.all.conf.iface = "eth0"
sniff(filter=("(tcp dst port %s) and dst host %s") % (TCPPORT,HOSTADDR), prn=dispatcher_callback)
Some suggestions:
Sniff may append some payload to the end of the packet, so len(pkt.payload.payload.load) may not be the real payload length. You can use pkt[IP].len-40 (40 is the common header length of IP+TCP). You may also use -len(pkt[IP].options)-len(pkt[TCP].options) for more accurate results.
Usually the application layer above TCP uses line breaks ("\r\n") to separate commands, so you'd better change ADD_TEST to "abc\r\n"
If none of above methods work, you may upgrade to the latest netcat and try again.
I tested your code, you are missing sending proper tcp sequence
httpPart=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="PA", ack=pkt.payload.payload.seq + pushLen, seq=pkt.payload.payload.ack)/Raw(load=ADD_TEST)
should fix the issue, you may have other packet length issue, but the eaten 1 byte is caused by missing proper tcp sequence
I am facing a strange problem on my Ubuntu Karmic system.
When I call getaddrinfo() with AI_PASSIVE and AF_UNSPEC, for an empty host and the UDP 12000 port to get a bindable address, I only get back one IPv4 result (0.0.0.0:12000 for instance).
If I change my call and specify AF_INET6 instead of AF_UNSPEC, then getaddrinfo() returns "Name or service not known".
Shouldn't I get [::]:12000 as a result ?
The same thing happens if I set the host to ::1.
When I call getaddrinfo() without AI_PASSIVE (to get a "connectable" address) for the host "localhost" and the UDP 12000 port, I first get [::1]:12000 then 127.0.0.1:12000.
So apparently, my system is IPv6 ready (I can ping to both IPv4 and IPv6 addresses, as well as DNS resolution). But how is it that I can't get an IPv6 address to bind to with getaddrinfo() ?
Do you guys have any idea about what could be wrong ?
My OS is Ubuntu Karmic, fresh install without any networking tweaking.
Thank you.
P.S: If you have no idea but still want to help me, you can get this sample program or type:
wget http://people.apache.org/~jorton/gai.c
And give me the result of:
$ ./gai -ap null 12000
My result is:
$ ./gai -ap null 12000
getaddrinfo(NULL, "12000", {.family=AF_UNSPEC, .hints=0|AI_ADDRCONFIG|AI_PASSIVE}) = 0:
family= 2, proto= 6 inet4: addr=0.0.0.0, port=12000
There you can see that I only have one IPv4 result.
This happens on new systems that use eglibc: debian-glibc.
Apparently, there is a bug that requires you to set at least one valid IPv6 address to one of your network interfaces (the loopback doesn't count).
After I did this:
$ sudo ip -6 addr add 2001:660:4701:1001::1 dev eth0
I have:
$ ./gai -ap null 12000
getaddrinfo(NULL, "12000", {.family=AF_UNSPEC, .hints=0|AI_ADDRCONFIG|AI_PASSIVE}) = 0:
family= 2, proto= 6 inet4: addr=0.0.0.0, port=12000
family=10, proto= 6 inet6: addr=::, port=12000, flowinfo=0
I hope this can help someone.
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.