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