Exemple #1
0
int TunManager::getLinkRespParser(const struct sockaddr_nl *who,
                                  struct nlmsghdr *n,
                                  void *arg) {
  // only cares about RTM_NEWLINK
  if (n->nlmsg_type != RTM_NEWLINK) {
    return 0;
  }

  struct ifinfomsg *ifi = static_cast<struct ifinfomsg *>(NLMSG_DATA(n));
  struct rtattr *tb[IFLA_MAX + 1];
  int len = n->nlmsg_len;
  len -= NLMSG_LENGTH(sizeof(*ifi));
  if (len < 0) {
    throw FbossError("Wrong length for RTM_GETLINK response ", len, " vs ",
                     NLMSG_LENGTH(sizeof(*ifi)));
  }
  parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
  if (tb[IFLA_IFNAME] == nullptr) {
    throw FbossError("Device @ index ", static_cast<int>(ifi->ifi_index),
                     " does not have a nmae");
  }
  const auto name = rta_getattr_str(tb[IFLA_IFNAME]);
  // match the interface name against intfPrefix
  if (!TunIntf::isTunIntf(name)) {
    VLOG(3) << "Ignore interface " << name
            << " because it is not a tun interface";
    return 0;
  }
  // base on the name, get the router ID
  auto rid = TunIntf::getRidFromName(name);

  TunManager *mgr = static_cast<TunManager *>(arg);
  mgr->addIntf(rid, std::string(name), ifi->ifi_index);
  return 0;
}
Exemple #2
0
static int rtnl_linkinfo_parse(struct rtattr *rta)
{
	int index = -1;
	const char *kind;
	struct rtattr *linkinfo[IFLA_INFO_MAX];
	struct rtattr *bond[IFLA_BOND_MAX];

	if (rtnl_nested_rtattr_parse(linkinfo, IFLA_INFO_MAX, rta) < 0)
		return -1;

	if (linkinfo[IFLA_INFO_KIND]) {
		kind = rta_getattr_str(linkinfo[IFLA_INFO_KIND]);

		if (kind && !strncmp(kind, "bond", 4) &&
		    linkinfo[IFLA_INFO_DATA]) {
			if (rtnl_nested_rtattr_parse(bond, IFLA_BOND_MAX,
						 linkinfo[IFLA_INFO_DATA]) < 0)
				return -1;

			if (bond[IFLA_BOND_ACTIVE_SLAVE]) {
				index = rta_getattr_u32(bond[IFLA_BOND_ACTIVE_SLAVE]);
			}
		}
	}
	return index;
}
Exemple #3
0
static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
{
	int qlen;

	if (tb[IFLA_TXQLEN])
		qlen = *(int *)RTA_DATA(tb[IFLA_TXQLEN]);
	else {
		struct ifreq ifr;
		int s = socket(AF_INET, SOCK_STREAM, 0);

		if (s < 0)
			return;

		memset(&ifr, 0, sizeof(ifr));
		strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]));
		if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
			fprintf(f, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno));
			close(s);
			return;
		}
		close(s);
		qlen = ifr.ifr_qlen;
	}
	if (qlen)
		fprintf(f, "qlen %d", qlen);
}
Exemple #4
0
static int bpf_print_opt(struct action_util *au, FILE *f, struct rtattr *arg)
{
	struct rtattr *tb[TCA_ACT_BPF_MAX + 1];
	struct tc_act_bpf *parm;

	SPRINT_BUF(action_buf);

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_ACT_BPF_MAX, arg);

	if (!tb[TCA_ACT_BPF_PARMS]) {
		fprintf(f, "[NULL bpf parameters]");
		return -1;
	}

	parm = RTA_DATA(tb[TCA_ACT_BPF_PARMS]);
	fprintf(f, "bpf ");

	if (tb[TCA_ACT_BPF_NAME])
		fprintf(f, "%s ", rta_getattr_str(tb[TCA_ACT_BPF_NAME]));
	else if (tb[TCA_ACT_BPF_FD])
		fprintf(f, "pfd %u ", rta_getattr_u32(tb[TCA_ACT_BPF_FD]));

	if (tb[TCA_ACT_BPF_OPS] && tb[TCA_ACT_BPF_OPS_LEN]) {
		bpf_print_ops(f, tb[TCA_ACT_BPF_OPS],
			      rta_getattr_u16(tb[TCA_ACT_BPF_OPS_LEN]));
		fprintf(f, " ");
	}

	fprintf(f, "default-action %s\n", action_n2a(parm->action, action_buf,
		sizeof(action_buf)));
	fprintf(f, "\tindex %d ref %d bind %d", parm->index, parm->refcnt,
		parm->bindcnt);

	if (show_stats) {
		if (tb[TCA_ACT_BPF_TM]) {
			struct tcf_t *tm = RTA_DATA(tb[TCA_ACT_BPF_TM]);

			print_tm(f, tm);
		}
	}

	fprintf(f, "\n ");
	return 0;
}
Exemple #5
0
const char *get_ifname_rta(int ifindex, const struct rtattr *rta)
{
	const char *name;

	if (rta) {
		name = rta_getattr_str(rta);
	} else {
		fprintf(stderr,
			"BUG: device with ifindex %d has nil ifname\n",
			ifindex);
		name = ll_idx_n2a(ifindex);
	}

	if (check_ifname(name))
		return NULL;

	return name;
}
Exemple #6
0
static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle)
{
	struct rtattr *tb[TCA_FW_MAX+1];

	if (opt == NULL)
		return 0;

	parse_rtattr_nested(tb, TCA_FW_MAX, opt);

	if (handle || tb[TCA_FW_MASK]) {
		__u32 mark = 0, mask = 0;
		if(handle)
			mark = handle;
		if(tb[TCA_FW_MASK] &&
		    (mask = rta_getattr_u32(tb[TCA_FW_MASK])) != 0xFFFFFFFF)
			fprintf(f, "handle 0x%x/0x%x ", mark, mask);
		else
			fprintf(f, "handle 0x%x ", handle);
	}

	if (tb[TCA_FW_CLASSID]) {
		SPRINT_BUF(b1);
		fprintf(f, "classid %s ", sprint_tc_classid(rta_getattr_u32(tb[TCA_FW_CLASSID]), b1));
	}

	if (tb[TCA_FW_POLICE])
		tc_print_police(f, tb[TCA_FW_POLICE]);
	if (tb[TCA_FW_INDEV]) {
		struct rtattr *idev = tb[TCA_FW_INDEV];
		fprintf(f, "input dev %s ",rta_getattr_str(idev));
	}

	if (tb[TCA_FW_ACT]) {
		fprintf(f, "\n");
		tc_print_action(f, tb[TCA_FW_ACT]);
	}
	return 0;
}
Exemple #7
0
static int get_response(struct nlmsghdr *n, void *arg)
{
	struct genlmsghdr *ghdr;
	struct l2tp_data *data = arg;
	struct l2tp_parm *p = &data->config;
	struct rtattr *attrs[L2TP_ATTR_MAX + 1];
	struct rtattr *nla_stats;
	int len;

	/* Validate message and parse attributes */
	if (n->nlmsg_type == NLMSG_ERROR)
		return -EBADMSG;

	ghdr = NLMSG_DATA(n);
	len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ghdr));
	if (len < 0)
		return -1;

	parse_rtattr(attrs, L2TP_ATTR_MAX, (void *)ghdr + GENL_HDRLEN, len);

	if (attrs[L2TP_ATTR_PW_TYPE])
		p->pw_type = rta_getattr_u16(attrs[L2TP_ATTR_PW_TYPE]);
	if (attrs[L2TP_ATTR_ENCAP_TYPE])
		p->encap = rta_getattr_u16(attrs[L2TP_ATTR_ENCAP_TYPE]);
	if (attrs[L2TP_ATTR_OFFSET])
		p->offset = rta_getattr_u16(attrs[L2TP_ATTR_OFFSET]);
	if (attrs[L2TP_ATTR_DATA_SEQ])
		p->data_seq = rta_getattr_u16(attrs[L2TP_ATTR_DATA_SEQ]);
	if (attrs[L2TP_ATTR_CONN_ID])
		p->tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_CONN_ID]);
	if (attrs[L2TP_ATTR_PEER_CONN_ID])
		p->peer_tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_CONN_ID]);
	if (attrs[L2TP_ATTR_SESSION_ID])
		p->session_id = rta_getattr_u32(attrs[L2TP_ATTR_SESSION_ID]);
	if (attrs[L2TP_ATTR_PEER_SESSION_ID])
		p->peer_session_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_SESSION_ID]);
	if (attrs[L2TP_ATTR_L2SPEC_TYPE])
		p->l2spec_type = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_TYPE]);
	if (attrs[L2TP_ATTR_L2SPEC_LEN])
		p->l2spec_len = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_LEN]);

	p->udp_csum = !!attrs[L2TP_ATTR_UDP_CSUM];
	if (attrs[L2TP_ATTR_COOKIE])
		memcpy(p->cookie, RTA_DATA(attrs[L2TP_ATTR_COOKIE]),
		       p->cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_COOKIE]));

	if (attrs[L2TP_ATTR_PEER_COOKIE])
		memcpy(p->peer_cookie, RTA_DATA(attrs[L2TP_ATTR_PEER_COOKIE]),
		       p->peer_cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_PEER_COOKIE]));

	p->recv_seq = !!attrs[L2TP_ATTR_RECV_SEQ];
	p->send_seq = !!attrs[L2TP_ATTR_SEND_SEQ];

	if (attrs[L2TP_ATTR_RECV_TIMEOUT])
		p->reorder_timeout = rta_getattr_u64(attrs[L2TP_ATTR_RECV_TIMEOUT]);
	if (attrs[L2TP_ATTR_IP_SADDR]) {
		p->local_ip.family = AF_INET;
		p->local_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_SADDR]);
		p->local_ip.bytelen = 4;
		p->local_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_IP_DADDR]) {
		p->peer_ip.family = AF_INET;
		p->peer_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_DADDR]);
		p->peer_ip.bytelen = 4;
		p->peer_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_IP6_SADDR]) {
		p->local_ip.family = AF_INET6;
		memcpy(&p->local_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_SADDR]),
			p->local_ip.bytelen = 16);
		p->local_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_IP6_DADDR]) {
		p->peer_ip.family = AF_INET6;
		memcpy(&p->peer_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_DADDR]),
			p->peer_ip.bytelen = 16);
		p->peer_ip.bitlen = -1;
	}
	if (attrs[L2TP_ATTR_UDP_SPORT])
		p->local_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_SPORT]);
	if (attrs[L2TP_ATTR_UDP_DPORT])
		p->peer_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_DPORT]);
	if (attrs[L2TP_ATTR_MTU])
		p->mtu = rta_getattr_u16(attrs[L2TP_ATTR_MTU]);
	if (attrs[L2TP_ATTR_IFNAME])
		p->ifname = rta_getattr_str(attrs[L2TP_ATTR_IFNAME]);

	nla_stats = attrs[L2TP_ATTR_STATS];
	if (nla_stats) {
		struct rtattr *tb[L2TP_ATTR_STATS_MAX + 1];

		parse_rtattr_nested(tb, L2TP_ATTR_STATS_MAX, nla_stats);

		if (tb[L2TP_ATTR_TX_PACKETS])
			data->stats.data_tx_packets = rta_getattr_u64(tb[L2TP_ATTR_TX_PACKETS]);
		if (tb[L2TP_ATTR_TX_BYTES])
			data->stats.data_tx_bytes = rta_getattr_u64(tb[L2TP_ATTR_TX_BYTES]);
		if (tb[L2TP_ATTR_TX_ERRORS])
			data->stats.data_tx_errors = rta_getattr_u64(tb[L2TP_ATTR_TX_ERRORS]);
		if (tb[L2TP_ATTR_RX_PACKETS])
			data->stats.data_rx_packets = rta_getattr_u64(tb[L2TP_ATTR_RX_PACKETS]);
		if (tb[L2TP_ATTR_RX_BYTES])
			data->stats.data_rx_bytes = rta_getattr_u64(tb[L2TP_ATTR_RX_BYTES]);
		if (tb[L2TP_ATTR_RX_ERRORS])
			data->stats.data_rx_errors = rta_getattr_u64(tb[L2TP_ATTR_RX_ERRORS]);
		if (tb[L2TP_ATTR_RX_SEQ_DISCARDS])
			data->stats.data_rx_oos_discards = rta_getattr_u64(tb[L2TP_ATTR_RX_SEQ_DISCARDS]);
		if (tb[L2TP_ATTR_RX_OOS_PACKETS])
			data->stats.data_rx_oos_packets = rta_getattr_u64(tb[L2TP_ATTR_RX_OOS_PACKETS]);
	}

	return 0;
}
Exemple #8
0
int print_link(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) {
	struct ndmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *ifattr[IFLA_MAX+1];
	struct rtattr *ifinfo[IFLA_INFO_MAX+1];
	struct rtattr *ifgreo[IFLA_GRE_MAX+1];
	const char *ifname;
	const char *kind;
	int link=0;
	int tunid=0;
	struct in_addr sip,dip;
	uint8_t ttl=0,tos=0;
	struct ifinfomsg *ifi;

	sip.s_addr=dip.s_addr=htonl(0);

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) {
		fprintf(stderr, "Not RTM_xxxLINK: %08x %08x %08x\n", n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	ifi=(void *)r;

	parse_rtattr(ifattr, IFLA_MAX, IFLA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
	if (ifattr[IFLA_IFNAME])
		ifname=rta_getattr_str(ifattr[IFLA_IFNAME]);
	else
		ifname="";
	if (ifattr[IFLA_LINKINFO])
		parse_rtattr(ifinfo, IFLA_INFO_MAX, (void *)rta_getattr_str(ifattr[IFLA_LINKINFO]), ifattr[IFLA_LINKINFO]->rta_len);
	else
		memset(ifinfo,0,sizeof ifinfo);
	if (ifinfo[IFLA_INFO_KIND])
		kind=rta_getattr_str(ifinfo[IFLA_INFO_KIND]);
	else
		kind="";
	if (!strcmp(kind,"eoip") && ifinfo[IFLA_INFO_DATA]) {
		char ts[IFNAMSIZ],td[IFNAMSIZ];

		parse_rtattr(ifgreo, IFLA_GRE_MAX, (void *)rta_getattr_str(ifinfo[IFLA_INFO_DATA]), ifinfo[IFLA_INFO_DATA]->rta_len);
		if (ifgreo[IFLA_GRE_LINK])
			link=rta_getattr_u32(ifgreo[IFLA_GRE_LINK]);
		if (ifgreo[IFLA_GRE_TOS])
			tos=rta_getattr_u8(ifgreo[IFLA_GRE_TOS]);
		if (ifgreo[IFLA_GRE_TTL])
			ttl=rta_getattr_u8(ifgreo[IFLA_GRE_TTL]);
		if (ifgreo[IFLA_GRE_LOCAL])
			sip.s_addr=rta_getattr_u32(ifgreo[IFLA_GRE_LOCAL]);
		if (ifgreo[IFLA_GRE_REMOTE])
			dip.s_addr=rta_getattr_u32(ifgreo[IFLA_GRE_REMOTE]);
		if (ifgreo[IFLA_GRE_IKEY])
			tunid=rta_getattr_u32(ifgreo[IFLA_GRE_IKEY]);
		strcpy(ts,inet_ntoa(sip));
		strcpy(td,inet_ntoa(dip));
		printf("%d: %s@%d: link/%s %s remote %s tunnel-id %d ttl %d tos %d\n",ifi->ifi_index,ifname,link,kind,ts,td,tunid,ttl,tos);
	}

	return 0;
}
Exemple #9
0
int print_qdisc(const struct sockaddr_nl *who,
		       struct nlmsghdr *n,
		       void *arg)
{
	FILE *fp = (FILE *)arg;
	struct tcmsg *t = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[TCA_MAX+1];
	struct qdisc_util *q;
	char abuf[256];

	if (n->nlmsg_type != RTM_NEWQDISC && n->nlmsg_type != RTM_DELQDISC) {
		fprintf(stderr, "Not a qdisc\n");
		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*t));
	if (len < 0) {
		fprintf(stderr, "Wrong len %d\n", len);
		return -1;
	}

	if (filter_ifindex && filter_ifindex != t->tcm_ifindex)
		return 0;

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len);

	if (tb[TCA_KIND] == NULL) {
		fprintf(stderr, "print_qdisc: NULL kind\n");
		return -1;
	}

	if (n->nlmsg_type == RTM_DELQDISC)
		fprintf(fp, "deleted ");

	fprintf(fp, "qdisc %s %x: ", rta_getattr_str(tb[TCA_KIND]), t->tcm_handle>>16);
	if (filter_ifindex == 0)
		fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));
	if (t->tcm_parent == TC_H_ROOT)
		fprintf(fp, "root ");
	else if (t->tcm_parent) {
		print_tc_classid(abuf, sizeof(abuf), t->tcm_parent);
		fprintf(fp, "parent %s ", abuf);
	}
	if (t->tcm_info != 1) {
		fprintf(fp, "refcnt %d ", t->tcm_info);
	}
	/* pfifo_fast is generic enough to warrant the hardcoding --JHS */

	if (0 == strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND])))
		q = get_qdisc_kind("prio");
	else
		q = get_qdisc_kind(RTA_DATA(tb[TCA_KIND]));

	if (tb[TCA_OPTIONS]) {
		if (q)
			q->print_qopt(q, fp, tb[TCA_OPTIONS]);
		else
			fprintf(fp, "[cannot parse qdisc parameters]");
	}
	fprintf(fp, "\n");
	if (show_details && tb[TCA_STAB]) {
		print_size_table(fp, " ", tb[TCA_STAB]);
		fprintf(fp, "\n");
	}
	if (show_stats) {
		struct rtattr *xstats = NULL;

		if (tb[TCA_STATS] || tb[TCA_STATS2] || tb[TCA_XSTATS]) {
			print_tcstats_attr(fp, tb, " ", &xstats);
			fprintf(fp, "\n");
		}

		if (q && xstats && q->print_xstats) {
			q->print_xstats(q, fp, xstats);
			fprintf(fp, "\n");
		}
	}
	fflush(fp);
	return 0;
}
Exemple #10
0
static int
netl_handler(struct netl_handle *h,
			 pktj_unused(struct sockaddr_nl *nladdr),
			 struct nlmsghdr *hdr, void *args)
{
	int len = hdr->nlmsg_len;

