This source file includes following definitions.
- family_name
- get_fd
- toss_fd
- socki_lookup
- sockfd_lookup
- sock_alloc
- sock_release_peer
- sock_release
- sock_lseek
- sock_read
- sock_write
- sock_readdir
- sock_ioctl
- sock_select
- sock_close
- sock_awaitconn
- sock_socket
- sock_socketpair
- sock_bind
- sock_listen
- sock_accept
- sock_connect
- sock_getsockname
- sock_getpeername
- sys_send
- sys_sendto
- sys_recv
- sys_recvfrom
- sys_setsockopt
- sys_getsockopt
- sys_shutdown
- sock_fcntl
- sys_socketcall
- sock_init
1
2 #include <linux/signal.h>
3 #include <linux/errno.h>
4 #include <linux/sched.h>
5 #include <linux/kernel.h>
6 #include <linux/stat.h>
7 #include <linux/socket.h>
8 #include <linux/fcntl.h>
9 #include <linux/termios.h>
10
11 #include <asm/system.h>
12 #include <asm/segment.h>
13
14 #include "kern_sock.h"
15 #include "socketcall.h"
16
17 extern int sys_close(int fd);
18
19 extern struct proto_ops unix_proto_ops;
20 #ifdef INET_SOCKETS
21 extern struct proto_ops inet_proto_ops;
22 #endif
23
24 static struct {
25 short family;
26 char *name;
27 struct proto_ops *ops;
28 } proto_table[] = {
29 {AF_UNIX, "AF_UNIX", &unix_proto_ops},
30 #ifdef INET_SOCKETS
31 {AF_INET, "AF_INET", &inet_proto_ops},
32 #endif
33 };
34 #define NPROTO (sizeof(proto_table) / sizeof(proto_table[0]))
35
36 static char *
37 family_name(int family)
38 {
39 int i;
40
41 for (i = 0; i < NPROTO; ++i)
42 if (proto_table[i].family == family)
43 return proto_table[i].name;
44 return "UNKNOWN";
45 }
46
47 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
48 int whence);
49 static int sock_read(struct inode *inode, struct file *file, char *buf,
50 int size);
51 static int sock_write(struct inode *inode, struct file *file, char *buf,
52 int size);
53 static int sock_readdir(struct inode *inode, struct file *file,
54 struct dirent *dirent, int count);
55 static void sock_close(struct inode *inode, struct file *file);
56 static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
57 static int sock_ioctl(struct inode *inode, struct file *file,
58 unsigned int cmd, unsigned int arg);
59
60 static struct file_operations socket_file_ops = {
61 sock_lseek,
62 sock_read,
63 sock_write,
64 sock_readdir,
65 sock_select,
66 sock_ioctl,
67 NULL,
68 NULL,
69 sock_close
70 };
71
72 #define SOCK_INODE(S) ((struct inode *)(S)->dummy)
73
74 static struct socket sockets[NSOCKETS];
75 #define last_socket (sockets + NSOCKETS - 1)
76 static struct wait_queue *socket_wait_free = NULL;
77
78
79
80
81 static int
82 get_fd(struct inode *inode)
83 {
84 int fd, i;
85 struct file *file;
86
87
88
89
90 for (fd = 0; fd < NR_OPEN; ++fd)
91 if (!current->filp[fd])
92 break;
93 if (fd == NR_OPEN)
94 return -1;
95 current->close_on_exec &= ~(1 << fd);
96 for (file = file_table, i = 0; i < NR_FILE; ++i, ++file)
97 if (!file->f_count)
98 break;
99 if (i == NR_FILE)
100 return -1;
101 current->filp[fd] = file;
102 file->f_op = &socket_file_ops;
103 file->f_mode = 3;
104 file->f_flags = 0;
105 file->f_count = 1;
106 file->f_inode = inode;
107 file->f_pos = 0;
108 return fd;
109 }
110
111
112
113
114
115
116 static inline void
117 toss_fd(int fd)
118 {
119 current->filp[fd]->f_inode = NULL;
120 sys_close(fd);
121 }
122
123 static inline struct socket *
124 socki_lookup(struct inode *inode)
125 {
126 struct socket *sock;
127
128 for (sock = sockets; sock <= last_socket; ++sock)
129 if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
130 return sock;
131 return NULL;
132 }
133
134 static inline struct socket *
135 sockfd_lookup(int fd, struct file **pfile)
136 {
137 struct file *file;
138
139 if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd]))
140 return NULL;
141 if (pfile)
142 *pfile = file;
143 return socki_lookup(file->f_inode);
144 }
145
146 static struct socket *
147 sock_alloc(int wait)
148 {
149 struct socket *sock;
150
151 while (1) {
152 cli();
153 for (sock = sockets; sock <= last_socket; ++sock)
154 if (sock->state == SS_FREE) {
155 sock->state = SS_UNCONNECTED;
156 sti();
157 sock->flags = 0;
158 sock->ops = NULL;
159 sock->data = NULL;
160 sock->conn = NULL;
161 sock->iconn = NULL;
162
163
164
165
166
167
168
169
170
171 if (!(SOCK_INODE(sock) = get_empty_inode())) {
172 printk("sock_alloc: no more inodes\n");
173 sock->state = SS_FREE;
174 return NULL;
175 }
176 SOCK_INODE(sock)->i_mode = S_IFSOCK;
177 sock->wait = &SOCK_INODE(sock)->i_wait;
178 PRINTK("sock_alloc: socket 0x%x, inode 0x%x\n",
179 sock, SOCK_INODE(sock));
180 return sock;
181 }
182 sti();
183 if (!wait)
184 return NULL;
185 PRINTK("sock_alloc: no free sockets, sleeping...\n");
186 interruptible_sleep_on(&socket_wait_free);
187 if (current->signal & ~current->blocked) {
188 PRINTK("sock_alloc: sleep was interrupted\n");
189 return NULL;
190 }
191 PRINTK("sock_alloc: wakeup... trying again...\n");
192 }
193 }
194
195 static inline void
196 sock_release_peer(struct socket *peer)
197 {
198 peer->state = SS_DISCONNECTING;
199 wake_up(peer->wait);
200 }
201
202 static void
203 sock_release(struct socket *sock)
204 {
205 int oldstate;
206 struct socket *peersock, *nextsock;
207
208 PRINTK("sock_release: socket 0x%x, inode 0x%x\n", sock,
209 SOCK_INODE(sock));
210 if ((oldstate = sock->state) != SS_UNCONNECTED)
211 sock->state = SS_DISCONNECTING;
212
213
214
215 for (peersock = sock->iconn; peersock; peersock = nextsock) {
216 nextsock = peersock->next;
217 sock_release_peer(peersock);
218 }
219
220
221
222
223 peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
224 if (sock->ops)
225 sock->ops->release(sock, peersock);
226 if (peersock)
227 sock_release_peer(peersock);
228 sock->state = SS_FREE;
229 wake_up(&socket_wait_free);
230 }
231
232 static int
233 sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
234 {
235 PRINTK("sock_lseek: huh?\n");
236 return -EBADF;
237 }
238
239 static int
240 sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
241 {
242 struct socket *sock;
243
244 PRINTK("sock_read: buf=0x%x, size=%d\n", ubuf, size);
245 if (!(sock = socki_lookup(inode))) {
246 printk("sock_read: can't find socket for inode!\n");
247 return -EBADF;
248 }
249 if (sock->flags & SO_ACCEPTCON)
250 return -EINVAL;
251 return sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK));
252 }
253
254 static int
255 sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
256 {
257 struct socket *sock;
258
259 PRINTK("sock_write: buf=0x%x, size=%d\n", ubuf, size);
260 if (!(sock = socki_lookup(inode))) {
261 printk("sock_write: can't find socket for inode!\n");
262 return -EBADF;
263 }
264 if (sock->flags & SO_ACCEPTCON)
265 return -EINVAL;
266 return sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK));
267 }
268
269 static int
270 sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
271 int count)
272 {
273 PRINTK("sock_readdir: huh?\n");
274 return -EBADF;
275 }
276
277 int
278 sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
279 unsigned int arg)
280 {
281 struct socket *sock;
282
283 PRINTK("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg);
284 if (!(sock = socki_lookup(inode))) {
285 printk("sock_ioctl: can't find socket for inode!\n");
286 return -EBADF;
287 }
288 return sock->ops->ioctl(sock, cmd, arg);
289 }
290
291 static int
292 sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
293 {
294 struct socket *sock;
295
296 PRINTK("sock_select: inode = 0x%x, kind = %s\n", inode,
297 (sel_type == SEL_IN) ? "in" :
298 (sel_type == SEL_OUT) ? "out" : "ex");
299 if (!(sock = socki_lookup(inode))) {
300 printk("sock_select: can't find socket for inode!\n");
301 return 0;
302 }
303
304
305
306 if (sock->ops && sock->ops->select)
307 return sock->ops->select(sock, sel_type, wait);
308 return 0;
309 }
310
311 void
312 sock_close(struct inode *inode, struct file *file)
313 {
314 struct socket *sock;
315
316 PRINTK("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count);
317
318
319
320
321 if (!inode)
322 return;
323 if (!(sock = socki_lookup(inode))) {
324 printk("sock_close: can't find socket for inode!\n");
325 return;
326 }
327 sock_release(sock);
328 }
329
330 int
331 sock_awaitconn(struct socket *mysock, struct socket *servsock)
332 {
333 struct socket *last;
334
335 PRINTK("sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
336 mysock, servsock);
337 if (!(servsock->flags & SO_ACCEPTCON)) {
338 PRINTK("sock_awaitconn: server not accepting connections\n");
339 return -EINVAL;
340 }
341
342
343
344
345 mysock->next = NULL;
346 cli();
347 if (!(last = servsock->iconn))
348 servsock->iconn = mysock;
349 else {
350 while (last->next)
351 last = last->next;
352 last->next = mysock;
353 }
354 mysock->state = SS_CONNECTING;
355 mysock->conn = servsock;
356 sti();
357
358
359
360
361
362 wake_up(servsock->wait);
363 if (mysock->state != SS_CONNECTED) {
364 interruptible_sleep_on(mysock->wait);
365 if (mysock->state != SS_CONNECTED) {
366
367
368
369
370
371
372
373 if (mysock->conn == servsock) {
374 cli();
375 if ((last = servsock->iconn) == mysock)
376 servsock->iconn = mysock->next;
377 else {
378 while (last->next != mysock)
379 last = last->next;
380 last->next = mysock->next;
381 }
382 sti();
383 }
384 return mysock->conn ? -EINTR : -EACCES;
385 }
386 }
387 return 0;
388 }
389
390
391
392
393
394 static int
395 sock_socket(int family, int type, int protocol)
396 {
397 int i, fd;
398 struct socket *sock;
399 struct proto_ops *ops;
400
401 PRINTK("sys_socket: family = %d (%s), type = %d, protocol = %d\n",
402 family, family_name(family), type, protocol);
403
404
405
406
407 for (i = 0; i < NPROTO; ++i)
408 if (proto_table[i].family == family)
409 break;
410 if (i == NPROTO) {
411 PRINTK("sys_socket: family not found\n");
412 return -EINVAL;
413 }
414 ops = proto_table[i].ops;
415
416
417
418
419
420
421 if ((type != SOCK_STREAM &&
422 type != SOCK_DGRAM &&
423 type != SOCK_SEQPACKET &&
424 type != SOCK_RAW) ||
425 protocol < 0)
426 return -EINVAL;
427
428
429
430
431
432
433 if (!(sock = sock_alloc(1))) {
434 printk("sys_socket: no more sockets\n");
435 return -EAGAIN;
436 }
437 sock->type = type;
438 sock->ops = ops;
439 if ((i = sock->ops->create(sock, protocol)) < 0) {
440 sock_release(sock);
441 return i;
442 }
443
444 if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
445 sock_release(sock);
446 return -EINVAL;
447 }
448
449 return fd;
450 }
451
452 static int
453 sock_socketpair(int family, int type, int protocol, int usockvec[2])
454 {
455 int fd1, fd2, i;
456 struct socket *sock1, *sock2;
457
458 PRINTK("sys_socketpair: family = %d, type = %d, protocol = %d\n",
459 family, type, protocol);
460
461
462
463
464
465 if ((fd1 = sock_socket(family, type, protocol)) < 0)
466 return fd1;
467 sock1 = sockfd_lookup(fd1, NULL);
468 if (!sock1->ops->socketpair) {
469 sys_close(fd1);
470 return -EINVAL;
471 }
472
473
474
475
476 if ((fd2 = sock_socket(family, type, protocol)) < 0) {
477 sys_close(fd1);
478 return -EINVAL;
479 }
480 sock2 = sockfd_lookup(fd2, NULL);
481 if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
482 sys_close(fd1);
483 sys_close(fd2);
484 return i;
485 }
486 sock1->conn = sock2;
487 sock2->conn = sock1;
488 sock1->state = SS_CONNECTED;
489 sock2->state = SS_CONNECTED;
490
491 verify_area(usockvec, 2 * sizeof(int));
492 put_fs_long(fd1, &usockvec[0]);
493 put_fs_long(fd2, &usockvec[1]);
494
495 return 0;
496 }
497
498
499
500
501
502 static int
503 sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
504 {
505 struct socket *sock;
506 int i;
507
508 PRINTK("sys_bind: fd = %d\n", fd);
509 if (!(sock = sockfd_lookup(fd, NULL)))
510 return -EBADF;
511 if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) {
512 PRINTK("sys_bind: bind failed\n");
513 return i;
514 }
515 return 0;
516 }
517
518
519
520
521
522
523 static int
524 sock_listen(int fd, int backlog)
525 {
526 struct socket *sock;
527
528 PRINTK("sys_listen: fd = %d\n", fd);
529 if (!(sock = sockfd_lookup(fd, NULL)))
530 return -EBADF;
531 if (sock->state != SS_UNCONNECTED) {
532 PRINTK("sys_listen: socket isn't unconnected\n");
533 return -EINVAL;
534 }
535 if (sock->flags & SO_ACCEPTCON) {
536 PRINTK("sys_listen: socket already accepting connections!\n");
537 return -EINVAL;
538 }
539 if (sock->ops && sock->ops->listen)
540 sock->ops->listen (sock, backlog);
541 sock->flags |= SO_ACCEPTCON;
542 return 0;
543 }
544
545
546
547
548
549 static int
550 sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
551 {
552 struct file *file;
553 struct socket *sock, *newsock;
554 int i;
555
556 PRINTK("sys_accept: fd = %d\n", fd);
557 if (!(sock = sockfd_lookup(fd, &file)))
558 return -EBADF;
559 if (sock->state != SS_UNCONNECTED) {
560 PRINTK("sys_accept: socket isn't unconnected\n");
561 return -EINVAL;
562 }
563 if (!(sock->flags & SO_ACCEPTCON)) {
564 PRINTK("sys_accept: socket not accepting connections!\n");
565 return -EINVAL;
566 }
567
568 if (!(newsock = sock_alloc(0))) {
569 printk("sys_accept: no more sockets\n");
570 return -EAGAIN;
571 }
572 newsock->type = sock->type;
573 newsock->ops = sock->ops;
574 if ((i = sock->ops->dup(newsock, sock)) < 0) {
575 sock_release(newsock);
576 return i;
577 }
578
579 if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
580 sock_release(newsock);
581 return -EINVAL;
582 }
583 i = newsock->ops->accept(sock, newsock, file->f_flags);
584
585 if ( i < 0)
586 {
587 sys_close (fd);
588 return (i);
589 }
590
591 PRINTK("sys_accept: connected socket 0x%x via 0x%x\n",
592 sock, newsock);
593
594 if (upeer_sockaddr)
595 newsock->ops->getname(newsock, upeer_sockaddr,
596 upeer_addrlen, 1);
597
598 return fd;
599 }
600
601
602
603
604 static int
605 sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
606 {
607 struct socket *sock;
608 struct file *file;
609 int i;
610
611 PRINTK("sys_connect: fd = %d\n", fd);
612 if (!(sock = sockfd_lookup(fd, &file)))
613 return -EBADF;
614 if (sock->state != SS_UNCONNECTED) {
615 PRINTK("sys_connect: socket not unconnected\n");
616 return -EINVAL;
617 }
618 i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
619 if (i < 0) {
620 PRINTK("sys_connect: connect failed\n");
621 return i;
622 }
623 return 0;
624 }
625
626 static int
627 sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
628 {
629 struct socket *sock;
630
631 PRINTK("sys_getsockname: fd = %d\n", fd);
632 if (!(sock = sockfd_lookup(fd, NULL)))
633 return -EBADF;
634 return sock->ops->getname(sock, usockaddr, usockaddr_len, 0);
635 }
636
637 static int
638 sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
639 {
640 struct socket *sock;
641
642 PRINTK("sys_getpeername: fd = %d\n", fd);
643 if (!(sock = sockfd_lookup(fd, NULL)))
644 return -EBADF;
645 return sock->ops->getname(sock, usockaddr, usockaddr_len, 1);
646 }
647
648
649
650
651 static int
652 sys_send( int fd, void * buff, int len, unsigned flags)
653 {
654 struct socket *sock;
655 struct file *file;
656
657 PRINTK("sys_send (fd = %d, buff = %X, len = %d, flags = %X)\n",
658 fd, buff, len, flags);
659
660 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
661 return (-EBADF);
662
663 if (!(sock = sockfd_lookup(fd, NULL)))
664 return (-ENOTSOCK);
665
666 return (sock->ops->send (sock, buff, len, (file->f_flags & O_NONBLOCK),
667 flags));
668
669 }
670
671 static int
672 sys_sendto( int fd, void * buff, int len, unsigned flags,
673 struct sockaddr *addr, int addr_len)
674 {
675 struct socket *sock;
676 struct file *file;
677
678 PRINTK("sys_sendto (fd = %d, buff = %X, len = %d, flags = %X,"
679 " addr=%X, alen = %d\n", fd, buff, len, flags, addr, addr_len);
680
681 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
682 return (-EBADF);
683
684 if (!(sock = sockfd_lookup(fd, NULL)))
685 return (-ENOTSOCK);
686
687 return (sock->ops->sendto (sock, buff, len,
688 (file->f_flags & O_NONBLOCK),
689 flags, addr, addr_len));
690
691 }
692
693
694 static int
695 sys_recv( int fd, void * buff, int len, unsigned flags)
696 {
697 struct socket *sock;
698 struct file *file;
699
700 PRINTK("sys_recv (fd = %d, buff = %X, len = %d, flags = %X)\n",
701 fd, buff, len, flags);
702
703 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
704 return (-EBADF);
705
706 if (!(sock = sockfd_lookup(fd, NULL)))
707 return (-ENOTSOCK);
708
709 return (sock->ops->recv (sock, buff, len,(file->f_flags & O_NONBLOCK),
710 flags));
711
712 }
713
714 static int
715 sys_recvfrom( int fd, void * buff, int len, unsigned flags,
716 struct sockaddr *addr, int *addr_len)
717 {
718 struct socket *sock;
719 struct file *file;
720
721 PRINTK("sys_recvfrom (fd = %d, buff = %X, len = %d, flags = %X,"
722 " addr=%X, alen=%X\n", fd, buff, len, flags, addr, addr_len);
723
724 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
725 return (-EBADF);
726
727 if (!(sock = sockfd_lookup(fd, NULL)))
728 return (-ENOTSOCK);
729
730 return (sock->ops->recvfrom (sock, buff, len,
731 (file->f_flags & O_NONBLOCK),
732 flags, addr, addr_len));
733
734 }
735
736
737 static int
738 sys_setsockopt (int fd, int level, int optname, char *optval, int optlen)
739 {
740 struct socket *sock;
741 struct file *file;
742
743 PRINTK ("sys_setsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
744 optname);
745 PRINTK (" optval = %X, optlen = %d)\n", optval, optlen);
746
747 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
748 return (-EBADF);
749
750 if (!(sock = sockfd_lookup(fd, NULL)))
751 return (-ENOTSOCK);
752
753 return (sock->ops->setsockopt (sock, level, optname, optval, optlen));
754
755 }
756
757 static int
758 sys_getsockopt (int fd, int level, int optname, char *optval, int *optlen)
759 {
760 struct socket *sock;
761 struct file *file;
762 PRINTK ("sys_getsockopt(fd=%d, level=%d, optname=%d,\n",fd, level,
763 optname);
764 PRINTK (" optval = %X, optlen = %X)\n", optval, optlen);
765
766 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
767 return (-EBADF);
768
769 if (!(sock = sockfd_lookup(fd, NULL)))
770 return (-ENOTSOCK);
771
772 return (0);
773 return (sock->ops->getsockopt (sock, level, optname, optval, optlen));
774
775 }
776
777
778 static int
779 sys_shutdown( int fd, int how)
780 {
781 struct socket *sock;
782 struct file *file;
783
784 PRINTK("sys_shutdown (fd = %d, how = %d)\n",fd, how);
785
786 file = current->filp[fd];
787 if (fd < 0 || fd >= NR_OPEN || file == NULL)
788 return (-EBADF);
789
790 if (!(sock = sockfd_lookup(fd, NULL)))
791 return (-ENOTSOCK);
792
793 return (sock->ops->shutdown (sock, how));
794
795 }
796
797 int
798 sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
799 {
800 struct socket *sock;
801 sock = socki_lookup (filp->f_inode);
802
803 if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
804 return (sock->ops->fcntl (sock, cmd, arg));
805
806 return (-EINVAL);
807 }
808
809
810
811
812
813
814
815 int
816 sys_socketcall(int call, unsigned long *args)
817 {
818 switch (call) {
819 case SYS_SOCKET:
820 verify_area(args, 3 * sizeof(long));
821 return sock_socket(get_fs_long(args+0),
822 get_fs_long(args+1),
823 get_fs_long(args+2));
824
825 case SYS_BIND:
826 verify_area(args, 3 * sizeof(long));
827 return sock_bind(get_fs_long(args+0),
828 (struct sockaddr *)get_fs_long(args+1),
829 get_fs_long(args+2));
830
831 case SYS_CONNECT:
832 verify_area(args, 3 * sizeof(long));
833 return sock_connect(get_fs_long(args+0),
834 (struct sockaddr *)get_fs_long(args+1),
835 get_fs_long(args+2));
836
837 case SYS_LISTEN:
838 verify_area(args, 2 * sizeof(long));
839 return sock_listen(get_fs_long(args+0),
840 get_fs_long(args+1));
841
842 case SYS_ACCEPT:
843 verify_area(args, 3 * sizeof(long));
844 return sock_accept(get_fs_long(args+0),
845 (struct sockaddr *)get_fs_long(args+1),
846 (int *)get_fs_long(args+2));
847
848 case SYS_GETSOCKNAME:
849 verify_area(args, 3 * sizeof(long));
850 return sock_getsockname(get_fs_long(args+0),
851 (struct sockaddr *)get_fs_long(args+1),
852 (int *)get_fs_long(args+2));
853
854 case SYS_GETPEERNAME:
855 verify_area(args, 3 * sizeof(long));
856 return sock_getpeername(get_fs_long(args+0),
857 (struct sockaddr *)get_fs_long(args+1),
858 (int *)get_fs_long(args+2));
859
860 case SYS_SOCKETPAIR:
861 verify_area(args, 4 * sizeof(long));
862 return sock_socketpair(get_fs_long(args+0),
863 get_fs_long(args+1),
864 get_fs_long(args+2),
865 (int *)get_fs_long(args+3));
866
867 case SYS_SEND:
868 verify_area(args, 4 * sizeof (unsigned long));
869 return ( sys_send (get_fs_long(args+0),
870 (void *)get_fs_long(args+1),
871 get_fs_long(args+2),
872 get_fs_long(args+3)));
873
874 case SYS_SENDTO:
875 verify_area(args, 6 * sizeof (unsigned long));
876 return ( sys_sendto (get_fs_long(args+0),
877 (void *)get_fs_long(args+1),
878 get_fs_long(args+2),
879 get_fs_long(args+3),
880 (struct sockaddr *)get_fs_long(args+4),
881 get_fs_long(args+5)));
882
883
884 case SYS_RECV:
885 verify_area(args, 4 * sizeof (unsigned long));
886 return ( sys_recv (get_fs_long(args+0),
887 (void *)get_fs_long(args+1),
888 get_fs_long(args+2),
889 get_fs_long(args+3)));
890
891 case SYS_RECVFROM:
892 verify_area(args, 6 * sizeof (unsigned long));
893 return ( sys_recvfrom (get_fs_long(args+0),
894 (void *)get_fs_long(args+1),
895 get_fs_long(args+2),
896 get_fs_long(args+3),
897 (struct sockaddr *)get_fs_long(args+4),
898 (int *)get_fs_long(args+5)));
899
900 case SYS_SHUTDOWN:
901 verify_area (args, 2* sizeof (unsigned long));
902 return ( sys_shutdown (get_fs_long (args+0),
903 get_fs_long (args+1)));
904
905 case SYS_SETSOCKOPT:
906 verify_area (args, 5*sizeof (unsigned long));
907 return (sys_setsockopt (get_fs_long (args+0),
908 get_fs_long (args+1),
909 get_fs_long (args+2),
910 (char *)get_fs_long (args+3),
911 get_fs_long (args+4)));
912
913
914 case SYS_GETSOCKOPT:
915 verify_area (args, 5*sizeof (unsigned long));
916 return (sys_getsockopt (get_fs_long (args+0),
917 get_fs_long (args+1),
918 get_fs_long (args+2),
919 (char *)get_fs_long (args+3),
920 (int *)get_fs_long (args+4)));
921
922 default:
923 return -EINVAL;
924 }
925 }
926
927 void
928 sock_init(void)
929 {
930 struct socket *sock;
931 int i, ok;
932
933 for (sock = sockets; sock <= last_socket; ++sock)
934 sock->state = SS_FREE;
935 for (i = ok = 0; i < NPROTO; ++i) {
936 printk("sock_init: initializing family %d (%s)\n",
937 proto_table[i].family, proto_table[i].name);
938 if ((*proto_table[i].ops->init)() < 0) {
939 printk("sock_init: init failed.\n",
940 proto_table[i].family);
941 proto_table[i].family = -1;
942 }
943 else
944 ++ok;
945 }
946 if (!ok)
947 printk("sock_init: warning: no protocols initialized\n");
948 return;
949 }
950