This source file includes following definitions.
- dprintf
- get_fd
- toss_fd
- socki_lookup
- sockfd_lookup
- sock_alloc
- sock_release_peer
- sock_release
- sock_lseek
- sock_read
- sock_write
- sock_readdir
- sock_ioctl
- sock_select
- sock_close
- sock_awaitconn
- sock_socket
- sock_socketpair
- sock_bind
- sock_listen
- sock_accept
- sock_connect
- sock_getsockname
- sock_getpeername
- sock_send
- sock_sendto
- sock_recv
- sock_recvfrom
- sock_setsockopt
- sock_getsockopt
- sock_shutdown
- sock_fcntl
- sys_socketcall
- net_ioctl
- net_fioctl
- sock_register
- sock_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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>
33
34 #include <asm/system.h>
35 #include <asm/segment.h>
36
37 #undef SOCK_DEBUG
38
39 #ifdef SOCK_DEBUG
40 #include <stdarg.h>
41 #define DPRINTF(x) dprintf x
42 #else
43 #define DPRINTF(x)
44 #endif
45
46 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
47 int whence);
48 static int sock_read(struct inode *inode, struct file *file, char *buf,
49 int size);
50 static int sock_write(struct inode *inode, struct file *file, char *buf,
51 int size);
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);
58
59
60 static struct file_operations socket_file_ops = {
61 sock_lseek,
62 sock_read,
63 sock_write,
64 sock_readdir,
65 sock_select,
66 sock_ioctl,
67 NULL,
68 NULL,
69 sock_close
70 };
71
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;
76
77 #define last_socket (sockets + NSOCKETS - 1)
78
79 #ifdef SOCK_DEBUG
80
81 static void
82 dprintf(int level, char *fmt, ...)
83 {
84 char buff[1024];
85 va_list args;
86 extern int vsprintf(char * buf, const char * fmt, va_list args);
87
88 if (level == 0) return;
89 va_start(args, fmt);
90 vsprintf(buff, fmt, args);
91 va_end(args);
92 printk(buff);
93 }
94 #endif
95
96
97 static int
98 get_fd(struct inode *inode)
99 {
100 int fd;
101 struct file *file;
102
103
104 file = get_empty_filp();
105 if (!file) return(-1);
106 for (fd = 0; fd < NR_OPEN; ++fd)
107 if (!current->filp[fd]) break;
108 if (fd == NR_OPEN) {
109 file->f_count = 0;
110 return(-1);
111 }
112 FD_CLR(fd, ¤t->close_on_exec);
113 current->filp[fd] = file;
114 file->f_op = &socket_file_ops;
115 file->f_mode = 3;
116 file->f_flags = 0;
117 file->f_count = 1;
118 file->f_inode = inode;
119 if (inode) inode->i_count++;
120 file->f_pos = 0;
121 return(fd);
122 }
123
124
125
126
127
128
129
130 static inline void
131 toss_fd(int fd)
132 {
133 sys_close(fd);
134 }
135
136
137 struct socket *
138 socki_lookup(struct inode *inode)
139 {
140 struct socket *sock;
141
142 if ((sock = inode->i_socket) != NULL) {
143 if (sock->state != SS_FREE && SOCK_INODE(sock) == inode)
144 return sock;
145 printk("socket.c: uhhuh. stale inode->i_socket pointer\n");
146 }
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");
150 return(sock);
151 }
152 return(NULL);
153 }
154
155
156 static inline struct socket *
157 sockfd_lookup(int fd, struct file **pfile)
158 {
159 struct file *file;
160
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));
164 }
165
166
167 static struct socket *
168 sock_alloc(int wait)
169 {
170 struct socket *sock;
171
172 while (1) {
173 cli();
174 for (sock = sockets; sock <= last_socket; ++sock) {
175 if (sock->state == SS_FREE) {
176 sock->state = SS_UNCONNECTED;
177 sti();
178 sock->flags = 0;
179 sock->ops = NULL;
180 sock->data = NULL;
181 sock->conn = NULL;
182 sock->iconn = NULL;
183
184
185
186
187
188
189
190
191 if (!(SOCK_INODE(sock) = get_empty_inode())) {
192 printk("NET: sock_alloc: no more inodes\n");
193 sock->state = SS_FREE;
194 return(NULL);
195 }
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;
200
201 sock->wait = &SOCK_INODE(sock)->i_wait;
202 DPRINTF((net_debug,
203 "NET: sock_alloc: sk 0x%x, ino 0x%x\n",
204 sock, SOCK_INODE(sock)));
205 return(sock);
206 }
207 }
208 sti();
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"));
214 return(NULL);
215 }
216 DPRINTF((net_debug, "NET: sock_alloc: wakeup... trying again...\n"));
217 }
218 }
219
220
221 static inline void
222 sock_release_peer(struct socket *peer)
223 {
224 peer->state = SS_DISCONNECTING;
225 wake_up_interruptible(peer->wait);
226 }
227
228
229 static void
230 sock_release(struct socket *sock)
231 {
232 int oldstate;
233 struct inode *inode;
234 struct socket *peersock, *nextsock;
235
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;
240
241
242 for (peersock = sock->iconn; peersock; peersock = nextsock) {
243 nextsock = peersock->next;
244 sock_release_peer(peersock);
245 }
246
247
248
249
250
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;
256 wake_up_interruptible(&socket_wait_free);
257
258
259 iput(inode);
260 }
261
262
263 static int
264 sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence)
265 {
266 DPRINTF((net_debug, "NET: sock_lseek: huh?\n"));
267 return(-ESPIPE);
268 }
269
270
271 static int
272 sock_read(struct inode *inode, struct file *file, char *ubuf, int size)
273 {
274 struct socket *sock;
275
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");
279 return(-EBADF);
280 }
281 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
282 return(sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK)));
283 }
284
285
286 static int
287 sock_write(struct inode *inode, struct file *file, char *ubuf, int size)
288 {
289 struct socket *sock;
290
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");
294 return(-EBADF);
295 }
296 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
297 return(sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)));
298 }
299
300
301 static int
302 sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent,
303 int count)
304 {
305 DPRINTF((net_debug, "NET: sock_readdir: huh?\n"));
306 return(-EBADF);
307 }
308
309
310 int
311 sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
312 unsigned long arg)
313 {
314 struct socket *sock;
315
316 DPRINTF((net_debug, "NET: sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n",
317 inode, cmd, arg));
318 if (!(sock = socki_lookup(inode))) {
319 printk("NET: sock_ioctl: can't find socket for inode!\n");
320 return(-EBADF);
321 }
322 return(sock->ops->ioctl(sock, cmd, arg));
323 }
324
325
326 static int
327 sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
328 {
329 struct socket *sock;
330
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");
336 return(0);
337 }
338
339
340 if (sock->ops && sock->ops->select)
341 return(sock->ops->select(sock, sel_type, wait));
342 return(0);
343 }
344
345
346 void
347 sock_close(struct inode *inode, struct file *file)
348 {
349 struct socket *sock;
350
351 DPRINTF((net_debug, "NET: sock_close: inode=0x%x (cnt=%d)\n",
352 inode, inode->i_count));
353
354
355 if (!inode) return;
356 if (!(sock = socki_lookup(inode))) {
357 printk("NET: sock_close: can't find socket for inode!\n");
358 return;
359 }
360 sock_release(sock);
361 }
362
363
364 int
365 sock_awaitconn(struct socket *mysock, struct socket *servsock)
366 {
367 struct socket *last;
368
369 DPRINTF((net_debug,
370 "NET: sock_awaitconn: trying to connect socket 0x%x to 0x%x\n",
371 mysock, servsock));
372 if (!(servsock->flags & SO_ACCEPTCON)) {
373 DPRINTF((net_debug,
374 "NET: sock_awaitconn: server not accepting connections\n"));
375 return(-EINVAL);
376 }
377
378
379 mysock->next = NULL;
380 cli();
381 if (!(last = servsock->iconn)) servsock->iconn = mysock;
382 else {
383 while (last->next) last = last->next;
384 last->next = mysock;
385 }
386 mysock->state = SS_CONNECTING;
387 mysock->conn = servsock;
388 sti();
389
390
391
392
393
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) {
399
400
401
402
403
404
405
406 if (mysock->conn == servsock) {
407 cli();
408 if ((last = servsock->iconn) == mysock)
409 servsock->iconn = mysock->next;
410 else {
411 while (last->next != mysock) last = last->next;
412 last->next = mysock->next;
413 }
414 sti();
415 }
416 return(mysock->conn ? -EINTR : -EACCES);
417 }
418 }
419 return(0);
420 }
421
422
423
424
425
426
427 static int
428 sock_socket(int family, int type, int protocol)
429 {
430 int i, fd;
431 struct socket *sock;
432 struct proto_ops *ops;
433
434 DPRINTF((net_debug,
435 "NET: sock_socket: family = %d, type = %d, protocol = %d\n",
436 family, type, protocol));
437
438
439 for (i = 0; i < NPROTO; ++i) {
440 if (pops[i] == NULL) continue;
441 if (pops[i]->family == family) break;
442 }
443 if (i == NPROTO) {
444 DPRINTF((net_debug, "NET: sock_socket: family not found\n"));
445 return(-EINVAL);
446 }
447 ops = pops[i];
448
449
450
451
452
453
454 if ((type != SOCK_STREAM && type != SOCK_DGRAM &&
455 type != SOCK_SEQPACKET && type != SOCK_RAW &&
456 type != SOCK_PACKET) || protocol < 0)
457 return(-EINVAL);
458
459
460
461
462
463
464 if (!(sock = sock_alloc(1))) {
465 printk("sock_socket: no more sockets\n");
466 return(-EAGAIN);
467 }
468 sock->type = type;
469 sock->ops = ops;
470 if ((i = sock->ops->create(sock, protocol)) < 0) {
471 sock_release(sock);
472 return(i);
473 }
474
475 if ((fd = get_fd(SOCK_INODE(sock))) < 0) {
476 sock_release(sock);
477 return(-EINVAL);
478 }
479
480 return(fd);
481 }
482
483
484 static int
485 sock_socketpair(int family, int type, int protocol, unsigned long usockvec[2])
486 {
487 int fd1, fd2, i;
488 struct socket *sock1, *sock2;
489 int er;
490
491 DPRINTF((net_debug,
492 "NET: sock_socketpair: family = %d, type = %d, protocol = %d\n",
493 family, type, protocol));
494
495
496
497
498
499 if ((fd1 = sock_socket(family, type, protocol)) < 0) return(fd1);
500 sock1 = sockfd_lookup(fd1, NULL);
501 if (!sock1->ops->socketpair) {
502 sys_close(fd1);
503 return(-EINVAL);
504 }
505
506
507 if ((fd2 = sock_socket(family, type, protocol)) < 0) {
508 sys_close(fd1);
509 return(-EINVAL);
510 }
511 sock2 = sockfd_lookup(fd2, NULL);
512 if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) {
513 sys_close(fd1);
514 sys_close(fd2);
515 return(i);
516 }
517 sock1->conn = sock2;
518 sock2->conn = sock1;
519 sock1->state = SS_CONNECTED;
520 sock2->state = SS_CONNECTED;
521
522 er=verify_area(VERIFY_WRITE, usockvec, 2 * sizeof(int));
523 if(er)
524 return er;
525 put_fs_long(fd1, &usockvec[0]);
526 put_fs_long(fd2, &usockvec[1]);
527
528 return(0);
529 }
530
531
532
533
534
535
536 static int
537 sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
538 {
539 struct socket *sock;
540 int i;
541
542 DPRINTF((net_debug, "NET: sock_bind: fd = %d\n", fd));
543 if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
544 return(-EBADF);
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"));
548 return(i);
549 }
550 return(0);
551 }
552
553
554
555
556
557
558
559 static int
560 sock_listen(int fd, int backlog)
561 {
562 struct socket *sock;
563
564 DPRINTF((net_debug, "NET: sock_listen: fd = %d\n", fd));
565 if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
566 return(-EBADF);
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"));
570 return(-EINVAL);
571 }
572 if (sock->ops && sock->ops->listen) sock->ops->listen(sock, backlog);
573 sock->flags |= SO_ACCEPTCON;
574 return(0);
575 }
576
577
578
579
580
581
582
583 static int
584 sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
585 {
586 struct file *file;
587 struct socket *sock, *newsock;
588 int i;
589
590 DPRINTF((net_debug, "NET: sock_accept: fd = %d\n", fd));
591 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
592 return(-EBADF);
593
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"));
597 return(-EINVAL);
598 }
599 if (!(sock->flags & SO_ACCEPTCON)) {
600 DPRINTF((net_debug,
601 "NET: sock_accept: socket not accepting connections!\n"));
602 return(-EINVAL);
603 }
604
605 if (!(newsock = sock_alloc(0))) {
606 printk("NET: sock_accept: no more sockets\n");
607 return(-EAGAIN);
608 }
609 newsock->type = sock->type;
610 newsock->ops = sock->ops;
611 if ((i = sock->ops->dup(newsock, sock)) < 0) {
612 sock_release(newsock);
613 return(i);
614 }
615
616 i = newsock->ops->accept(sock, newsock, file->f_flags);
617 if ( i < 0) {
618 sock_release(newsock);
619 return(i);
620 }
621
622 if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
623 sock_release(newsock);
624 return(-EINVAL);
625 }
626
627 DPRINTF((net_debug, "NET: sock_accept: connected socket 0x%x via 0x%x\n",
628 sock, newsock));
629
630 if (upeer_sockaddr)
631 newsock->ops->getname(newsock, upeer_sockaddr, upeer_addrlen, 1);
632
633 return(fd);
634 }
635
636
637
638 static int
639 sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
640 {
641 struct socket *sock;
642 struct file *file;
643 int i;
644
645 DPRINTF((net_debug, "NET: sock_connect: fd = %d\n", fd));
646 if (fd < 0 || fd >= NR_OPEN || (file=current->filp[fd]) == NULL)
647 return(-EBADF);
648
649 if (!(sock = sockfd_lookup(fd, &file))) return(-ENOTSOCK);
650 switch(sock->state) {
651 case SS_UNCONNECTED:
652
653 break;
654 case SS_CONNECTED:
655
656 return -EISCONN;
657 case SS_CONNECTING:
658
659 return(sock->ops->connect(sock, uservaddr,
660 addrlen, file->f_flags));
661 default:
662 DPRINTF((net_debug,
663 "NET: sock_connect: socket not unconnected\n"));
664 return(-EINVAL);
665 }
666 i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
667 if (i < 0) {
668 DPRINTF((net_debug, "NET: sock_connect: connect failed\n"));
669 return(i);
670 }
671 return(0);
672 }
673
674
675 static int
676 sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
677 {
678 struct socket *sock;
679
680 DPRINTF((net_debug, "NET: sock_getsockname: fd = %d\n", fd));
681 if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
682 return(-EBADF);
683 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
684 return(sock->ops->getname(sock, usockaddr, usockaddr_len, 0));
685 }
686
687
688 static int
689 sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len)
690 {
691 struct socket *sock;
692
693 DPRINTF((net_debug, "NET: sock_getpeername: fd = %d\n", fd));
694 if (fd < 0 || fd >= NR_OPEN || current->filp[fd] == NULL)
695 return(-EBADF);
696 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
697 return(sock->ops->getname(sock, usockaddr, usockaddr_len, 1));
698 }
699
700
701 static int
702 sock_send(int fd, void * buff, int len, unsigned flags)
703 {
704 struct socket *sock;
705 struct file *file;
706
707 DPRINTF((net_debug,
708 "NET: sock_send(fd = %d, buff = %X, len = %d, flags = %X)\n",
709 fd, buff, len, flags));
710
711 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
712 return(-EBADF);
713 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
714
715 return(sock->ops->send(sock, buff, len, (file->f_flags & O_NONBLOCK), flags));
716 }
717
718
719 static int
720 sock_sendto(int fd, void * buff, int len, unsigned flags,
721 struct sockaddr *addr, int addr_len)
722 {
723 struct socket *sock;
724 struct file *file;
725
726 DPRINTF((net_debug,
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));
729
730 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
731 return(-EBADF);
732 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
733
734 return(sock->ops->sendto(sock, buff, len, (file->f_flags & O_NONBLOCK),
735 flags, addr, addr_len));
736 }
737
738
739 static int
740 sock_recv(int fd, void * buff, int len, unsigned flags)
741 {
742 struct socket *sock;
743 struct file *file;
744
745 DPRINTF((net_debug,
746 "NET: sock_recv(fd = %d, buff = %X, len = %d, flags = %X)\n",
747 fd, buff, len, flags));
748
749 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
750 return(-EBADF);
751 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
752
753 return(sock->ops->recv(sock, buff, len,(file->f_flags & O_NONBLOCK), flags));
754 }
755
756
757 static int
758 sock_recvfrom(int fd, void * buff, int len, unsigned flags,
759 struct sockaddr *addr, int *addr_len)
760 {
761 struct socket *sock;
762 struct file *file;
763
764 DPRINTF((net_debug,
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));
767
768 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
769 return(-EBADF);
770 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
771
772 return(sock->ops->recvfrom(sock, buff, len, (file->f_flags & O_NONBLOCK),
773 flags, addr, addr_len));
774 }
775
776
777 static int
778 sock_setsockopt(int fd, int level, int optname, char *optval, int optlen)
779 {
780 struct socket *sock;
781 struct file *file;
782
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",
786 optval, optlen));
787
788 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
789 return(-EBADF);
790 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
791
792 return(sock->ops->setsockopt(sock, level, optname, optval, optlen));
793 }
794
795
796 static int
797 sock_getsockopt(int fd, int level, int optname, char *optval, int *optlen)
798 {
799 struct socket *sock;
800 struct file *file;
801
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",
805 optval, optlen));
806
807 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
808 return(-EBADF);
809 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
810
811 if (!sock->ops || !sock->ops->getsockopt) return(0);
812 return(sock->ops->getsockopt(sock, level, optname, optval, optlen));
813 }
814
815
816 static int
817 sock_shutdown(int fd, int how)
818 {
819 struct socket *sock;
820 struct file *file;
821
822 DPRINTF((net_debug, "NET: sock_shutdown(fd = %d, how = %d)\n", fd, how));
823
824 if (fd < 0 || fd >= NR_OPEN || ((file = current->filp[fd]) == NULL))
825 return(-EBADF);
826
827 if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);
828
829 return(sock->ops->shutdown(sock, how));
830 }
831
832
833 int
834 sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg)
835 {
836 struct socket *sock;
837
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));
841 return(-EINVAL);
842 }
843
844
845
846
847
848
849
850 asmlinkage int
851 sys_socketcall(int call, unsigned long *args)
852 {
853 int er;
854 switch(call) {
855 case SYS_SOCKET:
856 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
857 if(er)
858 return er;
859 return(sock_socket(get_fs_long(args+0),
860 get_fs_long(args+1),
861 get_fs_long(args+2)));
862 case SYS_BIND:
863 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
864 if(er)
865 return er;
866 return(sock_bind(get_fs_long(args+0),
867 (struct sockaddr *)get_fs_long(args+1),
868 get_fs_long(args+2)));
869 case SYS_CONNECT:
870 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
871 if(er)
872 return er;
873 return(sock_connect(get_fs_long(args+0),
874 (struct sockaddr *)get_fs_long(args+1),
875 get_fs_long(args+2)));
876 case SYS_LISTEN:
877 er=verify_area(VERIFY_READ, args, 2 * sizeof(long));
878 if(er)
879 return er;
880 return(sock_listen(get_fs_long(args+0),
881 get_fs_long(args+1)));
882 case SYS_ACCEPT:
883 er=verify_area(VERIFY_READ, args, 3 * sizeof(long));
884 if(er)
885 return er;
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));
891 if(er)
892 return er;
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));
898 if(er)
899 return er;
900 return(sock_getpeername(get_fs_long(args+0),
901 (struct sockaddr *)get_fs_long(args+1),
902 (int *)get_fs_long(args+2)));
903 case SYS_SOCKETPAIR:
904 er=verify_area(VERIFY_READ, args, 4 * sizeof(long));
905 if(er)
906 return er;
907 return(sock_socketpair(get_fs_long(args+0),
908 get_fs_long(args+1),
909 get_fs_long(args+2),
910 (unsigned long *)get_fs_long(args+3)));
911 case SYS_SEND:
912 er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
913 if(er)
914 return er;
915 return(sock_send(get_fs_long(args+0),
916 (void *)get_fs_long(args+1),
917 get_fs_long(args+2),
918 get_fs_long(args+3)));
919 case SYS_SENDTO:
920 er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
921 if(er)
922 return er;
923 return(sock_sendto(get_fs_long(args+0),
924 (void *)get_fs_long(args+1),
925 get_fs_long(args+2),
926 get_fs_long(args+3),
927 (struct sockaddr *)get_fs_long(args+4),
928 get_fs_long(args+5)));
929 case SYS_RECV:
930 er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long));
931 if(er)
932 return er;
933 return(sock_recv(get_fs_long(args+0),
934 (void *)get_fs_long(args+1),
935 get_fs_long(args+2),
936 get_fs_long(args+3)));
937 case SYS_RECVFROM:
938 er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long));
939 if(er)
940 return er;
941 return(sock_recvfrom(get_fs_long(args+0),
942 (void *)get_fs_long(args+1),
943 get_fs_long(args+2),
944 get_fs_long(args+3),
945 (struct sockaddr *)get_fs_long(args+4),
946 (int *)get_fs_long(args+5)));
947 case SYS_SHUTDOWN:
948 er=verify_area(VERIFY_READ, args, 2* sizeof(unsigned long));
949 if(er)
950 return er;
951 return(sock_shutdown(get_fs_long(args+0),
952 get_fs_long(args+1)));
953 case SYS_SETSOCKOPT:
954 er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
955 if(er)
956 return er;
957 return(sock_setsockopt(get_fs_long(args+0),
958 get_fs_long(args+1),
959 get_fs_long(args+2),
960 (char *)get_fs_long(args+3),
961 get_fs_long(args+4)));
962 case SYS_GETSOCKOPT:
963 er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long));
964 if(er)
965 return er;
966 return(sock_getsockopt(get_fs_long(args+0),
967 get_fs_long(args+1),
968 get_fs_long(args+2),
969 (char *)get_fs_long(args+3),
970 (int *)get_fs_long(args+4)));
971 default:
972 return(-EINVAL);
973 }
974 }
975
976
977 static int
978 net_ioctl(unsigned int cmd, unsigned long arg)
979 {
980 int er;
981 switch(cmd) {
982 case DDIOCSDBG:
983 er=verify_area(VERIFY_READ, (void *)arg, sizeof(long));
984 if(er)
985 return er;
986 net_debug = get_fs_long((long *)arg);
987 if (net_debug != 0 && net_debug != 1) {
988 net_debug = 0;
989 return(-EINVAL);
990 }
991 return(0);
992 default:
993 return(-EINVAL);
994 }
995
996 return(0);
997 }
998
999
1000
1001
1002
1003
1004
1005
1006
1007 static int
1008 net_fioctl(struct inode *inode, struct file *file,
1009 unsigned int cmd, unsigned long arg)
1010 {
1011 extern int arp_ioctl(unsigned int, void *);
1012
1013
1014 switch(MINOR(inode->i_rdev)) {
1015 case 0:
1016 DPRINTF((net_debug, "NET: SOCKET level I/O control request.\n"));
1017 return(net_ioctl(cmd, arg));
1018 #ifdef CONFIG_INET
1019 case 1:
1020 DPRINTF((net_debug, "NET: ARP level I/O control request.\n"));
1021 return(arp_ioctl(cmd, (void *) arg));
1022 #endif
1023 default:
1024 return(-ENODEV);
1025 }
1026
1027 return(-EINVAL);
1028 }
1029
1030
1031 static struct file_operations net_fops = {
1032 NULL,
1033 NULL,
1034 NULL,
1035 NULL,
1036 NULL,
1037 net_fioctl,
1038 NULL,
1039 NULL,
1040 NULL
1041 };
1042
1043
1044
1045
1046
1047
1048
1049 int
1050 sock_register(int family, struct proto_ops *ops)
1051 {
1052 int i;
1053
1054 cli();
1055 for(i = 0; i < NPROTO; i++) {
1056 if (pops[i] != NULL) continue;
1057 pops[i] = ops;
1058 pops[i]->family = family;
1059 sti();
1060 DPRINTF((net_debug, "NET: Installed protocol %d in slot %d (0x%X)\n",
1061 family, i, (long)ops));
1062 return(i);
1063 }
1064 sti();
1065 return(-ENOMEM);
1066 }
1067
1068
1069 void
1070 sock_init(void)
1071 {
1072 struct socket *sock;
1073 int i;
1074
1075
1076 if (register_chrdev(SOCKET_MAJOR, "socket", &net_fops) < 0) {
1077 printk("NET: cannot register major device %d!\n", SOCKET_MAJOR);
1078 return;
1079 }
1080
1081
1082 for (sock = sockets; sock <= last_socket; ++sock) sock->state = SS_FREE;
1083
1084
1085 for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
1086
1087
1088 ddi_init();
1089
1090
1091 #if 0
1092 arp_init();
1093 #endif
1094 }