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