DNS和ARP怎么实现?

HCRM技术_小炮 DNS 2026-01-31 201 2

我来详细解释 DNS 和 ARP 的实现原理:

DNS(域名系统)实现

**基本工作原理

目的:将域名(如 www.example.com)转换为 IP 地址(如 192.0.2.1)

分层结构:

  根域名服务器(.)
  │
  ├── 顶级域名服务器(.com, .org, .cn)
  │
  └── 权威域名服务器(example.com)
        │
        └── 具体记录(www.example.com → 192.0.2.1)

**DNS 查询过程

简化的 DNS 查询流程
def dns_lookup(domain):
    # 1. 检查本地缓存
    if domain in local_cache:
        return local_cache[domain]
    
    # 2. 检查 hosts 文件
    # 3. 查询本地 DNS 服务器
    # 4. 递归/迭代查询
    # 5. 获取结果并缓存

**DNS 报文格式

DNS 报文结构:
┌─────────────────┐
│   Header        │  # 事务ID、标志位、计数
├─────────────────┤
│   Question      │  # 查询的问题(域名、类型)
├─────────────────┤
│   Answer        │  # 资源记录(答案)
├─────────────────┤
│   Authority     │  # 权威服务器信息
├─────────────────┤
│   Additional    │  # 附加信息
└─────────────────┘

**DNS 记录类型

常见记录类型:
A记录     - IPv4地址
AAAA记录  - IPv6地址
CNAME记录 - 别名
MX记录    - 邮件服务器
NS记录    - 域名服务器
TXT记录   - 文本信息

**DNS 服务器实现示例

简化的 DNS 服务器代码结构
import socket
import struct
class DNSServer:
    def __init__(self):
        self.cache = {}
        self.records = {
            'www.example.com': {'type': 'A', 'value': '192.0.2.1'},
            'mail.example.com': {'type': 'MX', 'value': '10 mail.example.com'}
        }
    
    def parse_dns_query(self, data):
        # 解析 DNS 查询
        header = struct.unpack('!HHHHHH', data[:12])
        question = data[12:]
        
        # 提取域名
        domain_parts = []
        pos = 0
        while question[pos] != 0:
            length = question[pos]
            part = question[pos+1:pos+1+length]
            domain_parts.append(part.decode())
            pos += length + 1
        
        domain = '.'.join(domain_parts)
        return domain
    
    def create_response(self, domain):
        # 构建 DNS 响应
        # ... 实现响应构建逻辑
        pass
    
    def start(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        server.bind(('', 53))
        
        while True:
            data, addr = server.recvfrom(512)
            domain = self.parse_dns_query(data)
            response = self.create_response(domain)
            server.sendto(response, addr)

ARP(地址解析协议)实现

**基本工作原理

目的:将 IP 地址转换为 MAC 地址(物理地址)

ARP 表(缓存):存储 IP-MAC 映射

**ARP 工作流程

def arp_resolve(target_ip):
    # 1. 检查本地 ARP 缓存
    if target_ip in arp_cache:
        return arp_cache[target_ip]
    
    # 2. 发送 ARP 请求(广播)
    arp_request = create_arp_request(target_ip)
    send_broadcast(arp_request)
    
    # 3. 等待 ARP 响应
    response = wait_for_arp_response(timeout=5)
    
    # 4. 更新 ARP 缓存
    if response:
        arp_cache[target_ip] = response.mac_address
        return response.mac_address
    
    return None

**ARP 报文格式

以太网帧头部:
┌─────────────────┬─────────────────┬─────────┐
│ 目的MAC(6字节)  │ 源MAC(6字节)    │ 类型    │
├─────────────────┴─────────────────┴─────────┤
│ ARP 报文(28字节)                          │
│ ┌─────────────────────────────────────┐    │
│ │ 硬件类型(2) │ 协议类型(2)           │    │
│ ├─────────────────────────────────────┤    │
│ │ 硬件地址长度│ 协议地址长度           │    │
│ ├─────────────────────────────────────┤    │
│ │ 操作码(2)                           │    │
│ ├─────────────────────────────────────┤    │
│ │ 发送方MAC地址(6)                    │    │
│ ├─────────────────────────────────────┤    │
│ │ 发送方IP地址(4)                     │    │
│ ├─────────────────────────────────────┤    │
│ │ 目标MAC地址(6)                      │    │
│ ├─────────────────────────────────────┤    │
│ │ 目标IP地址(4)                       │    │
│ └─────────────────────────────────────┘    │
└─────────────────────────────────────────────┘

**ARP 实现示例

import socket
import struct
import time
class ARPProtocol:
    def __init__(self):
        self.arp_table = {}  # IP -> MAC 映射
        self.pending_requests = {}
    
    def create_arp_request(self, target_ip, src_ip, src_mac):
        """创建 ARP 请求包"""
        # 以太网帧头
        eth_header = struct.pack('!6s6sH',
            b'\xff\xff\xff\xff\xff\xff',  # 广播地址
            src_mac,                     # 源MAC
            0x0806)                      # ARP类型
        
        # ARP 报文
        arp_packet = struct.pack('!HHBBH6s4s6s4s',
            0x0001,     # 硬件类型:以太网
            0x0800,     # 协议类型:IPv4
            6,          # 硬件地址长度
            4,          # 协议地址长度
            1,          # 操作码:请求
            src_mac,    # 发送方MAC
            src_ip,     # 发送方IP
            b'\x00'*6,  # 目标MAC(未知)
            target_ip)  # 目标IP
        
        return eth_header + arp_packet
    
    def create_arp_reply(self, target_mac, target_ip, src_mac, src_ip):
        """创建 ARP 响应包"""
        eth_header = struct.pack('!6s6sH',
            target_mac,    # 目标MAC
            src_mac,       # 源MAC
            0x0806)        # ARP类型
        
        arp_packet = struct.pack('!HHBBH6s4s6s4s',
            0x0001,     # 硬件类型
            0x0800,     # 协议类型
            6,          # 硬件地址长度
            4,          # 协议地址长度
            2,          # 操作码:响应
            src_mac,    # 发送方MAC
            src_ip,     # 发送方IP
            target_mac, # 目标MAC
            target_ip)  # 目标IP
        
        return eth_header + arp_packet
    
    def handle_arp_packet(self, data, src_mac):
        """处理收到的 ARP 包"""
        # 解析 ARP 报文
        arp_fields = struct.unpack('!HHBBH6s4s6s4s', data[14:42])
        opcode = arp_fields[4]
        sender_mac = arp_fields[5]
        sender_ip = socket.inet_ntoa(arp_fields[6])
        target_ip = socket.inet_ntoa(arp_fields[9])
        
        # 更新 ARP 表
        self.arp_table[sender_ip] = sender_mac
        
        if opcode == 1:  # ARP 请求
            # 如果是询问我们的 IP,发送响应
            if target_ip == self.local_ip:
                reply = self.create_arp_reply(
                    sender_mac, sender_ip,
                    self.local_mac, self.local_ip
                )
                self.send_frame(reply)

5.Gratuitous ARP(免费 ARP)

def send_gratuitous_arp(ip, mac):
    """发送免费 ARP 宣告自己的 IP-MAC 映射"""
    # 源和目标 IP 都是自己的 IP
    arp_packet = create_arp_request(ip, ip, mac)
    send_broadcast(arp_packet)

关键差异总结

特性 DNS ARP
作用 域名→IP地址 IP地址→MAC地址
工作层次 应用层 网络层/链路层
传输协议 UDP/TCP(端口53) 直接封装在以太网帧中
缓存 DNS缓存(域名→IP) ARP缓存(IP→MAC)
查询范围 全局互联网 本地局域网
记录类型 A、AAAA、CNAME等 只有IP-MAC映射

实际部署考虑

DNS 部署:

1、递归解析器:为用户提供 DNS 查询服务

2、权威服务器:管理特定域名的记录

3、缓存策略:TTL 控制缓存时间

4、安全机制:DNSSEC 防止缓存投毒

ARP 部署:

1、ARP 表管理:定时清理老化条目

2、ARP 欺骗防护:静态 ARP 绑定、ARP 监控

3、代理 ARP:路由器代为响应 ARP 请求

这两个协议是网络通信的基础,DNS 负责全局地址解析,ARP 负责局域网内的地址解析,它们共同确保网络数据能够正确路由到目标设备。

文章摘自:https://idc.huochengrm.cn/dns/23356.html

评论

精彩评论
  • 2026-02-01 18:17:07

    DNS通过域名解析成IP地址,ARP通过IP地址查询物理地址,两者结合实现网络设备间通信。

  • 2026-04-18 06:19:49

    DNS通过域名解析成IP地址,ARP通过IP地址查询MAC地址实现。