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