%# -*- coding: utf-8-unix -*-

\section{IP与ICMP分析}
\label{sec:c:wireshark:s:ip}

\subsection{实验目的}
\label{subsec:c:wireshark:s:ip_object}

IP和ICMP协议是TCP/IP协议簇中的网络层协议，
在网络寻址定位、数据分组转发和路由选择等任务中发挥了重要作用。
本实验使学生能熟练使用Wireshark软件，观察IP数据报的基本结构，
分析数据报的分片；掌握基于ICMP协议的ping和traceroute命令及其工作过程。

\subsection{实验内容}
\label{subsec:c:wireshark:s:ip_content}

启动Wireshark，捕捉网络命令执行过程中本机接受和发送的数据报。

\begin{enumerate}
  \item \textbf{执行ping命令，观察IP数据报和ICMP询问报文的结构：}
  通过Wireshark监视器观察捕获流量中的ICMP询问报文和IP数据报的结构。
  注意比较ICMP请求帧与回应帧，及其IP头部数据字段的异同。
  \item \textbf{改变ping命令的参数，观察IP数据报分片：}
  更改ping命令参数MTU，使其发出长报文以触发IP数据报分片，
  再观察IP数据报的结构变化。
  \item \textbf{执行Traceroute命令，观察ICMP差错报文的结构，并分析其工作原理：}
  使用Linux操作系统提供的traceroute命令（或者Windows系统提供的tracert命令），
  捕获和分析该命令所产生的IP数据报，特别注意相关的ICMP差错报文。
  结合捕获的具体数据，画出命令执行过程中数据交互的示意图，
  掌握traceroute的工作原理。
\end{enumerate}

\subsection{实验原理、方法和手段}
\label{subsec:c:wireshark:s:ip_principle}

\subsubsection{IP协议及数据报格式}

网际互连协议（Internet Protocol，IP），是TCP/IP体系中的网络层协议，
可实现大规模的异构网络互联互通，为主机提供无连接的、尽力而为的数据包传输服务。
在网际协议第4版（IPv4）中，IP数据报是一个可变长分组，
包括首部和数据两部分(如图\ref{c:wireshark_ip-structure})。
首部由20~60字节组成，包含与路由选择和传输有关的重要信息，其各字段意义如下：

\begin{figure}[!ht]
  \centering
  \includegraphics[width=12cm]{ip-structure}
  \caption{IP数据报结构示意图}
  \label{c:wireshark_ip-structure}
\end{figure}

\begin{enumerate}
  \item \textbf{版本（4位）：}该字段定义IP协议版本，
  所有字段都要按照此版本的协议来解释。
  \item \textbf{首部长度（4位）：}该字段定义数据报协议头长度，
  表示协议首部具有32位字长的数量，最小值为5，最大值为15。
  \item \textbf{服务（8位）：}该字段定义上层协议对处理当前数据报所期望的服务质量，
  并对数据报按照重要性级别进行分配。前3位成为优先位，后面4位成为服务类型，
  最后1位没有定义。这些8位字段可用于分配优先级、延迟、吞吐量以及可靠性。
  \item \textbf{总长度（16位）：}该字段定义整个IP数据报的字节长度，
  包括协议首部和数据，其最大值为65535字节。
  \item \textbf{标识（16位）：}该字段包含一个整数，用于标识当前数据报。
  当数据报分片时，标识字段的值被复制到所有的分中片。
  \item \textbf{标记（3位）：}该字段由3位字段构成，其中最低位（MF）控制分片：
  若存在下一个分片则值为1；否则置0代表该分片是最后一个。
  中间位（DF）指出数据报是否可进行分片，若置1则不允许该数据报进行分片。
  第三位即最高位保留不使用，值为0。
  \item \textbf{分片偏移（13位）：}该字段指出数据分片在源数据报中的相对位置，
  以8字节为长度单位。
  \item \textbf{生存时间（8位）：}该字段是计数器，
  转发该数据报的路由器依次减1直至减少为0。
  \item \textbf{协议（8位）：}该字段指出在IP处理过程完成之后，
  有哪种上层协议接收导入数据报。
  \item \textbf{头部校验和（16位）：}该字段帮助确保IP协议头的正确性。
  计算过程是先将校验和字段置为0，然后将整个头部每16位划分为一部分，
  将个部分相加，再将计算结果取反码，插入到校验和字段中。
  \item \textbf{源地址（32位）：}源主机的IP地址。
  \item \textbf{目的地址（32位）：}目标主机的IP地址。