	switch (hdr->nlmsg_type) {
		// TODO RTM_SETLINK
	case RTM_NEWLINK:
	case RTM_DELLINK:
		{
			struct ifinfomsg *ifi = NLMSG_DATA(hdr);
			struct rtattr *rta_tb[IFLA_MAX + 1];
			struct ether_addr lladdr;
			int ifid = ifi->ifi_index;
			int mtu = -1;
			const char *ifname = "";
			uint16_t vlanid = 0;
			oper_state_t state = LINK_UNKNOWN;
			link_action_t action = LINK_ADD;

			len -= NLMSG_LENGTH(sizeof(*ifi));

			if (len < 0) {
				// incomplete message
				return -1;
			}

			parse_rtattr_flags(rta_tb, IFLA_MAX, IFLA_RTA(ifi), len, 0);

			if (ifi->ifi_type != ARPHRD_ETHER)
				return 0;		// This is not ethernet
			if (rta_tb[IFLA_IFNAME] == NULL)
				return -1;		// There should be a name, this is a bug

			if (hdr->nlmsg_type == RTM_DELLINK)
				action = LINK_DELETE;

			if (rta_tb[IFLA_MTU])
				mtu = *(int *) RTA_DATA(rta_tb[IFLA_MTU]);
			if (rta_tb[IFLA_IFNAME])
				ifname = rta_getattr_str(rta_tb[IFLA_IFNAME]);
			if (rta_tb[IFLA_OPERSTATE])
				state = rta_getattr_u8(rta_tb[IFLA_OPERSTATE]);
			if (rta_tb[IFLA_ADDRESS])
				memcpy(&lladdr.addr_bytes, RTA_DATA(rta_tb[IFLA_ADDRESS]),
					   sizeof(lladdr.addr_bytes));

			if (rta_tb[IFLA_LINKINFO]) {
				struct rtattr *linkinfo[IFLA_INFO_MAX + 1];
				parse_rtattr_nested(linkinfo, IFLA_INFO_MAX,
									rta_tb[IFLA_LINKINFO]);
				if (linkinfo[IFLA_INFO_KIND]) {
					char *kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
					//XXX only handle vlan type for now
					if (!strcmp(kind, "vlan")) {
						vlanid = get_vlan_id(linkinfo);
					} else {
						//TODO receive an IF without vlan id
					}
				}

			}

			if (h->cb.link != NULL) {
				h->cb.link(action, ifid, &lladdr, mtu,
						   ifname, state, vlanid, args);
			}

		}
		break;
	}


