devip.c 23 KB

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