Beispiel #1
0
/****************************************************************************
Try and find an interface that matches an ip. If we cannot, return NULL
  **************************************************************************/
static struct interface *iface_find(struct interface *interfaces, 
				    struct in_addr ip, bool CheckMask)
{
	struct interface *i;
	if (is_zero_ip_v4(ip)) return interfaces;

	for (i=interfaces;i;i=i->next)
		if (CheckMask) {
			if (same_net_v4(i->ip,ip,i->nmask)) return i;
		} else if (i->ip.s_addr == ip.s_addr) return i;

	return NULL;
}
Beispiel #2
0
void load_lmhosts_file(const char *fname)
{
	char *name = NULL;
	int name_type;
	struct sockaddr_storage ss;
	TALLOC_CTX *ctx = talloc_init("load_lmhosts_file");
	FILE *fp = startlmhosts( fname );

	if (!fp) {
		DEBUG(2,("load_lmhosts_file: Can't open lmhosts file %s. Error was %s\n",
			fname, strerror(errno)));
		TALLOC_FREE(ctx);
		return;
	}

	while (getlmhostsent(ctx, fp, &name, &name_type, &ss) ) {
		struct in_addr ipaddr;
		struct subnet_record *subrec = NULL;
		enum name_source source = LMHOSTS_NAME;

		if (ss.ss_family != AF_INET) {
			TALLOC_FREE(name);
			continue;
		}

		ipaddr = ((struct sockaddr_in *)&ss)->sin_addr;

		/* We find a relevent subnet to put this entry on, then add it. */
		/* Go through all the broadcast subnets and see if the mask matches. */
		for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
			if(same_net_v4(ipaddr, subrec->bcast_ip, subrec->mask_ip))
				break;
		}

		/* If none match add the name to the remote_broadcast_subnet. */
		if(subrec == NULL)
			subrec = remote_broadcast_subnet;

		if(name_type == -1) {
			/* Add the (0) and (0x20) names directly into the namelist for this subnet. */
			(void)add_name_to_subnet(subrec,name,0x00,(uint16_t)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
			(void)add_name_to_subnet(subrec,name,0x20,(uint16_t)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
		} else {
			/* Add the given name type to the subnet namelist. */
			(void)add_name_to_subnet(subrec,name,name_type,(uint16_t)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
		}
	}

	TALLOC_FREE(ctx);
	endlmhosts(fp);
}
Beispiel #3
0
bool is_linklocal_addr(const struct sockaddr_storage *pss)
{
#ifdef HAVE_IPV6
	if (pss->ss_family == AF_INET6) {
		const struct in6_addr *pin6 =
			&((const struct sockaddr_in6 *)pss)->sin6_addr;
		return IN6_IS_ADDR_LINKLOCAL(pin6);
	}
#endif
	if (pss->ss_family == AF_INET) {
		const struct in_addr *pin =
			&((const struct sockaddr_in *)pss)->sin_addr;
		struct in_addr ll_addr;
		struct in_addr mask_addr;

		/* 169.254.0.0/16, is link local, see RFC 3927 */
		ll_addr.s_addr = 0xa9fe0000;
		mask_addr.s_addr = 0xffff0000;
		return same_net_v4(*pin, ll_addr, mask_addr);
	}
	return false;
}
Beispiel #4
0
/**
 * Are two IPs on the same subnet?
 */
bool same_net(const struct sockaddr *ip1,
		const struct sockaddr *ip2,
		const struct sockaddr *mask)
{
	if (ip1->sa_family != ip2->sa_family) {
		/* Never on the same net. */
		return false;
	}

#if defined(HAVE_IPV6)
	if (ip1->sa_family == AF_INET6) {
		struct sockaddr_in6 ip1_6 = *(const struct sockaddr_in6 *)ip1;
		struct sockaddr_in6 ip2_6 = *(const struct sockaddr_in6 *)ip2;
		struct sockaddr_in6 mask_6 = *(const struct sockaddr_in6 *)mask;
		char *p1 = (char *)&ip1_6.sin6_addr;
		char *p2 = (char *)&ip2_6.sin6_addr;
		char *m = (char *)&mask_6.sin6_addr;
		int i;

		for (i = 0; i < sizeof(struct in6_addr); i++) {
			*p1++ &= *m;
			*p2++ &= *m;
			m++;
		}
		return (memcmp(&ip1_6.sin6_addr,
				&ip2_6.sin6_addr,
				sizeof(struct in6_addr)) == 0);
	}
#endif
	if (ip1->sa_family == AF_INET) {
		return same_net_v4(((const struct sockaddr_in *)ip1)->sin_addr,
				((const struct sockaddr_in *)ip2)->sin_addr,
				((const struct sockaddr_in *)mask)->sin_addr);
	}
	return false;
}
Beispiel #5
0
/**
  return true if a IP matches a IP/netmask pair
*/
bool iface_same_net(const char *ip1, const char *ip2, const char *netmask)
{
	return same_net_v4(interpret_addr2(ip1),
			interpret_addr2(ip2),
			interpret_addr2(netmask));
}
Beispiel #6
0
/**
interpret a single element from a interfaces= config line 

This handles the following different forms:

1) wildcard interface name
2) DNS name
3) IP/masklen
4) ip/mask
5) bcast/mask
**/
static void interpret_interface(TALLOC_CTX *mem_ctx, 
				const char *token, 
				struct iface_struct *probed_ifaces, 
				int total_probed,
				struct interface **local_interfaces)
{
	struct in_addr ip, nmask;
	char *p;
	char *address;
	int i, added=0;

	ip.s_addr = 0;
	nmask.s_addr = 0;
	
	/* first check if it is an interface name */
	for (i=0;i<total_probed;i++) {
		if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
			add_interface(mem_ctx, probed_ifaces[i].ip,
				      probed_ifaces[i].netmask,
				      local_interfaces);
			added = 1;
		}
	}
	if (added) return;

	/* maybe it is a DNS name */
	p = strchr_m(token,'/');
	if (!p) {
		/* don't try to do dns lookups on wildcard names */
		if (strpbrk(token, "*?") != NULL) {
			return;
		}
		ip.s_addr = interpret_addr2(token).s_addr;
		for (i=0;i<total_probed;i++) {
			if (ip.s_addr == probed_ifaces[i].ip.s_addr) {
				add_interface(mem_ctx, probed_ifaces[i].ip,
					      probed_ifaces[i].netmask,
					      local_interfaces);
				return;
			}
		}
		DEBUG(2,("can't determine netmask for %s\n", token));
		return;
	}

	address = talloc_strdup(mem_ctx, token);
	p = strchr_m(address,'/');

	/* parse it into an IP address/netmasklength pair */
	*p++ = 0;

	ip.s_addr = interpret_addr2(address).s_addr;

	if (strlen(p) > 2) {
		nmask.s_addr = interpret_addr2(p).s_addr;
	} else {
		nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
	}

	/* maybe the first component was a broadcast address */
	if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
	    ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
		for (i=0;i<total_probed;i++) {
			if (same_net_v4(ip, probed_ifaces[i].ip, nmask)) {
				add_interface(mem_ctx, probed_ifaces[i].ip, nmask,
					      local_interfaces);
				talloc_free(address);
				return;
			}
		}
		DEBUG(2,("Can't determine ip for broadcast address %s\n", address));
		talloc_free(address);
		return;
	}

	add_interface(mem_ctx, ip, nmask, local_interfaces);
	talloc_free(address);
}