udhcp源码详解(四)  之租赁IP的管理

小c学Linux(10)--DHCP服务 其实在之前动态获取IP地址的时候,我就在想一个问题:为什么主机没有IP地址,反而能够发送广播给DHCP服务器然后获得一个可用的IP?数据传输不是要通过网络层和运输层吗,没有IP也能传送数据到某个主机???一头雾水….. RARP协议 RARP协议(Reverse Address Resolution Protocol),反向地址转换协议。 反向地址转换协议就是将局域网中某个主机的物... 阅读详情

udhcp源码详解(四)             之租赁IP的管理

Author : hui <632254504@qq.com>

From : <http://blog.youkuaiyun.com/hui_love2046>

Created : 2010-10-4

 

       Server端对于租赁出去的IP的管理是基于结构体dhcpOfferedAddr的,该结构体的定义是在leases.c文件里:(结构体的成员介绍说明见详解之数据结构)

[cpp] view plain copy

  1. struct dhcpOfferedAddr {  
  2.     uint8_t chaddr[16];  
  3.     uint32_t yiaddr;    /* network order */  
  4.     uint32_t expires;   /* host order */  
  5. };  

 

在dhcpd.c文件里用该结构体定义指向该结构数组的指针leases;

/* dhcpd.c */

#include <leases.h>

       struct dhcpOfferedAddr *leases;

 

       在读取完配置信息server_config后,就可以依据配置信息的内存为该结构数组申请内存空间了:

 

[cpp] view plain copy

  1. /*  
  2.  * strut dhcpOfferedAddr { 
  3.  *  uint8_t     chaddr[16]; 
  4.  *  uint32_t    yiaddr;         //network order 
  5.  *  uint32_t    expires;        //host order 
  6.  * }; 
  7.  * 
  8.  * 该结构数组leases是记录租赁出去的IP,   yiaddr 
  9.  * 租赁IP客户机的MAC, charddr 
  10.  * 租赁的到期时间,expires(从1970年1月1日00:00:00到租赁到期的总共的秒数) 
  11.  * 
  12.  * dhcp server启动后(可能是异常重启) 
  13.  * 所以要充server_config.file里读取上次为哪些客户机分配了IP 
  14.  * 并把读取到的内容添加到leases数组里 
  15.  */  
  16. leases = xzalloc(server_config.max_leases * sizeof(struct dhcpOfferedAddr));  
  17. read_leases(server_config.lease_file);   
  18.        //server_config.lease_file = "/var/lib/misc/udhcpd.leases"  

 

 

 2).  查找租赁最早到期的租约:

 

[cpp] view plain copy

  1. /*  
  2.  * add a lease into the table, clearing out any old ones 
  3.  * add_lease是把MAC:chaddr, IP : yiaddr, expires: lease 
  4.  * 租赁信息添加到leases数组里 
  5.  * 函数首先调用clear_lease把数组里旧的删除掉(与chaddr or yiaddr相同的) 
  6.  * 从leases数组里找到最早到期的,再添加 
  7.  * 
  8.  * 返回oldest (NULL 表示未添加成功)  
  9.  */  
  10. struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)  
  11. {  
  12.     struct dhcpOfferedAddr *oldest;  
  13.   
  14.     /* clean out any old ones */  
  15.     clear_lease(chaddr, yiaddr);  
  16.    
  17.     /* 从leases数组里找到一个最早到期的oldest,以便添加新的 */  
  18.     oldest = oldest_expired_lease();  
  19.   
  20.     if (oldest) //oldest != NULL ,Found...  
  21.     {  
  22.         memcpy(oldest->chaddr, chaddr, 16);  
  23.         oldest->yiaddr = yiaddr;  
  24.   
  25.         /*  
  26.          * 函数的第三个参数,即lease,表示的是租赁的剩余时间 
  27.          * 在动态租赁数组leases里记录的租赁到期时间 
  28.          * 
  29.          * 所以 oldest->expires = time(0) + lease; 
  30.          */  
  31.         oldest->expires = time(0) + lease;  
  32.     }  
  33.   
  34.     return oldest;  
  35. }  

 

 

 

 

 3).  通过MAC或IP查找租约:

 

 

