2 * NET An implementation of the SOCKET network access protocol.
4 * Version: @(#)socket.c 1.0.5 05/25/93
6 * Authors: Orest Zborowski, <obz@Kodak.COM>
7 * Ross Biro, <bir7@leland.Stanford.Edu>
8 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
11 * Anonymous : NOTSOCK/BADF cleanup. Error fix in
13 * Alan Cox : verify_area() fixes
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version
19 * 2 of the License, or (at your option) any later version.
22 #include <linux/config.h>
23 #include <linux/signal.h>
24 #include <linux/errno.h>
25 #include <linux/sched.h>
26 #include <linux/kernel.h>
27 #include <linux/major.h>
28 #include <linux/stat.h>
29 #include <linux/socket.h>
30 #include <linux/fcntl.h>
31 #include <linux/net.h>
32 #include <linux/ddi.h>
34 #include <asm/system.h>
35 #include <asm/segment.h>
41 #define DPRINTF(x) dprintf x
43 #define DPRINTF(x) /**/
46 static int sock_lseek(struct inode
*inode
, struct file
*file
, off_t offset
,
48 static int sock_read(struct inode
*inode
, struct file
*file
, char *buf
,
50 static int sock_write(struct inode
*inode
, struct file
*file
, char *buf
,
52 static int sock_readdir(struct inode
*inode
, struct file
*file
,
53 struct dirent
*dirent
, int count
);
54 static void sock_close(struct inode
*inode
, struct file
*file
);
55 static int sock_select(struct inode
*inode
, struct file
*file
, int which
, select_table
*seltable
);
56 static int sock_ioctl(struct inode
*inode
, struct file
*file
,
57 unsigned int cmd
, unsigned long arg
);
60 static struct file_operations socket_file_ops
= {
68 NULL
, /* no special open code... */
72 static struct socket sockets
[NSOCKETS
];
73 static struct wait_queue
*socket_wait_free
= NULL
;
74 static struct proto_ops
*pops
[NPROTO
];
75 static int net_debug
= 0;
77 #define last_socket (sockets + NSOCKETS - 1)
80 /* Module debugging. */
82 dprintf(int level
, char *fmt
, ...)
86 extern int vsprintf(char * buf
, const char * fmt
, va_list args
);
88 if (level
== 0) return;
90 vsprintf(buff
, fmt
, args
);
96 /* Obtains the first available file descriptor and sets it up for use. */
98 get_fd(struct inode
*inode
)
103 /* Find a file descriptor suitable for return to the user. */
104 file
= get_empty_filp();
105 if (!file
) return(-1);
106 for (fd
= 0; fd
< NR_OPEN
; ++fd
)
107 if (!current
->filp
[fd
]) break;
112 FD_CLR(fd
, ¤t
->close_on_exec
);
113 current
->filp
[fd
] = file
;
114 file
->f_op
= &socket_file_ops
;
118 file
->f_inode
= inode
;
119 if (inode
) inode
->i_count
++;
126 * Reverses the action of get_fd() by releasing the file. it closes
127 * the descriptor, but makes sure it does nothing more. Called when
128 * an incomplete socket must be closed, along with sock_release().
133 sys_close(fd
); /* the count protects us from iput */
138 socki_lookup(struct inode
*inode
)
142 if ((sock
= inode
->i_socket
) != NULL
) {
143 if (sock
->state
!= SS_FREE
&& SOCK_INODE(sock
) == inode
)
145 printk("socket.c: uhhuh. stale inode->i_socket pointer\n");
147 for (sock
= sockets
; sock
<= last_socket
; ++sock
)
148 if (sock
->state
!= SS_FREE
&& SOCK_INODE(sock
) == inode
) {
149 printk("socket.c: uhhuh. Found socket despite no inode->i_socket pointer\n");
156 static inline struct socket
*
157 sockfd_lookup(int fd
, struct file
**pfile
)
161 if (fd
< 0 || fd
>= NR_OPEN
|| !(file
= current
->filp
[fd
])) return(NULL
);
162 if (pfile
) *pfile
= file
;
163 return(socki_lookup(file
->f_inode
));
167 static struct socket
*
174 for (sock
= sockets
; sock
<= last_socket
; ++sock
) {
175 if (sock
->state
== SS_FREE
) {
176 sock
->state
= SS_UNCONNECTED
;
185 * This really shouldn't be necessary, but everything
186 * else depends on inodes, so we grab it.
187 * Sleeps are also done on the i_wait member of this
188 * inode. The close system call will iput this inode
191 if (!(SOCK_INODE(sock
) = get_empty_inode())) {
192 printk("NET: sock_alloc: no more inodes\n");
193 sock
->state
= SS_FREE
;
196 SOCK_INODE(sock
)->i_mode
= S_IFSOCK
;
197 SOCK_INODE(sock
)->i_uid
= current
->euid
;
198 SOCK_INODE(sock
)->i_gid
= current
->egid
;
199 SOCK_INODE(sock
)->i_socket
= sock
;
201 sock
->wait
= &SOCK_INODE(sock
)->i_wait
;
203 "NET: sock_alloc: sk 0x%x, ino 0x%x\n",
204 sock
, SOCK_INODE(sock
)));
209 if (!wait
) return(NULL
);
210 DPRINTF((net_debug
, "NET: sock_alloc: no free sockets, sleeping...\n"));
211 interruptible_sleep_on(&socket_wait_free
);
212 if (current
->signal
& ~current
->blocked
) {
213 DPRINTF((net_debug
, "NET: sock_alloc: sleep was interrupted\n"));
216 DPRINTF((net_debug
, "NET: sock_alloc: wakeup... trying again...\n"));
222 sock_release_peer(struct socket
*peer
)
224 peer
->state
= SS_DISCONNECTING
;
225 wake_up_interruptible(peer
->wait
);
230 sock_release(struct socket
*sock
)
234 struct socket
*peersock
, *nextsock
;
236 DPRINTF((net_debug
, "NET: sock_release: socket 0x%x, inode 0x%x\n",
237 sock
, SOCK_INODE(sock
)));
238 if ((oldstate
= sock
->state
) != SS_UNCONNECTED
)
239 sock
->state
= SS_DISCONNECTING
;
241 /* Wake up anyone waiting for connections. */
242 for (peersock
= sock
->iconn
; peersock
; peersock
= nextsock
) {
243 nextsock
= peersock
->next
;
244 sock_release_peer(peersock
);
248 * Wake up anyone we're connected to. First, we release the
249 * protocol, to give it a chance to flush data, etc.
251 peersock
= (oldstate
== SS_CONNECTED
) ? sock
->conn
: NULL
;
252 if (sock
->ops
) sock
->ops
->release(sock
, peersock
);
253 if (peersock
) sock_release_peer(peersock
);
254 inode
= SOCK_INODE(sock
);
255 sock
->state
= SS_FREE
; /* this really releases us */
256 wake_up_interruptible(&socket_wait_free
);
258 /* We need to do this. If sock alloc was called we already have an inode. */
264 sock_lseek(struct inode
*inode
, struct file
*file
, off_t offset
, int whence
)
266 DPRINTF((net_debug
, "NET: sock_lseek: huh?\n"));
272 sock_read(struct inode
*inode
, struct file
*file
, char *ubuf
, int size
)
276 DPRINTF((net_debug
, "NET: sock_read: buf=0x%x, size=%d\n", ubuf
, size
));
277 if (!(sock
= socki_lookup(inode
))) {
278 printk("NET: sock_read: can't find socket for inode!\n");
281 if (sock
->flags
& SO_ACCEPTCON
) return(-EINVAL
);
282 return(sock
->ops
->read(sock
, ubuf
, size
, (file
->f_flags
& O_NONBLOCK
)));
287 sock_write(struct inode
*inode
, struct file
*file
, char *ubuf
, int size
)
291 DPRINTF((net_debug
, "NET: sock_write: buf=0x%x, size=%d\n", ubuf
, size
));
292 if (!(sock
= socki_lookup(inode
))) {
293 printk("NET: sock_write: can't find socket for inode!\n");
296 if (sock
->flags
& SO_ACCEPTCON
) return(-EINVAL
);
297 return(sock
->ops
->write(sock
, ubuf
, size
,(file
->f_flags
& O_NONBLOCK
)));
302 sock_readdir(struct inode
*inode
, struct file
*file
, struct dirent
*dirent
,
305 DPRINTF((net_debug
, "NET: sock_readdir: huh?\n"));
311 sock_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
,
316 DPRINTF((net_debug
, "NET: sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n",
318 if (!(sock
= socki_lookup(inode
))) {
319 printk("NET: sock_ioctl: can't find socket for inode!\n");
322 return(sock
->ops
->ioctl(sock
, cmd
, arg
));
327 sock_select(struct inode
*inode
, struct file
*file
, int sel_type
, select_table
* wait
)
331 DPRINTF((net_debug
, "NET: sock_select: inode = 0x%x, kind = %s\n", inode
,
332 (sel_type
== SEL_IN
) ? "in" :
333 (sel_type
== SEL_OUT
) ? "out" : "ex"));
334 if (!(sock
= socki_lookup(inode
))) {
335 printk("NET: sock_select: can't find socket for inode!\n");
339 /* We can't return errors to select, so its either yes or no. */
340 if (sock
->ops
&& sock
->ops
->select
)
341 return(sock
->ops
->select(sock
, sel_type
, wait
));
347 sock_close(struct inode
*inode
, struct file
*file
)
351 DPRINTF((net_debug
, "NET: sock_close: inode=0x%x (cnt=%d)\n",
352 inode
, inode
->i_count
));
354 /* It's possible the inode is NULL if we're closing an unfinished socket. */
356 if (!(sock
= socki_lookup(inode
))) {
357 printk("NET: sock_close: can't find socket for inode!\n");
365 sock_awaitconn(struct socket
*mysock
, struct socket
*servsock
)
370 "NET: sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
372 if (!(servsock
->flags
& SO_ACCEPTCON
)) {
374 "NET: sock_awaitconn: server not accepting connections\n"));
378 /* Put ourselves on the server's incomplete connection queue. */
381 if (!(last
= servsock
->iconn
)) servsock
->iconn
= mysock
;
383 while (last
->next
) last
= last
->next
;
386 mysock
->state
= SS_CONNECTING
;
387 mysock
->conn
= servsock
;
391 * Wake up server, then await connection. server will set state to
392 * SS_CONNECTED if we're connected.
394 wake_up_interruptible(servsock
->wait
);
395 if (mysock
->state
!= SS_CONNECTED
) {
396 interruptible_sleep_on(mysock
->wait
);
397 if (mysock
->state
!= SS_CONNECTED
&&
398 mysock
->state
!= SS_DISCONNECTING
) {
400 * if we're not connected we could have been
401 * 1) interrupted, so we need to remove ourselves
402 * from the server list
403 * 2) rejected (mysock->conn == NULL), and have
404 * already been removed from the list
406 if (mysock
->conn
== servsock
) {
408 if ((last
= servsock
->iconn
) == mysock
)
409 servsock
->iconn
= mysock
->next
;
411 while (last
->next
!= mysock
) last
= last
->next
;
412 last
->next
= mysock
->next
;
416 return(mysock
->conn
? -EINTR
: -EACCES
);
424 * Perform the socket system call. we locate the appropriate
425 * family, then create a fresh socket.
428 sock_socket(int family
, int type
, int protocol
)
432 struct proto_ops
*ops
;
435 "NET: sock_socket: family = %d, type = %d, protocol = %d\n",
436 family
, type
, protocol
));
438 /* Locate the correct protocol family. */
439 for (i
= 0; i
< NPROTO
; ++i
) {
440 if (pops
[i
] == NULL
) continue;
441 if (pops
[i
]->family
== family
) break;
444 DPRINTF((net_debug
, "NET: sock_socket: family not found\n"));
450 * Check that this is a type that we know how to manipulate and
451 * the protocol makes sense here. The family can still reject the
454 if ((type
!= SOCK_STREAM
&& type
!= SOCK_DGRAM
&&
455 type
!= SOCK_SEQPACKET
&& type
!= SOCK_RAW
&&
456 type
!= SOCK_PACKET
) || protocol
< 0)
460 * allocate the socket and allow the family to set things up. if
461 * the protocol is 0, the family is instructed to select an appropriate
464 if (!(sock
= sock_alloc(1))) {
465 printk("sock_socket: no more sockets\n");
470 if ((i
= sock
->ops
->create(sock
, protocol
)) < 0) {
475 if ((fd
= get_fd(SOCK_INODE(sock
))) < 0) {
485 sock_socketpair(int family
, int type
, int protocol
, unsigned long usockvec
[2])
488 struct socket
*sock1
, *sock2
;
492 "NET: sock_socketpair: family = %d, type = %d, protocol = %d\n",
493 family
, type
, protocol
));
496 * Obtain the first socket and check if the underlying protocol
497 * supports the socketpair call.
499 if ((fd1
= sock_socket(family
, type
, protocol
)) < 0) return(fd1
);
500 sock1
= sockfd_lookup(fd1
, NULL
);
501 if (!sock1
->ops
->socketpair
) {
506 /* Now grab another socket and try to connect the two together. */
507 if ((fd2
= sock_socket(family
, type
, protocol
)) < 0) {
511 sock2
= sockfd_lookup(fd2
, NULL
);
512 if ((i
= sock1
->ops
->socketpair(sock1
, sock2
)) < 0) {
519 sock1
->state
= SS_CONNECTED
;
520 sock2
->state
= SS_CONNECTED
;
522 er
=verify_area(VERIFY_WRITE
, usockvec
, 2 * sizeof(int));
525 put_fs_long(fd1
, &usockvec
[0]);
526 put_fs_long(fd2
, &usockvec
[1]);
533 * Bind a name to a socket. Nothing much to do here since its
534 * the protocol's responsibility to handle the local address.
537 sock_bind(int fd
, struct sockaddr
*umyaddr
, int addrlen
)
542 DPRINTF((net_debug
, "NET: sock_bind: fd = %d\n", fd
));
543 if (fd
< 0 || fd
>= NR_OPEN
|| current
->filp
[fd
] == NULL
)
545 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
546 if ((i
= sock
->ops
->bind(sock
, umyaddr
, addrlen
)) < 0) {
547 DPRINTF((net_debug
, "NET: sock_bind: bind failed\n"));
555 * Perform a listen. Basically, we allow the protocol to do anything
556 * necessary for a listen, and if that works, we mark the socket as
557 * ready for listening.
560 sock_listen(int fd
, int backlog
)
564 DPRINTF((net_debug
, "NET: sock_listen: fd = %d\n", fd
));
565 if (fd
< 0 || fd
>= NR_OPEN
|| current
->filp
[fd
] == NULL
)
567 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
568 if (sock
->state
!= SS_UNCONNECTED
) {
569 DPRINTF((net_debug
, "NET: sock_listen: socket isn't unconnected\n"));
572 if (sock
->ops
&& sock
->ops
->listen
) sock
->ops
->listen(sock
, backlog
);
573 sock
->flags
|= SO_ACCEPTCON
;
579 * For accept, we attempt to create a new socket, set up the link
580 * with the client, wake up the client, then return the new
584 sock_accept(int fd
, struct sockaddr
*upeer_sockaddr
, int *upeer_addrlen
)
587 struct socket
*sock
, *newsock
;
590 DPRINTF((net_debug
, "NET: sock_accept: fd = %d\n", fd
));
591 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
594 if (!(sock
= sockfd_lookup(fd
, &file
))) return(-ENOTSOCK
);
595 if (sock
->state
!= SS_UNCONNECTED
) {
596 DPRINTF((net_debug
, "NET: sock_accept: socket isn't unconnected\n"));
599 if (!(sock
->flags
& SO_ACCEPTCON
)) {
601 "NET: sock_accept: socket not accepting connections!\n"));
605 if (!(newsock
= sock_alloc(0))) {
606 printk("NET: sock_accept: no more sockets\n");
609 newsock
->type
= sock
->type
;
610 newsock
->ops
= sock
->ops
;
611 if ((i
= sock
->ops
->dup(newsock
, sock
)) < 0) {
612 sock_release(newsock
);
616 i
= newsock
->ops
->accept(sock
, newsock
, file
->f_flags
);
618 sock_release(newsock
);
622 if ((fd
= get_fd(SOCK_INODE(newsock
))) < 0) {
623 sock_release(newsock
);
627 DPRINTF((net_debug
, "NET: sock_accept: connected socket 0x%x via 0x%x\n",
631 newsock
->ops
->getname(newsock
, upeer_sockaddr
, upeer_addrlen
, 1);
637 /* Attempt to connect to a socket with the server address. */
639 sock_connect(int fd
, struct sockaddr
*uservaddr
, int addrlen
)
645 DPRINTF((net_debug
, "NET: sock_connect: fd = %d\n", fd
));
646 if (fd
< 0 || fd
>= NR_OPEN
|| (file
=current
->filp
[fd
]) == NULL
)
649 if (!(sock
= sockfd_lookup(fd
, &file
))) return(-ENOTSOCK
);
650 switch(sock
->state
) {
652 /* This is ok... continue with connect */
655 /* Socket is already connected */
658 /* Not yet connected... we will check this. */
659 return(sock
->ops
->connect(sock
, uservaddr
,
660 addrlen
, file
->f_flags
));
663 "NET: sock_connect: socket not unconnected\n"));
666 i
= sock
->ops
->connect(sock
, uservaddr
, addrlen
, file
->f_flags
);
668 DPRINTF((net_debug
, "NET: sock_connect: connect failed\n"));
676 sock_getsockname(int fd
, struct sockaddr
*usockaddr
, int *usockaddr_len
)
680 DPRINTF((net_debug
, "NET: sock_getsockname: fd = %d\n", fd
));
681 if (fd
< 0 || fd
>= NR_OPEN
|| current
->filp
[fd
] == NULL
)
683 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
684 return(sock
->ops
->getname(sock
, usockaddr
, usockaddr_len
, 0));
689 sock_getpeername(int fd
, struct sockaddr
*usockaddr
, int *usockaddr_len
)
693 DPRINTF((net_debug
, "NET: sock_getpeername: fd = %d\n", fd
));
694 if (fd
< 0 || fd
>= NR_OPEN
|| current
->filp
[fd
] == NULL
)
696 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
697 return(sock
->ops
->getname(sock
, usockaddr
, usockaddr_len
, 1));
702 sock_send(int fd
, void * buff
, int len
, unsigned flags
)
708 "NET: sock_send(fd = %d, buff = %X, len = %d, flags = %X)\n",
709 fd
, buff
, len
, flags
));
711 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
713 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
715 return(sock
->ops
->send(sock
, buff
, len
, (file
->f_flags
& O_NONBLOCK
), flags
));
720 sock_sendto(int fd
, void * buff
, int len
, unsigned flags
,
721 struct sockaddr
*addr
, int addr_len
)
727 "NET: sock_sendto(fd = %d, buff = %X, len = %d, flags = %X,"
728 " addr=%X, alen = %d\n", fd
, buff
, len
, flags
, addr
, addr_len
));
730 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
732 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
734 return(sock
->ops
->sendto(sock
, buff
, len
, (file
->f_flags
& O_NONBLOCK
),
735 flags
, addr
, addr_len
));
740 sock_recv(int fd
, void * buff
, int len
, unsigned flags
)
746 "NET: sock_recv(fd = %d, buff = %X, len = %d, flags = %X)\n",
747 fd
, buff
, len
, flags
));
749 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
751 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
753 return(sock
->ops
->recv(sock
, buff
, len
,(file
->f_flags
& O_NONBLOCK
), flags
));
758 sock_recvfrom(int fd
, void * buff
, int len
, unsigned flags
,
759 struct sockaddr
*addr
, int *addr_len
)
765 "NET: sock_recvfrom(fd = %d, buff = %X, len = %d, flags = %X,"
766 " addr=%X, alen=%X\n", fd
, buff
, len
, flags
, addr
, addr_len
));
768 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
770 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
772 return(sock
->ops
->recvfrom(sock
, buff
, len
, (file
->f_flags
& O_NONBLOCK
),
773 flags
, addr
, addr_len
));
778 sock_setsockopt(int fd
, int level
, int optname
, char *optval
, int optlen
)
783 DPRINTF((net_debug
, "NET: sock_setsockopt(fd=%d, level=%d, optname=%d,\n",
784 fd
, level
, optname
));
785 DPRINTF((net_debug
, " optval = %X, optlen = %d)\n",
788 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
790 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
792 return(sock
->ops
->setsockopt(sock
, level
, optname
, optval
, optlen
));
797 sock_getsockopt(int fd
, int level
, int optname
, char *optval
, int *optlen
)
802 DPRINTF((net_debug
, "NET: sock_getsockopt(fd=%d, level=%d, optname=%d,\n",
803 fd
, level
, optname
));
804 DPRINTF((net_debug
, " optval = %X, optlen = %X)\n",
807 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
809 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
811 if (!sock
->ops
|| !sock
->ops
->getsockopt
) return(0);
812 return(sock
->ops
->getsockopt(sock
, level
, optname
, optval
, optlen
));
817 sock_shutdown(int fd
, int how
)
822 DPRINTF((net_debug
, "NET: sock_shutdown(fd = %d, how = %d)\n", fd
, how
));
824 if (fd
< 0 || fd
>= NR_OPEN
|| ((file
= current
->filp
[fd
]) == NULL
))
827 if (!(sock
= sockfd_lookup(fd
, NULL
))) return(-ENOTSOCK
);
829 return(sock
->ops
->shutdown(sock
, how
));
834 sock_fcntl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
838 sock
= socki_lookup (filp
->f_inode
);
839 if (sock
!= NULL
&& sock
->ops
!= NULL
&& sock
->ops
->fcntl
!= NULL
)
840 return(sock
->ops
->fcntl(sock
, cmd
, arg
));
846 * System call vectors. Since I (RIB) want to rewrite sockets as streams,
847 * we have this level of indirection. Not a lot of overhead, since more of
848 * the work is done via read/write/select directly.
851 sys_socketcall(int call
, unsigned long *args
)
856 er
=verify_area(VERIFY_READ
, args
, 3 * sizeof(long));
859 return(sock_socket(get_fs_long(args
+0),
861 get_fs_long(args
+2)));
863 er
=verify_area(VERIFY_READ
, args
, 3 * sizeof(long));
866 return(sock_bind(get_fs_long(args
+0),
867 (struct sockaddr
*)get_fs_long(args
+1),
868 get_fs_long(args
+2)));
870 er
=verify_area(VERIFY_READ
, args
, 3 * sizeof(long));
873 return(sock_connect(get_fs_long(args
+0),
874 (struct sockaddr
*)get_fs_long(args
+1),
875 get_fs_long(args
+2)));
877 er
=verify_area(VERIFY_READ
, args
, 2 * sizeof(long));
880 return(sock_listen(get_fs_long(args
+0),
881 get_fs_long(args
+1)));
883 er
=verify_area(VERIFY_READ
, args
, 3 * sizeof(long));
886 return(sock_accept(get_fs_long(args
+0),
887 (struct sockaddr
*)get_fs_long(args
+1),
888 (int *)get_fs_long(args
+2)));
889 case SYS_GETSOCKNAME
:
890 er
=verify_area(VERIFY_READ
, args
, 3 * sizeof(long));
893 return(sock_getsockname(get_fs_long(args
+0),
894 (struct sockaddr
*)get_fs_long(args
+1),
895 (int *)get_fs_long(args
+2)));
896 case SYS_GETPEERNAME
:
897 er
=verify_area(VERIFY_READ
, args
, 3 * sizeof(long));
900 return(sock_getpeername(get_fs_long(args
+0),
901 (struct sockaddr
*)get_fs_long(args
+1),
902 (int *)get_fs_long(args
+2)));
904 er
=verify_area(VERIFY_READ
, args
, 4 * sizeof(long));
907 return(sock_socketpair(get_fs_long(args
+0),
910 (unsigned long *)get_fs_long(args
+3)));
912 er
=verify_area(VERIFY_READ
, args
, 4 * sizeof(unsigned long));
915 return(sock_send(get_fs_long(args
+0),
916 (void *)get_fs_long(args
+1),
918 get_fs_long(args
+3)));
920 er
=verify_area(VERIFY_READ
, args
, 6 * sizeof(unsigned long));
923 return(sock_sendto(get_fs_long(args
+0),
924 (void *)get_fs_long(args
+1),
927 (struct sockaddr
*)get_fs_long(args
+4),
928 get_fs_long(args
+5)));
930 er
=verify_area(VERIFY_READ
, args
, 4 * sizeof(unsigned long));
933 return(sock_recv(get_fs_long(args
+0),
934 (void *)get_fs_long(args
+1),
936 get_fs_long(args
+3)));
938 er
=verify_area(VERIFY_READ
, args
, 6 * sizeof(unsigned long));
941 return(sock_recvfrom(get_fs_long(args
+0),
942 (void *)get_fs_long(args
+1),
945 (struct sockaddr
*)get_fs_long(args
+4),
946 (int *)get_fs_long(args
+5)));
948 er
=verify_area(VERIFY_READ
, args
, 2* sizeof(unsigned long));
951 return(sock_shutdown(get_fs_long(args
+0),
952 get_fs_long(args
+1)));
954 er
=verify_area(VERIFY_READ
, args
, 5*sizeof(unsigned long));
957 return(sock_setsockopt(get_fs_long(args
+0),
960 (char *)get_fs_long(args
+3),
961 get_fs_long(args
+4)));
963 er
=verify_area(VERIFY_READ
, args
, 5*sizeof(unsigned long));
966 return(sock_getsockopt(get_fs_long(args
+0),
969 (char *)get_fs_long(args
+3),
970 (int *)get_fs_long(args
+4)));
978 net_ioctl(unsigned int cmd
, unsigned long arg
)
983 er
=verify_area(VERIFY_READ
, (void *)arg
, sizeof(long));
986 net_debug
= get_fs_long((long *)arg
);
987 if (net_debug
!= 0 && net_debug
!= 1) {
1001 * Handle the IOCTL system call for the NET devices. This basically
1002 * means I/O control for the SOCKET layer (future expansions could be
1003 * a variable number of socket table entries, et al), and for the more
1004 * general protocols like ARP. The latter currently lives in the INET
1005 * module, so we have to get ugly a tiny little bit. Later... -FvK
1008 net_fioctl(struct inode
*inode
, struct file
*file
,
1009 unsigned int cmd
, unsigned long arg
)
1011 extern int arp_ioctl(unsigned int, void *);
1013 /* Dispatch on the minor device. */
1014 switch(MINOR(inode
->i_rdev
)) {
1015 case 0: /* NET (SOCKET) */
1016 DPRINTF((net_debug
, "NET: SOCKET level I/O control request.\n"));
1017 return(net_ioctl(cmd
, arg
));
1020 DPRINTF((net_debug
, "NET: ARP level I/O control request.\n"));
1021 return(arp_ioctl(cmd
, (void *) arg
));
1031 static struct file_operations net_fops
= {
1037 net_fioctl
, /* IOCTL */
1045 * This function is called by a protocol handler that wants to
1046 * advertise its address family, and have it linked into the
1050 sock_register(int family
, struct proto_ops
*ops
)
1055 for(i
= 0; i
< NPROTO
; i
++) {
1056 if (pops
[i
] != NULL
) continue;
1058 pops
[i
]->family
= family
;
1060 DPRINTF((net_debug
, "NET: Installed protocol %d in slot %d (0x%X)\n",
1061 family
, i
, (long)ops
));
1072 struct socket
*sock
;
1075 /* Set up our SOCKET VFS major device. */
1076 if (register_chrdev(SOCKET_MAJOR
, "socket", &net_fops
) < 0) {
1077 printk("NET: cannot register major device %d!\n", SOCKET_MAJOR
);
1081 /* Release all sockets. */
1082 for (sock
= sockets
; sock
<= last_socket
; ++sock
) sock
->state
= SS_FREE
;
1084 /* Initialize all address (protocol) families. */
1085 for (i
= 0; i
< NPROTO
; ++i
) pops
[i
] = NULL
;
1087 /* Initialize the DDI module. */
1090 /* Initialize the ARP module. */