Construct UDP raw datagram in Linux-DNS message example C Language

Source: Internet
Author: User
Tags htons

Several days ago, I constructed a DNS packet and checked some information. It seems that many of my friends have always had problems with the UDP packet checksum. I tried some sample code and there were also problems. So it took some time to make a successful example. In Linux, GCC passes and verifies the success.

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <unistd. h>
# Include <sys/socket. h>
# Include <ARPA/inet. h>
# Include <netinet/in. h>
# Include <netinet/IP. h>
# Include <netinet/udp. h>

Unsigned short checksum (unsigned short * buffer, int size)
{
Unsigned long cksum = 0;

While (size> 1)
{
Cksum + = * buffer ++;
Size-= sizeof (unsigned short );
}
If (size)
{
Cksum + = * (unsigned char *) buffer;
}
Cksum = (cksum> 16) + (cksum & 0 xFFFF );
Cksum + = (cksum> 16 );

Return (unsigned short )(~ Cksum );
}

Void calculatechecksum (
Void * iphdr,
Struct udphdr * udphdr,
Char * payload,
Int payloadlen)
{
Struct iphdr * v4hdr = NULL;
Unsigned long zero = 0;
Char Buf [1000],
* PTR = NULL;
Int chksumlen = 0,
I;

PTR = Buf;

V4hdr = (struct iphdr *) iphdr;

// Include the source and destination IP addresses
Memcpy (PTR, & v4hdr-> saddr, sizeof (v4hdr-> saddr ));
PTR + = sizeof (v4hdr-> saddr );
Chksumlen + = sizeof (v4hdr-> saddr );

Memcpy (PTR, & v4hdr-> daddr, sizeof (v4hdr-> daddr ));
PTR + = sizeof (v4hdr-> daddr );
Chksumlen + = sizeof (v4hdr-> daddr );

// Include the 8 bit zero field
Memcpy (PTR, & zero, 1 );
PTR ++;
Chksumlen + = 1;

// Protocol
Memcpy (PTR, & v4hdr-> protocol, sizeof (v4hdr-> protocol ));
PTR + = sizeof (v4hdr-> Protocol );
Chksumlen + = sizeof (v4hdr-> Protocol );

// UDP Length
Memcpy (PTR, & udphdr-> Len, sizeof (udphdr-> Len ));
PTR + = sizeof (udphdr-> Len );
Chksumlen + = sizeof (udphdr-> Len );

// UDP source port
Memcpy (PTR, & udphdr-> source, sizeof (udphdr-> source ));
PTR + = sizeof (udphdr-> source );
Chksumlen + = sizeof (udphdr-> source );

// UDP destination port
Memcpy (PTR, & udphdr-> DEST, sizeof (udphdr-> DEST ));
PTR + = sizeof (udphdr-> DEST );
Chksumlen + = sizeof (udphdr-> DEST );

// UDP length again
Memcpy (PTR, & udphdr-> Len, sizeof (udphdr-> Len ));
PTR + = sizeof (udphdr-> Len );
Chksumlen + = sizeof (udphdr-> Len );

// 16-bit UDP checksum, zero
Memcpy (PTR, & zero, sizeof (unsigned short ));
PTR + = sizeof (unsigned short );
Chksumlen + = sizeof (unsigned short );

// Payload
Memcpy (PTR, payload, payloadlen );
PTR + = payloadlen;
Chksumlen + = payloadlen;

// Pad to next 16-bit Boundary
For (I = 0; I <payloadlen % 2; I ++, PTR ++)
{
Printf ("pad one byte/N ");
* PTR = 0;
PTR ++;
Chksumlen ++;
}

// Compute the checksum and put it in the UDP Header
Udphdr-> check = checksum (unsigned short *) BUF, chksumlen );

Return;
}

Void main ()
{

Int sock;
Unsigned int buffer_size = sizeof (struct iphdr) + sizeof (struct udphdr );

Char dns_data [] = "/x71/x79/x81/X80/x00/x01"
"/X00/x02/x00/x04/x00/x04/x03/x77/x77/x77/x03/x61/x62/x63/x03/x63"
"/X6f/x6d/x00/x00/x01/x00/x01/xc0/x0c/x00/x05/x00/x01/x00/x00/x02"
"/Xe8/x00/x02/xc0/x10/xc0/x10/x00/x01/x00/x00/x00/x02/xe9/x00"
"/X04/x0a/xb5/x84/xfa/xc0/x10/x00/x02/x00/x01/x00/x00/xda/xeb/x00"
"/X0d/x06/x73/X65/x6e/x73/x30/x31/x03/x64/x69/x67/xc0/x14/xc0/x10"
"/X00/x02/x00/x01/x00/x00/xda/xeb/x00/x09/x06/x73/X65/x6e/x73/x30"
"/X32/xc0/x4e/xc0/x10/x00/x02/x00/x01/x00/x00/xda/xeb/x00/x09/x06"
"/X6f/x72/x6e/x73/x30/x31/xc0/x4e/xc0/x10/x00/x02/x00/x01/x00/x00"
"/Xda/xeb/x00/x09/x06/x6f/x72/x6e/x73/x30/x32/xc0/x4e/xc0/x75/x00"
"/X01/x00/x01/x00/x00/x7a/x36/x00/x04/x0a/xbb/xbd/x2c/xc0/x8a/x00"
"/X01/x00/x01/x00/x00/x1b/x96/x00/x04/x0a/xbb/xbe/x2c/xc0/x47/x00"
"/X01/x00/x01/x00/x00/x92/xb1/x00/x04/x0a/xb5/x86/x10/xc0/X60/x00"
"/X01/x00/x01/x00/x00/x92/xb1/x00/x04/x0a/xb5/x87/xc7 ";
 
Buffer_size + = sizeof (dns_data );

Unsigned char buffer [buffer_size];
Memset (buffer, 0, buffer_size );

Struct iphdr * IP = (struct iphdr *) buffer;
Struct udphdr * UDP = (struct udphdr *) (buffer + sizeof (struct iphdr ));

If (sock = socket (af_inet, sock_raw, ipproto_udp) =-1 ){

Perror ("socket ()");
Exit (exit_failure );
}

Int o = 1;
If (setsockopt (sock, ipproto_ip, ip_hdrincl, & O, sizeof (O) =-1 ){

Perror ("setsockopt ()");
Exit (exit_failure );
}

IP-> Version = 4;
IP-> IHL = 5;
IP-> id = htonl (random ());
IP-> saddr = inet_addr ("1.0.0.1 ");
IP-> daddr = inet_addr ("10.0.0.63 ");
IP-> TTL = 255;
IP-> protocol = ipproto_udp;
IP-> tot_len = buffer_size;
IP-> check = 0;

UDP-> source = htons (53 );
UDP-> DEST = htons (1234 );
UDP-> Len = htons (buffer_size-sizeof (struct iphdr ));
UDP-> check = 0;

Struct sockaddr_in ADDR;
ADDR. sin_family = af_inet;
ADDR. sin_port = UDP-> source;
ADDR. sin_addr.s_addr = IP-> saddr;

Memcpy (buffer + sizeof (struct iphdr) + sizeof (struct udphdr), dns_data, sizeof (dns_data ));
Calculatechecksum (IP, UDP, dns_data, sizeof (dns_data ));

If (sendto (sock, buffer, buffer_size, 0, (struct sockaddr *) & ADDR,
Sizeof (struct sockaddr_in) =-1 ){

Perror ("Send ()");
Exit (1 );
}
Else
Printf ("OK/N ");
}

 

The above code constructs a DNS response packet. Use the packet capture program to verify the correctness.

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.