\end{enumerate}

一个IP包从源主机传输到目标主机可能需要经过多个传输媒介不同的网络。
每种网络对数据帧都设置了一个最大传输单元(MTU)的限制（例如以太网的MTU是1500字节）。
因此，当路由器在转发IP包时，如果数据包的大小超过了出口链路网络的MTU时，
需将对该IP数据报进行分片，才能在目标链路上顺利传输。每个IP分片将独立传输，
直到所有分片都到达目的地后，目标主机才会把他们重组成一个完整的IP数据报。
在IP数据报的分片与重组过程中，以下三个首部字段发挥了重要作用：

\begin{enumerate}
  \item 标记占3位，该字段目前只有后两位有意义。
  其中，最低位记为MF（More Fragment），MF = 1代表还有后续分片，
  MF = 0表示此为原始数据报的最后分片。次低位DF（Don't Fragment），
  用来控制数据报是否允许分片。DF = 1表示该数据报不允许分片；DF = 0允许分片。
  \item 标识符占16位，用于目的主机将IP数据报的各个分片重装成原来的数据报。
  当IP数据报分片时，该标识字段的值被复制到所有的数据报分片的标识字段中。
  这样，目的主机就可以正确的将标识字段值相同的各数据报分片重装成原来的数据报。
  \item 片偏移占13位，表示本分片在原IP数据报中的偏移位置，偏移量以8字节为单位。
  由于每个数据分片按照独立数据报方式传输，因此到达目的主机的顺序是不确定的，
  目的主机在重装IP数据报时需要根据该字段提供偏移量进行排序。
\end{enumerate}

\subsubsection{ICMP协议及报文格式}

因特网控制报文协议（Internet Control Message Protocol，ICMP），
用于IP主机、路由器之间传递控制消息。
控制消息是指网络是否连通、主机是否可达、路由是否可用等网络本身的控制管理消息，
对网络正常运行起着重要的作用。

ICMP报文的类型可以分为ICMP差错报文和ICMP询问报文两种
（其结构如图\ref{c:wireshark_icmp-structure}）。
ICMP差错报告报文主要有终点不可达、源站抑制、超时、参数问题和路由重定向5种。
ICMP询问报文有回送请求和应答、时间戳请求和应答、
地址掩码请求和应答以及路由器询问和通告4种。
其常见的类型与代码如表\ref{tab:c:wireshark_icmp-format}所示。

\begin{figure}[!ht]
  \centering
  \includegraphics[width=12cm]{icmp-structure}
  \caption{ICMP报文结构示意图}
  \label{c:wireshark_icmp-structure}
\end{figure}

