This commit is contained in:
Hanzhang ma 2024-12-25 19:57:28 +01:00
commit 000d0b90fb
2 changed files with 165 additions and 2 deletions

View File

@ -362,3 +362,143 @@ ICMPv6 邻居通告消息由以下几部分组成:
- 确保链路层地址和目标地址一致。 - 确保链路层地址和目标地址一致。
如果你需要进一步分析或有其他问题,请随时补充! 如果你需要进一步分析或有其他问题,请随时补充!
=======
是的,你可以在这个 `tuntap.c` 文件的基础上完成第二问和第三问。以下是如何扩展这个文件来实现处理 ARP 请求和生成 ARP 响应的建议步骤:
---
### **扩展步骤**
#### **1. 增加 ARP 数据包解析和生成的逻辑**
- 定义 ARP 数据包的结构。
- 添加解析函数,用于从 `buf` 中提取 ARP 请求包的信息。
- 添加响应生成函数,用于根据解析结果生成 ARP 响应包。
#### **2. 在现有的读取逻辑中嵌入 ARP 处理**
- 当前的代码已经实现了从 `TUN/TAP` 设备读取数据的功能(`read`)。
- 在读取的数据中,检查是否为 ARP 请求包(根据协议类型和操作码)。
- 如果是 ARP 请求,则生成响应数据,并通过设备写回。
#### **3. 实现发送 ARP 响应的逻辑**
- 使用 `write` 系统调用,将生成的 ARP 响应包通过 `tap` 接口发送回去。
---
### **代码实现(示例)**
以下是如何在现有代码基础上扩展实现 ARP 请求解析和响应的代码示例。
#### **(1) 定义 ARP 数据包结构和处理函数**
在文件顶部增加 ARP 相关的定义和函数:
```c
#include <stdint.h>
#include <string.h>
// 定义 ARP 包结构
typedef struct arp_packet {
uint16_t hardware_type;
uint16_t protocol_type;
uint8_t hardware_len;
uint8_t protocol_len;
uint16_t opcode;
uint8_t sender_mac[6];
uint8_t sender_ip[4];
uint8_t target_mac[6];
uint8_t target_ip[4];
} arp_packet_t;
// 解析 ARP 请求
int parse_arp_request(const uint8_t *buf, arp_packet_t *arp_req) {
memcpy(arp_req, buf + 14, sizeof(arp_packet_t)); // 跳过以太网头部
return ntohs(arp_req->opcode) == 1; // 返回是否为 ARP 请求
}
// 生成 ARP 响应
void create_arp_response(const arp_packet_t *arp_req, uint8_t *buf) {
memset(buf, 0, 42); // 清空响应缓冲区
// 填充以太网头部
memcpy(buf, arp_req->sender_mac, 6); // 目标 MAC 地址(原请求的发送方)
uint8_t mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01}; // 响应方 MAC
memcpy(buf + 6, mac, 6); // 源 MAC 地址
buf[12] = 0x08; buf[13] = 0x06; // ARP 协议类型 (0x0806)
// 填充 ARP 数据包部分
arp_packet_t *arp_resp = (arp_packet_t *)(buf + 14);
arp_resp->hardware_type = htons(1); // 硬件类型 (Ethernet)
arp_resp->protocol_type = htons(0x0800); // 协议类型 (IPv4)
arp_resp->hardware_len = 6;
arp_resp->protocol_len = 4;
arp_resp->opcode = htons(2); // ARP 响应
memcpy(arp_resp->sender_mac, mac, 6); // 响应方 MAC
memcpy(arp_resp->sender_ip, arp_req->target_ip, 4); // 响应方 IP
memcpy(arp_resp->target_mac, arp_req->sender_mac, 6); // 请求方 MAC
memcpy(arp_resp->target_ip, arp_req->sender_ip, 4); // 请求方 IP
}
```
---
#### **(2) 修改 `main` 函数,添加 ARP 处理逻辑**
`main` 函数的 `while` 循环中扩展读取和处理逻辑:
```c
uint8_t buf[BUF_LEN];
uint8_t response_buf[BUF_LEN]; // 用于存储响应数据
arp_packet_t arp_req;
while (running) {
int nread;
if ((nread = read(tun_fd, buf, BUF_LEN)) < 0) {
perror("ERR: Read from tun_fd");
break;
}
printf("Read %d bytes from device %s\n", nread, dev);
// 检查是否为 ARP 包
if (nread >= 42 && buf[12] == 0x08 && buf[13] == 0x06) {
printf("ARP packet detected\n");
// 解析 ARP 请求
if (parse_arp_request(buf, &arp_req)) {
printf("Processing ARP request from %d.%d.%d.%d\n",
arp_req.sender_ip[0], arp_req.sender_ip[1],
arp_req.sender_ip[2], arp_req.sender_ip[3]);
// 生成 ARP 响应
create_arp_response(&arp_req, response_buf);
// 发送 ARP 响应
if (write(tun_fd, response_buf, 42) < 0) {
perror("ERR: Write to tun_fd");
} else {
printf("Sent ARP response\n");
}
}
}
}
```
---
### **功能验证**
1. **启动 `tuntap.c` 程序**
```bash
sudo ./tuntap mytap0
```
2. **使用 `arping` 测试**
在另一台主机上运行以下命令:
```bash
arping -I mytap0 <tap0 对应的 IP 地址>
```
程序应打印检测到 ARP 请求,并生成和发送 ARP 响应。
---
### **总结**
- 第二问通过定义 `arp_packet_t` 数据结构和解析/生成函数,设计了一个合适的接口。
- 第三问通过扩展 `tuntap.c` 文件,增加了 ARP 请求处理和响应功能。
- 使用 `arping` 工具可以测试实现的正确性。

View File

