I have written an network discovery code to discover the devices on the network.The code should discover the devices on the network even if the icmp echo response is disabled . I read about tcp ping from nmap where it sends TCP SYN packet and creates an half open connection to the remote device to check whether it is discoverable .In the code i made use of connect function from the windows socket library to check whether the host is discover able or not by establishing an socket connection on port 80 .
I disabled the ping on one of the test machines which runs windows 7 by following the link to check whether the machine is discover able or not but surprisingly the socket connection too failed with connection refused error . However nmap
could discover the device through the TCP ping option (which is through default port 80 ) .
So my questions:
-
Is what is the exact difference between both of them ?
-
What are other alternate ways to discover the devices on the network.
This is just a sample code to establish an socket connection .
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
int wmain()
{
// Initialize Winsock
WSADATA wsaData;
int i=0;
char ip[20];
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
SOCKET ConnectSocket;
sockaddr_in clientService;
do{
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
printf("\n Enter the Ip Address : ");
scanf("%s",ip);
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(ip);
clientService.sin_port = htons(80);
// Connect to server
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
if (iResult == SOCKET_ERROR) {
wprintf(L"connect function failed with machine number %d with error: %ld\n",i, WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with machine %d error: %ld\n",i, WSAGetLastError());
return 1;
}
wprintf(L"\n Connected to machine %d : ",i);
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket function failed with machine %d error: %ld\n",i, WSAGetLastError());
WSACleanup();
return 1;
}
i++;
}while(i<2);
WSACleanup();
return 0;
}
Best Answer
Between what sorry? ICMP ping and TCP ping? - Well one uses the ICMP echo and reply messages which I believe you already know, the other tries to play on the negotiation of a 3-way TCP handshake.
If you mean what is the difference between TCP Ping in your code and nmap, you'd have to read the nmap code for that. Or another idea would be to run something like http://www.wireshark.org/to see what you application sends down the wire, and what nmap is sending down the wire, and comparing the results.
Look through all the options in nmap and read some nmap tutorials, there are a few different discovery options there (research about how they work). One good method is trying to connect to TCP port 0 on machines. Different machines react in different ways, as this is an unusable socket (reserved). This is often used of OS identification (some OSs drop the packet, others send a
RST
back etc, so you can guess what OS might be assigned to that IP).No method is fool proof though for host discovery. You can configure firewalls to react in all sorts of ways (silently drop packets, respond with a
RST
packet, send back ICMP prohibited packets, and so on). So factoring this in, host discovery can be very difficult when firewalls are involved. If you are on the same LAN as a host you can play around witharpping
, RARPs etc, gratuitous ARPs, to try and get the MAC of the host, and possibly the IP. This can work even if they don't respond to pings etc. You can also play with sending IP packets to a broadcast address (255.255.255.255) and multicast addresses (this includes layer 2 traffic FF:FF:FF:FF:FF:FF etc).It's a long subject, that's not super easy, so best of luck!
UPDATE -
difference between TCP connection and TCP ping
The "TCP ping" here is just sending a TCP SYN packet to the destination host. It just runs the first part of the TCP 3 way handshake, you can see this on the Wikipedia page for TCP here. A TCP connection can be filtered by a firewall, i.e. It might see a SYN packet come through, a SYN-ACK returned, then before the final ACK is passed it filters it, to stop a TCP connection reaching the
CONNECTED
state. It is tracking the state of TCP connections. If you send a SYN packet on it's own, a firewall might not recognise this.TCP SYN scanning, and various other scanning techniques are found on Wikipedia page here. The Wiki page describes it more succinctly than I can, so I shall quote that directly: