Ejemplo n.º 1
0
static void
_j4status_nl_cache_change(struct nl_cache *cache, struct nl_object *object, int something, void *user_data)
{
    J4statusPluginContext *self = user_data;
        J4statusNlSection *section;

    if ( cache == self->link_cache )
    {
        struct rtnl_link *link = nl_object_priv(object);

        section = g_hash_table_lookup(self->sections, GINT_TO_POINTER(rtnl_link_get_ifindex(link)));
        if ( section == NULL )
            return;
        g_debug("Link cache update: %p = %s", object, rtnl_link_get_ifalias(link));

        if ( section->link != link )
        {
            nl_object_get(object);
            rtnl_link_put(section->link);
            section->link = link;
        }

    }
    else if ( cache == self->addr_cache )
    {
        struct rtnl_addr *addr = nl_object_priv(object);
        section = g_hash_table_lookup(self->sections, GINT_TO_POINTER(rtnl_addr_get_ifindex(addr)));
        if ( section == NULL )
            return;
        g_debug("Addr cache update: %p = %d", object, rtnl_addr_get_ifindex(addr));

        GList **list;
        switch ( rtnl_addr_get_family(addr) )
        {
        case AF_INET:
            list = &section->ipv4_addresses;
        break;
        case AF_INET6:
            list = &section->ipv6_addresses;
        break;
        default:
            /* Not supported */
            return;
        }

        if ( g_list_find_custom(*list, addr,_j4status_nl_address_compare)  != NULL )
            /* Already got it */
            return;

        nl_object_get(object);
        *list = g_list_prepend(*list, addr);
    }
    else
        g_assert_not_reached();
    _j4status_nl_section_update(section);
}
static void
find_one_address (struct nl_object *object, void *user_data)
{
	FindAddrInfo *info = user_data;
	struct rtnl_addr *addr = (struct rtnl_addr *) object;
	struct nl_addr *local;
	void *binaddr;

	if (info->found)
		return;

	if (rtnl_addr_get_ifindex (addr) != info->ifindex)
		return;
	if (rtnl_addr_get_family (addr) != info->family)
		return;

	if (rtnl_addr_get_prefixlen (addr) != info->prefix)
		return;

	local = rtnl_addr_get_local (addr);
	if (nl_addr_get_family (local) != info->family)
		return;
	if (nl_addr_get_len (local) != info->addrlen)
		return;
	binaddr = nl_addr_get_binary_addr (local);
	if (binaddr) {
		if (memcmp (binaddr, info->addr, info->addrlen) == 0)
			info->found = TRUE; /* Yay, found it */
	}
}
static NMIP6Device *
process_address_change (NMIP6Manager *manager, struct nl_msg *msg)
{
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	NMIP6Device *device;
	struct nlmsghdr *hdr;
	struct rtnl_addr *rtnladdr;
	int old_size;

	hdr = nlmsg_hdr (msg);
	rtnladdr = NULL;
	nl_msg_parse (msg, ref_object, &rtnladdr);
	if (!rtnladdr) {
		nm_log_dbg (LOGD_IP6, "error processing netlink new/del address message");
		return NULL;
	}

	device = nm_ip6_manager_get_device (manager, rtnl_addr_get_ifindex (rtnladdr));

	old_size = nl_cache_nitems (priv->addr_cache);
	nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL, NULL);

	/* The kernel will re-notify us of automatically-added addresses
	 * every time it gets another router advertisement. We only want
	 * to notify higher levels if we actually changed something.
	 */
	nm_log_dbg (LOGD_IP6, "(%s): address cache size: %d -> %d:",
		    device_get_iface (device), old_size, nl_cache_nitems (priv->addr_cache));
	dump_address_change (device, hdr, rtnladdr);
	rtnl_addr_put (rtnladdr);
	if (nl_cache_nitems (priv->addr_cache) == old_size)
		return NULL;

	return device;
}
static void
wait_for_no_addresses (NMIP6Manager *self, NMIP6Device *device)
{
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (self);
	guint64 now, end;
	gboolean has_addrs = TRUE;

	now = end = g_get_real_time ();
	end += (G_USEC_PER_SEC * 3);

	while (has_addrs && now < end) {
		struct rtnl_addr *rtnladdr;
		struct nl_addr *nladdr;

		nl_cache_refill (priv->nlh, priv->addr_cache);
		for (has_addrs = FALSE, rtnladdr = FIRST_ADDR (priv->addr_cache);
		     rtnladdr;
		     rtnladdr = NEXT_ADDR (rtnladdr)) {

			nladdr = rtnl_addr_get_local (rtnladdr);
			if (   rtnl_addr_get_ifindex (rtnladdr) == device->ifindex
			    && nladdr
			    && nl_addr_get_family (nladdr) == AF_INET6) {
				/* Still IPv6 addresses on the interface */
				has_addrs = TRUE;
				nm_log_dbg (LOGD_IP6, "(%s) waiting for cleared IPv6 addresses", device->iface);
				g_usleep (100);
				now = g_get_real_time ();
				break;
			}
		}
	}
}
Ejemplo n.º 5
0
	void add_addr_to_list(struct nl_object *obj, void *data)
	{
		char buf[INET6_ADDRSTRLEN+5];
		std::list<vaddress> *list = static_cast<std::list<vaddress>*>(data);

		struct nl_addr *naddr = rtnl_addr_get_local((struct rtnl_addr *) obj);
		int ifindex = 0;
		int scope = rtnl_addr_get_scope((struct rtnl_addr *) obj);

		if (scope == rtnl_str2scope("link"))
			ifindex = rtnl_addr_get_ifindex((struct rtnl_addr *) obj);

		if (naddr)
		{
			int family = nl_addr_get_family(naddr);
			nl_addr2str( naddr, buf, sizeof( buf ) );
			vaddress vaddr(vaddress::Family(family), vaddress::strip_netmask(std::string(buf)), ifindex, false);
			list->push_back( vaddr );
		}

		struct nl_addr *baddr = rtnl_addr_get_broadcast((struct rtnl_addr *) obj);

		if (baddr)
		{
			int family = nl_addr_get_family(baddr);
			nl_addr2str( baddr, buf, sizeof( buf ) );
			vaddress vaddr(vaddress::Family(family), vaddress::strip_netmask(std::string(buf)), ifindex, true);
			list->push_back( vaddr );
		}
	}
static void
check_addresses (NMIP6Device *device)
{
	NMIP6Manager *manager = device->manager;
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	struct rtnl_addr *rtnladdr;
	struct nl_addr *nladdr;
	struct in6_addr *addr;

	/* Reset address information */
	device->has_linklocal = FALSE;
	device->has_nonlinklocal = FALSE;

	/* Look for any IPv6 addresses the kernel may have set for the device */
	for (rtnladdr = (struct rtnl_addr *) nl_cache_get_first (priv->addr_cache);
		 rtnladdr;
		 rtnladdr = (struct rtnl_addr *) nl_cache_get_next ((struct nl_object *) rtnladdr)) {
		char buf[INET6_ADDRSTRLEN];

		if (rtnl_addr_get_ifindex (rtnladdr) != device->ifindex)
			continue;

		nladdr = rtnl_addr_get_local (rtnladdr);
		if (!nladdr || nl_addr_get_family (nladdr) != AF_INET6)
			continue;

		addr = nl_addr_get_binary_addr (nladdr);

		if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0) {
			nm_log_dbg (LOGD_IP6, "(%s): netlink address: %s/%d",
			            device->iface, buf,
			            rtnl_addr_get_prefixlen (rtnladdr));
		}

		if (IN6_IS_ADDR_LINKLOCAL (addr)) {
			if (device->state == NM_IP6_DEVICE_UNCONFIGURED)
				device_set_state (device, NM_IP6_DEVICE_GOT_LINK_LOCAL);
			device->has_linklocal = TRUE;
		} else {
			if (device->state == NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT)
				device_set_state (device, NM_IP6_DEVICE_GOT_ADDRESS);
			device->has_nonlinklocal = TRUE;
		}
	}

	/* There might be a LL address hanging around on the interface from
	 * before in the initial run, but if it goes away later, make sure we
	 * regress from GOT_LINK_LOCAL back to UNCONFIGURED.
	 */
	if ((device->state == NM_IP6_DEVICE_GOT_LINK_LOCAL) && !device->has_linklocal)
		device_set_state (device, NM_IP6_DEVICE_UNCONFIGURED);

	nm_log_dbg (LOGD_IP6, "(%s): addresses checked (state %s)",
		    device->iface, state_to_string (device->state));
}
Ejemplo n.º 7
0
TError TNlLink::WaitAddress(int timeout_s) {
    struct nl_cache *cache;
    int ret;

    L() << "Wait for autoconf at " << GetDesc() << std::endl;

    ret = rtnl_addr_alloc_cache(GetSock(), &cache);
    if (ret < 0)
        return Nl->Error(ret, "Cannot allocate addr cache");

    do {
        for (auto obj = nl_cache_get_first(cache); obj; obj = nl_cache_get_next(obj)) {
            auto addr = (struct rtnl_addr *)obj;

            if (!rtnl_addr_get_local(addr) ||
                    rtnl_addr_get_ifindex(addr) != GetIndex() ||
                    rtnl_addr_get_family(addr) != AF_INET6 ||
                    rtnl_addr_get_scope(addr) >= RT_SCOPE_LINK ||
                    (rtnl_addr_get_flags(addr) &
                     (IFA_F_TENTATIVE | IFA_F_DEPRECATED)))
                continue;

            L() << "Got " << TNlAddr(rtnl_addr_get_local(addr)).Format()
                << " at " << GetDesc() << std::endl;

            nl_cache_free(cache);
            return TError::Success();
        }

        usleep(1000000);
        ret = nl_cache_refill(GetSock(), cache);
        if (ret < 0)
            return Nl->Error(ret, "Cannot refill address cache");
    } while (--timeout_s > 0);

    nl_cache_free(cache);
    return TError(EError::Unknown, "Network autoconf timeout");
}
Ejemplo n.º 8
0
static void
nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
{
	NMIP6Manager *manager = device->manager;
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	struct rtnl_addr *rtnladdr;
	struct nl_addr *nladdr;
	struct in6_addr *addr;
	CallbackInfo *info;
	guint dhcp_opts = IP6_DHCP_OPT_NONE;
	gboolean found_linklocal = FALSE, found_other = FALSE;

	nm_log_dbg (LOGD_IP6, "(%s): syncing with netlink (ra_flags 0x%X) (state/target '%s'/'%s')",
	            device->iface, device->ra_flags,
	            state_to_string (device->state),
	            state_to_string (device->target_state));

	/* Look for any IPv6 addresses the kernel may have set for the device */
	for (rtnladdr = (struct rtnl_addr *) nl_cache_get_first (priv->addr_cache);
		 rtnladdr;
		 rtnladdr = (struct rtnl_addr *) nl_cache_get_next ((struct nl_object *) rtnladdr)) {
		char buf[INET6_ADDRSTRLEN];

		if (rtnl_addr_get_ifindex (rtnladdr) != device->ifindex)
			continue;

		nladdr = rtnl_addr_get_local (rtnladdr);
		if (!nladdr || nl_addr_get_family (nladdr) != AF_INET6)
			continue;

		addr = nl_addr_get_binary_addr (nladdr);

		if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0) {
			nm_log_dbg (LOGD_IP6, "(%s): netlink address: %s",
			            device->iface, buf);
		}

		if (IN6_IS_ADDR_LINKLOCAL (addr)) {
			if (device->state == NM_IP6_DEVICE_UNCONFIGURED)
				device->state = NM_IP6_DEVICE_GOT_LINK_LOCAL;
			found_linklocal = TRUE;
		} else {
			if (device->state < NM_IP6_DEVICE_GOT_ADDRESS)
				device->state = NM_IP6_DEVICE_GOT_ADDRESS;
			found_other = TRUE;
		}
	}

	/* There might be a LL address hanging around on the interface from
	 * before in the initial run, but if it goes away later, make sure we
	 * regress from GOT_LINK_LOCAL back to UNCONFIGURED.
	 */
	if ((device->state == NM_IP6_DEVICE_GOT_LINK_LOCAL) && !found_linklocal)
		device->state = NM_IP6_DEVICE_UNCONFIGURED;

	nm_log_dbg (LOGD_IP6, "(%s): addresses synced (state %s)",
	            device->iface, state_to_string (device->state));

	/* We only care about router advertisements if we want a real IPv6 address */
	if (   (device->target_state == NM_IP6_DEVICE_GOT_ADDRESS)
	    && (device->ra_flags & IF_RA_RCVD)) {

		if (device->state < NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT)
			device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT;

		if (device->ra_flags & IF_RA_MANAGED) {
			dhcp_opts = IP6_DHCP_OPT_MANAGED;
			nm_log_dbg (LOGD_IP6, "router advertisement deferred to DHCPv6");
		} else if (device->ra_flags & IF_RA_OTHERCONF) {
			dhcp_opts = IP6_DHCP_OPT_OTHERCONF;
			nm_log_dbg (LOGD_IP6, "router advertisement requests parallel DHCPv6");
		}
	}

	if (!device->addrconf_complete) {
		/* Managed mode (ie DHCP only) short-circuits automatic addrconf, so
		 * we don't bother waiting for the device's target state to be reached
		 * when the RA requests managed mode.
		 */
		if (   (device->state >= device->target_state)
		    || (dhcp_opts == IP6_DHCP_OPT_MANAGED)) {
			/* device->finish_addrconf_id may currently be a timeout
			 * rather than an idle, so we remove the existing source.
			 */
			if (device->finish_addrconf_id)
				g_source_remove (device->finish_addrconf_id);

			nm_log_dbg (LOGD_IP6, "(%s): reached target state or Managed-mode requested (state '%s') (dhcp opts 0x%X)",
			            device->iface, state_to_string (device->state),
			            dhcp_opts);

			info = callback_info_new (device, dhcp_opts, TRUE);
			device->finish_addrconf_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
			                                              finish_addrconf,
			                                              info,
			                                              (GDestroyNotify) g_free);
		}
	} else if (config_changed) {
		if (!device->config_changed_id) {
			gboolean success = TRUE;

			/* If for some reason an RA-provided address disappeared, we need
			 * to make sure we fail the connection as it's no longer valid.
			 */
			if (   (device->state == NM_IP6_DEVICE_GOT_ADDRESS)
			    && (device->target_state == NM_IP6_DEVICE_GOT_ADDRESS)
			    && !found_other) {
				nm_log_dbg (LOGD_IP6, "(%s): RA-provided address no longer valid",
				            device->iface);
				success = FALSE;
			}

			info = callback_info_new (device, dhcp_opts, success);
			device->config_changed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
			                                             emit_config_changed,
			                                             info,
			                                             (GDestroyNotify) g_free);
		}
	}
}
Ejemplo n.º 9
0
NMIP6Config *
nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex)
{
	NMIP6ManagerPrivate *priv;
	NMIP6Device *device;
	NMIP6Config *config;
	struct rtnl_addr *rtnladdr;
	struct nl_addr *nladdr;
	struct in6_addr *addr;
	NMIP6Address *ip6addr;
	struct rtnl_route *rtnlroute;
	struct nl_addr *nldest, *nlgateway;
	struct in6_addr *dest, *gateway;
	gboolean defgw_set = FALSE;
	struct in6_addr defgw;
	uint32_t metric;
	NMIP6Route *ip6route;
	int i;

	g_return_val_if_fail (NM_IS_IP6_MANAGER (manager), NULL);
	g_return_val_if_fail (ifindex > 0, NULL);

	priv = NM_IP6_MANAGER_GET_PRIVATE (manager);

	device = (NMIP6Device *) g_hash_table_lookup (priv->devices,
	                                              GINT_TO_POINTER (ifindex));
	if (!device) {
		nm_log_warn (LOGD_IP6, "(%d): addrconf not started.", ifindex);
		return NULL;
	}

	config = nm_ip6_config_new ();
	if (!config) {
		nm_log_err (LOGD_IP6, "(%s): out of memory creating IP6 config object.",
		            device->iface);
		return NULL;
	}

	/* Make sure we refill the route and address caches, otherwise we won't get
	 * up-to-date information here since the netlink route/addr change messages
	 * may be lagging a bit.
	 */
	nl_cache_refill (priv->nlh, priv->route_cache);
	nl_cache_refill (priv->nlh, priv->addr_cache);

	/* Add routes */
	for (rtnlroute = FIRST_ROUTE (priv->route_cache); rtnlroute; rtnlroute = NEXT_ROUTE (rtnlroute)) {
		/* Make sure it's an IPv6 route for this device */
		if (rtnl_route_get_oif (rtnlroute) != device->ifindex)
			continue;
		if (rtnl_route_get_family (rtnlroute) != AF_INET6)
			continue;

		nldest = rtnl_route_get_dst (rtnlroute);
		if (!nldest || nl_addr_get_family (nldest) != AF_INET6)
			continue;
		dest = nl_addr_get_binary_addr (nldest);

		nlgateway = rtnl_route_get_gateway (rtnlroute);
		if (!nlgateway || nl_addr_get_family (nlgateway) != AF_INET6)
			continue;
		gateway = nl_addr_get_binary_addr (nlgateway);

		if (rtnl_route_get_dst_len (rtnlroute) == 0) {
			/* Default gateway route; don't add to normal routes but to each address */
			if (!defgw_set) {
				memcpy (&defgw, gateway, sizeof (defgw));
				defgw_set = TRUE;
			}
			continue;
		}

		/* Also ignore link-local routes where the destination and gateway are
		 * the same, which apparently get added by the kernel but return -EINVAL
		 * when we try to add them via netlink.
		 */
		if (gateway && IN6_ARE_ADDR_EQUAL (dest, gateway))
			continue;

		ip6route = nm_ip6_route_new ();
		nm_ip6_route_set_dest (ip6route, dest);
		nm_ip6_route_set_prefix (ip6route, rtnl_route_get_dst_len (rtnlroute));
		nm_ip6_route_set_next_hop (ip6route, gateway);
		rtnl_route_get_metric(rtnlroute, 1, &metric);
		if (metric != UINT_MAX)
			nm_ip6_route_set_metric (ip6route, metric);
		nm_ip6_config_take_route (config, ip6route);
	}

	/* Add addresses */
	for (rtnladdr = FIRST_ADDR (priv->addr_cache); rtnladdr; rtnladdr = NEXT_ADDR (rtnladdr)) {
		if (rtnl_addr_get_ifindex (rtnladdr) != device->ifindex)
			continue;

		nladdr = rtnl_addr_get_local (rtnladdr);
		if (!nladdr || nl_addr_get_family (nladdr) != AF_INET6)
			continue;

		addr = nl_addr_get_binary_addr (nladdr);
		ip6addr = nm_ip6_address_new ();
		nm_ip6_address_set_prefix (ip6addr, rtnl_addr_get_prefixlen (rtnladdr));
		nm_ip6_address_set_address (ip6addr, addr);
		nm_ip6_config_take_address (config, ip6addr);
		if (defgw_set)
			nm_ip6_address_set_gateway (ip6addr, &defgw);
	}

	/* Add DNS servers */
	if (device->rdnss_servers) {
		NMIP6RDNSS *rdnss = (NMIP6RDNSS *)(device->rdnss_servers->data);

		for (i = 0; i < device->rdnss_servers->len; i++)
			nm_ip6_config_add_nameserver (config, &rdnss[i].addr);
	}

	/* Add DNS domains */
	if (device->dnssl_domains) {
		NMIP6DNSSL *dnssl = (NMIP6DNSSL *)(device->dnssl_domains->data);

		for (i = 0; i < device->dnssl_domains->len; i++)
			nm_ip6_config_add_domain (config, dnssl[i].domain);
	}

	return config;
}
Ejemplo n.º 10
0
static void nl_ihandler_cb(struct incident *i, void *ctx)
{
	g_debug("%s i %p ctx %p", __PRETTY_FUNCTION__, i, ctx);
	struct connection *con;
	incident_value_con_get(i, "con", &con);

	char *remote = con->remote.ip_string;
	char *local = con->local.ip_string;
	char *prefix = "::ffff:";
	if( strncmp(local, prefix, strlen(prefix)) == 0)
		local += strlen(prefix);
	if( strncmp(remote, prefix, strlen(prefix)) == 0)
		remote += strlen(prefix);


	int ifindex;
	int err;
	{
		g_debug("local addr %s remote addr %s", local, remote);
		struct rtnl_addr *addr = rtnl_addr_alloc();
	
		struct nl_addr *a;

		if ( ( err = nl_addr_parse(local, AF_UNSPEC, &a)) != 0 )
			g_critical("could not parse addr %s (%s)", local, nl_geterror(err));
		rtnl_addr_set_local(addr, a);
		nl_addr_put(a);
	
		struct rtnl_addr *res = NULL;
		nl_cache_foreach_filter(nl_runtime.addr_cache, OBJ_CAST(addr), cache_lookup_cb, &res);
	
		g_critical("LOCAL RTNL_ADDR %p", res);
	
	/*	struct nl_dump_params params = {
			.dp_type = NL_DUMP_LINE,
			.dp_fd = stdout,
		};
		nl_cache_dump_filter(nl_runtime.addr_cache, &params, OBJ_CAST(addr));
	*/
		ifindex = rtnl_addr_get_ifindex(res);
	}
	

	struct rtnl_neigh *res = NULL;
	{
		struct rtnl_neigh *neigh = rtnl_neigh_alloc();
		rtnl_neigh_set_ifindex(neigh, ifindex);
		struct nl_addr *a;
		if ( ( err = nl_addr_parse(remote, AF_UNSPEC, &a)) != 0 )
			g_critical("could not parse addr %s (%s)", remote, nl_geterror(err));
		rtnl_neigh_set_dst(neigh, a);
		nl_addr_put(a);

		nl_cache_foreach_filter(nl_runtime.neigh_cache, OBJ_CAST(neigh), cache_lookup_cb, &res);
	}

	if( res )
	{
		g_critical("GOT NEIGH %p", res);
		struct nl_addr *lladdr = rtnl_neigh_get_lladdr(res);
		char buf[123];
		nl_addr2str(lladdr, buf, sizeof(buf));
		g_critical("GOT NEIGH %s", buf);

		struct incident *i = incident_new("dionaea.module.nl.connection.info.mac");
		incident_value_string_set(i, "mac", g_string_new(buf));
		incident_value_con_set(i, "con", con);
		incident_report(i);
		incident_free(i);
	}
}
Ejemplo n.º 11
0
static void nl_obj_input(struct nl_object *obj, void *arg)
{
	struct _obj
	{
		NLHDR_COMMON
	};

	struct _obj *o = (struct _obj *)obj;

	if( o->ce_msgtype == RTM_NEWLINK  || o->ce_msgtype == RTM_DELLINK ) 
	{
		struct rtnl_link *link = (struct rtnl_link *)obj;
		struct nl_addr *a = rtnl_link_get_addr(link);
		char buf[123];
		nl_addr2str(a, buf, sizeof(buf));
		int ifindex = rtnl_link_get_ifindex(link);
		bool active = rtnl_link_get_flags(link) & IFF_UP;
		char *iface = rtnl_link_get_name(link);
		if( o->ce_msgtype == RTM_NEWLINK ) 
		{
			struct link_addr *nla = g_hash_table_lookup(nl_runtime.link_addr_cache, &ifindex);
			if( nla == NULL )
			{
				g_critical("LINK NEW %s %i", iface, ifindex);
				struct link_addr *nla = link_addr_new(iface, ifindex, active);
				g_hash_table_insert(nl_runtime.link_addr_cache, &nla->ifindex, nla);
			}else
			{
				g_critical("LINK CHANGE %s %i", iface, ifindex);
				GHashTableIter iter;
				gpointer key, value;
				g_hash_table_iter_init(&iter, nla->addrs);
				if( active != nla->active )
				{
					while( g_hash_table_iter_next(&iter, &key, &value) )
					{
						struct incident *i;
						if( active )
						{
							g_critical("LINK UP");
							i = incident_new("dionaea.module.nl.addr.new");
						}else
						{
							g_critical("LINK DOWN");
							i = incident_new("dionaea.module.nl.addr.del");
						}
						incident_value_string_set(i, "addr", g_string_new(key));
						incident_value_string_set(i, "iface", g_string_new(nla->iface));
						incident_value_int_set(i, "scope", nla->ifindex);
						incident_report(i);
						incident_free(i);
					}
					nla->active = active;
				}
			}
		}else
		if( o->ce_msgtype == RTM_DELLINK ) 
		{
			g_critical("LINK DEL %s %i", iface, ifindex);
			struct link_addr *nla = g_hash_table_lookup(nl_runtime.link_addr_cache, &ifindex);
			g_hash_table_remove(nl_runtime.link_addr_cache, &ifindex);
			link_addr_free(nla);
		}
	}else
	if( o->ce_msgtype == RTM_NEWADDR  || o->ce_msgtype == RTM_DELADDR ) 
	{
		char buf[128];
		struct rtnl_addr *addr = (struct rtnl_addr *)obj;
		struct nl_addr *a = rtnl_addr_get_local(addr);
		int ifindex = rtnl_addr_get_ifindex(addr);
		nl_addr2str(a, buf, 128);
		char *slash; 
		if( (slash = strstr(buf, "/")) != NULL)
			*slash = '\0';
		char *saddr = NULL;

		struct link_addr *nla = g_hash_table_lookup(nl_runtime.link_addr_cache, &ifindex);
		if( !nla )
			return;

		if( o->ce_msgtype == RTM_NEWADDR ) 
		{
			if( g_hash_table_lookup(nla->addrs, buf) == NULL )
			{
				g_warning("NEW ADDR %s!", buf);
				saddr = g_strdup(buf);
				g_hash_table_insert(nla->addrs, saddr, saddr);

				if( nla->active )
				{
					struct incident *i = incident_new("dionaea.module.nl.addr.new");
					incident_value_string_set(i, "addr", g_string_new(saddr));
					incident_value_string_set(i, "iface", g_string_new(nla->iface));
					incident_value_int_set(i, "scope", nla->ifindex);
					incident_report(i);
					incident_free(i);
				}
			}
		}else
		if( o->ce_msgtype == RTM_DELADDR )
		{
			if( ( saddr = g_hash_table_lookup(nla->addrs, buf) ) != NULL )
			{
				g_warning("DEL ADDR! %s", buf);
				if( nla->active )
				{
					struct incident *i = incident_new("dionaea.module.nl.addr.del");
					incident_value_string_set(i, "addr", g_string_new(saddr));
					incident_value_string_set(i, "iface", g_string_new(nla->iface));
					incident_value_int_set(i, "scope", nla->ifindex);
					incident_report(i);
					incident_free(i);
				}
				g_hash_table_remove(nla->addrs, buf);
				g_free(saddr);
			}
		}
	}
/*
	struct nl_dump_params dp = {
		.dp_type = NL_DUMP_STATS,
		.dp_fd = stdout,
		.dp_dump_msgtype = 1,
	};

	nl_object_dump(obj, &dp);

	struct nl_dump_params params = {
		.dp_type = NL_DUMP_LINE,
		.dp_fd = stdout,
		.dp_prefix = 1,
	};
	g_debug("addr cache");
	nl_cache_dump(nl_runtime.addr_cache, &params);
	g_debug("arp cache");
	nl_cache_dump(nl_runtime.neigh_cache, &params);
	g_debug("link cache");
	nl_cache_dump(nl_runtime.link_cache, &params);
*/
}
Ejemplo n.º 12
0
static void env_dump(struct nl_object *obj, void *arg)
{
	struct nl_dump_params *p = arg;
	struct rtnl_addr *addr = (struct rtnl_addr *) obj;
	struct nl_cache *link_cache;
	struct nl_addr *a;
	static int index = 0;
	char buf[128], pfx[32], *s;

	snprintf(pfx, sizeof(pfx), "ADDR%d", index++);

	nl_dump_line(p, "%s_FAMILY=%s\n", pfx,
		     nl_af2str(rtnl_addr_get_family(addr), buf, sizeof(buf)));

	nl_dump_line(p, "%s_LOCAL=%s\n", pfx,
		     nl_addr2str(rtnl_addr_get_local(addr), buf, sizeof(buf)));

	nl_dump_line(p, "%s_IFINDEX=%u\n", pfx, rtnl_addr_get_ifindex(addr));
	link_cache = nl_cache_mngt_require_safe("route/link");
	if (link_cache)
		nl_dump_line(p, "%s_IFNAME=%s\n", pfx,
			     rtnl_link_i2name(link_cache,
			     		      rtnl_addr_get_ifindex(addr),
			     		      buf, sizeof(buf)));

	if ((a = rtnl_addr_get_peer(addr)))
		nl_dump_line(p, "%s_PEER=%s\n", pfx,
			     nl_addr2str(a, buf, sizeof(buf)));

	if ((a = rtnl_addr_get_broadcast(addr)))
		nl_dump_line(p, "%s_BROADCAST=%s\n", pfx,
			     nl_addr2str(a, buf, sizeof(buf)));

	nl_dump_line(p, "%s_SCOPE=%s\n", pfx,
		     rtnl_scope2str(rtnl_addr_get_scope(addr),
				    buf, sizeof(buf)));

	if ((s = rtnl_addr_get_label(addr)))
		nl_dump_line(p, "%s_LABEL=%s\n", pfx, s);

	rtnl_addr_flags2str(rtnl_addr_get_flags(addr), buf, sizeof(buf));
	if (buf[0])
		nl_dump_line(p, "%s_FLAGS=%s\n", pfx, buf);

	nl_dump_line(p, "%s_CACHEINFO_VALID=%u\n", pfx,
		     rtnl_addr_get_valid_lifetime(addr));

	if (link_cache)
		nl_cache_put(link_cache);

#if 0
	if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
		struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;

		nl_dump_line(p, "ADDR_CACHEINFO_PREFERRED=%u\n",
			     ci->aci_prefered);

		nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%u\n", ci->aci_cstamp);
		nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%u\n",
			     ci->aci_tstamp);
	}
#endif
}