devip.c 24 KB

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