Analysis of TCP/IP protocol stack code-UDP (stm32 platform)

Source: Internet
Author: User
Tags rfc
ARP part IP & ICMP UDP part TCP Section

1. UDP IntroductionUDP is a simple datagram-oriented transport layer protocol. Each output operation of a process generates a UDP datagram and assembles it into an IP datagram to be sent. This is different from the stream-oriented character protocol, such as TCP. The full data generated by the application may be unrelated to the Single IP datagram actually sent. The format of an IP datagram is 11-1. RFC 768 [Postel 1980] is the formal specification of UDP. UDP does not provide reliability: it sends data from applications to the IP layer, but it does not guarantee that the data can reach the destination. Due to lack of reliability, we seem to think that we should avoid using UDP to use a reliable protocol such as TCP. After discussing TCP, I will return to this topic to see what applications can use UDP.2. UDP HeaderThe fields in the UDP header are 11-2. The port number indicates the sending and receiving processes. In Figure 1-8, we plot the process of using the destination port number for TCP and UDP to use data from the IP layer. Because the IP layer has allocated IP datagram to TCP or UDP (based on the protocol field value in the I p header), the TCP port number is viewed by TCP, while the UDP port number is viewed by UDP. The TCP port number and the UDP port number are independent of each other. Although they are independent of each other, if TCP and UDP provide a well-known service at the same time, the two Protocols usually select the same port number. This is purely for ease of use, rather than the requirements of the Protocol itself. The UDP length field refers to the byte length of the UDP header and UDP data. The minimum value of this field is 8 bytes (sending a 0-byte UDP datagram is OK ). The UDP length is redundant. The IP datagram length refers to the total length of the datagram (Figure 3-1). Therefore, the length of the UDP datagram is the total length minus the length of the IP header (this value is specified in the header length field, as shown in 3-1) UDP checks and overwrites UDP header and UDP data. Review the IP header check. It only overwrites the IP header-not any data in the IP datagram. Both UDP and TCP have the test that overwrites their header and data. UDP checks are optional, while TCP checks are required. Although the basic calculation method of UDP test is similar to the IP Address Header test and calculation method described in the preceding section (16-bit binary anticode and, but slightly different, some processing is added when the field type is determined to be UDP or TCP, and you can see the code), but there are differences between them. First, the UDP datagram length can be an odd number of bytes, but the test algorithm adds several 16-bit characters. The solution is to add the padding byte 0 at the end when necessary, only for testing and calculation (that is, the increased padding byte may not be transmitted)
. Second, both UDP datagram and TCP segment contain a 1-2-byte pseudo header (this TCP/IP protocol stack is different, only the 4-byte source IP address and 4-byte destination IP address are added, that is, the tail of the IP header is used to reuse the space and read the code.) It is set for computing check and. The pseudo header contains some IP header fields. The purpose is to let UDP check whether the data has arrived at the destination correctly twice (for example, if the IP address is not accepted and the address is not the datagram of the host, and the IP does not send the datagram that should be sent to another high-level layer to UDP ). Pseudo-Header Format 11 in UDP datagram
-3. In this figure, we provide an example of an odd-length datagram. Therefore, we need to add the padding byte (0) in the calculation test ). Note that the UDP datagram length appears twice during the test and calculation. If the result of the test is 0, the saved value is all 1 (65535), which is equivalent to binary anticode calculation. If the transfer check is 0, it indicates that the sending end has no calculation check. (Because of the Protocol requirements, the code needs to be implemented .) If the sending end does not have a computing check and the receiving end detects the check and errors, the UDP datagram will be quietly discarded. No error messages are generated (this is also done when the IP layer detects IP header checks and errors ). UDP test is an end-to-end test. It is calculated by the sender and then verified by the receiver. The aim is to find any changes made between the UDP header and the data sending end and the receiving end. /* The following describes the history and necessity of UDP checksum */although UDP checksum is optional, it should always be used. In 1980s, some computer vendors disabled the UDP test function by default to speed up the use of Network File System (NFS) over UDP. This may be acceptable in a single LAN. However, when a data packet passes through a router, the majority of errors can be detected through the Cyclic Redundancy test (such as Ethernet or ring-based data frames) on the link layer data frame, the transmission fails. Believe it or not, there are also software and hardware errors in the router, so that you can modify the data in the datagram. If end-to-end UDP verification is disabled, these errors cannot be detected in UDP datagram. In addition, some data link layer protocols (such as slip) do not have any form of Data Link inspection. Host Requirements RFC declares that UDP checks and options are enabled by default. It also states that if the sender has calculated the test, the receiver must check the received test (for example, the received test is not 0 ). However, many systems do not comply with this by verifying the received inspection only when the exit inspection and option is turned on. Several additional terms need to be explained:IP DatagramIt refers to the end-to-end transmission unit of the IP layer (before and after the fragmentation ),GroupIt refers to the Data Unit transmitted between the IP layer and the link layer. A group can be a complete IP datagram or a part of an IP datagram. (Here is a description of how to fragment. The details in the book are described. In short, if the MTU is exceeded, the first part is different from the next one. The first part is the UDP header, others do not exist, but they can be combined through the IP flags. The following figure shows the image .) ---------------------------------------- The above content is summarized in the "TCP/IP protocol details: Volume 1". The following content is generated in code and analysis --------------------------------------3. UDP macro definition implementationC ++ code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ******** UDP *******
# Define udp_header_len 8
// Source Port location
# Define udp_src_port_h_p 0x22
# Define udp_src_port_l_p 0x23
// Target port location
# Define udp_dst_port_h_p 0x24
# Define udp_dst_port_l_p 0x25
// UDP data length location
# Define udp_len_h_p 0x26
# Define udp_len_l_p 0x27
// UDP checksum location
# Define udp_checksum_h_p 0x28
# Define udp_checksum_l_p 0x29
// UDP data start address
# Define udp_data_p 0x2a
4. UDP function implementationIn this TCP/IP protocol stack, UDP implements only one make_udp_reply_from_request function-udp server, which can respond to other UDP requests. In the order of connection, the servers on the stm32 board are waiting for the request from the PC client. When the request arrives, the response set by the programmer is returned, as shown in this article, we will make three response examples (of course, once UDP is established, some clients and servers have the same status, but the initiators are considered as clien to be more cognitive ). The following is the input: Buf is the buffer, data is the data to be transmitted, datalen is sizeof (data), and port is the UDP port number on the PC.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Void make_udp_reply_from_request (unsigned char * Buf, char * data, unsigned int datalen, unsigned int port)
{
Unsigned int I = 0, tol_len;
Unsigned int CK;
// Same as ARP and ICMP
Make_eth (BUF );
// Total length field in the IP header must be set:
// For example, IP Header
Tol_len = ip_header_len + udp_header_len + datalen;
Buf [ip_totlen_h_p] = tol_len> 8;
Buf [ip_totlen_l_p] = tol_len;
// For example, ICMP
Make_ip (BUF );
// The port number of the local UDP
Buf [udp_dst_port_h_p] = port> 8;
Buf [udp_dst_port_l_p] = Port & 0xff;
// Source port does not matter and is what the sender used.
// Calculte the UDP length: the maximum length of 16 bits, that is, 65535-14-20-8, but it is usually set to a small value. Why? As mentioned above.
Buf [udp_len_h_p] = datalen> 8;
Buf [udp_len_l_p] = udp_header_len + datalen;
// Zero the checksum
Buf [udp_checksum_h_p] = 0;
Buf [udp_checksum_l_p] = 0;

// Copy the data:
While (I <datalen)
{
Buf [udp_data_p + I] = data [I];
I ++;
}

// Insert udp_debug here
// The 16 bytes here is the pseudo header of UDP, that is, the source IP address-0x1a + Destination Address-0x1e (which is different from the standard one ),
// + UDP header = 4 + 4 + 8 = 16
Ck = checksum (& Buf [ip_src_p], 16 + datalen, 1 );
Buf [udp_checksum_h_p] = CK> 8;
Buf [udp_checksum_l_p] = ck & 0xff;
Enc28j60packetsend (udp_header_len + ip_header_len + eth_header_len + datalen, Buf );
}

5. UDP ExperimentAfter the preceding UDP implementation, you also need to request UDP, as shown in the following code: the following code is placed in a while (1) or RTOS process, wait for client response as a server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* ------------------- UDP Server start, we listen on UDP port 1200 = 0x4b0 -----------------------------*/
If (BUF [ip_proto_p] = ip_proto_udp_v & Buf [udp_dst_port_h_p] = 4 & Buf [udp_dst_port_l_p] = 0xb0)
{
// UDP Data Length
Udpdatalen = Buf [udp_len_h_p];
Udpdatalen = udpdatalen <8;
Udpdatalen = (udpdatalen + Buf [udp_len_l_p])-udp_header_len;
// Udpdatalen = Buf [udp_len_l_p]-udp_header_len;
// Obtain the UDP port pcudpport = Buf [udp_src_port_h_p] on the PC end <8 | Buf [udp_src_port_l_p];

// Write the data Buf obtained by the UDP client to buf1, because the following experiment requires the input information to perform the corresponding action.
For (I1 = 0; I1 <udpdatalen; I1 ++)
Buf1 [I1] = Buf [udp_data_p + I1];

Make_udp_reply_from_request (BUF, buf1, udpdatalen,Pcudpport);
}
/* ---------------------------------------- UDP end -----------------------------------------------*/

