⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windows internet programming part 3.html

📁 黑客培训教程
💻 HTML
📖 第 1 页 / 共 5 页
字号:


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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -