Ejemplo n.º 1
0
int inet_setip_bcast(inet_prefix *ip, int family)
{
	if(family==AF_INET) {
		u_int data[MAX_IP_INT]={0, 0, 0, 0};
		data[0]=INADDR_BROADCAST;
		inet_setip(ip, data, family);
	} else if(family==AF_INET6) {
		u_int data[MAX_IP_INT]=IPV6_ADDR_BROADCAST;
		inet_setip(ip, data, family);
	} else 
		fatal(ERROR_MSG "family not supported", ERROR_POS);

	return 0;
}
Ejemplo n.º 2
0
int inet_setip_anyaddr(inet_prefix *ip, int family)
{
	if(family==AF_INET) {
		u_int data[MAX_IP_INT]={0, 0, 0, 0};
		
		data[0]=INADDR_ANY;
		inet_setip(ip, data, family);
	} else if(family==AF_INET6) {
		struct in6_addr ipv6=IN6ADDR_ANY_INIT;
		inet_setip(ip, (u_int *)(&ipv6), family);
	} else 
		fatal(ERROR_MSG "family not supported", ERROR_POS);

	return 0;
}
Ejemplo n.º 3
0
int inet_setip_loopback(inet_prefix *ip, int family)
{
	if(family==AF_INET) {
		u_int data[MAX_IP_INT]={0, 0, 0, 0};
		
		data[0]=LOOPBACK_IP;
		inet_setip(ip, data, family);
		inet_htonl(ip->data, ip->family);
	} else if(family==AF_INET6) {
		u_int data[MAX_IP_INT]=LOOPBACK_IPV6;
		inet_setip(ip, data, family);
	} else 
		fatal(ERROR_MSG "family not supported", ERROR_POS);

	return 0;
}
Ejemplo n.º 4
0
/*
 * get_dev_ip: fetches the ip currently assigned to the interface named `dev'
 * and stores it to `ip'.
 * On success 0 is returned, -1 otherwise.
 */
int get_dev_ip(inet_prefix *ip, int family, char *dev)
{
	int s=-1;
	int ret=0;

	setzero(ip, sizeof(inet_prefix));

	if((s=new_socket(family)) < 0) {
		error("Error while setting \"%s\" ip: Cannot open socket", dev);
		return -1;
	}

	if(family == AF_INET) {
		struct ifreq req;

		strncpy(req.ifr_name, dev, IFNAMSIZ);
		req.ifr_addr.sa_family = family;
		
		if(ioctl(s, SIOCGIFADDR, &req))
			ERROR_FINISH(ret, -1, finish);

		sockaddr_to_inet(&req.ifr_addr, ip, 0);
	} else if(family == AF_INET6) {
		struct in6_ifreq req6;

		/*
		 * XXX: NOT TESTED
		 */

		req6.ifr6_ifindex=ll_name_to_index(dev);
		req6.ifr6_prefixlen=0;

		if(ioctl(s, SIOCGIFADDR, &req6))
			ERROR_FINISH(ret, -1, finish);

		inet_setip(ip, (u_int *)&req6.ifr6_addr, family);
	}

finish:
	if(s != -1)
		close(s);
	return ret;
}
Ejemplo n.º 5
0
/*
 * random_ip
 *
 * It generates a new random ip.
 * If `ipstart' is not NULL the new ip is restricted in the `final_gid' of
 * `final_level', so it'll be taken inside this range:
 * 	A=ipstart + (MAXGROUPNODE^( final_level + 1)) * final_gid;
 * 	B=ipstart + (MAXGROUPNODE^( final_level + 1)) * (final_gid + 1);
 * 		A <= x <= B
 * If `ipstart' is NULL a completely random ip is generated.
 * `total_levels' is the maximum number of levels.
 * `ext_map' is an external map.
 * If `only_free_gnode' is not 0, only the available and empty gnode are chosen.
 * In this case -1 may be returned if there aren't any free gnode to choose.
 * The new ip is stored in `new_ip' and on success 0 is returned.
 */
