首页 > 编程语言 >DHCP源码分析-dhcp模块

DHCP源码分析-dhcp模块

时间:2023-02-17 17:55:05浏览次数:36  
标签:subnet option IP packet client 源码 dhcp DHCP lease


一, DHCP函数流程

 

 

 

函数void dhcp (struct packet *packet)是处理DHCP包的入口函数,在进入这个函数的时候,对包的解析已经完成,已经将包的内容转换成内部结构struct packet。dhcp()函数主要做的工作就是对不同的packet -> packet_type对应的包进行处理。

二, locate_network()流程分析

进入dhcp函数,首先就是调用int locate_network (struct packet *packet)来确定client所属subnet,以便从这个subnet下分配正确的IP。

1,查找link selection和subnet selection options
if ((oc = lookup_option(&agent_universe, packet->options, RAI_LINK_SELECT)) == NULL)
oc=lookup_option(&dhcp_universe,packet->options, DHO_SUBNET_SELECTION);
首先,先查找DHCP包中是否有relay-agent-option下linkselection sub-option,这个option用于当client与server处于不同网段,需要DHCP relay转发时,client想要得到一个relay agent不同网段的IP。具体信息请参考RFC 3527。

如果没有该option,就继续在包中查找subnet selection option。这个option用于在client与server同一网段的情况下,client需要获得不同网段的IP,具体信息参考RFC3011。

这两个option在功能上有相似之处,都是client要求获得一个指定网段的IP。不同之处在于,relay-agent-option是用于DHCP relay的,也就说DHCP包是通过relay转发到server端的,client与server处于不同的物理网段。而subnet selection option,是client与server处于同一个物理网段,但是想要获得不同网段的IP,而由client将这个option加入到DHCP包中。

 

2,使用网卡所在网段为预分配的subnet

if (!oc && !packet -> raw -> giaddr.s_addr) {
if (packet -> interface -> shared_network) {
shared_network_reference
(&packet -> shared_network,
packet -> interface -> shared_network, MDL);
return 1; }
return 0; }
如果没有找到这两个option,那么通过packet -> raw -> giaddr.s_addr来判断这个包是否是由relay转发过来的。packet -> raw -> giaddr.s_addr是relay的地址,由relay填写。如果不是转发过来的包,那么到此就可以确定client与server同一网段,并且没有要求不同网段的IP。那么就确定了接收到该包网卡所属的网段,为分配IP的网段,并赋给packet->shared_network。

3,使用option或relay地址确定subnet
if (oc) {
memset (&data, 0, sizeof data);
if (!evaluate_option_cache (&data, packet, (struct lease *)0, (struct client_state *)0,packet -> options,
(struct option_state *)0,&global_scope, oc, MDL))
{ return 0; }
if (data.len != 4)
{ return 0; }
ia.len = 4;
memcpy (ia.iabuf, data.data, 4);
data_string_forget (&data, MDL);
}
else {
ia.len = 4;
memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);}
if (find_subnet (&subnet, ia, MDL)) {
shared_network_reference (&packet -> shared_network,subnet -> shared_network, MDL);
subnet_dereference (&subnet, MDL);
return 1;
}


在没有前面两个option的情况下,server将通过packet -> raw -> giaddr来确定分配IP的subnet。

通过对locate_network的分析,我们可以确定subnet选择因素的优先级为

linkselection sub-option > subnet selection option > relay address > 网卡的subnet

三, find_lease()流程分析

 

 

函数dhcpdiscover通过调用find_lease来确定分配哪个IP给client。

1, 通过client identifer或hardware确定host

首先sever会尝试用DHCP请求中的client identifer或者hardware来确定该请求是否来自于一个配置文件指定的host。(通常当client的管理员没有指定client indentifier的时候,client会把自己的网卡的MAC地址作为client identifer发给server。)
通过find_hosts_by_uid(&hp,client_identifier.data, client_identifier.len, MDL)来使用client identifier找到host即hp,通过find_hosts_by_haddr(&hp,packet->raw->htype, packet->raw->chaddr, packet->raw->hlen,MDL)来使用MAC地址来找到host。找到host后,通过host尝试查找fixedlease——即在配置文件的host中,指定的IP地址。这是通过mockup_lease (&fixed_lease, packet, share, host)这个函数实现的。这里注意的是,传入参数share为预分配IP的subnet。将它作为参数,是为了排除不在该subnet中的fixed ip,即使这个IP是host的指定IP。

其实除了使用clientindentifer和MAC地址来查找host的方式外,还支持通过指定option来查找host,这种用法并不常见。

通过host确定的IP,在ISC DHCP中被称为fixedIP,其对应的lease自然被称为fixedlease。


2,通过client identifier获得fixed lease
if (find_hosts_by_uid (&hp, client_identifier.data,client_identifier.len, MDL)) {
/* Remember if we know of this client. */
packet -> known = 1;
mockup_lease (&fixed_lease, packet, share, hp);
}

