什么是实现TCP所需的最小一组TCP/IP协议?

huangapple go评论60阅读模式
英文:

What is the smallest set of TCP/IP protocols required to implement TCP

问题

我正在编写自己的网络堆栈。我将只接收TCP数据。实现TCP的最基本的TCP/IP协议是什么?

我认为应该包括:

  • 以太网
  • TCP
  • IP
  • UDP
  • DNS(gethostbyname)
  • ARP(不知道MAC地址)
  • DHCP(被分配一个IP地址)

然而,这个维基百科页面:

https://en.wikipedia.org/wiki/Internet_protocol_suite#:~:text=A%20minimal%20implementation%20of%20TCP,Group%20Management%20Protocol%20(IGMP).

说:

TCP/IP的最小实现包括以下内容:Internet Protocol (IP), Address Resolution Protocol (ARP), Internet Control Message Protocol (ICMP), Transmission Control Protocol (TCP), User Datagram Protocol (UDP), and Internet Group Management Protocol (IGMP). In addition to IP, ICMP, TCP, UDP, Internet Protocol version 6 requires Neighbor Discovery Protocol (NDP), ICMPv6, and Multicast Listener Discovery (MLD) and is often accompanied by an integrated IPSec security layer.

接收TCP数据的最小实用协议集是什么?

英文:

I'm writing my own network stack. I will only be receiving TCP data. What is the bare minimum TCP/IP protocols to implement TCP?

I thought it would be:

  • Ethernet
  • TCP
  • IP
  • UDP
  • DNS (gethostbyname)
  • ARP (not knowing MAC addresses)
  • DHCP (be assigned an IP address)

However, this wikipedia page:

https://en.wikipedia.org/wiki/Internet_protocol_suite#:~:text=A%20minimal%20implementation%20of%20TCP,Group%20Management%20Protocol%20(IGMP).

says:

> A minimal implementation of TCP/IP includes the following: Internet Protocol (IP), Address Resolution Protocol (ARP), Internet Control Message Protocol (ICMP), Transmission Control Protocol (TCP), User Datagram Protocol (UDP), and Internet Group Management Protocol (IGMP). In addition to IP, ICMP, TCP, UDP, Internet Protocol version 6 requires Neighbor Discovery Protocol (NDP), ICMPv6, and Multicast Listener Discovery (MLD) and is often accompanied by an integrated IPSec security layer.

What is the smallest practical set of protocols to receive TCP data?

答案1

得分: 4

TCP需要IPv4或IPv6,尽管有一个RFC可以在IPX上运行,但我认为实际上没有人真正实现过。

IP(两个版本)不需要任何特定的数据链路协议,比如以太网。它可以在任何数据链路协议上运行(以太网、Wi-Fi、令牌环、FDDI、PPP、ATM、HDLC、帧中继等)。

UDP是一种并行传输协议,您不使用它,或任何其他传输协议(SCTP、DCCP等)用于TCP。

ARP仅用于IPv4(IPv6使用NDP),在一些但不是所有的数据链路协议上使用。

DHCP不是必需的。它被用作配置主机的一种方法,但还有其他方法。

此外,ICMP是IP(两个版本)的组成部分。 "ICMP使用IP的基本支持,就好像它是一个更高级的协议一样,然而,ICMP实际上是IP的一个组成部分,必须由每个IP模块实现。"

英文:

TCP requires IPv4 or IPv6, although there is an RFC to run on IPX, but I do not think anyone ever really implemented it.

IP (both versions) does not require any particular data-link protocols, such as ethernet. It can run on any data-link protocol (ethernet, Wi-Fi, token ring, FDDI, PPP, ATM, HDLC, frame relay, etc.).

UDP is a parallel transport protocol, and you do not use it, or any other transport protocol (SCTP, DCCP, etc.) for TCP.

ARP is only used for IPv4 (IPv6 uses NDP) on some, but not all, data-link protocols.

DHCP is not a requirement. It is used as one method of configuring a host, but there are other methods.

Also, ICMP is an integral part of IP (both versions). "ICMP, uses the basic support of IP as if it were a higher level protocol, however, ICMP is actually an integral part of IP, and must be implemented by every IP module."

答案2

得分: 3

不要考虑“要实现哪些协议?”我建议考虑你将收到哪些数据包以及如何处理它们。你可以采取很多捷径。

我假设是以太网和IPv4,而不是IPv6。


你的设备必须首先理解ARP请求(Ethernet+ARP)并发送ARP回复,以便其他设备可以根据其IP地址找到你的设备的MAC地址。当另一个设备想要发送IP数据包到你的设备时,它首先会通过ARP查找MAC地址。MAC地址会被该设备保存一段时间,以便不必每次都发送。

ARP并不需要做太多工作。你的设备只需检查一堆标头字段,确保它是寻址到你的设备,然后交换一些字段以返回给发送者,将自己的MAC地址插入回复中并将其发送回去。


你可以稍微偏离一下,使你的设备能够理解ping请求(Ethernet+IP+ICMP)并发送ping回复。这基本上与ARP的过程相同。IP有一个校验和,你需要根据数据包内容计算出来。(一旦你在发送的数据包中使其工作,你可能还会检查你的设备接收到的数据包的校验和)。然后,你可以ping你的设备并在屏幕上得到一些具体的结果。

当你发送回复时,你需要一个MAC地址来发送回复,一个合适的堆栈将通过使用ARP获得该地址,但为什么要费劲呢——只需使用发送请求给你的相同地址!


对于TCP,你的设备还需要理解TCP数据包(Ethernet+IP+TCP)。因为你只想接收数据,所以要做的工作就没那么多了。你希望跟踪打开的连接,因为每个连接都是独立工作的。

  • 当你收到一个SYN数据包时,这是一个新的连接,所以记住它并记住那是什么序列号(+1,因为SYN算作一个序列号),然后发送一个SYN+ACK。
  • 当你收到任何其他数据包时,如果其序列号与你记住的序列号相同,那么这个数据包在正确的顺序中,所以处理数据并更新记住的序列号。
  • 无论如何(即使序列号错误),都要发送一个ACK回去,ACK号是你记住的序列号(你想在下一个数据包中看到的那个号码)。
  • 如果你收到一个FIN,发送FIN+ACK(即使你不知道这个连接)并忘记这个连接。
  • 如果你收到一个数据包,你不认识这个连接,而且它没有SYN,发送RST。

再次强调,无论何时发送回复,都只需使用你从中获取数据包的相同MAC地址。因为你的设备只接收,它从不需要发送ARP请求来查找MAC地址。

我想强调一下,这是一个非常愚蠢的TCP算法,采取了很多捷径,但它确实有效——我实际上在一个设备上实现过这个,并与之连接过。与我实现的相比,我可能在这里犯了一些小错误。


DHCP是一种让你的设备向路由器请求IP地址的方式。你不需要它。只需硬编码一个IP地址。


DNS是一种将名称转换为IP地址的方式。你不需要它。但如果你确实需要它,它将在你和DNS服务器之间查找设备的地址——设备不参与其中。如果你的设备想要使用DNS名称查找IP地址,它需要知道DNS。

英文:

Instead of thinking about "which protocols to implement?" I suggest thinking about which packets you will receive and what to do with them. You can take a lot of shortcuts.

I assume Ethernet, and IPv4, not IPv6.


The very first thing your device must do is understand ARP requests (Ethernet+ARP) and send ARP replies, so other devices can find your device's MAC address based on its IP address. When another device wants to send an IP packet to yours the first thing it will do is find the MAC address by using ARP. The MAC address is saved by that device for a while, so it doesn't send one every time.

There's not very much work to ARP. Your device just checks a bunch of header fields to ensure that it's addressed to your device, then swaps some around to return to sender, inserts its own MAC address into the reply and sends it back out.


You can take a little detour and make your device understand ping requests (Ethernet+IP+ICMP) and send ping replies. It's basically the same process as ARP. IP has a checksum, which you need to calculate based on the packet contents. (Once you have that working in packets you send, you may as well also check the checksum of packets your device receives). Then you can ping your device and get some tangible results on the screen.

When you send a reply you need a MAC address to send it to, which a proper stack would get by using ARP, but why bother with that - just use the same address that sent the request to you!


For TCP your device needs to also understand TCP packets (Ethernet+IP+TCP). Because you only want to receive data you don't have as much work to do. You want to keep track of connections that are open, since each connection works independently.

  • When you get a SYN packet, that's a new connection so remember it and remember what sequence number that was (+1 because the SYN counts as a sequence number) and send a SYN+ACK.
  • When you get any other packet, if its sequence number is the sequence number you remembered, then this packet is in the right sequence, so process the data and update the remembered sequence number.
  • No matter what (even if the sequence number is wrong), send an ACK back, with the ACK number being the remembered sequence number (the one you want to see in the next packet).
  • If you get a FIN, send FIN+ACK (even if you don't know the connection) and forget the connection.
  • If you get a packet and you don't recognize the connection and it doesn't have SYN, send RST.

Again, whenever you send a reply, just use the same MAC address that you got the packet from. Because your device only receives, it never needs to send an ARP request to find a MAC address.

I want to emphasize this is a really dumb algorithm for TCP taking lots of shortcuts, but it does work - I have actually implemented this on a device and connected to it. I may have made some small mistakes here compared to what I implemented.


DHCP is a way to make your device ask the router for an IP address. You don't need it. Just hard-code an IP address.


DNS is a way to convert names to IP addresses. You don't need it. But if you did need it, it would be between you and a DNS server to look up the device's address - the device doesn't participate in that. If your device wanted to look up IP addresses using DNS names, it would need to know DNS.

huangapple
  • 本文由 发表于 2023年3月7日 01:39:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75654078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定