\renewcommand{\arraystretch}{1.5}
\begin{table}[!ht]
  \small
  \centering
  \caption{ICMP各类型报文的格式}
  \label{tab:c:wireshark_icmp-format}
  \begin{tabular}{|m{1.4cm}<{\centering}
                  |m{1.4cm}<{\centering}
                  |m{7cm}
                  |m{1.4cm}<{\centering}
                  |m{1.4cm}<{\centering}|}
    \hline
    \heiti 类型(TYPE) &\heiti 代码(CODE) &
    \multicolumn{1}{|c|}{\heiti 描述(Description)} &
    \heiti 查询类(Query) &\heiti  差错类(Error)\\  \hline

    0 & 0 & Echo Reply——回显应答（Ping应答）& $\checkmark$	& \\ \hline
    3 & 1 & Host Unreachable——主机不可达 & & $\checkmark$\\ \hline
    3 & 3 & Port Unreachable——端口不可达 & & $\checkmark$\\ \hline
    3 & 4 & Fragmentation needed but no frag. bit set \newline
              ——需要进行分片但设置不分片比特	& &$\checkmark$\\ \hline
    8 & 0 & Echo request——回显请求（Ping请求）& $\checkmark$ & \\ \hline
    11&	0 & TTL equals 0 during transit \newline
              ——传输期间生存时间为0 & & $\checkmark$\\ \hline
  \end{tabular}
\end{table}

本实验涉及以下两个常用网络命令，都属于ICMP协议的典型应用。

\begin{enumerate}
  \item ping命令，是测试网络最有效的工具之一。
  它是由主机或路由器执行ping命令向一个特定的目的主机发送一份ICMP回显请求（Echo request）报文，
  并等待其返回ICMP回显应答（Echo Reply）。
  ping命令可以检测网络的连通性，简单估测数据报的往返时间（Round Trip Time），
  确定是否有数据包丢失或损坏，从而帮助分析网络故障。
  ping命令格式和常用参数如图\ref{fig:ping-cmd}所示。
  \begin{figure}[!ht]
    \centering
    \begin{code}[text]
      ping [-t] [-a] [-n count] [-l length] [-f] [-i ttl] [-v tos]
          [-r count] [-s count] [-j computer-list] | [-k computer-list]
          [-w timeout] destination-list

        -a 将地址解析为计算机名。
        -n count 发送 count 指定的 ECHO 数据包数。默认值为 4。
        -l length 发送包含由 length 指定的数据量的 ECHO 数据包。默认为 32 字节;最大值是65,527。
        -f 在数据包中发送"不要分片"标志。数据包就不会被路由上的网关分片。
        -i ttl 将"生存时间"字段设置为 ttl 指定的值。
    \end{code}
    \caption{ping命令语法及参数}
    \label{fig:ping-cmd}
  \end{figure}

  \item traceroute/tracert命令，利用TTL字段和ICMP差错类型报文，
  查找IP数据报的路由转发路径（含路由器信息）。
  源主机执行该命令向目的主机发送生存时间（TTL）不同的ICMP回送请求报文，
  直至收到目的主机应答，并通过分析应答报文获得转发路径和时延信息。
\end{enumerate}

首先源主机发起一个TTL=1的ICMP报文。
第一个路由器收到该报文后，TTL减1变为0并丢弃此报文，
返回一个[ICMP time exceeded]的消息。
源主机通过这个消息获知IP数据报转发路径上的第一个路由器信息。
然后，依次增加发送ICMP报文的TTL值，可以获取路径上的后续路由器的信息。
当到达目的地时，目标主机返回一个[ICMP port unreachable]的消息，
使发起者确认IP数据报已经正常到达。
至此，traceroute命令发起者已经获得了通向目标主机路径上的所有路由信息。
tracert命令（Linux）格式和常用参数如图\ref{fig:tracert-cmd}所示。

\begin{figure}[!ht]
  \centering
\begin{code}[text]
  tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] [-R]
          [-S srcaddr] [-4] [-6] target_name

    -d Do not resolve addresses to hostnames.
    -h maximum_hops Maximum number of hops to search for target.
    -j host-list Loose source route along host-list (IPv4-only).
    -w timeout Wait timeout milliseconds for each reply.
    -R Trace round-trip path (IPv6-only).
    -S srcaddr Source address to use (IPv6-only).
    -4 Force using IPv4.
    -6 Force using IPv6.
\end{code}
\caption{tracert命令语法及参数}
\label{fig:tracert-cmd}
\end{figure}

\subsubsection{实验方法和手段}

