aboutsummaryrefslogtreecommitdiff
path: root/net/sctp
diff options
context:
space:
mode:
authorDiego Elio 'Flameeyes' Pettenò <flameeyes@gmail.com>2010-09-03 03:47:03 +0000
committerDavid S. Miller <davem@davemloft.net>2010-09-08 13:08:05 -0700
commit65040c33ee8d0199ab7686402bffdbf9e1e26cbe (patch)
tree4c8a35d0b6da2964a0de8f6668c0f5f47efe2825 /net/sctp
parent2edae08e5b75269855fef3c74fe4292c066e7c33 (diff)
sctp: implement SIOCINQ ioctl() (take 3)
This simple patch copies the current approach for SIOCINQ ioctl() from DCCP into SCTP so that the userland code working with SCTP can use a similar interface across different protocols to know how much space to allocate for a buffer. Signed-off-by: Diego Elio Pettenò <flameeyes@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/socket.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index cf6dcc908b8..6a691d84aef 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3592,7 +3592,40 @@ out:
/* The SCTP ioctl handler. */
SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
- return -ENOIOCTLCMD;
+ int rc = -ENOTCONN;
+
+ sctp_lock_sock(sk);
+
+ /*
+ * SEQPACKET-style sockets in LISTENING state are valid, for
+ * SCTP, so only discard TCP-style sockets in LISTENING state.
+ */
+ if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
+ goto out;
+
+ switch (cmd) {
+ case SIOCINQ: {
+ struct sk_buff *skb;
+ unsigned int amount = 0;
+
+ skb = skb_peek(&sk->sk_receive_queue);
+ if (skb != NULL) {
+ /*
+ * We will only return the amount of this packet since
+ * that is all that will be read.
+ */
+ amount = skb->len;
+ }
+ rc = put_user(amount, (int __user *)arg);
+ }
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+out:
+ sctp_release_sock(sk);
+ return rc;
}
/* This is the function which gets called during socket creation to