[cpp] view plain copy

  1. /* Find the first lease that matches chaddr, NULL if no match */  
  2. struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr)  
  3. {  
  4.     unsigned int i;  
  5.   
  6.     for (i = 0; i < server_config.max_leases; i++)  
  7.         if (!memcmp(leases[i].chaddr, chaddr, 16)) return &(leases[i]);  
  8.   
  9.     return NULL;  
  10. }  
  11.   
  12. /* Find the first lease that matches yiaddr, NULL is no match */  
  13. struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr)  
  14. {  
  15.     unsigned int i;  
  16.   
  17.     for (i = 0; i < server_config.max_leases; i++)  
  18.         if (leases[i].yiaddr == yiaddr) return &(leases[i]);  
  19.   
  20.     return NULL;  
  21. }  

 

 

 4).  检查IP addr是否被网络中主机所使用,若被使用的话添加到leases数组里:

 

 

[cpp] view plain copy

  1. /* 
  2.  * check is an IP is taken, if it is, add it to the lease table 
  3.  * 
  4.  * 检查addr is a free IP(网络中是否有主机使用addr) 
  5.  * if addr is a used IP, 把addr添加到租赁数组里 
  6.  * 
  7.  *  1. 返回0 表示addr 是a free IP 
  8.  *  2. 返回1表示addr已被网络中的某台主机使用了 
  9.  *      并且把使用addr的主机添加到leases数组里 
  10.  *      其中MAC: blank_chaddr, IP: addr, expires: server_config.confict_time(def: 3600sec) 
  11.  * 
  12.  */  
  13. static int check_ip(uint32_t addr)  
  14. {  
  15.     struct in_addr temp;  
  16.   
  17.     /* arpping()返回0表示addr used */  
  18.     if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) {  
  19.         temp.s_addr = addr;  
  20.         LOG(LOG_INFO, "%s belongs to someone, reserving it for %ld seconds",  
  21.             inet_ntoa(temp), server_config.conflict_time);  
  22.   
  23.         /* 
  24.          * 因为刚在未在leases数组里找到这个已被used 的IP 
  25.          * 所以要把这个used IP添加到leases数组里 
  26.          * 租赁客户机MAC 为blank_chaddr(黑户) 
  27.          * 租赁的IP即used IP(addr) 
  28.          * 租赁时间:server_config.conflict_time 
  29.          */  
  30.         add_lease(blank_chaddr, addr, server_config.conflict_time);  
  31.         return 1;  
  32.     } else return 0;  
  33. }  

 

5)  从可用IP地址池里找到一个可用的IP(a Free IP)

uint32_t    find_address(int check_expire);

 

该函数的调用是在,server端接收到DHCPDISOCVER的报文的时候,会为client提供一个IP地址:

a)       server首先利用client的MAC地址在leases数组里查找该client以前是否在这里租赁过IP,租赁过的话,把以前的IP提供给client

b)      第一种情况不满足的话,server会检查DHCPDISCOVER报文的选项字段,client是否有请求的IP(该选项信息的CODE :DHCP_REQUESTED_IP),有的话检查该IP是否为Free,可以的话把Request IP提供给client。

c)      上面两种情况都不满足的话,就调用find_address这个函数了。

 

[cpp] view plain copy

  1. /* 
  2.  * find an assignable address, it check_expired is true, 
  3.  * we check all the expired leases as well. 
  4.  * Maybe this should try expired leases by age... 
  5.  * 
  6.  * 找到一个可分配的IP,如果check_expired is true, 
  7.  * 会检查所有到期租约 
  8.  * find_address()函数找到free IP 返回IP的值(network order) 
  9.  * 未找到返回0 
  10.  *  
  11.  */  
  12. uint32_t find_address(int check_expired)  
  13. {  
  14.     uint32_t addr, ret;  
  15.     struct dhcpOfferedAddr *lease = NULL;  
  16.   
  17.     /* 
  18.      * 在端上进行计算比较的时候使用 host order 
  19.      * 一般存储的时候采用 network order 
  20.      * 
  21.      * 遍历整个可分配地址server_config.start -- server_config.end 
  22.      */  
  23.          /* addr is in host order here */  
  24.     addr = ntohl(server_config.start);  
  25.     for (;addr <= ntohl(server_config.end); addr++)   
  26.     {  
  27.         /* ie, 192.168.55.0 */  
  28.         if (!(addr & 0xFF)) continue;  
  29.   
  30.         /* ie, 192.168.55.255 */  
  31.         if ((addr & 0xFF) == 0xFF) continue;  
  32.   
  33.         /*  
  34.          * Only do if it isn't  
  35.                  * an assigned as a static lease 
  36.          * rexervedIP()检查addr是否在静态租赁链表里 
  37.          * addr在静态链表的话,函数返回1,反之返回0 
  38.          */  
  39.         if(!reservedIp(server_config.static_leases, htonl(addr)))  
  40.         {  
  41.             /* lease is not taken */  
  42.             ret = htonl(addr);  
  43.   
  44.             /* !(lease = find_lease_by_yiaddr(ret)) 地址addr是否已被租赁出去了 */  
  45.             if ((!(lease = find_lease_by_yiaddr(ret)) ||  
  46.   
  47.                     /*  
  48.                      * or it expired and we are checking for expired leases 
  49.                  * or 租赁出去的话, 
  50.                  * addr是否是a free IP还取决与 
  51.                  * lease_expired(lease)是否已到期和check_expired 
  52.                  *  
  53.                      */  
  54.                     (check_expired  && lease_expired(lease))) &&  
  55.   
  56.                     /*  
  57.                      * and it isn't on the network 
  58.                      * 如果addr满足上面两个条件的其中一个 
  59.                      * 1.!(lease = find_lease_by_yiaddr(ret)) 没有被租赁出去                    * 2.(check_expired && lease_expired(lease)) 已被租赁出去了, 
  60.                      * 但租赁过期了(check_expired == ture) 
  61.                      * 
  62.                      * addr 满足上面条件之一,还要检查addr是否被网络上其他主机使用 
  63.                      *  
  64.                      * check_ip() 发送arp Request包确认addr是否被使用 
  65.                      * 返回0, addr is a free IP 
  66.                      */  
  67.                     !check_ip(ret))   
  68.             {  
  69.             return ret;  
  70.             break;  
  71.             }  
  72.         }  
  73.     }  
  74.     return 0;  
  75. }  
24-Openwrt dnsmasq dnsmasq是openwrt一个重要的进程,里面提供了两个重要的功能。一个是dhcp server,给lan口使用的,另一个是dns功能,维护路由器的dns信息,而且支持ipv4和ipv6。 1、 dnsmasq启动过程 从/etc/init.d/dnsmasq start脚本启动 root@Openwrt:/# cat /etc/config/dhcp config dnsmasq option domainneeded '1' option boguspriv '. 阅读详情

相关推荐

vivado生成及调用自定义IP的方法

开发环境:vivado 2018.2 1.将整个工程封装为自定义IP 将整个工程封装为自定义IP主要有以下步骤: 步骤1.选中工程中的top模块。点击Tools ------> Create and Package New IP,如图1所示 图1 步骤2.弹出界面后,点击next至图2界面,选择Package your current project,然后继续点击next 图2 步骤3.选择生成的IP路径,如图3所示。这个路径就是后续添加该IP的路径 图3 步骤4.继续点击next,然后选择fi

进击的阿日比 4730

基于嵌入式linux的DHCP服务器的搭建与移植(udhcp)

DHCP包括DHCP服务器和DHCP客户端两种模式,其中DHCP服务器用于设置IP分配规则、IP分配范围等管理功能;DHCP客户端提出分配请求,自动获得IP地址。本节介绍基于arm64的嵌入式linux移植udhcp搭建DHCP服务器的详细过程。本文采用udhcp源码压缩包进行aarch64交叉编译移植,并利用计算机作为客户端进行测试。在ft2004的嵌入式linux上实测可用。

q544344318的博客 4076

电容式麦克风:从原理到实际电路波形解析

本文深入解析电容式麦克风的工作原理,从核心的振膜与背板结构、电荷锁定机制到场效应管放大器的作用。通过实物拆解与等效电路分析,阐明声音振动如何转换为电压信号,并指导如何用示波器实测波形,直观展现声电转换过程,适合电子爱好者和音频技术学习者。

Black的专栏 1080

udhcp源码详解(四) 之租赁IP的管理

