⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config.c

📁 IPv6环境下的DHCP实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		cp += 2;		bp++;	}	duid->duid_len = duidlen;	duid->duid_id = idbuf;	return(0);  bad:	if (idbuf)		free(idbuf);	dprintf(LOG_ERR, "%s" "assumption failure (bad string)", FNAME);	return(-1);}/* we currently only construct EUI-64 based interface ID */static intget_default_ifid(pif)	struct prefix_ifconf *pif;{	struct ifaddrs *ifa, *ifap;	struct sockaddr_dl *sdl;	if (pif->ifid_len < 64) {		dprintf(LOG_NOTICE, "%s" "ID length too short", FNAME);		return -1;	}	if (getifaddrs(&ifap) < 0) {		dprintf(LOG_ERR, "%s" "getifaddrs failed: %s",			FNAME, strerror(errno));		return -1;	}		for (ifa = ifap; ifa; ifa = ifa->ifa_next) {		char *cp;		if (strcmp(ifa->ifa_name, pif->ifname) != 0)			continue;		if (ifa->ifa_addr->sa_family != AF_LINK)			continue;		sdl = (struct sockaddr_dl *)ifa->ifa_addr;		if (sdl->sdl_alen < 6) {			dprintf(LOG_NOTICE, "%s"				"link layer address is too short (%s)",				FNAME, pif->ifname);			goto fail;		}		memset(pif->ifid, 0, sizeof(pif->ifid));		cp = (char *)(sdl->sdl_data + sdl->sdl_nlen);		pif->ifid[8] = cp[0];		pif->ifid[8] ^= 0x02; /* reverse the u/l bit*/		pif->ifid[9] = cp[1];		pif->ifid[10] = cp[2];		pif->ifid[11] = 0xff;		pif->ifid[12] = 0xfe;		pif->ifid[13] = cp[3];		pif->ifid[14] = cp[4];		pif->ifid[15] = cp[5];		break;	}	if (ifa == NULL) {		dprintf(LOG_INFO, "%s"			"cannot find interface information for %s",			FNAME, pif->ifname);		goto fail;	}	freeifaddrs(ifap);	return(0);  fail:	freeifaddrs(ifap);	return(-1);}voidconfigure_cleanup(){	clear_ifconf(dhcp6_ifconflist);	dhcp6_ifconflist = NULL;	clear_prefixifconf(prefix_ifconflist0);	prefix_ifconflist0 = NULL;	clear_hostconf(host_conflist0);	host_conflist0 = NULL;	dhcp6_clear_list(&dnslist0);	TAILQ_INIT(&dnslist0);}voidconfigure_commit(){	struct dhcp6_ifconf *ifc;	struct dhcp6_if *ifp;	/* commit interface configuration */	for (ifc = dhcp6_ifconflist; ifc; ifc = ifc->next) {		if ((ifp = find_ifconfbyname(ifc->ifname)) != NULL) {			ifp->send_flags = ifc->send_flags;			ifp->allow_flags = ifc->allow_flags;			clear_options(ifp->send_options);			ifp->send_options = ifc->send_options;			ifc->send_options = NULL;			dhcp6_clear_list(&ifp->reqopt_list);			ifp->reqopt_list = ifc->reqopt_list;			TAILQ_INIT(&ifc->reqopt_list);			ifp->server_pref = ifc->server_pref;		}	}	clear_ifconf(dhcp6_ifconflist);	/* commit prefix configuration */	if (prefix_ifconflist) {		/* clear previous configuration. (need more work?) */		clear_prefixifconf(prefix_ifconflist);	}	prefix_ifconflist = prefix_ifconflist0;	prefix_ifconflist0 = NULL;	/* commit prefix configuration */	if (host_conflist) {		/* clear previous configuration. (need more work?) */		clear_hostconf(host_conflist);	}	host_conflist = host_conflist0;	host_conflist0 = NULL;	/* commit DNS addresses */	if (!TAILQ_EMPTY(&dnslist)) {		dhcp6_clear_list(&dnslist);	}	dnslist = dnslist0;	TAILQ_INIT(&dnslist0);}static voidclear_ifconf(iflist)	struct dhcp6_ifconf *iflist;{	struct dhcp6_ifconf *ifc, *ifc_next;	for (ifc = iflist; ifc; ifc = ifc_next) {		ifc_next = ifc->next;		free(ifc->ifname);		clear_options(ifc->send_options);		dhcp6_clear_list(&ifc->reqopt_list);		free(ifc);	}}static voidclear_prefixifconf(iflist)	struct prefix_ifconf *iflist;{	struct prefix_ifconf *pif, *pif_next;	for (pif = iflist; pif; pif = pif_next) {		pif_next = pif->next;		free(pif->ifname);		free(pif);	}}static voidclear_hostconf(hlist)	struct host_conf *hlist;{	struct host_conf *host, *host_next;	struct dhcp6_listval *p;	for (host = hlist; host; host = host_next) {		host_next = host->next;		free(host->name);		while (p = TAILQ_FIRST(&host->prefix_list)) {			TAILQ_REMOVE(&host->prefix_list, p, link);			free(p);		}		if (host->duid.duid_id)			free(host->duid.duid_id);		free(host);	}}static voidclear_options(opt0)	struct dhcp6_optconf *opt0;{	struct dhcp6_optconf *opt, *opt_next;	for (opt = opt0; opt; opt = opt_next) {		opt_next = opt->next;		free(opt->val);		free(opt);	}}static intadd_options(opcode, ifc, cfl0)	int opcode;	struct dhcp6_ifconf *ifc;	struct cf_list *cfl0;{	struct dhcp6_listval *opt;	struct cf_list *cfl;	int opttype;	for (cfl = cfl0; cfl; cfl = cfl->next) {		if (opcode ==  DHCPOPTCODE_REQUEST) {			for (TAILQ_FIRST(&ifc->reqopt_list); opt;			     opt = TAILQ_NEXT(opt, link)) {				if (opt->val_num == cfl->type) {					dprintf(LOG_INFO, "%s"						"duplicated requested"						" option: %s", FNAME,						dhcp6optstr(cfl->type));					goto next; /* ignore it */				}			}		}		switch(cfl->type) {		case DHCPOPT_RAPID_COMMIT:			switch(opcode) {			case DHCPOPTCODE_SEND:				ifc->send_flags |= DHCIFF_RAPID_COMMIT;				break;			case DHCPOPTCODE_ALLOW:				ifc->allow_flags |= DHCIFF_RAPID_COMMIT;				break;			default:				dprintf(LOG_ERR, "%s" "invalid operation (%d) "					"for option type (%d)",					FNAME, opcode, cfl->type);				return(-1);			}			break;		case DHCPOPT_PREFIX_DELEGATION:			switch(opcode) {			case DHCPOPTCODE_REQUEST:				opttype = DH6OPT_PREFIX_DELEGATION;				if (dhcp6_add_listval(&ifc->reqopt_list,				    &opttype, DHCP6_LISTVAL_NUM) == NULL) {					dprintf(LOG_ERR, "%s" "failed to "					    "configure an option", FNAME);					return(-1);				}				break;			default:				dprintf(LOG_ERR, "%s" "invalid operation (%d) "					"for option type (%d)",					FNAME, opcode, cfl->type);				break;			}			break;		case DHCPOPT_DNS:			switch(opcode) {			case DHCPOPTCODE_REQUEST:				opttype = DH6OPT_DNS;				if (dhcp6_add_listval(&ifc->reqopt_list,				    &opttype, DHCP6_LISTVAL_NUM) == NULL) {					dprintf(LOG_ERR, "%s" "failed to "					    "configure an option", FNAME);					return(-1);				}				break;			default:				dprintf(LOG_ERR, "%s" "invalid operation (%d) "					"for option type (%d)",					FNAME, opcode, cfl->type);				break;			}			break;		default:			dprintf(LOG_ERR, "%s"				"unknown option type: %d", FNAME, cfl->type);				return(-1);		}	  next:	}	return(0);}static intadd_prefix(hconf, prefix0)	struct host_conf *hconf;	struct dhcp6_prefix *prefix0;{	struct dhcp6_prefix oprefix;	struct dhcp6_listval *p, *pent;	oprefix = *prefix0;	/* additional validation of parameters */	if (oprefix.plen < 0 || oprefix.plen > 128) {		dprintf(LOG_ERR, "%s" "invalid prefix: %d",			FNAME, oprefix.plen);		return(-1);	}	/* clear trailing bits */	prefix6_mask(&oprefix.addr, oprefix.plen);	if (!IN6_ARE_ADDR_EQUAL(&prefix0->addr, &oprefix.addr)) {		dprintf(LOG_WARNING, "%s" "prefix %s/%d for %s "			"has a trailing garbage.  It should be %s/%d",			FNAME, in6addr2str(&prefix0->addr, 0), prefix0->plen,			hconf->name,			in6addr2str(&oprefix.addr, 0), oprefix.plen);		/* ignore the error */	}	/* avoid invalid prefix addresses */	if (IN6_IS_ADDR_MULTICAST(&oprefix.addr) ||	    IN6_IS_ADDR_LINKLOCAL(&oprefix.addr) ||	    IN6_IS_ADDR_SITELOCAL(&oprefix.addr)) {		dprintf(LOG_ERR, "%s" "invalid prefix address: %s",			FNAME, in6addr2str(&oprefix.addr, 0));		return(-1);	}	/* prefix duplication check */	for (p = TAILQ_FIRST(&hconf->prefix_list); p;	     p = TAILQ_NEXT(p, link)) {		if (IN6_ARE_ADDR_EQUAL(&p->val_prefix6.addr, &oprefix.addr) &&		    p->val_prefix6.plen == oprefix.plen) {			dprintf(LOG_ERR, "%s"				"duplicated prefix: %s/%d for %s", FNAME,				in6addr2str(&oprefix.addr, 0), oprefix.plen,				hconf->name);			return(-1);		}	}	/* allocate memory for the new prefix and insert it to the chain */	if ((pent = malloc(sizeof(*pent))) == NULL) {		dprintf(LOG_ERR, "%s" "memory allocation failed for %s",			FNAME, hconf->name);		return(-1);	}	memset(pent, 0, sizeof(*pent));	pent->val_prefix6 = oprefix;	TAILQ_INSERT_TAIL(&hconf->prefix_list, pent, link);	return(0);}struct dhcp6_if *find_ifconfbyname(ifname)	char *ifname;{	struct dhcp6_if *ifp;	for (ifp = dhcp6_if; ifp; ifp = ifp->next) {		if (strcmp(ifp->ifname, ifname) == 0)			return(ifp);	}	return(NULL);}struct dhcp6_if *find_ifconfbyid(id)	unsigned int id;{	struct dhcp6_if *ifp;	for (ifp = dhcp6_if; ifp; ifp = ifp->next) {		if (ifp->ifid == id)			return(ifp);	}	return(NULL);}struct prefix_ifconf *find_prefixifconf(ifname)	char *ifname;{	struct prefix_ifconf *ifp;	for (ifp = prefix_ifconflist; ifp; ifp = ifp->next) {		if (strcmp(ifp->ifname, ifname) == NULL)			return(ifp);	}	return(NULL);}struct host_conf *find_hostconf(duid)	struct duid *duid;{	struct host_conf *host;	for (host = host_conflist; host; host = host->next) {		if (host->duid.duid_len == duid->duid_len &&		    memcmp(host->duid.duid_id, duid->duid_id,			   host->duid.duid_len) == 0) {			return(host);		}	}	return(NULL);}struct dhcp6_prefix *find_prefix6(list, prefix)	struct dhcp6_list *list;	struct dhcp6_prefix *prefix;{	struct dhcp6_listval *v;	for (v = TAILQ_FIRST(list); v; v = TAILQ_NEXT(v, link)) {		if (v->val_prefix6.plen == prefix->plen &&		    IN6_ARE_ADDR_EQUAL(&v->val_prefix6.addr, &prefix->addr)) {			return(&v->val_prefix6);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -