Hello, all


Can anyone help with such problem : I need to find out quickly what computers on the network are currently online. Standart raw ping code does it slow, when encounters an ip with machine offline, recvfrom function waits for a reply too long and if there are a lot of such comps the scanning will last forever ...

Is there any other way to determine if the machine is online, using UDP protocol and how to do this ?
Posted on 2004-03-18 03:50:12 by Kick10
Ping is done via ICMP, so there's no "fast UDP way" to do this. You could do TCP SYN scanning, but it would suffer from the same problem you're currently having...

The trick would be to set up two threads - one doing the ICMP ping sweep (with a small Sleep() in it so you don't flood the network), and another one doing recvfrom taking note of the incoming ICMP echo replies. Do the final timeout X seconds after the last ping request was sent.
Posted on 2004-03-18 05:31:03 by f0dder
I'm not very good at network programming, im just new at it, could you please explain more detailed or give some link to example or doc on that technique ?

And how to set the final timeout ?
Posted on 2004-03-18 08:58:30 by Kick10
(wonderful pseudo-asm blocks coming up ^_^)
Your current program logic is probably something like this:


loop:
send ping
wait for ping reply
jmp loop if more hosts should be checked


Instead, you'd want to split this in two threads. The pinger thread is very easy:



loop:
update timeout-value
send ping
Sleep() for some "network friendly" period
jmp loop if more hosts should be checked


once this loop is done, the pinger-thread can simply exit. The "update timeout-value" step means getting the current system time, and storing it somewhere the reply-thread can read it.

The reply-thread requires a bit more logic. Something along the lines of...



loop:
invoke WSAEventSelect, socket, addr event, FD_READ or FD_CLOSE
invoke WaitForSingleObject, event, 1000

cmp eax, WAIT_TIMEOUT
je checktimeout

; do recvfrom, process data, possibly handling ping reply
jmp loop

checktimeout:
get current system time
check if last_ping_sent_time+timeoutvalue > current time
jmp loop if not
Posted on 2004-03-18 10:54:21 by f0dder
Thank you a lot. Now everything seems to work fine
Posted on 2004-03-21 02:40:21 by Kick10
Great, glad if I helped :) - perhaps you could post the full code here? Would be interesting to see how you implemented it, and it could probably be useful to other people.
Posted on 2004-03-21 07:59:13 by f0dder
Ok, I'll post the whole code, but I write this in C. While writing some new questions appeared :
When second thread checks for network events - some unuseful events come, which are not the ping replies and i cant determine the iterations count for recvfrom loop. Maybe I'm doing something wrong... I cant determine exatly when to stop listening for replies ...

Btw I found the way how to scan via UDP using netbios port 137- it helps to avoid calling gethostbyaddr/name to resolve the computers name, and you can get the OS version and current logged user from there.
Posted on 2004-04-03 08:43:02 by Kick10