| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * An interface between IEEE802.15.4 device and rest of the kernel. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007-2012 Siemens AG |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License version 2 |
|---|
| 8 | | - * as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - * GNU General Public License for more details. |
|---|
| 14 | 6 | * |
|---|
| 15 | 7 | * Written by: |
|---|
| 16 | 8 | * Pavel Smolenskiy <pavel.smolenskiy@gmail.com> |
|---|
| .. | .. |
|---|
| 22 | 14 | |
|---|
| 23 | 15 | #ifndef IEEE802154_NETDEVICE_H |
|---|
| 24 | 16 | #define IEEE802154_NETDEVICE_H |
|---|
| 17 | + |
|---|
| 18 | +#define IEEE802154_REQUIRED_SIZE(struct_type, member) \ |
|---|
| 19 | + (offsetof(typeof(struct_type), member) + \ |
|---|
| 20 | + sizeof(((typeof(struct_type) *)(NULL))->member)) |
|---|
| 21 | + |
|---|
| 22 | +#define IEEE802154_ADDR_OFFSET \ |
|---|
| 23 | + offsetof(typeof(struct sockaddr_ieee802154), addr) |
|---|
| 24 | + |
|---|
| 25 | +#define IEEE802154_MIN_NAMELEN (IEEE802154_ADDR_OFFSET + \ |
|---|
| 26 | + IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, addr_type)) |
|---|
| 27 | + |
|---|
| 28 | +#define IEEE802154_NAMELEN_SHORT (IEEE802154_ADDR_OFFSET + \ |
|---|
| 29 | + IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, short_addr)) |
|---|
| 30 | + |
|---|
| 31 | +#define IEEE802154_NAMELEN_LONG (IEEE802154_ADDR_OFFSET + \ |
|---|
| 32 | + IEEE802154_REQUIRED_SIZE(struct ieee802154_addr_sa, hwaddr)) |
|---|
| 25 | 33 | |
|---|
| 26 | 34 | #include <net/af_ieee802154.h> |
|---|
| 27 | 35 | #include <linux/netdevice.h> |
|---|
| .. | .. |
|---|
| 173 | 181 | memcpy(raw, &temp, IEEE802154_ADDR_LEN); |
|---|
| 174 | 182 | } |
|---|
| 175 | 183 | |
|---|
| 184 | +static inline int |
|---|
| 185 | +ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len) |
|---|
| 186 | +{ |
|---|
| 187 | + struct ieee802154_addr_sa *sa; |
|---|
| 188 | + int ret = 0; |
|---|
| 189 | + |
|---|
| 190 | + sa = &daddr->addr; |
|---|
| 191 | + if (len < IEEE802154_MIN_NAMELEN) |
|---|
| 192 | + return -EINVAL; |
|---|
| 193 | + switch (sa->addr_type) { |
|---|
| 194 | + case IEEE802154_ADDR_NONE: |
|---|
| 195 | + break; |
|---|
| 196 | + case IEEE802154_ADDR_SHORT: |
|---|
| 197 | + if (len < IEEE802154_NAMELEN_SHORT) |
|---|
| 198 | + ret = -EINVAL; |
|---|
| 199 | + break; |
|---|
| 200 | + case IEEE802154_ADDR_LONG: |
|---|
| 201 | + if (len < IEEE802154_NAMELEN_LONG) |
|---|
| 202 | + ret = -EINVAL; |
|---|
| 203 | + break; |
|---|
| 204 | + default: |
|---|
| 205 | + ret = -EINVAL; |
|---|
| 206 | + break; |
|---|
| 207 | + } |
|---|
| 208 | + return ret; |
|---|
| 209 | +} |
|---|
| 210 | + |
|---|
| 176 | 211 | static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a, |
|---|
| 177 | 212 | const struct ieee802154_addr_sa *sa) |
|---|
| 178 | 213 | { |
|---|