Now before we start the tutorial, I'm going to give you a little bit of background on what drove me to develop this, and why I designed it the way I did. The college at which I work has had many problems with viruses (I prefer virii, but for the benefit of most people reading this tutorial, I'll go with the spelling you most commonly use) running rampant on residence networks. These viruses for the most part have been Nachi, Welchia and MyDoom, all viruses which open remote ports. Unfortunately, residence students bring in their own computers, and we really have no control. Our only ability is to shut down the switch port they are connected to, which meant if we caught them remotely we could terminate their connection and they would have to call us to get it turned back on and we could then clean their machine of the infection and patch it (where possible). This project had been underway for some time before I started here. Several times a day, someone would walk over to a machine and plug it into one of the 13 residence VLANs, and scan manually. They would then record all the PCs with open ports and move over to another VLAN. To me this was a waste of time, so together with Network Services, they setup a trunk port and I devised an autmoated scanning system, we came up with an effective way to scan. The result was this scanner (as the back-end anways). After I finish this document, I'll begin writing the front-end for the software. Because I wanted this fully automated, I wanted to see the results of the scans from anywhere, my solution to this problem was to write a flag that would output a full html page. We maintain a textfile of common virus ports, so we wanted to use this for the scans. My solution was to make reading from a file the default and require a flag to scan with ports from the command line. Another problem was the amount of time it took to scan, while scanning one host at a time. For this problem I investigated threading, and ended up with a program that scans every IP address simultaneously. Now, I wanted simplicity because those maintaining this will not be programmers, and if they are they won't be coding in python. Python has two threading modules, the outdated thread.py and the newer threading.py. So for simplicity, and because I'm new to threading, I used the older module. It allows me create threads, however the program won't wait for the threads, it'll finish and just terminate them (more on this later), so I added a flag to allow the program to sleep long enough to wait for the threads to finish. The last main question is, "Why python?". So many consider it to be an outdated scripting language, instead of a powerful programming language. They are very wrong. Python is as powerful and versitile as C and C++. It is portable because it is an interpreted language. This was a primary requirement as we have primarily Windows boxes, but we have a few linux machines, one of which will hopefully be on another trunk port soon. I have written several tutorials on Python, so I won't explain the pure basics of the language, if it's covered in another of my tutorials I'm going to hope you'll read them. I will explain everything, just not the intimate details of things I have outlined in other posts. And now, on with the tutorial. I am going to ignore comments and work with just the code. For your reference ''' (three single quotes) marks the beginning and the end of a comment in Python. If you have any questions about the comments (I am going to include the source at the end of this tutorial) please fee free to post them here, or send me a PM. I am also not going to be following the code in the order it is displayed, but rather in the order which it is executed. code: import socket, sys, getopt, string, time, array try: import thread except ImportError: import dummy_thread as thread This is the first chunk of code that you encounter, it is also the first chunk of code that is executed. The import command is similar to the include command from c/c++. There are two ways of using the import command. You can import the library as I have (import socket) or you could import commands from the library (from socket import *). The asterisk in the second command would import all of the commands when the program first runs, this can cause problems if too modules have the same command. It is usually preferable to import the library, or to import specific commands (from thread import start_new_thread) (more details on the commands later). This would only import the start_new_thread command, allowing you to access it directly start_new_thread(function to start). However as I said the preferred method is to import the library (import thread), then when calling commands you reference the library that the command comes from (thread.start_new_thread(function to start)). I have imported several libraries, they are: socket - Provides socket functionality to the program sys - Provides a series of system related command (in this case sys.exit() will be used) getopt - Provides for retrieval of arguments from the command line, and provides a series of functions to handle those arguments. string - provides string handling/manipulation functions time - provides time and date related functions (in this case the sleep command) array - provides a series of commands and functions for handling/manipulating arrays. The last section of this code is a try and except line. Since this is the first time that white space is used, I will mention how incredible important it is to use whitespace in python. Brackets don't exist in this language like they do in others to separate statements, the only way to separate them is with whitespace. A single tab is used to include code. If you have an If statement followed by three lines of code (all tabbed in), when the statement evaluates true, the three tabbed lines will be executed. Now on to the try and except. The code will try to import the thread library, however as it is being phased out (replaced with the newer threading library), newer installs don't include it, however they all include dummy_thread which provides the same functionality. If the program can't import thread.py it will receive an import error. The except line tells to run the command import dummy_thread and consider it to be the library thread (as thread) if it can't import the real thread library. Try and except is a great method of handling errors as they arise, there is a whole series of standard exceptions that are generated by python. A list of these exceptions can be found documentation at http://www.python.org/doc/current/a...Exceptions.html. The next chunk of code that is executed is: code: if __name__ == "__main__" : try : main(sys.argv[1:]) except KeyboardInterrupt : print "Scanning terminated by user." print "Thank you for using PyScan." except : usage() sys.exit() if __name__ == "__main__": is very similar to the int main() { line in c. Everything found after that (in C between the {} and in python after the : and preceded by white space) is executed first. Again I have used a try and except statement. I try to call the main function (the body of my code), and I pass it all the arguments that follow the program name. argv is a representation of the command line arguments. argv[0] would be the name of the program I am running, which is why I don't pass it on. The : after the 1 indicate that I want to pass all the remaining arguments 1, 2, 3.... 100... however many exist. As you can see the argv command is located in the sys library. I've allowed for two exceptions. The first is KeyboardInterrupt (this would be ctrl+c on most systems, ctrl+break whatever your interrupt is set to). Because the code will be "trying" to execute the main function for the rest of it's running, if I enter a KeyboardInterrupt at any time during the execution of this program, that message will be displayed and yes, to print a line to the screen in python it is simply print followed by the text in double quotes. For more on the basics of the print command you can view my first python tutorial, Python Introduction. For information on formatting options which are similar to the c/c++ standard that are available with the print command you can view my third python tutorial, Python Introduction #3. I have not used any formatting options in this program (again, I was going for simplicity), but they are very interesting to look into and use. The last exception is raised on any other exception (no specific exception is listed). It will simply call the usage() function and then cleanly exit the program. Since the usage() function is called quite frequently, we will look at it before we delve into the main() function. code: def usage() : banner() print "Usage: python pyscan.py \n" print "Options:" print "-h -- Displays this help screen" print "-w -- HTML output" print "-u -- UDP Scan (Semi-Functional; default is TCP Scan)" print "-t -- Specify a timeout (default 1)" print "-s