aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn/mISDN/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN/socket.c')
-rw-r--r--drivers/isdn/mISDN/socket.c111
1 files changed, 54 insertions, 57 deletions
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 7446d8b4282..1be82284cf9 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -17,6 +17,7 @@
#include <linux/mISDNif.h>
#include <linux/slab.h>
+#include <linux/export.h>
#include "core.h"
static u_int *debug;
@@ -112,18 +113,17 @@ mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
static int
mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t len, int flags)
+ struct msghdr *msg, size_t len, int flags)
{
struct sk_buff *skb;
struct sock *sk = sock->sk;
- struct sockaddr_mISDN *maddr;
int copied, err;
if (*debug & DEBUG_SOCKET)
printk(KERN_DEBUG "%s: len %d, flags %x ch.nr %d, proto %x\n",
- __func__, (int)len, flags, _pms(sk)->ch.nr,
- sk->sk_protocol);
+ __func__, (int)len, flags, _pms(sk)->ch.nr,
+ sk->sk_protocol);
if (flags & (MSG_OOB))
return -EOPNOTSUPP;
@@ -134,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
return err;
- if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
- msg->msg_namelen = sizeof(struct sockaddr_mISDN);
- maddr = (struct sockaddr_mISDN *)msg->msg_name;
+ if (msg->msg_name) {
+ DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
+
maddr->family = AF_ISDN;
maddr->dev = _pms(sk)->dev->id;
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
@@ -149,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
maddr->sapi = _pms(sk)->ch.addr & 0xFF;
maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
}
- } else {
- if (msg->msg_namelen)
- printk(KERN_WARNING "%s: too small namelen %d\n",
- __func__, msg->msg_namelen);
- msg->msg_namelen = 0;
+ msg->msg_namelen = sizeof(*maddr);
}
copied = skb->len + MISDN_HEADER_LEN;
@@ -165,7 +161,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return -ENOSPC;
}
memcpy(skb_push(skb, MISDN_HEADER_LEN), mISDN_HEAD_P(skb),
- MISDN_HEADER_LEN);
+ MISDN_HEADER_LEN);
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
@@ -178,22 +174,21 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
static int
mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t len)
+ struct msghdr *msg, size_t len)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
int err = -ENOMEM;
- struct sockaddr_mISDN *maddr;
if (*debug & DEBUG_SOCKET)
printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
- __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr,
- sk->sk_protocol);
+ __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr,
+ sk->sk_protocol);
if (msg->msg_flags & MSG_OOB)
return -EOPNOTSUPP;
- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
+ if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL | MSG_ERRQUEUE))
return -EINVAL;
if (len < MISDN_HEADER_LEN)
@@ -218,7 +213,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
/* if we have a address, we use it */
- maddr = (struct sockaddr_mISDN *)msg->msg_name;
+ DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
mISDN_HEAD_ID(skb) = maddr->channel;
} else { /* use default for L2 messages */
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
@@ -228,7 +223,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (*debug & DEBUG_SOCKET)
printk(KERN_DEBUG "%s: ID:%x\n",
- __func__, mISDN_HEAD_ID(skb));
+ __func__, mISDN_HEAD_ID(skb));
err = -ENODEV;
if (!_pms(sk)->ch.peer)
@@ -311,16 +306,16 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
}
if ((sk->sk_protocol & ~ISDN_P_B_MASK) == ISDN_P_B_START) {
list_for_each_entry_safe(bchan, next,
- &_pms(sk)->dev->bchannels, list) {
+ &_pms(sk)->dev->bchannels, list) {
if (bchan->nr == cq.channel) {
err = bchan->ctrl(bchan,
- CONTROL_CHANNEL, &cq);
+ CONTROL_CHANNEL, &cq);
break;
}
}
} else
err = _pms(sk)->dev->D.ctrl(&_pms(sk)->dev->D,
- CONTROL_CHANNEL, &cq);
+ CONTROL_CHANNEL, &cq);
if (err)
break;
if (copy_to_user(p, &cq, sizeof(cq)))
@@ -337,11 +332,11 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
break;
}
err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
- CONTROL_CHANNEL, val);
+ CONTROL_CHANNEL, val);
break;
case IMHOLD_L1:
if (sk->sk_protocol != ISDN_P_LAPD_NT
- && sk->sk_protocol != ISDN_P_LAPD_TE) {
+ && sk->sk_protocol != ISDN_P_LAPD_TE) {
err = -EINVAL;
break;
}
@@ -351,7 +346,7 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
break;
}
err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
- CONTROL_CHANNEL, val);
+ CONTROL_CHANNEL, val);
break;
default:
err = -EINVAL;
@@ -365,7 +360,7 @@ done:
static int
data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
- int err = 0, id;
+ int err = 0, id;
struct sock *sk = sock->sk;
struct mISDNdevice *dev;
struct mISDNversion ver;
@@ -398,7 +393,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
di.protocol = dev->D.protocol;
memcpy(di.channelmap, dev->channelmap,
- sizeof(di.channelmap));
+ sizeof(di.channelmap));
di.nrbchan = dev->nrbchan;
strcpy(di.name, dev_name(&dev->dev));
if (copy_to_user((void __user *)arg, &di, sizeof(di)))
@@ -409,7 +404,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
default:
if (sk->sk_state == MISDN_BOUND)
err = data_sock_ioctl_bound(sk, cmd,
- (void __user *)arg);
+ (void __user *)arg);
else
err = -ENOTCONN;
}
@@ -417,14 +412,14 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
static int data_sock_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int len)
+ char __user *optval, unsigned int len)
{
struct sock *sk = sock->sk;
int err = 0, opt = 0;
if (*debug & DEBUG_SOCKET)
printk(KERN_DEBUG "%s(%p, %d, %x, %p, %d)\n", __func__, sock,
- level, optname, optval, len);
+ level, optname, optval, len);
lock_sock(sk);
@@ -449,7 +444,7 @@ static int data_sock_setsockopt(struct socket *sock, int level, int optname,
}
static int data_sock_getsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int __user *optlen)
+ char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
int len, opt;
@@ -457,6 +452,9 @@ static int data_sock_getsockopt(struct socket *sock, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
+ if (len != sizeof(char))
+ return -EINVAL;
+
switch (optname) {
case MISDN_TIME_STAMP:
if (_pms(sk)->cmask & MISDN_TIME_STAMP)
@@ -479,7 +477,6 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
struct sock *sk = sock->sk;
- struct hlist_node *node;
struct sock *csk;
int err = 0;
@@ -504,7 +501,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
if (sk->sk_protocol < ISDN_P_B_START) {
read_lock_bh(&data_sockets.lock);
- sk_for_each(csk, node, &data_sockets.head) {
+ sk_for_each(csk, &data_sockets.head) {
if (sk == csk)
continue;
if (_pms(csk)->dev != _pms(sk)->dev)
@@ -512,7 +509,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
if (csk->sk_protocol >= ISDN_P_B_START)
continue;
if (IS_ISDN_P_TE(csk->sk_protocol)
- == IS_ISDN_P_TE(sk->sk_protocol))
+ == IS_ISDN_P_TE(sk->sk_protocol))
continue;
read_unlock_bh(&data_sockets.lock);
err = -EBUSY;
@@ -531,14 +528,14 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
case ISDN_P_NT_E1:
mISDN_sock_unlink(&data_sockets, sk);
err = connect_layer1(_pms(sk)->dev, &_pms(sk)->ch,
- sk->sk_protocol, maddr);
+ sk->sk_protocol, maddr);
if (err)
mISDN_sock_link(&data_sockets, sk);
break;
case ISDN_P_LAPD_TE:
case ISDN_P_LAPD_NT:
err = create_l2entity(_pms(sk)->dev, &_pms(sk)->ch,
- sk->sk_protocol, maddr);
+ sk->sk_protocol, maddr);
break;
case ISDN_P_B_RAW:
case ISDN_P_B_HDLC:
@@ -547,7 +544,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
case ISDN_P_B_L2DSP:
case ISDN_P_B_L2DSPHDLC:
err = connect_Bstack(_pms(sk)->dev, &_pms(sk)->ch,
- sk->sk_protocol, maddr);
+ sk->sk_protocol, maddr);
break;
default:
err = -EPROTONOSUPPORT;
@@ -564,9 +561,9 @@ done:
static int
data_sock_getname(struct socket *sock, struct sockaddr *addr,
- int *addr_len, int peer)
+ int *addr_len, int peer)
{
- struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
+ struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
struct sock *sk = sock->sk;
if (!_pms(sk)->dev)
@@ -575,6 +572,7 @@ data_sock_getname(struct socket *sock, struct sockaddr *addr,
lock_sock(sk);
*addr_len = sizeof(*maddr);
+ maddr->family = AF_ISDN;
maddr->dev = _pms(sk)->dev->id;
maddr->channel = _pms(sk)->ch.nr;
maddr->sapi = _pms(sk)->ch.addr & 0xff;
@@ -647,7 +645,7 @@ base_sock_release(struct socket *sock)
static int
base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
- int err = 0, id;
+ int err = 0, id;
struct mISDNdevice *dev;
struct mISDNversion ver;
@@ -679,7 +677,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
di.protocol = dev->D.protocol;
memcpy(di.channelmap, dev->channelmap,
- sizeof(di.channelmap));
+ sizeof(di.channelmap));
di.nrbchan = dev->nrbchan;
strcpy(di.name, dev_name(&dev->dev));
if (copy_to_user((void __user *)arg, &di, sizeof(di)))
@@ -688,20 +686,20 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
err = -ENODEV;
break;
case IMSETDEVNAME:
- {
- struct mISDN_devrename dn;
- if (copy_from_user(&dn, (void __user *)arg,
- sizeof(dn))) {
- err = -EFAULT;
- break;
- }
- dev = get_mdevice(dn.id);
- if (dev)
- err = device_rename(&dev->dev, dn.name);
- else
- err = -ENODEV;
+ {
+ struct mISDN_devrename dn;
+ if (copy_from_user(&dn, (void __user *)arg,
+ sizeof(dn))) {
+ err = -EFAULT;
+ break;
}
- break;
+ dev = get_mdevice(dn.id);
+ if (dev)
+ err = device_rename(&dev->dev, dn.name);
+ else
+ err = -ENODEV;
+ }
+ break;
default:
err = -EINVAL;
}
@@ -786,7 +784,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
{
int err = -EPROTONOSUPPORT;
- switch (proto) {
+ switch (proto) {
case ISDN_P_BASE:
err = base_sock_create(net, sock, proto);
break;
@@ -834,4 +832,3 @@ misdn_sock_cleanup(void)
{
sock_unregister(PF_ISDN);
}
-