日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 udhcp源码详解(四) 之租赁IP的管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Server端對于租賃出去的IP的管理是基于結構體dhcpOfferedAddr的,該結構體的定義是在leases.c文件里:(結構體的成員介紹說明見詳解之數據結構)

[cpp] view plaincopy

  • struct dhcpOfferedAddr {?
  • ??? uint8_t chaddr[16];?
  • ??? uint32_t yiaddr;??? /* network order */
  • ??? uint32_t expires;?? /* host order */
  • };?
  • 在dhcpd.c文件里用該結構體定義指向該結構數組的指針leases;

    /* dhcpd.c */

    #include <leases.h>

    struct dhcpOfferedAddr *leases;

    在讀取完配置信息server_config后,就可以依據配置信息的內存為該結構數組申請內存空間了:

    [cpp] view plaincopy

  • /*
  • * strut dhcpOfferedAddr {
  • *? uint8_t???? chaddr[16];
  • *? uint32_t??? yiaddr;???????? //network order
  • *? uint32_t??? expires;??????? //host order
  • * };
  • *
  • * 該結構數組leases是記錄租賃出去的IP,?? yiaddr
  • * 租賃IP客戶機的MAC, charddr
  • * 租賃的到期時間,expires(從1970年1月1日00:00:00到租賃到期的總共的秒數)
  • *
  • * dhcp server啟動后(可能是異常重啟)
  • * 所以要充server_config.file里讀取上次為哪些客戶機分配了IP
  • * 并把讀取到的內容添加到leases數組里
  • */
  • leases = xzalloc(server_config.max_leases * sizeof(struct dhcpOfferedAddr));?
  • read_leases(server_config.lease_file);??
  • //server_config.lease_file = "/var/lib/misc/udhcpd.leases"
  • 2). 查找租賃最早到期的租約:

    [cpp] view plaincopy

  • /*
  • * add a lease into the table, clearing out any old ones
  • * add_lease是把MAC:chaddr, IP : yiaddr, expires: lease
  • * 租賃信息添加到leases數組里
  • * 函數首先調用clear_lease把數組里舊的刪除掉(與chaddr or yiaddr相同的)
  • * 從leases數組里找到最早到期的,再添加
  • *
  • * 返回oldest (NULL 表示未添加成功)
  • */
  • struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)?
  • {?
  • struct dhcpOfferedAddr *oldest;?
  • /* clean out any old ones */
  • ??? clear_lease(chaddr, yiaddr);?
  • /* 從leases數組里找到一個最早到期的oldest,以便添加新的 */
  • ??? oldest = oldest_expired_lease();?
  • if (oldest) //oldest != NULL ,Found...
  • ??? {?
  • ??????? memcpy(oldest->chaddr, chaddr, 16);?
  • ??????? oldest->yiaddr = yiaddr;?
  • /*
  • ???????? * 函數的第三個參數,即lease,表示的是租賃的剩余時間
  • ???????? * 在動態租賃數組leases里記錄的租賃到期時間
  • ???????? *
  • ???????? * 所以 oldest->expires = time(0) + lease;
  • ???????? */
  • ??????? oldest->expires = time(0) + lease;?
  • ??? }?
  • return oldest;?
  • }?
  • 3). 通過MAC或IP查找租約:

    [cpp] view plaincopy

  • /* Find the first lease that matches chaddr, NULL if no match */
  • struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr)?
  • {?
  • ??? unsigned int i;?
  • for (i = 0; i < server_config.max_leases; i++)?
  • if (!memcmp(leases[i].chaddr, chaddr, 16)) return &(leases[i]);?
  • return NULL;?
  • }?
  • /* Find the first lease that matches yiaddr, NULL is no match */
  • struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr)?
  • {?
  • ??? unsigned int i;?
  • for (i = 0; i < server_config.max_leases; i++)?
  • if (leases[i].yiaddr == yiaddr) return &(leases[i]);?
  • return NULL;?
  • }?
  • 4). 檢查IP addr是否被網絡中主機所使用,若被使用的話添加到leases數組里:

    [cpp] view plaincopy

  • /*
  • * check is an IP is taken, if it is, add it to the lease table
  • *
  • * 檢查addr is a free IP(網絡中是否有主機使用addr)
  • * if addr is a used IP, 把addr添加到租賃數組里
  • *
  • *? 1. 返回0 表示addr 是a free IP
  • *? 2. 返回1表示addr已被網絡中的某臺主機使用了
  • *????? 并且把使用addr的主機添加到leases數組里
  • *????? 其中MAC: blank_chaddr, IP: addr, expires: server_config.confict_time(def: 3600sec)
  • *
  • */
  • static int check_ip(uint32_t addr)?
  • {?
  • struct in_addr temp;?
  • /* arpping()返回0表示addr used */
  • if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) {?
  • ??????? temp.s_addr = addr;?
  • ??????? LOG(LOG_INFO, "%s belongs to someone, reserving it for %ld seconds",?
  • ??????????? inet_ntoa(temp), server_config.conflict_time);?
  • /*
  • ???????? * 因為剛在未在leases數組里找到這個已被used 的IP
  • ???????? * 所以要把這個used IP添加到leases數組里
  • ???????? * 租賃客戶機MAC 為blank_chaddr(黑戶)
  • ???????? * 租賃的IP即used IP(addr)
  • ???????? * 租賃時間:server_config.conflict_time
  • ???????? */
  • ??????? add_lease(blank_chaddr, addr, server_config.conflict_time);?
  • return 1;?
  • ??? } else return 0;?
  • }?
  • 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 plaincopy

  • /*
  • * find an assignable address, it check_expired is true,
  • * we check all the expired leases as well.
  • * Maybe this should try expired leases by age...
  • *
  • * 找到一個可分配的IP,如果check_expired is true,
  • * 會檢查所有到期租約
  • * find_address()函數找到free IP 返回IP的值(network order)
  • * 未找到返回0
  • *
  • */
  • uint32_t find_address(int check_expired)?
  • {?
  • ??? uint32_t addr, ret;?
  • struct dhcpOfferedAddr *lease = NULL;?
  • /*
  • ???? * 在端上進行計算比較的時候使用 host order
  • ???? * 一般存儲的時候采用 network order
  • ???? *
  • ???? * 遍歷整個可分配地址server_config.start -- server_config.end
  • ???? */
  • /* addr is in host order here */
  • ??? addr = ntohl(server_config.start);?
  • for (;addr <= ntohl(server_config.end); addr++)??
  • ??? {?
  • /* ie, 192.168.55.0 */
  • if (!(addr & 0xFF)) continue;?
  • /* ie, 192.168.55.255 */
  • if ((addr & 0xFF) == 0xFF) continue;?
  • /*
  • ???????? * Only do if it isn't
  • ???????????????? * an assigned as a static lease
  • ???????? * rexervedIP()檢查addr是否在靜態租賃鏈表里
  • ???????? * addr在靜態鏈表的話,函數返回1,反之返回0
  • ???????? */
  • if(!reservedIp(server_config.static_leases, htonl(addr)))?
  • ??????? {?
  • /* lease is not taken */
  • ??????????? ret = htonl(addr);?
  • /* !(lease = find_lease_by_yiaddr(ret)) 地址addr是否已被租賃出去了 */
  • if ((!(lease = find_lease_by_yiaddr(ret)) ||?
  • /*
  • ???????????????????? * or it expired and we are checking for expired leases
  • ???????????????? * or 租賃出去的話,
  • ???????????????? * addr是否是a free IP還取決與
  • ???????????????? * lease_expired(lease)是否已到期和check_expired
  • ???????????????? *
  • ???????????????????? */
  • ??????????????????? (check_expired? && lease_expired(lease))) &&?
  • /*
  • ???????????????????? * and it isn't on the network
  • ???????????????????? * 如果addr滿足上面兩個條件的其中一個
  • ???????????????????? * 1.!(lease = find_lease_by_yiaddr(ret)) 沒有被租賃出去??????????????????? * 2.(check_expired && lease_expired(lease)) 已被租賃出去了,
  • ???????????????????? * 但租賃過期了(check_expired == ture)
  • ???????????????????? *
  • ???????????????????? * addr 滿足上面條件之一,還要檢查addr是否被網絡上其他主機使用
  • ???????????????????? *
  • ???????????????????? * check_ip() 發送arp Request包確認addr是否被使用
  • ???????????????????? * 返回0, addr is a free IP
  • ???????????????????? */
  • ??????????????????? !check_ip(ret))??
  • ??????????? {?
  • return ret;?
  • break;?
  • ??????????? }?
  • ??????? }?
  • ??? }?
  • return 0;?
  • }?
  • 轉載于:https://www.cnblogs.com/woainilsr/p/3181028.html

    總結

    以上是生活随笔為你收集整理的udhcp源码详解(四) 之租赁IP的管理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。