@ -1,4 +1,27 @@
# Das Internet und Autonome Systeme # Das Internet und Autonome Systeme
- [Das Internet und Autonome Systeme](#das-internet-und-autonome-systeme)
* [3.1 Vermittlungsschicht (OSI-Schicht3)](#31-vermittlungsschicht--osi-schicht3-)
+ [3.1.1 Fragmentierung 分片](#311-fragmentierung---)
- [Fragmentierung von IP-Paketen IP 数据包的分片](#fragmentierung-von-ip-paketen-ip-------)
+ [3.1.2 Tunneling 隧道技术](#312-tunneling-----)
* [3.2 Internet Protocol Version 6 IPv6](#32-internet-protocol-version-6-ipv6)
+ [3.2.1 Adressen 地址](#321-adressen---)
+ [3.2.2 Hilfsprotokolle 辅助协议](#322-hilfsprotokolle-----)
+ [3.2.3 Koexistenz von IPv4 und IPv6 IPv4 和 IPv6 的共存](#323-koexistenz-von-ipv4-und-ipv6-ipv4---ipv6----)
* [3.3 Routing-Verfahren 路由方法](#33-routing-verfahren-----)
+ [3.3.1 Optimale Pfade最优路径](#331-optimale-pfade----)
+ [3.3.2 Distanz-Vektor Verfahren 距离向量方法](#332-distanz-vektor-verfahren-------)
+ [3.3.3 Link-State Verfahren 链路状态方法](#333-link-state-verfahren-------)
+ [3.3.4 Inter-AS-Routing 跨自治系统路由](#334-inter-as-routing--------)
+ [3.3.5 FRRouting Suite FRRouting 套件](#335-frrouting-suite-frrouting---)
* [3.4 Aufgaben](#34-aufgaben)
+ [A300 Fragmentierung und IP-Tunneling (Theorie)](#a300-fragmentierung-und-ip-tunneling--theorie-)
+ [A301 IPv6 (Theorie)](#a301-ipv6--theorie-)
+ [A302 Fragmentierung und Tunneling](#a302-fragmentierung-und-tunneling)
+ [A303 IPv6](#a303-ipv6)
+ [A304 Distanz-Vektor Routing mit RIP](#a304-distanz-vektor-routing-mit-rip)
+ [A305 Link-State Routing mit OSPF](#a305-link-state-routing-mit-ospf)
+ [A306 Autonome Systeme und BGP](#a306-autonome-systeme-und-bgp)
Das Internet ist ein Verbundnetz, bestehend aus den Netzen vieler verschiedener Betreiber (Unternehmen, Bildungseinrichtungen, Militär, usw), die jeweils eigene, administrativ unabhängige Netze betreiben. Das Internet ist ein Verbundnetz, bestehend aus den Netzen vieler verschiedener Betreiber (Unternehmen, Bildungseinrichtungen, Militär, usw), die jeweils eigene, administrativ unabhängige Netze betreiben.
互联网是一个互联网络,由许多不同运营商的网络组成(如企业、教育机构、军队等),这些运营商各自运行独立的行政网络。 互联网是一个互联网络,由许多不同运营商的网络组成(如企业、教育机构、军队等),这些运营商各自运行独立的行政网络。
@ -903,8 +926,8 @@ vi) Weisen Sie dem Interface router3.eth3 eine beliebige IPv6 Adresse zu. Ist de
vii) Konfigurieren Sie einen IP-Tunnel zwischen router1 und router2 und konfigurieren Sie die Systeme so, dass sämtliche IP-Nachrichten zwischen pc1 und pc2 durch den Tunnel übertragen werden! vii) Konfigurieren Sie einen IP-Tunnel zwischen router1 und router2 und konfigurieren Sie die Systeme so, dass sämtliche IP-Nachrichten zwischen pc1 und pc2 durch den Tunnel übertragen werden!
在 router1 和 router2 之间配置一个 IP 隧道,并将系统配置为通过该隧道传输 pc1 和 pc2 之间的所有 IP 消息! 在 router1 和 router2 之间配置一个 IP 隧道,并将系统配置为通过该隧道传输 pc1 和 pc2 之间的所有 IP 消息!
Hinweis: Benutzen Sie einen GRE-Tunnel, den Sie mit dem Programm ip einrichten. Hintergrundinformation zu GRE (Generic Routing Encapsulation) lesen Sie bitte in [RFC 2784] vor Durchführung des Versuchs nach; zur praktischen Nutzung finden Sie die Dokumentation in der Manpage ip-tunnel (8). Hinweis: Benutzen Sie einen GRE-Tunnel, den Sie mit dem Programm ip einrichten. Hintergrundinformation zu GRE (Generic Routing Encapsulation) lesen Sie bitte in [RFC 2784] vor Durchführung des Versuchs nach; zur praktischen Nutzung finden Sie die [Dokumentation](https://man7.org/linux/man-pages/man8/ip-tunnel.8.html) in der Manpage ip-tunnel (8).
提示:使用 ip 程序配置一个 GRE 隧道。请在实验前查阅 [RFC 2784] 中的 GRE通用路由封装背景信息实际使用的文档请参阅 ip-tunnel (8) 的手册页。 提示:使用 ip 程序配置一个 GRE 隧道。请在实验前查阅 [RFC 2784] 中的 GRE通用路由封装背景信息实际使用的文档请参阅 ip-tunnel (8) 的[手册页](https://man7.org/linux/man-pages/man8/ip-tunnel.8.html)
viii) Zeigen Sie mit traceroute, dass alle Nachrichten durch den Tunnel übertragen werden! viii) Zeigen Sie mit traceroute, dass alle Nachrichten durch den Tunnel übertragen werden!
使用 traceroute 验证所有消息通过隧道传输! 使用 traceroute 验证所有消息通过隧道传输!