示例#1
0
文件: send.c 项目: verrio/radvd
static int send_ra(int sock, struct Interface *iface, struct in6_addr const *dest)
{
	if (!iface->AdvSendAdvert) {
		dlog(LOG_DEBUG, 2, "AdvSendAdvert is off for %s", iface->props.name);
		return 0;
	}

	if (dest == NULL) {
		static uint8_t const all_hosts_addr[] = { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
		dest = (struct in6_addr const *)all_hosts_addr;
		clock_gettime(CLOCK_MONOTONIC, &iface->times.last_multicast);
	}

	update_iface_times(iface);

	char address_text[INET6_ADDRSTRLEN] = { "" };
	inet_ntop(AF_INET6, dest, address_text, INET6_ADDRSTRLEN);
	dlog(LOG_DEBUG, 5, "sending RA to %s on %s", address_text, iface->props.name);

	struct safe_buffer safe_buffer = SAFE_BUFFER_INIT;

	build_ra(&safe_buffer, iface);

	int err = really_send(sock, dest, &iface->props, &safe_buffer);

	safe_buffer_free(&safe_buffer);

	if (err < 0) {
		if (!iface->IgnoreIfMissing || !(errno == EINVAL || errno == ENODEV))
			flog(LOG_WARNING, "sendmsg: %s", strerror(errno));
		else
			dlog(LOG_DEBUG, 3, "sendmsg: %s", strerror(errno));
		return -1;
	}

	return 0;
}
示例#2
0
文件: send.c 项目: dskvorc/mif-radvd
static void add_pvd(struct safe_buffer * sb, struct AdvPvd const *pvd, int cease_adv)
{
	while (pvd) {
		/* create a temporary buffer to write the encapsulated options to
		   until we calculate the total length of the outer PVD_CO option */
		size_t total_len = 0;
		struct safe_buffer pvd_sb = SAFE_BUFFER_INIT;

		struct AdvPrefix *prefix = pvd->AdvPrefixList;
		while (prefix) {
			char pfx_str[INET6_ADDRSTRLEN];
			addrtostr(&prefix->Prefix, pfx_str, sizeof(pfx_str));
			prefix = prefix->next;
		}

		struct nd_opt_pvd pvdinfo;
		memset(&pvdinfo, 0, sizeof(pvdinfo));

		/* create PVD_CO container option */
		pvdinfo.nd_opt_pvd_container_type = ND_OPT_PVD_CONTAINER;
		/* initial length of PVD_CO option without encapsulated options */
		pvdinfo.nd_opt_pvd_container_len = 1;
		total_len += pvdinfo.nd_opt_pvd_container_len;
		pvdinfo.nd_opt_pvd_container_s = 0;
		pvdinfo.nd_opt_pvd_container_nametype = 0;

		/* add PVD_ID option */
		pvdinfo.nd_opt_pvd_id_type = ND_OPT_PVD_ID;
		pvdinfo.nd_opt_pvd_id_len = 5;
		total_len += pvdinfo.nd_opt_pvd_id_len;
		pvdinfo.nd_opt_pvd_id_idtype = 4;
		pvdinfo.nd_opt_pvd_id_idlen = 36;
		memcpy(&pvdinfo.nd_opt_pvd_id_pvdid, pvd->pvdid, sizeof(pvdinfo.nd_opt_pvd_id_pvdid));;

		/* add encapsulated ND options if specified */
		if (pvd->AdvPrefixList) {
			total_len += add_prefix(&pvd_sb, pvd->AdvPrefixList, cease_adv);
		}

		if (pvd->AdvRouteList) {
			total_len += add_route(&pvd_sb, pvd->AdvRouteList, cease_adv);
		}

		if (pvd->AdvRDNSSList) {
			total_len += add_rdnss(&pvd_sb, pvd->AdvRDNSSList, cease_adv);
		}

		if (pvd->AdvDNSSLList) {
			total_len += add_dnssl(&pvd_sb, pvd->AdvDNSSLList, cease_adv);
		}

		/*
		if (iface->AdvLinkMTU != 0) {
			add_mtu(sb, iface->AdvLinkMTU);
		}

		if (iface->AdvSourceLLAddress && iface->sllao.if_hwaddr_len > 0) {
			add_sllao(sb, &iface->sllao);
		}

		if (iface->mipv6.AdvIntervalOpt) {
			add_mipv6_rtr_adv_interval(sb, iface->MaxRtrAdvInterval);
		}

		if (iface->mipv6.AdvHomeAgentInfo
		    && (iface->mipv6.AdvMobRtrSupportFlag || iface->mipv6.HomeAgentPreference != 0
			|| iface->mipv6.HomeAgentLifetime != iface->ra_header_info.AdvDefaultLifetime)) {
			add_mipv6_home_agent_info(sb, &iface->mipv6);
		}
		*/

		if (pvd->AdvLowpanCoList) {
			total_len += add_lowpanco(&pvd_sb, pvd->AdvLowpanCoList);
		}

		if (pvd->AdvAbroList) {
			total_len += add_abro(&pvd_sb, pvd->AdvAbroList);
		}

		/* write out PVD_CO container option + PVD_ID option */
		pvdinfo.nd_opt_pvd_container_len = total_len;
		safe_buffer_append(sb, &pvdinfo, sizeof(pvdinfo));
		/* write out encapsulated ND options */
		safe_buffer_append(sb, pvd_sb.buffer, pvd_sb.used);
		/* destroy a temporary buffer */
		safe_buffer_free(&pvd_sb);

		pvd = pvd->next;
	}
}