Example #1
0
int get_prefix_1(inet_prefix *dst, char *arg, int family)
{
	int err;
	unsigned plen;
	char *slash;

	memset(dst, 0, sizeof(*dst));

	if (strcmp(arg, "default") == 0 ||
	    strcmp(arg, "any") == 0 ||
	    strcmp(arg, "all") == 0) {
		if ((family == AF_DECnet) || (family == AF_MPLS))
			return -1;
		dst->family = family;
		dst->bytelen = 0;
		dst->bitlen = 0;
		return 0;
	}

	slash = strchr(arg, '/');
	if (slash)
		*slash = 0;

	err = get_addr_1(dst, arg, family);
	if (err == 0) {
		dst->bitlen = af_bit_len(dst->family);

		if (slash) {
			if (get_netmask(&plen, slash+1, 0)
			    || plen > dst->bitlen) {
				err = -1;
				goto done;
			}
			dst->flags |= PREFIXLEN_SPECIFIED;
			dst->bitlen = plen;
		}
	}
done:
	if (slash)
		*slash = '/';
	return err;
}
Example #2
0
File: utils.c Project: dtaht/tc-adv
int get_prefix_1(inet_prefix *dst, char *arg, int family)
{
	char *slash;
	int err, bitlen, flags;

	slash = strchr(arg, '/');
	if (slash)
		*slash = 0;

	err = get_addr_1(dst, arg, family);

	if (slash)
		*slash = '/';

	if (err)
		return err;

	bitlen = af_bit_len(dst->family);

	flags = 0;
	if (slash) {
		unsigned int plen;

		if (dst->bitlen == -2)
			return -1;
		if (get_netmask(&plen, slash + 1, 0))
			return -1;
		if (plen > bitlen)
			return -1;

		flags |= PREFIXLEN_SPECIFIED;
		bitlen = plen;
	} else {
		if (dst->bitlen == -2)
			bitlen = 0;
	}

	dst->flags |= flags;
	dst->bitlen = bitlen;

	return 0;
}
Example #3
0
int af_byte_len(int af)
{
	return af_bit_len(af) / 8;
}
Example #4
0
int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct rtmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * tb[RTA_MAX+1];
	char abuf[256];
	int host_len;
	__u32 table;
	SPRINT_BUF(b1);
	static int hz;

	if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
		fprintf(stderr, "Not a route: %08x %08x %08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}
	if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
		return 0;
	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	host_len = af_bit_len(r->rtm_family);

	parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
	table = rtm_get_table(r, tb);

	if (!filter_nlmsg(n, tb, host_len))
		return 0;

	if (filter.flushb) {
		struct nlmsghdr *fn;
		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
			if (flush_update())
				return -1;
		}
		fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
		memcpy(fn, n, n->nlmsg_len);
		fn->nlmsg_type = RTM_DELROUTE;
		fn->nlmsg_flags = NLM_F_REQUEST;
		fn->nlmsg_seq = ++rth.seq;
		filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
		filter.flushed++;
		if (show_stats < 2)
			return 0;
	}

	if (n->nlmsg_type == RTM_DELROUTE)
		fprintf(fp, "Deleted ");
	if ((r->rtm_type != RTN_UNICAST || show_details > 0) && !filter.type)
		fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));

	if (tb[RTA_DST]) {
		if (r->rtm_dst_len != host_len) {
			fprintf(fp, "%s/%u ", rt_addr_n2a(r->rtm_family,
						       RTA_PAYLOAD(tb[RTA_DST]),
						       RTA_DATA(tb[RTA_DST]),
						       abuf, sizeof(abuf)),
				r->rtm_dst_len
				);
		} else {
			fprintf(fp, "%s ", format_host(r->rtm_family,
						       RTA_PAYLOAD(tb[RTA_DST]),
						       RTA_DATA(tb[RTA_DST]),
						       abuf, sizeof(abuf))
				);
		}
	} else if (r->rtm_dst_len) {
		fprintf(fp, "0/%d ", r->rtm_dst_len);
	} else {
		fprintf(fp, "default ");
	}
	if (tb[RTA_SRC]) {
		if (r->rtm_src_len != host_len) {
			fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
						       RTA_PAYLOAD(tb[RTA_SRC]),
						       RTA_DATA(tb[RTA_SRC]),
						       abuf, sizeof(abuf)),
				r->rtm_src_len
				);
		} else {
			fprintf(fp, "from %s ", format_host(r->rtm_family,
						       RTA_PAYLOAD(tb[RTA_SRC]),
						       RTA_DATA(tb[RTA_SRC]),
						       abuf, sizeof(abuf))
				);
		}
	} else if (r->rtm_src_len) {
		fprintf(fp, "from 0/%u ", r->rtm_src_len);
	}
	if (tb[RTA_NEWDST]) {
		fprintf(fp, "as to %s ", format_host(r->rtm_family,
						  RTA_PAYLOAD(tb[RTA_NEWDST]),
						  RTA_DATA(tb[RTA_NEWDST]),
						  abuf, sizeof(abuf))
			);
	}
	if (r->rtm_tos && filter.tosmask != -1) {
		SPRINT_BUF(b1);
		fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
	}

	if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) {
		fprintf(fp, "via %s ",
			format_host(r->rtm_family,
				    RTA_PAYLOAD(tb[RTA_GATEWAY]),
				    RTA_DATA(tb[RTA_GATEWAY]),
				    abuf, sizeof(abuf)));
	}
	if (tb[RTA_VIA]) {
		size_t len = RTA_PAYLOAD(tb[RTA_VIA]) - 2;
		struct rtvia *via = RTA_DATA(tb[RTA_VIA]);
		fprintf(fp, "via %s %s ",
			family_name(via->rtvia_family),
			format_host(via->rtvia_family, len, via->rtvia_addr,
				    abuf, sizeof(abuf)));
	}
	if (tb[RTA_OIF] && filter.oifmask != -1)
		fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));

	if (!(r->rtm_flags&RTM_F_CLONED)) {
		if ((table != RT_TABLE_MAIN || show_details > 0) && !filter.tb)
			fprintf(fp, " table %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
		if ((r->rtm_protocol != RTPROT_BOOT || show_details > 0) && filter.protocolmask != -1)
			fprintf(fp, " proto %s ", rtnl_rtprot_n2a(r->rtm_protocol, b1, sizeof(b1)));
		if ((r->rtm_scope != RT_SCOPE_UNIVERSE || show_details > 0) && filter.scopemask != -1)
			fprintf(fp, " scope %s ", rtnl_rtscope_n2a(r->rtm_scope, b1, sizeof(b1)));
	}
	if (tb[RTA_PREFSRC] && filter.rprefsrc.bitlen != host_len) {
		/* Do not use format_host(). It is our local addr
		   and symbolic name will not be useful.
		 */
		fprintf(fp, " src %s ",
			rt_addr_n2a(r->rtm_family,
				    RTA_PAYLOAD(tb[RTA_PREFSRC]),
				    RTA_DATA(tb[RTA_PREFSRC]),
				    abuf, sizeof(abuf)));
	}
	if (tb[RTA_PRIORITY])
		fprintf(fp, " metric %u ", rta_getattr_u32(tb[RTA_PRIORITY]));
	if (r->rtm_flags & RTNH_F_DEAD)
		fprintf(fp, "dead ");
	if (r->rtm_flags & RTNH_F_ONLINK)
		fprintf(fp, "onlink ");
	if (r->rtm_flags & RTNH_F_PERVASIVE)
		fprintf(fp, "pervasive ");
	if (r->rtm_flags & RTNH_F_EXTERNAL)
		fprintf(fp, "offload ");
	if (r->rtm_flags & RTM_F_NOTIFY)
		fprintf(fp, "notify ");
	if (tb[RTA_MARK]) {
		unsigned int mark = *(unsigned int*)RTA_DATA(tb[RTA_MARK]);
		if (mark) {
			if (mark >= 16)
				fprintf(fp, " mark 0x%x", mark);
			else
				fprintf(fp, " mark %u", mark);
		}
	}

	if (tb[RTA_FLOW] && filter.realmmask != ~0U) {
		__u32 to = rta_getattr_u32(tb[RTA_FLOW]);
		__u32 from = to>>16;
		to &= 0xFFFF;
		fprintf(fp, "realm%s ", from ? "s" : "");
		if (from) {
			fprintf(fp, "%s/",
				rtnl_rtrealm_n2a(from, b1, sizeof(b1)));
		}
		fprintf(fp, "%s ",
			rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
	}
Example #5
0
int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct rtmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	int host_len = -1;
	__u32 table;
	struct rtattr * tb[FRA_MAX+1];
	char abuf[256];
	SPRINT_BUF(b1);

	if (n->nlmsg_type != RTM_NEWRULE && n->nlmsg_type != RTM_DELRULE)
		return 0;

	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0)
		return -1;

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

	host_len = af_bit_len(r->rtm_family);

	if (n->nlmsg_type == RTM_DELRULE)
		fprintf(fp, "Deleted ");

	if (tb[FRA_PRIORITY])
		fprintf(fp, "%u:\t", *(unsigned*)RTA_DATA(tb[FRA_PRIORITY]));
	else
		fprintf(fp, "0:\t");

	if (r->rtm_flags & FIB_RULE_INVERT)
		fprintf(fp, "not ");

	if (tb[FRA_SRC]) {
		if (r->rtm_src_len != host_len) {
			fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
						       RTA_PAYLOAD(tb[FRA_SRC]),
						       RTA_DATA(tb[FRA_SRC]),
						       abuf, sizeof(abuf)),
				r->rtm_src_len
				);
		} else {
			fprintf(fp, "from %s ", format_host(r->rtm_family,
						       RTA_PAYLOAD(tb[FRA_SRC]),
						       RTA_DATA(tb[FRA_SRC]),
						       abuf, sizeof(abuf))
				);
		}
	} else if (r->rtm_src_len) {
		fprintf(fp, "from 0/%d ", r->rtm_src_len);
	} else {
		fprintf(fp, "from all ");
	}

	if (tb[FRA_DST]) {
		if (r->rtm_dst_len != host_len) {
			fprintf(fp, "to %s/%u ", rt_addr_n2a(r->rtm_family,
						       RTA_PAYLOAD(tb[FRA_DST]),
						       RTA_DATA(tb[FRA_DST]),
						       abuf, sizeof(abuf)),
				r->rtm_dst_len
				);
		} else {
			fprintf(fp, "to %s ", format_host(r->rtm_family,
						       RTA_PAYLOAD(tb[FRA_DST]),
						       RTA_DATA(tb[FRA_DST]),
						       abuf, sizeof(abuf)));
		}
	} else if (r->rtm_dst_len) {
		fprintf(fp, "to 0/%d ", r->rtm_dst_len);
	}

	if (r->rtm_tos) {
		SPRINT_BUF(b1);
		fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
	}

	if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) {
		__u32 mark = 0, mask = 0;

		if (tb[FRA_FWMARK])
			mark = rta_getattr_u32(tb[FRA_FWMARK]);

		if (tb[FRA_FWMASK] &&
		    (mask = rta_getattr_u32(tb[FRA_FWMASK])) != 0xFFFFFFFF)
			fprintf(fp, "fwmark 0x%x/0x%x ", mark, mask);
		else
			fprintf(fp, "fwmark 0x%x ", mark);
	}

	if (tb[FRA_IFNAME]) {
		fprintf(fp, "iif %s ", rta_getattr_str(tb[FRA_IFNAME]));
		if (r->rtm_flags & FIB_RULE_IIF_DETACHED)
			fprintf(fp, "[detached] ");
	}

	if (tb[FRA_OIFNAME]) {
		fprintf(fp, "oif %s ", rta_getattr_str(tb[FRA_OIFNAME]));
		if (r->rtm_flags & FIB_RULE_OIF_DETACHED)
			fprintf(fp, "[detached] ");
	}

	table = rtm_get_table(r, tb);
	if (table) {
		fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));

		if (tb[FRA_SUPPRESS_PREFIXLEN]) {
			int pl = rta_getattr_u32(tb[FRA_SUPPRESS_PREFIXLEN]);
			if (pl != -1) {
				fprintf(fp, "suppress_prefixlength %d ", pl);
			}
		}
		if (tb[FRA_SUPPRESS_IFGROUP]) {
			int group = rta_getattr_u32(tb[FRA_SUPPRESS_IFGROUP]);
			if (group != -1) {
				SPRINT_BUF(b1);
				fprintf(fp, "suppress_ifgroup %s ", rtnl_group_n2a(group, b1, sizeof(b1)));
			}
		}
	}

	if (tb[FRA_FLOW]) {
		__u32 to = rta_getattr_u32(tb[FRA_FLOW]);
		__u32 from = to>>16;
		to &= 0xFFFF;
		if (from) {
			fprintf(fp, "realms %s/",
				rtnl_rtrealm_n2a(from, b1, sizeof(b1)));
		}
		fprintf(fp, "%s ",
			rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
	}

	if (r->rtm_type == RTN_NAT) {
		if (tb[RTA_GATEWAY]) {
			fprintf(fp, "map-to %s ",
				format_host(r->rtm_family,
					    RTA_PAYLOAD(tb[RTA_GATEWAY]),
					    RTA_DATA(tb[RTA_GATEWAY]),
					    abuf, sizeof(abuf)));
		} else
			fprintf(fp, "masquerade");
	} else if (r->rtm_type == FR_ACT_GOTO) {
		fprintf(fp, "goto ");
		if (tb[FRA_GOTO])
			fprintf(fp, "%u", rta_getattr_u32(tb[FRA_GOTO]));
		else
			fprintf(fp, "none");
		if (r->rtm_flags & FIB_RULE_UNRESOLVED)
			fprintf(fp, " [unresolved]");
	} else if (r->rtm_type == FR_ACT_NOP)
		fprintf(fp, "nop");
	else if (r->rtm_type != RTN_UNICAST)
		fprintf(fp, "%s", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));

	fprintf(fp, "\n");
	fflush(fp);
	return 0;
}