dhcpd开源工程(一) 守护进程中选择dhcp 的udp_port

dhcpd传输层基于UDP协议,dhcpv4的client和server分别使用udp的68和67号端口,在守护进程中,关于port设置的代码结构如下:
判断全局变量local_port,若是0,从getenv函数从环境中获取DHCPD_PORT环境变量的值,getenv函数原型如下:
/* Return the value of envariable NAME, or NULL if it doesn't exist.  */
extern char *getenv (__const char *__name) __THROW __nonnull ((1)) __wur;
一个简单的使用示例:
char * env = getenv("HOME");
	printf("%s\n", env);
结果是打印/root
一般获取不到,然后判断全局变量local_family是否是AF_INET,即ipv4套接字,若是,调用getservbyname以dhcp为入参获取dhcp的udp端口号,否则是v6,还是调用这个函数以dhcpv6为入参获取dhcpv6的udp端口号。注意这里是server的代码流程,因此获取的都是server的端口号,v4默认是67,v6是547,getservbyname函数定义如下
struct servent * PASCAL
getservbyname(const char* a0, const char* a1)
{
    static  struct servent * (PASCAL *fp)(const char* a0, const char* a1);

#ifdef DEBUG_STUB
    idnLogPrintf(idn_log_level_trace, "stub getservbyname() called\n");
#endif
    if (fp == NULL) {
	void *p;
	if ((p = GetProcAddress(DLLHANDLE, "getservbyname")) == NULL) {
	    FATAL("cannot find entry getservbyname (%d)\n", GetLastError());
	    abort();
	}
	fp = p;
    }
    return (*fp)(a0, a1);
}
里面涉及一些结构体和系统调用,其中,struct servent声明在inlcude/netdb.h中,声明如下
/* 单个条目的数据库条目描述 */
struct servent
{
  char *s_name;			/* 服务名称 */
  char **s_aliases;		/* 别名列表 */
  int s_port;			/* 端口号 */
  char *s_proto;		/* 协议 */
};

GetProcAddress函数从指定dll库中寻找函数地址,其内部实现在这里不做探究。调用getservbyname("dhcp","port"),将得到一个struct servent结构的ent变量,从ent->s_port中可以获取对应的端口号,若获取不到,就使用默认的。
若是dhcpv4,给全局变量remote_port远端端口号赋值为68,即client使用的udp端口号,否则是dhcpv6,给remote_port赋值为546,main函数中完整代码如下



if (!local_port)
	{
		if ((s = getenv ("DHCPD_PORT"))) {
			local_port = validate_port (s);
			log_debug ("binding to environment-specified port %d",
				   ntohs (local_port));
		} else {
			if (local_family == AF_INET) {
				ent = getservbyname("dhcp", "udp");
				if (ent == NULL) {
					local_port = htons(67);
				} else {
					local_port = ent->s_port;
				}
			} else {
				/* INSIST(local_family == AF_INET6); */
				ent = getservbyname("dhcpv6-server", "udp");
				if (ent == NULL) {
					local_port = htons(547);
				} else {
					local_port = ent->s_port;
				}
			}
#ifndef __CYGWIN32__ /* XXX */
			endservent ();
#endif
		}
	}

  	if (local_family == AF_INET) {
		remote_port = htons(ntohs(local_port) + 1);
	} else {
		/* INSIST(local_family == AF_INET6); */
		ent = getservbyname("dhcpv6-client", "udp");
		if (ent == NULL) {
			remote_port = htons(546);
		} else {
			remote_port = ent->s_port;
		}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值