linux dhcpd源码,dhcpd 源码分析

dhcpd是linux下的一个DHCP服务器,下载地址:

下载完成后

tar -zxvf dhcp-4.2.1-P1.tar.gz

./configure

make

make install

编辑 /etc/dhcpd.conf 文件

ddns-update-style none;

subnet 192.168.66.0 netmask 255.255.255.0 {

option routers 192.168.66.1;

option subnet-mask 255.255.255.0;

option domain-name "wayos";

option domain-name-servers 61.139.2.69;

range 192.168.66.2 192.168.66.254;

default-lease-time 600;

max-lease-time 7200;

}

192.168.66.0 为主机所在网段

如果程序提示没有 "/var/db/dhcpd.leases" 文件,touch 一个

main

{

/* Set up the isc and dns library managers */

/* Set up the client classification system. */

/* Initialize the omapi system. */

/* Set up the OMAPI wrappers for common objects. */

/* Set up the OMAPI wrappers for various server database internal

objects. */

/* Initially, log errors to stderr as well as to syslogd. */

/* 解析命令行参数 */

/* get user and group info if those options were given */

/* get around the ISC declaration of group */

/* Default to the DHCP/BOOTP port. */

/* Set up the initial dhcp option universe. */

/* Add the ddns update style enumeration prior to parsing. */

/* Set up various hooks. */

dhcp_interface_setup_hook = dhcpd_interface_setup_hook;

bootp_packet_handler = do_packet;

/* Set up the standard name service updater routine. */

/* Initialize icmp support... */

/* Read the dhcpd.conf file... */

/* Start up the database... */

/* Discover all the network interfaces and initialize them. */

/* First part of becoming a daemon... */

/* Become session leader and get pid... */

/* Receive packets and dispatch them... */

dispatch ();

}

关键代码:

discover.c 文件中有bootp_packet_handler函数指针声明

void (*bootp_packet_handler) PROTO ((struct interface_info *,

struct dhcp_packet *, unsigned,

unsigned int,

struct iaddr, struct hardware *));

dhcpd.c 文件中 main函数对bootp_packet_handler函数指针进行了赋值,然后调用discover_interfaces函数:

bootp_packet_handler = do_packet;

discover_interfaces(DISCOVER_SERVER);

discover.c 文件有discover_interfaces函数的定义,其中关键的调用了got_one函数:

status = omapi_register_io_object((omapi_object_t *)tmp,

if_readsocket,

0, got_one, 0, 0);

discover.c 文件有got_one函数定义,其关键代码是调用了receive_packet函数,和bootp_packet_handler函数指针:

receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)

if (bootp_packet_handler) {

ifrom.len = 4;

memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);

(*bootp_packet_handler) (ip, &u.packet, (unsigned)result,

from.sin_port, ifrom, &hfrom);

}

socket.c 文件中有receive_packet函数的定义

result = recvfrom (interface -> rfdesc, (char *)buf, len, 0,

(struct sockaddr *)from, &flen);

options.c 文件中有do_packet函数的定义:

packet_allocate (&decoded_packet, MDL);

decoded_packet -> raw = packet;

decoded_packet -> packet_length = len;

decoded_packet -> client_port = from_port;

decoded_packet -> client_addr = from;

interface_reference (&decoded_packet -> interface, interface, MDL);

decoded_packet -> haddr = hfrom;

/* If there's an option buffer, try to parse it. */

if (decoded_packet -> packet_length >= DHCP_FIXED_NON_UDP + 4) {

if (!parse_options (decoded_packet)) {

if (decoded_packet -> options)

option_state_dereference

(&decoded_packet -> options, MDL);

packet_dereference (&decoded_packet, MDL);

return;

}

if (decoded_packet -> options_valid &&

(op = lookup_option (&dhcp_universe,

decoded_packet -> options,

DHO_DHCP_MESSAGE_TYPE))) {

struct data_string dp;

memset (&dp, 0, sizeof dp);

evaluate_option_cache (&dp, decoded_packet,

(struct lease *)0,

(struct client_state *)0,

decoded_packet -> options,

(struct option_state *)0,

(struct binding_scope **)0,

op, MDL);

if (dp.len > 0)

decoded_packet -> packet_type = dp.data [0];

else

decoded_packet -> packet_type = 0;

data_string_forget (&dp, MDL);

}

}

if (decoded_packet -> packet_type)

dhcp (decoded_packet);

else

bootp (decoded_packet);

dhcp.c 文件有dhcp函数的定义,主要做的工作就是对不同的packet -> packet_type对应的包进行处理:

switch (packet -> packet_type) {

case DHCPDISCOVER:

dhcpdiscover (packet, ms_nulltp);

break;

case DHCPREQUEST:

dhcprequest (packet, ms_nulltp, lease);

break;

case DHCPRELEASE:

dhcprelease (packet, ms_nulltp);

break;

case DHCPDECLINE:

dhcpdecline (packet, ms_nulltp);

break;

case DHCPINFORM:

dhcpinform (packet, ms_nulltp);

break;

case DHCPLEASEQUERY:

dhcpleasequery(packet, ms_nulltp);

break;

case DHCPACK:

case DHCPOFFER:

case DHCPNAK:

case DHCPLEASEUNASSIGNED:

case DHCPLEASEUNKNOWN:

case DHCPLEASEACTIVE:

break;

default:

errmsg = "unknown packet type";

goto bad_packet;

}

dhcp.c 文件有dhcprequest函数的定义,此函数的执行流程为:

/* Find the lease that matches the address requested by the

client. */

/*If it's RENEWING, we are the only server to hear it, so

* we have to serve it.*/

/* If we do know where it came from and it asked for an

address that is not on that shared network, nak it. */

/* If the address the client asked for is ours, but it wasn't

available for the client, NAK it. */

/* Otherwise, send the lease to the client if we found one. */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值