《Linux高性能服务器编程》——1.5 ARP协议工作原理

简介: 本节书摘来自华章计算机《Linux高性能服务器编程》一书中的第1章,第1.5节,作者 游双,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.5 ARP协议工作原理

ARP协议能实现任意网络层地址到任意物理地址的转换,不过本书仅讨论从IP地址到以太网地址(MAC地址)的转换。其工作原理是:主机向自己所在的网络广播一个ARP请求,该请求包含目标机器的网络地址。此网络上的其他机器都将收到这个请求,但只有被请求的目标机器会回应一个ARP应答,其中包含自己的物理地址。

1.5.1 以太网ARP请求/应答报文详解

以太网ARP请求/应答报文的格式如图1-9所示。

image

图1-9所示以太网ARP请求/应答报文各字段具体介绍如下。

image
image

由图1-9可知,ARP请求/应答报文的长度为28字节。如果再加上以太网帧头部和尾部的18字节(见图1-6),则一个携带ARP请求/应答报文的以太网帧长度为46字节。不过有的实现要求以太网帧数据部分长度至少为46字节(见图1-4),此时ARP请求/应答报文将增加一些填充字节,以满足这个要求。在这种情况下,一个携带ARP请求/应答报文的以太网帧长度为64字节。

1.5.2 ARP高速缓存的查看和修改

通常,ARP维护一个高速缓存,其中包含经常访问(比如网关地址)或最近访问的机器的IP地址到物理地址的映射。这样就避免了重复的ARP请求,提高了发送数据包的速度。

Linux下可以使用arp命令来查看和修改ARP高速缓存。比如,ernest-laptop在某一时刻(注意,ARP高速缓存是动态变化的)的ARP缓存内容如下(使用arp-a命令):

Kongming20 (192.168.1.109) at 08:00:27:53:10:67 [ether] on eth0
?(192.168.1.1) at 14:e6:e4:93:5b:78 [ether] on eth0

其中,第一项描述的是另一台测试机器Kongming20(注意,其IP地址、MAC地址都与图1-8描述的一致),第二项描述的是路由器。下面两条命令则分别删除和添加一个ARP缓存项:

$ sudo arp –d 192.168.1.109            #删除Kongming20对应的ARP缓存项
$ sudo arp –s 192.168.1.109 08:00:27:53:10:67    #添加Kongming20对应的ARP缓存项

1.5.3 使用tcpdump观察ARP通信过程

为了清楚地了解ARP的运作过程,我们从ernest-laptop上执行telnet命令登录Kongming20的echo服务(已经开启),并用tcpdump(详见第17章)抓取这个过程中两台测试机器之间交换的以太网帧。具体的操作过程如下:

$ sudo arp –d 192.168.1.109            #清除ARP缓存中Kongming20对应的项
$ sudo tcpdump -i eth0 -ent '(dst 192.168.1.109 and src 192.168.1.108)or
(dst 192.168.1.108 and src 192.168.1.109)'    #如无特殊声明,抓包都在机器ernest-
                              laptop上执行
$ telnet 192.168.1.109 echo            #开启另一个终端执行telnet命令
Trying 192.168.1.109...
Connected to 192.168.1.109.
Escape character is '^]'.
^](回车)                        #输入Ctrl+]并回车

telnet> quit(回车)
Connection closed.

在执行telnet命令之前,应先清除ARP缓存中与Kongming20对应的项,否则ARP通信不被执行,我们也就无法抓取到期望的以太网帧。当执行telnet命令并在两台通信主机之间建立TCP连接后(telnet输出“Connected to 192.168.1.109”),输入Ctrl+]以调出telnet程序的命令提示符,然后在telnet命令提示符后输入quit,退出telnet客户端程序(因为ARP通信在TCP连接建立之前就已经完成,故我们不关心后续内容)。tcpdump抓取到的众多数据包中,只有最靠前的两个和ARP通信有关系,现在将它们列出(数据包前面的编号是笔者加入的,后同):

1. 00:16:d3:5c:b9:e3 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.109 tell 192.168.1.108, length 28
2. 08:00:27:53:10:67 > 00:16:d3:5c:b9:e3, ethertype ARP (0x0806), length 60: Reply 192.168.1.109 is-at 08:00:27:53:10:67, length 46

由tcpdump抓取的数据包本质上是以太网帧,我们通过该命令的众多选项来控制帧的过滤(比如用dst和src指定通信的目的端IP地址和源端IP地址)和显示(比如用-e选项开启以太网帧头部信息的显示)。