	if (hdr->nlmsg_type == RTM_NEWADDR || hdr->nlmsg_type == RTM_DELADDR) {
		//struct if_rtattrs attrs;
		struct rtattr *rta_tb[IFA_MAX + 1];
		struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
		//unsigned int ifa_flags;
		unsigned char buf_addr[sizeof(struct in6_addr)];
		addr_action_t action;
		len -= NLMSG_LENGTH(sizeof(*ifa));

		if (len < 0) {
			// incomplete message
			return -1;
		}

		if (hdr->nlmsg_type == RTM_NEWADDR)
			action = ADDR_ADD;
		else if (hdr->nlmsg_type == RTM_DELADDR)
			action = ADDR_DELETE;
		else
			return -1;


		parse_rtattr_flags(rta_tb, IFA_MAX, IFA_RTA(ifa), len, 0);
		//ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]);

		if (!rta_tb[IFA_LOCAL])
			rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
		if (!rta_tb[IFA_ADDRESS])
			rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];

		if (rta_tb[IFA_LOCAL]) {
			//we may optimize by passing directly RTA_DATA(rta_tb[IFA_LOCAL]) to the cb
			memcpy(buf_addr, RTA_DATA(rta_tb[IFA_LOCAL]),
				   RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
		}
		switch (ifa->ifa_family) {
		case AF_INET:
			if (h->cb.addr4 != NULL) {
				h->cb.addr4(action, ifa->ifa_index,
							(struct in_addr *) buf_addr,
							ifa->ifa_prefixlen, args);
			}
			break;
		case AF_INET6:
			if (h->cb.addr6 != NULL) {
				h->cb.addr6(action, ifa->ifa_index,
							(struct in6_addr *) buf_addr,
							ifa->ifa_prefixlen, args);
			}
			break;
		default:
			//only handling IP
			return -1;
		}
	}

	if (hdr->nlmsg_type == RTM_NEWROUTE || hdr->nlmsg_type == RTM_DELROUTE) {
		struct rtattr *tb[RTA_MAX + 1];
		struct rtmsg *r = NLMSG_DATA(hdr);
		//__u32 table;
		len -= NLMSG_LENGTH(sizeof(*r));

		if (len < 0) {
			// incomplete message
			return -1;
		}

		if (r->rtm_family != RTNL_FAMILY_IPMR &&
			r->rtm_family != RTNL_FAMILY_IP6MR) {
			// This is an unicast route, no interest for multicast
			route_action_t action;
			if (hdr->nlmsg_type == RTM_NEWROUTE)
				action = ROUTE_ADD;
			else
				action = ROUTE_DELETE;

			parse_rtattr_flags(tb, RTA_MAX, RTM_RTA(r), len, 0);
			//table = rtm_get_table(r, tb);

			switch(r->rtm_type) {
				case RTN_UNICAST:
					if (!tb[RTA_DST])
						return 0;

					if (!tb[RTA_GATEWAY])
						return 0;
				case RTN_BLACKHOLE:
					break;
				default:
					return 0;
			}

			switch (r->rtm_family) {
			case AF_INET:
				if (h->cb.route4 != NULL) {
					h->cb.route4(r, action, RTA_DATA(tb[RTA_DST]),
								 r->rtm_dst_len, RTA_DATA(tb[RTA_GATEWAY]),
								 r->rtm_type, args);
				}
				break;
			case AF_INET6:
				if (h->cb.route6 != NULL) {
					h->cb.route6(r, action, RTA_DATA(tb[RTA_DST]),
								 r->rtm_dst_len, RTA_DATA(tb[RTA_GATEWAY]),
								 r->rtm_type, args);
				}
				break;
			default:
				//only handling IP
				return 0;
			}
		}
	}

	if (hdr->nlmsg_type == RTM_NEWNEIGH || hdr->nlmsg_type == RTM_DELNEIGH) {
		struct ndmsg *neighbor = NLMSG_DATA(hdr);
		struct rtattr *tb[NDA_MAX + 1];
		uint16_t vlanid = 0;

		len -= NLMSG_LENGTH(sizeof(*neighbor));

		if (len < 0) {
			// incomplete message
			return -1;
		}
		// Ignore non-ip
		if (neighbor->ndm_family != AF_INET &&
			neighbor->ndm_family != AF_INET6)
			return 0;

		parse_rtattr_flags(tb, NDA_MAX, RTM_RTA(neighbor), len, 0);

		neighbor_action_t action;
		if (hdr->nlmsg_type == RTM_NEWNEIGH)
			action = NEIGHBOR_ADD;
		else
			action = NEIGHBOR_DELETE;
		if (tb[NDA_VLAN])
			vlanid = rta_getattr_u16(tb[NDA_VLAN]);
		switch (neighbor->ndm_family) {
		case AF_INET:
			if (h->cb.neighbor4 != NULL) {
				if (tb[NDA_LLADDR]) {
					h->cb.neighbor4(action, neighbor->ndm_ifindex,
									RTA_DATA(tb[NDA_DST]),
									RTA_DATA(tb[NDA_LLADDR]),
									neighbor->ndm_state, vlanid, args);
				} else {
					h->cb.neighbor4(action, neighbor->ndm_ifindex,
									RTA_DATA(tb[NDA_DST]),
									&invalid_mac,
									neighbor->ndm_state, vlanid, args);
				}
			}
			break;
		case AF_INET6:
			if (h->cb.neighbor6 != NULL) {
				if (tb[NDA_LLADDR]) {
					h->cb.neighbor6(action, neighbor->ndm_ifindex,
									RTA_DATA(tb[NDA_DST]),
									RTA_DATA(tb[NDA_LLADDR]),
									neighbor->ndm_state, vlanid, args);
				} else {
					h->cb.neighbor6(action, neighbor->ndm_ifindex,
									RTA_DATA(tb[NDA_DST]),
									&invalid_mac,
									neighbor->ndm_state, vlanid, args);
				}
			}
			break;
		default:
			//only handling IP
			return 0;
		}
	}

