Commit 1cc76e36 authored by Phoebe Buckheister's avatar Phoebe Buckheister Committed by David S. Miller

ieee802154: fix dgram socket sendmsg()

802.15.4 datagram sockets do not currently have a compliant sendmsg().
The destination address supplied is always ignored, and in unconnected
mode, packets are broadcast instead of dropped with -EDESTADDRREQ. This
patch fixes 802.15.4 dgram sockets to be compliant, i.e.

 !conn && !msg_name => -EDESTADDRREQ
 !conn &&  msg_name => send to msg_name
  conn && !msg_name => send to connected
  conn &&  msg_name => -EISCONN
Signed-off-by: default avatarPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4b2816d
...@@ -45,6 +45,7 @@ struct dgram_sock { ...@@ -45,6 +45,7 @@ struct dgram_sock {
struct ieee802154_addr dst_addr; struct ieee802154_addr dst_addr;
unsigned int bound:1; unsigned int bound:1;
unsigned int connected:1;
unsigned int want_ack:1; unsigned int want_ack:1;
}; };
...@@ -73,10 +74,7 @@ static int dgram_init(struct sock *sk) ...@@ -73,10 +74,7 @@ static int dgram_init(struct sock *sk)
{ {
struct dgram_sock *ro = dgram_sk(sk); struct dgram_sock *ro = dgram_sk(sk);
ro->dst_addr.mode = IEEE802154_ADDR_LONG;
ro->dst_addr.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
ro->want_ack = 1; ro->want_ack = 1;
memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN);
return 0; return 0;
} }
...@@ -183,6 +181,7 @@ static int dgram_connect(struct sock *sk, struct sockaddr *uaddr, ...@@ -183,6 +181,7 @@ static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
} }
ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr); ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr);
ro->connected = 1;
out: out:
release_sock(sk); release_sock(sk);
...@@ -194,10 +193,7 @@ static int dgram_disconnect(struct sock *sk, int flags) ...@@ -194,10 +193,7 @@ static int dgram_disconnect(struct sock *sk, int flags)
struct dgram_sock *ro = dgram_sk(sk); struct dgram_sock *ro = dgram_sk(sk);
lock_sock(sk); lock_sock(sk);
ro->connected = 0;
ro->dst_addr.mode = IEEE802154_ADDR_LONG;
memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN);
release_sock(sk); release_sock(sk);
return 0; return 0;
...@@ -211,6 +207,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -211,6 +207,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
struct sk_buff *skb; struct sk_buff *skb;
struct ieee802154_mac_cb *cb; struct ieee802154_mac_cb *cb;
struct dgram_sock *ro = dgram_sk(sk); struct dgram_sock *ro = dgram_sk(sk);
struct ieee802154_addr dst_addr;
int hlen, tlen; int hlen, tlen;
int err; int err;
...@@ -219,6 +216,11 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -219,6 +216,11 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (!ro->connected && !msg->msg_name)
return -EDESTADDRREQ;
else if (ro->connected && msg->msg_name)
return -EISCONN;
if (!ro->bound) if (!ro->bound)
dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
else else
...@@ -254,8 +256,16 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -254,8 +256,16 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
cb->type = IEEE802154_FC_TYPE_DATA; cb->type = IEEE802154_FC_TYPE_DATA;
cb->ackreq = ro->want_ack; cb->ackreq = ro->want_ack;
err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr, if (msg->msg_name) {
ro->bound ? &ro->src_addr : NULL, size); DECLARE_SOCKADDR(struct sockaddr_ieee802154*, daddr, msg->msg_name);
ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
} else {
dst_addr = ro->dst_addr;
}
err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &dst_addr,
ro->bound ? &ro->src_addr : NULL, size);
if (err < 0) if (err < 0)
goto out_skb; goto out_skb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment