Ejemplo n.º 1
0
int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	int h;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct idxmap *im, **imp;
	struct rtattr *tb[IFLA_MAX+1];

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

	if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
		return -1;


	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
	if (tb[IFLA_IFNAME] == NULL)
		return 0;

	h = ifi->ifi_index&0xF;

	for (imp=&idxmap[h]; (im=*imp)!=NULL; imp = &im->next)
		if (im->index == ifi->ifi_index)
			break;

	if (im == NULL) {
		im = malloc(sizeof(*im));
		if (im == NULL)
			return 0;
		im->next = *imp;
		im->index = ifi->ifi_index;
		*imp = im;
	}

	im->type = ifi->ifi_type;
	im->flags = ifi->ifi_flags;
	if (tb[IFLA_ADDRESS]) {
		int alen;
		im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
		if (alen > sizeof(im->addr))
			alen = sizeof(im->addr);
		memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen);
	} else {
		im->alen = 0;
		memset(im->addr, 0, sizeof(im->addr));
	}
	strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
	return 0;
}
int print_addrlabel(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct ifaddrlblmsg *ifal = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	int host_len = -1;
	struct rtattr *tb[IFAL_MAX+1];
	char abuf[256];

	if (n->nlmsg_type != RTM_NEWADDRLABEL && n->nlmsg_type != RTM_DELADDRLABEL)
		return 0;

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

	parse_rtattr(tb, IFAL_MAX, IFAL_RTA(ifal), len);

	if (ifal->ifal_family == AF_INET)
		host_len = 32;
	else if (ifal->ifal_family == AF_INET6)
		host_len = 128;

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

	if (tb[IFAL_ADDRESS]) {
		fprintf(fp, "prefix %s/%u ",
			format_host(ifal->ifal_family,
				    RTA_PAYLOAD(tb[IFAL_ADDRESS]),
				    RTA_DATA(tb[IFAL_ADDRESS]),
				    abuf, sizeof(abuf)),
			ifal->ifal_prefixlen);
	}

	if (ifal->ifal_index)
		fprintf(fp, "dev %s ", ll_index_to_name(ifal->ifal_index));

	if (tb[IFAL_LABEL] && RTA_PAYLOAD(tb[IFAL_LABEL]) == sizeof(int32_t)) {
		int32_t label;
		memcpy(&label, RTA_DATA(tb[IFAL_LABEL]), sizeof(label));
		fprintf(fp, "label %d ", label);
	}

	fprintf(fp, "\n");
	fflush(fp);
	return 0;
}
Ejemplo n.º 3
0
/* Netlink flag Link update */
static int
netlink_reflect_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
{
	struct ifinfomsg *ifi;
	struct rtattr *tb[IFLA_MAX + 1];
	interface_t *ifp;
	int len;

	ifi = NLMSG_DATA(h);
	if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
		return 0;

	len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifinfomsg));
	if (len < 0)
		return -1;

	/* Interface name lookup */
	memset(tb, 0, sizeof (tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL)
		return -1;

	/* ignore loopback device */
	if (ifi->ifi_type == ARPHRD_LOOPBACK)
		return 0;

	/* find the VMAC interface (if any) */
	ifp = if_get_by_vmac_base_ifindex(ifi->ifi_index);

	/* if found, reflect base interface flags on VMAC interface */
	if (ifp)
		ifp->flags = ifi->ifi_flags;

	/* find the interface_t */
	ifp = if_get_by_ifindex(ifi->ifi_index);
	if (!ifp)
		return -1;

	/*
	 * Update flags.
	 * VMAC interfaces should never update it own flags, only be reflected
	 * by the base interface flags, see above.
	 */
	if (!ifp->vmac)
		ifp->flags = ifi->ifi_flags;

	return 0;
}
Ejemplo n.º 4
0
int get_rtstat_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *m, void *arg)
{
#ifndef IFLA_RTSTATS
		return -1;
#else
	struct ifinfomsg *ifi = NLMSG_DATA(m);
	struct rtattr * tb[IFLA_MAX+1];
	int len = m->nlmsg_len;
	struct rtstat_ent *n;
	unsigned long ival[RTMAXS];
	int i;

	if (m->nlmsg_type != RTM_NEWLINK)
		return 0;

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

	if (!(ifi->ifi_flags&IFF_UP))
		return 0;


	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL || tb[IFLA_RTSTATS] == NULL)
		return 0;

	n = malloc(sizeof(*n));
	if (!n)
		abort();
	n->ifindex = ifi->ifi_index;
	n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));

	memcpy(&ival, RTA_DATA(tb[IFLA_RTSTATS]), sizeof(ival));

	for (i=0; i<RTMAXS; i++) {
		n->ival[i] = ival[i];
	}

	n->next = rtstat_db;
	rtstat_db = n;


	return 0;
#endif
}
static int
hfsc_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{
	struct rtattr *tb[TCA_HFSC_MAX+1];
	struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL;

	if (opt == NULL)
		return 0;

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, TCA_HFSC_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt));

	if (tb[TCA_HFSC_RSC]) {
		if (RTA_PAYLOAD(tb[TCA_HFSC_RSC]) < sizeof(*rsc))
			fprintf(stderr, "HFSC: truncated realtime option\n");
		else
			rsc = RTA_DATA(tb[TCA_HFSC_RSC]);
	}
	if (tb[TCA_HFSC_FSC]) {
		if (RTA_PAYLOAD(tb[TCA_HFSC_FSC]) < sizeof(*fsc))
			fprintf(stderr, "HFSC: truncated linkshare option\n");
		else
			fsc = RTA_DATA(tb[TCA_HFSC_FSC]);
	}
	if (tb[TCA_HFSC_USC]) {
		if (RTA_PAYLOAD(tb[TCA_HFSC_USC]) < sizeof(*usc))
			fprintf(stderr, "HFSC: truncated upperlimit option\n");
		else
			usc = RTA_DATA(tb[TCA_HFSC_USC]);
	}

	
	if (rsc != NULL && fsc != NULL &&
	    memcmp(rsc, fsc, sizeof(*rsc)) == 0)
		hfsc_print_sc(f, "sc", rsc);
	else {
		if (rsc != NULL)
			hfsc_print_sc(f, "rt", rsc);
		if (fsc != NULL)
			hfsc_print_sc(f, "ls", fsc);
	}
	if (usc != NULL)
		hfsc_print_sc(f, "ul", usc);

	return 0;
}
Ejemplo n.º 6
0
static int print_ila_mapping(const struct sockaddr_nl *who,
			     struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE *)arg;
	struct genlmsghdr *ghdr;
	struct rtattr *tb[ILA_ATTR_MAX + 1];
	int len = n->nlmsg_len;

	if (n->nlmsg_type != genl_family)
		return 0;

	len -= NLMSG_LENGTH(GENL_HDRLEN);
	if (len < 0)
		return -1;

	ghdr = NLMSG_DATA(n);
	parse_rtattr(tb, ILA_ATTR_MAX, (void *) ghdr + GENL_HDRLEN, len);

	print_ila_locid(fp, ILA_ATTR_LOCATOR_MATCH, tb, ADDR_BUF_SIZE);
	print_ila_locid(fp, ILA_ATTR_LOCATOR, tb, ADDR_BUF_SIZE);

	if (tb[ILA_ATTR_IFINDEX])
		fprintf(fp, "%-16s",
			ll_index_to_name(rta_getattr_u32(
						tb[ILA_ATTR_IFINDEX])));
	else
		fprintf(fp, "%-10s ", "-");

	if (tb[ILA_ATTR_CSUM_MODE])
		fprintf(fp, "%s",
			ila_csum_mode2name(rta_getattr_u8(
						tb[ILA_ATTR_CSUM_MODE])));
	else
		fprintf(fp, "%-10s ", "-");

	if (tb[ILA_ATTR_IDENT_TYPE])
		fprintf(fp, "%s",
			ila_ident_type2name(rta_getattr_u8(
						tb[ILA_ATTR_IDENT_TYPE])));
	else
		fprintf(fp, "-");

	fprintf(fp, "\n");

	return 0;
}
Ejemplo n.º 7
0
/*
 * parse ematch meta
 */
int parse_ematch_meta(char *msg, char *mp, void *p, int len)
{
    struct rtattr *meta[__TCA_EM_META_MAX];
    struct tcf_meta_hdr *hdr = NULL;
    struct tcf_meta_val *left = NULL, *right = NULL;

    parse_rtattr(meta, TCA_EM_META_MAX, p, len);

    if(meta[TCA_EM_META_HDR]) {
        if(RTA_PAYLOAD(meta[TCA_EM_META_HDR]) < sizeof(*hdr)) {
            rec_log("error: %s: TCA_EM_META_HDR: payload too short", __func__);
            return(1);
        }
        hdr = (struct tcf_meta_hdr *)RTA_DATA(meta[TCA_EM_META_HDR]);
        left = &(hdr->left);
        right = &(hdr->right);
    } else {
        rec_log("error: %s: TCA_EM_META_HDR: no attribute", __func__);
        return(1);
    }

    mp = add_log(msg, mp, "match=(");

    if(meta[TCA_EM_META_LVALUE]) {
        if(parse_tca_em_meta_value(msg, &mp, left, meta[TCA_EM_META_LVALUE]))
            return(1);
    } else {
        rec_log("error: %s: TCA_EM_META_LVALUE: no attribute", __func__);
        return(1);
    }

    mp = add_log(msg, mp, "%s ", conv_tcf_em_opnd(left->op, 0));

    if(meta[TCA_EM_META_RVALUE]) {
        if(parse_tca_em_meta_value(msg, &mp, right, meta[TCA_EM_META_RVALUE]))
            return(1);
    } else {
        rec_log("error: %s: TCA_EM_META_RVALUE: no attribute", __func__);
        return(1);
    }
    mp = add_log(msg, mp, ") ");

    rec_log("%s", msg);

    return(0);
}
Ejemplo n.º 8
0
static int get_netstat_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *m, void *arg)
{
	struct ifinfomsg *ifi = NLMSG_DATA(m);
	struct rtattr * tb[IFLA_MAX+1];
	int len = m->nlmsg_len;
	struct ifstat_ent *n;
	uint64_t ival[MAXS];
	int i;

	if (m->nlmsg_type != RTM_NEWLINK)
		return 0;

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

	if (!(ifi->ifi_flags&IFF_UP))
		return 0;

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL || tb[IFLA_STATS64] == NULL)
		return 0;

	n = malloc(sizeof(*n));
	if (!n)
		abort();
	n->ifindex = ifi->ifi_index;
	n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));
	memcpy(&ival, RTA_DATA(tb[IFLA_STATS64]), sizeof(ival));
	for (i=0; i<MAXS; i++) {

#undef DO_L2_STATS
#ifdef DO_L2_STATS

		if(i == 2) n->ival[i] = n->ival[i]+4; /* RX CRC */
		if(i == 3) n->ival[i] = n->ival[i]+18; /* TX 14+4 E-hdr + CRC */
#endif
		n->val[i] = ival[i];
	}
	n->next = kern_db;
	kern_db = n;
	return 0;
}
Ejemplo n.º 9
0
static int get_netnsid_from_name(const char *name)
{
	struct {
		struct nlmsghdr n;
		struct rtgenmsg g;
		char            buf[1024];
	} req, answer;
	struct rtattr *tb[NETNSA_MAX + 1];
	struct rtgenmsg *rthdr;
	int len, fd;

	memset(&req, 0, sizeof(req));
	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST;
	req.n.nlmsg_type = RTM_GETNSID;
	req.g.rtgen_family = AF_UNSPEC;

	fd = netns_get_fd(name);
	if (fd < 0)
		return fd;

	addattr32(&req.n, 1024, NETNSA_FD, fd);
	if (rtnl_talk(&rth, &req.n, 0, 0, &answer.n) < 0) {
		close(fd);
		return -2;
	}
	close(fd);

	/* Validate message and parse attributes */
	if (answer.n.nlmsg_type == NLMSG_ERROR)
		return -1;

	rthdr = NLMSG_DATA(&answer.n);
	len = answer.n.nlmsg_len - NLMSG_SPACE(sizeof(*rthdr));
	if (len < 0)
		return -1;

	parse_rtattr(tb, NETNSA_MAX, NETNS_RTA(rthdr), len);

	if (tb[NETNSA_NSID])
		return rta_getattr_u32(tb[NETNSA_NSID]);

	return -1;
}
Ejemplo n.º 10
0
int TunManager::getAddrRespParser(const struct sockaddr_nl *who,
                                  struct nlmsghdr *n,
                                  void *arg) {
  // only cares about RTM_NEWADDR
  if (n->nlmsg_type != RTM_NEWADDR) {
    return 0;
  }
  struct ifaddrmsg *ifa = static_cast<struct ifaddrmsg *>(NLMSG_DATA(n));
  struct rtattr *tb[IFA_MAX + 1];
  int len = n->nlmsg_len;
  len -= NLMSG_LENGTH(sizeof(*ifa));
  if (len < 0) {
    throw FbossError("Wrong length for RTM_GETADDR response ", len, " vs ",
                     NLMSG_LENGTH(sizeof(*ifa)));
  }
  // only care about v4 and v6 address
  if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6) {
    VLOG(3) << "Skip address from device @ index "
            << static_cast<int>(ifa->ifa_index)
            << " because of its address family "
            << static_cast<int>(ifa->ifa_family);
    return 0;
  }

  parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
  if (tb[IFA_ADDRESS] == nullptr) {
    VLOG(3) << "Device @ index " << static_cast<int>(ifa->ifa_index)
            << " does not have address at family "
            << static_cast<int>(ifa->ifa_family);
    return 0;
  }
  IPAddress addr;
  const void *data = RTA_DATA(tb[IFA_ADDRESS]);
  if (ifa->ifa_family == AF_INET) {
    addr = IPAddress(*static_cast<const in_addr *>(data));
  } else {
    addr = IPAddress(*static_cast<const in6_addr *>(data));
  }

  TunManager *mgr = static_cast<TunManager *>(arg);
  mgr->addProbedAddr(ifa->ifa_index, addr, ifa->ifa_prefixlen);
  return 0;
}
Ejemplo n.º 11
0
int print_mpls(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	struct rtattr *tb[MPLS_ATTR_MAX + 1];
	struct genlmsghdr *ghdr = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr *attrs;

	if (n->nlmsg_type !=  PF_MPLS) {
		fprintf(stderr, "Not a controller message, nlmsg_len=%d "
			"nlmsg_type=0x%x\n", n->nlmsg_len, n->nlmsg_type);
		return 0;
	}

        len -= NLMSG_LENGTH(GENL_HDRLEN);
        if (len < 0) {
                fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
                return -1;
        }

	attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
	parse_rtattr(tb, MPLS_ATTR_MAX, attrs, len);

	switch (ghdr->cmd) {
		case MPLS_CMD_NEWILM:
			return print_ilm(n,arg,tb);
		case MPLS_CMD_NEWNHLFE:
			return print_nhlfe(n,arg,tb);
		case MPLS_CMD_NEWXC:
			return print_xc(n,arg,tb);
		case MPLS_CMD_SETLABELSPACE:
			return print_labelspace(n,arg,tb);
		default:
			return 0;
	}

#if 0
	if (n->nlmsg_type >= MPLS_RTM_ADDTUNNEL &&
		n->nlmsg_type <= MPLS_RTM_DELTUNNEL) {
		return print_tunnel(n,arg, tb);
	}
#endif
	return 0;
}
Ejemplo n.º 12
0
int print_mdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	FILE *fp = arg;
	struct br_port_msg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * tb[MDBA_MAX+1];

	if (n->nlmsg_type != RTM_GETMDB && n->nlmsg_type != RTM_NEWMDB && n->nlmsg_type != RTM_DELMDB) {
		fprintf(stderr, "Not RTM_GETMDB, RTM_NEWMDB or RTM_DELMDB: %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;
	}

	if (filter_index && filter_index != r->ifindex)
		return 0;

	parse_rtattr(tb, MDBA_MAX, MDBA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));

	if (tb[MDBA_MDB]) {
		struct rtattr *i;
		int rem = RTA_PAYLOAD(tb[MDBA_MDB]);

		for (i = RTA_DATA(tb[MDBA_MDB]); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
			br_print_mdb_entry(fp, r->ifindex, i);
	}

	if (tb[MDBA_ROUTER]) {
		if (show_details) {
			fprintf(fp, "router ports on %s: ", ll_index_to_name(r->ifindex));
			br_print_router_ports(fp, tb[MDBA_ROUTER]);
		}
	}

	return 0;
}
Ejemplo n.º 13
0
static int xfrm_report_print(const struct sockaddr_nl *who,
			     struct nlmsghdr *n, void *arg)
{
	FILE *fp = (FILE*)arg;
	struct xfrm_user_report *xrep = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * tb[XFRMA_MAX+1];
	__u16 family;

	if (n->nlmsg_type != XFRM_MSG_REPORT) {
		fprintf(stderr, "Not a report: %08x %08x %08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}

	len -= NLMSG_LENGTH(sizeof(*xrep));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	family = xrep->sel.family;
	if (family == AF_UNSPEC)
		family = preferred_family;

	fprintf(fp, "report ");

	fprintf(fp, "proto %s ", strxf_xfrmproto(xrep->proto));
	fprintf(fp, "%s", _SL_);

	xfrm_selector_print(&xrep->sel, family, fp, "  sel ");

	parse_rtattr(tb, XFRMA_MAX, XFRMREP_RTA(xrep), len);

	xfrm_xfrma_print(tb, family, fp, "  ");

	if (oneline)
		fprintf(fp, "\n");

	return 0;
}
Ejemplo n.º 14
0
/**
 * returns non-local addresses for specified interface
 */
void ipaddr_global_get(int *count, char **bufPtr, int ifindex, struct nlmsg_list *ainfo) {
    int cnt=0;
    char * buf=0, * tmpbuf=0;
    char addr[16];
    struct rtattr * rta_tb[IFA_MAX+1];
    int pos;

    for ( ;ainfo ;  ainfo = ainfo->next) {
	struct nlmsghdr *n = &ainfo->h;
	struct ifaddrmsg *ifa = NLMSG_DATA(n);
	if ( (ifa->ifa_family == AF_INET6) && (ifa->ifa_index == ifindex) ) {
	    memset(rta_tb, 0, sizeof(*rta_tb));
	    parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
	    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];
	    
	    memcpy(addr,(char*)RTA_DATA(rta_tb[IFLA_ADDRESS]),16);
	    if ( (addr[0]==0xfe && addr[1]==0x80) || /* link local */
		 (addr[0]==0xff) ) { /* multicast */
		continue; /* ignore non link-scoped addrs */
	    }
	    
	    /* ifa->ifa_flags & 128 - permenent */
	    /* printf("flags:%d : ",ifa->ifa_flags); */

	    pos = cnt*16;
	    buf = (char*) malloc( pos + 16);
            if (pos > 0) {
                memcpy(buf,tmpbuf, pos); /* copy old addrs */
            }
	    memcpy(buf+pos,addr,16); /* copy new addr */
	    if (pos > 0) {
                free(tmpbuf);
            }
	    tmpbuf = buf;
	    cnt++;
	}
    }
    *count = cnt;
    *bufPtr = buf;
}
Ejemplo n.º 15
0
int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
{
	struct rtattr *tb[NETLINK_DIAG_MAX+1];
	struct netlink_diag_msg *m;
	struct netlink_sk_desc *sd;
	unsigned long *groups;

	m = NLMSG_DATA(hdr);
	pr_info("Collect netlink sock 0x%x\n", m->ndiag_ino);

	sd = xmalloc(sizeof(*sd));
	if (!sd)
		return -1;

	sd->protocol = m->ndiag_protocol;
	sd->portid = m->ndiag_portid;
	sd->dst_portid = m->ndiag_dst_portid;
	sd->dst_group = m->ndiag_dst_group;
	sd->state = m->ndiag_state;

	parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr *)(m + 1),
		     hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));

	if (tb[NETLINK_DIAG_GROUPS]) {
		sd->gsize = RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS]);
		groups = RTA_DATA(tb[NETLINK_DIAG_GROUPS]);

		sd->groups = xmalloc(sd->gsize);
		if (!sd->groups) {
			xfree(sd);
			return -1;
		}
		memcpy(sd->groups, groups, sd->gsize);
	} else {
		sd->groups = NULL;
		sd->gsize = 0;
	}

	return sk_collect_one(m->ndiag_ino, PF_NETLINK, &sd->sd);
}
Ejemplo n.º 16
0
/*
 * debug ematch meta
 */
void debug_ematch_meta(int lev, void *p, int len)
{
    struct rtattr *meta[__TCA_EM_META_MAX];
    struct tcf_meta_hdr *hdr = NULL;

    parse_rtattr(meta, TCA_EM_META_MAX, p, len);

    if(meta[TCA_EM_META_HDR])
        hdr = debug_tca_em_meta_hdr(lev, meta[TCA_EM_META_HDR],
            "TCA_EM_META_HDR");

    if(!hdr)
        return;

    if(meta[TCA_EM_META_LVALUE])
        debug_tca_em_meta_value(lev, meta[TCA_EM_META_LVALUE],
            "TCA_EM_META_LVALUE", &(hdr->left));

    if(meta[TCA_EM_META_RVALUE])
        debug_tca_em_meta_value(lev, meta[TCA_EM_META_RVALUE],
            "TCA_EM_META_RVALUE", &(hdr->right));
}
Ejemplo n.º 17
0
static int flush_rule(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];

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

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

	if (tb[RTA_PRIORITY]) {
		n->nlmsg_type = RTM_DELRULE;
		n->nlmsg_flags = NLM_F_REQUEST;

		if (rtnl_talk(&rth, n, 0, 0, NULL, NULL, NULL) < 0)
			return -2;
	}

	return 0;
}
Ejemplo n.º 18
0
int print_action(const struct sockaddr_nl *who,
			   struct nlmsghdr *n,
			   void *arg)
{
	FILE *fp = (FILE*)arg;
	struct tcamsg *t = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * tb[TCAA_MAX+1];

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

	if (len < 0) {
		fprintf(stderr, "Wrong len %d\n", len);
		return -1;
	}

	parse_rtattr(tb, TCAA_MAX, TA_RTA(t), len);

	if (NULL == tb[TCA_ACT_TAB]) {
		if (n->nlmsg_type != RTM_GETACTION)
			fprintf(stderr, "print_action: NULL kind\n");
		return -1;
	}

	if (n->nlmsg_type == RTM_DELACTION) {
		if (n->nlmsg_flags & NLM_F_ROOT) {
			fprintf(fp, "Flushed table ");
			tab_flush = 1;
		} else {
			fprintf(fp, "deleted action ");
		}
	}

	if (n->nlmsg_type == RTM_NEWACTION)
		fprintf(fp, "Added action ");
	tc_print_action(fp, tb[TCA_ACT_TAB]);

	return 0;
}
Ejemplo n.º 19
0
/****************************************************************
 NAME	: print_addr				00/06/02 18:24:09
 AIM	: 
 REMARK	:
****************************************************************/
static int get_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	struct ifaddrmsg *ifa 	= NLMSG_DATA(n);
	int		len	= n->nlmsg_len;
	iplist_ctx	*ctx	= (iplist_ctx *)arg;
	struct rtattr 	*rta_tb[IFA_MAX+1];
	/* sanity check */
	len -= NLMSG_LENGTH(sizeof(*ifa));
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}
	/* check the message type */
	if (n->nlmsg_type != RTM_NEWADDR )
		return 0;
	/* check it is ipv4 */
	if( ifa->ifa_family != AF_INET)
		return 0;
	/* check it is the good interface */
	if( ifa->ifa_index != ctx->ifindex )
		return 0;
		
	/* parse the attribute */
	memset(rta_tb, 0, sizeof(rta_tb));
	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), len);

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

	if (rta_tb[IFA_LOCAL]) {
		u_char *src = RTA_DATA(rta_tb[IFA_LOCAL]);
		if( ctx->nb_elem >= ctx->max_elem )
			return 0;
		ctx->addr[ctx->nb_elem++] = 	(src[0]<<24) + (src[1]<<16) +
						(src[2]<<8) + src[3];
	}
	return 0;
}
Ejemplo n.º 20
0
static void ipoe_up_handler(const struct sockaddr_nl *addr, struct nlmsghdr *h)
{
	struct rtattr *tb[PKT_ATTR_MAX + 1];
	struct rtattr *tb2[IPOE_ATTR_MAX + 1];
	struct genlmsghdr *ghdr = NLMSG_DATA(h);
	int len = h->nlmsg_len;
	struct rtattr *attrs;
	int i;
	int ifindex;
	struct iphdr *iph;
	struct ethhdr *eth;

	len -= NLMSG_LENGTH(GENL_HDRLEN);

	if (len < 0) {
		log_warn("ipoe: wrong controller message length %d\n", len);
		return;
	}

	attrs = (struct rtattr *)((char *)ghdr + GENL_HDRLEN);
	parse_rtattr(tb, PKT_ATTR_MAX, attrs, len);

	for (i = 1; i < PKT_ATTR_MAX; i++) {
		if (!tb[i])
			break;

		parse_rtattr_nested(tb2, IPOE_ATTR_MAX, tb[i]);

		if (!tb2[IPOE_ATTR_ETH_HDR] || !tb2[IPOE_ATTR_IP_HDR] || !tb2[IPOE_ATTR_IFINDEX])
			continue;

		ifindex = *(uint32_t *)(RTA_DATA(tb2[IPOE_ATTR_IFINDEX]));
		iph = (struct iphdr *)(RTA_DATA(tb2[IPOE_ATTR_IP_HDR]));
		eth = (struct ethhdr *)(RTA_DATA(tb2[IPOE_ATTR_ETH_HDR]));

		ipoe_recv_up(ifindex, eth, iph);
	}
}
Ejemplo n.º 21
0
int ll_remember_index(const struct sockaddr_nl *who,
                      struct nlmsghdr *n, void *arg)
{
    int h;
    struct ifinfomsg *ifi = NLMSG_DATA(n);
    struct ll_cache *im, **imp;
    struct rtattr *tb[IFLA_MAX+1];

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