int
random_ip(inet_prefix * ipstart, int final_level, int final_gid,
		  int total_levels, map_gnode ** ext_map, int only_free_gnode,
		  inet_prefix * new_ip, int my_family)
{
	int i, e, x, level, levels;
	int gid[total_levels];
	quadro_group qg;

	setzero(new_ip, sizeof(inet_prefix));

	if (!ipstart || final_level == total_levels) {
		u_int idata[MAX_IP_INT] = { 0, 0, 0, 0 };

		for (;;) {
			/*
			 * Let's choose a completely random ip.
			 */
			levels = total_levels;
			if (my_family == AF_INET)
				idata[0] = rand();
			else {
				idata[0] = rand();
				idata[1] = rand();
				idata[2] = rand();
				idata[3] = rand();
			}

			inet_setip(new_ip, idata, my_family);

			if (!inet_validate_ip(*new_ip))
				break;
		}
		return 0;
	}

	/*
	 * We can choose only a random ip which is inside the final_gid.
	 * `final_gid' is a gnode of the `final_level' level.
	 * `final_level' has its `ipstart'; with it we determine
	 * its higher levels.
	 * The work is done in this way:
	 *   - ipstart is splitted in gnode_ids and they are placed in qg.gid.
	 *   - The final_level gid is set to `final_gid'.
	 *   - The gids of levels lower than `final_level' are chosen
	 *     randomly.
	 *   - The gids of levels higher than `final_level' are set to the
	 *     gids of qg.gid[x >= final_level].
	 * - The ipstart is recomposed from the gids.
	 */
	levels = final_level;
	iptoquadg(*ipstart, ext_map, &qg, QUADG_GID);
	gid[levels] = final_gid;
	for (i = final_level + 1; i < total_levels; i++)
		gid[i] = qg.gid[i];

	/* Change the gids if some of them point to full gnodes */
	free_gids(&qg, final_level + 1, ext_map, 0);

	/*
	 * Now we choose random gids for each level so we'll have a random ip
	 * with gidtoipstart();
	 */
	for (level = levels - 1; level >= 0; level--) {
		gid[level] = rand_range(0, MAXGROUPNODE - 1);

		if (level && only_free_gnode) {
			/*
			 * We have to be sure that we're not picking a gnode
			 * already used in the ext_map. Generally when we hook
			 * we have loaded the old ext_map, so skipping the
			 * taken gnodes we increase the possibility to create a
			 * brand new, and not already used, gnode.
			 */
			if (!(ext_map[_EL(level)][gid[level]].flags & GMAP_VOID)) {

				/* Take a random position and loop trough the
				 * map */
				i = rand_range(0, MAXGROUPNODE - 1);

				for (x = 0, e = i; e < MAXGROUPNODE; e++) {
					if (is_group_invalid(gid, e, level, my_family))
						continue;

					if (ext_map[_EL(level)][e].flags & GMAP_VOID) {
						gid[level] = e;
						x = 1;
						break;
					}
				}
				if (!x) {
					for (x = 0; i >= 0; i--) {
						if (is_group_invalid(gid, i, level, my_family))
							continue;

						if (ext_map[_EL(level)][i].flags & GMAP_VOID) {
							gid[level] = i;
							x = 1;
							break;
						}
					}
				}
				if (!x)
					/* not a single free gnode was found */
					return -1;
			}
		}
	}

	/*
	 * Ok, we've set the gids of each level so we recompose them in the
	 * new_ip.
	 */
	gidtoipstart(gid, total_levels, total_levels, my_family, new_ip);

	return 0;
}
Ejemplo n.º 6
0
/*
 * route_get_gw: if the route stored in `who' and `n' is matched by the
 * `filter', it stores the gateway address of that route in `arg', which
 * is a pointer to an inet_prefix struct. The address is stored in host order.
 * The dev name of the route is appended at `arg'+sizeof(inet_prefix).
 * Only the non-deleted routes are considered.
 */