Server端对于租赁出去的IP的管理是基于结构体dhcpOfferedAddr的,该结构体的定义是在leases.c文件里:(结构体的成员介绍说明见详解之数据结构) [cpp] view plaincopy struct dhcpOfferedAddr { uint8_t chaddr[16]; uint32_t yiaddr; /* netw...

weixin_34087301的博客 561

Wireshark抓包分析:如何从HTTP流量中快速定位黑客攻击痕迹(附pcap文件)

本文通过Wireshark实战,详细解析了如何从HTTP流量中快速定位黑客攻击痕迹。文章提供了核心过滤策略,并重点剖析了如何识别SQL注入攻击的流量特征、揭露WebShell的隐蔽通信以及追踪攻击者在横向移动中的行为,帮助安全人员系统性地从pcap文件中还原完整攻击链。

sprite的博客 1009

科研ABC - The Results Section(SCI论文写作补充)

1 前言 1.1 IMRD格式 1.2 Results部分意义 1.3 Results部分主要内容 2 Results & Discussion关系 2.1 Results & Discussion部分的搭配方式 2.2 Results & Discussion部分的区分 3 Results部分的结构 3.1 Move 1: Set the Stage 3.1....

洋洋洋2020的blog 1621

C语言读取DHCP数据包(pcap文件)内容

/pacp文件头结构体//识别文件和字节顺序:小端/大端模式//主版本号//次版本号//当地的标准时间//时间戳精度//最大的存储长度//链路类型//时间戳//时间戳高位,精确到seconds//时间戳地位,精确到microseconds//pcap数据包头结构体//捕获时间//数据帧/区的长度//离线数据长度//数据链路层数据//源MAC地址//目的MAC地址//帧类型}DL_Header;//IP数据报头//版本+报头长度u_int8 TOS;

sakura0908的博客 2303

LPDDR5 物理层一致性测试(连载・下):电平、过冲下冲与 Rx 接收眼图 Mask 掩模完整指标解读

本文系统梳理LPDDR5物理层一致性测试全流程,涵盖差分/单端电平、边沿斜率、交叉点电压、过冲下冲及CS/CA/DQ接收眼图掩模(Rx Mask)测试,详解各参数定义与工程实操要点。强调配置需与DRAM MR寄存器同步,突出差分≠合格、面积积分不可忽视、掩模失败优先排查参考电压与信号完整性等高频坑点,为硬件调试与SI工程师提供权威参考。

一只豌豆象的博客 42

openwrt 显示客户端client 连接的信息 /proc/net/arp /tmp/dhcp.leases

显示当前路由器上,client的name,ip,mac,connect_type信息 有两种方式:来自链接 一。通过DHCP client分配列表 (缺点:client列表会根据超时时间刷新,一般超时时间为12h,) 二。通过arp缓存列表/proc/net/arp(缺点:arp刷新时间默认为30s,这个时间的误差可以接受。) 主要讲解第二种方法: Flags: 0x0是找不到这台主...

linbounconstraint的专栏 1万+

卫星遥感影像处理:地物分类与变化检测

卫星遥感影像处理:地物分类与变化检测​ ,人工智能,计算机视觉,大模型,AI,卫星遥感技术通过搭载在卫星上的传感器获取地球表面的电磁波信息,为地物分类与变化检测提供了宏观、动态的观测数据。随着高分辨率遥感卫星(如高分系列、哨兵系列)的发展,遥感影像的空间分辨率、光谱分辨率和时间分辨率不断提升,为精准地物识别和动态变化监测奠定了基础。地物分类旨在将遥感影像中的像元按地表覆盖类型(如植被、水体、建筑、农田等)进行分类,而变化检测则通过对比不同时期的影像,识别地表覆盖的变化区域(如城市扩张、森林砍伐、土地退化等)

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 17万+

运行openclaw gateway install时出现Gateway install failed: Error: schtasks create failed的解决方案

本文主要介绍了运行openclaw gateway install时出现Gateway install failed: Error: schtasks create failed的解决方案,希望能对学习和使用openclaw的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 11万+

udhcp源码详解(四)

udhcp源码详解(四)             之租赁IP的管理Author : hui From : Created : 2010-10-4       Server端对于租赁出去的IP的管理是基于结构体dhcpOfferedAddr的,该结构体的定义是在leases.c文件里:(结构体的成员介绍说明见详解之数据结构)struct dhcpOfferedAddr { uint8_t chaddr[16]; uint32_t yiaddr; /* network order */ uint32

前进路上的点滴 5811

【Python机器学习】零基础掌握RFECV特征选择

通过应用算法,有效地识别了影响购买意愿的关键特征(浏览时长和点击数)和历史货币流通的主要因素(年代、人口和货币流通量)。这样的特征选择不仅提高了模型的解释能力,还可能用于电商推荐系统和历史研究的优化。优点总结,这种方法可以高效地找出对目标变量有最大影响的特征,进而可以用于各种实际应用场景,如电商推荐和历史研究。优点名称对应描述说明高解释性易于理解哪些特征最为重要泛化性能强通过交叉验证提高模型的稳健性应用场景多样可用于电商、金融、历史研究等多个领域。

Mr数据杨 1996

udhcp源码详解(三)上   之配置信息的读取

udhcp源码详解(三)上之配置信息的读取 Author : hui<632254504@qq.com> From :<http://blog.csdn.net/hui_love2046> Created : 2010-10-3 上节介绍了存储管理配置信息的结构体struct server_config_t,该结构体...

echo 675

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

udhcp源码详解(三) 上

<br />udhcp源码详解(三)上             之配置信息的读取<br />Author : hui <632254504@qq.com><br />From : <http://blog.csdn.net/hui_love2046><br />Created : 2010-10-3<br /> <br />       上节介绍了存储管理配置信息的结构体struct server_config_t,该结构体贯穿整个server端程序的运行。<br />在dhcpd.c里的用该结构体定义个一

前进路上的点滴 5096

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

udhcp源码详解(二)

udhcp源码详解(二)             之定义的结构体 Author : hui  From :  Created : 2010-10-2     ---   2010-10-3   定义的数据结构对于C程序的重要性,不言而喻。面向对象设计的程序是一个个对象的集合,而面向过程语言设计的程序则是数据结构与算法的集合。 下面来分析的是dhcp server中的定义结构体:  

eydwyz的专栏 910

udhcp源码详解(二)--转

定义的数据结构对于C程序的重要性,不言而喻。面向对象设计的程序是一个个对象的集合,而面向过程语言设计的程序则是数据结构与算法的集合。 下面来分析的是dhcp server中的定义结构体: 1)、在packet.h文件里定义了DHCP报文的格式: struct dhcpMessage报文的字段虽然都有注释,但还是有必要讲下options字段。 options在大多文档中的说法是可选字...