    if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
        return -1;

    memset(tb, 0, sizeof(tb));
    parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
    if (tb[IFLA_IFNAME] == NULL)
        return 0;

    h = ifi->ifi_index & (IDXMAP_SIZE - 1);
    for (imp = &idx_head[h]; (im=*imp)!=NULL; imp = &im->idx_next)
        if (im->index == ifi->ifi_index)
            break;

    if (im == NULL) {
        im = malloc(sizeof(*im));
        if (im == NULL)
            return 0;
        im->idx_next = *imp;
        im->index = ifi->ifi_index;
        *imp = im;
    }

    im->type = ifi->ifi_type;
    im->flags = ifi->ifi_flags;
    strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
    return 0;
}
static int meta_print_eopt(FILE *fd, struct tcf_ematch_hdr *hdr, void *data,
			   int data_len)
{
	struct rtattr *tb[TCA_EM_META_MAX+1];
	struct tcf_meta_hdr *meta_hdr;

	if (parse_rtattr(tb, TCA_EM_META_MAX, data, data_len) < 0)
		return -1;

	if (tb[TCA_EM_META_HDR] == NULL) {
		fprintf(stderr, "Missing meta header\n");
		return -1;
	}

	if (RTA_PAYLOAD(tb[TCA_EM_META_HDR]) < sizeof(*meta_hdr)) {
		fprintf(stderr, "Meta header size mismatch\n");
		return -1;
	}

	meta_hdr = RTA_DATA(tb[TCA_EM_META_HDR]);

	if (print_object(fd, &meta_hdr->left, tb[TCA_EM_META_LVALUE]) < 0)
		return -1;

	switch (meta_hdr->left.op) {
		case TCF_EM_OPND_EQ:
			fprintf(fd, " eq ");
			break;
		case TCF_EM_OPND_LT:
			fprintf(fd, " lt ");
			break;
		case TCF_EM_OPND_GT:
			fprintf(fd, " gt ");
			break;
	}

	return print_object(fd, &meta_hdr->right, tb[TCA_EM_META_RVALUE]);
}
Ejemplo n.º 23
0
static int xfrm_policy_flush_print(const struct sockaddr_nl *who,
				   struct nlmsghdr *n, void *arg)
{
	struct rtattr *tb[XFRMA_MAX+1];
	FILE *fp = (FILE *)arg;
	int len = n->nlmsg_len;

	len -= NLMSG_SPACE(0);
	if (len < 0) {
		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	fprintf(fp, "Flushed policy ");

	parse_rtattr(tb, XFRMA_MAX, NLMSG_DATA(n), len);

	if (tb[XFRMA_POLICY_TYPE]) {
		struct xfrm_userpolicy_type *upt;

		fprintf(fp, "ptype ");

		if (RTA_PAYLOAD(tb[XFRMA_POLICY_TYPE]) < sizeof(*upt))
			fprintf(fp, "(ERROR truncated)");

		upt = (struct xfrm_userpolicy_type *)RTA_DATA(tb[XFRMA_POLICY_TYPE]);
		fprintf(fp, "%s ", strxf_ptype(upt->type));
	}

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

	if (oneline)
		fprintf(fp, "\n");
	fflush(fp);

	return 0;
}
int cthd_nl_wrapper::genl_print_acpi_event_message(const struct sockaddr_nl *who,
					 struct nlmsghdr *n, void *arg)
{
	struct rtattr *tb[ACPI_GENL_ATTR_MAX + 1];
	struct genlmsghdr *ghdr = (struct genlmsghdr *)NLMSG_DATA(n);
	FILE *fp = (FILE *) arg;
	int len = n->nlmsg_len;
	struct rtattr *attrs;

	if (n->nlmsg_type != acpi_event_family_id) {
		fprintf(stderr, "Not a acpi event message, nlmsg_len=%d "
			"nlmsg_type=0x%x\n", n->nlmsg_len, n->nlmsg_type);
		return 0;
	}

	len -= NLMSG_LENGTH(GENL_HDRLEN);

	if (len < 0) {
		fprintf(stderr, "wrong controller message len %d\n", len);
		return -1;
	}

	attrs = (struct rtattr *)((char *)ghdr + GENL_HDRLEN);
	parse_rtattr(tb, ACPI_GENL_ATTR_MAX, attrs, len);

	if (tb[ACPI_GENL_ATTR_EVENT]) {
		struct acpi_genl_event *event =
		    (struct acpi_genl_event *)RTA_DATA(tb[ACPI_GENL_ATTR_EVENT]);
		fprintf(fp, "\n%20s %15s %08x %08x\n", event->device_class,
			event->bus_id, event->type, event->data);
		fflush(fp);
		return 0;
	}

