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
- 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 #include <linux/firewall.h>
67
68 #include <net/netlink.h>
69
70 #include <asm/system.h>
71 #include <asm/segment.h>
72
73 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
74 int whence);
75 static int sock_read(struct inode *inode, struct file *file, char *buf,
76 int size);
77 static int sock_write(struct inode *inode, struct file *file, const char *buf,
78 int size);
79
80 static void sock_close(struct inode *inode, struct file *file);
81 static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable);
82 static int sock_ioctl(struct inode *inode, struct file *file,
83 unsigned int cmd, unsigned long arg);
84 static int sock_fasync(struct inode *inode, struct file *filp, int on);
85
86
87
88
89
90
91
92 static struct file_operations socket_file_ops = {
93 sock_lseek,
94 sock_read,
95 sock_write,
96 NULL,
97 sock_select,
98 sock_ioctl,
99 NULL,
100 NULL,
101 sock_close,
102 NULL,
103 sock_fasync
104 };
105
106
107
108
109 static struct proto_ops *pops[NPROTO];
110
111
112
113 static int sockets_in_use = 0;
114
115
116
117
118
119
120 #define MAX_SOCK_ADDR 128
121
122 int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr)
123 {
124 int err;
125 if(ulen<0||ulen>MAX_SOCK_ADDR)
126 return -EINVAL;
127 if(ulen==0)
128 return 0;
129 if((err=verify_area(VERIFY_READ,uaddr,ulen))<0)
130 return err;
131 memcpy_fromfs(kaddr,uaddr,ulen);
132 return 0;
133 }
134
135 int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen)
136 {
137 int err;
138 int len;
139
140
141 if((err=verify_area(VERIFY_WRITE,ulen,sizeof(*ulen)))<0)
142 return err;
143 len=get_user(ulen);
144 if(len>klen)
145 len=klen;
146 if(len<0 || len> MAX_SOCK_ADDR)
147 return -EINVAL;
148 if(len)
149 {
150 if((err=verify_area(VERIFY_WRITE,uaddr,len))<0)
151 return err;
152 memcpy_tofs(uaddr,kaddr,len);
153 }
154 put_user(len,ulen);
155 return 0;
156 }
157
158
159
160
161
162 static int get_fd(struct inode *inode)
163 {
164 int fd;
165 struct file *file;
166
167
168
169
170
171 file = get_empty_filp();
172 if (!file)
173 return(-1);
174
175 for (fd = 0; fd < NR_OPEN; ++fd)
176 if (!current->files->fd[fd])
177 break;
178 if (fd == NR_OPEN)
179 {
180 file->f_count = 0;
181 return(-1);
182 }
183
184 FD_CLR(fd, ¤t->files->close_on_exec);
185 current->files->fd[fd] = file;
186 file->f_op = &socket_file_ops;
187 file->f_mode = 3;
188 file->f_flags = O_RDWR;
189 file->f_count = 1;
190 file->f_inode = inode;
191 if (inode)
192 inode->i_count++;
193 file->f_pos = 0;
194 return(fd);
195 }
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 extern __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
490 asmlinkage int sys_socket(int family, int type, int protocol)
491 {
492 int i, fd;
493 struct socket *sock;
494 struct proto_ops *ops;
495
496
497 for (i = 0; i < NPROTO; ++i)
498 {
499 if (pops[i] == NULL) continue;
500 if (pops[i]->family == family)
501 break;
502 }
503
504 if (i == NPROTO)
505 {
506 return -EINVAL;
507 }
508
509 ops = pops[i];
510
511
512
513
514
515
516
517 if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
518 type != SOCK_SEQPACKET && type != SOCK_RAW &&
519 type != SOCK_PACKET) || protocol < 0)
520 return(-EINVAL);
521
522
523
524
525
526
527
528 if (!(sock = sock_alloc()))
529 {
530 printk("NET: sys_socket: no more sockets\n");
531 return(-ENOSR);
532
533 }
534
535 sock->type = type;
536 sock->ops = ops;
537 if ((i = sock->ops->create(sock, protocol)) < 0)
538 {
539 sock_release(sock);
540 return(i);
541 }
542
543 if ((fd = get_fd(SOCK_INODE(sock))) < 0)
544 {
545 sock_release(sock);
546 return(-EINVAL);
547 }
548
549 return(fd);
550 }
551
552
553
554
555
556 asmlinkage int sys_socketpair(int family, int type, int protocol, int usockvec[2])
557 {
558 int fd1, fd2, i;
559 struct socket *sock1, *sock2;
560 int er;
561
562
563
564
565
566
567 if ((fd1 = sys_socket(family, type, protocol)) < 0)
568 return(fd1);
569 sock1 = sockfd_lookup(fd1, NULL);
570 if (!sock1->ops->socketpair)
571 {
572 sys_close(fd1);
573 return(-EINVAL);
574 }
575
576
577
578
579
580 if ((fd2 = sys_socket(family, type, protocol)) < 0)
581 {
582 sys_close(fd1);
583 return(-EINVAL);
584 }
585
586 sock2 = sockfd_lookup(fd2, NULL);
587 if ((i = sock1->ops->socketpair(sock1, sock2)) < 0)
588 {
589 sys_close(fd1);
590 sys_close(fd2);
591 return(i);
592 }
593
594 sock1->conn = sock2;
595 sock2->conn = sock1;
596 sock1->state = SS_CONNECTED;
597 sock2->state = SS_CONNECTED;
598
599 er=verify_area(VERIFY_WRITE, usockvec, sizeof(usockvec));
600 if(er)
601 {
602 sys_close(fd1);
603 sys_close(fd2);
604 return er;
605 }
606 put_user(fd1, &usockvec[0]);
607 put_user(fd2, &usockvec[1]);
608
609 return(0);
610 }
611
612
613
614
615
616
617
618
619
620
621 asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen)
622 {
623 struct socket *sock;
624 int i;
625 char address[MAX_SOCK_ADDR];
626 int err;
627
628 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
629 return(-EBADF);
630
631 if (!(sock = sockfd_lookup(fd, NULL)))
632 return(-ENOTSOCK);
633
634 if((err=move_addr_to_kernel(umyaddr,addrlen,address))<0)
635 return err;
636
637 if ((i = sock->ops->bind(sock, (struct sockaddr *)address, addrlen)) < 0)
638 {
639 return(i);
640 }
641 return(0);
642 }
643
644
645
646
647
648
649
650
651 asmlinkage int sys_listen(int fd, int backlog)
652 {
653 struct socket *sock;
654
655 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
656 return(-EBADF);
657 if (!(sock = sockfd_lookup(fd, NULL)))
658 return(-ENOTSOCK);
659
660 if (sock->state != SS_UNCONNECTED)
661 {
662 return(-EINVAL);
663 }
664
665 if (sock->ops && sock->ops->listen)
666 sock->ops->listen(sock, backlog);
667 sock->flags |= SO_ACCEPTCON;
668 return(0);
669 }
670
671
672
673
674
675
676
677
678
679
680 asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
681 {
682 struct file *file;
683 struct socket *sock, *newsock;
684 int i;
685 char address[MAX_SOCK_ADDR];
686 int len;
687
688 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
689 return(-EBADF);
690 if (!(sock = sockfd_lookup(fd, &file)))
691 return(-ENOTSOCK);
692 if (sock->state != SS_UNCONNECTED)
693 {
694 return(-EINVAL);
695 }
696 if (!(sock->flags & SO_ACCEPTCON))
697 {
698 return(-EINVAL);
699 }
700
701 if (!(newsock = sock_alloc()))
702 {
703 printk("NET: sock_accept: no more sockets\n");
704 return(-ENOSR);
705
706 }
707 newsock->type = sock->type;
708 newsock->ops = sock->ops;
709 if ((i = sock->ops->dup(newsock, sock)) < 0)
710 {
711 sock_release(newsock);
712 return(i);
713 }
714
715 i = newsock->ops->accept(sock, newsock, file->f_flags);
716 if ( i < 0)
717 {
718 sock_release(newsock);
719 return(i);
720 }
721
722 if ((fd = get_fd(SOCK_INODE(newsock))) < 0)
723 {
724 sock_release(newsock);
725 return(-EINVAL);
726 }
727
728 if (upeer_sockaddr)
729 {
730 newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1);
731 move_addr_to_user(address,len, upeer_sockaddr, upeer_addrlen);
732 }
733 return(fd);
734 }
735
736
737
738
739
740
741
742 asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen)
743 {
744 struct socket *sock;
745 struct file *file;
746 int i;
747 char address[MAX_SOCK_ADDR];
748 int err;
749
750 if (fd < 0 || fd >= NR_OPEN || (file=current->files->fd[fd]) == NULL)
751 return(-EBADF);
752 if (!(sock = sockfd_lookup(fd, &file)))
753 return(-ENOTSOCK);
754
755 if((err=move_addr_to_kernel(uservaddr,addrlen,address))<0)
756 return err;
757
758 switch(sock->state)
759 {
760 case SS_UNCONNECTED:
761
762 break;
763 case SS_CONNECTED:
764
765 if(sock->type == SOCK_DGRAM)
766 break;
767 return -EISCONN;
768 case SS_CONNECTING:
769
770
771
772
773
774
775
776 break;
777 default:
778 return(-EINVAL);
779 }
780 i = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, file->f_flags);
781 if (i < 0)
782 {
783 return(i);
784 }
785 return(0);
786 }
787
788
789
790
791
792
793 asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
794 {
795 struct socket *sock;
796 char address[MAX_SOCK_ADDR];
797 int len;
798 int err;
799
800 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
801 return(-EBADF);
802 if (!(sock = sockfd_lookup(fd, NULL)))
803 return(-ENOTSOCK);
804
805 err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
806 if(err)
807 return err;
808 if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))<0)
809 return err;
810 return 0;
811 }
812
813
814
815
816
817
818 asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
819 {
820 struct socket *sock;
821 char address[MAX_SOCK_ADDR];
822 int len;
823 int err;
824
825 if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
826 return(-EBADF);
827 if (!(sock = sockfd_lookup(fd, NULL)))
828 return(-ENOTSOCK);
829
830 err=sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
831 if(err)
832 return err;
833 if((err=move_addr_to_user(address,len, usockaddr, usockaddr_len))<0)
834 return err;
835 return 0;
836 }
837
838
839
840
841
842
843 asmlinkage int sys_send(int fd, void * buff, int len, unsigned flags)
844 {
845 struct socket *sock;
846 struct file *file;
847 int err;
848
849 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
850 return(-EBADF);
851 if (!(sock = sockfd_lookup(fd, NULL)))
852 return(-ENOTSOCK);
853
854 if(len<0)
855 return -EINVAL;
856 err=verify_area(VERIFY_READ, buff, len);
857 if(err)
858 return err;
859 return(sock->ops->send(sock, buff, len, (file->f_flags & O_NONBLOCK), flags));
860 }
861
862
863
864
865
866
867
868 asmlinkage int sys_sendto(int fd, void * buff, int len, unsigned flags,
869 struct sockaddr *addr, int addr_len)
870 {
871 struct socket *sock;
872 struct file *file;
873 char address[MAX_SOCK_ADDR];
874 int err;
875
876 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
877 return(-EBADF);
878 if (!(sock = sockfd_lookup(fd, NULL)))
879 return(-ENOTSOCK);
880
881 if(len<0)
882 return -EINVAL;
883 err=verify_area(VERIFY_READ,buff,len);
884 if(err)
885 return err;
886
887 if((err=move_addr_to_kernel(addr,addr_len,address))<0)
888 return err;
889
890 return(sock->ops->sendto(sock, buff, len, (file->f_flags & O_NONBLOCK),
891 flags, (struct sockaddr *)address, addr_len));
892 }
893
894
895
896
897
898
899
900
901
902
903 asmlinkage int sys_recv(int fd, void * buff, int len, unsigned flags)
904 {
905 struct socket *sock;
906 struct file *file;
907 int err;
908
909 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
910 return(-EBADF);
911
912 if (!(sock = sockfd_lookup(fd, NULL)))
913 return(-ENOTSOCK);
914
915 if(len<0)
916 return -EINVAL;
917 if(len==0)
918 return 0;
919 err=verify_area(VERIFY_WRITE, buff, len);
920 if(err)
921 return err;
922
923 return(sock->ops->recv(sock, buff, len,(file->f_flags & O_NONBLOCK), flags));
924 }
925
926
927
928
929
930
931
932 asmlinkage int sys_recvfrom(int fd, void * buff, int len, unsigned flags,
933 struct sockaddr *addr, int *addr_len)
934 {
935 struct socket *sock;
936 struct file *file;
937 char address[MAX_SOCK_ADDR];
938 int err;
939 int alen;
940 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
941 return(-EBADF);
942 if (!(sock = sockfd_lookup(fd, NULL)))
943 return(-ENOTSOCK);
944 if(len<0)
945 return -EINVAL;
946 if(len==0)
947 return 0;
948
949 err=verify_area(VERIFY_WRITE,buff,len);
950 if(err)
951 return err;
952
953 len=sock->ops->recvfrom(sock, buff, len, (file->f_flags & O_NONBLOCK),
954 flags, (struct sockaddr *)address, &alen);
955
956 if(len<0)
957 return len;
958 if(addr!=NULL && (err=move_addr_to_user(address,alen, addr, addr_len))<0)
959 return err;
960
961 return len;
962 }
963
964
965
966
967
968
969 asmlinkage int sys_setsockopt(int fd, int level, int optname, char *optval, int optlen)
970 {
971 struct socket *sock;
972 struct file *file;
973
974 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
975 return(-EBADF);
976 if (!(sock = sockfd_lookup(fd, NULL)))
977 return(-ENOTSOCK);
978
979 return(sock->ops->setsockopt(sock, level, optname, optval, optlen));
980 }
981
982
983
984
985
986
987 asmlinkage int sys_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
988 {
989 struct socket *sock;
990 struct file *file;
991
992 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
993 return(-EBADF);
994 if (!(sock = sockfd_lookup(fd, NULL)))
995 return(-ENOTSOCK);
996
997 if (!sock->ops->getsockopt)
998 return(0);
999 return(sock->ops->getsockopt(sock, level, optname, optval, optlen));
1000 }
1001
1002
1003
1004
1005
1006
1007 asmlinkage int sys_shutdown(int fd, int how)
1008 {
1009 struct socket *sock;
1010 struct file *file;
1011
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
1017 return(sock->ops->shutdown(sock, how));
1018 }
1019
1020
1021
1022
1023
1024 asmlinkage int sys_sendmsg(int fd, struct msghdr *msg, unsigned int flags)
1025 {
1026 struct socket *sock;
1027 struct file *file;
1028 char address[MAX_SOCK_ADDR];
1029 struct iovec iov[MAX_IOVEC];
1030 struct msghdr msg_sys;
1031 int err;
1032 int total_len;
1033
1034 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1035 return(-EBADF);
1036 if (!(sock = sockfd_lookup(fd, NULL)))
1037 return(-ENOTSOCK);
1038
1039 err=verify_area(VERIFY_READ, msg,sizeof(struct msghdr));
1040 if(err)
1041 return err;
1042 memcpy_fromfs(&msg_sys,msg,sizeof(struct msghdr));
1043 if(msg_sys.msg_iovlen>MAX_IOVEC)
1044 return -EINVAL;
1045 err=verify_iovec(&msg_sys,iov,address, VERIFY_READ);
1046 if(err<0)
1047 return err;
1048 total_len=err;
1049
1050 if(sock->ops->sendmsg==NULL)
1051 return -EOPNOTSUPP;
1052 return sock->ops->sendmsg(sock, &msg_sys, total_len, (file->f_flags&O_NONBLOCK), flags);
1053 }
1054
1055
1056
1057
1058
1059 asmlinkage int sys_recvmsg(int fd, struct msghdr *msg, unsigned int flags)
1060 {
1061 struct socket *sock;
1062 struct file *file;
1063 char address[MAX_SOCK_ADDR];
1064 struct iovec iov[MAX_IOVEC];
1065 struct msghdr msg_sys;
1066 int err;
1067 int total_len;
1068 int addr_len;
1069 int len;
1070
1071 if (fd < 0 || fd >= NR_OPEN || ((file = current->files->fd[fd]) == NULL))
1072 return(-EBADF);
1073 if (!(sock = sockfd_lookup(fd, NULL)))
1074 return(-ENOTSOCK);
1075
1076 err=verify_area(VERIFY_READ, msg,sizeof(struct msghdr));
1077 if(err)
1078 return err;
1079 memcpy_fromfs(&msg_sys,msg,sizeof(struct msghdr));
1080 if(msg_sys.msg_iovlen>MAX_IOVEC)
1081 return -EINVAL;
1082 err=verify_iovec(&msg_sys,iov,address, VERIFY_WRITE);
1083 if(err<0)
1084 return err;
1085 total_len=err;
1086
1087 if(sock->ops->recvmsg==NULL)
1088 return -EOPNOTSUPP;
1089 len=sock->ops->recvmsg(sock, &msg_sys, total_len, (file->f_flags&O_NONBLOCK), flags, &addr_len);
1090 if(len<0)
1091 return len;
1092
1093
1094
1095 if(msg_sys.msg_name!=NULL && (err=move_addr_to_user(address,addr_len, msg_sys.msg_name, &msg_sys.msg_namelen))<0)
1096 return err;
1097 return len;
1098 }
1099
1100
1101
1102
1103
1104
1105 int sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
1106 {
1107 struct socket *sock;
1108
1109 sock = socki_lookup (filp->f_inode);
1110 if (sock != NULL && sock->ops != NULL && sock->ops->fcntl != NULL)
1111 return(sock->ops->fcntl(sock, cmd, arg));
1112 return(-EINVAL);
1113 }
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128 asmlinkage int sys_socketcall(int call, unsigned long *args)
1129 {
1130 int er;
1131 unsigned char nargs[18]={0,3,3,3,2,3,3,3,
1132 4,4,4,6,6,2,5,5,3,3};
1133
1134 unsigned long a0,a1;
1135
1136 if(call<1||call>SYS_RECVMSG)
1137 return -EINVAL;
1138
1139 er=verify_area(VERIFY_READ, args, nargs[call] * sizeof(unsigned long));
1140 if(er)
1141 return er;
1142
1143 a0=get_user(args);
1144 a1=get_user(args+1);
1145
1146
1147 switch(call)
1148 {
1149 case SYS_SOCKET:
1150 return(sys_socket(a0,a1,get_user(args+2)));
1151 case SYS_BIND:
1152 return(sys_bind(a0,(struct sockaddr *)a1,
1153 get_user(args+2)));
1154 case SYS_CONNECT:
1155 return(sys_connect(a0, (struct sockaddr *)a1,
1156 get_user(args+2)));
1157 case SYS_LISTEN:
1158 return(sys_listen(a0,a1));
1159 case SYS_ACCEPT:
1160 return(sys_accept(a0,(struct sockaddr *)a1,
1161 (int *)get_user(args+2)));
1162 case SYS_GETSOCKNAME:
1163 return(sys_getsockname(a0,(struct sockaddr *)a1,
1164 (int *)get_user(args+2)));
1165 case SYS_GETPEERNAME:
1166 return(sys_getpeername(a0, (struct sockaddr *)a1,
1167 (int *)get_user(args+2)));
1168 case SYS_SOCKETPAIR:
1169 return(sys_socketpair(a0,a1,
1170 get_user(args+2),
1171 (int *)get_user(args+3)));
1172 case SYS_SEND:
1173 return(sys_send(a0,
1174 (void *)a1,
1175 get_user(args+2),
1176 get_user(args+3)));
1177 case SYS_SENDTO:
1178 return(sys_sendto(a0,(void *)a1,
1179 get_user(args+2),
1180 get_user(args+3),
1181 (struct sockaddr *)get_user(args+4),
1182 get_user(args+5)));
1183 case SYS_RECV:
1184 return(sys_recv(a0,
1185 (void *)a1,
1186 get_user(args+2),
1187 get_user(args+3)));
1188 case SYS_RECVFROM:
1189 return(sys_recvfrom(a0,
1190 (void *)a1,
1191 get_user(args+2),
1192 get_user(args+3),
1193 (struct sockaddr *)get_user(args+4),
1194 (int *)get_user(args+5)));
1195 case SYS_SHUTDOWN:
1196 return(sys_shutdown(a0,a1));
1197 case SYS_SETSOCKOPT:
1198 return(sys_setsockopt(a0,
1199 a1,
1200 get_user(args+2),
1201 (char *)get_user(args+3),
1202 get_user(args+4)));
1203 case SYS_GETSOCKOPT:
1204 return(sys_getsockopt(a0,
1205 a1,
1206 get_user(args+2),
1207 (char *)get_user(args+3),
1208 (int *)get_user(args+4)));
1209 case SYS_SENDMSG:
1210 return sys_sendmsg(a0,
1211 (struct msghdr *) a1,
1212 get_user(args+2));
1213 case SYS_RECVMSG:
1214 return sys_recvmsg(a0,
1215 (struct msghdr *) a1,
1216 get_user(args+2));
1217 }
1218 return -EINVAL;
1219 }
1220
1221
1222
1223
1224
1225
1226
1227 int sock_register(int family, struct proto_ops *ops)
1228 {
1229 int i;
1230
1231 cli();
1232 for(i = 0; i < NPROTO; i++)
1233 {
1234 if (pops[i] != NULL)
1235 continue;
1236 pops[i] = ops;
1237 pops[i]->family = family;
1238 sti();
1239 return(i);
1240 }
1241 sti();
1242 return(-ENOMEM);
1243 }
1244
1245
1246
1247
1248
1249
1250
1251 int sock_unregister(int family)
1252 {
1253 int i;
1254
1255 cli();
1256 for(i = 0; i < NPROTO; i++)
1257 {
1258 if (pops[i] == NULL)
1259 continue;
1260 if (pops[i]->family == family)
1261 {
1262 pops[i]=NULL;
1263 sti();
1264 return(i);
1265 }
1266 }
1267 sti();
1268 return(-ENOENT);
1269 }
1270
1271 void proto_init(void)
1272 {
1273 extern struct net_proto protocols[];
1274 struct net_proto *pro;
1275
1276
1277 pro = protocols;
1278 while (pro->name != NULL)
1279 {
1280 (*pro->init_func)(pro);
1281 pro++;
1282 }
1283
1284 }
1285
1286
1287 void sock_init(void)
1288 {
1289 int i;
1290
1291 printk("Swansea University Computer Society NET3.032 for Linux 1.3.35\n");
1292
1293
1294
1295
1296
1297 for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
1298
1299
1300
1301
1302
1303 #ifdef CONFIG_NETLINK
1304 init_netlink();
1305 #endif
1306
1307
1308
1309
1310 #if defined(CONFIG_RTNETLINK)
1311 netlink_attach(NETLINK_ROUTE, netlink_donothing);
1312 #endif
1313
1314
1315
1316
1317
1318 #ifdef CONFIG_FIREWALL
1319 fwchain_init();
1320 #endif
1321
1322
1323
1324
1325
1326 proto_init();
1327 }
1328
1329 int socket_get_info(char *buffer, char **start, off_t offset, int length)
1330 {
1331 int len = sprintf(buffer, "sockets: used %d\n", sockets_in_use);
1332 if (offset >= len)
1333 {
1334 *start = buffer;
1335 return 0;
1336 }
1337 *start = buffer + offset;
1338 len -= offset;
1339 if (len > length)
1340 len = length;
1341 return len;
1342 }