	return 0;
}
Exemple #11
0
int print_linkinfo(const struct sockaddr_nl *who,
		   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

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

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return 0;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return 0;

	if (tb[IFLA_GROUP]) {
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		if (filter.group != -1 && group != filter.group)
			return -1;
	}

	if (tb[IFLA_MASTER]) {
		int master = *(int*)RTA_DATA(tb[IFLA_MASTER]);
		if (filter.master > 0 && master != filter.master)
			return -1;
	}
	else if (filter.master > 0)
		return -1;

	if (filter.kind) {
		if (tb[IFLA_LINKINFO]) {
			char *kind = parse_link_kind(tb[IFLA_LINKINFO]);

			if (strcmp(kind, filter.kind))
				return -1;
		} else {
			return -1;
		}
	}

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

	fprintf(fp, "%d: ", ifi->ifi_index);
	color_fprintf(fp, COLOR_IFNAME, "%s",
		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			fprintf(fp, "@NONE: ");
		else {
			if (tb[IFLA_LINK_NETNSID])
				fprintf(fp, "@if%d: ", iflink);
			else {
				fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
				m_flag = ll_index_to_flags(iflink);
				m_flag = !(m_flag & IFF_UP);
			}
		}
	} else {
		fprintf(fp, ": ");
	}
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}

	if (tb[IFLA_PHYS_PORT_ID]) {
		SPRINT_BUF(b1);
		fprintf(fp, "portid %s ",
			hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_PORT_ID]),
				      RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]),
				      b1, sizeof(b1)));
	}

	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

	if (do_link && tb[IFLA_LINKMODE])
		print_linkmode(fp, tb[IFLA_LINKMODE]);

	if (tb[IFLA_GROUP]) {
		SPRINT_BUF(b1);
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		fprintf(fp, "group %s ", rtnl_group_n2a(group, b1, sizeof(b1)));
	}

	if (filter.showqueue)
		print_queuelen(fp, tb);

	if (!filter.family || filter.family == AF_PACKET || show_details) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));

		if (tb[IFLA_ADDRESS]) {
			color_fprintf(fp, COLOR_MAC, "%s",
					ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						ifi->ifi_type,
						b1, sizeof(b1)));
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags&IFF_POINTOPOINT)
				fprintf(fp, " peer ");
			else
				fprintf(fp, " brd ");
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
	}

	if (tb[IFLA_LINK_NETNSID]) {
		int id = *(int*)RTA_DATA(tb[IFLA_LINK_NETNSID]);

		if (id >= 0)
			fprintf(fp, " link-netnsid %d", id);
		else
			fprintf(fp, " link-netnsid unknown");
	}

	if (tb[IFLA_PROMISCUITY] && show_details)
		fprintf(fp, " promiscuity %u ",
			*(int*)RTA_DATA(tb[IFLA_PROMISCUITY]));

	if (tb[IFLA_LINKINFO] && show_details)
		print_linktype(fp, tb[IFLA_LINKINFO]);

	if (do_link && tb[IFLA_AF_SPEC] && show_details)
		print_af_spec(fp, tb[IFLA_AF_SPEC]);

	if ((do_link || show_details) && tb[IFLA_IFALIAS]) {
		fprintf(fp, "%s    alias %s", _SL_,
			rta_getattr_str(tb[IFLA_IFALIAS]));
	}

	if (do_link && show_stats) {
		fprintf(fp, "%s", _SL_);
		__print_link_stats(fp, tb);
	}

	if ((do_link || show_details) && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
		int rem = RTA_PAYLOAD(vflist);
		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			print_vfinfo(fp, i);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 1;
}
Exemple #12
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);

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

	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_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;
}
Exemple #13
0
static int print_ntable(struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;
	struct ndtmsg *ndtm = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[NDTA_MAX+1];
	struct rtattr *tpb[NDTPA_MAX+1];
	int ret;

	if (n->nlmsg_type != RTM_NEWNEIGHTBL) {
		fprintf(stderr, "Not NEIGHTBL: %08x %08x %08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*ndtm));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	if (preferred_family && preferred_family != ndtm->ndtm_family)
		return 0;

	parse_rtattr(tb, NDTA_MAX, NDTA_RTA(ndtm),
		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm)));

	if (tb[NDTA_NAME]) {
		const char *name = rta_getattr_str(tb[NDTA_NAME]);

		if (filter.name && strcmp(filter.name, name))
			return 0;
	}

	if (tb[NDTA_PARMS]) {
		parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]),
			     RTA_PAYLOAD(tb[NDTA_PARMS]));

		if (tpb[NDTPA_IFINDEX]) {
			__u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]);

			if (filter.index && filter.index != ifindex)
				return 0;
		} else {
			if (filter.index && filter.index != NONE_DEV)
				return 0;
		}
	}

	open_json_object(NULL);
	print_string(PRINT_ANY, "family",
		     "%s ", family_name(ndtm->ndtm_family));

	if (tb[NDTA_NAME]) {
		const char *name = rta_getattr_str(tb[NDTA_NAME]);

		print_string(PRINT_ANY, "name", "%s ", name);
	}

	print_nl();

	ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] ||
	       tb[NDTA_GC_INTERVAL]);
	if (ret)
		print_string(PRINT_FP, NULL, "    ", NULL);

	if (tb[NDTA_THRESH1]) {
		__u32 thresh1 = rta_getattr_u32(tb[NDTA_THRESH1]);

		print_uint(PRINT_ANY, "thresh1", "thresh1 %u ", thresh1);
	}

	if (tb[NDTA_THRESH2]) {
		__u32 thresh2 = rta_getattr_u32(tb[NDTA_THRESH2]);

		print_uint(PRINT_ANY, "thresh2", "thresh2 %u ", thresh2);
	}

	if (tb[NDTA_THRESH3]) {
		__u32 thresh3 = rta_getattr_u32(tb[NDTA_THRESH3]);

		print_uint(PRINT_ANY, "thresh3", "thresh3 %u ", thresh3);
	}

	if (tb[NDTA_GC_INTERVAL]) {
		__u64 gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]);

		print_u64(PRINT_ANY, "gc_interval", "gc_int %llu ", gc_int);
	}

	if (ret)
		print_nl();

	if (tb[NDTA_CONFIG] && show_stats)
		print_ndtconfig(RTA_DATA(tb[NDTA_CONFIG]));

	if (tb[NDTA_PARMS])
		print_ndtparams(tpb);

	if (tb[NDTA_STATS] && show_stats)
		print_ndtstats(RTA_DATA(tb[NDTA_STATS]));

	print_string(PRINT_FP, NULL, "\n", "");
	close_json_object();
	fflush(fp);

	return 0;
}
Exemple #14
0
static int
print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
{
	struct rtattr *tb[TCA_IPT_MAX + 1];
	struct xt_entry_target *t = NULL;

	if (arg == NULL)
		return -1;

	xtables_init_all(&tcipt_globals, NFPROTO_IPV4);
	set_lib_dir();

	parse_rtattr_nested(tb, TCA_IPT_MAX, arg);

	if (tb[TCA_IPT_TABLE] == NULL) {
		fprintf(f, "[NULL ipt table name ] assuming mangle ");
	} else {
		fprintf(f, "tablename: %s ",
			rta_getattr_str(tb[TCA_IPT_TABLE]));
	}

	if (tb[TCA_IPT_HOOK] == NULL) {
		fprintf(f, "[NULL ipt hook name ]\n ");
		return -1;
	} else {
		__u32 hook;
		hook = rta_getattr_u32(tb[TCA_IPT_HOOK]);
		fprintf(f, " hook: %s \n", ipthooks[hook]);
	}

	if (tb[TCA_IPT_TARG] == NULL) {
		fprintf(f, "\t[NULL ipt target parameters ] \n");
		return -1;
	} else {
		struct xtables_target *m = NULL;
		t = RTA_DATA(tb[TCA_IPT_TARG]);
		m = xtables_find_target(t->u.user.name, XTF_TRY_LOAD);
		if (NULL != m) {
			if (0 > build_st(m, t)) {
				fprintf(stderr, " %s error \n", m->name);
				return -1;
			}

			tcipt_globals.opts =
			    xtables_merge_options(
#if (XTABLES_VERSION_CODE >= 6)
				                  tcipt_globals.orig_opts,
#endif
				                  tcipt_globals.opts,
			                          m->extra_opts,
			                          &m->option_offset);
		} else {
			fprintf(stderr, " failed to find target %s\n\n",
				t->u.user.name);
			return -1;
		}
		fprintf(f, "\ttarget ");
		m->print(NULL, m->t, 0);
		if (tb[TCA_IPT_INDEX] == NULL) {
			fprintf(f, " [NULL ipt target index ]\n");
		} else {
			__u32 index;
			index = rta_getattr_u32(tb[TCA_IPT_INDEX]);
			fprintf(f, " \n\tindex %d", index);
		}

		if (tb[TCA_IPT_CNT]) {
			struct tc_cnt *c  = RTA_DATA(tb[TCA_IPT_CNT]);;
			fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt);
		}
		if (show_stats) {
			if (tb[TCA_IPT_TM]) {
				struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]);
				print_tm(f,tm);
			}
		}
		fprintf(f, " \n");

	}
	xtables_free_opts(1);

	return 0;
}
Exemple #15
0
int print_linkinfo(const struct sockaddr_nl *who,
		   struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr * tb[IFLA_MAX+1];
	int len = n->nlmsg_len;
	unsigned m_flag = 0;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

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

	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
		return 0;
	if (filter.up && !(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
	}
	if (filter.label &&
	    (!filter.family || filter.family == AF_PACKET) &&
	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
		return 0;

	if (tb[IFLA_GROUP]) {
		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
		if (group != filter.group)
			return -1;
	}

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

	fprintf(fp, "%d: %s", ifi->ifi_index,
		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

	if (tb[IFLA_LINK]) {
		SPRINT_BUF(b1);
		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
		if (iflink == 0)
			fprintf(fp, "@NONE: ");
		else {
			fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
			m_flag = ll_index_to_flags(iflink);
			m_flag = !(m_flag & IFF_UP);
		}
	} else {
		fprintf(fp, ": ");
	}
	print_link_flags(fp, ifi->ifi_flags, m_flag);

	if (tb[IFLA_MTU])
		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}

	if (tb[IFLA_OPERSTATE])
		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

	if (do_link && tb[IFLA_LINKMODE])
		print_linkmode(fp, tb[IFLA_LINKMODE]);

	if (filter.showqueue)
		print_queuelen(fp, tb);

	if (!filter.family || filter.family == AF_PACKET) {
		SPRINT_BUF(b1);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));

		if (tb[IFLA_ADDRESS]) {
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						      RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags&IFF_POINTOPOINT)
				fprintf(fp, " peer ");
			else
				fprintf(fp, " brd ");
			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)));
		}
	}

	if (do_link && tb[IFLA_LINKINFO] && show_details)
		print_linktype(fp, tb[IFLA_LINKINFO]);

	if (do_link && tb[IFLA_IFALIAS])
		fprintf(fp,"\n    alias %s", 
			rta_getattr_str(tb[IFLA_IFALIAS]));

	if (do_link && show_stats) {
		if (tb[IFLA_STATS64])
			print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]));
		else if (tb[IFLA_STATS])
			print_link_stats(fp, RTA_DATA(tb[IFLA_STATS]));
	}

	if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
		int rem = RTA_PAYLOAD(vflist);
		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			print_vfinfo(fp, i);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 0;
}
Exemple #16
0
static int
print_ipt(struct action_util *au, FILE * f, struct rtattr *arg)
{
	struct rtattr *tb[TCA_IPT_MAX + 1];
	struct xt_entry_target *t = NULL;

	if (arg == NULL)
		return -1;

	set_lib_dir();

	parse_rtattr_nested(tb, TCA_IPT_MAX, arg);

	if (tb[TCA_IPT_TABLE] == NULL) {
		fprintf(f, "[NULL ipt table name ] assuming mangle ");
	} else {
		fprintf(f, "tablename: %s ",
			rta_getattr_str(tb[TCA_IPT_TABLE]));
	}

	if (tb[TCA_IPT_HOOK] == NULL) {
		fprintf(f, "[NULL ipt hook name ]\n ");
		return -1;
	} else {
		__u32 hook;

		hook = rta_getattr_u32(tb[TCA_IPT_HOOK]);
		fprintf(f, " hook: %s\n", ipthooks[hook]);
	}

	if (tb[TCA_IPT_TARG] == NULL) {
		fprintf(f, "\t[NULL ipt target parameters ]\n");
		return -1;
	} else {
		struct xtables_target *m = NULL;

		t = RTA_DATA(tb[TCA_IPT_TARG]);
		m = find_target(t->u.user.name, TRY_LOAD);
		if (m != NULL) {
			if (build_st(m, t) < 0) {
				fprintf(stderr, " %s error\n", m->name);
				return -1;
			}

			opts =
			    merge_options(opts, m->extra_opts,
					  &m->option_offset);
		} else {
			fprintf(stderr, " failed to find target %s\n\n",
				t->u.user.name);
			return -1;
		}
		fprintf(f, "\ttarget ");
		m->print(NULL, m->t, 0);
		if (tb[TCA_IPT_INDEX] == NULL) {
			fprintf(f, " [NULL ipt target index ]\n");
		} else {
			__u32 index;

			index = rta_getattr_u32(tb[TCA_IPT_INDEX]);
			fprintf(f, "\n\tindex %u", index);
		}

		if (tb[TCA_IPT_CNT]) {
			struct tc_cnt *c  = RTA_DATA(tb[TCA_IPT_CNT]);

			fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt);
		}
		if (show_stats) {
			if (tb[TCA_IPT_TM]) {
				struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]);

				print_tm(f, tm);
			}
		}
		fprintf(f, "\n");

	}
	free_opts(opts);

	return 0;
}
Exemple #17
0
int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ndtmsg *ndtm = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *tb[NDTA_MAX+1];
	struct rtattr *tpb[NDTPA_MAX+1];
	int ret;

	if (n->nlmsg_type != RTM_NEWNEIGHTBL) {
		fprintf(stderr, "Not NEIGHTBL: %08x %08x %08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}
	len -= NLMSG_LENGTH(sizeof(*ndtm));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	if (preferred_family && preferred_family != ndtm->ndtm_family)
		return 0;

	parse_rtattr(tb, NDTA_MAX, NDTA_RTA(ndtm),
		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm)));

	if (tb[NDTA_NAME]) {
		const char *name = rta_getattr_str(tb[NDTA_NAME]);

		if (strlen(filter.name) > 0 && strcmp(filter.name, name))
			return 0;
	}
	if (tb[NDTA_PARMS]) {
		parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]),
			     RTA_PAYLOAD(tb[NDTA_PARMS]));

		if (tpb[NDTPA_IFINDEX]) {
			__u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]);

			if (filter.index && filter.index != ifindex)
				return 0;
		} else {
			if (filter.index && filter.index != NONE_DEV)
				return 0;
		}
	}

	if (ndtm->ndtm_family == AF_INET)
		fprintf(fp, "inet ");
	else if (ndtm->ndtm_family == AF_INET6)
		fprintf(fp, "inet6 ");
	else if (ndtm->ndtm_family == AF_DECnet)
		fprintf(fp, "dnet ");
	else
		fprintf(fp, "(%d) ", ndtm->ndtm_family);

	if (tb[NDTA_NAME]) {
		const char *name = rta_getattr_str(tb[NDTA_NAME]);
		fprintf(fp, "%s ", name);
	}

	fprintf(fp, "%s", _SL_);

	ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] ||
	       tb[NDTA_GC_INTERVAL]);
	if (ret)
		fprintf(fp, "    ");

	if (tb[NDTA_THRESH1]) {
		__u32 thresh1 = rta_getattr_u32(tb[NDTA_THRESH1]);
		fprintf(fp, "thresh1 %u ", thresh1);
	}
	if (tb[NDTA_THRESH2]) {
		__u32 thresh2 = rta_getattr_u32(tb[NDTA_THRESH2]);
		fprintf(fp, "thresh2 %u ", thresh2);
	}
	if (tb[NDTA_THRESH3]) {
		__u32 thresh3 = rta_getattr_u32(tb[NDTA_THRESH3]);
		fprintf(fp, "thresh3 %u ", thresh3);
	}
	if (tb[NDTA_GC_INTERVAL]) {
		unsigned long long gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]);
		fprintf(fp, "gc_int %llu ", gc_int);
	}

	if (ret)
		fprintf(fp, "%s", _SL_);

	if (tb[NDTA_CONFIG] && show_stats) {
		struct ndt_config *ndtc = RTA_DATA(tb[NDTA_CONFIG]);

		fprintf(fp, "    ");
		fprintf(fp, "config ");

		fprintf(fp, "key_len %u ", ndtc->ndtc_key_len);
		fprintf(fp, "entry_size %u ", ndtc->ndtc_entry_size);
		fprintf(fp, "entries %u ", ndtc->ndtc_entries);

		fprintf(fp, "%s", _SL_);
		fprintf(fp, "        ");

		fprintf(fp, "last_flush %s ",
			ntable_strtime_delta(ndtc->ndtc_last_flush));
		fprintf(fp, "last_rand %s ",
			ntable_strtime_delta(ndtc->ndtc_last_rand));

		fprintf(fp, "%s", _SL_);
		fprintf(fp, "        ");

		fprintf(fp, "hash_rnd %u ", ndtc->ndtc_hash_rnd);
		fprintf(fp, "hash_mask %08x ", ndtc->ndtc_hash_mask);

		fprintf(fp, "hash_chain_gc %u ", ndtc->ndtc_hash_chain_gc);
		fprintf(fp, "proxy_qlen %u ", ndtc->ndtc_proxy_qlen);

		fprintf(fp, "%s", _SL_);
	}

	if (tb[NDTA_PARMS]) {
		if (tpb[NDTPA_IFINDEX]) {
			__u32 ifindex = rta_getattr_u32(tpb[NDTPA_IFINDEX]);

			fprintf(fp, "    ");
			fprintf(fp, "dev %s ", ll_index_to_name(ifindex));
			fprintf(fp, "%s", _SL_);
		}

		fprintf(fp, "    ");

		if (tpb[NDTPA_REFCNT]) {
			__u32 refcnt = rta_getattr_u32(tpb[NDTPA_REFCNT]);
			fprintf(fp, "refcnt %u ", refcnt);
		}
		if (tpb[NDTPA_REACHABLE_TIME]) {
			unsigned long long reachable = rta_getattr_u64(tpb[NDTPA_REACHABLE_TIME]);
			fprintf(fp, "reachable %llu ", reachable);
		}
		if (tpb[NDTPA_BASE_REACHABLE_TIME]) {
			unsigned long long breachable = rta_getattr_u64(tpb[NDTPA_BASE_REACHABLE_TIME]);
			fprintf(fp, "base_reachable %llu ", breachable);
		}
		if (tpb[NDTPA_RETRANS_TIME]) {
			unsigned long long retrans = rta_getattr_u64(tpb[NDTPA_RETRANS_TIME]);
			fprintf(fp, "retrans %llu ", retrans);
		}

		fprintf(fp, "%s", _SL_);

		fprintf(fp, "    ");

		if (tpb[NDTPA_GC_STALETIME]) {
			unsigned long long gc_stale = rta_getattr_u64(tpb[NDTPA_GC_STALETIME]);
			fprintf(fp, "gc_stale %llu ", gc_stale);
		}
		if (tpb[NDTPA_DELAY_PROBE_TIME]) {
			unsigned long long delay_probe = rta_getattr_u64(tpb[NDTPA_DELAY_PROBE_TIME]);
			fprintf(fp, "delay_probe %llu ", delay_probe);
		}
		if (tpb[NDTPA_QUEUE_LEN]) {
			__u32 queue = rta_getattr_u32(tpb[NDTPA_QUEUE_LEN]);
			fprintf(fp, "queue %u ", queue);
		}

		fprintf(fp, "%s", _SL_);

		fprintf(fp, "    ");

		if (tpb[NDTPA_APP_PROBES]) {
			__u32 aprobe = rta_getattr_u32(tpb[NDTPA_APP_PROBES]);
			fprintf(fp, "app_probes %u ", aprobe);
		}
		if (tpb[NDTPA_UCAST_PROBES]) {
			__u32 uprobe = rta_getattr_u32(tpb[NDTPA_UCAST_PROBES]);
			fprintf(fp, "ucast_probes %u ", uprobe);
		}
		if (tpb[NDTPA_MCAST_PROBES]) {
			__u32 mprobe = rta_getattr_u32(tpb[NDTPA_MCAST_PROBES]);
			fprintf(fp, "mcast_probes %u ", mprobe);
		}

		fprintf(fp, "%s", _SL_);

		fprintf(fp, "    ");

		if (tpb[NDTPA_ANYCAST_DELAY]) {
			unsigned long long anycast_delay = rta_getattr_u64(tpb[NDTPA_ANYCAST_DELAY]);
			fprintf(fp, "anycast_delay %llu ", anycast_delay);
		}
		if (tpb[NDTPA_PROXY_DELAY]) {
			unsigned long long proxy_delay = rta_getattr_u64(tpb[NDTPA_PROXY_DELAY]);
			fprintf(fp, "proxy_delay %llu ", proxy_delay);
		}
		if (tpb[NDTPA_PROXY_QLEN]) {
			__u32 pqueue = rta_getattr_u32(tpb[NDTPA_PROXY_QLEN]);
			fprintf(fp, "proxy_queue %u ", pqueue);
		}
		if (tpb[NDTPA_LOCKTIME]) {
			unsigned long long locktime = rta_getattr_u64(tpb[NDTPA_LOCKTIME]);
			fprintf(fp, "locktime %llu ", locktime);
		}

		fprintf(fp, "%s", _SL_);
	}

	if (tb[NDTA_STATS] && show_stats) {
		struct ndt_stats *ndts = RTA_DATA(tb[NDTA_STATS]);

		fprintf(fp, "    ");
		fprintf(fp, "stats ");

		fprintf(fp, "allocs %llu ",
			(unsigned long long) ndts->ndts_allocs);
		fprintf(fp, "destroys %llu ",
			(unsigned long long) ndts->ndts_destroys);
		fprintf(fp, "hash_grows %llu ",
			(unsigned long long) ndts->ndts_hash_grows);

		fprintf(fp, "%s", _SL_);
		fprintf(fp, "        ");

		fprintf(fp, "res_failed %llu ",
			(unsigned long long) ndts->ndts_res_failed);
		fprintf(fp, "lookups %llu ",
			(unsigned long long) ndts->ndts_lookups);
		fprintf(fp, "hits %llu ",
			(unsigned long long) ndts->ndts_hits);

		fprintf(fp, "%s", _SL_);
		fprintf(fp, "        ");

		fprintf(fp, "rcv_probes_mcast %llu ",
			(unsigned long long) ndts->ndts_rcv_probes_mcast);
		fprintf(fp, "rcv_probes_ucast %llu ",
			(unsigned long long) ndts->ndts_rcv_probes_ucast);

		fprintf(fp, "%s", _SL_);
		fprintf(fp, "        ");

		fprintf(fp, "periodic_gc_runs %llu ",
			(unsigned long long) ndts->ndts_periodic_gc_runs);
		fprintf(fp, "forced_gc_runs %llu ",
			(unsigned long long) ndts->ndts_forced_gc_runs);

		fprintf(fp, "%s", _SL_);
	}

	fprintf(fp, "\n");

	fflush(fp);
	return 0;
}
Exemple #18
0
static int parse_ipt(struct action_util *a,int *argc_p,
		     char ***argv_p, int tca_id, struct nlmsghdr *n)
{
	struct xtables_target *m = NULL;
	struct ipt_entry fw;
	struct rtattr *tail;

	int c;
	int rargc = *argc_p;
	char **argv = *argv_p;
	int argc = 0, iargc = 0;
	char k[16];
	int size = 0;
	int iok = 0, ok = 0;
	__u32 hook = 0, index = 0;
	struct option *opts = NULL;

	xtables_init_all(&tcipt_globals, NFPROTO_IPV4);
	set_lib_dir();

	{
		int i;
		for (i = 0; i < rargc; i++) {
			if (NULL == argv[i] || 0 == strcmp(argv[i], "action")) {
				break;
			}
		}
		iargc = argc = i;
	}

	if (argc <= 2) {
		fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc);
		return -1;
	}

	while (1) {
		c = getopt_long(argc, argv, "j:", tcipt_globals.opts, NULL);
		if (c == -1)
			break;
		switch (c) {
		case 'j':
			m = xtables_find_target(optarg, XTF_TRY_LOAD);
			if (NULL != m) {

				if (0 > build_st(m, NULL)) {
					printf(" %s error \n", m->name);
					return -1;
				}
#if (XTABLES_VERSION_CODE >= 6)
			opts = xtables_options_xfrm(tcipt_globals.orig_opts,
						    tcipt_globals.opts,
						    m->x6_options,
						    &m->option_offset);
#else
			opts = xtables_merge_options(tcipt_globals.orig_opts,
						     tcipt_globals.opts,
						     m->extra_opts,
						     &m->option_offset);
#endif
			if (opts == NULL) {
				fprintf(stderr, " failed to find aditional options for target %s\n\n", optarg);
				return -1;
			} else
				tcipt_globals.opts = opts;
			} else {
				fprintf(stderr," failed to find target %s\n\n", optarg);
				return -1;
			}
			ok++;
			break;

		default:
			memset(&fw, 0, sizeof (fw));
#if (XTABLES_VERSION_CODE >= 6)
		if (m != NULL && m->x6_parse != NULL ) {
			xtables_option_tpcall(c, argv, 0 , m, NULL);
#else
		if (m != NULL && m->parse != NULL ) {
			m->parse(c - m->option_offset, argv, 0, &m->tflags,
				 NULL, &m->t);
#endif
			} else {
				fprintf(stderr,"failed to find target %s\n\n", optarg);
				return -1;

			}
			ok++;
			break;
		}
	}

	if (iargc > optind) {
		if (matches(argv[optind], "index") == 0) {
			if (get_u32(&index, argv[optind + 1], 10)) {
				fprintf(stderr, "Illegal \"index\"\n");
				xtables_free_opts(1);
				return -1;
			}
			iok++;

			optind += 2;
		}
	}

	if (!ok && !iok) {
		fprintf(stderr," ipt Parser BAD!! (%s)\n", *argv);
		return -1;
	}

	/* check that we passed the correct parameters to the target */
#if (XTABLES_VERSION_CODE >= 6)
	if (m)
		xtables_option_tfcall(m);
#else
	if (m && m->final_check)
		m->final_check(m->tflags);
#endif

	{
		struct tcmsg *t = NLMSG_DATA(n);
		if (t->tcm_parent != TC_H_ROOT
		    && t->tcm_parent == TC_H_MAJ(TC_H_INGRESS)) {
			hook = NF_IP_PRE_ROUTING;
		} else {
			hook = NF_IP_POST_ROUTING;
		}
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
	fprintf(stdout, "tablename: %s hook: %s\n ", tname, ipthooks[hook]);
	fprintf(stdout, "\ttarget: ");

	if (m)
		m->print(NULL, m->t, 0);
	fprintf(stdout, " index %d\n", index);

	if (strlen(tname) > 16) {
		size = 16;
		k[15] = 0;
	} else {
		size = 1 + strlen(tname);
	}
	strncpy(k, tname, size);

	addattr_l(n, MAX_MSG, TCA_IPT_TABLE, k, size);
	addattr_l(n, MAX_MSG, TCA_IPT_HOOK, &hook, 4);
	addattr_l(n, MAX_MSG, TCA_IPT_INDEX, &index, 4);
	if (m)
		addattr_l(n, MAX_MSG, TCA_IPT_TARG, m->t, m->t->u.target_size);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;

	argc -= optind;
	argv += optind;
	*argc_p = rargc - iargc;
	*argv_p = argv;

	optind = 0;
	xtables_free_opts(1);

	if (m) {
		/* Clear flags if target will be used again */
		m->tflags = 0;
		m->used = 0;
		/* Free allocated memory */
		if (m->t)
			free(m->t);
	}

	return 0;

}

static int
print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
{
	struct rtattr *tb[TCA_IPT_MAX + 1];
	struct xt_entry_target *t = NULL;
	struct option *opts = NULL;

	if (arg == NULL)
		return -1;

	xtables_init_all(&tcipt_globals, NFPROTO_IPV4);
	set_lib_dir();

	parse_rtattr_nested(tb, TCA_IPT_MAX, arg);

	if (tb[TCA_IPT_TABLE] == NULL) {
		fprintf(f, "[NULL ipt table name ] assuming mangle ");
	} else {
		fprintf(f, "tablename: %s ",
			rta_getattr_str(tb[TCA_IPT_TABLE]));
	}

	if (tb[TCA_IPT_HOOK] == NULL) {
		fprintf(f, "[NULL ipt hook name ]\n ");
		return -1;
	} else {
		__u32 hook;
		hook = rta_getattr_u32(tb[TCA_IPT_HOOK]);
		fprintf(f, " hook: %s \n", ipthooks[hook]);
	}

	if (tb[TCA_IPT_TARG] == NULL) {
		fprintf(f, "\t[NULL ipt target parameters ] \n");
		return -1;
	} else {
		struct xtables_target *m = NULL;
		t = RTA_DATA(tb[TCA_IPT_TARG]);
		m = xtables_find_target(t->u.user.name, XTF_TRY_LOAD);
		if (NULL != m) {
			if (0 > build_st(m, t)) {
				fprintf(stderr, " %s error \n", m->name);
				return -1;
			}

#if (XTABLES_VERSION_CODE >= 6)
		opts = xtables_options_xfrm(tcipt_globals.orig_opts,
					    tcipt_globals.opts,
					    m->x6_options,
					    &m->option_offset);
#else
		opts = xtables_merge_options(tcipt_globals.orig_opts,
					     tcipt_globals.opts,
					     m->extra_opts,
					     &m->option_offset);
#endif
	if (opts == NULL) {
		fprintf(stderr, " failed to find aditional options for target %s\n\n", optarg);
		return -1;
	} else
		tcipt_globals.opts = opts;
		} else {
			fprintf(stderr, " failed to find target %s\n\n",
				t->u.user.name);
			return -1;
		}
		fprintf(f, "\ttarget ");
		m->print(NULL, m->t, 0);
		if (tb[TCA_IPT_INDEX] == NULL) {
			fprintf(f, " [NULL ipt target index ]\n");
		} else {
			__u32 index;
			index = rta_getattr_u32(tb[TCA_IPT_INDEX]);
			fprintf(f, " \n\tindex %d", index);
		}

		if (tb[TCA_IPT_CNT]) {
			struct tc_cnt *c  = RTA_DATA(tb[TCA_IPT_CNT]);;
			fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt);
		}
		if (show_stats) {
			if (tb[TCA_IPT_TM]) {
				struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]);
				print_tm(f,tm);
			}
		}
		fprintf(f, " \n");

	}
	xtables_free_opts(1);

	return 0;
}

