His methodology relies on Firefox's quirk, whereby the page loading would wait for the <link> tag to be processed before rendering the rest of the page. This means you could use the link tag to reference local IPs and use a subsequent image to see how long did it take for the IP to respond. If the response was very quick, then you know the host has something listening on a given port and if it does not, well then the port is being blocked or filtered.
The problem with his approach is that to scan an entire network would be rather slow and require multiple iframes to perform the scan. Not to mention very noticeable, I decided to see if something can be done about this limitation.
The problem with scanning is that there is no way to set a timeout so, if you encounter a local IP that takes forever to reply your scan is effectively stalled. Jeremiah tried to resolve this by putting a meta-refresh tag, but it seems Firefox chooses to ignore this tag while waiting for the <link> tag to load.
Fortunately, Firefox, Safari and Opera support a very interesting Content-Type called "multipart/x-mixed-replace".
(It does not work in IE6, but I'd be very curious to know if IE7 supports this or not)
The above PHP code creates just such a payload, where each "page" prints a little progress indicator followed by a <link> tag pointing to a local IP address. We then have an image pointing to a monitoring script who's job it'll be to record the scanned IP and the time at which the scan was initiated. After this we call the flush() function forcing PHP to dump the current data to screen and wait for 3 seconds. The 3 seconds is our timeout, which in my tests on my network seems to have resulted in the best results, but a different value may work better for you.
This means that we give our scanner roughly 3 seconds to scan an IP after which, regardless of whether we got a response or not we are going to move on to the next address. The process is repeated until we run of IPs or the user leaves the page.
Now on to the scan.php script, which is quite simple, it is just two lines long.
The first thing we do is call the session_start() function that creates a new session for the user or resumes an existing one. The session id, will become the unique identifier for the user allowing us to separate scans for separate users. The next line is call to a php 5.2 function file_put_contents() that writes the result of the scan to a file. Each result line consists of the scanned Ip, time of scan and the timestamp of when the request arrived at the server. In 5.2 you can use the $_SERVER['REQUEST_TIME'] variable for this, in earlier versions of PHP you will need to call the time() function. The function then appends the line to the file, locking it the process to avoid corrupting in the even of multiple writers to the same file.
Another trick would be to store the last scanned IP inside the session, so that when a user comes back to the site you can resume scanning at the last know position rather then starting at the very beginning, allowing you within a few visits to scan the entire network of the user.