OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [socket.c] - Blame information for rev 1629

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 * NET          An implementation of the SOCKET network access protocol.
3
 *
4
 * Version:     @(#)socket.c    1.1.93  18/02/95
5
 *
6
 * Authors:     Orest Zborowski, <obz@Kodak.COM>
7
 *              Ross Biro, <bir7@leland.Stanford.Edu>
8
 *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
9
 *
10
 * Fixes:
11
 *              Anonymous       :       NOTSOCK/BADF cleanup. Error fix in
12
 *                                      shutdown()
13
 *              Alan Cox        :       verify_area() fixes
14
 *              Alan Cox        :       Removed DDI
15
 *              Jonathan Kamens :       SOCK_DGRAM reconnect bug
16
 *              Alan Cox        :       Moved a load of checks to the very
17
 *                                      top level.
18
 *              Alan Cox        :       Move address structures to/from user
19
 *                                      mode above the protocol layers.
20
 *              Rob Janssen     :       Allow 0 length sends.
21
 *              Alan Cox        :       Asynchronous I/O support (cribbed from the
22
 *                                      tty drivers).
23
 *              Niibe Yutaka    :       Asynchronous I/O for writes (4.4BSD style)
24
 *              Jeff Uphoff     :       Made max number of sockets command-line
25
 *                                      configurable.
26
 *              Matti Aarnio    :       Made the number of sockets dynamic,
27
 *                                      to be allocated when needed, and mr.
28
 *                                      Uphoff's max is used as max to be
29
 *                                      allowed to allocate.
30
 *              Linus           :       Argh. removed all the socket allocation
31
 *                                      altogether: it's in the inode now.
32
 *              Alan Cox        :       Made sock_alloc()/sock_release() public
33
 *                                      for NetROM and future kernel nfsd type
34
 *                                      stuff.
35
 *              Alan Cox        :       sendmsg/recvmsg basics.
36
 *              Tom Dyas        :       Export net symbols.
37
 *              Marcin Dalecki  :       Fixed problems with CONFIG_NET="n".
38
 *
39
 *
40
 *              This program is free software; you can redistribute it and/or
41
 *              modify it under the terms of the GNU General Public License
42
 *              as published by the Free Software Foundation; either version
43
 *              2 of the License, or (at your option) any later version.
44
 *
45
 *
46
 *      This module is effectively the top level interface to the BSD socket
47
 *      paradigm. Because it is very simple it works well for Unix domain sockets,
48
 *      but requires a whole layer of substructure for the other protocols.
49
 *
50
 *      In addition it lacks an effective kernel -> kernel interface to go with
51
 *      the user one.
52
 */
53
 
54
#include <linux/config.h>
55
#include <linux/signal.h>
56
#include <linux/errno.h>
57
#include <linux/sched.h>
58
#include <linux/mm.h>
59
#include <linux/kernel.h>
60
#include <linux/major.h>
61
#include <linux/stat.h>
62
#include <linux/socket.h>
63
#include <linux/fcntl.h>
64
#include <linux/file.h>
65
#include <linux/net.h>
66
#include <linux/interrupt.h>
67
#include <linux/netdevice.h>
68
#include <linux/proc_fs.h>
69
#include <linux/firewall.h>
70
 
71
#ifdef CONFIG_KERNELD
72
#include <linux/kerneld.h>
73
#endif
74
 
75
#include <net/netlink.h>
76
 
77
#include <asm/system.h>
78
#include <asm/segment.h>
79
 
80
#if defined(CONFIG_MODULES) && defined(CONFIG_NET)
81
extern void export_net_symbols(void);
82
#endif
83
 
84
static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
85
                      int whence);
86
static int sock_read(struct inode *inode, struct file *file, char *buf,
87
                     int size);
88
static int sock_write(struct inode *inode, struct file *file, const char *buf,
89
                      int size);
90
 
91
static void sock_close(struct inode *inode, struct file *file);
92
static int sock_no_open(struct inode *inode, struct file *file);
93
static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
94
static int sock_ioctl(struct inode *inode, struct file *file,
95
                      unsigned int cmd, unsigned long arg);
96
static int sock_fasync(struct inode *inode, struct file *filp, int on);
97
 
98
 
99
/*
100
 *      Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
101
 *      in the operation structures but are done directly via the socketcall() multiplexor.
102
 */
103
 
104
static struct file_operations socket_file_ops = {
105
        sock_lseek,
106
        sock_read,
107
        sock_write,
108
        NULL,                   /* readdir */
109
        sock_select,
110
        sock_ioctl,
111
        NULL,                   /* mmap */
112
        sock_no_open,           /* special open code... */
113
        sock_close,
114
        NULL,                   /* no fsync */
115
        sock_fasync
116
};
117
 
118
/*
119
 *      The protocol list. Each protocol is registered in here.
120
 */
121
static struct proto_ops *pops[NPROTO];
122
/*
123
 *      Statistics counters of the socket lists
124
 */
125
static int sockets_in_use  = 0;
126
 
127
/*
128
 *      Support routines. Move socket addresses back and forth across the kernel/user
129
 *      divide and look after the messy bits.
130
 */
131
 
132
#define MAX_SOCK_ADDR   128             /* 108 for Unix domain - 16 for IP, 16 for IPX, about 80 for AX.25 */
133
 
134
int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr)
135
{
136
        int err;
137
        if(ulen<0||ulen>MAX_SOCK_ADDR)
138
                return -EINVAL;
139
        if(ulen==0)
140
                return 0;
141
        if((err=verify_area(VERIFY_READ,uaddr,ulen))<0)
142
                return err;
143
        memcpy_fromfs(kaddr,uaddr,ulen);
144
        return 0;
145
}
146
 
147
int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen)
148
{
149
        int err;
150
        int len;
151
 
152
 
153
        if((err=verify_area(VERIFY_WRITE,ulen,sizeof(*ulen)))<0)
154
                return err;
155
        len=get_user(ulen);
156
        if(len>klen)
157
                len=klen;
158
        if(len<0 || len> MAX_SOCK_ADDR)
159
                return -EINVAL;
160
        if(len)
161
        {
162
                if((err=verify_area(VERIFY_WRITE,uaddr,len))<0)
163
                        return err;
164
                memcpy_tofs(uaddr,kaddr,len);
165
        }
166
        put_user(len,ulen);
167
        return 0;
168
}
169
 
170
/*
171
 *      Obtains the first available file descriptor and sets it up for use.
172
 */
173
 
174
static int get_fd(struct inode *inode)
175
{
176
        int fd;
177
 
178
        /*
179
         *      Find a file descriptor suitable for return to the user.
180
         */
181
 
182
        fd = get_unused_fd();
183
        if (fd >= 0) {
184
                struct file *file = get_empty_filp();
185
 
186
                if (!file) {
187
                        put_unused_fd(fd);
188
                        return -ENFILE;
189
                }
190
 
191
                current->files->fd[fd] = file;
192
                file->f_op = &socket_file_ops;
193
                file->f_mode = 3;
194
                file->f_flags = O_RDWR;
195
                file->f_count = 1;
196
                file->f_inode = inode;
197
                if (inode)
198
                        inode->i_count++;
199
                file->f_pos = 0;
200
        }
201
        return fd;
202
}
203
 
204
 
205
/*
206
 *      Go from an inode to its socket slot.
207
 *
208
 * The original socket implementation wasn't very clever, which is
209
 * why this exists at all..
210
 */
211
 
212
__inline struct socket *socki_lookup(struct inode *inode)
213
{
214
        return &inode->u.socket_i;
215
}
216
 
217
/*
218
 *      Go from a file number to its socket slot.
219
 */
220
 
221
extern __inline struct socket *sockfd_lookup(int fd, int *err)
222
{
223
        struct file *file;
224
        struct inode *inode;
225
        struct socket *sock;
226
 
227
        if (!(file = fget(fd)))
228
        {
229
                *err = -EBADF;
230
                return NULL;
231
        }
232
 
233
        inode = file->f_inode;
234
 
235
        if (!inode || !inode->i_sock || !(sock = socki_lookup(inode)))
236
        {
237
                *err = -ENOTSOCK;
238
                fput(file, inode);
239
                return NULL;
240
        }
241
 
242
        if (sock->file != file) {
243
                printk(KERN_ERR "socki_lookup: socket file changed!\n");
244
                sock->file = file;
245
        }
246
 
247
        return sock;
248
}
249
 
250
extern __inline__ void sockfd_put(struct socket *sock)
251
{
252
        fput(sock->file, sock->file->f_inode);
253
}
254
 
255
/*
256
 *      Allocate a socket.
257
 */
258
 
259
struct socket *sock_alloc(void)
260
{
261
        struct inode * inode;
262
        struct socket * sock;
263
 
264
        inode = get_empty_inode();
265
        if (!inode)
266
                return NULL;
267
 
268
        inode->i_mode = S_IFSOCK;
269
        inode->i_sock = 1;
270
        inode->i_uid = current->uid;
271
        inode->i_gid = current->gid;
272
 
273
        sock = &inode->u.socket_i;
274
        sock->state = SS_UNCONNECTED;
275
        sock->flags = 0;
276
        sock->ops = NULL;
277
        sock->data = NULL;
278
        sock->conn = NULL;
279
        sock->iconn = NULL;
280
        sock->next = NULL;
281
        sock->file = NULL;
282
        sock->wait = &inode->i_wait;
283
        sock->inode = inode;            /* "backlink": we could use pointer arithmetic instead */
284
        sock->fasync_list = NULL;
285
        sock->file = NULL;
286
        sockets_in_use++;
287
        return sock;
288
}
289
 
290
/*
291
 *      Release a socket.
292
 */
293
 
294
static inline void sock_release_peer(struct socket *peer)
295
{
296
        peer->state = SS_DISCONNECTING;
297
        wake_up_interruptible(peer->wait);
298
        sock_wake_async(peer, 1);
299
}
300
 
301
/*
302
 *      In theory you can't get an open on this inode, but /proc provides
303
 *      a back door. Remember to keep it shut otherwise you'll let the
304
 *      creepy crawlies in.
305
 */
306
 
307
static int sock_no_open(struct inode *inode, struct file *file)
308
{
309
        return -ENXIO;
310
}
311
 
312
void sock_release(struct socket *sock)
313
{
314
        int oldstate;
315
        struct socket *peersock, *nextsock;
316
 
317
        if ((oldstate = sock->state) != SS_UNCONNECTED)
318
                sock->state = SS_DISCONNECTING;
319
 
320
        /*
321
         *      Wake up anyone waiting for connections.
322
         */
323
 
324
        for (peersock = sock->iconn; peersock; peersock = nextsock)
325
        {
326
                nextsock = peersock->next;
327
                sock_release_peer(peersock);
328
        }
329
 
330
        /*
331
         * Wake up anyone we're connected to. First, we release the
332
         * protocol, to give it a chance to flush data, etc.
333
         */
334
 
335
        peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
336
        if (sock->ops)
337
                sock->ops->release(sock, peersock);
338
        if (peersock)
339
                sock_release_peer(peersock);
340
        --sockets_in_use;       /* Bookkeeping.. */
341
        sock->file=NULL;
342
        iput(SOCK_INODE(sock));
343
}
344
 
345
/*
346
 *      Sockets are not seekable.
347
 */
348
 
349
static int sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
350
{
351
        return(-ESPIPE);
352
}
353
 
354
/*
355
 *      Read data from a socket. ubuf is a user mode pointer. We make sure the user
356
 *      area ubuf...ubuf+size-1 is writable before asking the protocol.
357
 */
358
 
359
static int sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
360
{
361
        struct socket *sock;
362
        int err;
363
        struct iovec iov;
364
        struct msghdr msg;
365
 
366
        sock = socki_lookup(inode);
367
        if (sock->flags & SO_ACCEPTCON)
368
                return(-EINVAL);
369
 
370
        if(size<0)
371
                return -EINVAL;
372
        if(size==0)              /* Match SYS5 behaviour */
373
                return 0;
374
        if ((err=verify_area(VERIFY_WRITE,ubuf,size))<0)
375
                return err;
376
        msg.msg_name=NULL;
377
        msg.msg_iov=&iov;
378
        msg.msg_iovlen=1;
379
        msg.msg_control=NULL;
380
        iov.iov_base=ubuf;
381
        iov.iov_len=size;
382
 
383
        return(sock->ops->recvmsg(sock, &msg, size,(file->f_flags & O_NONBLOCK), 0,&msg.msg_namelen));
384
}
385
 
386
/*
387
 *      Write data to a socket. We verify that the user area ubuf..ubuf+size-1 is
388
 *      readable by the user process.
389
 */
390
 
391
static int sock_write(struct inode *inode, struct file *file, const char *ubuf, int size)
392
{
393
        struct socket *sock;
394
        int err;
395
        struct msghdr msg;
396
        struct iovec iov;
397
 
398
        sock = socki_lookup(inode);
399
 
400
        if (sock->flags & SO_ACCEPTCON)
401
                return(-EINVAL);
402
 
403
        if(size<0)
404
                return -EINVAL;
405
        if(size==0)              /* Match SYS5 behaviour */
406
                return 0;
407
 
408
        if ((err=verify_area(VERIFY_READ,ubuf,size))<0)
409
                return err;
410
 
411
        msg.msg_name=NULL;
412
        msg.msg_iov=&iov;
413
        msg.msg_iovlen=1;
414
        msg.msg_control=NULL;
415
        iov.iov_base=(void *)ubuf;
416
        iov.iov_len=size;
417
 
418
        return(sock->ops->sendmsg(sock, &msg, size,(file->f_flags & O_NONBLOCK),0));
419
}
420
 
421
/*
422
 *      With an ioctl arg may well be a user mode pointer, but we don't know what to do
423
 *      with it - that's up to the protocol still.
424
 */
425
 
426
int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
427
           unsigned long arg)
428
{
429
        struct socket *sock;
430
        sock = socki_lookup(inode);
431
        return(sock->ops->ioctl(sock, cmd, arg));
432
}
433
 
434
 
435
static int sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
436
{
437
        struct socket *sock;
438
 
439
        sock = socki_lookup(inode);
440
 
441
        /*
442
         *      We can't return errors to select, so it's either yes or no.
443
         */
444
 
445
        if (sock->ops->select)
446
                return(sock->ops->select(sock, sel_type, wait));
447
        return(0);
448
}
449
 
450
 
451
void sock_close(struct inode *inode, struct file *filp)
452
{
453
        /*
454
         *      It's possible the inode is NULL if we're closing an unfinished socket.
455
         */
456
 
457
        if (!inode)
458
                return;
459
        sock_fasync(inode, filp, 0);
460
        sock_release(socki_lookup(inode));
461
}
462
 
463
/*
464
 *      Update the socket async list
465
 */
466
 
467
static int sock_fasync(struct inode *inode, struct file *filp, int on)
468
{
469
        struct fasync_struct *fa, *fna=NULL, **prev;
470
        struct socket *sock;
471
        unsigned long flags;
472
 
473
        if (on)
474
        {
475
                fna=(struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
476
                if(fna==NULL)
477
                        return -ENOMEM;
478
        }
479
 
480
        sock = socki_lookup(inode);
481
 
482
        prev=&(sock->fasync_list);
483
 
484
        save_flags(flags);
485
        cli();
486
 
487
        for(fa=*prev; fa!=NULL; prev=&fa->fa_next,fa=*prev)
488
                if(fa->fa_file==filp)
489
                        break;
490
 
491
        if(on)
492
        {
493
                if(fa!=NULL)
494
                {
495
                        kfree_s(fna,sizeof(struct fasync_struct));
496
                        restore_flags(flags);
497
                        return 0;
498
                }
499
                fna->fa_file=filp;
500
                fna->magic=FASYNC_MAGIC;
501
                fna->fa_next=sock->fasync_list;
502
                sock->fasync_list=fna;
503
        }
504
        else
505
        {
506
                if(fa!=NULL)
507
                {
508
                        *prev=fa->fa_next;
509
                        kfree_s(fa,sizeof(struct fasync_struct));
510
                }
511
        }
512
        restore_flags(flags);
513
        return 0;
514
}
515
 
516
int sock_wake_async(struct socket *sock, int how)
517
{
518
        if (!sock || !sock->fasync_list)
519
                return -1;
520
        switch (how)
521
        {
522
                case 0:
523
                        kill_fasync(sock->fasync_list, SIGIO);
524
                        break;
525
                case 1:
526
                        if (!(sock->flags & SO_WAITDATA))
527
                                kill_fasync(sock->fasync_list, SIGIO);
528
                        break;
529
                case 2:
530
                        if (sock->flags & SO_NOSPACE)
531
                        {
532
                                kill_fasync(sock->fasync_list, SIGIO);
533
                                sock->flags &= ~SO_NOSPACE;
534
                        }
535
                        break;
536
        }
537
        return 0;
538
}
539
 
540
 
541
/*
542
 *      Perform the socket system call. we locate the appropriate
543
 *      family, then create a fresh socket.
544
 */
545
 
546
static int find_protocol_family(int family)
547
{
548
        register int i;
549
        for (i = 0; i < NPROTO; i++)
550
        {
551
                if (pops[i] == NULL)
552
                        continue;
553
                if (pops[i]->family == family)
554
                        return i;
555
        }
556
        return -1;
557
}
558
 
559
asmlinkage int sys_socket(int family, int type, int protocol)
560
{
561
        int i, fd;
562
        struct socket *sock;
563
        struct proto_ops *ops;
564
 
565
        /* Locate the correct protocol family. */
566
        i = find_protocol_family(family);
567
 
568
#ifdef CONFIG_KERNELD
569
        /* Attempt to load a protocol module if the find failed. */
570
        if (i < 0)
571
        {
572
                char module_name[30];
573
                sprintf(module_name,"net-pf-%d",family);
574
                request_module(module_name);
575
                i = find_protocol_family(family);
576
        }
577
#endif
578
 
579
        if (i < 0)
580
        {
581
                return -EINVAL;
582
        }
583
 
584
        ops = pops[i];
585
 
586
/*
587
 *      Check that this is a type that we know how to manipulate and
588
 *      the protocol makes sense here. The family can still reject the
589
 *      protocol later.
590
 */
591
 
592
        if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
593
                type != SOCK_SEQPACKET && type != SOCK_RAW &&
594
                type != SOCK_PACKET) || protocol < 0)
