This source file includes following definitions.
- min
- unix_lock
- unix_unlock
- unix_proto_listen
- unix_proto_setsockopt
- unix_proto_getsockopt
- unix_proto_sendto
- unix_proto_recvfrom
- unix_proto_shutdown
- unix_proto_send
- unix_proto_recv
- unix_data_lookup
- unix_data_alloc
- unix_data_ref
- unix_data_deref
- unix_proto_create
- unix_proto_dup
- unix_proto_release
- unix_proto_bind
- unix_proto_connect
- unix_proto_socketpair
- unix_proto_accept
- unix_proto_getname
- unix_proto_read
- unix_proto_write
- unix_proto_select
- unix_proto_ioctl
- unix_proto_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/config.h>
31 #include <linux/kernel.h>
32 #include <linux/major.h>
33 #include <linux/signal.h>
34 #include <linux/sched.h>
35 #include <linux/errno.h>
36 #include <linux/string.h>
37 #include <linux/stat.h>
38 #include <linux/socket.h>
39 #include <linux/un.h>
40 #include <linux/fcntl.h>
41 #include <linux/termios.h>
42 #include <linux/sockios.h>
43 #include <linux/net.h>
44 #include <linux/fs.h>
45 #include <linux/malloc.h>
46
47 #include <asm/system.h>
48 #include <asm/segment.h>
49
50 #include <stdarg.h>
51
52 #include "unix.h"
53
54 struct unix_proto_data unix_datas[NSOCKETS];
55
56 static int unix_proto_create(struct socket *sock, int protocol);
57 static int unix_proto_dup(struct socket *newsock, struct socket *oldsock);
58 static int unix_proto_release(struct socket *sock, struct socket *peer);
59 static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
60 int sockaddr_len);
61 static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
62 int sockaddr_len, int flags);
63 static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2);
64 static int unix_proto_accept(struct socket *sock, struct socket *newsock,
65 int flags);
66 static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
67 int *usockaddr_len, int peer);
68 static int unix_proto_read(struct socket *sock, char *ubuf, int size,
69 int nonblock);
70 static int unix_proto_write(struct socket *sock, char *ubuf, int size,
71 int nonblock);
72 static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait);
73 static int unix_proto_ioctl(struct socket *sock, unsigned int cmd,
74 unsigned long arg);
75 static int unix_proto_listen(struct socket *sock, int backlog);
76 static int unix_proto_send(struct socket *sock, void *buff, int len,
77 int nonblock, unsigned flags);
78 static int unix_proto_recv(struct socket *sock, void *buff, int len,
79 int nonblock, unsigned flags);
80 static int unix_proto_sendto(struct socket *sock, void *buff, int len,
81 int nonblock, unsigned flags,
82 struct sockaddr *addr, int addr_len);
83 static int unix_proto_recvfrom(struct socket *sock, void *buff, int len,
84 int nonblock, unsigned flags,
85 struct sockaddr *addr, int *addr_len);
86
87 static int unix_proto_shutdown(struct socket *sock, int how);
88
89 static int unix_proto_setsockopt(struct socket *sock, int level, int optname,
90 char *optval, int optlen);
91 static int unix_proto_getsockopt(struct socket *sock, int level, int optname,
92 char *optval, int *optlen);
93
94
95 static inline int
96 min(int a, int b)
97 {
98 if (a < b) return(a);
99 return(b);
100 }
101
102
103
104
105
106
107
108
109
110
111
112
113 static void unix_lock(struct unix_proto_data *upd)
114 {
115 while (upd->lock_flag)
116 sleep_on(&upd->wait);
117 upd->lock_flag = 1;
118 }
119
120
121 static void unix_unlock(struct unix_proto_data *upd)
122 {
123 upd->lock_flag = 0;
124 wake_up(&upd->wait);
125 }
126
127
128 static int
129 unix_proto_listen(struct socket *sock, int backlog)
130 {
131 return(0);
132 }
133
134
135 static int
136 unix_proto_setsockopt(struct socket *sock, int level, int optname,
137 char *optval, int optlen)
138 {
139 return(-EOPNOTSUPP);
140 }
141
142
143 static int
144 unix_proto_getsockopt(struct socket *sock, int level, int optname,
145 char *optval, int *optlen)
146 {
147 return(-EOPNOTSUPP);
148 }
149
150 static int
151 unix_proto_sendto(struct socket *sock, void *buff, int len, int nonblock,
152 unsigned flags, struct sockaddr *addr, int addr_len)
153 {
154 return(-EOPNOTSUPP);
155 }
156
157 static int
158 unix_proto_recvfrom(struct socket *sock, void *buff, int len, int nonblock,
159 unsigned flags, struct sockaddr *addr, int *addr_len)
160 {
161 return(-EOPNOTSUPP);
162 }
163
164
165 static int
166 unix_proto_shutdown(struct socket *sock, int how)
167 {
168 return(-EOPNOTSUPP);
169 }
170
171
172
173 static int
174 unix_proto_send(struct socket *sock, void *buff, int len, int nonblock,
175 unsigned flags)
176 {
177 if (flags != 0) return(-EINVAL);
178 return(unix_proto_write(sock, (char *) buff, len, nonblock));
179 }
180
181
182
183 static int
184 unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
185 unsigned flags)
186 {
187 if (flags != 0) return(-EINVAL);
188 return(unix_proto_read(sock, (char *) buff, len, nonblock));
189 }
190
191
192 static struct unix_proto_data *
193 unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len,
194 struct inode *inode)
195 {
196 struct unix_proto_data *upd;
197
198 for(upd = unix_datas; upd <= last_unix_data; ++upd) {
199 if (upd->refcnt > 0 && upd->socket &&
200 upd->socket->state == SS_UNCONNECTED &&
201 upd->sockaddr_un.sun_family == sockun->sun_family &&
202 upd->inode == inode) return(upd);
203 }
204 return(NULL);
205 }
206
207
208 static struct unix_proto_data *
209 unix_data_alloc(void)
210 {
211 struct unix_proto_data *upd;
212
213 cli();
214 for(upd = unix_datas; upd <= last_unix_data; ++upd) {
215 if (!upd->refcnt) {
216 upd->refcnt = -1;
217 sti();
218 upd->socket = NULL;
219 upd->sockaddr_len = 0;
220 upd->sockaddr_un.sun_family = 0;
221 upd->buf = NULL;
222 upd->bp_head = upd->bp_tail = 0;
223 upd->inode = NULL;
224 upd->peerupd = NULL;
225 return(upd);
226 }
227 }
228 sti();
229 return(NULL);
230 }
231
232
233 static inline void
234 unix_data_ref(struct unix_proto_data *upd)
235 {
236 if (!upd) {
237 return;
238 }
239 ++upd->refcnt;
240 }
241
242
243 static void
244 unix_data_deref(struct unix_proto_data *upd)
245 {
246 if (!upd) {
247 return;
248 }
249 if (upd->refcnt == 1) {
250 if (upd->buf) {
251 free_page((unsigned long)upd->buf);
252 upd->buf = NULL;
253 upd->bp_head = upd->bp_tail = 0;
254 }
255 }
256 --upd->refcnt;
257 }
258
259
260
261
262
263
264 static int
265 unix_proto_create(struct socket *sock, int protocol)
266 {
267 struct unix_proto_data *upd;
268
269 if (protocol != 0) {
270 return(-EINVAL);
271 }
272 if (!(upd = unix_data_alloc())) {
273 printk("UNIX: create: can't allocate buffer\n");
274 return(-ENOMEM);
275 }
276 if (!(upd->buf = (char*) get_free_page(GFP_USER))) {
277 printk("UNIX: create: can't get page!\n");
278 unix_data_deref(upd);
279 return(-ENOMEM);
280 }
281 upd->protocol = protocol;
282 upd->socket = sock;
283 UN_DATA(sock) = upd;
284 upd->refcnt = 1;
285 return(0);
286 }
287
288
289 static int
290 unix_proto_dup(struct socket *newsock, struct socket *oldsock)
291 {
292 struct unix_proto_data *upd = UN_DATA(oldsock);
293
294 return(unix_proto_create(newsock, upd->protocol));
295 }
296
297
298 static int
299 unix_proto_release(struct socket *sock, struct socket *peer)
300 {
301 struct unix_proto_data *upd = UN_DATA(sock);
302
303 if (!upd) return(0);
304 if (upd->socket != sock) {
305 printk("UNIX: release: socket link mismatch!\n");
306 return(-EINVAL);
307 }
308 if (upd->inode) {
309 iput(upd->inode);
310 upd->inode = NULL;
311 }
312 UN_DATA(sock) = NULL;
313 upd->socket = NULL;
314 if (upd->peerupd) unix_data_deref(upd->peerupd);
315 unix_data_deref(upd);
316 return(0);
317 }
318
319
320
321
322
323
324
325
326
327
328
329 static int
330 unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
331 int sockaddr_len)
332 {
333 char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
334 struct unix_proto_data *upd = UN_DATA(sock);
335 unsigned long old_fs;
336 int i;
337 int er;
338
339 if (sockaddr_len <= UN_PATH_OFFSET ||
340 sockaddr_len > sizeof(struct sockaddr_un)) {
341 return(-EINVAL);
342 }
343 if (upd->sockaddr_len || upd->inode) {
344 printk("UNIX: bind: already bound!\n");
345 return(-EINVAL);
346 }
347 er=verify_area(VERIFY_WRITE, umyaddr, sockaddr_len);
348 if(er)
349 return er;
350 memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len);
351 upd->sockaddr_un.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
352 if (upd->sockaddr_un.sun_family != AF_UNIX) {
353 return(-EINVAL);
354 }
355
356 memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET);
357 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
358 old_fs = get_fs();
359 set_fs(get_ds());
360 i = do_mknod(fname, S_IFSOCK | S_IRWXUGO, 0);
361 if (i == 0) i = open_namei(fname, 0, S_IFSOCK, &upd->inode, NULL);
362 set_fs(old_fs);
363 if (i < 0) {
364 printk("UNIX: bind: can't open socket %s\n", fname);
365 return(i);
366 }
367 upd->sockaddr_len = sockaddr_len;
368
369 return(0);
370 }
371
372
373
374
375
376
377
378 static int
379 unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
380 int sockaddr_len, int flags)
381 {
382 char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
383 struct sockaddr_un sockun;
384 struct unix_proto_data *serv_upd;
385 struct inode *inode;
386 unsigned long old_fs;
387 int i;
388 int er;
389
390 if (sockaddr_len <= UN_PATH_OFFSET ||
391 sockaddr_len > sizeof(struct sockaddr_un)) {
392 return(-EINVAL);
393 }
394 if (sock->state == SS_CONNECTING) return(-EINPROGRESS);
395 if (sock->state == SS_CONNECTED) return(-EISCONN);
396
397 er=verify_area(VERIFY_READ, uservaddr, sockaddr_len);
398 if(er)
399 return er;
400 memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
401 sockun.sun_path[sockaddr_len-UN_PATH_OFFSET] = '\0';
402 if (sockun.sun_family != AF_UNIX) {
403 return(-EINVAL);
404 }
405
406
407
408
409
410
411
412 memcpy(fname, sockun.sun_path, sockaddr_len-UN_PATH_OFFSET);
413 fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
414 old_fs = get_fs();
415 set_fs(get_ds());
416 i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
417 set_fs(old_fs);
418 if (i < 0) {
419 return(i);
420 }
421
422 serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
423 iput(inode);
424 if (!serv_upd) {
425 return(-EINVAL);
426 }
427 if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
428 return(i);
429 }
430 if (sock->conn) {
431 unix_data_ref(UN_DATA(sock->conn));
432 UN_DATA(sock)->peerupd = UN_DATA(sock->conn);
433 }
434 return(0);
435 }
436
437
438
439
440
441
442
443
444 static int
445 unix_proto_socketpair(struct socket *sock1, struct socket *sock2)
446 {
447 struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2);
448
449 unix_data_ref(upd1);
450 unix_data_ref(upd2);
451 upd1->peerupd = upd2;
452 upd2->peerupd = upd1;
453 return(0);
454 }
455
456
457
458 static int
459 unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
460 {
461 struct socket *clientsock;
462
463
464
465
466
467 while(!(clientsock = sock->iconn)) {
468 if (flags & O_NONBLOCK) return(-EAGAIN);
469 interruptible_sleep_on(sock->wait);
470 if (current->signal & ~current->blocked) {
471 return(-ERESTARTSYS);
472 }
473 }
474
475
476
477
478
479 sock->iconn = clientsock->next;
480 clientsock->next = NULL;
481 newsock->conn = clientsock;
482 clientsock->conn = newsock;
483 clientsock->state = SS_CONNECTED;
484 newsock->state = SS_CONNECTED;
485 unix_data_ref(UN_DATA(clientsock));
486 UN_DATA(newsock)->peerupd = UN_DATA(clientsock);
487 UN_DATA(newsock)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
488 UN_DATA(newsock)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
489 wake_up_interruptible(clientsock->wait);
490 return(0);
491 }
492
493
494
495 static int
496 unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr,
497 int *usockaddr_len, int peer)
498 {
499 struct unix_proto_data *upd;
500 int len;
501 int er;
502
503 if (peer) {
504 if (sock->state != SS_CONNECTED) {
505 return(-EINVAL);
506 }
507 upd = UN_DATA(sock->conn);
508 } else
509 upd = UN_DATA(sock);
510
511 er=verify_area(VERIFY_WRITE, usockaddr_len, sizeof(*usockaddr_len));
512 if(er)
513 return er;
514 if ((len = get_fs_long(usockaddr_len)) <= 0) return(-EINVAL);
515 if (len > upd->sockaddr_len) len = upd->sockaddr_len;
516 if (len) {
517 er=verify_area(VERIFY_WRITE, usockaddr, len);
518 if(er)
519 return er;
520 memcpy_tofs(usockaddr, &upd->sockaddr_un, len);
521 }
522 put_fs_long(len, usockaddr_len);
523 return(0);
524 }
525
526
527
528 static int
529 unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock)
530 {
531 struct unix_proto_data *upd;
532 int todo, avail;
533 int er;
534
535 if ((todo = size) <= 0) return(0);
536 upd = UN_DATA(sock);
537 while(!(avail = UN_BUF_AVAIL(upd))) {
538 if (sock->state != SS_CONNECTED) {
539 return((sock->state == SS_DISCONNECTING) ? 0 : -EINVAL);
540 }
541 if (nonblock) return(-EAGAIN);
542 interruptible_sleep_on(sock->wait);
543 if (current->signal & ~current->blocked) {
544 return(-ERESTARTSYS);
545 }
546 }
547
548
549
550
551
552
553 unix_lock(upd);
554 do {
555 int part, cando;
556
557 if (avail <= 0) {
558 printk("UNIX: read: AVAIL IS NEGATIVE!!!\n");
559 send_sig(SIGKILL, current, 1);
560 return(-EPIPE);
561 }
562
563 if ((cando = todo) > avail) cando = avail;
564 if (cando >(part = BUF_SIZE - upd->bp_tail)) cando = part;
565 if((er=verify_area(VERIFY_WRITE,ubuf,cando))<0)
566 {
567 unix_unlock(upd);
568 return er;
569 }
570 memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando);
571 upd->bp_tail =(upd->bp_tail + cando) &(BUF_SIZE-1);
572 ubuf += cando;
573 todo -= cando;
574 if (sock->state == SS_CONNECTED)
575 wake_up_interruptible(sock->conn->wait);
576 avail = UN_BUF_AVAIL(upd);
577 } while(todo && avail);
578 unix_unlock(upd);
579 return(size - todo);
580 }
581
582
583
584
585
586
587
588 static int
589 unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock)
590 {
591 struct unix_proto_data *pupd;
592 int todo, space;
593 int er;
594
595 if ((todo = size) <= 0) return(0);
596 if (sock->state != SS_CONNECTED) {
597 if (sock->state == SS_DISCONNECTING) {
598 send_sig(SIGPIPE, current, 1);
599 return(-EPIPE);
600 }
601 return(-EINVAL);
602 }
603 pupd = UN_DATA(sock)->peerupd;
604
605 while(!(space = UN_BUF_SPACE(pupd))) {
606 if (nonblock) return(-EAGAIN);
607 interruptible_sleep_on(sock->wait);
608 if (current->signal & ~current->blocked) {
609 return(-ERESTARTSYS);
610 }
611 if (sock->state == SS_DISCONNECTING) {
612 send_sig(SIGPIPE, current, 1);
613 return(-EPIPE);
614 }
615 }
616
617
618
619
620
621
622 unix_lock(pupd);
623
624 do {
625 int part, cando;
626
627 if (space <= 0) {
628 printk("UNIX: write: SPACE IS NEGATIVE!!!\n");
629 send_sig(SIGKILL, current, 1);
630 return(-EPIPE);
631 }
632
633
634
635
636
637 if (sock->state == SS_DISCONNECTING) {
638 send_sig(SIGPIPE, current, 1);
639 unix_unlock(pupd);
640 return(-EPIPE);
641 }
642 if ((cando = todo) > space) cando = space;
643 if (cando >(part = BUF_SIZE - pupd->bp_head)) cando = part;
644 er=verify_area(VERIFY_READ, ubuf, cando);
645 if(er)
646 {
647 unix_unlock(pupd);
648 return er;
649 }
650 memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando);
651 pupd->bp_head =(pupd->bp_head + cando) &(BUF_SIZE-1);
652 ubuf += cando;
653 todo -= cando;
654 if (sock->state == SS_CONNECTED)
655 wake_up_interruptible(sock->conn->wait);
656 space = UN_BUF_SPACE(pupd);
657 } while(todo && space);
658 unix_unlock(pupd);
659 return(size - todo);
660 }
661
662
663 static int
664 unix_proto_select(struct socket *sock, int sel_type, select_table * wait)
665 {
666 struct unix_proto_data *upd, *peerupd;
667
668
669 if (sock->flags & SO_ACCEPTCON) {
670 if (sel_type == SEL_IN) {
671 if (sock->iconn) return(1);
672 select_wait(sock->wait, wait);
673 return(sock->iconn ? 1 : 0);
674 }
675 select_wait(sock->wait, wait);
676 return(0);
677 }
678
679 if (sel_type == SEL_IN) {
680 upd = UN_DATA(sock);
681 if (UN_BUF_AVAIL(upd))
682 return(1);
683 else if (sock->state != SS_CONNECTED) {
684 return(1);
685 }
686 select_wait(sock->wait,wait);
687 return(0);
688 }
689 if (sel_type == SEL_OUT) {
690 if (sock->state != SS_CONNECTED) {
691 return(1);
692 }
693 peerupd = UN_DATA(sock->conn);
694 if (UN_BUF_SPACE(peerupd) > 0) return(1);
695 select_wait(sock->wait,wait);
696 return(0);
697 }
698
699
700 return(0);
701 }
702
703
704 static int
705 unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
706 {
707 struct unix_proto_data *upd, *peerupd;
708 int er;
709
710 upd = UN_DATA(sock);
711 peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL;
712
713 switch(cmd) {
714 case TIOCINQ:
715 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
716 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
717 if(er)
718 return er;
719 if (UN_BUF_AVAIL(upd) || peerupd)
720 put_fs_long(UN_BUF_AVAIL(upd),(unsigned long *)arg);
721 else
722 put_fs_long(0,(unsigned long *)arg);
723 break;
724 case TIOCOUTQ:
725 if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
726 er=verify_area(VERIFY_WRITE,(void *)arg, sizeof(unsigned long));
727 if(er)
728 return er;
729 if (peerupd) put_fs_long(UN_BUF_SPACE(peerupd),
730 (unsigned long *)arg);
731 else
732 put_fs_long(0,(unsigned long *)arg);
733 break;
734 default:
735 return(-EINVAL);
736 }
737 return(0);
738 }
739
740
741 static struct proto_ops unix_proto_ops = {
742 AF_UNIX,
743 unix_proto_create,
744 unix_proto_dup,
745 unix_proto_release,
746 unix_proto_bind,
747 unix_proto_connect,
748 unix_proto_socketpair,
749 unix_proto_accept,
750 unix_proto_getname,
751 unix_proto_read,
752 unix_proto_write,
753 unix_proto_select,
754 unix_proto_ioctl,
755 unix_proto_listen,
756 unix_proto_send,
757 unix_proto_recv,
758 unix_proto_sendto,
759 unix_proto_recvfrom,
760 unix_proto_shutdown,
761 unix_proto_setsockopt,
762 unix_proto_getsockopt,
763 NULL
764 };
765
766
767 void
768 unix_proto_init(struct net_proto *pro)
769 {
770 struct unix_proto_data *upd;
771
772
773 (void) sock_register(unix_proto_ops.family, &unix_proto_ops);
774
775 for(upd = unix_datas; upd <= last_unix_data; ++upd) {
776 upd->refcnt = 0;
777 }
778 }