温馨提示×

Linux中dhclient启动流程

小樊
44
2026-06-30 19:19:43
栏目: 智能运维

dhclientISC DHCP 客户端,在 Linux 中用于通过 DHCP 协议自动获取 IP 地址、路由、DNS 等网络配置。下面我按 从“程序启动”到“接口完成配置” 的顺序,系统地讲解 dhclient 的启动流程,并穿插关键源码/系统行为说明。


一、dhclient 是什么

  • 属于 ISC DHCP 套件
  • 用户态程序
  • 通过 原始套接字 / AF_PACKET 与 DHCP 服务器通信
  • 配置结果通常通过:
    • ioctl() / netlink 设置 IP
    • 调用 dhclient-script 完成后续配置(DNS、路由等)

二、dhclient 启动方式

1️⃣ 常见启动方式

dhclient eth0

或系统启动时由:

  • systemd-networkd
  • NetworkManager
  • init scripts
  • ifupdown

调用。


三、dhclient 启动流程(总体)

命令行解析
   ↓
读取配置文件
   ↓
初始化网络接口
   ↓
构建 DHCP 报文
   ↓
发送 DHCP DISCOVER
   ↓
接收 DHCP OFFER
   ↓
发送 DHCP REQUEST
   ↓
接收 DHCP ACK
   ↓
应用网络配置
   ↓
调用 dhclient-script
   ↓
进入租约维护阶段

四、详细流程解析


1️⃣ 参数解析与初始化

源码入口

main()   // client/dhclient.c

主要工作:

  • 解析参数:
    • -d(前台)
    • -v(verbose)
    • -cf(配置文件)
    • -lf(租约文件)
    • -pf(PID 文件)
  • 检查是否已有实例运行
  • 打开日志

2️⃣ 读取配置文件

配置文件

文件 作用
/etc/dhcp/dhclient.conf 用户配置
/var/lib/dhcp/dhclient.leases 租约信息

关键动作

  • 解析 dhclient.conf
  • 加载:
    • 请求的选项(如 request subnet-mask, routers, domain-name-servers;
    • 接口相关配置

3️⃣ 初始化网络接口

核心操作

  1. 打开 raw socket(AF_PACKET)
  2. 绑定到指定接口(如 eth0
  3. 设置接口为 UP
  4. 构造 DHCP 使用的源地址:
    • 源 IP:0.0.0.0
    • 目的 IP:255.255.255.255

关键代码

socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));

4️⃣ DHCP 协议交互(核心)

DHCP 状态机

INIT
 ↓
SELECTING
 ↓
REQUESTING
 ↓
BOUND

① DHCP DISCOVER

  • 广播发送
  • 目的端口:67
  • 源端口:68
Src: 0.0.0.0:68
Dst: 255.255.255.255:67

包含:

  • Client MAC
  • Transaction ID
  • 请求参数列表

② DHCP OFFER

  • 服务器响应
  • 提供:
    • IP 地址
    • 子网掩码
    • 网关
    • DNS

③ DHCP REQUEST

  • 客户端确认选择某个 OFFER
  • 广播发送(通知其他服务器)

④ DHCP ACK

  • 服务器确认
  • 客户端正式获得 IP

5️⃣ 应用网络配置

设置 IP / 路由

  • 使用:
    • ioctl(SIOCSIFADDR)
    • ioctl(SIOCSIFNETMASK)
    • ioctl(SIOCSIFBRDADDR)
  • 或 netlink(新版本)

设置接口 UP

ip addr add 192.168.1.100/24 dev eth0
ip link set eth0 up

6️⃣ 调用 dhclient-script(非常重要)

脚本路径

/etc/dhcp/dhclient-enter-hooks.d/
/etc/dhcp/dhclient-exit-hooks.d/
/sbin/dhclient-script

调用方式

dhclient-script <reason>

常见 reason:

reason 含义
BOUND 新获取 IP
RENEW 续租
REBIND 重新绑定
EXPIRE 租约过期
FAIL 失败

脚本中常见操作

  • 设置默认路由
  • 写入 /etc/resolv.conf
  • 修改 /etc/hosts

7️⃣ 租约管理与维护

租约保存

/var/lib/dhcp/dhclient.leases

租约时间

时间 行为
T1(50%) 尝试 RENEW
T2(87.5%) 尝试 REBIND
过期 EXPIRE

续租流程

  • 单播 REQUEST
  • 若失败 → 广播 REQUEST

8️⃣ 守护模式

  • 默认以 daemon 运行
  • 监听:
    • DHCP 响应
    • 信号(HUP、TERM)
  • 处理租约到期

五、关键系统调用总结

功能 系统调用
发包 sendto()
收包 recvfrom()
配置 IP ioctl() / netlink
脚本执行 fork() + exec()

六、常见调试方式

1️⃣ 前台运行

dhclient -d eth0

2️⃣ 抓包

tcpdump -i eth0 port 67 or port 68

3️⃣ 查看租约

cat /var/lib/dhcp/dhclient.leases

七、总结一句话

dhclient 启动后,通过 DHCP 协议与服务器交互获取 IP,然后利用 ioctl/netlink 配置接口,并通过 dhclient-script 完成 DNS、路由等系统级网络配置,同时维护 DHCP 租约生命周期。


如果你愿意,我也可以:

  • ✅ 画一张 dhclient 状态机图
  • ✅ 结合 systemd-networkd / NetworkManager 讲调用关系
  • ✅ 深入 源码函数级解析
  • ✅ 对比 dhclient vs systemd-networkd DHCP

你可以直接告诉我你关注哪一层。

0