595
                        return(-EINVAL);
596
 
597
/*
598
 *      Allocate the socket and allow the family to set things up. if
599
 *      the protocol is 0, the family is instructed to select an appropriate
600
 *      default.
601
 */
602
 
603
        if (!(sock = sock_alloc()))
604
        {
605
                printk(KERN_WARNING "socket: no more sockets\n");
606
                return(-ENOSR); /* Was: EAGAIN, but we are out of
607
                                   system resources! */
608
        }
609
 
610
        sock->type = type;
611
        sock->ops = ops;
612
        if ((i = sock->ops->create(sock, protocol)) < 0)
613
        {
614
                sock_release(sock);
615
                return(i);
616
        }
617
 
618
        if ((fd = get_fd(SOCK_INODE(sock))) < 0)
619
        {
620
                sock_release(sock);
621
                return fd;
622
        }
623
 
624
        sock->file=current->files->fd[fd];
625
 
626
        return(fd);
627
}
628
 
629
/*
630
 *      Create a pair of connected sockets.
631
 */
632
 
633
asmlinkage int sys_socketpair(int family, int type, int protocol, int usockvec[2])
634
{
635
        int fd1, fd2, i;
636
        struct socket *sock1, *sock2;
637
        int er;
638
 
639
        /*
640
         * Obtain the first socket and check if the underlying protocol
641
         * supports the socketpair call.
642
         */
643
 
644
        if ((fd1 = sys_socket(family, type, protocol)) < 0)
645
                return(fd1);
646
        sock1 = sockfd_lookup(fd1, &er);
647
        if (!sock1->ops->socketpair)
648
        {
649
                sockfd_put(sock1);
650
                sys_close(fd1);
651
                return(-EINVAL);
652
        }
653
 
654
        /*
655
         *      Now grab another socket and try to connect the two together.
656
         */
657
 
658
        if ((fd2 = sys_socket(family, type, protocol)) < 0)
659
        {
660
                sockfd_put(sock1);
661
                sys_close(fd1);
662
                return(-EINVAL);
663
        }
664
 
665
        sock2 = sockfd_lookup(fd2, &er);
666
        if ((i = sock1->ops->socketpair(sock1, sock2)) < 0)
667
        {
668
                sockfd_put(sock1);
669
                sys_close(fd1);
670
                sockfd_put(sock2);
671
                sys_close(fd2);
672
                return(i);
673
        }
674
 
675
        sock1->conn = sock2;
676
        sock2->conn = sock1;
677
        sock1->state = SS_CONNECTED;
678
        sock2->state = SS_CONNECTED;
679
 
680
        er=verify_area(VERIFY_WRITE, usockvec, sizeof(usockvec));
681
        if(er)
682
        {
683
                sockfd_put(sock1);
684
                sys_close(fd1);
685
                sockfd_put(sock2);
686
                sys_close(fd2);
687
                return er;
688
        }
689
        put_user(fd1, &usockvec[0]);
690
        put_user(fd2, &usockvec[1]);
691
 
692
        sockfd_put(sock1);
693
        sockfd_put(sock2);
694
        return(0);
695
}
696
 
697
 
698
/*
699
 *      Bind a name to a socket. Nothing much to do here since it's
700
 *      the protocol's responsibility to handle the local address.
701
 *
702
 *      We move the socket address to kernel space before we call
703
 *      the protocol layer (having also checked the address is ok).
704
 */
705
 
706
asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen)
707
{
708
        struct socket *sock;
709
        char address[MAX_SOCK_ADDR];
710
        int err;
711
 
712
        if (!(sock = sockfd_lookup(fd, &err)))
713
                return err;
714
 
715
        if((err=move_addr_to_kernel(umyaddr,addrlen,address))<0)
716
                goto out;
717
 
718
        if ((err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen)) > 0)
719
                err = 0;
720
out:
721
        sockfd_put(sock);
722
        return err;
723
}
724
 
725
 
726
/*
727
 *      Perform a listen. Basically, we allow the protocol to do anything
728
 *      necessary for a listen, and if that works, we mark the socket as
729
 *      ready for listening.
730
 */
731
 
732
asmlinkage int sys_listen(int fd, int backlog)
733
{
734
        struct socket *sock;
735
        int err=-EOPNOTSUPP;
736
 
737
        if (!(sock = sockfd_lookup(fd, &err)))
738
                return err;
739
 
740
        if (sock->state != SS_UNCONNECTED)
741
        {
742
                err=-EINVAL;
743
                goto out;
744
        }
745
 
746
        if (sock->ops && sock->ops->listen)
747
        {
748
                err=sock->ops->listen(sock, backlog);
749
                if(!err)
750
                        sock->flags |= SO_ACCEPTCON;
751
        }
752
out:
753
        sockfd_put(sock);
754
        return(err);
755
}
756
 
757
 
758
/*
759
 *      For accept, we attempt to create a new socket, set up the link
760
 *      with the client, wake up the client, then return the new
761
 *      connected fd. We collect the address of the connector in kernel
762
 *      space and move it to user at the very end. This is buggy because
763
 *      we open the socket then return an error.
764
 */
765
 
