> For the complete documentation index, see [llms.txt](https://valineliu.gitbook.io/deuterium-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://valineliu.gitbook.io/deuterium-wiki/reading/cs-jing-dian-shu-ji/tcpv1/ch04-address-resolutin-protocol.md).

# ch04: Address Resolutin Protocol

ARP

## MindMap

![ARP: Address Resolution Protocol](https://tva1.sinaimg.cn/large/007S8ZIlly1gfni5qz9tdj314h0u0q9h.jpg)

## 一个例子

![image-20200611183838494](https://tva1.sinaimg.cn/large/007S8ZIlly1gfojajuxlsj30u00yvwi9.jpg)

流程：

1. 应用程序调用`gethostbyname`通过hostname获得对应的IP地址；
2. 应用程序请求TCP建立和IP的连接；
3. TCP发送一个连接请求，使用IP地址来发送一个IP datagram；
4. 如果目标主机在本地网络，就直接发送到对应的主机上。如果在远程的网络，就发送到下一跳的路由器上来转发。这两种情况都需要将IP datagram发送到一台主机或路由器上；
5. 如果是以太网，那么需要知道对应主机的以太网地址MAC。IP是逻辑地址，MAC是物理地址。ARP就是根据IP获得MAC；
6. ARP发送一个ARP请求，包含对应的IP地址，问”谁的IP地址是这个就告诉我你的MAC地址“；
7. 目的主机收到这个ARP请求后，发送一个ARP相应，应答包括IP地址和MAC地址；
8. 收到ARP应答之后，就可以将那个IP datagram发送到下一跳了；
9. 发送IP datagram到目标主机或路由器。

## ARP 缓存

还可以将一个主机所知道的IP到MAC的映射缓存起来，缓存时间是20分钟。

可以通过下面命令查看ARP缓存：

```
$ arp -a
? (169.254.0.34) at <incomplete> on eth1
? (10.233.145.193) at bc:16:65:fb:a7:ff [ether] on eth1
? (169.254.0.35) at <incomplete> on eth1
? (10.233.145.241) at ec:38:8f:7b:0b:0a [ether] on eth1
```

#### ARP包格式

格式如下图：

![image-20200611184810137](https://tva1.sinaimg.cn/large/007S8ZIlly1gfojkf698zj31940amn00.jpg)

* 前两个是以太网的目的地址和源地址。目的地址全是1的是广播地址；
* Frame Type：两个字节，对于ARP请求和ARP响应，这个值是0x0806；
* Hard Type：硬件类型，以太网的值是1；
* Prot Type：协议类型，IP的值是0x0800；
* Hard Size和Prot Size，分别是MAC地址和IP地址的大小，分别是6和4，单位是字节；
* op：operation，ARP请求是1，响应是2，RARP请求是3，RARP响应是4；
* 接下来就是源和目的的MAC地址以及IP地址，其中目的主机的MAC地址是空的，需要响应来填充。
