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