struct action_util xt_action_util = {
        .id = "xt",
        .parse_aopt = parse_ipt,
        .print_aopt = print_ipt,
};
Exemple #19
0
int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
		   void *arg)
{
	FILE *fp = arg;
	struct ifaddrmsg *ifa = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	int deprecated = 0;
	/* Use local copy of ifa_flags to not interfere with filtering code */
	unsigned int ifa_flags;
	struct rtattr * rta_tb[IFA_MAX+1];
	char abuf[256];
	SPRINT_BUF(b1);

	if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
		return 0;
	len -= NLMSG_LENGTH(sizeof(*ifa));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
		return 0;

	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa),
		     n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));

	ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]);

	if (!rta_tb[IFA_LOCAL])
		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
	if (!rta_tb[IFA_ADDRESS])
		rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];

	if (filter.ifindex && filter.ifindex != ifa->ifa_index)
		return 0;
	if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
		return 0;
	if ((filter.flags ^ ifa_flags) & filter.flagmask)
		return 0;
	if (filter.label) {
		SPRINT_BUF(b1);
		const char *label;
		if (rta_tb[IFA_LABEL])
			label = RTA_DATA(rta_tb[IFA_LABEL]);
		else
			label = ll_idx_n2a(ifa->ifa_index, b1);
		if (fnmatch(filter.label, label, 0) != 0)
			return 0;
	}
	if (filter.pfx.family) {
		if (rta_tb[IFA_LOCAL]) {
			inet_prefix dst;
			memset(&dst, 0, sizeof(dst));
			dst.family = ifa->ifa_family;
			memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
			if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
				return 0;
		}
	}

	if (filter.family && filter.family != ifa->ifa_family)
		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_DELADDR;
		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_DELADDR)
		fprintf(fp, "Deleted ");

	if (filter.oneline || filter.flushb)
		fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
	if (ifa->ifa_family == AF_INET)
		fprintf(fp, "    inet ");
	else if (ifa->ifa_family == AF_INET6)
		fprintf(fp, "    inet6 ");
	else if (ifa->ifa_family == AF_DECnet)
		fprintf(fp, "    dnet ");
	else if (ifa->ifa_family == AF_IPX)
		fprintf(fp, "     ipx ");
	else
		fprintf(fp, "    family %d ", ifa->ifa_family);

	if (rta_tb[IFA_LOCAL]) {
		if (ifa->ifa_family == AF_INET)
			color_fprintf(fp, COLOR_INET, "%s", format_host(ifa->ifa_family,
						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
						RTA_DATA(rta_tb[IFA_LOCAL]),
						abuf, sizeof(abuf)));
		else if (ifa->ifa_family == AF_INET6)
			color_fprintf(fp, COLOR_INET6, "%s", format_host(ifa->ifa_family,
						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
						RTA_DATA(rta_tb[IFA_LOCAL]),
						abuf, sizeof(abuf)));
		else
			fprintf(fp, "%s", format_host(ifa->ifa_family,
						RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
						RTA_DATA(rta_tb[IFA_LOCAL]),
						abuf, sizeof(abuf)));

		if (rta_tb[IFA_ADDRESS] == NULL ||
		    memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]),
			   ifa->ifa_family == AF_INET ? 4 : 16) == 0) {
			fprintf(fp, "/%d ", ifa->ifa_prefixlen);
		} else {
			fprintf(fp, " peer %s/%d ",
				format_host(ifa->ifa_family,
					    RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
					    RTA_DATA(rta_tb[IFA_ADDRESS]),
					    abuf, sizeof(abuf)),
				ifa->ifa_prefixlen);
		}
	}

	if (rta_tb[IFA_BROADCAST]) {
		fprintf(fp, "brd %s ",
			format_host(ifa->ifa_family,
				    RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
				    RTA_DATA(rta_tb[IFA_BROADCAST]),
				    abuf, sizeof(abuf)));
	}
	if (rta_tb[IFA_ANYCAST]) {
		fprintf(fp, "any %s ",
			format_host(ifa->ifa_family,
				    RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
				    RTA_DATA(rta_tb[IFA_ANYCAST]),
				    abuf, sizeof(abuf)));
	}
	fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
	if (ifa_flags & IFA_F_SECONDARY) {
		ifa_flags &= ~IFA_F_SECONDARY;
		if (ifa->ifa_family == AF_INET6)
			fprintf(fp, "temporary ");
		else
			fprintf(fp, "secondary ");
	}
	if (ifa_flags & IFA_F_TENTATIVE) {
		ifa_flags &= ~IFA_F_TENTATIVE;
		fprintf(fp, "tentative ");
	}
	if (ifa_flags & IFA_F_DEPRECATED) {
		ifa_flags &= ~IFA_F_DEPRECATED;
		deprecated = 1;
		fprintf(fp, "deprecated ");
	}
	if (ifa_flags & IFA_F_HOMEADDRESS) {
		ifa_flags &= ~IFA_F_HOMEADDRESS;
		fprintf(fp, "home ");
	}
	if (ifa_flags & IFA_F_NODAD) {
		ifa_flags &= ~IFA_F_NODAD;
		fprintf(fp, "nodad ");
	}
	if (ifa_flags & IFA_F_MANAGETEMPADDR) {
		ifa_flags &= ~IFA_F_MANAGETEMPADDR;
		fprintf(fp, "mngtmpaddr ");
	}
	if (ifa_flags & IFA_F_NOPREFIXROUTE) {
		ifa_flags &= ~IFA_F_NOPREFIXROUTE;
		fprintf(fp, "noprefixroute ");
	}
	if (ifa_flags & IFA_F_MCAUTOJOIN) {
		ifa_flags &= ~IFA_F_MCAUTOJOIN;
		fprintf(fp, "autojoin ");
	}
	if (!(ifa_flags & IFA_F_PERMANENT)) {
		fprintf(fp, "dynamic ");
	} else
		ifa_flags &= ~IFA_F_PERMANENT;
	if (ifa_flags & IFA_F_DADFAILED) {
		ifa_flags &= ~IFA_F_DADFAILED;
		fprintf(fp, "dadfailed ");
	}
	if (ifa_flags)
		fprintf(fp, "flags %02x ", ifa_flags);
	if (rta_tb[IFA_LABEL])
		fprintf(fp, "%s", rta_getattr_str(rta_tb[IFA_LABEL]));
	if (rta_tb[IFA_CACHEINFO]) {
		struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
		fprintf(fp, "%s", _SL_);
		fprintf(fp, "       valid_lft ");
		if (ci->ifa_valid == INFINITY_LIFE_TIME)
			fprintf(fp, "forever");
		else
			fprintf(fp, "%usec", ci->ifa_valid);
		fprintf(fp, " preferred_lft ");
		if (ci->ifa_prefered == INFINITY_LIFE_TIME)
			fprintf(fp, "forever");
		else {
			if (deprecated)
				fprintf(fp, "%dsec", ci->ifa_prefered);
			else
				fprintf(fp, "%usec", ci->ifa_prefered);
		}
	}
	fprintf(fp, "\n");
	fflush(fp);
	return 0;
}
Exemple #20
0
int print_linkinfo(const struct sockaddr_nl *who,
                   struct nlmsghdr *n, void *arg)
{
    FILE *fp = arg;
    int len = n->nlmsg_len;
    struct ifinfomsg *ifi = NLMSG_DATA(n);
    struct rtattr * tb[IFLA_MAX+1];
    char b1[IFNAMSIZ];

