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