Click here to Skip to main content
15,867,488 members
Articles / Desktop Programming / MFC
Article

How to write a simple but effective TCP/IP port scanner for Win32

Rate me:
Please Sign up or sign in to vote.
4.82/5 (15 votes)
27 Oct 20017 min read 162.6K   7.3K   101   9
An article on how to write a TCP/IP port scanner with a GUI, based on the MFC's property sheet paradigm

The TCP/IP port scanner

Introduction

Writing a TCP/IP port scanner, it's not so hard. This article shows you how to develop a simple but effective port scanner for Win32, using a self written socket classes (not the CSocket which comes with MFC) and a small framework based on the CPropertySheet/CPropertyPage classes.

The scanner also includes a module for testing connections (the Connect page) and allows the handling of the local database of services (the Services page).

What you should to know

The sample application presented here does not requires a deep knowledge of the TCP/IP protocol. If you have some notions about the MFC and the Winsock API, then you are on the right direction.

How a scanner works

Each time you send or receive data through the Internet, your mail (or web, chat, or whatever) program must connect to a remote port of a remote host. Some of the services which runs over the Internet are resumed into the following table:

serviceportdescription
echo7Echo
daytime13Daytime
ftp21File Transfer Protocol
ssh22SSH Remote Login Protocol
telnet23Telnet
smtp25Simple Mail Transfer
time37Time
nameserver42Host Name Server
nicname43Who Is
domain53Domain Name Server
gopher70Gopher
http80World Wide Web HTTP
kerberos88Kerberos
pop3110Post Office Protocol
netbios-ns137NETBIOS Name Service
netbios-dgm138NETBIOS Datagram Service
netbios-ssn139NETBIOS Session Service

In fact, the list of services/ports is greater than the above and includes three different port ranges:

port rangeutilization
0 - 1023well known ports, which include the most common services, like SMTP, POP3, FTP, etc.
1024 - 49151registered ports, which are assigned by the IANA organization
49152 - 65535dynamic and/or private ports, which can be freely used

As the RFCs say (RFC793 for the TCP and RFC768 for the UDP protocol), the above ports can be used for TCP and UDP connections, so it's not unusual to see duplicated entries for the same service, like in:

serviceport/protocoldescription
echo7/tcpEcho
echo7/udpEcho

The TCP/IP protocol is based on the OSI (Open Systems Interconnection) model, developed between 1977 and 1984. That model uses a proposal of the ISO (International Organization for Standardization), so it is well known as the ISO/OSI model also. The ISO/OSI architecture divides the network into various layers (application, presentation, session, transport, network, data-link and physical).

Think to a layer like a plant of a building. At the lower level is your network card, used to exchange raw data between the computers, while at the higher level is your preferred client sending mail or browsing the web. In fact, the TCP/IP is not a protocol, but a suite of protocols, composed by:

protocoldescription
IP (Internet Protocol)the protocol used to exchange raw data between remote hosts
TCP (Transport Control Protocol)the protocol used to exchange data between applications
UDP (User Data Protocol)used as the TCP to exchange data between applications, but more simpler and less reliable than the TCP
ICMP (Internet Control Message Protocol)used at the network layer for error messaging

The correspondence between the ISO/OSI model and the suite of the TCP/IP protocols can be represented by the following table:

ISO/OSI modelTCP/IP suite
application layerclient program
presentation layerclient program
session layerclient program
transport layerTCP/UDP
network layerICMP/IP/IGMP
data-link layerARP/hardware/RARP
physical layerARP/hardware/RARP

The IP and TCP protocols are the ground of data transfer. The IP protocol, which works at network layer, handles the transfer of raw data between computers. At this level, each packet contains the data which must be transferred and the IP address of the sender and the receiver. The TCP protocol works at the transport layer, but the principle is the same. TCP replaces the IP address concept with the port concept. Each transferred packet contains the data and the port number, where the port number is associated with a service instead of a computer.

In other words, the IP protocol moves the raw data from one computer to other, using the IP address to identify each computer of the network. Well, but when the data arrives to the destination computer, where must it be left? Are you browsing the WEB? If so, the TCP protocol redirects the incoming data through the port used by the HTTP service (80). Are you using an FTP client? The TCP protocol redirects the incoming data through the port used by the service (21), and so on.

As you can see, the port and service concepts are the basic principles used during data transfer through the Internet. Now you can understand which is the main purpose of a TCP/IP scanner. If you want to know what are the services currently running on a remote host, you must scan its ports.

Implementation

The sample code presented here is only an example of Winsock programming. Do not think it like the best approach to the scan topical. As you know, the Winsock API can be used with three different modes, blocking, non-blocking and asyncronous modes. Our scanner uses the third (asyncronous) mode.

Probably this is not the best mode which can be used with this topical (maybe using the blocking mode into a separate thread guarantees a better result), but this is not the point. Commercial scanners use a lot of threads to scan as fast as possible the mayor number of ports at the same time. This is not our purpose. Our scanner must scan one port at time, without blocking the UI until the work is done, and to do it in that way, the best approach is the asyncronous mode, used here to practice and exercise with the Winsock API. Of course, you are free to modify the proposed code to apply the Winsock mode you prefer.

All the code contained into the sample project can be divided into two sections, the simple framework used to build a CPropertySheet based MFC application and the classes used for the Winsock interface.

The CPropertySheetDialog.cpp/.h and CPropertyPageDialog.cpp/.h files contain all the classes required to use the property sheet paradigm as a base for our MFC application.