	return -1;

}
Ejemplo n.º 25
0
static int get_nlmsg(const struct sockaddr_nl *who,
		     struct nlmsghdr *m, void *arg)
{
	struct ifinfomsg *ifi = NLMSG_DATA(m);
	struct rtattr *tb[IFLA_MAX+1];
	int len = m->nlmsg_len;
	struct ifstat_ent *n;
	int i;

	if (m->nlmsg_type != RTM_NEWLINK)
		return 0;

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

	if (!(ifi->ifi_flags&IFF_UP))
		return 0;

	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL || tb[IFLA_STATS] == NULL)
		return 0;

	n = malloc(sizeof(*n));
	if (!n)
		abort();
	n->ifindex = ifi->ifi_index;
	n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));
	memcpy(&n->ival, RTA_DATA(tb[IFLA_STATS]), sizeof(n->ival));
	memset(&n->rate, 0, sizeof(n->rate));
	for (i = 0; i < MAXS; i++)
		n->val[i] = n->ival[i];
	n->next = kern_db;
	kern_db = n;
	return 0;
}
Ejemplo n.º 26
0
/* Netlink flag Link update */
static int
netlink_reflect_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
{
	struct ifinfomsg *ifi;
	struct rtattr *tb[IFLA_MAX + 1];
	interface *ifp;
	int len;

	ifi = NLMSG_DATA(h);
	if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
		return 0;

	len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifinfomsg));
	if (len < 0)
		return -1;

	/* Interface name lookup */
	memset(tb, 0, sizeof (tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL)
		return -1;

	/* ignore loopback device */
	if (ifi->ifi_type == ARPHRD_LOOPBACK)
		return 0;

	/* find the interface */
	ifp = if_get_by_ifindex(ifi->ifi_index);
	if (!ifp)
		return -1;

	/* Update flags */
	ifp->flags = ifi->ifi_flags;

	return 0;
}
Ejemplo n.º 27
0
int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n,
		     void *arg)
{
	FILE *fp = (FILE*)arg;
	struct xfrm_usersa_info *xsinfo = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * tb[XFRMA_MAX+1];

	if (n->nlmsg_type != XFRM_MSG_NEWSA &&
	    n->nlmsg_type != XFRM_MSG_DELSA) {
//		fprintf(stderr, "Not a state: %08x %08x %08x\n",
//			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}

	len -= NLMSG_LENGTH(sizeof(*xsinfo));
	if (len < 0) {
//		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
		return -1;
	}

	if (!xfrm_state_filter_match(xsinfo))
		return 0;

	parse_rtattr(tb, XFRMA_MAX, XFRMS_RTA(xsinfo), len);

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

	xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL);

	if (oneline)
		fprintf(fp, "\n");

	return 0;
}
Ejemplo n.º 28
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;
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo)
{
	struct nlmsg_list *l, **lp;

	lp = &linfo->head;
	while ( (l = *lp) != NULL) {
		int ok = 0;
		int missing_net_address = 1;
		struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
		struct nlmsg_list *a;

		for (a = ainfo->head; a; a = a->next) {
			struct nlmsghdr *n = &a->h;
			struct ifaddrmsg *ifa = NLMSG_DATA(n);
			struct rtattr *tb[IFA_MAX + 1];
			unsigned int ifa_flags;

			if (ifa->ifa_index != ifi->ifi_index)
				continue;
			missing_net_address = 0;
			if (filter.family && filter.family != ifa->ifa_family)
				continue;
			if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
				continue;

			parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
			ifa_flags = get_ifa_flags(ifa, tb[IFA_FLAGS]);

			if ((filter.flags ^ ifa_flags) & filter.flagmask)
				continue;
			if (filter.pfx.family || filter.label) {
				if (!tb[IFA_LOCAL])
					tb[IFA_LOCAL] = tb[IFA_ADDRESS];

				if (filter.pfx.family && tb[IFA_LOCAL]) {
					inet_prefix dst;
					memset(&dst, 0, sizeof(dst));
					dst.family = ifa->ifa_family;
					memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
					if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
						continue;
				}
				if (filter.label) {
					SPRINT_BUF(b1);
					const char *label;
					if (tb[IFA_LABEL])
						label = RTA_DATA(tb[IFA_LABEL]);
					else
						label = ll_idx_n2a(ifa->ifa_index, b1);
					if (fnmatch(filter.label, label, 0) != 0)
						continue;
				}
			}

			ok = 1;
			break;
		}
		if (missing_net_address &&
		    (filter.family == AF_UNSPEC || filter.family == AF_PACKET))
			ok = 1;
		if (!ok) {
			*lp = l->next;
			free(l);
		} else
			lp = &l->next;
	}
}