766
asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
767
{
768
        struct socket *sock, *newsock;
769
        int i;
770
        char address[MAX_SOCK_ADDR];
771
        int len;
772
 
773
        if (!(sock = sockfd_lookup(fd, &i)))
774
                return i;
775
        if (sock->state != SS_UNCONNECTED || (!(sock->flags & SO_ACCEPTCON)))
776
        {
777
                sockfd_put(sock);
778
                return(-EINVAL);
779
        }
780
 
781
        if (!(newsock = sock_alloc()))
782
        {
783
                printk(KERN_WARNING "accept: no more sockets\n");
784
                sockfd_put(sock);
785
                return(-ENOSR); /* Was: EAGAIN, but we are out of system
786
                                   resources! */
787
        }
788
        newsock->type = sock->type;
789
        newsock->ops = sock->ops;
790
        if ((i = sock->ops->dup(newsock, sock)) < 0)
791
        {
792
                sock_release(newsock);
793
                sockfd_put(sock);
794
                return(i);
795
        }
796
 
797
        i = newsock->ops->accept(sock, newsock, sock->file->f_flags);
798
        if ( i < 0)
799
        {
800
                sock_release(newsock);
801
                sockfd_put(sock);
802
                return(i);
803
        }
804
 
805
        if ((fd = get_fd(SOCK_INODE(newsock))) < 0)
806
        {
807
                sock_release(newsock);
808
                sockfd_put(sock);
809
                return(-EINVAL);
810
        }
811
        newsock->file=current->files->fd[fd];
812
 
813
        if (upeer_sockaddr)
814
        {
815
                newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1);
816
                move_addr_to_user(address,len, upeer_sockaddr, upeer_addrlen);
817
        }
818
        sockfd_put(sock);
819
        return(fd);
820
}
821
 
822
 
823
/*
824
 *      Attempt to connect to a socket with the server address.  The address
825
 *      is in user space so we verify it is OK and move it to kernel space.
826
 */
827
 
828
asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen)
829
{
830
        struct socket *sock;
831
        char address[MAX_SOCK_ADDR];
832
        int err;
833
 
834
        if (!(sock = sockfd_lookup(fd, &err)))
835
                return(err);
836
 
837
        if((err=move_addr_to_kernel(uservaddr,addrlen,address))<0)
838
                goto out;
839
 
840
        switch(sock->state)
841
        {
842
                case SS_UNCONNECTED:
843
                        /* This is ok... continue with connect */
844
                        break;
845
                case SS_CONNECTED:
846
                        /* Socket is already connected */
847
                        if(sock->type == SOCK_DGRAM) /* Hack for now - move this all into the protocol */
848
                                break;
849
                        err = -EISCONN;
850
                        goto out;
851
                case SS_CONNECTING:
852
                        /* Not yet connected... we will check this. */
853
 
854
                        /*
855
                         *      FIXME:  for all protocols what happens if you start
856
                         *      an async connect fork and both children connect. Clean
857
                         *      this up in the protocols!
858
                         */
859
                        break;
860
                default:
861
                        err = -EINVAL;
862
                        goto out;
863
        }
864
        err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, sock->file->f_flags);
865
        if (err > 0)
866
                err = 0;
867
out:
868
        sockfd_put(sock);
869
        return err;
870
}
871
 
872
/*
873
 *      Get the local address ('name') of a socket object. Move the obtained
874
 *      name to user space.
875
 */
876
 
877
asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
878
{
879
        struct socket *sock;
880
        char address[MAX_SOCK_ADDR];
881
        int len;
882
        int err;
883
 
884
        if (!(sock = sockfd_lookup(fd, &err)))
885
                return err;
886
 
887
        err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
888
        if(err)
889
                goto out;
890
        if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))>0)
891
                err = 0;
892
out:
893
        sockfd_put(sock);
894
        return err;
895
}
896
 
897
/*
898
 *      Get the remote address ('name') of a socket object. Move the obtained
899
 *      name to user space.
900
 */
901
 
902
asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
903
{
904
        struct socket *sock;
905
        char address[MAX_SOCK_ADDR];
906
        int len;
907
        int err;
908
 
909
        if (!(sock = sockfd_lookup(fd, &err)))
910
                return err;
911
 
912
        err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
913
        if(err)
914
                goto out;
915
        if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))>0)
916
                err = 0;
917
out:
918
        sockfd_put(sock);
919
        return err;
920
}
921
 
922
/*
923
 *      Send a datagram down a socket. The datagram as with write() is
924
 *      in user space. We check it can be read.
925
 */
926
 
927
asmlinkage int sys_send(int fd, void * buff, int len, unsigned flags)
928
{
929
        struct socket *sock;
930
        int err;
931
        struct msghdr msg;
932
        struct iovec iov;
933
 
934
        if(len<0)
935
                return -EINVAL;
936
        err=verify_area(VERIFY_READ, buff, len);
937
        if(err)
938
                return err;
939
 
940
        if (!(sock = sockfd_lookup(fd, &err)))
941
                return err;
942
 
943
        iov.iov_base=buff;
944
        iov.iov_len=len;
945
        msg.msg_name=NULL;
946
        msg.msg_iov=&iov;
947
        msg.msg_iovlen=1;
948
        msg.msg_control=NULL;
949
        err=sock->ops->sendmsg(sock, &msg, len, (sock->file->f_flags & O_NONBLOCK), flags);
950
        sockfd_put(sock);
951
        return err;
952
}
953
 
954
/*
955
 *      Send a datagram to a given address. We move the address into kernel
956
 *      space and check the user space data area is readable before invoking
957
 *      the protocol.
958
 */
959
 
960
asmlinkage int sys_sendto(int fd, void * buff, int len, unsigned flags,
961
           struct sockaddr *addr, int addr_len)
962
{
963
        struct socket *sock;
964
        char address[MAX_SOCK_ADDR];
965
        int err;
966
        struct msghdr msg;
967
        struct iovec iov;
968
 
969
        if(len<0)
970
                return -EINVAL;
971
        err=verify_area(VERIFY_READ,buff,len);
972
        if(err)
973
                return err;
974
        if (!(sock = sockfd_lookup(fd, &err)))
975
                return err;
976
 
977
        iov.iov_base=buff;
978
        iov.iov_len=len;
979
        msg.msg_name = NULL;
980
        msg.msg_namelen = 0;
981
        msg.msg_iov=&iov;
982
        msg.msg_iovlen=1;
983
        msg.msg_control=NULL;
984
        if (addr && addr_len) {
985
                err=move_addr_to_kernel(addr,addr_len,address);
986
                if (err < 0)
987
                {
988
                        sockfd_put(sock);
989
                        return err;
990
                }
991
                msg.msg_name=address;
992
                msg.msg_namelen=addr_len;
993
        }
994
 
995
        err=sock->ops->sendmsg(sock, &msg, len, (sock->file->f_flags & O_NONBLOCK), flags);
996
        sockfd_put(sock);
997
        return err;
998
}
999
 
1000
 
1001
/*
1002
 *      Receive a datagram from a socket. Call the protocol recvmsg method
1003
 */
1004
 
1005
asmlinkage int sys_recv(int fd, void * ubuf, int size, unsigned flags)
1006
{
1007
        struct iovec iov;
1008
        struct msghdr msg;
1009
        struct socket *sock;
1010
        int err;
1011
 
1012
        if(size<0)
1013
                return -EINVAL;
1014
        if(size==0)
1015
                return 0;
1016
        err=verify_area(VERIFY_WRITE, ubuf, size);
1017
        if(err)
1018
                return err;
1019
        if (!(sock = sockfd_lookup(fd, &err)))
1020
                return err;
1021
 
1022
        msg.msg_name=NULL;
1023
        msg.msg_iov=&iov;
1024
        msg.msg_iovlen=1;
1025
        msg.msg_control=NULL;
1026
        iov.iov_base=ubuf;
1027
        iov.iov_len=size;
1028
 
1029
        err=sock->ops->recvmsg(sock, &msg, size,(sock->file->f_flags & O_NONBLOCK), flags,&msg.msg_namelen);
1030
        sockfd_put(sock);
1031
        return err;
1032
}
1033
 
1034
/*
1035
 *      Receive a frame from the socket and optionally record the address of the
1036
 *      sender. We verify the buffers are writable and if needed move the
1037
 *      sender address from kernel to user space.
1038
 */
1039
 
1040
asmlinkage int sys_recvfrom(int fd, void * ubuf, int size, unsigned flags,
1041
             struct sockaddr *addr, int *addr_len)
1042
{
1043
        struct socket *sock;
1044
        struct iovec iov;
1045
        struct msghdr msg;
1046
        char address[MAX_SOCK_ADDR];
1047
        int err;
1048
        int alen;
1049
        if(size<0)
1050
                return -EINVAL;
1051
        if(size==0)
1052
                return 0;
1053
        err=verify_area(VERIFY_WRITE,ubuf,size);
1054
        if(err)
1055
                return err;
1056
        if (!(sock = sockfd_lookup(fd, &err)))
1057
                return err;
1058
 
1059
        msg.msg_control=NULL;
1060
        msg.msg_iovlen=1;
1061
        msg.msg_iov=&iov;
1062
        iov.iov_len=size;
1063
        iov.iov_base=ubuf;
1064
        msg.msg_name=address;
1065
        msg.msg_namelen=MAX_SOCK_ADDR;
1066
        size=sock->ops->recvmsg(sock, &msg, size, (sock->file->f_flags & O_NONBLOCK),
1067
                     flags, &alen);
1068
 
1069
        sockfd_put(sock);
1070
 
1071
        if(size<0)
1072
                return size;
1073
        if(addr!=NULL && (err=move_addr_to_user(address,alen, addr, addr_len))<0)
1074
                return err;
1075
 
1076
        return size;
1077
}
1078
 
1079
/*
1080
 *      Set a socket option. Because we don't know the option lengths we have
1081
 *      to pass the user mode parameter for the protocols to sort out.
1082
 */
1083
 
1084
asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen)
1085
{
1086
        struct socket *sock;
1087
        int err;
1088
 
1089
        if (!(sock = sockfd_lookup(fd, &err)))
1090
                return err;
1091
 
1092
        err=sock->ops->setsockopt(sock, level, optname, optval, optlen);
1093
        sockfd_put(sock);
1094
        return err;
1095
}
1096
 
1097
/*
1098
 *      Get a socket option. Because we don't know the option lengths we have
1099
 *      to pass a user mode parameter for the protocols to sort out.
1100
 */
1101
 
1102
asmlinkage int sys_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
1103
{
1104
        struct socket *sock;
1105
        int err;
1106
 
1107
        if (!(sock = sockfd_lookup(fd, &err)))
1108
                return err;
1109
 
1110
        if (!sock->ops->getsockopt)
1111
        {
1112
                sockfd_put(sock);
1113
                return(0);
1114
        }
1115
        err=sock->ops->getsockopt(sock, level, optname, optval, optlen);
1116
        sockfd_put(sock);
1117
        return err;
1118
}
1119
 
1120
 
1121
/*
1122
 *      Shutdown a socket.
1123
 */
1124
 
1125
asmlinkage int sys_shutdown(int fd, int how)
1126
{
1127
        struct socket *sock;
1128
        int err;
1129
 
1130
        if (!(sock = sockfd_lookup(fd, &err)))
1131
                return err;
1132
        err=sock->ops->shutdown(sock, how);
1133
        sockfd_put(sock);
1134
        return err;
1135
}
1136
 
1137
/*
1138
 *      BSD sendmsg interface
1139
 */
1140
 
1141
asmlinkage int sys_sendmsg(int fd, struct msghdr *msg, unsigned int flags)
1142
{
1143
        struct socket *sock;
1144
        char address[MAX_SOCK_ADDR];
1145
        struct iovec iov[UIO_MAXIOV];
1146
        struct msghdr msg_sys;
1147
        int err;
1148
        int total_len;
1149
 
1150
        err=verify_area(VERIFY_READ, msg,sizeof(struct msghdr));
1151
        if(err)
1152
                return err;
1153
        if (!(sock = sockfd_lookup(fd, &err)))
1154
                return err;
1155
        if(sock->ops->sendmsg==NULL)
1156
        {
1157
                err = -EOPNOTSUPP;
1158
                goto out;
1159
        }
1160
 
1161
        memcpy_fromfs(&msg_sys,msg,sizeof(struct msghdr));
1162
 
1163
        /* do not move before msg_sys is valid */
1164
        if(msg_sys.msg_iovlen>UIO_MAXIOV)
1165
        {
1166
                err = -EINVAL;
1167
                goto out;
1168
        }
1169
 
1170
        /* This will also move the address data into kernel space */
1171
        err = verify_iovec(&msg_sys, iov, address, VERIFY_READ);
1172
        if (err < 0)
1173
                goto out;
1174
 
1175
        total_len=err;
1176
 
1177
        err=sock->ops->sendmsg(sock, &msg_sys, total_len, (sock->file->f_flags&O_NONBLOCK), flags);
1178
out:
1179
        sockfd_put(sock);
1180
        return err;
1181
}
1182
 
1183
/*
1184
 *      BSD recvmsg interface
1185
 */
1186
 
1187
asmlinkage int sys_recvmsg(int fd, struct msghdr *msg, unsigned int flags)
1188
{
1189
        struct socket *sock;
1190
        struct iovec iov[UIO_MAXIOV];
1191
        struct msghdr msg_sys;
1192
        int err;
1193
        int total_len;
1194
        int len;
1195
 
1196
        /* kernel mode address */
1197
        char addr[MAX_SOCK_ADDR];
1198
        int addr_len;
1199
 
1200
        /* user mode address pointers */
1201
        struct sockaddr *uaddr;
1202
        int *uaddr_len;
1203
 
1204
        err=verify_area(VERIFY_READ, msg,sizeof(struct msghdr));
1205
        if(err)
1206
                return err;
1207
        memcpy_fromfs(&msg_sys,msg,sizeof(struct msghdr));
1208
        if(msg_sys.msg_iovlen>UIO_MAXIOV)
1209
                return -EINVAL;
1210
 
1211
        if (!(sock = sockfd_lookup(fd, &err)))
1212
                return err;
1213
 
1214
 
1215
        /*
1216
         * save the user-mode address (verify_iovec will change the
1217
         * kernel msghdr to use the kernel address space)
1218
         */
1219
        uaddr = msg_sys.msg_name;
1220
        uaddr_len = &msg->msg_namelen;
1221
        err=verify_iovec(&msg_sys,iov,addr, VERIFY_WRITE);
1222
        if(err<0)
1223
                goto out;
1224
 
1225
        total_len=err;
1226
 
1227
        if(sock->ops->recvmsg==NULL)
1228
        {
1229
                err = -EOPNOTSUPP;
1230
                goto out;
1231
        }
1232
        err=sock->ops->recvmsg(sock, &msg_sys, total_len, (sock->file->f_flags&O_NONBLOCK), flags, &addr_len);
1233
        if(err<0)
1234
                goto out;
1235
        len=err;
1236
 
1237
        if (uaddr != NULL) {
1238
                err = move_addr_to_user(addr, addr_len, uaddr, uaddr_len);
1239
                if (err)
1240
                        goto out;
1241
        }
1242
        sockfd_put(sock);
1243
        return len;
1244
 
1245
out:
1246
        sockfd_put(sock);
1247
        return err;
1248
}
1249
 
1250
 
1251
/*
1252
 *      Perform a file control on a socket file descriptor.
1253
 */
1254
 
1255
int sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
1256
{
1257
        struct socket *sock;
1258
 
1259
        sock = socki_lookup (filp->f_inode);
1260
        if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
1261
                return(sock->ops->fcntl(sock, cmd, arg));
1262
        return(-EINVAL);
1263
}
1264
 
1265
 
1266
/*
1267
 *      System call vectors. Since I (RIB) want to rewrite sockets as streams,
1268
 *      we have this level of indirection. Not a lot of overhead, since more of
1269
 *      the work is done via read/write/select directly.
1270
 *
1271
 *      I'm now expanding this up to a higher level to separate the assorted
1272
 *      kernel/user space manipulations and global assumptions from the protocol
1273
 *      layers proper - AC.
1274
 *
1275
 *      Argument checking cleaned up. Saved 20% in size.
1276
 */
1277
 
1278
asmlinkage int sys_socketcall(int call, unsigned long *args)
1279
{
1280
        int er;
1281
        unsigned char nargs[18]={0,3,3,3,2,3,3,3,
1282
                                 4,4,4,6,6,2,5,5,3,3};
1283
 
1284
        unsigned long a0,a1;
1285
 
1286
        if(call<1||call>SYS_RECVMSG)
1287
                return -EINVAL;
1288
 
1289
        er=verify_area(VERIFY_READ, args, nargs[call] * sizeof(unsigned long));
1290
        if(er)
1291
                return er;
1292
 
1293
        a0=get_user(args);
1294
        a1=get_user(args+1);
1295
 
1296
 
1297
        switch(call)
1298
        {
1299
                case SYS_SOCKET:
1300
                        return(sys_socket(a0,a1,get_user(args+2)));
1301
                case SYS_BIND:
1302
                        return(sys_bind(a0,(struct sockaddr *)a1,
1303
                                        get_user(args+2)));
1304
                case SYS_CONNECT:
1305
                        return(sys_connect(a0, (struct sockaddr *)a1,
1306
                                           get_user(args+2)));
1307
                case SYS_LISTEN:
1308
                        return(sys_listen(a0,a1));
1309
                case SYS_ACCEPT:
1310
                        return(sys_accept(a0,(struct sockaddr *)a1,
1311
                                          (int *)get_user(args+2)));
1312
                case SYS_GETSOCKNAME:
1313
                        return(sys_getsockname(a0,(struct sockaddr *)a1,
1314
                                               (int *)get_user(args+2)));
1315
                case SYS_GETPEERNAME:
1316
                        return(sys_getpeername(a0, (struct sockaddr *)a1,
1317
                                               (int *)get_user(args+2)));
1318
                case SYS_SOCKETPAIR:
1319
                        return(sys_socketpair(a0,a1,
1320
                                              get_user(args+2),
1321
                                              (int *)get_user(args+3)));
1322
                case SYS_SEND:
1323
                        return(sys_send(a0,
1324
                                (void *)a1,
1325
                                get_user(args+2),
1326
                                get_user(args+3)));
1327
                case SYS_SENDTO:
1328
                        return(sys_sendto(a0,(void *)a1,
1329
                                get_user(args+2),
1330
                                get_user(args+3),
1331
                                (struct sockaddr *)get_user(args+4),
1332
                                get_user(args+5)));
1333
                case SYS_RECV:
1334
                        return(sys_recv(a0,
1335
                                (void *)a1,
1336
                                get_user(args+2),
1337
                                get_user(args+3)));
1338
                case SYS_RECVFROM:
1339
                        return(sys_recvfrom(a0,
1340
                                (void *)a1,
1341
                                get_user(args+2),
1342
                                get_user(args+3),
1343
                                (struct sockaddr *)get_user(args+4),
1344
                                (int *)get_user(args+5)));
1345
                case SYS_SHUTDOWN:
1346
                        return(sys_shutdown(a0,a1));
1347
                case SYS_SETSOCKOPT:
1348
                        return(sys_setsockopt(a0,
1349
                                a1,
1350
                                get_user(args+2),
1351
                                (char *)get_user(args+3),
1352
                                get_user(args+4)));
1353
                case SYS_GETSOCKOPT:
1354
                        return(sys_getsockopt(a0,
1355
                                a1,
1356
                                get_user(args+2),
1357
                                (char *)get_user(args+3),
1358
                                (int *)get_user(args+4)));
1359
                case SYS_SENDMSG:
1360
                                return sys_sendmsg(a0,
1361
                                        (struct msghdr *) a1,
1362
                                        get_user(args+2));
1363
                case SYS_RECVMSG:
1364
                                return sys_recvmsg(a0,
1365
                                        (struct msghdr *) a1,
1366
                                        get_user(args+2));
1367
        }
1368
        return -EINVAL; /* to keep gcc happy */
1369
}
1370
 
1371
/*
1372
 *      This function is called by a protocol handler that wants to
1373
 *      advertise its address family, and have it linked into the
1374
 *      SOCKET module.
1375
 */
1376
 
1377
int sock_register(int family, struct proto_ops *ops)
1378
{
1379
        int i;
1380
 
1381
        cli();
1382
        for(i = 0; i < NPROTO; i++)
1383
        {
1384
                if (pops[i] != NULL)
1385
                        continue;
1386
                pops[i] = ops;
1387
                pops[i]->family = family;
1388
                sti();
1389
                return(i);
1390
        }
1391
        sti();
1392
        return(-ENOMEM);
1393
}
1394
 
1395
/*
1396
 *      This function is called by a protocol handler that wants to
1397
 *      remove its address family, and have it unlinked from the
1398
 *      SOCKET module.
1399
 */
1400
 
1401
int sock_unregister(int family)
1402
{
1403
        int i;
1404
 
1405
        cli();
1406
        for(i = 0; i < NPROTO; i++)
1407
        {
1408
                if (pops[i] == NULL)
1409
                        continue;
1410
                if (pops[i]->family == family)
1411
                {
1412
                        pops[i]=NULL;
1413
                        sti();
1414
                        return(i);
1415
                }
1416
        }
1417
        sti();
1418
        return(-ENOENT);
1419
}
1420
 
1421
void proto_init(void)
1422
{
1423
        extern struct net_proto protocols[];    /* Network protocols */
1424
        struct net_proto *pro;
1425
 
1426
        /* Kick all configured protocols. */
1427
        pro = protocols;
1428
        while (pro->name != NULL)
1429
        {
1430
                (*pro->init_func)(pro);
1431
                pro++;
1432
        }
1433
        /* We're all done... */
1434
}
1435
 
1436
 
1437
void sock_init(void)
1438
{
1439
        int i;
1440
 
1441
        printk(KERN_INFO "Swansea University Computer Society NET3.035 for Linux 2.0\n");
1442
 
1443
        /*
1444
         *      Initialize all address (protocol) families.
1445
         */
1446
 
1447
        for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
1448
 
1449
        /*
1450
         *      The netlink device handler may be needed early.
1451
         */
1452
 
1453
#ifdef CONFIG_NETLINK
1454
        init_netlink();
1455
#endif           
1456
        /*
1457
         *      Attach the routing/device information port.
1458
         */
1459
 
1460
#if defined(CONFIG_RTNETLINK)
1461
        netlink_attach(NETLINK_ROUTE, netlink_donothing);
1462
#endif
1463
 
1464
        /*
1465
         *      Attach the firewall module if configured
1466
         */
1467
 
1468
#ifdef CONFIG_FIREWALL   
1469
        fwchain_init();
1470
#endif
1471
 
1472
        /*
1473
         *      Initialize the protocols module.
1474
         */
1475
 
1476
        proto_init();
1477
 
1478
        /*
1479
         *      Export networking symbols to the world.
1480
         */
1481
 
1482
#if defined(CONFIG_MODULES) && defined(CONFIG_NET)
1483
        export_net_symbols();
1484
#endif
1485
}
1486
 
1487
int socket_get_info(char *buffer, char **start, off_t offset, int length)
1488
{
1489
        int len = sprintf(buffer, "sockets: used %d\n", sockets_in_use);
1490
        if (offset >= len)
1491
        {
1492
                *start = buffer;
1493
                return 0;
1494
        }
1495
        *start = buffer + offset;
1496
        len -= offset;
1497
        if (len > length)
1498
                len = length;
1499
        return len;
1500
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.