    len -= NLMSG_LENGTH(sizeof(*ifi));
    if (len < 0) {
        fprintf(stderr, "Message too short!\n");
        return -1;
    }

    if (!(ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_UNSPEC))
        return 0;

    if (filter_index && filter_index != ifi->ifi_index)
        return 0;

    parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);

    if (tb[IFLA_IFNAME] == NULL) {
        fprintf(stderr, "BUG: nil ifname\n");
        return -1;
    }

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

    fprintf(fp, "%d: %s ", ifi->ifi_index,
            tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");

    if (tb[IFLA_OPERSTATE])
        print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));

    if (tb[IFLA_LINK]) {
        SPRINT_BUF(b1);
        int iflink = rta_getattr_u32(tb[IFLA_LINK]);
        if (iflink == 0)
            fprintf(fp, "@NONE: ");
        else
            fprintf(fp, "@%s: ",
                    if_indextoname(iflink, b1));
    } else
        fprintf(fp, ": ");

    print_link_flags(fp, ifi->ifi_flags);

    if (tb[IFLA_MTU])
        fprintf(fp, "mtu %u ", rta_getattr_u32(tb[IFLA_MTU]));

    if (tb[IFLA_MASTER])
        fprintf(fp, "master %s ",
                if_indextoname(rta_getattr_u32(tb[IFLA_MASTER]), b1));

    if (tb[IFLA_PROTINFO]) {
        if (tb[IFLA_PROTINFO]->rta_type & NLA_F_NESTED) {
            struct rtattr *prtb[IFLA_BRPORT_MAX+1];

            parse_rtattr_nested(prtb, IFLA_BRPORT_MAX,
                                tb[IFLA_PROTINFO]);

            if (prtb[IFLA_BRPORT_STATE])
                print_portstate(fp,
                                rta_getattr_u8(prtb[IFLA_BRPORT_STATE]));
            if (prtb[IFLA_BRPORT_PRIORITY])
                fprintf(fp, "priority %hu ",
                        rta_getattr_u16(prtb[IFLA_BRPORT_PRIORITY]));
            if (prtb[IFLA_BRPORT_COST])
                fprintf(fp, "cost %u ",
                        rta_getattr_u32(prtb[IFLA_BRPORT_COST]));

            if (show_details) {
                fprintf(fp, "%s    ", _SL_);

                if (prtb[IFLA_BRPORT_MODE])
                    print_onoff(fp, "hairpin",
                                rta_getattr_u8(prtb[IFLA_BRPORT_MODE]));
                if (prtb[IFLA_BRPORT_GUARD])
                    print_onoff(fp, "guard",
                                rta_getattr_u8(prtb[IFLA_BRPORT_GUARD]));
                if (prtb[IFLA_BRPORT_PROTECT])
                    print_onoff(fp, "root_block",
                                rta_getattr_u8(prtb[IFLA_BRPORT_PROTECT]));
                if (prtb[IFLA_BRPORT_FAST_LEAVE])
                    print_onoff(fp, "fastleave",
                                rta_getattr_u8(prtb[IFLA_BRPORT_FAST_LEAVE]));
                if (prtb[IFLA_BRPORT_LEARNING])
                    print_onoff(fp, "learning",
                                rta_getattr_u8(prtb[IFLA_BRPORT_LEARNING]));
                if (prtb[IFLA_BRPORT_LEARNING_SYNC])
                    print_onoff(fp, "learning_sync",
                                rta_getattr_u8(prtb[IFLA_BRPORT_LEARNING_SYNC]));
                if (prtb[IFLA_BRPORT_UNICAST_FLOOD])
                    print_onoff(fp, "flood",
                                rta_getattr_u8(prtb[IFLA_BRPORT_UNICAST_FLOOD]));
            }
        } else
            print_portstate(fp, rta_getattr_u8(tb[IFLA_PROTINFO]));
    }

    if (tb[IFLA_AF_SPEC]) {
        /* This is reported by HW devices that have some bridging
         * capabilities.
         */
        struct rtattr *aftb[IFLA_BRIDGE_MAX+1];

        parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]);

        if (aftb[IFLA_BRIDGE_MODE])
            print_hwmode(fp, rta_getattr_u16(aftb[IFLA_BRIDGE_MODE]));
    }

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