aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee802154
diff options
context:
space:
mode:
authorPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>2014-05-14 11:43:10 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-15 15:51:43 -0400
commit1cc76e365405eae54a15e86b5d75ee885cd7d891 (patch)
tree0870bee3e462afd904eceb63e832aae521978931 /net/ieee802154
parentd4b2816d67d6e07b2f27037f282d8db03a5829d7 (diff)
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: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee802154')
-rw-r--r--net/ieee802154/dgram.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index d95e2e1bdf54..76c77256a56e 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -45,6 +45,7 @@ struct dgram_sock {
45 struct ieee802154_addr dst_addr; 45 struct ieee802154_addr dst_addr;
46 46
47 unsigned int bound:1; 47 unsigned int bound:1;
48 unsigned int connected:1;
48 unsigned int want_ack:1; 49 unsigned int want_ack:1;
49}; 50};
50 51
@@ -73,10 +74,7 @@ static int dgram_init(struct sock *sk)
73{ 74{
74 struct dgram_sock *ro = dgram_sk(sk); 75 struct dgram_sock *ro = dgram_sk(sk);
75 76
76 ro->dst_addr.mode = IEEE802154_ADDR_LONG;
77 ro->dst_addr.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
78 ro->want_ack = 1; 77 ro->want_ack = 1;
79 memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN);
80 return 0; 78 return 0;
81} 79}
82 80
@@ -183,6 +181,7 @@ static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
183 } 181 }
184 182
185 ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr); 183 ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr);
184 ro->connected = 1;
186 185
187out: 186out:
188 release_sock(sk); 187 release_sock(sk);
@@ -194,10 +193,7 @@ static int dgram_disconnect(struct sock *sk, int flags)
194 struct dgram_sock *ro = dgram_sk(sk); 193 struct dgram_sock *ro = dgram_sk(sk);
195 194
196 lock_sock(sk); 195 lock_sock(sk);
197 196 ro->connected = 0;
198 ro->dst_addr.mode = IEEE802154_ADDR_LONG;
199 memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN);
200
201 release_sock(sk); 197 release_sock(sk);
202 198
203 return 0; 199 return 0;
@@ -211,6 +207,7 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
211 struct sk_buff *skb; 207 struct sk_buff *skb;
212 struct ieee802154_mac_cb *cb; 208 struct ieee802154_mac_cb *cb;
213 struct dgram_sock *ro = dgram_sk(sk); 209 struct dgram_sock *ro = dgram_sk(sk);
210 struct ieee802154_addr dst_addr;
214 int hlen, tlen; 211 int hlen, tlen;
215 int err; 212 int err;
216 213
@@ -219,6 +216,11 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
219 return -EOPNOTSUPP; 216 return -EOPNOTSUPP;
220 } 217 }
221 218
219 if (!ro->connected && !msg->msg_name)
220 return -EDESTADDRREQ;
221 else if (ro->connected && msg->msg_name)
222 return -EISCONN;
223
222 if (!ro->bound) 224 if (!ro->bound)
223 dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); 225 dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
224 else 226 else
@@ -254,8 +256,16 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
254 cb->type = IEEE802154_FC_TYPE_DATA; 256 cb->type = IEEE802154_FC_TYPE_DATA;
255 cb->ackreq = ro->want_ack; 257 cb->ackreq = ro->want_ack;
256 258
257 err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr, 259 if (msg->msg_name) {
258 ro->bound ? &ro->src_addr : NULL, size); 260 DECLARE_SOCKADDR(struct sockaddr_ieee802154*, daddr, msg->msg_name);
261
262 ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
263 } else {
264 dst_addr = ro->dst_addr;
265 }
266
267 err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &dst_addr,
268 ro->bound ? &ro->src_addr : NULL, size);
259 if (err < 0) 269 if (err < 0)
260 goto out_skb; 270 goto out_skb;
261 271