TCP and UDP full packet verification and general computing

Source: Internet
Author: User
Tags htons
ICMP, IP, UDP, and TCP headers all have checksum (TEST) fields. The Calculation of ICMP and IP header checksum is very simple. You can use the method given in rfc1071 (as follows ).? // Calculate the checksum
Ushort checksum (ushort * buffer, int size)
{
Unsigned long cksum = 0;
While (size> 1)
{
Cksum + = * buffer ++;
Size-= sizeof (ushort );
}
If (size)
{
Cksum + = * (uchar *) buffer;
}
// Convert 32 digits to 16 digits
While (cksum> 16)
Cksum = (cksum> 16) + (cksum & 0 xFFFF );
Return (ushort )(~ Cksum );
}
???

The calculation of the checksum in the UDP/TCP header is complicated. You need to use the UDP/tcp pseudo-header: first fill in the fields of the pseudo-header, and then add the UDP/TCP Header (including the header) the data is appended to the end of the pseudo header, and then the checksum is used to calculate the header. The obtained value is the checksum of the UDP/TCP Header .? Bit headers can be represented by the following struct: Typedef struct {
Ulong? Sourceip ;??? // Source IP address
Ulong? Destip ;????? // Destination IP address
Byte mbz ;?????????? // Leave null (0)
Byte ptcl ;????????? // Protocol type
Ushort Plen ;??????? // Length of TCP/UDP packets (that is, the length unit from the calculation of the TCP/UDP header to the end of the packet: bytes)
} Psd_header;
?? This process is a very tedious process. After several computations, I can no longer endure such repetitive work. So I wrote a general computing function. I feel very convenient to use this function: encapsulate your data packet (complete, including the Ethernet header), and then use the first address of the data packet as a parameter to call this function. The function will help you calculate the IP header and UDP/TCP Header checksum .? //-------------------------------------------------------------------------
// Packetchecksum
// Calculate the packet checksum
// Parameter: Packet-data to be processed (pointer of the encapsulated data packet)
//-------------------------------------------------------------------------
Void packetchecksum (unsigned char packet [])
{
Dlc_header * pdlc_header = NULL; // Ethernet header pointer
Ip_header? * Pip_header = NULL ;? // IP header pointer
Unsigned short attachsize = 0; // The total length of the transport layer protocol header and additional data
? Pdlc_header = (dlc_header *) packet; ? // Determine the ethertype. If it is not an IP package, it will not be processed.
If (ntohs (pdlc_header-> ethertype )! = 0x0800) return;
? Pip_header = (ip_header? *) (Packet + 14 );
// TCP packet
If (0x06 = pip_header-> PROTO)
{

Tcp_header * ptcp_header = NULL; // TCP Header pointer
Tcp_psd_header * ptcp_psd_header = NULL;

Ptcp_header = (tcp_header *) (packet + 14 + (pip_header-> ver_len) & 15) * 4 );?? Attachsize = ntohs (pip_header-> total_len)-(pip_header-> ver_len) & 15) * 4;
Ptcp_psd_header = (tcp_psd_header *) malloc (attachsize + sizeof (tcp_psd_header ));
If (! Ptcp_psd_header) return;
Memset (ptcp_psd_header, 0, attachsize + sizeof (tcp_psd_header ));
?? // Fill in the pseudo TCP Header
Ptcp_psd_header-> destip = pip_header-> destip;
Ptcp_psd_header-> sourceip = pip_header-> sourceip;
Ptcp_psd_header-> mbz = 0;
Ptcp_psd_header-> ptcl = 0x06;
Ptcp_psd_header-> tcpl = htons (attachsize );
?? // Calculate the TCP checksum
Ptcp_header-> chksum = 0;
Memcpy (unsigned char *) ptcp_psd_header + sizeof (tcp_psd_header ),
(Unsigned char *) ptcp_header, attachsize );
Ptcp_header-> chksum = checksum (unsigned short *) ptcp_psd_header,
Attachsize + sizeof (tcp_psd_header ));

// Calculate the IP header checksum
Pip_header-> checksum = 0;
Pip_header-> checksum = checksum (unsigned short *) pip_header, 20 );
Return;
}

// UDP Packet
If (0x11 = pip_header-> PROTO)
{
Udp_header * pudp_header = NULL; // UDP header pointer
Udp_psd_header * pudp_psd_header = NULL;
?? Pudp_header = (udp_header *) (packet + 14 + (pip_header-> ver_len) & 15) * 4 );?? Attachsize = ntohs (pip_header-> total_len)-(pip_header-> ver_len) & 15) * 4;
Pudp_psd_header = (udp_psd_header *) malloc (attachsize + sizeof (udp_psd_header ));
If (! Pudp_psd_header) return;
Memset (pudp_psd_header, 0, attachsize + sizeof (udp_psd_header ));
?? // Fill in the pseudo UDP Header
Pudp_psd_header-> destip = pip_header-> destip;
Pudp_psd_header-> sourceip = pip_header-> sourceip;
Pudp_psd_header-> mbz = 0;
Pudp_psd_header-> ptcl = 0x11;
Pudp_psd_header-> udpl = htons (attachsize );

// Calculate the UDP checksum
Pudp_header-> chksum = 0;
Memcpy (unsigned char *) pudp_psd_header + sizeof (udp_psd_header ),
(Unsigned char *) pudp_header, attachsize );
Pudp_header-> chksum = checksum (unsigned short *) pudp_psd_header,
Attachsize + sizeof (udp_psd_header ));

// Calculate the IP header checksum
Pip_header-> checksum = 0;
Pip_header-> checksum = checksum (unsigned short *) pip_header, 20 );??
Return;
}
Return;
}
?Several header files and libraries are required:?# Include <winsock2.h>
# Include <windows. h>
# Include "packet. H"
# Pragma comment (Lib, "ws2_32.lib ")
??? The structure of the data packet I used is attached (more ):?? // Data packet structure
# Pragma pack (1 )?
/* Physical Frame header structure */
Typedef struct {
Byte? Desmac [6]; ??? // Target MAC address
Byte? Srcmac [6]; ??? // Source MAC address
Ushort? Ethertype ;??? // Frame Type
} Dlc_header;/* ARP Frame Structure */
Typedef struct {
Ushort hw_type ;?????? // Hardware type Ethernet: 0x1
Ushort prot_type ;???? // Ip address of the Upper-layer protocol type: 0x0800
Byte hw_addr_len ;???? // Hardware address length: 6
Byte prot_addr_len ;?? // Protocol address (IP address) Length: 4
Ushort flag ;????????? // 1 indicates the request and 2 indicates the response
Byte send_hw_addr [6]; // source MAC address
Uint send_prot_addr ;? // Source IP address
Byte targ_hw_addr [6]; // target MAC address
Uint targ_prot_addr ;? // Destination IP address
Byte padding [18]; ??? // Fill in the data ??
} Arp_frame;/* ARP packet = DLC header + ARP frame */
Typedef struct {
Dlc_header dlcheader; // DLC Header
Arp_frame arpframe ;? // ARP Frame
} Arp_packet;/* IP header structure */
Typedef struct {
Byte? Ver_len ;?????? // Length of the IP packet header, in the unit of 4 bytes
Byte? ToS ;?????????? // Service type TOS
Ushort total_len ;??? // What is the total length of the IP package?
Ushort ident ;??????? // ID
Ushort frag_and_flags ;? // Flag Space
Byte TTL ;?????????? // Survival time
Byte proto ;???????? // Protocol
Ushort checksum ;??? // IP header checksum
Uint? Sourceip ;? // Source IP address (32-bit)
Uint? Destip ;??? // Destination IP address (32-bit)
} Ip_header;/* TCP Header structure */
Typedef struct {
Ushort srcport ;?? // Source Port
Ushort dstport ;?? // Target port
Uint seqnum ;????? // Sequence number
Uint acknum ;????? // Confirmation number
Byte dataoff ;???? // TCP Header Length
Byte flags ;?????? // Flag (URG, ack, etc)
Ushort window ;??? // Window size
Ushort chksum ;??? // Checksum
Ushort urgptr ;??? // Emergency pointer
} Tcp_header; // The TCP pseudo header is used for TCP checksum calculation to ensure the validity of TCP verification.
Typedef struct {
Ulong? Sourceip ;??? // Source IP address
Ulong? Destip ;????? // Destination IP address
Byte mbz ;?????????? // Leave null (0)
Byte ptcl ;????????? // Protocol type (ipproto_tcp)
Ushort tcpl ;??????? // The total length of the TCP packet (unit: bytes)
} Tcp_psd_header;/* UDP header */
Typedef struct? {?
Ushort srcport ;???? // Source Port
Ushort dstport ;???? // Target port
Ushort total_len ;?? // The length of the UDP header and UDP data (in bytes)
Ushort chksum ;????? // Checksum
} Udp_header;/* UDP pseudo header-used only for calculating the checksum */
Typedef struct tsd_hdr?
{?
Ulong? Sourceip ;??? // Source IP address
Ulong? Destip ;????? // Destination IP address
Byte? Mbz ;?????????? // Leave null (0)
Byte? Ptcl ;????????? // Protocol type (ipproto_udp)
Ushort udpl ;???????? // What is the total length of a UDP packet (in bytes )?
} Udp_psd_header;/* ICMP header */
Typedef struct {
Byte I _type ;???? // The type is critical: 0-> send/reply (Ping response) 8-> send/send (Ping request)
Byte I _code ;???? // Code. This is related to the type. If the type is 0 or 8, it is 0.
Ushort I _cksum ;? // ICMP packet checksum
Ushort I _id ;???? // Identification number (process ID is generally used as the identification number)
Ushort I _seq ;??? // Message serial number (usually set to 0)
// Uint timestamp ;? // Timestamp
Byte padding [32]; // fill in data
} Icmp_header;
/* ICMP packet */
Typedef struct
{
Dlc_header ;? // Ethernet frame
Ip_header? Ip_header ;?? // IP Header
Icmp_header; // ICMP Frame
} Icmp_packet;/* attack information */
Typedef struct
{
Unsigned char flag ;???? // Attack packet type 1-arp, 2-tcp, 3-udp
Unsigned int srcip ;???? // Attacker IP Address
Unsigned char code [33]; // attack pattern
} Attack_infor;
# Pragma pack ()?

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.