Example #1
0
static int parse_v4_neighbor(
        orc_options_t * options,
        struct nlmsghdr * nl_msg,
        orc_v4_neighbor_t * neigh)
{
    struct ndmsg * nd_msg;
    struct rtattr * attr;
    int rtattr_len;
    int found_l3_addr = 0;

    nd_msg = (struct ndmsg *) NLMSG_DATA(nl_msg);
    /* extract first attribute */
    attr = (struct rtattr *) NDA_RTA(nd_msg);
    rtattr_len = NDA_PAYLOAD(nl_msg);

    if (nd_msg->ndm_family != AF_INET)
    {
        /* TODO: add IPv6 support */
        orc_debug("Ignoring IPv6 neighbor update: IPv6 unsupported\n");
        return 0;
    }

    neigh->if_index = nd_msg->ndm_ifindex;

    /** TODO: ignore neighbor updates on non-orc interfaces
     */

    if (nd_msg->ndm_state != NUD_STALE &&
            nd_msg->ndm_state != NUD_PERMANENT &&
            nd_msg->ndm_state != NUD_FAILED &&
            nd_msg->ndm_state != NUD_REACHABLE)
    {
        orc_trace("Ignoring irrelevant neighbor update:"
                    " not STALE/PERM/REACHABLE/FAILED\n");
        return 0;
    }

    /** note: the RTA_NEXT() macro decrements rtattr_len each time */
    for(; RTA_OK(attr, rtattr_len); attr = RTA_NEXT(attr, rtattr_len))
    {
        switch (attr->rta_type)
        {
            case NDA_DST:
                found_l3_addr = 1;
                memcpy(&neigh->ip, RTA_DATA(attr), sizeof(neigh->ip));
                orc_debug("Parsed IPv4 neighbor L3 addr: " IPV4_FORMAT "\n",
                        IPV4_ADDR_PRINT(neigh->ip));
                break;
            case NDA_LLADDR:
                neigh->mac_valid = 1;
                memcpy(neigh->mac, RTA_DATA(attr), 6);
                orc_debug("Parsed IPv4 neighbor L2 addr: " ETH_FORMAT "\n",
                        ETH_ADDR_PRINT(neigh->mac));
                break;
            case NDA_CACHEINFO:
                orc_trace("Ignoring irrelevant neighbor attr NDA_CACHEINFO\n");
                break;
            case NDA_PROBES:
                orc_trace("Ignoring irrelevant neighbor attr NDA_PROBES\n");
                break;
            default:
            /** TODO: decide if we actually need anything from here */
                orc_warn("Skipping unhandled ipv4 neighbor attr: %d\n", attr->rta_type);
        };
    }

    return found_l3_addr;
}
Example #2
0
static void rtnl_print_neigh(struct nlmsghdr *hdr)
{
	struct ndmsg *ndm = NLMSG_DATA(hdr);
	uint32_t attrs_len = NDA_PAYLOAD(hdr);
	struct rtattr *attr = NDA_RTA(ndm);
	struct nda_cacheinfo *ci;
	int hz = get_user_hz();
	char addr_str[256];
	char hw_addr[30];
	char states[256];
	char flags[256];

	if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ndm)))
		return;

	tprintf(" [ Neigh Family %d (%s%s%s)", ndm->ndm_family,
			colorize_start(bold),
			addr_family2str(ndm->ndm_family),
			colorize_end());
	tprintf(", Link Index %d", ndm->ndm_ifindex);
	tprintf(", State %d (%s%s%s)", ndm->ndm_state,
			colorize_start(bold),
			flags2str(neigh_states, ndm->ndm_state, states,
				sizeof(states)),
			colorize_end());
	tprintf(", Flags %d (%s%s%s)", ndm->ndm_flags,
			colorize_start(bold),
			flags2str(neigh_flags, ndm->ndm_flags, flags,
				sizeof(flags)),
			colorize_end());
	tprintf(", Type %d (%s%s%s)", ndm->ndm_type,
			colorize_start(bold),
			route_type2str(ndm->ndm_type),
			colorize_end());
	tprintf(" ]\n");

	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
		switch (attr->rta_type) {
		case NDA_DST:
			rta_fmt(attr, "Address %s", addr2str(ndm->ndm_family,
						RTA_DATA(attr), addr_str,
						sizeof(addr_str)));
			break;
		case NDA_LLADDR:
			rta_fmt(attr, "HW Address %s",
					device_addr2str(RTA_DATA(attr),
						RTA_LEN(attr), 0, hw_addr,
						sizeof(hw_addr)));
			break;
		case NDA_PROBES:
			rta_fmt(attr, "Probes %d", RTA_UINT32(attr));
			break;
		case NDA_CACHEINFO:
			ci = RTA_DATA(attr);
			tprintf("\tA: Cache (");
			tprintf("confirmed(%ds)", ci->ndm_confirmed / hz);
			tprintf(", used(%ds)", ci->ndm_used / hz);
			tprintf(", updated(%ds)", ci->ndm_updated / hz);
			tprintf(", refcnt(%d))", ci->ndm_refcnt);
			tprintf(", Len %d\n", RTA_LEN(attr));
			break;
		default:
			rta_fmt(attr, "0x%x", attr->rta_type);
			break;
		}
	}
}