\begin{enumerate}
  \item 使用Wireshark软件，
  捕获本机在ping和traceroute网络命令执行过程中接收和发出的全部数据流量。
  \item 合理设置过滤条件，观察IP数据报和ICMP报文，
  着重分析报文首部和内容变化，从而掌握协议的工作原理。
  \item 调整ping命令的参数，观察并分析IP数据报分片情况。
  \item 结合所捕获的数据报，画出traceroute命令过程中数据交互示意图。
\end{enumerate}

\subsection{实验条件}
\label{subsec:c:wireshark:s:ip_requirement}

装有Wireshark软件的PC机一台（Linux或OS 操作系统）；局域网环境。

参考资料：

\begin{itemize}
  \item \href{http://www-net.cs.umass.edu/wireshark-labs/Wireshark_ICMP_v8.0.pdf}
  {J.F Kurose and K.W. Ross, Wireshark Lab: ICMP v8.0}
  \item \href{https://www.wireshark.org/docs/man-pages/wireshark-filter.html}
  {Wireshark官方过滤器语法指导书}
  \item \href{https://datatracker.ietf.org/doc/rfc791/}{IP协议的RFC}
\end{itemize}

\subsection{实验步骤}
\label{subsec:c:wireshark:s:ip_procedure}

\subsubsection{ping命令}

本机（示例IP为192.168.1.251）启动Wireshark软件，
选择要监听的网络接口（如eth0、wlan0）；
然后在终端发起网络命令：ping IP地址/域名。

\begin{enumerate}
  \item 在Wireshark监视器中设置过滤条件。
  例如图\ref{fig:c:wireshark_wireshark-monitor}设置过滤条件为icmp，
  则显示出所捕获的ICMP数据包。

  \begin{figure}[!ht]
    \centering
    \includegraphics[width=16cm]{wireshark-monitor}
    \caption{Wireshark监视器界面}
    \label{fig:c:wireshark_wireshark-monitor}
  \end{figure}

  \item 点击Internet Protocol Version 4展开（如图\ref{fig:c:wireshark_ip-view}），
  查看IP数据报，特别观察IP数据报的首部字段及其内容。

  \begin{figure}[!ht]
    \centering
    \includegraphics[width=16cm]{ip-view}
    \caption{查看IP数据报}
    \label{fig:c:wireshark_ip-view}
  \end{figure}

  \item 点击Internet Control Message Protocol展开（如图\ref{fig:c:wireshark_echo-request}），
  查看ICMP报文，并解释回显（Echo Request和Echo Reply）报文的首部字段。

  \begin{figure}[!ht]
    \centering
    \includegraphics[width=16cm]{echo-request}
    \caption{Echo request示例}
    \label{fig:c:wireshark_echo-request}
  \end{figure}

  \item 清空Wireshark监控器，重新发起网络命令（如图\ref{fig:c:wireshark_ping-exec}）：
  ping IP地址/域名 –l \#length，并解释对比前后两次执行ping命令的结果。
  其中，-l \#length确定echo数据报的长度为\#length，
  其默认值为32字节，且小于65,527字节。

  \begin{figure}[!ht]
    \centering
    \includegraphics[width=12cm]{ping-exec}
    \caption{ping命令执行示例}
    \label{fig:c:wireshark_ping-exec}
  \end{figure}

  \item 可以多次改变\#length的大小（例如1000字节、2000字节和4000字节），
  观察IP数据报何时会分片？请解释IP数据报分片的原因和具体情况。
  提示：请先确认该网络的MTU，可在Wireshark记录中查找“IPv4 fragments”项目。
\end{enumerate}

\subsubsection{traceroute命令}

本机（示例IP为192.168.1.251）启动Wireshark软件，
选择要监听的网络接口（如eth0、wlan0）；
然后在终端发起网络命令：traceroute IP地址/域名。

\begin{enumerate}
  \item 启动Wireshark软件，选择要监听的网络接口，设置过滤条件icmp
  （如图\ref{fig:c:wireshark_wireshark-filter-setup}）。

  \begin{figure}[!ht]
    \centering
    \includegraphics[width=16cm]{wireshark-filter-setup}
    \caption{在Wireshark中设置过滤条件}
    \label{fig:c:wireshark_wireshark-filter-setup}
  \end{figure}

  \item 在终端中使用traceroute命令，
  目的主机是外网的一台设备（如图\ref{fig:c:wireshark_traceroute-exec}，示例IP为210.34.0.1）。

  \begin{figure}[!ht]
    \centering
    \includegraphics[width=10cm]{traceroute-exec}
    \caption{在终端中执行traceroute命令示例}
    \label{fig:c:wireshark_traceroute-exec}
  \end{figure}

  \item 点击Internet Control Message Protocol展开，
  查看ICMP差错报文，观察并解释ICMP报文结构和字段内容。
  \item 结合ICMP报文记录画出数据交互示意图，并描述tracert工作原理。

\end{enumerate}

\subsection{思考题}
\label{subsec:c:wireshark:s:ip_rethink}

\begin{enumerate}
  \item 在有线局域网中，PC1的IP地址为192.168.1.5/24，
  默认路由器的IP地址为192.168.1.1；
  PC2的IP地址为192.168.2.6/24，默认路由器的IP地址为192.168.2.1。
  在PC1向PC2发送数据的传输过程中，
  以太网数据帧的首部字段和IP数据报的首部字段是怎样变化的？
  如果有条件，请搭建实验平台进行实验，并使用Wireshark软件验证你的答案。
  \item 拒绝服务（Denial of Service，DoS）攻击，通过消耗目标主机设备的某种资源，
  导致其网络服务不能被正常用户使用。
  \begin{enumerate}
    \item IP数据报分片机制可能被攻击者利用来构建拒绝服务攻击。
    试设计一种利用IP数据报分片机制发动DOS攻击的方法，并提出防御的思路。
    \item 请思考利用ICMP报文构建DOS攻击的可能性以及防御方法。
  \end{enumerate}
  \item 在实际操作中，Traceroute命令返回的某些条目以“*”号表示。
  请思考有哪些原因可能导致这样的情况，该如何避免这样的情况。
  \item 发送方要怎样决定IP数据报分组大小，
  才能避免因为不同网络MTU不一致而引起分片呢？
  \item 从客户端给服务器（其地址为\texttt{\#IP}）发送三个ping命令，
  请比较命令的结果，并用Wireshark软件进行观察分析。
  \begin{enumerate}
    \item \texttt{ping \#IP -l 1472 -f -n 1}
    \item \texttt{ping \#IP -l 1473 -f -n 1}
    \item \texttt{ping \#IP -l 1473 -n 1}
  \end{enumerate}
\end{enumerate}

\subsection{考核方法}
\label{subsec:c:wireshark:s:ip_criterion}

本次实验需提交一份实验报告和一组Wireshark数据存储文件。
报告内容应当包括以下三个部分，其中的分析解释都有对应的截图，
且与数据存储文件记录相符。
\begin{enumerate}
  \item （30分）实施ping命令，记录引发的IP数据报和ICMP报文，保存为pcapng文件；
  解释任一个IP数据报的首部，并对比ICMP Echo请求帧和回应帧；
  改变ping的长度参数，解释IP数据报分片情况。
  \item （40分）实施tracert命令，记录引发的ICMP报文，保存为pcapng文件；
  解释任一个ICMP差错报文的结构；
  描述tracert工作原理，结合ICMP报文记录画出数据交互示意图。
  \item （20分）回答任意两道思考题。
  \item （10分）记录自己在本次实验中所遇到的问题，以及心得感悟。
  如果遇到异常情况，或者无法完成任务时，也请分析错误产生的原因。
\end{enumerate}
