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