dgram.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. /*
  2. * IEEE 802.15.4 dgram socket interface
  3. *
  4. * Copyright 2007, 2008 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. *
  15. * Written by:
  16. * Sergey Lapin <slapin@ossfans.org>
  17. * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
  18. */
  19. #include <linux/capability.h>
  20. #include <linux/net.h>
  21. #include <linux/module.h>
  22. #include <linux/if_arp.h>
  23. #include <linux/list.h>
  24. #include <linux/slab.h>
  25. #include <linux/ieee802154.h>
  26. #include <net/sock.h>
  27. #include <net/af_ieee802154.h>
  28. #include <net/ieee802154_netdev.h>
  29. #include <asm/ioctls.h>
  30. #include "af802154.h"
  31. static HLIST_HEAD(dgram_head);
  32. static DEFINE_RWLOCK(dgram_lock);
  33. struct dgram_sock {
  34. struct sock sk;
  35. struct ieee802154_addr src_addr;
  36. struct ieee802154_addr dst_addr;
  37. unsigned int bound:1;
  38. unsigned int connected:1;
  39. unsigned int want_ack:1;
  40. unsigned int secen:1;
  41. unsigned int secen_override:1;
  42. unsigned int seclevel:3;
  43. unsigned int seclevel_override:1;
  44. };
  45. static inline struct dgram_sock *dgram_sk(const struct sock *sk)
  46. {
  47. return container_of(sk, struct dgram_sock, sk);
  48. }
  49. static void dgram_hash(struct sock *sk)
  50. {
  51. write_lock_bh(&dgram_lock);
  52. sk_add_node(sk, &dgram_head);
  53. sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
  54. write_unlock_bh(&dgram_lock);
  55. }
  56. static void dgram_unhash(struct sock *sk)
  57. {
  58. write_lock_bh(&dgram_lock);
  59. if (sk_del_node_init(sk))
  60. sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
  61. write_unlock_bh(&dgram_lock);
  62. }
  63. static int dgram_init(struct sock *sk)
  64. {
  65. struct dgram_sock *ro = dgram_sk(sk);
  66. ro->want_ack = 1;
  67. return 0;
  68. }
  69. static void dgram_close(struct sock *sk, long timeout)
  70. {
  71. sk_common_release(sk);
  72. }
  73. static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
  74. {
  75. struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
  76. struct ieee802154_addr haddr;
  77. struct dgram_sock *ro = dgram_sk(sk);
  78. int err = -EINVAL;
  79. struct net_device *dev;
  80. lock_sock(sk);
  81. ro->bound = 0;
  82. if (len < sizeof(*addr))
  83. goto out;
  84. if (addr->family != AF_IEEE802154)
  85. goto out;
  86. ieee802154_addr_from_sa(&haddr, &addr->addr);
  87. dev = ieee802154_get_dev(sock_net(sk), &haddr);
  88. if (!dev) {
  89. err = -ENODEV;
  90. goto out;
  91. }
  92. if (dev->type != ARPHRD_IEEE802154) {
  93. err = -ENODEV;
  94. goto out_put;
  95. }
  96. ro->src_addr = haddr;
  97. ro->bound = 1;
  98. err = 0;
  99. out_put:
  100. dev_put(dev);
  101. out:
  102. release_sock(sk);
  103. return err;
  104. }
  105. static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
  106. {
  107. switch (cmd) {
  108. case SIOCOUTQ:
  109. {
  110. int amount = sk_wmem_alloc_get(sk);
  111. return put_user(amount, (int __user *)arg);
  112. }
  113. case SIOCINQ:
  114. {
  115. struct sk_buff *skb;
  116. unsigned long amount;
  117. amount = 0;
  118. spin_lock_bh(&sk->sk_receive_queue.lock);
  119. skb = skb_peek(&sk->sk_receive_queue);
  120. if (skb != NULL) {
  121. /* We will only return the amount
  122. * of this packet since that is all
  123. * that will be read.
  124. */
  125. amount = skb->len - ieee802154_hdr_length(skb);
  126. }
  127. spin_unlock_bh(&sk->sk_receive_queue.lock);
  128. return put_user(amount, (int __user *)arg);
  129. }
  130. }
  131. return -ENOIOCTLCMD;
  132. }
  133. /* FIXME: autobind */
  134. static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
  135. int len)
  136. {
  137. struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
  138. struct dgram_sock *ro = dgram_sk(sk);
  139. int err = 0;
  140. if (len < sizeof(*addr))
  141. return -EINVAL;
  142. if (addr->family != AF_IEEE802154)
  143. return -EINVAL;
  144. lock_sock(sk);
  145. if (!ro->bound) {
  146. err = -ENETUNREACH;
  147. goto out;
  148. }
  149. ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr);
  150. ro->connected = 1;
  151. out:
  152. release_sock(sk);
  153. return err;
  154. }
  155. static int dgram_disconnect(struct sock *sk, int flags)
  156. {
  157. struct dgram_sock *ro = dgram_sk(sk);
  158. lock_sock(sk);
  159. ro->connected = 0;
  160. release_sock(sk);
  161. return 0;
  162. }
  163. static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
  164. struct msghdr *msg, size_t size)
  165. {
  166. struct net_device *dev;
  167. unsigned int mtu;
  168. struct sk_buff *skb;
  169. struct ieee802154_mac_cb *cb;
  170. struct dgram_sock *ro = dgram_sk(sk);
  171. struct ieee802154_addr dst_addr;
  172. int hlen, tlen;
  173. int err;
  174. if (msg->msg_flags & MSG_OOB) {
  175. pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags);
  176. return -EOPNOTSUPP;
  177. }
  178. if (!ro->connected && !msg->msg_name)
  179. return -EDESTADDRREQ;
  180. else if (ro->connected && msg->msg_name)
  181. return -EISCONN;
  182. if (!ro->bound)
  183. dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
  184. else
  185. dev = ieee802154_get_dev(sock_net(sk), &ro->src_addr);
  186. if (!dev) {
  187. pr_debug("no dev\n");
  188. err = -ENXIO;
  189. goto out;
  190. }
  191. mtu = dev->mtu;
  192. pr_debug("name = %s, mtu = %u\n", dev->name, mtu);
  193. if (size > mtu) {
  194. pr_debug("size = %Zu, mtu = %u\n", size, mtu);
  195. err = -EMSGSIZE;
  196. goto out_dev;
  197. }
  198. hlen = LL_RESERVED_SPACE(dev);
  199. tlen = dev->needed_tailroom;
  200. skb = sock_alloc_send_skb(sk, hlen + tlen + size,
  201. msg->msg_flags & MSG_DONTWAIT,
  202. &err);
  203. if (!skb)
  204. goto out_dev;
  205. skb_reserve(skb, hlen);
  206. skb_reset_network_header(skb);
  207. cb = mac_cb_init(skb);
  208. cb->type = IEEE802154_FC_TYPE_DATA;
  209. cb->ackreq = ro->want_ack;
  210. if (msg->msg_name) {
  211. DECLARE_SOCKADDR(struct sockaddr_ieee802154*,
  212. daddr, msg->msg_name);
  213. ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
  214. } else {
  215. dst_addr = ro->dst_addr;
  216. }
  217. cb->secen = ro->secen;
  218. cb->secen_override = ro->secen_override;
  219. cb->seclevel = ro->seclevel;
  220. cb->seclevel_override = ro->seclevel_override;
  221. err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &dst_addr,
  222. ro->bound ? &ro->src_addr : NULL, size);
  223. if (err < 0)
  224. goto out_skb;
  225. err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
  226. if (err < 0)
  227. goto out_skb;
  228. skb->dev = dev;
  229. skb->sk = sk;
  230. skb->protocol = htons(ETH_P_IEEE802154);
  231. dev_put(dev);
  232. err = dev_queue_xmit(skb);
  233. if (err > 0)
  234. err = net_xmit_errno(err);
  235. return err ?: size;
  236. out_skb:
  237. kfree_skb(skb);
  238. out_dev:
  239. dev_put(dev);
  240. out:
  241. return err;
  242. }
  243. static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk,
  244. struct msghdr *msg, size_t len, int noblock,
  245. int flags, int *addr_len)
  246. {
  247. size_t copied = 0;
  248. int err = -EOPNOTSUPP;
  249. struct sk_buff *skb;
  250. DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
  251. skb = skb_recv_datagram(sk, flags, noblock, &err);
  252. if (!skb)
  253. goto out;
  254. copied = skb->len;
  255. if (len < copied) {
  256. msg->msg_flags |= MSG_TRUNC;
  257. copied = len;
  258. }
  259. /* FIXME: skip headers if necessary ?! */
  260. err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
  261. if (err)
  262. goto done;
  263. sock_recv_ts_and_drops(msg, sk, skb);
  264. if (saddr) {
  265. saddr->family = AF_IEEE802154;
  266. ieee802154_addr_to_sa(&saddr->addr, &mac_cb(skb)->source);
  267. *addr_len = sizeof(*saddr);
  268. }
  269. if (flags & MSG_TRUNC)
  270. copied = skb->len;
  271. done:
  272. skb_free_datagram(sk, skb);
  273. out:
  274. if (err)
  275. return err;
  276. return copied;
  277. }
  278. static int dgram_rcv_skb(struct sock *sk, struct sk_buff *skb)
  279. {
  280. skb = skb_share_check(skb, GFP_ATOMIC);
  281. if (!skb)
  282. return NET_RX_DROP;
  283. if (sock_queue_rcv_skb(sk, skb) < 0) {
  284. kfree_skb(skb);
  285. return NET_RX_DROP;
  286. }
  287. return NET_RX_SUCCESS;
  288. }
  289. static inline bool
  290. ieee802154_match_sock(__le64 hw_addr, __le16 pan_id, __le16 short_addr,
  291. struct dgram_sock *ro)
  292. {
  293. if (!ro->bound)
  294. return true;
  295. if (ro->src_addr.mode == IEEE802154_ADDR_LONG &&
  296. hw_addr == ro->src_addr.extended_addr)
  297. return true;
  298. if (ro->src_addr.mode == IEEE802154_ADDR_SHORT &&
  299. pan_id == ro->src_addr.pan_id &&
  300. short_addr == ro->src_addr.short_addr)
  301. return true;
  302. return false;
  303. }
  304. int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
  305. {
  306. struct sock *sk, *prev = NULL;
  307. int ret = NET_RX_SUCCESS;
  308. __le16 pan_id, short_addr;
  309. __le64 hw_addr;
  310. /* Data frame processing */
  311. BUG_ON(dev->type != ARPHRD_IEEE802154);
  312. pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
  313. short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev);
  314. hw_addr = ieee802154_devaddr_from_raw(dev->dev_addr);
  315. read_lock(&dgram_lock);
  316. sk_for_each(sk, &dgram_head) {
  317. if (ieee802154_match_sock(hw_addr, pan_id, short_addr,
  318. dgram_sk(sk))) {
  319. if (prev) {
  320. struct sk_buff *clone;
  321. clone = skb_clone(skb, GFP_ATOMIC);
  322. if (clone)
  323. dgram_rcv_skb(prev, clone);
  324. }
  325. prev = sk;
  326. }
  327. }
  328. if (prev) {
  329. dgram_rcv_skb(prev, skb);
  330. } else {
  331. kfree_skb(skb);
  332. ret = NET_RX_DROP;
  333. }
  334. read_unlock(&dgram_lock);
  335. return ret;
  336. }
  337. static int dgram_getsockopt(struct sock *sk, int level, int optname,
  338. char __user *optval, int __user *optlen)
  339. {
  340. struct dgram_sock *ro = dgram_sk(sk);
  341. int val, len;
  342. if (level != SOL_IEEE802154)
  343. return -EOPNOTSUPP;
  344. if (get_user(len, optlen))
  345. return -EFAULT;
  346. len = min_t(unsigned int, len, sizeof(int));
  347. switch (optname) {
  348. case WPAN_WANTACK:
  349. val = ro->want_ack;
  350. break;
  351. case WPAN_SECURITY:
  352. if (!ro->secen_override)
  353. val = WPAN_SECURITY_DEFAULT;
  354. else if (ro->secen)
  355. val = WPAN_SECURITY_ON;
  356. else
  357. val = WPAN_SECURITY_OFF;
  358. break;
  359. case WPAN_SECURITY_LEVEL:
  360. if (!ro->seclevel_override)
  361. val = WPAN_SECURITY_LEVEL_DEFAULT;
  362. else
  363. val = ro->seclevel;
  364. break;
  365. default:
  366. return -ENOPROTOOPT;
  367. }
  368. if (put_user(len, optlen))
  369. return -EFAULT;
  370. if (copy_to_user(optval, &val, len))
  371. return -EFAULT;
  372. return 0;
  373. }
  374. static int dgram_setsockopt(struct sock *sk, int level, int optname,
  375. char __user *optval, unsigned int optlen)
  376. {
  377. struct dgram_sock *ro = dgram_sk(sk);
  378. struct net *net = sock_net(sk);
  379. int val;
  380. int err = 0;
  381. if (optlen < sizeof(int))
  382. return -EINVAL;
  383. if (get_user(val, (int __user *)optval))
  384. return -EFAULT;
  385. lock_sock(sk);
  386. switch (optname) {
  387. case WPAN_WANTACK:
  388. ro->want_ack = !!val;
  389. break;
  390. case WPAN_SECURITY:
  391. if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
  392. !ns_capable(net->user_ns, CAP_NET_RAW)) {
  393. err = -EPERM;
  394. break;
  395. }
  396. switch (val) {
  397. case WPAN_SECURITY_DEFAULT:
  398. ro->secen_override = 0;
  399. break;
  400. case WPAN_SECURITY_ON:
  401. ro->secen_override = 1;
  402. ro->secen = 1;
  403. break;
  404. case WPAN_SECURITY_OFF:
  405. ro->secen_override = 1;
  406. ro->secen = 0;
  407. break;
  408. default:
  409. err = -EINVAL;
  410. break;
  411. }
  412. break;
  413. case WPAN_SECURITY_LEVEL:
  414. if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
  415. !ns_capable(net->user_ns, CAP_NET_RAW)) {
  416. err = -EPERM;
  417. break;
  418. }
  419. if (val < WPAN_SECURITY_LEVEL_DEFAULT ||
  420. val > IEEE802154_SCF_SECLEVEL_ENC_MIC128) {
  421. err = -EINVAL;
  422. } else if (val == WPAN_SECURITY_LEVEL_DEFAULT) {
  423. ro->seclevel_override = 0;
  424. } else {
  425. ro->seclevel_override = 1;
  426. ro->seclevel = val;
  427. }
  428. break;
  429. default:
  430. err = -ENOPROTOOPT;
  431. break;
  432. }
  433. release_sock(sk);
  434. return err;
  435. }
  436. struct proto ieee802154_dgram_prot = {
  437. .name = "IEEE-802.15.4-MAC",
  438. .owner = THIS_MODULE,
  439. .obj_size = sizeof(struct dgram_sock),
  440. .init = dgram_init,
  441. .close = dgram_close,
  442. .bind = dgram_bind,
  443. .sendmsg = dgram_sendmsg,
  444. .recvmsg = dgram_recvmsg,
  445. .hash = dgram_hash,
  446. .unhash = dgram_unhash,
  447. .connect = dgram_connect,
  448. .disconnect = dgram_disconnect,
  449. .ioctl = dgram_ioctl,
  450. .getsockopt = dgram_getsockopt,
  451. .setsockopt = dgram_setsockopt,
  452. };