Exemplo n.º 1
0
int iface_count_v4_nl(void)
{
	int ret = 0;
	struct interface *i;

	for (i=local_interfaces;i;i=i->next) {
		if (is_loopback_addr((struct sockaddr *)&i->ip)) {
			continue;
		}
		if (i->ip.ss_family == AF_INET) {
			ret++;
		}
	}
	return ret;
}
Exemplo n.º 2
0
/**
load the list of network interfaces
**/
void load_interface_list(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct interface **local_interfaces)
{
    const char **ptr = lpcfg_interfaces(lp_ctx);
    int i;
    struct iface_struct *ifaces;
    int total_probed;
    bool enable_ipv6 = lpcfg_parm_bool(lp_ctx, NULL, "ipv6", "enable", true);

    *local_interfaces = NULL;

    /* probe the kernel for interfaces */
    total_probed = get_interfaces(mem_ctx, &ifaces);

    /* if we don't have a interfaces line then use all interfaces
       except loopback */
    if (!ptr || !*ptr || !**ptr) {
        if (total_probed <= 0) {
            DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
        }
        for (i=0; i<total_probed; i++) {
            if (!is_loopback_addr((struct sockaddr *)&ifaces[i].ip)) {
                add_interface(mem_ctx, &ifaces[i], local_interfaces, enable_ipv6);
            }
        }
    }

    while (ptr && *ptr) {
        interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces, enable_ipv6);
        ptr++;
    }

    if (!*local_interfaces) {
        DEBUG(0,("WARNING: no network interfaces found\n"));
    }
    talloc_free(ifaces);
}
Exemplo n.º 3
0
bool create_subnets(void)
{
	/* We only count IPv4 interfaces whilst we're waiting. */
	int num_interfaces;
	int i;
	struct in_addr unicast_ip, ipzero;

  try_interfaces_again:

	/* Only count IPv4, non-loopback interfaces. */
	if (iface_count_v4_nl() == 0) {
		DEBUG(0,("create_subnets: No local IPv4 non-loopback interfaces !\n"));
		DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
	}

	/* We only count IPv4, non-loopback interfaces here. */
	while (iface_count_v4_nl() == 0) {
		void (*saved_handler)(int);

		/*
		 * Whilst we're waiting for an interface, allow SIGTERM to
		 * cause us to exit.
		 */

		saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );

		sleep(5);
		load_interfaces();

		/*
		 * We got an interface, restore our normal term handler.
		 */

		CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
	}

	/*
	 * Here we count v4 and v6 - we know there's at least one
	 * IPv4 interface and we filter on it below.
	 */
	num_interfaces = iface_count();

	/*
	 * Create subnets from all the local interfaces and thread them onto
	 * the linked list.
	 */

	for (i = 0 ; i < num_interfaces; i++) {
		const struct interface *iface = get_interface(i);

		if (!iface) {
			DEBUG(2,("create_subnets: can't get interface %d.\n", i ));
			continue;
		}

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

		/*
		 * 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((struct sockaddr *)&iface->ip)) {
			DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
			continue;
		}

		if (!make_normal_subnet(iface))
			return False;
	}

        /* We must have at least one subnet. */
	if (subnetlist == NULL) {
		void (*saved_handler)(int);

		DEBUG(0,("create_subnets: Unable to create any subnet from "
				"given interfaces. Is your interface line in "
				"smb.conf correct ?\n"));

		saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );

		sleep(5);
		load_interfaces();

		CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
		goto try_interfaces_again;
	}

	if (lp_we_are_a_wins_server()) {
		/* Pick the first interface IPv4 address as the WINS server
		 * ip. */
		const struct in_addr *nip = first_ipv4_iface();

		if (!nip) {
			return False;
		}

		unicast_ip = *nip;
	} else {
		/* note that we do not set the wins server IP here. We just
			set it at zero and let the wins registration code cope
			with getting the IPs right for each packet */
		zero_ip_v4(&unicast_ip);
	}

	/*
	 * Create the unicast and remote broadcast subnets.
	 * Don't put these onto the linked list.
	 * The ip address of the unicast subnet is set to be
	 * the WINS server address, if it exists, or ipzero if not.
	 */

	unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET, 
				unicast_ip, unicast_ip, unicast_ip);

	zero_ip_v4(&ipzero);

	remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
				REMOTE_BROADCAST_SUBNET,
				ipzero, ipzero, ipzero);

	if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
		return False;

	/* 
	 * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
	 * the linked list.
	 */

	if (lp_we_are_a_wins_server()) {
		if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
						WINS_SERVER_SUBNET, 
						ipzero, ipzero, ipzero )) == NULL )
			return False;
	}

	return True;
}
Exemplo n.º 4
0
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;
	}
}