第一个数据包中,ARP通信的源端的物理地址是00:16:d3:5c:b9:e3(ernest-laptop),目的端的物理地址是ff:ff:ff:ff:ff:ff,这是以太网的广播地址,用以表示整个LAN。该LAN上的所有机器都会收到并处理这样的帧。数值0x806是以太网帧头部的类型字段的值,它表示分用的目标是ARP模块。该以太网帧的长度为42字节(实际上是46字节,tcpdump未统计以太网帧尾部4字节的CRC字段),其中数据部分长度为28字节。“Request”表示这是一个ARP请求,“who-has 192.168.1.109 tell 192.168.1.108”则表示是ernest-laptop要查询Kongming20的IP地址。

第二个数据包中,ARP通信的源端的物理地址是08:00:27:53:10:67(Kongming20),目的端的物理地址是00:16:d3:5c:b9:e3(ernest-laptop)。“Reply”表示这是一个ARP应答,“192.168.1.109 is-at 08:00:27:53:10:67”则表示目标机器Kongming20报告其物理地址。该以太网帧的长度为60字节(实际上是64字节),可见它使用了填充字节来满足最小帧长度。

为了便于理解,我们将上述讨论用图1-10来详细说明。

image

关于该图,需要说明三点:

第一,我们将两次传输的以太网帧按照图1-6所描述的以太网帧封装格式绘制在图的下半部分。

第二,ARP请求和应答是从以太网驱动程序发出的,而并非像图中描述的那样从ARP模块直接发送到以太网上,所以我们将它们用虚线表示,这主要是为了体现携带ARP数据的以太网帧和其他以太网帧(比如携带IP数据报的以太网帧)的区别。

第三,路由器也将接收到以太网帧1,因为该帧是一个广播帧。不过很显然,路由器并没有回应其中的ARP请求,正如前文讨论的那样。

相关文章
|
13天前
|
存储 缓存 网络协议
Linux系统之ARP命令的基本使用
【7月更文挑战第2天】Linux系统之ARP命令的基本使用
23 2
|
12天前
|
存储 网络协议 Ubuntu
【Linux开发实战指南】基于UDP协议的即时聊天室:快速构建登陆、聊天与退出功能
UDP 是一种无连接的、不可靠的传输层协议,位于IP协议之上。它提供了最基本的数据传输服务,不保证数据包的顺序、可靠到达或无重复。与TCP(传输控制协议)相比,UDP具有较低的传输延迟,因为省去了建立连接和确认接收等过程,适用于对实时性要求较高、但能容忍一定数据丢失的场景,如在线视频、语音通话、DNS查询等。 链表 链表是一种动态数据结构,用于存储一系列元素(节点),每个节点包含数据字段和指向下一个节点的引用(指针)。链表分为单向链表、双向链表和循环链表等类型。与数组相比,链表在插入和删除操作上更为高效,因为它不需要移动元素,只需修改节点间的指针即可。但访问链表中的元素不如数组直接,通常需要从
|
12天前
|
Linux 网络安全 开发工具
linux 常用命令【编程必备】
linux 常用命令【编程必备】
25 4
|
12天前
|
小程序 Linux
【编程小实验】利用Linux fork()与文件I/O:父进程与子进程协同实现高效cp命令(前半文件与后半文件并行复制)
这个小程序是在文件IO的基础上去结合父子进程的一个使用,利用父子进程相互独立的特点实现对数据不同的操作
|
12天前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
|
16天前
|
Linux 编译器 调度
【Linux】对共享库加载问题的深入理解——基本原理概述
【Linux】对共享库加载问题的深入理解——基本原理概述
|
26天前
|
Java 数据安全/隐私保护
深入剖析:Java Socket编程原理及客户端-服务器通信机制
【6月更文挑战第21天】Java Socket编程用于构建网络通信,如在线聊天室。服务器通过`ServerSocket`监听,接收客户端`Socket`连接请求。客户端使用`Socket`连接服务器,双方通过`PrintWriter`和`BufferedReader`交换数据。案例展示了服务器如何处理每个新连接并广播消息,以及客户端如何发送和接收消息。此基础为理解更复杂的网络应用奠定了基础。
|
24天前
|
缓存 小程序 前端开发
Java服务器端技术探秘:Servlet与JSP的核心原理
【6月更文挑战第23天】Java Web开发中的Servlet和JSP详解:Servlet是服务器端的Java小程序,处理HTTP请求并响应。生命周期含初始化、服务和销毁。创建Servlet示例代码展示了`doGet()`方法的覆盖。JSP则侧重视图,动态HTML生成,通过JSP脚本元素、声明和表达式嵌入Java代码。Servlet常作为控制器,JSP处理视图,遵循MVC模式。优化策略涉及缓存、分页和安全措施。这些技术是Java服务器端开发的基础。
|
4天前
|
安全 网络协议 网络安全
SSL(Secure Sockets Layer)是一种安全协议,用于在客户端和服务器之间建立加密的通信通道。
SSL(Secure Sockets Layer)是一种安全协议,用于在客户端和服务器之间建立加密的通信通道。
9 0
|
4天前
|
网络协议 安全 Python
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
11 0