예제 #1
0
/************************************************************************** **
reload the list of network interfaces
 ************************************************************************** */
static void reload_interfaces(time_t t)
{
	static time_t lastt;
	int n;
	struct subnet_record *subrec;
	extern BOOL rescan_listen_set;
	extern struct in_addr loopback_ip;

	if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return;
	lastt = t;

	if (!interfaces_changed()) return;

	/* the list of probed interfaces has changed, we may need to add/remove
	   some subnets */
	load_interfaces();

	/* find any interfaces that need adding */
	for (n=iface_count() - 1; n >= 0; n--) {
		struct interface *iface = get_interface(n);

		/*
		 * We don't want to add a loopback interface, in case
		 * someone has added 127.0.0.1 for smbd, nmbd needs to
		 * ignore it here. JRA.
		 */

		if (ip_equal(iface->ip, loopback_ip)) {
			DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
			continue;
		}

		for (subrec=subnetlist; subrec; subrec=subrec->next) {
			if (ip_equal(iface->ip, subrec->myip) &&
			    ip_equal(iface->nmask, subrec->mask_ip)) break;
		}

		if (!subrec) {
			/* it wasn't found! add it */
			DEBUG(2,("Found new interface %s\n", 
				 inet_ntoa(iface->ip)));
			subrec = make_normal_subnet(iface);
			if (subrec) register_my_workgroup_one_subnet(subrec);
		}
	}

	/* find any interfaces that need deleting */
	for (subrec=subnetlist; subrec; subrec=subrec->next) {
		for (n=iface_count() - 1; n >= 0; n--) {
			struct interface *iface = get_interface(n);
			if (ip_equal(iface->ip, subrec->myip) &&
			    ip_equal(iface->nmask, subrec->mask_ip)) break;
		}
		if (n == -1) {
			/* oops, an interface has disapeared. This is
			 tricky, we don't dare actually free the
			 interface as it could be being used, so
			 instead we just wear the memory leak and
			 remove it from the list of interfaces without
			 freeing it */
			DEBUG(2,("Deleting dead interface %s\n", 
				 inet_ntoa(subrec->myip)));
			close_subnet(subrec);
		}
	}
	
	rescan_listen_set = True;
}
예제 #2
0
파일: nmbd.c 프로젝트: eduardok/samba
static void reload_interfaces(time_t t)
{
	static time_t lastt;
	int n;
	bool print_waiting_msg = true;
	struct subnet_record *subrec;

	if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
		return;
	}

	lastt = t;

	if (!interfaces_changed()) {
		return;
	}

  try_again:

	/* the list of probed interfaces has changed, we may need to add/remove
	   some subnets */
	load_interfaces();

	/* find any interfaces that need adding */
	for (n=iface_count() - 1; n >= 0; n--) {
		char str[INET6_ADDRSTRLEN];
		const struct interface *iface = get_interface(n);
		struct in_addr ip, nmask;

		if (!iface) {
			DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
			continue;
		}

		/* Ensure we're only dealing with IPv4 here. */
		if (iface->ip.ss_family != AF_INET) {
			DEBUG(2,("reload_interfaces: "
				"ignoring non IPv4 interface.\n"));
			continue;
		}

		ip = ((const struct sockaddr_in *)(const void *)&iface->ip)->sin_addr;
		nmask = ((const struct sockaddr_in *)(const void *)
			 &iface->netmask)->sin_addr;

		/*
		 * We don't want to add a loopback interface, in case
		 * someone has added 127.0.0.1 for smbd, nmbd needs to
		 * ignore it here. JRA.
		 */

		if (is_loopback_addr((const struct sockaddr *)(const void *)&iface->ip)) {
			DEBUG(2,("reload_interfaces: Ignoring loopback "
				"interface %s\n",
				print_sockaddr(str, sizeof(str), &iface->ip) ));
			continue;
		}

		for (subrec=subnetlist; subrec; subrec=subrec->next) {
			if (ip_equal_v4(ip, subrec->myip) &&
			    ip_equal_v4(nmask, subrec->mask_ip)) {
				break;
			}
		}

		if (!subrec) {
			/* it wasn't found! add it */
			DEBUG(2,("Found new interface %s\n",
				 print_sockaddr(str,
					 sizeof(str), &iface->ip) ));
			subrec = make_normal_subnet(iface);
			if (subrec)
				register_my_workgroup_one_subnet(subrec);
		}
	}

	/* find any interfaces that need deleting */
	for (subrec=subnetlist; subrec; subrec=subrec->next) {
		for (n=iface_count() - 1; n >= 0; n--) {
			struct interface *iface = get_interface(n);
			struct in_addr ip, nmask;
			if (!iface) {
				continue;
			}
			/* Ensure we're only dealing with IPv4 here. */
			if (iface->ip.ss_family != AF_INET) {
				DEBUG(2,("reload_interfaces: "
					"ignoring non IPv4 interface.\n"));
				continue;
			}
			ip = ((struct sockaddr_in *)(void *)
			      &iface->ip)->sin_addr;
			nmask = ((struct sockaddr_in *)(void *)
				 &iface->netmask)->sin_addr;
			if (ip_equal_v4(ip, subrec->myip) &&
			    ip_equal_v4(nmask, subrec->mask_ip)) {
				break;
			}
		}
		if (n == -1) {
			/* oops, an interface has disapeared. This is
			 tricky, we don't dare actually free the
			 interface as it could be being used, so
			 instead we just wear the memory leak and
			 remove it from the list of interfaces without
			 freeing it */
			DEBUG(2,("Deleting dead interface %s\n",
				 inet_ntoa(subrec->myip)));
			close_subnet(subrec);
		}
	}

	rescan_listen_set = True;

	/* We need to wait if there are no subnets... */
	if (FIRST_SUBNET == NULL) {
		void (*saved_handler)(int);

		if (print_waiting_msg) {
			DEBUG(0,("reload_interfaces: "
				"No subnets to listen to. Waiting..\n"));
			print_waiting_msg = false;
		}

		/*
		 * Whilst we're waiting for an interface, allow SIGTERM to
		 * cause us to exit.
		 */
		saved_handler = CatchSignal(SIGTERM, SIG_DFL);

		/* We only count IPv4, non-loopback interfaces here. */
		while (iface_count_v4_nl() == 0) {
			sleep(5);
			load_interfaces();
		}

		CatchSignal(SIGTERM, saved_handler);

		/*
		 * We got an interface, go back to blocking term.
		 */

		goto try_again;
	}
}