在通过host来确定要分配IP的同时,也会使用函数find_lease_by_uid(&uid_lease,client_identifer.data, client_identifier.len, MDL)和find_lease_by_hw_addr(&hw_lease, h.hbuf, h.hlen,MDL)来直接通过client_identifier和MAC地址确定lease。
在代码中,有两个lease的hash表,分别以client identifier和hardware address为key。从这里可以看出,DHCP server一般情况下,都是会给client上次同样的IP。


3,获得client的请求地址
client除了被动的接受server给分配的IP,它还可以主动向server提出要求,要求想要得到的IP。这是通过client在DHCP包中的client地址,或者使用requestedaddress option来实现的。

if (packet -> raw -> ciaddr.s_addr)
{cip.len = 4;
memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
}
else
{/* Look up the requested address. */
oc = lookup_option (&dhcp_universe, packet -> ptions,DHO_DHCP_REQUESTED_ADDRESS);
memset (&d1, 0, sizeof d1);
if (oc &&evaluate_option_cache (&d1, packet, (struct lease *)0,(struct client_state *)0,packet -> options,(struct option_state *)0,&global_scope, oc, MDL))
{packet -> got_requested_address = 1;
cip.len = 4;
memcpy (cip.iabuf, d1.data, cip.len);
data_string_forget (&d1, MDL);
}else
cip.len = 0;
}


server会使用这个cip来分配一个lease,然后再通过一系列检查来判断是否可以使用这个lease。在不与其他配置的不冲突的情况下,尽量满足client的要求,分配给其要求的IP。
确定分配IP的优先级是fixed lease > uid lease > hw lease > ip lease,其 fixed lease是配置文件中host所配置的lease,uid lease 是通过uid确定的lease,hw lease是通过硬件地址查找到的lease,ip lease是client希望请求得到的lease。


四, DISCOVER报文的处理流程

 

 

标签:subnet,option,IP,packet,client,源码,dhcp,DHCP,lease
From: https://www.cnblogs.com/dhcpclass/p/17131070.html

相关文章

  • ISC DHCP租约分析
    租约状态转换DHCP服务系统中的租约共有八种状态:空闲状态、预留状态、活跃状态、过期状态、释放状态、废弃状态、重置状态、备份状态。重置状态和备份状态为启动FAILOVER模......
  • 2、HashMap源码分析
    目录1一般数据结构及特点2HashMap基本属性说明3HashMap数据结构3.1构造函数3.2Node<k,v>分析4put过程分析4.1扩容方法resize()分析4.2put方法分析5关于HashMap5.1......
  • qiankun 2.x 运行时沙箱 源码分析
    qiankun2.x运行时沙箱源码分析简介从源码层面详细讲解了qiankun框架中的JS沙箱和样式沙箱的实现原理。序言沙箱这个词想必大家应该不陌生,即使陌生,读完这篇文......
  • linux源码解析12–page数据结构
    几个问题:1.当开启了MMU之后,CPU访问内存的最小单位是多少呢?page2.linux怎样描述这个页呢?3.linux内核里,怎么理解和使用这个页?linux内核用stuctpage来描述一个物理页面:1......
  • Callable的基本使用和源码解读
    1使用java.util.concurrent.Callable是有返回值的多线程任务:publicinterfaceCallable<V>{Vcall()throwsException;}通过实现Callable接口,在call()方......
  • CyclicBarrier源码解析
    CyclicBarrier源码解析描述:一个同步帮助,允许一组线程互相等待到达一个共同的屏障点。Cyclicbarrier在涉及固定大小的线程组的程序中非常有用,这些线程必须偶尔相互等待。......
  • CountDownLatch源码解析
    CountDownLatch源码解析描述:一种同步辅助工具,允许一个或多个线程等待在其他线程中执行的一组操作完成。用给定的count初始化CountDownLatch。因为调用了countDown()......
  • Llvm 源码结构及测试基础
    Llvm源码结构及测试基础Llvm源码目录功能简介了解一下Llvm源码工程目录介绍、Llvm相关lib库的介绍、Llvm生成的工具链介绍,方便我们后期学习Llvm。LLVM源码工程目录介......
  • 深入探索Android 启动优化(七) - JetPack App Startup 使用及源码浅析
    本文首发我的微信公众号:徐公,想成为一名优秀的Android开发者,需要一份完备的知识体系,在这里,让我们一起成长,变得更好~。前言前一阵子,写了几篇Android启动优化的文章......
  • SpringMVC源码(八):Controller控制器执行流程
    在MVC请求流程中,获取到HandlerAdapter适配器后,会执行handler处理器(Controller控制器)的相关逻辑,通过适配器的handle()方法,完成目标Controller处理器的调用。在源码(七......