TcpPropertySheet.cpp/.h files contain the code for the main app, while all the Tcp[...]Page.cpp/.h files contain the code for the pages of the sheet.

All the code used to interface the Winsock API is contained into the CWinsock.cpp/.h and CSock.cpp/.h files. CAsyncSock.cpp/.h file contains the classes used to access the Winsock API in asyncronous mode, while the rest of the code is used internally to handle the list control (CListCtrlEx.cpp/.h), the program's configuration, etc.

Note that the base class for the Winsock interface is the CWinsock class, not the CSock. As you can see looking into the code, the CWinsock class is used to map all the Winsock services to the real library or to a dummy implementation, depending on the _DEBUGSOCKET macro definition. This is because the CWinsock class contains the code to handle locally a minimal SMTP/POP3 server, which you can use to exercise the SMTP/POP3 protocols without using an active Internet connection.

As usual for an MFC app, you must derive you own class (in this case, the CTcpScanApp class) from the CWinApp. Our scanner is not dialog, but property sheet-based, so you must override the default InitInstance() implementation for creating the property sheet and all the related pages:

BOOL CTcpScanApp::InitInstance(void)
{
    CScanPage ScanPage;
    CConnectPage ConnectPage;
    CServicesPage ServicesPage;
    CPropertyPageList* pPropertyPageList = new CPropertyPageList();

    if(pPropertyPageList)
    {
        PROPERTYPAGE* p;

        p = new PROPERTYPAGE(IDD_PAGE_SCAN,&ScanPage,RUNTIME_CLASS(CScanPage));
        pPropertyPageList->Add(p);

        p = new PROPERTYPAGE(IDD_PAGE_CONNECT,
              &ConnectPage,RUNTIME_CLASS(CConnectPage));
        pPropertyPageList->Add(p);
        
        p = new PROPERTYPAGE(IDD_PAGE_SERVICES,
              &ServicesPage,RUNTIME_CLASS(CServicesPage));
        pPropertyPageList->Add(p);

        CTcpScanPropertySheet* pPropertySheetDialog
              = new CTcpScanPropertySheet(NULL,pPropertyPageList);
        if(pPropertySheetDialog)
        {
            if(pPropertySheetDialog->Create())
            {
                m_pMainWnd = pPropertySheetDialog;
                pPropertySheetDialog->DoModal();
            }

            delete pPropertySheetDialog;
        }

        delete pPropertyPageList;
    }

    return(FALSE);
}

The property sheet dialog is based on the CPropertySheetDialog/CPropertyPageDialog classes, which handles all the required stuff. The Apply and the Help buttons are removed by the framework, so each page of the property sheet has only the OK and the Cancel buttons. Each page of the sheet modifies the text of the OK button, according to its needs.

As you can see, each class used as a page of the sheet defines the following handlers:

BOOL    OnInitDialog(void);
BOOL    OnSetActive(void);
BOOL    OnKillActive(void);
void    OnKillSheet(void);
void    OnOk(void);
void    OnCancel(void);

If you decide to use the CPropertySheetDialog/CPropertyPageDialog classes into your own code, do not miss to do the same.

About the features of our scanner, consider that the Connect page allows you to test only the connections which use the same channel for commands and data. This means you can use that page to send and receive data with protocols like SMTP, POP3, HTTP, etc., but not with protocols like FTP, which uses two different channels (one for the commands and other for the data).

When using the Connect page, remember that you are entering raw data, so if you want to get some HTML page through the HTTP protocol, you must specify the HTTP request as the standard say (in this case, specifying the pair of CR/LF chars at the end of the request).

Any kind of ideas, suggestions or enhancements are always welcome.

Luca Piergentili

lpiergentili@yahoo.com

http://www.geocities.com/lpiergentili/

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Italy Italy
I like C and C++, Acid Jazz, James Brown, gli Spaghetti Aglio e Olio, alla Bolognesa, alla Puttanesca e le Fettuccine alla Matriciana ('Maccaroni' over the world). Of course I like beautiful big tits girls too, my little car, Frank Zappa, the art of Zen, italian coffee and much more...

Comments and Discussions

 
Generalvery good Pin
Southmountain8-Feb-20 12:43
Southmountain8-Feb-20 12:43 
QuestionNot able to sniff TCP packet on windows Vista. But could do so on XP Pin
Aseem Sharma21-Dec-09 22:41
Aseem Sharma21-Dec-09 22:41 
GeneralNice Work Pin
CourageousSam6-Apr-07 6:29
CourageousSam6-Apr-07 6:29 
Generalabout the sample TCPScan program Pin
Luca Piergentili6-Jan-07 23:28
Luca Piergentili6-Jan-07 23:28 
Generalvery good program Pin
Georgi Petrov7-Nov-06 22:22
Georgi Petrov7-Nov-06 22:22 
QuestionEvent when Connection is Stablish in Port 2346 ?? Pin
Vitoto17-Jun-05 5:07
Vitoto17-Jun-05 5:07 
Questionhow can i add ur connect code in my project Pin
ladwal7-Aug-03 19:30
ladwal7-Aug-03 19:30 
QuestionHow do you close an open port? Pin
2-Nov-01 13:22
suss2-Nov-01 13:22 
AnswerRe: How do you close an open port? Pin
Nish Nishant19-Feb-02 7:56
sitebuilderNish Nishant19-Feb-02 7:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.