Ejemplo n.º 1
0
/*
 * Utility function for families
 */
struct net_device *ieee802154_get_dev(struct net *net,
		struct ieee802154_addr *addr)
{
	struct net_device *dev = NULL;
	struct net_device *tmp;
	u16 pan_id, short_addr;

	switch (addr->addr_type) {
	case IEEE802154_ADDR_LONG:
		rcu_read_lock();
		dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, addr->hwaddr);
		if (dev)
			dev_hold(dev);
		rcu_read_unlock();
		break;
	case IEEE802154_ADDR_SHORT:
		if (addr->pan_id == 0xffff ||
		    addr->short_addr == IEEE802154_ADDR_UNDEF ||
		    addr->short_addr == 0xffff)
			break;

		rtnl_lock();

		for_each_netdev(net, tmp) {
			if (tmp->type != ARPHRD_IEEE802154)
				continue;

			pan_id = ieee802154_mlme_ops(tmp)->get_pan_id(tmp);
			short_addr =
				ieee802154_mlme_ops(tmp)->get_short_addr(tmp);

			if (pan_id == addr->pan_id &&
			    short_addr == addr->short_addr) {
				dev = tmp;
				dev_hold(dev);
				break;
			}
		}

		rtnl_unlock();
		break;
	default:
		pr_warning("Unsupported ieee802154 address type: %d\n",
				addr->addr_type);
		break;
	}

	return dev;
}
Ejemplo n.º 2
0
static int arp_req_set_public(struct net *net, struct arpreq *r,
		struct net_device *dev)
{
	__be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
	__be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;

	if (mask && mask != htonl(0xFFFFFFFF))
		return -EINVAL;
	if (!dev && (r->arp_flags & ATF_COM)) {
		dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family,
				      r->arp_ha.sa_data);
		if (!dev)
			return -ENODEV;
	}
	if (mask) {
		if (pneigh_lookup(&arp_tbl, net, &ip, dev, 1) == NULL)
			return -ENOBUFS;
		return 0;
	}

	return arp_req_set_proxy(net, dev, 1);
}