xref: /plan9-contrib/sys/src/9/ip/devip.c (revision 25fc69938fdecc61cd09e795cbe2d2f72f1082b1)
1 #include	"u.h"
2 #include	"../port/lib.h"
3 #include	"mem.h"
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"../port/error.h"
7 #include	"../ip/ip.h"
8 
9 enum
10 {
11 	Qtopdir=	1,		/* top level directory */
12 	Qtopbase,
13 	Qarp=		Qtopbase,
14 	Qbootp,
15 	Qndb,
16 	Qiproute,
17 	Qipselftab,
18 	Qlog,
19 
20 	Qprotodir,			/* directory for a protocol */
21 	Qprotobase,
22 	Qclone=		Qprotobase,
23 	Qstats,
24 
25 	Qconvdir,			/* directory for a conversation */
26 	Qconvbase,
27 	Qctl=		Qconvbase,
28 	Qdata,
29 	Qerr,
30 	Qlisten,
31 	Qlocal,
32 	Qremote,
33 	Qstatus,
34 	Qsnoop,
35 
36 	Logtype=	5,
37 	Masktype=	(1<<Logtype)-1,
38 	Logconv=	12,
39 	Maskconv=	(1<<Logconv)-1,
40 	Shiftconv=	Logtype,
41 	Logproto=	8,
42 	Maskproto=	(1<<Logproto)-1,
43 	Shiftproto=	Logtype + Logconv,
44 
45 	Nfs=		128,
46 };
47 #define TYPE(x) 	( ((ulong)(x).path) & Masktype )
48 #define CONV(x) 	( (((ulong)(x).path) >> Shiftconv) & Maskconv )
49 #define PROTO(x) 	( (((ulong)(x).path) >> Shiftproto) & Maskproto )
50 #define QID(p, c, y) 	( ((p)<<(Shiftproto)) | ((c)<<Shiftconv) | (y) )
51 
52 static char network[] = "network";
53 
54 QLock	fslock;
55 Fs	*ipfs[Nfs];	/* attached fs's */
56 Queue	*qlog;
57 
58 extern	void nullmediumlink(void);
59 extern	void pktmediumlink(void);
60 	long ndbwrite(Fs *f, char *a, ulong off, int n);
61 
62 static int
63 ip3gen(Chan *c, int i, Dir *dp)
64 {
65 	Qid q;
66 	Conv *cv;
67 	char *p;
68 
69 	cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)];
70 	if(cv->owner == nil)
71 		kstrdup(&cv->owner, eve);
72 	mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE);
73 
74 	switch(i) {
75 	default:
76 		return -1;
77 	case Qctl:
78 		devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp);
79 		return 1;
80 	case Qdata:
81 		devdir(c, q, "data", qlen(cv->rq), cv->owner, cv->perm, dp);
82 		return 1;
83 	case Qerr:
84 		devdir(c, q, "err", qlen(cv->eq), cv->owner, cv->perm, dp);
85 		return 1;
86 	case Qlisten:
87 		devdir(c, q, "listen", 0, cv->owner, cv->perm, dp);
88 		return 1;
89 	case Qlocal:
90 		p = "local";
91 		break;
92 	case Qremote:
93 		p = "remote";
94 		break;
95 	case Qsnoop:
96 		if(strcmp(cv->p->name, "ipifc") != 0)
97 			return -1;
98 		devdir(c, q, "snoop", qlen(cv->sq), cv->owner, 0400, dp);
99 		return 1;
100 	case Qstatus:
101 		p = "status";
102 		break;
103 	}
104 	devdir(c, q, p, 0, cv->owner, 0444, dp);
105 	return 1;
106 }
107 
108 static int
109 ip2gen(Chan *c, int i, Dir *dp)
110 {
111 	Qid q;
112 
113 	switch(i) {
114 	case Qclone:
115 		mkqid(&q, QID(PROTO(c->qid), 0, Qclone), 0, QTFILE);
116 		devdir(c, q, "clone", 0, network, 0666, dp);
117 		return 1;
118 	case Qstats:
119 		mkqid(&q, QID(PROTO(c->qid), 0, Qstats), 0, QTFILE);
120 		devdir(c, q, "stats", 0, network, 0444, dp);
121 		return 1;
122 	}
123 	return -1;
124 }
125 
126 static int
127 ip1gen(Chan *c, int i, Dir *dp)
128 {
129 	Qid q;
130 	char *p;
131 	int prot;
132 	int len = 0;
133 	Fs *f;
134 	extern ulong	kerndate;
135 
136 	f = ipfs[c->dev];
137 
138 	prot = 0666;
139 	mkqid(&q, QID(0, 0, i), 0, QTFILE);
140 	switch(i) {
141 	default:
142 		return -1;
143 	case Qarp:
144 		p = "arp";
145 		prot = 0664;
146 		break;
147 	case Qbootp:
148 		p = "bootp";
149 		break;
150 	case Qndb:
151 		p = "ndb";
152 		len = strlen(f->ndb);
153 		q.vers = f->ndbvers;
154 		break;
155 	case Qiproute:
156 		p = "iproute";
157 		prot = 0664;
158 		break;
159 	case Qipselftab:
160 		p = "ipselftab";
161 		prot = 0444;
162 		break;
163 	case Qlog:
164 		p = "log";
165 		break;
166 	}
167 	devdir(c, q, p, len, network, prot, dp);
168 	if(i == Qndb && f->ndbmtime > kerndate)
169 		dp->mtime = f->ndbmtime;
170 	return 1;
171 }
172 
173 static int
174 ipgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
175 {
176 	Qid q;
177 	Conv *cv;
178 	Fs *f;
179 
180 	f = ipfs[c->dev];
181 
182 	switch(TYPE(c->qid)) {
183 	case Qtopdir:
184 		if(s == DEVDOTDOT){
185 			mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
186 			sprint(up->genbuf, "#I%lud", c->dev);
187 			devdir(c, q, up->genbuf, 0, network, 0555, dp);
188 			return 1;
189 		}
190 		if(s < f->np) {
191 			if(f->p[s]->connect == nil)
192 				return 0;	/* protocol with no user interface */
193 			mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
194 			devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
195 			return 1;
196 		}
197 		s -= f->np;
198 		return ip1gen(c, s+Qtopbase, dp);
199 	case Qarp:
200 	case Qbootp:
201 	case Qndb:
202 	case Qlog:
203 	case Qiproute:
204 	case Qipselftab:
205 		return ip1gen(c, TYPE(c->qid), dp);
206 	case Qprotodir:
207 		if(s == DEVDOTDOT){
208 			mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
209 			sprint(up->genbuf, "#I%lud", c->dev);
210 			devdir(c, q, up->genbuf, 0, network, 0555, dp);
211 			return 1;
212 		}
213 		if(s < f->p[PROTO(c->qid)]->ac) {
214 			cv = f->p[PROTO(c->qid)]->conv[s];
215 			sprint(up->genbuf, "%d", s);
216 			mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR);
217 			devdir(c, q, up->genbuf, 0, cv->owner, 0555, dp);
218 			return 1;
219 		}
220 		s -= f->p[PROTO(c->qid)]->ac;
221 		return ip2gen(c, s+Qprotobase, dp);
222 	case Qclone:
223 	case Qstats:
224 		return ip2gen(c, TYPE(c->qid), dp);
225 	case Qconvdir:
226 		if(s == DEVDOTDOT){
227 			s = PROTO(c->qid);
228 			mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
229 			devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
230 			return 1;
231 		}
232 		return ip3gen(c, s+Qconvbase, dp);
233 	case Qctl:
234 	case Qdata:
235 	case Qerr:
236 	case Qlisten:
237 	case Qlocal:
238 	case Qremote:
239 	case Qstatus:
240 	case Qsnoop:
241 		return ip3gen(c, TYPE(c->qid), dp);
242 	}
243 	return -1;
244 }
245 
246 static void
247 ipreset(void)
248 {
249 	nullmediumlink();
250 	pktmediumlink();
251 
252 	fmtinstall('i', eipfmt);
253 	fmtinstall('I', eipfmt);
254 	fmtinstall('E', eipfmt);
255 	fmtinstall('V', eipfmt);
256 	fmtinstall('M', eipfmt);
257 }
258 
259 static Fs*
260 ipgetfs(int dev)
261 {
262 	extern void (*ipprotoinit[])(Fs*);
263 	Fs *f;
264 	int i;
265 
266 	if(dev >= Nfs)
267 		return nil;
268 
269 	qlock(&fslock);
270 	if(ipfs[dev] == nil){
271 		f = smalloc(sizeof(Fs));
272 		ip_init(f);
273 		arpinit(f);
274 		netloginit(f);
275 		for(i = 0; ipprotoinit[i]; i++)
276 			ipprotoinit[i](f);
277 		f->dev = dev;
278 		ipfs[dev] = f;
279 	}
280 	qunlock(&fslock);
281 
282 	return ipfs[dev];
283 }
284 
285 IPaux*
286 newipaux(char *owner, char *tag)
287 {
288 	IPaux *a;
289 	int n;
290 
291 	a = smalloc(sizeof(*a));
292 	kstrdup(&a->owner, owner);
293 	memset(a->tag, ' ', sizeof(a->tag));
294 	n = strlen(tag);
295 	if(n > sizeof(a->tag))
296 		n = sizeof(a->tag);
297 	memmove(a->tag, tag, n);
298 	return a;
299 }
300 
301 #define ATTACHER(c) (((IPaux*)((c)->aux))->owner)
302 
303 static Chan*
304 ipattach(char* spec)
305 {
306 	Chan *c;
307 	int dev;
308 
309 	dev = atoi(spec);
310 	if(dev >= Nfs)
311 		error("bad specification");
312 
313 	ipgetfs(dev);
314 	c = devattach('I', spec);
315 	mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR);
316 	c->dev = dev;
317 
318 	c->aux = newipaux(commonuser(), "none");
319 
320 	return c;
321 }
322 
323 static Walkqid*
324 ipwalk(Chan* c, Chan *nc, char **name, int nname)
325 {
326 	IPaux *a = c->aux;
327 	Walkqid* w;
328 
329 	w = devwalk(c, nc, name, nname, nil, 0, ipgen);
330 	if(w != nil && w->clone != nil)
331 		w->clone->aux = newipaux(a->owner, a->tag);
332 	return w;
333 }
334 
335 
336 static int
337 ipstat(Chan* c, uchar* db, int n)
338 {
339 	return devstat(c, db, n, nil, 0, ipgen);
340 }
341 
342 static int
343 incoming(void* arg)
344 {
345 	Conv *conv;
346 
347 	conv = arg;
348 	return conv->incall != nil;
349 }
350 
351 static int m2p[] = {
352 	[OREAD]		4,
353 	[OWRITE]	2,
354 	[ORDWR]		6
355 };
356 
357 static Chan*
358 ipopen(Chan* c, int omode)
359 {
360 	Conv *cv, *nc;
361 	Proto *p;
362 	int perm;
363 	Fs *f;
364 
365 	perm = m2p[omode&3];
366 
367 	f = ipfs[c->dev];
368 
369 	switch(TYPE(c->qid)) {
370 	default:
371 		break;
372 	case Qndb:
373 		if(omode & (OWRITE|OTRUNC) && !iseve())
374 			error(Eperm);
375 		if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
376 			f->ndb[0] = 0;
377 		break;
378 	case Qlog:
379 		netlogopen(f);
380 		break;
381 	case Qiproute:
382 	case Qarp:
383 		if(omode != OREAD && !iseve())
384 			error(Eperm);
385 		break;
386 	case Qtopdir:
387 	case Qprotodir:
388 	case Qconvdir:
389 	case Qstatus:
390 	case Qremote:
391 	case Qlocal:
392 	case Qstats:
393 	case Qbootp:
394 	case Qipselftab:
395 		if(omode != OREAD)
396 			error(Eperm);
397 		break;
398 	case Qsnoop:
399 		if(omode != OREAD)
400 			error(Eperm);
401 		p = f->p[PROTO(c->qid)];
402 		cv = p->conv[CONV(c->qid)];
403 		if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
404 			error(Eperm);
405 		incref(&cv->snoopers);
406 		break;
407 	case Qclone:
408 		p = f->p[PROTO(c->qid)];
409 		qlock(p);
410 		if(waserror()){
411 			qunlock(p);
412 			nexterror();
413 		}
414 		cv = Fsprotoclone(p, ATTACHER(c));
415 		qunlock(p);
416 		poperror();
417 		if(cv == nil) {
418 			error(Enodev);
419 			break;
420 		}
421 		mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE);
422 		break;
423 	case Qdata:
424 	case Qctl:
425 	case Qerr:
426 		p = f->p[PROTO(c->qid)];
427 		qlock(p);
428 		cv = p->conv[CONV(c->qid)];
429 		qlock(cv);
430 		if(waserror()) {
431 			qunlock(cv);
432 			qunlock(p);
433 			nexterror();
434 		}
435 		if((perm & (cv->perm>>6)) != perm) {
436 			if(strcmp(ATTACHER(c), cv->owner) != 0)
437 				error(Eperm);
438 		 	if((perm & cv->perm) != perm)
439 				error(Eperm);
440 
441 		}
442 		cv->inuse++;
443 		if(cv->inuse == 1){
444 			kstrdup(&cv->owner, ATTACHER(c));
445 			cv->perm = 0660;
446 		}
447 		qunlock(cv);
448 		qunlock(p);
449 		poperror();
450 		break;
451 	case Qlisten:
452 		cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
453 		if((perm & (cv->perm>>6)) != perm) {
454 			if(strcmp(ATTACHER(c), cv->owner) != 0)
455 				error(Eperm);
456 		 	if((perm & cv->perm) != perm)
457 				error(Eperm);
458 
459 		}
460 
461 		if(cv->state != Announced)
462 			error("not announced");
463 
464 		if(waserror()){
465 			closeconv(cv);
466 			nexterror();
467 		}
468 		qlock(cv);
469 		cv->inuse++;
470 		qunlock(cv);
471 
472 		nc = nil;
473 		while(nc == nil) {
474 			/* give up if we got a hangup */
475 			if(qisclosed(cv->rq))
476 				error("listen hungup");
477 
478 			qlock(&cv->listenq);
479 			if(waserror()) {
480 				qunlock(&cv->listenq);
481 				nexterror();
482 			}
483 
484 			/* wait for a connect */
485 			sleep(&cv->listenr, incoming, cv);
486 
487 			qlock(cv);
488 			nc = cv->incall;
489 			if(nc != nil){
490 				cv->incall = nc->next;
491 				mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
492 				kstrdup(&cv->owner, ATTACHER(c));
493 			}
494 			qunlock(cv);
495 
496 			qunlock(&cv->listenq);
497 			poperror();
498 		}
499 		closeconv(cv);
500 		poperror();
501 		break;
502 	}
503 	c->mode = openmode(omode);
504 	c->flag |= COPEN;
505 	c->offset = 0;
506 	return c;
507 }
508 
509 static void
510 ipcreate(Chan*, char*, int, ulong)
511 {
512 	error(Eperm);
513 }
514 
515 static void
516 ipremove(Chan*)
517 {
518 	error(Eperm);
519 }
520 
521 static int
522 ipwstat(Chan *c, uchar *dp, int n)
523 {
524 	Dir d;
525 	Conv *cv;
526 	Fs *f;
527 	Proto *p;
528 
529 	f = ipfs[c->dev];
530 	switch(TYPE(c->qid)) {
531 	default:
532 		error(Eperm);
533 		break;
534 	case Qctl:
535 	case Qdata:
536 		break;
537 	}
538 
539 	n = convM2D(dp, n, &d, nil);
540 	if(n > 0){
541 		p = f->p[PROTO(c->qid)];
542 		cv = p->conv[CONV(c->qid)];
543 		if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0)
544 			error(Eperm);
545 		if(d.uid[0])
546 			kstrdup(&cv->owner, d.uid);
547 		cv->perm = d.mode & 0777;
548 	}
549 	return n;
550 }
551 
552 void
553 closeconv(Conv *cv)
554 {
555 	Conv *nc;
556 	Ipmulti *mp;
557 
558 	qlock(cv);
559 
560 	if(--cv->inuse > 0) {
561 		qunlock(cv);
562 		return;
563 	}
564 
565 	/* close all incoming calls since no listen will ever happen */
566 	for(nc = cv->incall; nc; nc = cv->incall){
567 		cv->incall = nc->next;
568 		closeconv(nc);
569 	}
570 	cv->incall = nil;
571 
572 	kstrdup(&cv->owner, network);
573 	cv->perm = 0660;
574 
575 	while((mp = cv->multi) != nil)
576 		ipifcremmulti(cv, mp->ma, mp->ia);
577 
578 	cv->r = nil;
579 	cv->rgen = 0;
580 	cv->p->close(cv);
581 	cv->state = Idle;
582 	qunlock(cv);
583 }
584 
585 static void
586 ipclose(Chan* c)
587 {
588 	Fs *f;
589 
590 	f = ipfs[c->dev];
591 	switch(TYPE(c->qid)) {
592 	default:
593 		break;
594 	case Qlog:
595 		if(c->flag & COPEN)
596 			netlogclose(f);
597 		break;
598 	case Qdata:
599 	case Qctl:
600 	case Qerr:
601 		if(c->flag & COPEN)
602 			closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
603 		break;
604 	case Qsnoop:
605 		if(c->flag & COPEN)
606 			decref(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
607 		break;
608 	}
609 	free(((IPaux*)c->aux)->owner);
610 	free(c->aux);
611 }
612 
613 enum
614 {
615 	Statelen=	32*1024,
616 };
617 
618 static long
619 ipread(Chan *ch, void *a, long n, vlong off)
620 {
621 	Conv *c;
622 	Proto *x;
623 	char *buf, *p;
624 	long rv;
625 	Fs *f;
626 	ulong offset = off;
627 
628 	f = ipfs[ch->dev];
629 
630 	p = a;
631 	switch(TYPE(ch->qid)) {
632 	default:
633 		error(Eperm);
634 	case Qtopdir:
635 	case Qprotodir:
636 	case Qconvdir:
637 		return devdirread(ch, a, n, 0, 0, ipgen);
638 	case Qarp:
639 		return arpread(f->arp, a, offset, n);
640  	case Qbootp:
641  		return bootpread(a, offset, n);
642  	case Qndb:
643 		return readstr(offset, a, n, f->ndb);
644 	case Qiproute:
645 		return routeread(f, a, offset, n);
646 	case Qipselftab:
647 		return ipselftabread(f, a, offset, n);
648 	case Qlog:
649 		return netlogread(f, a, offset, n);
650 	case Qctl:
651 		buf = smalloc(16);
652 		sprint(buf, "%lud", CONV(ch->qid));
653 		rv = readstr(offset, p, n, buf);
654 		free(buf);
655 		return rv;
656 	case Qremote:
657 		buf = smalloc(Statelen);
658 		x = f->p[PROTO(ch->qid)];
659 		c = x->conv[CONV(ch->qid)];
660 		if(x->remote == nil) {
661 			sprint(buf, "%I!%d\n", c->raddr, c->rport);
662 		} else {
663 			(*x->remote)(c, buf, Statelen-2);
664 		}
665 		rv = readstr(offset, p, n, buf);
666 		free(buf);
667 		return rv;
668 	case Qlocal:
669 		buf = smalloc(Statelen);
670 		x = f->p[PROTO(ch->qid)];
671 		c = x->conv[CONV(ch->qid)];
672 		if(x->local == nil) {
673 			sprint(buf, "%I!%d\n", c->laddr, c->lport);
674 		} else {
675 			(*x->local)(c, buf, Statelen-2);
676 		}
677 		rv = readstr(offset, p, n, buf);
678 		free(buf);
679 		return rv;
680 	case Qstatus:
681 		buf = smalloc(Statelen);
682 		x = f->p[PROTO(ch->qid)];
683 		c = x->conv[CONV(ch->qid)];
684 		(*x->state)(c, buf, Statelen-2);
685 		rv = readstr(offset, p, n, buf);
686 		free(buf);
687 		return rv;
688 	case Qdata:
689 		c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
690 		return qread(c->rq, a, n);
691 	case Qerr:
692 		c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
693 		return qread(c->eq, a, n);
694 	case Qsnoop:
695 		c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
696 		return qread(c->sq, a, n);
697 	case Qstats:
698 		x = f->p[PROTO(ch->qid)];
699 		if(x->stats == nil)
700 			error("stats not implemented");
701 		buf = smalloc(Statelen);
702 		(*x->stats)(x, buf, Statelen);
703 		rv = readstr(offset, p, n, buf);
704 		free(buf);
705 		return rv;
706 	}
707 }
708 
709 static Block*
710 ipbread(Chan* ch, long n, ulong offset)
711 {
712 	Conv *c;
713 	Proto *x;
714 	Fs *f;
715 
716 	switch(TYPE(ch->qid)){
717 	case Qdata:
718 		f = ipfs[ch->dev];
719 		x = f->p[PROTO(ch->qid)];
720 		c = x->conv[CONV(ch->qid)];
721 		return qbread(c->rq, n);
722 	default:
723 		return devbread(ch, n, offset);
724 	}
725 }
726 
727 /*
728  *  set local address to be that of the ifc closest to remote address
729  */
730 static void
731 setladdr(Conv* c)
732 {
733 	findlocalip(c->p->f, c->laddr, c->raddr);
734 }
735 
736 /*
737  *  set a local port making sure the quad of raddr,rport,laddr,lport is unique
738  */
739 char*
740 setluniqueport(Conv* c, int lport)
741 {
742 	Proto *p;
743 	Conv *xp;
744 	int x;
745 
746 	p = c->p;
747 
748 	qlock(p);
749 	for(x = 0; x < p->nc; x++){
750 		xp = p->conv[x];
751 		if(xp == nil)
752 			break;
753 		if(xp == c)
754 			continue;
755 		if((xp->state == Connected || xp->state == Announced)
756 		&& xp->lport == lport
757 		&& xp->rport == c->rport
758 		&& ipcmp(xp->raddr, c->raddr) == 0
759 		&& ipcmp(xp->laddr, c->laddr) == 0){
760 			qunlock(p);
761 			return "address in use";
762 		}
763 	}
764 	c->lport = lport;
765 	qunlock(p);
766 	return nil;
767 }
768 
769 /*
770  * is lport in use by anyone?
771  */
772 static int
773 lportinuse(Proto *p, ushort lport)
774 {
775 	int x;
776 
777 	for(x = 0; x < p->nc && p->conv[x]; x++)
778 		if(p->conv[x]->lport == lport)
779 			return 1;
780 	return 0;
781 }
782 
783 /*
784  *  pick a local port and set it
785  */
786 char *
787 setlport(Conv* c)
788 {
789 	Proto *p;
790 	int i, port;
791 
792 	p = c->p;
793 	qlock(p);
794 	if(c->restricted){
795 		/* Restricted ports cycle between 600 and 1024. */
796 		for(i=0; i<1024-600; i++){
797 			if(p->nextrport >= 1024 || p->nextrport < 600)
798 				p->nextrport = 600;
799 			port = p->nextrport++;
800 			if(!lportinuse(p, port))
801 				goto chosen;
802 		}
803 	}else{
804 		/*
805 		 * Unrestricted ports are chosen randomly
806 		 * between 2^15 and 2^16.  There are at most
807 		 * 4*Nchan = 4096 ports in use at any given time,
808 		 * so even in the worst case, a random probe has a
809 		 * 1 - 4096/2^15 = 87% chance of success.
810 		 * If 64 successive probes fail, there is a bug somewhere
811 		 * (or a once in 10^58 event has happened, but that's
812 		 * less likely than a venti collision).
813 		 */
814 		for(i=0; i<64; i++){
815 			port = (1<<15) + nrand(1<<15);
816 			if(!lportinuse(p, port))
817 				goto chosen;
818 		}
819 	}
820 	qunlock(p);
821 	/*
822 	 * debugging: let's see if we ever get this.
823 	 * if we do (and we're a cpu server), we might as well restart
824 	 * since we're now unable to service new connections.
825 	 */
826 	panic("setlport: out of ports");
827 	return "no ports available";
828 
829 chosen:
830 	c->lport = port;
831 	qunlock(p);
832 	return nil;
833 }
834 
835 /*
836  *  set a local address and port from a string of the form
837  *	[address!]port[!r]
838  */
839 char*
840 setladdrport(Conv* c, char* str, int announcing)
841 {
842 	char *p;
843 	char *rv;
844 	ushort lport;
845 	uchar addr[IPaddrlen];
846 
847 	/*
848 	 *  ignore restricted part if it exists.  it's
849 	 *  meaningless on local ports.
850 	 */
851 	p = strchr(str, '!');
852 	if(p != nil){
853 		*p++ = 0;
854 		if(strcmp(p, "r") == 0)
855 			p = nil;
856 	}
857 
858 	c->lport = 0;
859 	if(p == nil){
860 		if(announcing)
861 			ipmove(c->laddr, IPnoaddr);
862 		else
863 			setladdr(c);
864 		p = str;
865 	} else {
866 		if(strcmp(str, "*") == 0)
867 			ipmove(c->laddr, IPnoaddr);
868 		else {
869 			if(parseip(addr, str) == -1)
870 				return Ebadip;
871 			if(ipforme(c->p->f, addr))
872 				ipmove(c->laddr, addr);
873 			else
874 				return "not a local IP address";
875 		}
876 	}
877 
878 	/* one process can get all connections */
879 	if(announcing && strcmp(p, "*") == 0){
880 		if(!iseve())
881 			error(Eperm);
882 		return setluniqueport(c, 0);
883 	}
884 
885 	lport = atoi(p);
886 	if(lport <= 0)
887 		rv = setlport(c);
888 	else
889 		rv = setluniqueport(c, lport);
890 	return rv;
891 }
892 
893 static char*
894 setraddrport(Conv* c, char* str)
895 {
896 	char *p;
897 
898 	p = strchr(str, '!');
899 	if(p == nil)
900 		return "malformed address";
901 	*p++ = 0;
902 	if (parseip(c->raddr, str) == -1)
903 		return Ebadip;
904 	c->rport = atoi(p);
905 	p = strchr(p, '!');
906 	if(p){
907 		if(strstr(p, "!r") != nil)
908 			c->restricted = 1;
909 	}
910 	return nil;
911 }
912 
913 /*
914  *  called by protocol connect routine to set addresses
915  */
916 char*
917 Fsstdconnect(Conv *c, char *argv[], int argc)
918 {
919 	char *p;
920 
921 	switch(argc) {
922 	default:
923 		return "bad args to connect";
924 	case 2:
925 		p = setraddrport(c, argv[1]);
926 		if(p != nil)
927 			return p;
928 		setladdr(c);
929 		p = setlport(c);
930 		if (p != nil)
931 			return p;
932 		break;
933 	case 3:
934 		p = setraddrport(c, argv[1]);
935 		if(p != nil)
936 			return p;
937 		p = setladdrport(c, argv[2], 0);
938 		if(p != nil)
939 			return p;
940 	}
941 
942 	if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
943 		memcmp(c->laddr, v4prefix, IPv4off) == 0)
944 		|| ipcmp(c->raddr, IPnoaddr) == 0)
945 		c->ipversion = V4;
946 	else
947 		c->ipversion = V6;
948 
949 	return nil;
950 }
951 /*
952  *  initiate connection and sleep till its set up
953  */
954 static int
955 connected(void* a)
956 {
957 	return ((Conv*)a)->state == Connected;
958 }
959 static void
960 connectctlmsg(Proto *x, Conv *c, Cmdbuf *cb)
961 {
962 	char *p;
963 
964 	if(c->state != 0)
965 		error(Econinuse);
966 	c->state = Connecting;
967 	c->cerr[0] = '\0';
968 	if(x->connect == nil)
969 		error("connect not supported");
970 	p = x->connect(c, cb->f, cb->nf);
971 	if(p != nil)
972 		error(p);
973 
974 	qunlock(c);
975 	if(waserror()){
976 		qlock(c);
977 		nexterror();
978 	}
979 	sleep(&c->cr, connected, c);
980 	qlock(c);
981 	poperror();
982 
983 	if(c->cerr[0] != '\0')
984 		error(c->cerr);
985 }
986 
987 /*
988  *  called by protocol announce routine to set addresses
989  */
990 char*
991 Fsstdannounce(Conv* c, char* argv[], int argc)
992 {
993 	memset(c->raddr, 0, sizeof(c->raddr));
994 	c->rport = 0;
995 	switch(argc){
996 	default:
997 		break;
998 	case 2:
999 		return setladdrport(c, argv[1], 1);
1000 	}
1001 	return "bad args to announce";
1002 }
1003 
1004 /*
1005  *  initiate announcement and sleep till its set up
1006  */
1007 static int
1008 announced(void* a)
1009 {
1010 	return ((Conv*)a)->state == Announced;
1011 }
1012 static void
1013 announcectlmsg(Proto *x, Conv *c, Cmdbuf *cb)
1014 {
1015 	char *p;
1016 
1017 	if(c->state != 0)
1018 		error(Econinuse);
1019 	c->state = Announcing;
1020 	c->cerr[0] = '\0';
1021 	if(x->announce == nil)
1022 		error("announce not supported");
1023 	p = x->announce(c, cb->f, cb->nf);
1024 	if(p != nil)
1025 		error(p);
1026 
1027 	qunlock(c);
1028 	if(waserror()){
1029 		qlock(c);
1030 		nexterror();
1031 	}
1032 	sleep(&c->cr, announced, c);
1033 	qlock(c);
1034 	poperror();
1035 
1036 	if(c->cerr[0] != '\0')
1037 		error(c->cerr);
1038 }
1039 
1040 /*
1041  *  called by protocol bind routine to set addresses
1042  */
1043 char*
1044 Fsstdbind(Conv* c, char* argv[], int argc)
1045 {
1046 	switch(argc){
1047 	default:
1048 		break;
1049 	case 2:
1050 		return setladdrport(c, argv[1], 0);
1051 	}
1052 	return "bad args to bind";
1053 }
1054 
1055 static void
1056 bindctlmsg(Proto *x, Conv *c, Cmdbuf *cb)
1057 {
1058 	char *p;
1059 
1060 	if(x->bind == nil)
1061 		p = Fsstdbind(c, cb->f, cb->nf);
1062 	else
1063 		p = x->bind(c, cb->f, cb->nf);
1064 	if(p != nil)
1065 		error(p);
1066 }
1067 
1068 static void
1069 tosctlmsg(Conv *c, Cmdbuf *cb)
1070 {
1071 	if(cb->nf < 2)
1072 		c->tos = 0;
1073 	else
1074 		c->tos = atoi(cb->f[1]);
1075 }
1076 
1077 static void
1078 ttlctlmsg(Conv *c, Cmdbuf *cb)
1079 {
1080 	if(cb->nf < 2)
1081 		c->ttl = MAXTTL;
1082 	else
1083 		c->ttl = atoi(cb->f[1]);
1084 }
1085 
1086 static long
1087 ipwrite(Chan* ch, void *v, long n, vlong off)
1088 {
1089 	Conv *c;
1090 	Proto *x;
1091 	char *p;
1092 	Cmdbuf *cb;
1093 	uchar ia[IPaddrlen], ma[IPaddrlen];
1094 	Fs *f;
1095 	char *a;
1096 	ulong offset = off;
1097 
1098 	a = v;
1099 	f = ipfs[ch->dev];
1100 
1101 	switch(TYPE(ch->qid)){
1102 	default:
1103 		error(Eperm);
1104 	case Qdata:
1105 		x = f->p[PROTO(ch->qid)];
1106 		c = x->conv[CONV(ch->qid)];
1107 
1108 		if(c->wq == nil)
1109 			error(Eperm);
1110 
1111 		qwrite(c->wq, a, n);
1112 		break;
1113 	case Qarp:
1114 		return arpwrite(f, a, n);
1115 	case Qiproute:
1116 		return routewrite(f, ch, a, n);
1117 	case Qlog:
1118 		netlogctl(f, a, n);
1119 		return n;
1120 	case Qndb:
1121 		return ndbwrite(f, a, offset, n);
1122 		break;
1123 	case Qctl:
1124 		x = f->p[PROTO(ch->qid)];
1125 		c = x->conv[CONV(ch->qid)];
1126 		cb = parsecmd(a, n);
1127 
1128 		qlock(c);
1129 		if(waserror()) {
1130 			qunlock(c);
1131 			free(cb);
1132 			nexterror();
1133 		}
1134 		if(cb->nf < 1)
1135 			error("short control request");
1136 		if(strcmp(cb->f[0], "connect") == 0)
1137 			connectctlmsg(x, c, cb);
1138 		else if(strcmp(cb->f[0], "announce") == 0)
1139 			announcectlmsg(x, c, cb);
1140 		else if(strcmp(cb->f[0], "bind") == 0)
1141 			bindctlmsg(x, c, cb);
1142 		else if(strcmp(cb->f[0], "ttl") == 0)
1143 			ttlctlmsg(c, cb);
1144 		else if(strcmp(cb->f[0], "tos") == 0)
1145 			tosctlmsg(c, cb);
1146 		else if(strcmp(cb->f[0], "ignoreadvice") == 0)
1147 			c->ignoreadvice = 1;
1148 		else if(strcmp(cb->f[0], "addmulti") == 0){
1149 			if(cb->nf < 2)
1150 				error("addmulti needs interface address");
1151 			if(cb->nf == 2){
1152 				if(!ipismulticast(c->raddr))
1153 					error("addmulti for a non multicast address");
1154 				if (parseip(ia, cb->f[1]) == -1)
1155 					error(Ebadip);
1156 				ipifcaddmulti(c, c->raddr, ia);
1157 			} else {
1158 				if (parseip(ia, cb->f[1]) == -1 ||
1159 				    parseip(ma, cb->f[2]) == -1)
1160 					error(Ebadip);
1161 				if(!ipismulticast(ma))
1162 					error("addmulti for a non multicast address");
1163 				ipifcaddmulti(c, ma, ia);
1164 			}
1165 		} else if(strcmp(cb->f[0], "remmulti") == 0){
1166 			if(cb->nf < 2)
1167 				error("remmulti needs interface address");
1168 			if(!ipismulticast(c->raddr))
1169 				error("remmulti for a non multicast address");
1170 			if (parseip(ia, cb->f[1]) == -1)
1171 				error(Ebadip);
1172 			ipifcremmulti(c, c->raddr, ia);
1173 		} else if(strcmp(cb->f[0], "maxfragsize") == 0){
1174 			if(cb->nf < 2)
1175 				error("maxfragsize needs size");
1176 
1177 			c->maxfragsize = (int)strtol(cb->f[1], nil, 0);
1178 
1179 		} else if(x->ctl != nil) {
1180 			p = x->ctl(c, cb->f, cb->nf);
1181 			if(p != nil)
1182 				error(p);
1183 		} else
1184 			error("unknown control request");
1185 		qunlock(c);
1186 		free(cb);
1187 		poperror();
1188 	}
1189 	return n;
1190 }
1191 
1192 static long
1193 ipbwrite(Chan* ch, Block* bp, ulong offset)
1194 {
1195 	Conv *c;
1196 	Proto *x;
1197 	Fs *f;
1198 	int n;
1199 
1200 	switch(TYPE(ch->qid)){
1201 	case Qdata:
1202 		f = ipfs[ch->dev];
1203 		x = f->p[PROTO(ch->qid)];
1204 		c = x->conv[CONV(ch->qid)];
1205 
1206 		if(c->wq == nil)
1207 			error(Eperm);
1208 
1209 		if(bp->next)
1210 			bp = concatblock(bp);
1211 		n = BLEN(bp);
1212 		qbwrite(c->wq, bp);
1213 		return n;
1214 	default:
1215 		return devbwrite(ch, bp, offset);
1216 	}
1217 }
1218 
1219 Dev ipdevtab = {
1220 	'I',
1221 	"ip",
1222 
1223 	ipreset,
1224 	devinit,
1225 	devshutdown,
1226 	ipattach,
1227 	ipwalk,
1228 	ipstat,
1229 	ipopen,
1230 	ipcreate,
1231 	ipclose,
1232 	ipread,
1233 	ipbread,
1234 	ipwrite,
1235 	ipbwrite,
1236 	ipremove,
1237 	ipwstat,
1238 };
1239 
1240 int
1241 Fsproto(Fs *f, Proto *p)
1242 {
1243 	if(f->np >= Maxproto)
1244 		return -1;
1245 
1246 	p->f = f;
1247 
1248 	if(p->ipproto > 0){
1249 		if(f->t2p[p->ipproto] != nil)
1250 			return -1;
1251 		f->t2p[p->ipproto] = p;
1252 	}
1253 
1254 	p->qid.type = QTDIR;
1255 	p->qid.path = QID(f->np, 0, Qprotodir);
1256 	p->conv = malloc(sizeof(Conv*)*(p->nc+1));
1257 	if(p->conv == nil)
1258 		panic("Fsproto");
1259 
1260 	p->x = f->np;
1261 	p->nextrport = 600;
1262 	f->p[f->np++] = p;
1263 
1264 	return 0;
1265 }
1266 
1267 /*
1268  *  return true if this protocol is
1269  *  built in
1270  */
1271 int
1272 Fsbuiltinproto(Fs* f, uchar proto)
1273 {
1274 	return f->t2p[proto] != nil;
1275 }
1276 
1277 /*
1278  *  called with protocol locked
1279  */
1280 Conv*
1281 Fsprotoclone(Proto *p, char *user)
1282 {
1283 	Conv *c, **pp, **ep;
1284 
1285 retry:
1286 	c = nil;
1287 	ep = &p->conv[p->nc];
1288 	for(pp = p->conv; pp < ep; pp++) {
1289 		c = *pp;
1290 		if(c == nil){
1291 			c = malloc(sizeof(Conv));
1292 			if(c == nil)
1293 				error(Enomem);
1294 			qlock(c);
1295 			c->p = p;
1296 			c->x = pp - p->conv;
1297 			if(p->ptclsize != 0){
1298 				c->ptcl = malloc(p->ptclsize);
1299 				if(c->ptcl == nil) {
1300 					free(c);
1301 					error(Enomem);
1302 				}
1303 			}
1304 			*pp = c;
1305 			p->ac++;
1306 			c->eq = qopen(1024, Qmsg, 0, 0);
1307 			(*p->create)(c);
1308 			break;
1309 		}
1310 		if(canqlock(c)){
1311 			/*
1312 			 *  make sure both processes and protocol
1313 			 *  are done with this Conv
1314 			 */
1315 			if(c->inuse == 0 && (p->inuse == nil || (*p->inuse)(c) == 0))
1316 				break;
1317 
1318 			qunlock(c);
1319 		}
1320 	}
1321 	if(pp >= ep) {
1322 		if(p->gc)
1323 			print("Fsprotoclone: garbage collecting Convs\n");
1324 		if(p->gc != nil && (*p->gc)(p))
1325 			goto retry;
1326 		/* debugging: do we ever get here? */
1327 		panic("Fsprotoclone: all conversations in use");
1328 		return nil;
1329 	}
1330 
1331 	c->inuse = 1;
1332 	kstrdup(&c->owner, user);
1333 	c->perm = 0660;
1334 	c->state = Idle;
1335 	ipmove(c->laddr, IPnoaddr);
1336 	ipmove(c->raddr, IPnoaddr);
1337 	c->r = nil;
1338 	c->rgen = 0;
1339 	c->lport = 0;
1340 	c->rport = 0;
1341 	c->restricted = 0;
1342 	c->maxfragsize = 0;
1343 	c->ttl = MAXTTL;
1344 	qreopen(c->rq);
1345 	qreopen(c->wq);
1346 	qreopen(c->eq);
1347 
1348 	qunlock(c);
1349 	return c;
1350 }
1351 
1352 int
1353 Fsconnected(Conv* c, char* msg)
1354 {
1355 	if(msg != nil && *msg != '\0')
1356 		strncpy(c->cerr, msg, ERRMAX-1);
1357 
1358 	switch(c->state){
1359 
1360 	case Announcing:
1361 		c->state = Announced;
1362 		break;
1363 
1364 	case Connecting:
1365 		c->state = Connected;
1366 		break;
1367 	}
1368 
1369 	wakeup(&c->cr);
1370 	return 0;
1371 }
1372 
1373 Proto*
1374 Fsrcvpcol(Fs* f, uchar proto)
1375 {
1376 	if(f->ipmux)
1377 		return f->ipmux;
1378 	else
1379 		return f->t2p[proto];
1380 }
1381 
1382 Proto*
1383 Fsrcvpcolx(Fs *f, uchar proto)
1384 {
1385 	return f->t2p[proto];
1386 }
1387 
1388 /*
1389  *  called with protocol locked
1390  */
1391 Conv*
1392 Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport, uchar version)
1393 {
1394 	Conv *nc;
1395 	Conv **l;
1396 	int i;
1397 
1398 	qlock(c);
1399 	i = 0;
1400 	for(l = &c->incall; *l; l = &(*l)->next)
1401 		i++;
1402 	if(i >= Maxincall) {
1403 		static int beenhere;
1404 
1405 		qunlock(c);
1406 		if (!beenhere) {
1407 			beenhere = 1;
1408 			print("Fsnewcall: incall queue full (%d) on port %d\n",
1409 				i, c->lport);
1410 		}
1411 		return nil;
1412 	}
1413 
1414 	/* find a free conversation */
1415 	nc = Fsprotoclone(c->p, network);
1416 	if(nc == nil) {
1417 		qunlock(c);
1418 		return nil;
1419 	}
1420 	ipmove(nc->raddr, raddr);
1421 	nc->rport = rport;
1422 	ipmove(nc->laddr, laddr);
1423 	nc->lport = lport;
1424 	nc->next = nil;
1425 	*l = nc;
1426 	nc->state = Connected;
1427 	nc->ipversion = version;
1428 
1429 	qunlock(c);
1430 
1431 	wakeup(&c->listenr);
1432 
1433 	return nc;
1434 }
1435 
1436 long
1437 ndbwrite(Fs *f, char *a, ulong off, int n)
1438 {
1439 	if(off > strlen(f->ndb))
1440 		error(Eio);
1441 	if(off+n >= sizeof(f->ndb))
1442 		error(Eio);
1443 	memmove(f->ndb+off, a, n);
1444 	f->ndb[off+n] = 0;
1445 	f->ndbvers++;
1446 	f->ndbmtime = seconds();
1447 	return n;
1448 }
1449 
1450 ulong
1451 scalednconv(void)
1452 {
1453 	if(cpuserver && conf.npage*BY2PG >= 128*MB)
1454 		return Nchans*4;
1455 	return Nchans;
1456 }
1457