Ethernet Message Format:
For detailed instructions, see "MAC Head Message Analysis".
IP Message Format:
For detailed instructions, see the IP datagram format.
UDP Message Format:
For detailed instructions, see the format of theUDP datagram.
Checksum function:
/******************************************************* function: Checksum function parameter: buf: Need to verify the first address of the data Nword: need to verify the data length of half the return value: CHECKSUM * * * * /unsigned Short Checksum (unsigned short *buf, int nword) {unsigned Long sum;for (sum = 0; nword > 0; nword--) {sum + = htons (*buf); buf++;} sum = (sum>>16) + (SUM&0XFFFF); sum + = (sum>>16); return ~sum;}
Here is a UDP packet from the original socket set under Ubuntu, which sends a message to the PC's network debugging assistant:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <net/if.h>//struct ifreq# Include <sys/ioctl.h>//ioctl, Siocgifaddr#include <sys/socket.h> #include <netinet/ether.h>//eth_ P_all#include <netpacket/packet.h>//struct sockaddr_llunsigned Short checksum (unsigned short *buf, int nword);// checksum function int main (int argc, char *argv[]) {//1. Create communication with the original socket int sock_raw_fd = socket (Pf_packet, Sock_raw, htons (Eth_p_all));// 2. Build the sending datagram unsigned char send_msg[1024] = {//--------------group mac--------------0x74, 0x27, 0xEA, 0xb5, 0xEF, based on various protocol header formats. 0xd8,//dst_mac:74-27-ea-b5-ff-d80xc8, 0x9c, 0xdc, 0xb7, 0x0f, 0x19,//src_mac:c8:9c:dc:b7:0f:190x08, 0x00, Type: 0X0800 IP protocol//--------------group IP---------------0x45, 0x00, 0x00, 0x00,//Version number: 4, header Length: 20 bytes, to s:0,---Total length--:0x00, 0x00, 0x00, 0x00,//16 bit ID, 3-bit flag, 13-bit offset are set 00x80, +, 0x00, 0x00,//ttl:128, Protocol: UDP (17), 16-bit header checksum 10, 221, 11,//src_ip:10.221.20.1110, 221, 20, 10,//dst_ip:10.221.20.10//--------------Group UDP--------8+78=86------0x1f, 0x90, 0x1f, 0x90,//src_port:0x1f90 (8080), Dst_port:0x1f90 (8080) 0x00, 0x00, 0x00, 0x00,//#--16 bit UDP length--30 bytes, #16位校验和};int len = sprintf (send_msg+42, "% S "," This was for the UDP test "); if (len% 2 = = 1)//Determine if Len is an odd number {len++;//If it is odd, Len should add 1 (because the data portion of UDP is filled with 0 if it is not an even number)}* (unsigned s Hort *) &send_msg[16]) = Htons (20+8+len),//ip total length = 8 + len* ((unsigned short *) &send_msg[14+20+4]) = Htons (8+le N)//udp Total length = 8 + len//3.udp pseudo head unsigned char pseudo_head[1024] = {//------------UDP pseudo-header--------12--10, 221, 11,//SR c_ip:10.221.20.1110, 221, 10,//dst_ip:10.221.20.100x00, X, 0x00, 0x00,//0,17,#--16 bit UDP length--20 bytes} ; * ((unsigned short *) &pseudo_head[10]) = htons (8 + len);//The UDP length in the header (and the true UDP length is the same value)//4. Building UDP checksum Required datagram = UDP pseudo header + UDP datagram memcpy (pseudo_head+12, send_msg+34, 8+len)//--the need to add a pseudo-header--//5 when calculating UDP checksum. Verify the IP header * ((unsigned short *) &send_ MSG[24]) = htons (checksum (unsigned shORT *) (SEND_MSG+14), 20/2);//6.--verifies the UDP data--* ((unsigned short *) &send_msg[40]) = htons (Checksum (unsigned *) Pseudo_head, (12+8+len)/2);//6. Send data struct SOCKADDR_LL sll;//original socket address structure struct IFREQ ethreq;//network interface address strncpy ( Ethreq.ifr_name, "eth0", ifnamsiz);//Specify the NIC name if ( -1 = = IOCTL (SOCK_RAW_FD, Siocgifindex,ðreq))//Get the network interface {perror ("ioctl"); Close (SOCK_RAW_FD); exit (-1);} /* Assign the network interface to the original socket address structure */bzero (&SLL, sizeof (SLL)); sll.sll_ifindex = Ethreq.ifr_ifindex;len = SendTo (SOCK_RAW_FD, Send_msg, 14+20+8+len, 0, (struct sockaddr *) &sll, sizeof (SLL)); if (len = =-1) {perror ("SendTo");} return 0;} unsigned short checksum (unsigned short *buf, int nword) {unsigned long sum;for (sum = 0; nword > 0; nword--) {sum + = Htons (*buf); buf++;} sum = (sum>>16) + (SUM&0XFFFF); sum + = (sum>>16); return ~sum;}
The results of the operation are as follows:
Source code download please click here.
Linux Network Programming--Raw socket instance: sending UDP Packets