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