int
route_get_gw(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	struct rtmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[RTA_MAX + 1];
	inet_prefix dst;
	inet_prefix via;
	int host_len = -1;


	if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE)
		return 0;
	if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
		return 0;
	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0)
		return -1;

	if (r->rtm_family == AF_INET6)
		host_len = 128;
	else if (r->rtm_family == AF_INET)
		host_len = 32;
	else if (r->rtm_family == AF_DECnet)
		host_len = 16;
	else if (r->rtm_family == AF_IPX)
		host_len = 80;

	if (r->rtm_family == AF_INET6) {
		if (filter.tb) {
			if (filter.tb < 0) {
				if (!(r->rtm_flags & RTM_F_CLONED))
					return 0;
			} else {
				if (r->rtm_flags & RTM_F_CLONED)
					return 0;
				if (filter.tb == RT_TABLE_LOCAL) {
					if (r->rtm_type != RTN_LOCAL)
						return 0;
				} else if (filter.tb == RT_TABLE_MAIN) {
					if (r->rtm_type == RTN_LOCAL)
						return 0;
				} else {
					return 0;
				}
			}
		}
	} else {
		if (filter.tb > 0 && filter.tb != r->rtm_table)
			return 0;
	}
	if ((filter.protocol ^ r->rtm_protocol) & filter.protocolmask)
		return 0;
	if ((filter.scope ^ r->rtm_scope) & filter.scopemask)
		return 0;
	if ((filter.type ^ r->rtm_type) & filter.typemask)
		return 0;
	if ((filter.tos ^ r->rtm_tos) & filter.tosmask)
		return 0;
	if (filter.rdst.family &&
		(r->rtm_family != filter.rdst.family
		 || filter.rdst.bits > r->rtm_dst_len))
		return 0;
	if (filter.mdst.family &&
		(r->rtm_family != filter.mdst.family ||
		 (filter.mdst.bits < r->rtm_dst_len)))
		return 0;
	if (filter.rsrc.family &&
		(r->rtm_family != filter.rsrc.family
		 || filter.rsrc.bits > r->rtm_src_len))
		return 0;
	if (filter.msrc.family &&
		(r->rtm_family != filter.msrc.family ||
		 (filter.msrc.bits < r->rtm_src_len)))
		return 0;
	if (filter.rvia.family && r->rtm_family != filter.rvia.family)
		return 0;
	if (filter.rprefsrc.family && r->rtm_family != filter.rprefsrc.family)
		return 0;

	parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);

	setzero(&dst, sizeof(dst));
	dst.family = r->rtm_family;
	if (tb[RTA_DST]) {
		memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len + 7) / 8);
	}
	if (filter.rdst.family
		&& inet_addr_match(&dst, &filter.rdst, filter.rdst.bits))
		return 0;
	if (filter.mdst.family &&
		inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
		return 0;

	if (n->nlmsg_type == RTM_DELROUTE)
		return 0;

	/*
	 * ... and finally if all the tests passed, copy the gateway address
	 */
	if (tb[RTA_GATEWAY]) {
		memcpy(&via.data, RTA_DATA(tb[RTA_GATEWAY]), host_len / 8);
		via.family = r->rtm_family;
		inet_setip(arg, (u_int *) & via.data, via.family);
	} else if (tb[RTA_MULTIPATH]) {
		struct rtnexthop *nh = RTA_DATA(tb[RTA_MULTIPATH]);

		len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);

		for (;;) {
			if (len < sizeof(*nh))
				break;
			if (nh->rtnh_len > len)
				break;
			if (r->rtm_flags & RTM_F_CLONED
				&& r->rtm_type == RTN_MULTICAST)
				goto skip_nexthop;

			if (nh->rtnh_len > sizeof(*nh)) {
				parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh),
							 nh->rtnh_len - sizeof(*nh));
				if (tb[RTA_GATEWAY]) {
					memcpy(&via.data, RTA_DATA(tb[RTA_GATEWAY]),
						   host_len / 8);
					via.family = r->rtm_family;
					inet_setip(arg, (u_int *) & via.data, via.family);

					/* Copy the interface name */
					strncpy((char *) arg + sizeof(inet_prefix),
							ll_index_to_name(nh->rtnh_ifindex), IFNAMSIZ);
					break;
				}
			}
		  skip_nexthop:
			len -= NLMSG_ALIGN(nh->rtnh_len);
			nh = RTNH_NEXT(nh);
		}
	}


	/* Copy the interface name */
	if (tb[RTA_OIF] && filter.oifmask != -1)
		strncpy((char *) arg + sizeof(inet_prefix),
				ll_index_to_name(*(int *) RTA_DATA(tb[RTA_OIF])),
				IFNAMSIZ);

	return 0;
}