weixin_33674976的博客 190

udhcp源码详解(三)上 之配置信息的读取

上节介绍了存储管理配置信息的结构体struct server_config_t,该结构体贯穿整个server端程序的运行。 在dhcpd.c里的用该结构体定义个一个全局的变量: struct server_config_t server_config; 在server启动做的第一件事就是初始化这个全局变量server_config: 现在就进入read_config

zou_J_L专栏 801

6个月转行机器人工程师:从零到项目落地的完整实战路线

机器人工程师本质上是机械、电气、软件与算法的系统集成者,真正的核心竞争力在于将各模块高效串联并解决实际问题的能力。从基础概念出发,理解ROS 2作为机器人软件通信框架的核心原理,掌握PID控制、坐标变换、建图导航等关键技术,是快速进入该行业的有效路径。这类技能不仅在移动抓取、自动巡检等应用场景中具有直接价值,也是企业筛选应用型人才的重点考察方向。对转行者而言,与其追求理论体系的完备,不如以具体项目为牵引,缺什么补什么,在实践中建立系统感知。通过6个月分阶段的项目实操,从单片机小车到激光雷达建图与导航,再到机

weixin_34128839的博客 541

linux中DHCP服务配置

DHCP: Dynamic Host Configuration Protocol lease:租约 报文: 首次获取IP地址(广播包) client 向服务器端发送DHCPDISCOVER 的UDP报文 server端回应 DHCPOFFER报文 client 发送DHCPREQUEST报文,向服务器请求使用该报文 server端发送DHCPACK 报文,发送确认报文 续租(单...

miner_k的博客 2万+

openwrt清理已分配的 DHCP 租约

【代码】openwrt清理已分配的 DHCP 租约。

cloudfly的博客 6599

dhcp租约(dhcp租约时间可设置为永久吗)

如何理解DHCP服务器中“地址租约期限”? 简单点讲就是你获取这个ip地址之后能使用的期限,如果你一直都是用这个ip,那么即使到了租约期限,自动重新获取的时候也会优先获得这个ip,但当你这个ip有很长一段时间没有使用,那么你下次获取的时候将会是另一个地址 dhcp租约多久合适? 可将租约时间设置为一天或半天,如果...

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 1万+

从dhcpd.lease中提取MAC和IP地址.

从DHCP的log中提取MAC和IP地址. /var/lib/dhcpd/dhcp.lease中的一段记录如下: lease 192.168.1.238 { starts 0 2007/11/25 11:57:41; ends 0 2007/11/25 17:57:41; tstp 0 2007/11/25 17:57:41; binding state f...

weixin_33749242的博客 527
上一篇: udhcp源码详解(三)下   之配置信息的读取
下一篇: udhcp源码详解(五) 之DHCP包--options字段
JIANXIN.Y
博客等级 码龄9年 273粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值