PS: In this experiment, UDP port is 1200, and PC port is 4001. In this experiment, three simple experiments are implemented:
  1. Output the IP address and port number of the UDP client through the serial port
  2. Output UDP input data through the serial port and UDP, namely, usart echo and udp echo
  3. Implement the UDP command to control the LEDs on the stm32 Board
C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
Void make_udp_reply_from_request (unsigned char * Buf, char * data, unsigned int datalen, unsigned int port)
{
Unsigned int I = 0, tol_len;
Unsigned int CK;
// Same as ARP and ICMP
Make_eth (BUF );
// Total length field in the IP header must be set:
// For example, IP Header
Tol_len = ip_header_len + udp_header_len + datalen;
Buf [ip_totlen_h_p] = tol_len> 8;
Buf [ip_totlen_l_p] = tol_len;
// For example, ICMP
Make_ip (BUF );
// The port number of the local UDP
Buf [udp_dst_port_h_p] = port> 8;
Buf [udp_dst_port_l_p] = Port & 0xff;
// Source port does not matter and is what the sender used.
// Calculte the UDP length: the maximum length of 16 bits, that is, 65535-14-20-8, but it is usually set to a small value. Why? As mentioned above.
Buf [udp_len_h_p] = datalen> 8;
Buf [udp_len_l_p] = udp_header_len + datalen;
// Zero the checksum
Buf [udp_checksum_h_p] = 0;
Buf [udp_checksum_l_p] = 0;

// Copy the data:
While (I <datalen)
{
Buf [udp_data_p + I] = data [I];
I ++;
}

# Ifdef udp_debug
I = 0;
Printf ("UDP server test. \ r \ n ");
Printf ("UDP client IP address and port number: \ r \ n ");

While (I <sizeof (20174_addr ))
{
// Note that UDP server is set up to output the IP address of the UDP client.
Printf ("% d", Buf [ip_dst_p + I]);

If (I! = Sizeof (ipv4_addr)-1)
{
Printf (".");
}

I ++;
}

I = 0; // output the UDP port printf (": % d \ r \ n", Port) on the PC end; // print the data sent by the UDP client through the serial port
Printf ("UDP client sent data: \ r \ n ");
Printf ("% s \ r \ n", data );

// Implement the UDP server to respond to the UDP client's control led command
// For example, led1 = on and led1 = off
If (strcmp (data, "led1 = on") = 0)
{
Gpio_resetbits (gpioa, gpio_pin_8 );
}

If (strcmp (data, "led1 = OFF") = 0)
{
Gpio_setbits (gpioa, gpio_pin_8 );
}

// For example, led2 = on and led2 = off
If (strcmp (data, "led2 = on") = 0)
{
Gpio_resetbits (gpiod, gpio_pin_2 );
}

If (strcmp (data, "led2 = OFF") = 0)
{
Gpio_setbits (gpiod, gpio_pin_2 );
}

# Endif
// The 16 bytes here is the pseudo header of UDP, that is, the source IP address-0x1a + Destination Address-0x1e (which is different from the standard one ),
// + UDP header = 4 + 4 + 8 = 16
Ck = checksum (& Buf [ip_src_p], 16 + datalen, 1 );
Buf [udp_checksum_h_p] = CK> 8;
Buf [udp_checksum_l_p] = ck & 0xff;
Enc28j60packetsend (udp_header_len + ip_header_len + eth_header_len + datalen, Buf );
}

TCP & UDP test tool symptom: Echo achieves serial port symptom: As expected. Note: Disable UDP reconnection to view randomly assigned UDP ports. WiresharkPhenomenon: successful packet capture ~~~ Development Board phenomenon: led2 is on, initially breaking through the atomic and digital worlds, but the experience is poor, O (∩) O ~

Http://www.os-forum.com/minix/net/index.html

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.