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