This source file includes following definitions.
- move_addr_to_kernel
- move_addr_to_user
- get_fd
- socki_lookup
- sockfd_lookup
- sock_alloc
- sock_release_peer
- sock_release
- sock_lseek
- sock_read
- sock_write
- sock_ioctl
- sock_select
- sock_close
- sock_fasync
- sock_wake_async
- sock_awaitconn
- sys_socket
- sys_socketpair
- sys_bind
- sys_listen
- sys_accept
- sys_connect
- sys_getsockname
- sys_getpeername
- sys_send
- sys_sendto
- sys_recv
- sys_recvfrom
- sys_setsockopt
- sys_getsockopt
- sys_shutdown
- sock_fcntl
- sys_socketcall
- sock_register
- sock_unregister
- proto_init
- sock_init
- socket_get_info
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #include <linux/config.h>
52 #include <linux/signal.h>
53 #include <linux/errno.h>
54 #include <linux/sched.h>
55 #include <linux/mm.h>
56 #include <linux/kernel.h>
57 #include <linux/major.h>
58 #include <linux/stat.h>
59 #include <linux/socket.h>
60 #include <linux/fcntl.h>
61 #include <linux/net.h>
62 #include <linux/interrupt.h>
63 #include <linux/netdevice.h>
64
65 #include <asm/system.h>
66 #include <asm/segment.h>
67
68 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
69 int whence);
70 static int sock_read(struct inode *inode, struct file *file, char *buf,
71 int size);
72 static int sock_write(struct inode *inode, struct file *file, char *buf,
73 int size);
74
75 static void sock_close(struct inode *inode, struct file *file);
76 static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
77 static int sock_ioctl(struct inode *inode, struct file *file,
78 unsigned int cmd, unsigned long arg);
79 static int sock_fasync(struct inode *inode, struct file *filp, int on);
80
81
82
83
84
85
86
87
88 static struct file_operations socket_file_ops = {
89 sock_lseek,
90 sock_read,
91 sock_write,
92 NULL,
93 sock_select,
94 sock_ioctl,
95 NULL,
96 NULL,
97 sock_close,
98 NULL,
99 sock_fasync
100 };
101
102
103
104
105 static struct proto_ops *pops[NPROTO];
106
107
108
109 static int sockets_in_use = 0;
110
111
112
113
114
115
116 #define MAX_SOCK_ADDR 128
117
118 static int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr)
119 {
120 int err;
121 if(ulen<0||ulen>MAX_SOCK_ADDR)
122 return -EINVAL;
123 if(ulen==0)
124 return 0;
125 if((err=verify_area(VERIFY_READ,uaddr,ulen))<0)
126 return err;
127 memcpy_fromfs(kaddr,uaddr,ulen);
128 return 0;
129 }
130
131 static int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen)
132 {
133 int err;
134 int len;
135
136
137 if((err=verify_area(VERIFY_WRITE,ulen,sizeof(*ulen)))<0)
138 return err;
139 len=get_user(ulen);
140 if(len>klen)
141 len=klen;
142 if(len<0 || len> MAX_SOCK_ADDR)
143 return -EINVAL;
144 if(len)
145 {
146 if((err=verify_area(VERIFY_WRITE,uaddr,len))<0)
147 return err;
148 memcpy_tofs(uaddr,kaddr,len);
149 }
150 put_user(len,ulen);
151 return 0;
152 }
153
154
155
156
157
158 static int get_fd(struct inode *inode)
159 {
160 int fd;
161 struct file *file;
162
163
164
165
166
167 file = get_empty_filp();
168 if (!file)
169 return(-1);
170
171 for (fd = 0; fd < NR_OPEN; ++fd)
172 if (!current->files->fd[fd])
173 break;
174 if (fd == NR_OPEN)
175 {
176 file->f_count = 0;
177 return(-1);
178 }
179
180 FD_CLR(fd, ¤t->files->close_on_exec);
181 current->files->fd[fd] = file;
182 file->f_op = &socket_file_ops;
183 file->f_mode = 3;
184 file->f_flags = O_RDWR;
185 file->f_count = 1;
186 file->f_inode = inode;
187 if (inode)
188 inode->i_count++;
189 file->f_pos = 0;
190 return(fd);
191 }
192
193
194
195
196
197
198
199
200 inline struct socket *socki_lookup(struct inode *inode)
201 {
202 return &inode->u.socket_i;
203 }
204
205
206
207
208
209 static inline struct socket *sockfd_lookup(int fd, struct file **pfile)
210 {
211 struct file *file;
212 struct inode *inode;
213
214 if (fd < 0 || fd >= NR_OPEN || !(file = current->files->fd[fd]))
215 return NULL;
216
217 inode = file->f_inode;
218 if (!inode || !inode->i_sock)
219 return NULL;
220
221 if (pfile)
222 *pfile = file;
223
224 return socki_lookup(inode);
225 }
226
227
228
229
230
231 struct socket *sock_alloc(void)
232 {
233 struct inode * inode;
234 struct socket * sock;
235
236 inode = get_empty_inode();
237 if (!inode)
238 return NULL;
239
240 inode->i_mode = S_IFSOCK;
241 inode->i_sock = 1;
242 inode->i_uid = current->uid;
243 inode->i_gid = current->gid;
244
245 sock = &inode->u.socket_i;
246 sock->state = SS_UNCONNECTED;
247 sock->flags = 0;
248 sock->ops = NULL;
249 sock->data = NULL;
250 sock->conn = NULL;
251 sock->iconn = NULL;
252 sock->next = NULL;
253 sock->wait = &inode->i_wait;
254 sock->inode = inode;
255 sock->fasync_list = NULL;
256 sockets_in_use++;
257 return sock;
258 }
259
260
261
262
263
264 static inline void sock_release_peer(struct socket *peer)
265 {
266 peer->state = SS_DISCONNECTING;
267 wake_up_interruptible(peer->wait);
268 sock_wake_async(peer, 1);
269 }
270
271 void sock_release(struct socket *sock)
272 {
273 int oldstate;
274 struct socket *peersock, *nextsock;
275
276 if ((oldstate = sock->state) != SS_UNCONNECTED)
277 sock->state = SS_DISCONNECTING;
278
279
280
281
282
283 for (peersock = sock->iconn; peersock; peersock = nextsock)
284 {
285 nextsock = peersock->next;
286 sock_release_peer(peersock);
287 }
288
289
290
291
292
293
294 peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
295 if (sock->ops)
296 sock->ops->release(sock, peersock);
297 if (peersock)
298 sock_release_peer(peersock);
299 --sockets_in_use;
300 iput(SOCK_INODE(sock));
301 }
302
303
304
305
306
307 static int sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
308 {
309 return(-ESPIPE);
310 }
311
312
313
314
315
316
317 static int sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
318 {
319 struct socket *sock;
320 int err;
321
322 sock = socki_lookup(inode);
323 if (sock->flags & SO_ACCEPTCON)
324 return(-EINVAL);
325
326 if(size<0)
327 return -EINVAL;
328 if(size==0)
329 return 0;
330 if ((err=verify_area(VERIFY_WRITE,ubuf,size))<0)
331 return err;
332 return(sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK)));
333 }
334
335
336
337
338
339
340 static int sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
341 {
342 struct socket *sock;
343 int err;
344
345 sock = socki_lookup(inode);
346
347 if (sock->flags & SO_ACCEPTCON)
348 return(-EINVAL);
349
350 if(size<0)
351 return -EINVAL;
352 if(size==0)
353 return 0;
354
355 if ((err=verify_area(VERIFY_READ,ubuf,size))<0)
356 return err;
357 return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
358 }
359
360
361
362
363
364
365 int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
366 unsigned long arg)
367 {
368 struct socket *sock;
369 sock = socki_lookup(inode);
370 return(sock->ops->ioctl(sock, cmd, arg));
371 }
372
373
374 static int sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
375 {
376 struct socket *sock;
377
378 sock = socki_lookup(inode);
379
380
381
382
383
384 if (sock->ops->select)
385 return(sock->ops->select(sock, sel_type, wait));
386 return(0);
387 }
388
389
390 void sock_close(struct inode *inode, struct file *filp)
391 {
392
393
394
395
396 if (!inode)
397 return;
398 sock_fasync(inode, filp, 0);
399 sock_release(socki_lookup(inode));
400 }
401
402
403
404
405
406 static int sock_fasync(struct inode *inode, struct file *filp, int on)
407 {
408 struct fasync_struct *fa, *fna=NULL, **prev;
409 struct socket *sock;
410 unsigned long flags;
411
412 if (on)
413 {
414 fna=(struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
415 if(fna==NULL)
416 return -ENOMEM;
417 }
418
419 sock = socki_lookup(inode);
420
421 prev=&(sock->fasync_list);
422
423 save_flags(flags);
424 cli();
425
426 for(fa=*prev; fa!=NULL; prev=&fa->fa_next,fa=*prev)
427 if(fa->fa_file==filp)
428 break;
429
430 if(on)
431 {
432 if(fa!=NULL)
433 {
434 kfree_s(fna,sizeof(struct fasync_struct));
435 restore_flags(flags);
436 return 0;
437 }
438 fna->fa_file=filp;
439 fna->magic=FASYNC_MAGIC;
440 fna->fa_next=sock->fasync_list;
441 sock->fasync_list=fna;
442 }
443 else
444 {
445 if(fa!=NULL)
446 {
447 *prev=fa->fa_next;
448 kfree_s(fa,sizeof(struct fasync_struct));
449 }
450 }
451 restore_flags(flags);
452 return 0;
453 }
454
455 int sock_wake_async(struct socket *sock, int how)
456 {
457 if (!sock || !sock->fasync_list)
458 return -1;
459 switch (how)
460 {
461 case 0:
462 kill_fasync(sock->fasync_list, SIGIO);
463 break;
464 case 1:
465 if (!(sock->flags & SO_WAITDATA))
466 kill_fasync(sock->fasync_list, SIGIO);
467 break;
468 case 2:
469 if (sock->flags & SO_NOSPACE)
470 {
471 kill_fasync(sock->fasync_list, SIGIO);
472 sock->flags &= ~SO_NOSPACE;
473 }
474 break;
475 }
476 return 0;
477 }
478
479
480
481
482
483
484 int sock_awaitconn(struct socket *mysock, struct socket *servsock, int flags)
485 {
486 struct socket *last;
487
488
489
490
491 if (!(servsock->flags & SO_ACCEPTCON))
492 {
493 return(-EINVAL);
494 }
495
496
497
498
499
500 mysock->next = NULL;
501 cli();
502 if (!(last = servsock->iconn))
503 servsock->iconn = mysock;
504 else
505 {
506 while (last->next)
507 last = last->next;
508 last->next = mysock;
509 }
510 mysock->state = SS_CONNECTING;
511 mysock->conn = servsock;
512 sti();
513
514
515
516
517
518 wake_up_interruptible(servsock->wait);
519 sock_wake_async(servsock, 0);
520
521 if (mysock->state != SS_CONNECTED)
522 {
523 if (flags & O_NONBLOCK)
524 return -EINPROGRESS;
525
526 interruptible_sleep_on(mysock->wait);
527 if (mysock->state != SS_CONNECTED &&
528 mysock->state != SS_DISCONNECTING)
529 {
530
531
532
533
534
535
536
537 if (mysock->conn == servsock)
538 {
539 cli();
540 if ((last = servsock->iconn) == mysock)
541 servsock->iconn = mysock->next;
542 else
543 {
544 while (last->next != mysock)
545 last = last->next;
546 last->next = mysock->next;
547 }
548 sti();
549 }
550 return(mysock->conn ? -EINTR : -EACCES);
551 }
552 }
553 return(0);
554 }
555
556
557
558
559
560
561
562 asmlinkage int sys_socket(int family, int type, int protocol)
563 {
564 int i, fd;
565 struct socket *sock;
566 struct proto_ops *ops;
567
568
569 for (i = 0; i < NPROTO; ++i)
570 {
571 if (pops[i] == NULL) continue;
572 if (pops[i]->family == family)
573 break;
574 }
575
576 if (i == NPROTO)
577 {
578 return -EINVAL;
579 }
580
581 ops = pops[i];
582
583
584
585
586
587
588
589 if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
590 type != SOCK_SEQPACKET && type != SOCK_RAW &&
591 type != SOCK_PACKET) || protocol < 0)
592 return(-EINVAL);
593
594
595
596
597
598
599
600 if (!(sock = sock_alloc()))
601 {
602 printk("NET: sys_socket: no more sockets\n");
603 return(-ENOSR);
604
605 }
606
607 sock->type = type;
608 sock->ops = ops;
609 if ((i = sock->ops->create(sock, protocol)) < 0)
610 {
611 sock_release(sock);
612 return(i);
613 }
614
615 if ((fd = get_fd(SOCK_INODE(sock))) < 0)
616 {
617 sock_release(sock);
618 return(-EINVAL);
619 }
620
621 return(fd);
622 }
623
624
625
626
627
628 asmlinkage int sys_socketpair(int family, int type, int protocol, int usockvec[2])
629 {
630 int fd1, fd2, i;
631 struct socket *sock1, *sock2;
632 int er;
633
634
635
636
637
638
639 if ((fd1 = sys_socket(family, type, protocol)) < 0)
640 return(fd1);
641 sock1 = sockfd_lookup(fd1, NULL);
642 if (!sock1->ops->socketpair)
643 {
644 sys_close(fd1);
645 return(-EINVAL);
646 }
647
648
649
650
651
652 if ((fd2 = sys_socket(family, type, protocol)) < 0)
653 {
654 sys_close(fd1);
655 return(-EINVAL);
656 }
657
658 sock2 = sockfd_lookup(fd2, NULL);
659 if ((i = sock1->ops->socketpair(sock1, sock2)) < 0)
660 {
661 sys_close(fd1);
662 sys_close(fd2);
663 return(i);
664 }
665
666 sock1->conn = sock2;
667 sock2->conn = sock1;
668 sock1->state = SS_CONNECTED;
669 sock2->state = SS_CONNECTED;
670
671 er=verify_area(VERIFY_WRITE, usockvec, sizeof(usockvec));
672 if(er)
673 {
674 sys_close(fd1);
675 sys_close(fd2);
676 return er;
677 }
678 put_user(fd1, &usockvec[0]);
679 put_user(fd2, &usockvec[1]);
680
681 return(0);
682 }
683
684
685
686
687
688
689
690
691
692
693 asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen)
694 {
695 struct socket *sock;
696 int i;
697 char address[MAX_SOCK_ADDR];
698 int err;
699
700 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
701 return(-EBADF);
702
703 if (!(sock = sockfd_lookup(fd, NULL)))
704 return(-ENOTSOCK);
705
706 if((err=move_addr_to_kernel(umyaddr,addrlen,address))<0)
707 return err;
708
709 if ((i = sock->ops->bind(sock, (struct sockaddr *)address, addrlen)) < 0)
710 {
711 return(i);
712 }
713 return(0);
714 }
715
716
717
718
719
720
721
722
723 asmlinkage int sys_listen(int fd, int backlog)
724 {
725 struct socket *sock;
726
727 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
728 return(-EBADF);
729 if (!(sock = sockfd_lookup(fd, NULL)))
730 return(-ENOTSOCK);
731
732 if (sock->state != SS_UNCONNECTED)
733 {
734 return(-EINVAL);
735 }
736
737 if (sock->ops && sock->ops->listen)
738 sock->ops->listen(sock, backlog);
739 sock->flags |= SO_ACCEPTCON;
740 return(0);
741 }
742
743
744
745
746
747
748
749
750
751
752 asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
753 {
754 struct file *file;
755 struct socket *sock, *newsock;
756 int i;
757 char address[MAX_SOCK_ADDR];
758 int len;
759
760 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
761 return(-EBADF);
762 if (!(sock = sockfd_lookup(fd, &file)))
763 return(-ENOTSOCK);
764 if (sock->state != SS_UNCONNECTED)
765 {
766 return(-EINVAL);
767 }
768 if (!(sock->flags & SO_ACCEPTCON))
769 {
770 return(-EINVAL);
771 }
772
773 if (!(newsock = sock_alloc()))
774 {
775 printk("NET: sock_accept: no more sockets\n");
776 return(-ENOSR);
777
778 }
779 newsock->type = sock->type;
780 newsock->ops = sock->ops;
781 if ((i = sock->ops->dup(newsock, sock)) < 0)
782 {
783 sock_release(newsock);
784 return(i);
785 }
786
787 i = newsock->ops->accept(sock, newsock, file->f_flags);
788 if ( i < 0)
789 {
790 sock_release(newsock);
791 return(i);
792 }
793
794 if ((fd = get_fd(SOCK_INODE(newsock))) < 0)
795 {
796 sock_release(newsock);
797 return(-EINVAL);
798 }
799
800 if (upeer_sockaddr)
801 {
802 newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1);
803 move_addr_to_user(address,len, upeer_sockaddr, upeer_addrlen);
804 }
805 return(fd);
806 }
807
808
809
810
811
812
813
814 asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen)
815 {
816 struct socket *sock;
817 struct file *file;
818 int i;
819 char address[MAX_SOCK_ADDR];
820 int err;
821
822 if (fd < 0 || fd >= NR_OPEN || (file=current->files->fd[fd]) == NULL)
823 return(-EBADF);
824 if (!(sock = sockfd_lookup(fd, &file)))
825 return(-ENOTSOCK);
826
827 if((err=move_addr_to_kernel(uservaddr,addrlen,address))<0)
828 return err;
829
830 switch(sock->state)
831 {
832 case SS_UNCONNECTED:
833
834 break;
835 case SS_CONNECTED:
836
837 if(sock->type == SOCK_DGRAM)
838 break;
839 return -EISCONN;
840 case SS_CONNECTING:
841
842
843
844
845
846
847
848 break;
849 default:
850 return(-EINVAL);
851 }
852 i = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, file->f_flags);
853 if (i < 0)
854 {
855 return(i);
856 }
857 return(0);
858 }
859
860
861
862
863
864
865 asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
866 {
867 struct socket *sock;
868 char address[MAX_SOCK_ADDR];
869 int len;
870 int err;
871
872 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
873 return(-EBADF);
874 if (!(sock = sockfd_lookup(fd, NULL)))
875 return(-ENOTSOCK);
876
877 err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
878 if(err)
879 return err;
880 if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))<0)
881 return err;
882 return 0;
883 }
884
885
886
887
888
889
890 asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
891 {
892 struct socket *sock;
893 char address[MAX_SOCK_ADDR];
894 int len;
895 int err;
896
897 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
898 return(-EBADF);
899 if (!(sock = sockfd_lookup(fd, NULL)))
900 return(-ENOTSOCK);
901
902 err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
903 if(err)
904 return err;
905 if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))<0)
906 return err;
907 return 0;
908 }
909
910
911
912
913
914
915 asmlinkage int sys_send(int fd, void * buff, int len, unsigned flags)
916 {
917 struct socket *sock;
918 struct file *file;
919 int err;
920
921 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
922 return(-EBADF);
923 if (!(sock = sockfd_lookup(fd, NULL)))
924 return(-ENOTSOCK);
925
926 if(len<0)
927 return -EINVAL;
928 err=verify_area(VERIFY_READ, buff, len);
929 if(err)
930 return err;
931 return(sock->ops->send(sock, buff, len, (file->f_flags & O_NONBLOCK), flags));
932 }
933
934
935
936
937
938
939
940 asmlinkage int sys_sendto(int fd, void * buff, int len, unsigned flags,
941 struct sockaddr *addr, int addr_len)
942 {
943 struct socket *sock;
944 struct file *file;
945 char address[MAX_SOCK_ADDR];
946 int err;
947
948 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
949 return(-EBADF);
950 if (!(sock = sockfd_lookup(fd, NULL)))
951 return(-ENOTSOCK);
952
953 if(len<0)
954 return -EINVAL;
955 err=verify_area(VERIFY_READ,buff,len);
956 if(err)
957 return err;
958
959 if((err=move_addr_to_kernel(addr,addr_len,address))<0)
960 return err;
961
962 return(sock->ops->sendto(sock, buff, len, (file->f_flags & O_NONBLOCK),
963 flags, (struct sockaddr *)address, addr_len));
964 }
965
966
967
968
969
970
971
972
973
974
975 asmlinkage int sys_recv(int fd, void * buff, int len, unsigned flags)
976 {
977 struct socket *sock;
978 struct file *file;
979 int err;
980
981 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
982 return(-EBADF);
983
984 if (!(sock = sockfd_lookup(fd, NULL)))
985 return(-ENOTSOCK);
986
987 if(len<0)
988 return -EINVAL;
989 if(len==0)
990 return 0;
991 err=verify_area(VERIFY_WRITE, buff, len);
992 if(err)
993 return err;
994
995 return(sock->ops->recv(sock, buff, len,(file->f_flags & O_NONBLOCK), flags));
996 }
997
998
999
1000
1001
1002
1003
1004 asmlinkage int sys_recvfrom(int fd, void * buff, int len, unsigned flags,
1005 struct sockaddr *addr, int *addr_len)
1006 {
1007 struct socket *sock;
1008 struct file *file;
1009 char address[MAX_SOCK_ADDR];
1010 int err;
1011 int alen;
1012 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1013 return(-EBADF);
1014 if (!(sock = sockfd_lookup(fd, NULL)))
1015 return(-ENOTSOCK);
1016 if(len<0)
1017 return -EINVAL;
1018 if(len==0)
1019 return 0;
1020
1021 err=verify_area(VERIFY_WRITE,buff,len);
1022 if(err)
1023 return err;
1024
1025 len=sock->ops->recvfrom(sock, buff, len, (file->f_flags & O_NONBLOCK),
1026 flags, (struct sockaddr *)address, &alen);
1027
1028 if(len<0)
1029 return len;
1030 if(addr!=NULL && (err=move_addr_to_user(address,alen, addr, addr_len))<0)
1031 return err;
1032
1033 return len;
1034 }
1035
1036
1037
1038
1039
1040
1041 asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen)
1042 {
1043 struct socket *sock;
1044 struct file *file;
1045
1046 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1047 return(-EBADF);
1048 if (!(sock = sockfd_lookup(fd, NULL)))
1049 return(-ENOTSOCK);
1050
1051 return(sock->ops->setsockopt(sock, level, optname, optval, optlen));
1052 }
1053
1054
1055
1056
1057
1058
1059 asmlinkage int sys_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
1060 {
1061 struct socket *sock;
1062 struct file *file;
1063
1064 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1065 return(-EBADF);
1066 if (!(sock = sockfd_lookup(fd, NULL)))
1067 return(-ENOTSOCK);
1068
1069 if (!sock->ops->getsockopt)
1070 return(0);
1071 return(sock->ops->getsockopt(sock, level, optname, optval, optlen));
1072 }
1073
1074
1075
1076
1077
1078
1079 asmlinkage int sys_shutdown(int fd, int how)
1080 {
1081 struct socket *sock;
1082 struct file *file;
1083
1084 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1085 return(-EBADF);
1086 if (!(sock = sockfd_lookup(fd, NULL)))
1087 return(-ENOTSOCK);
1088
1089 return(sock->ops->shutdown(sock, how));
1090 }
1091
1092
1093
1094
1095
1096
1097 int sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
1098 {
1099 struct socket *sock;
1100
1101 sock = socki_lookup (filp->f_inode);
1102 if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
1103 return(sock->ops->fcntl(sock, cmd, arg));
1104 return(-EINVAL);
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 asmlinkage int sys_socketcall(int call, unsigned long *args)
1121 {
1122 int er;
1123 unsigned char nargs[16]={0,3,3,3,2,3,3,3,
1124 4,4,4,6,6,2,5,5};
1125
1126 unsigned long a0,a1;
1127
1128 if(call<1||call>SYS_GETSOCKOPT)
1129 return -EINVAL;
1130
1131 er=verify_area(VERIFY_READ, args, nargs[call] * sizeof(unsigned long));
1132 if(er)
1133 return er;
1134
1135 a0=get_user(args);
1136 a1=get_user(args+1);
1137
1138
1139 switch(call)
1140 {
1141 case SYS_SOCKET:
1142 return(sys_socket(a0,a1,get_user(args+2)));
1143 case SYS_BIND:
1144 return(sys_bind(a0,(struct sockaddr *)a1,
1145 get_user(args+2)));
1146 case SYS_CONNECT:
1147 return(sys_connect(a0, (struct sockaddr *)a1,
1148 get_user(args+2)));
1149 case SYS_LISTEN:
1150 return(sys_listen(a0,a1));
1151 case SYS_ACCEPT:
1152 return(sys_accept(a0,(struct sockaddr *)a1,
1153 (int *)get_user(args+2)));
1154 case SYS_GETSOCKNAME:
1155 return(sys_getsockname(a0,(struct sockaddr *)a1,
1156 (int *)get_user(args+2)));
1157 case SYS_GETPEERNAME:
1158 return(sys_getpeername(a0, (struct sockaddr *)a1,
1159 (int *)get_user(args+2)));
1160 case SYS_SOCKETPAIR:
1161 return(sys_socketpair(a0,a1,
1162 get_user(args+2),
1163 (int *)get_user(args+3)));
1164 case SYS_SEND:
1165 return(sys_send(a0,
1166 (void *)a1,
1167 get_user(args+2),
1168 get_user(args+3)));
1169 case SYS_SENDTO:
1170 return(sys_sendto(a0,(void *)a1,
1171 get_user(args+2),
1172 get_user(args+3),
1173 (struct sockaddr *)get_user(args+4),
1174 get_user(args+5)));
1175 case SYS_RECV:
1176 return(sys_recv(a0,
1177 (void *)a1,
1178 get_user(args+2),
1179 get_user(args+3)));
1180 case SYS_RECVFROM:
1181 return(sys_recvfrom(a0,
1182 (void *)a1,
1183 get_user(args+2),
1184 get_user(args+3),
1185 (struct sockaddr *)get_user(args+4),
1186 (int *)get_user(args+5)));
1187 case SYS_SHUTDOWN:
1188 return(sys_shutdown(a0,a1));
1189 case SYS_SETSOCKOPT:
1190 return(sys_setsockopt(a0,
1191 a1,
1192 get_user(args+2),
1193 (char *)get_user(args+3),
1194 get_user(args+4)));
1195 case SYS_GETSOCKOPT:
1196 return(sys_getsockopt(a0,
1197 a1,
1198 get_user(args+2),
1199 (char *)get_user(args+3),
1200 (int *)get_user(args+4)));
1201 }
1202 return -EINVAL;
1203 }
1204
1205
1206
1207
1208
1209
1210
1211 int sock_register(int family, struct proto_ops *ops)
1212 {
1213 int i;
1214
1215 cli();
1216 for(i = 0; i < NPROTO; i++)
1217 {
1218 if (pops[i] != NULL)
1219 continue;
1220 pops[i] = ops;
1221 pops[i]->family = family;
1222 sti();
1223 return(i);
1224 }
1225 sti();
1226 return(-ENOMEM);
1227 }
1228
1229
1230
1231
1232
1233
1234
1235 int sock_unregister(int family)
1236 {
1237 int i;
1238
1239 cli();
1240 for(i = 0; i < NPROTO; i++)
1241 {
1242 if (pops[i] == NULL)
1243 continue;
1244 if(pops[i]->family == family)
1245 {
1246 pops[i]=NULL;
1247 sti();
1248 return(i);
1249 }
1250 }
1251 sti();
1252 return(-ENOENT);
1253 }
1254
1255 void proto_init(void)
1256 {
1257 extern struct net_proto protocols[];
1258 struct net_proto *pro;
1259
1260
1261 pro = protocols;
1262 while (pro->name != NULL)
1263 {
1264 (*pro->init_func)(pro);
1265 pro++;
1266 }
1267
1268 }
1269
1270
1271 void sock_init(void)
1272 {
1273 int i;
1274
1275 printk("Swansea University Computer Society NET3.030 Snap #1 for Linux 1.3.4\n");
1276
1277
1278
1279
1280
1281 for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
1282
1283
1284
1285
1286
1287 proto_init();
1288
1289 #ifdef CONFIG_NET
1290
1291
1292
1293
1294 dev_init();
1295
1296
1297
1298
1299
1300 bh_base[NET_BH].routine= net_bh;
1301 enable_bh(NET_BH);
1302 #endif
1303 }
1304
1305 int socket_get_info(char *buffer, char **start, off_t offset, int length)
1306 {
1307 int len = sprintf(buffer, "sockets: used %d\n", sockets_in_use);
1308 if (offset >= len)
1309 {
1310 *start = buffer;
1311 return 0;
1312 }
1313 *start = buffer + offset;
1314 len -= offset;
1315 if (len > length)
1316 len = length;
1317 return len;
1318 }