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