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

📄 common.c

📁 DHCPv6协议在Linux操作系统下的一个客户端实现。
💻 C
📖 第 1 页 / 共 4 页
字号:
				pi.validlifetime = htonl(dp->val_dhcp6addr.validlifetime);				pi.plen = dp->val_dhcp6addr.plen; 				memcpy(&pi.prefix, &dp->val_dhcp6addr.addr, sizeof(pi.prefix));				memcpy(tp, &pi, sizeof(pi));				tp += sizeof(pi);				dprintf(LOG_DEBUG, "set IAPREFIX option len %d: "			    		"%s/%d preferlifetime %d validlifetime %d", 			    		iaddr_len, in6addr2str(&pi.prefix, 0), pi.plen,			    		ntohl(pi.preferlifetime), ntohl(pi.validlifetime));				/* set up address status code if any */				if (dp->val_dhcp6addr.status_code != DH6OPT_STCODE_UNDEFINE) {					status.dh6_status_type = htons(DH6OPT_STATUS_CODE);					status.dh6_status_len = 						htons(sizeof(status.dh6_status_code));					status.dh6_status_code = 						htons(dp->val_dhcp6addr.status_code);					memcpy(tp, &status, sizeof(status));					dprintf(LOG_DEBUG, "  this address status code: %s",			    		dhcp6_stcodestr(ntohs(status.dh6_status_code)));					optlen += sizeof(status);					tp += sizeof(status);					/* copy status message if any */				}			}		} else if (dhcp6_mode == DHCP6_MODE_SERVER) {			int num;			num = DH6OPT_STCODE_NOPREFIXAVAIL;			dprintf(LOG_DEBUG, "  status code: %s",			    dhcp6_stcodestr(num));			/* XXX: need to check duplication? */			if (dhcp6_add_listval(&optinfo->stcode_list,			    &num, DHCP6_LISTVAL_NUM) == NULL) {				dprintf(LOG_ERR, "%s" "failed to copy "				    "status code", FNAME);				goto fail;			}		}		COPY_OPTION(DH6OPT_IA_PD, optlen, tmpbuf, p);		free(tmpbuf);		break;	default:		break;	}	if (dhcp6_mode == DHCP6_MODE_SERVER && optinfo->pref != DH6OPT_PREF_UNDEF) {		u_int8_t p8 = (u_int8_t)optinfo->pref;		dprintf(LOG_DEBUG, "server preference %2x", optinfo->pref);		COPY_OPTION(DH6OPT_PREFERENCE, sizeof(p8), &p8, p);	}	for (stcode = TAILQ_FIRST(&optinfo->stcode_list); stcode;	     stcode = TAILQ_NEXT(stcode, link)) {		u_int16_t code;		code = htons(stcode->val_num);		COPY_OPTION(DH6OPT_STATUS_CODE, sizeof(code), &code, p);	}	if (!TAILQ_EMPTY(&optinfo->reqopt_list)) {		struct dhcp6_listval *opt;		u_int16_t *valp;		tmpbuf = NULL;		optlen = dhcp6_count_list(&optinfo->reqopt_list) *			sizeof(u_int16_t);		if ((tmpbuf = malloc(optlen)) == NULL) {			dprintf(LOG_ERR, "%s"			    "memory allocation failed for options", FNAME);			goto fail;		}		valp = (u_int16_t *)tmpbuf;		for (opt = TAILQ_FIRST(&optinfo->reqopt_list); opt;		     opt = TAILQ_NEXT(opt, link), valp++) {			*valp = htons((u_int16_t)opt->val_num);		}		COPY_OPTION(DH6OPT_ORO, optlen, tmpbuf, p);		free(tmpbuf);	}	if (!TAILQ_EMPTY(&optinfo->dns_list.addrlist)) {		struct in6_addr *in6;		struct dhcp6_listval *d;		tmpbuf = NULL;		optlen = dhcp6_count_list(&optinfo->dns_list.addrlist) *			sizeof(struct in6_addr);		if ((tmpbuf = malloc(optlen)) == NULL) {			dprintf(LOG_ERR, "%s"			    "memory allocation failed for DNS options", FNAME);			goto fail;		}		in6 = (struct in6_addr *)tmpbuf;		for (d = TAILQ_FIRST(&optinfo->dns_list.addrlist); d;		     d = TAILQ_NEXT(d, link), in6++) {			memcpy(in6, &d->val_addr6, sizeof(*in6));		}		COPY_OPTION(DH6OPT_DNS_RESOLVERS, optlen, tmpbuf, p);		free(tmpbuf);	}	if (optinfo->dns_list.domainlist != NULL) {		struct domain_list *dlist;		u_char *dst;		size_t dstsiz;		optlen = 0;		tmpbuf = NULL;		if ((tmpbuf = malloc(MAXDNAME * MAXDN)) == NULL) {			dprintf(LOG_ERR, "%s"			    "memory allocation failed for DNS options", FNAME);			goto fail;		}		dst = tmpbuf;		for (dlist = optinfo->dns_list.domainlist; dlist; dlist = dlist->next) {			int n;			n = dn_comp(dlist->name, dst, MAXDNAME, NULL, NULL);			if (n < 0) {				dprintf(LOG_ERR, "%s" "compress domain name failed", FNAME);				goto fail;			} else 				dprintf(LOG_DEBUG, "compress domain name %s", dlist->name);			optlen += n ;			dst += n;		}		COPY_OPTION(DH6OPT_DOMAIN_LIST, optlen, tmpbuf, p);		free(tmpbuf);	}				return (len);  fail:	if (tmpbuf)		free(tmpbuf);	return (-1);}#undef COPY_OPTIONvoiddhcp6_set_timeoparam(ev)	struct dhcp6_event *ev;{	ev->retrans = 0;	ev->init_retrans = 0;	ev->max_retrans_cnt = 0;	ev->max_retrans_dur = 0;	ev->max_retrans_time = 0;	switch(ev->state) {	case DHCP6S_SOLICIT:		ev->init_retrans = SOL_TIMEOUT;		ev->max_retrans_time = SOL_MAX_RT;		break;	case DHCP6S_INFOREQ:		ev->init_retrans = INF_TIMEOUT;		ev->max_retrans_time = INF_MAX_RT;		break;	case DHCP6S_REQUEST:		ev->init_retrans = REQ_TIMEOUT;		ev->max_retrans_time = REQ_MAX_RT;		ev->max_retrans_cnt = REQ_MAX_RC;		break;	case DHCP6S_RENEW:		ev->init_retrans = REN_TIMEOUT;		ev->max_retrans_time = REN_MAX_RT;		break;	case DHCP6S_REBIND:		ev->init_retrans = REB_TIMEOUT;		ev->max_retrans_time = REB_MAX_RT;		break;        case DHCP6S_DECLINE:                ev->init_retrans = DEC_TIMEOUT;                ev->max_retrans_cnt = DEC_MAX_RC;                break;        case DHCP6S_RELEASE:                ev->init_retrans = REL_TIMEOUT;                ev->max_retrans_cnt = REL_MAX_RC;                break;        case DHCP6S_CONFIRM:                ev->init_retrans = CNF_TIMEOUT;                ev->max_retrans_dur = CNF_MAX_RD;                ev->max_retrans_time = CNF_MAX_RT;		break;	default:		dprintf(LOG_INFO, "%s" "unexpected event state %d on %s",		    FNAME, ev->state, ev->ifp->ifname);		exit(1);	}}voiddhcp6_reset_timer(ev)	struct dhcp6_event *ev;{	double n, r;	char *statestr;	struct timeval interval;	switch(ev->state) {	case DHCP6S_INIT:		/*		 * The first Solicit message from the client on the interface		 * MUST be delayed by a random amount of time between		 * MIN_SOL_DELAY and MAX_SOL_DELAY.		 * [dhcpv6-28 14.]		 */		ev->retrans = (random() % (MAX_SOL_DELAY - MIN_SOL_DELAY)) +			MIN_SOL_DELAY;		break;	default:		if (ev->timeouts == 0) {			/*			 * The first RT MUST be selected to be strictly			 * greater than IRT by choosing RAND to be strictly			 * greater than 0.			 * [dhcpv6-28 14.]			 */			r = (double)((random() % 1000) + 1) / 10000;			n = ev->init_retrans + r * ev->init_retrans;		} else {			r = (double)((random() % 2000) - 1000) / 10000;			if (ev->timeouts == 0) {				n = ev->init_retrans + r * ev->init_retrans;			} else				n = 2 * ev->retrans + r * ev->retrans;		}		if (ev->max_retrans_time && n > ev->max_retrans_time)			n = ev->max_retrans_time + r * ev->max_retrans_time;		ev->retrans = (long)n;		break;	}	switch(ev->state) {	case DHCP6S_INIT:		statestr = "INIT";		break;	case DHCP6S_SOLICIT:		statestr = "SOLICIT";		break;	case DHCP6S_INFOREQ:		statestr = "INFOREQ";		break;	case DHCP6S_REQUEST:		statestr = "REQUEST";		break;	case DHCP6S_RENEW:		statestr = "RENEW";		break;	case DHCP6S_REBIND:		statestr = "REBIND";		break;	case DHCP6S_CONFIRM:		statestr = "CONFIRM";		break;	case DHCP6S_DECLINE:		statestr = "DECLINE";		break;	case DHCP6S_RELEASE:		statestr = "RELEASE";		break;	case DHCP6S_IDLE:		statestr = "IDLE";		break;	default:		statestr = "???"; /* XXX */		break;	}	interval.tv_sec = (ev->retrans * 1000) / 1000000;	interval.tv_usec = (ev->retrans * 1000) % 1000000;	dhcp6_set_timer(&interval, ev->timer);	dprintf(LOG_DEBUG, "%s" "reset a timer on %s, "		"state=%s, timeo=%d, retrans=%ld", FNAME,		ev->ifp->ifname, statestr, ev->timeouts, (long) ev->retrans);}intduidcpy(struct duid *dd, const struct duid *ds){	dd->duid_len = ds->duid_len;	if ((dd->duid_id = malloc(dd->duid_len)) == NULL) {		dprintf(LOG_ERR, "%s" "len %d memory allocation failed", FNAME, dd->duid_len);		return (-1);	}	memcpy(dd->duid_id, ds->duid_id, dd->duid_len);	return (0);}intduidcmp(const struct duid *d1, 	const struct duid *d2){	if (d1->duid_len == d2->duid_len) {		return (memcmp(d1->duid_id, d2->duid_id, d1->duid_len));	} else		return (-1);}voidduidfree(duid)	struct duid *duid;{	dprintf(LOG_DEBUG, "%s" "DUID is %s, DUID_LEN is %d", 			FNAME, duidstr(duid), duid->duid_len);	if (duid->duid_id != NULL && duid->duid_len != 0) {		dprintf(LOG_DEBUG, "%s" "removing ID (ID: %s)",		    FNAME, duidstr(duid));		free(duid->duid_id);		duid->duid_id = NULL;		duid->duid_len = 0;	}	duid->duid_len = 0;}char *dhcp6optstr(type)	int type;{	static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */	if (type > 65535)		return "INVALID option";	switch(type) {	case DH6OPT_CLIENTID:		return "client ID";	case DH6OPT_SERVERID:		return "server ID";	case DH6OPT_ORO:		return "option request";	case DH6OPT_PREFERENCE:		return "preference";	case DH6OPT_STATUS_CODE:		return "status code";	case DH6OPT_RAPID_COMMIT:		return "rapid commit";	case DH6OPT_DNS_RESOLVERS:		return "DNS_RESOLVERS";	default:		sprintf(genstr, "opt_%d", type);		return (genstr);	}}char *dhcp6msgstr(type)	int type;{	static char genstr[sizeof("msg255") + 1]; /* XXX thread unsafe */	if (type > 255)		return "INVALID msg";	switch(type) {	case DH6_SOLICIT:		return "solicit";	case DH6_ADVERTISE:		return "advertise";	case DH6_RENEW:		return "renew";	case DH6_REBIND:		return "rebind";	case DH6_REQUEST:		return "request";	case DH6_REPLY:		return "reply";	case DH6_CONFIRM:		return "confirm";	case DH6_RELEASE:		return "release";	case DH6_DECLINE:		return "decline";	case DH6_INFORM_REQ:		return "information request";	case DH6_RECONFIGURE:		return "reconfigure";	case DH6_RELAY_FORW:		return "relay forwarding";	case DH6_RELAY_REPL:		return "relay reply";	default:		sprintf(genstr, "msg%d", type);		return (genstr);	}}char *dhcp6_stcodestr(code)	int code;{	static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */	if (code > 255)		return "INVALID code";	switch(code) {	case DH6OPT_STCODE_SUCCESS:		return "success";	case DH6OPT_STCODE_UNSPECFAIL:		return "unspec failure";	case DH6OPT_STCODE_AUTHFAILED:		return "auth fail";	case DH6OPT_STCODE_ADDRUNAVAIL:		return "address unavailable";	case DH6OPT_STCODE_NOADDRAVAIL:		return "no addresses";	case DH6OPT_STCODE_NOBINDING:		return "no binding";	case DH6OPT_STCODE_CONFNOMATCH:		return "confirm no match";	case DH6OPT_STCODE_NOTONLINK:		return "not on-link";	case DH6OPT_STCODE_USEMULTICAST:		return "use multicast";	default:		sprintf(genstr, "code%d", code);		return (genstr);	}}char *duidstr(const struct duid *duid){	int i;	char *cp;	static char duidstr[sizeof("xx:") * 256 + sizeof("...")];		duidstr[0] ='\0';		cp = duidstr;	for (i = 0; i < duid->duid_len && i <= 256; i++) {		cp += sprintf(cp, "%s%02x", i == 0 ? "" : ":",			      duid->duid_id[i] & 0xff);	}	if (i < duid->duid_len)		sprintf(cp, "%s", "...");	return (duidstr);}voidsetloglevel(debuglevel)	int debuglevel;{	if (foreground) {		switch(debuglevel) {		case 0:			debug_thresh = LOG_ERR;			break;		case 1:			debug_thresh = LOG_INFO;			break;		default:			debug_thresh = LOG_DEBUG;			break;		}	} else {		switch(debuglevel) {		case 0:			setlogmask(LOG_UPTO(LOG_ERR));			break;		case 1:			setlogmask(LOG_UPTO(LOG_INFO));			break;		}	}}voiddprintf(int level, const char *fmt, ...){	va_list ap;	char logbuf[LINE_MAX];	va_start(ap, fmt);	vsnprintf(logbuf, sizeof(logbuf), fmt, ap);	if (foreground && debug_thresh >= level) {		time_t now;		struct tm *tm_now;		const char *month[] = {			"Jan", "Feb", "Mar", "Apr", "May", "Jun",			"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",		};		if ((now = time(NULL)) < 0)			exit(1); /* XXX */		tm_now = localtime(&now);		fprintf(stderr, "%3s/%02d/%04d %02d:%02d:%02d %s\n",			month[tm_now->tm_mon], tm_now->tm_mday,			tm_now->tm_year + 1900,			tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec,			logbuf);	} else		syslog(level, "%s", logbuf);}

⌨️ 快捷键说明

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