devip.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  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= 128,
  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", 0, cv->owner, cv->perm, dp);
  72. return 1;
  73. case Qerr:
  74. devdir(c, q, "err", 0, 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", 0, 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 >= Nfs)
  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. perm = m2p[omode&3];
  328. f = ipfs[c->dev];
  329. switch(TYPE(c->qid)) {
  330. default:
  331. break;
  332. case Qndb:
  333. if(omode & (OWRITE|OTRUNC) && !iseve())
  334. error(Eperm);
  335. if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
  336. f->ndb[0] = 0;
  337. break;
  338. case Qlog:
  339. netlogopen(f);
  340. break;
  341. case Qiproute:
  342. break;
  343. case Qtopdir:
  344. case Qprotodir:
  345. case Qconvdir:
  346. case Qstatus:
  347. case Qremote:
  348. case Qlocal:
  349. case Qstats:
  350. case Qbootp:
  351. case Qipselftab:
  352. case Qipgate6:
  353. if(omode != OREAD)
  354. error(Eperm);
  355. break;
  356. case Qsnoop:
  357. if(omode != OREAD)
  358. error(Eperm);
  359. p = f->p[PROTO(c->qid)];
  360. cv = p->conv[CONV(c->qid)];
  361. if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
  362. error(Eperm);
  363. incref(&cv->snoopers);
  364. break;
  365. case Qclone:
  366. p = f->p[PROTO(c->qid)];
  367. qlock(p);
  368. if(waserror()){
  369. qunlock(p);
  370. nexterror();
  371. }
  372. cv = Fsprotoclone(p, ATTACHER(c));
  373. qunlock(p);
  374. poperror();
  375. if(cv == nil) {
  376. error(Enodev);
  377. break;
  378. }
  379. mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE);
  380. break;
  381. case Qdata:
  382. case Qctl:
  383. case Qerr:
  384. p = f->p[PROTO(c->qid)];
  385. qlock(p);
  386. cv = p->conv[CONV(c->qid)];
  387. qlock(cv);
  388. if(waserror()) {
  389. qunlock(cv);
  390. qunlock(p);
  391. nexterror();
  392. }
  393. if((perm & (cv->perm>>6)) != perm) {
  394. if(strcmp(ATTACHER(c), cv->owner) != 0)
  395. error(Eperm);
  396. if((perm & cv->perm) != perm)
  397. error(Eperm);
  398. }
  399. cv->inuse++;
  400. if(cv->inuse == 1){
  401. kstrdup(&cv->owner, ATTACHER(c));
  402. cv->perm = 0660;
  403. }
  404. qunlock(cv);
  405. qunlock(p);
  406. poperror();
  407. break;
  408. case Qlisten:
  409. cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
  410. if((perm & (cv->perm>>6)) != perm) {
  411. if(strcmp(ATTACHER(c), cv->owner) != 0)
  412. error(Eperm);
  413. if((perm & cv->perm) != perm)
  414. error(Eperm);
  415. }
  416. if(cv->state != Announced)
  417. error("not announced");
  418. nc = nil;
  419. while(nc == nil) {
  420. /* give up if we got a hangup */
  421. if(qisclosed(cv->rq))
  422. error("listen hungup");
  423. qlock(&cv->listenq);
  424. if(waserror()) {
  425. qunlock(&cv->listenq);
  426. nexterror();
  427. }
  428. /* wait for a connect */
  429. sleep(&cv->listenr, incoming, cv);
  430. qlock(cv);
  431. nc = cv->incall;
  432. if(nc != nil){
  433. cv->incall = nc->next;
  434. mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
  435. kstrdup(&cv->owner, ATTACHER(c));
  436. }
  437. qunlock(cv);
  438. qunlock(&cv->listenq);
  439. poperror();
  440. }
  441. break;
  442. }
  443. c->mode = openmode(omode);
  444. c->flag |= COPEN;
  445. c->offset = 0;
  446. return c;
  447. }
  448. static void
  449. ipcreate(Chan*, char*, int, ulong)
  450. {
  451. error(Eperm);
  452. }
  453. static void
  454. ipremove(Chan*)
  455. {
  456. error(Eperm);
  457. }
  458. static int
  459. ipwstat(Chan *c, uchar *dp, int n)
  460. {
  461. Dir d;
  462. Conv *cv;
  463. Fs *f;
  464. Proto *p;
  465. f = ipfs[c->dev];
  466. switch(TYPE(c->qid)) {
  467. default:
  468. error(Eperm);
  469. break;
  470. case Qctl:
  471. case Qdata:
  472. break;
  473. }
  474. n = convM2D(dp, n, &d, nil);
  475. if(n > 0){
  476. p = f->p[PROTO(c->qid)];
  477. cv = p->conv[CONV(c->qid)];
  478. if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0)
  479. error(Eperm);
  480. if(d.uid[0])
  481. kstrdup(&cv->owner, d.uid);
  482. cv->perm = d.mode & 0777;
  483. }
  484. return n;
  485. }
  486. void
  487. closeconv(Conv *cv)
  488. {
  489. Conv *nc;
  490. Ipmulti *mp;
  491. qlock(cv);
  492. if(--cv->inuse > 0) {
  493. qunlock(cv);
  494. return;
  495. }
  496. /* close all incoming calls since no listen will ever happen */
  497. for(nc = cv->incall; nc; nc = cv->incall){
  498. cv->incall = nc->next;
  499. closeconv(nc);
  500. }
  501. cv->incall = nil;
  502. kstrdup(&cv->owner, network);
  503. cv->perm = 0660;
  504. while((mp = cv->multi) != nil)
  505. ipifcremmulti(cv, mp->ma, mp->ia);
  506. cv->r = nil;
  507. cv->rgen = 0;
  508. cv->p->close(cv);
  509. cv->state = Idle;
  510. qunlock(cv);
  511. }
  512. static void
  513. ipclose(Chan* c)
  514. {
  515. Fs *f;
  516. f = ipfs[c->dev];
  517. switch(TYPE(c->qid)) {
  518. default:
  519. break;
  520. case Qlog:
  521. if(c->flag & COPEN)
  522. netlogclose(f);
  523. break;
  524. case Qdata:
  525. case Qctl:
  526. case Qerr:
  527. if(c->flag & COPEN)
  528. closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
  529. break;
  530. case Qsnoop:
  531. if(c->flag & COPEN)
  532. decref(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
  533. break;
  534. }
  535. free(((IPaux*)c->aux)->owner);
  536. free(c->aux);
  537. }
  538. enum
  539. {
  540. Statelen= 32*1024,
  541. };
  542. static long
  543. ipread(Chan *ch, void *a, long n, vlong off)
  544. {
  545. Conv *c;
  546. Proto *x;
  547. char *buf, *p;
  548. long rv;
  549. Fs *f;
  550. ulong offset = off;
  551. f = ipfs[ch->dev];
  552. p = a;
  553. switch(TYPE(ch->qid)) {
  554. default:
  555. error(Eperm);
  556. case Qtopdir:
  557. case Qprotodir:
  558. case Qconvdir:
  559. return devdirread(ch, a, n, 0, 0, ipgen);
  560. case Qarp:
  561. return arpread(f->arp, a, offset, n);
  562. case Qbootp:
  563. return bootpread(a, offset, n);
  564. case Qndb:
  565. return readstr(offset, a, n, f->ndb);
  566. case Qiproute:
  567. return routeread(f, a, offset, n);
  568. case Qipselftab:
  569. return ipselftabread(f, a, offset, n);
  570. case Qipgate6:
  571. return ipgateread6(f, a, offset, n);
  572. case Qlog:
  573. return netlogread(f, a, offset, n);
  574. case Qctl:
  575. buf = smalloc(16);
  576. sprint(buf, "%lud", CONV(ch->qid));
  577. rv = readstr(offset, p, n, buf);
  578. free(buf);
  579. return rv;
  580. case Qremote:
  581. buf = smalloc(Statelen);
  582. x = f->p[PROTO(ch->qid)];
  583. c = x->conv[CONV(ch->qid)];
  584. if(x->remote == nil) {
  585. sprint(buf, "%I!%d\n", c->raddr, c->rport);
  586. } else {
  587. (*x->remote)(c, buf, Statelen-2);
  588. }
  589. rv = readstr(offset, p, n, buf);
  590. free(buf);
  591. return rv;
  592. case Qlocal:
  593. buf = smalloc(Statelen);
  594. x = f->p[PROTO(ch->qid)];
  595. c = x->conv[CONV(ch->qid)];
  596. if(x->local == nil) {
  597. sprint(buf, "%I!%d\n", c->laddr, c->lport);
  598. } else {
  599. (*x->local)(c, buf, Statelen-2);
  600. }
  601. rv = readstr(offset, p, n, buf);
  602. free(buf);
  603. return rv;
  604. case Qstatus:
  605. buf = smalloc(Statelen);
  606. x = f->p[PROTO(ch->qid)];
  607. c = x->conv[CONV(ch->qid)];
  608. (*x->state)(c, buf, Statelen-2);
  609. rv = readstr(offset, p, n, buf);
  610. free(buf);
  611. return rv;
  612. case Qdata:
  613. c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
  614. return qread(c->rq, a, n);
  615. case Qerr:
  616. c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
  617. return qread(c->eq, a, n);
  618. case Qsnoop:
  619. c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
  620. return qread(c->sq, a, n);
  621. case Qstats:
  622. x = f->p[PROTO(ch->qid)];
  623. if(x->stats == nil)
  624. error("stats not implemented");
  625. buf = smalloc(Statelen);
  626. (*x->stats)(x, buf, Statelen);
  627. rv = readstr(offset, p, n, buf);
  628. free(buf);
  629. return rv;
  630. }
  631. }
  632. static Block*
  633. ipbread(Chan* ch, long n, ulong offset)
  634. {
  635. Conv *c;
  636. Proto *x;
  637. Fs *f;
  638. switch(TYPE(ch->qid)){
  639. case Qdata:
  640. f = ipfs[ch->dev];
  641. x = f->p[PROTO(ch->qid)];
  642. c = x->conv[CONV(ch->qid)];
  643. return qbread(c->rq, n);
  644. default:
  645. return devbread(ch, n, offset);
  646. }
  647. }
  648. /*
  649. * set local address to be that of the ifc closest to remote address
  650. */
  651. static void
  652. setladdr(Conv* c)
  653. {
  654. findlocalip(c->p->f, c->laddr, c->raddr);
  655. }
  656. /*
  657. * set a local port making sure the quad of raddr,rport,laddr,lport is unique
  658. */
  659. char*
  660. setluniqueport(Conv* c, int lport)
  661. {
  662. Proto *p;
  663. Conv *xp;
  664. int x;
  665. p = c->p;
  666. qlock(p);
  667. for(x = 0; x < p->nc; x++){
  668. xp = p->conv[x];
  669. if(xp == nil)
  670. break;
  671. if(xp == c)
  672. continue;
  673. if((xp->state == Connected || xp->state == Announced)
  674. && xp->lport == lport
  675. && xp->rport == c->rport
  676. && ipcmp(xp->raddr, c->raddr) == 0
  677. && ipcmp(xp->laddr, c->laddr) == 0){
  678. qunlock(p);
  679. return "address in use";
  680. }
  681. }
  682. c->lport = lport;
  683. qunlock(p);
  684. return nil;
  685. }
  686. /*
  687. * pick a local port and set it
  688. */
  689. void
  690. setlport(Conv* c)
  691. {
  692. Proto *p;
  693. ushort *pp;
  694. int x, found;
  695. p = c->p;
  696. if(c->restricted)
  697. pp = &p->nextrport;
  698. else
  699. pp = &p->nextport;
  700. qlock(p);
  701. for(;;(*pp)++){
  702. /*
  703. * Fsproto initialises p->nextport to 0 and the restricted
  704. * ports (p->nextrport) to 600.
  705. * Restricted ports must lie between 600 and 1024.
  706. * For the initial condition or if the unrestricted port number
  707. * has wrapped round, select a random port between 5000 and 1<<15
  708. * to start at.
  709. */
  710. if(c->restricted){
  711. if(*pp >= 1024)
  712. *pp = 600;
  713. }
  714. else while(*pp < 5000)
  715. *pp = nrand(1<<15);
  716. found = 0;
  717. for(x = 0; x < p->nc; x++){
  718. if(p->conv[x] == nil)
  719. break;
  720. if(p->conv[x]->lport == *pp){
  721. found = 1;
  722. break;
  723. }
  724. }
  725. if(!found)
  726. break;
  727. }
  728. c->lport = (*pp)++;
  729. qunlock(p);
  730. }
  731. /*
  732. * set a local address and port from a string of the form
  733. * [address!]port[!r]
  734. */
  735. char*
  736. setladdrport(Conv* c, char* str, int announcing)
  737. {
  738. char *p;
  739. char *rv;
  740. ushort lport;
  741. uchar addr[IPaddrlen];
  742. rv = nil;
  743. /*
  744. * ignore restricted part if it exists. it's
  745. * meaningless on local ports.
  746. */
  747. p = strchr(str, '!');
  748. if(p != nil){
  749. *p++ = 0;
  750. if(strcmp(p, "r") == 0)
  751. p = nil;
  752. }
  753. c->lport = 0;
  754. if(p == nil){
  755. if(announcing)
  756. ipmove(c->laddr, IPnoaddr);
  757. else
  758. setladdr(c);
  759. p = str;
  760. } else {
  761. if(strcmp(str, "*") == 0)
  762. ipmove(c->laddr, IPnoaddr);
  763. else {
  764. parseip(addr, str);
  765. if(ipforme(c->p->f, addr))
  766. ipmove(c->laddr, addr);
  767. else
  768. return "not a local IP address";
  769. }
  770. }
  771. /* one process can get all connections */
  772. if(announcing && strcmp(p, "*") == 0){
  773. if(!iseve())
  774. error(Eperm);
  775. return setluniqueport(c, 0);
  776. }
  777. lport = atoi(p);
  778. if(lport <= 0)
  779. setlport(c);
  780. else
  781. rv = setluniqueport(c, lport);
  782. return rv;
  783. }
  784. static char*
  785. setraddrport(Conv* c, char* str)
  786. {
  787. char *p;
  788. p = strchr(str, '!');
  789. if(p == nil)
  790. return "malformed address";
  791. *p++ = 0;
  792. parseip(c->raddr, str);
  793. c->rport = atoi(p);
  794. p = strchr(p, '!');
  795. if(p){
  796. if(strstr(p, "!r") != nil)
  797. c->restricted = 1;
  798. }
  799. return nil;
  800. }
  801. /*
  802. * called by protocol connect routine to set addresses
  803. */
  804. char*
  805. Fsstdconnect(Conv *c, char *argv[], int argc)
  806. {
  807. char *p;
  808. switch(argc) {
  809. default:
  810. return "bad args to connect";
  811. case 2:
  812. p = setraddrport(c, argv[1]);
  813. if(p != nil)
  814. return p;
  815. setladdr(c);
  816. setlport(c);
  817. break;
  818. case 3:
  819. p = setraddrport(c, argv[1]);
  820. if(p != nil)
  821. return p;
  822. p = setladdrport(c, argv[2], 0);
  823. if(p != nil)
  824. return p;
  825. }
  826. if( (memcmp(c->raddr, v4prefix, IPv4off) == 0 &&
  827. memcmp(c->laddr, v4prefix, IPv4off) == 0)
  828. || ipcmp(c->raddr, IPnoaddr) == 0)
  829. c->ipversion = V4;
  830. else
  831. c->ipversion = V6;
  832. return nil;
  833. }
  834. /*
  835. * initiate connection and sleep till its set up
  836. */
  837. static int
  838. connected(void* a)
  839. {
  840. return ((Conv*)a)->state == Connected;
  841. }
  842. static void
  843. connectctlmsg(Proto *x, Conv *c, Cmdbuf *cb)
  844. {
  845. char *p;
  846. if(c->state != 0)
  847. error(Econinuse);
  848. c->state = Connecting;
  849. c->cerr[0] = '\0';
  850. if(x->connect == nil)
  851. error("connect not supported");
  852. p = x->connect(c, cb->f, cb->nf);
  853. if(p != nil)
  854. error(p);
  855. qunlock(c);
  856. if(waserror()){
  857. qlock(c);
  858. nexterror();
  859. }
  860. sleep(&c->cr, connected, c);
  861. qlock(c);
  862. poperror();
  863. if(c->cerr[0] != '\0')
  864. error(c->cerr);
  865. }
  866. /*
  867. * called by protocol announce routine to set addresses
  868. */
  869. char*
  870. Fsstdannounce(Conv* c, char* argv[], int argc)
  871. {
  872. memset(c->raddr, 0, sizeof(c->raddr));
  873. c->rport = 0;
  874. switch(argc){
  875. default:
  876. return "bad args to announce";
  877. case 2:
  878. return setladdrport(c, argv[1], 1);
  879. }
  880. return nil;
  881. }
  882. /*
  883. * initiate announcement and sleep till its set up
  884. */
  885. static int
  886. announced(void* a)
  887. {
  888. return ((Conv*)a)->state == Announced;
  889. }
  890. static void
  891. announcectlmsg(Proto *x, Conv *c, Cmdbuf *cb)
  892. {
  893. char *p;
  894. if(c->state != 0)
  895. error(Econinuse);
  896. c->state = Announcing;
  897. c->cerr[0] = '\0';
  898. if(x->announce == nil)
  899. error("announce not supported");
  900. p = x->announce(c, cb->f, cb->nf);
  901. if(p != nil)
  902. error(p);
  903. qunlock(c);
  904. if(waserror()){
  905. qlock(c);
  906. nexterror();
  907. }
  908. sleep(&c->cr, announced, c);
  909. qlock(c);
  910. poperror();
  911. if(c->cerr[0] != '\0')
  912. error(c->cerr);
  913. }
  914. /*
  915. * called by protocol bind routine to set addresses
  916. */
  917. char*
  918. Fsstdbind(Conv* c, char* argv[], int argc)
  919. {
  920. switch(argc){
  921. default:
  922. return "bad args to bind";
  923. case 2:
  924. return setladdrport(c, argv[1], 0);
  925. }
  926. return nil;
  927. }
  928. static void
  929. bindctlmsg(Proto *x, Conv *c, Cmdbuf *cb)
  930. {
  931. char *p;
  932. if(x->bind == nil)
  933. p = Fsstdbind(c, cb->f, cb->nf);
  934. else
  935. p = x->bind(c, cb->f, cb->nf);
  936. if(p != nil)
  937. error(p);
  938. }
  939. static void
  940. tosctlmsg(Conv *c, Cmdbuf *cb)
  941. {
  942. if(cb->nf < 2)
  943. c->tos = 0;
  944. else
  945. c->tos = atoi(cb->f[1]);
  946. }
  947. static void
  948. ttlctlmsg(Conv *c, Cmdbuf *cb)
  949. {
  950. if(cb->nf < 2)
  951. c->ttl = MAXTTL;
  952. else
  953. c->ttl = atoi(cb->f[1]);
  954. }
  955. static long
  956. ipwrite(Chan* ch, void *v, long n, vlong off)
  957. {
  958. Conv *c;
  959. Proto *x;
  960. char *p;
  961. Cmdbuf *cb;
  962. uchar ia[IPaddrlen], ma[IPaddrlen];
  963. Fs *f;
  964. char *a;
  965. ulong offset = off;
  966. a = v;
  967. f = ipfs[ch->dev];
  968. switch(TYPE(ch->qid)){
  969. default:
  970. error(Eperm);
  971. case Qdata:
  972. x = f->p[PROTO(ch->qid)];
  973. c = x->conv[CONV(ch->qid)];
  974. if(c->wq == nil)
  975. error(Eperm);
  976. qwrite(c->wq, a, n);
  977. break;
  978. case Qarp:
  979. return arpwrite(f, a, n);
  980. case Qiproute:
  981. return routewrite(f, ch, a, n);
  982. case Qlog:
  983. netlogctl(f, a, n);
  984. return n;
  985. case Qndb:
  986. return ndbwrite(f, a, offset, n);
  987. break;
  988. case Qctl:
  989. x = f->p[PROTO(ch->qid)];
  990. c = x->conv[CONV(ch->qid)];
  991. cb = parsecmd(a, n);
  992. qlock(c);
  993. if(waserror()) {
  994. qunlock(c);
  995. free(cb);
  996. nexterror();
  997. }
  998. if(cb->nf < 1)
  999. error("short control request");
  1000. if(strcmp(cb->f[0], "connect") == 0)
  1001. connectctlmsg(x, c, cb);
  1002. else if(strcmp(cb->f[0], "announce") == 0)
  1003. announcectlmsg(x, c, cb);
  1004. else if(strcmp(cb->f[0], "bind") == 0)
  1005. bindctlmsg(x, c, cb);
  1006. else if(strcmp(cb->f[0], "ttl") == 0)
  1007. ttlctlmsg(c, cb);
  1008. else if(strcmp(cb->f[0], "tos") == 0)
  1009. tosctlmsg(c, cb);
  1010. else if(strcmp(cb->f[0], "ignoreadvice") == 0)
  1011. c->ignoreadvice = 1;
  1012. else if(strcmp(cb->f[0], "addmulti") == 0){
  1013. if(cb->nf < 2)
  1014. error("addmulti needs interface address");
  1015. if(cb->nf == 2){
  1016. if(!ipismulticast(c->raddr))
  1017. error("addmulti for a non multicast address");
  1018. parseip(ia, cb->f[1]);
  1019. ipifcaddmulti(c, c->raddr, ia);
  1020. } else {
  1021. parseip(ma, cb->f[2]);
  1022. if(!ipismulticast(ma))
  1023. error("addmulti for a non multicast address");
  1024. parseip(ia, cb->f[1]);
  1025. ipifcaddmulti(c, ma, ia);
  1026. }
  1027. } else if(strcmp(cb->f[0], "remmulti") == 0){
  1028. if(cb->nf < 2)
  1029. error("remmulti needs interface address");
  1030. if(!ipismulticast(c->raddr))
  1031. error("remmulti for a non multicast address");
  1032. parseip(ia, cb->f[1]);
  1033. ipifcremmulti(c, c->raddr, ia);
  1034. } else if(x->ctl != nil) {
  1035. p = x->ctl(c, cb->f, cb->nf);
  1036. if(p != nil)
  1037. error(p);
  1038. } else
  1039. error("unknown control request");
  1040. qunlock(c);
  1041. free(cb);
  1042. poperror();
  1043. }
  1044. return n;
  1045. }
  1046. static long
  1047. ipbwrite(Chan* ch, Block* bp, ulong offset)
  1048. {
  1049. Conv *c;
  1050. Proto *x;
  1051. Fs *f;
  1052. int n;
  1053. switch(TYPE(ch->qid)){
  1054. case Qdata:
  1055. f = ipfs[ch->dev];
  1056. x = f->p[PROTO(ch->qid)];
  1057. c = x->conv[CONV(ch->qid)];
  1058. if(c->wq == nil)
  1059. error(Eperm);
  1060. if(bp->next)
  1061. bp = concatblock(bp);
  1062. n = BLEN(bp);
  1063. qbwrite(c->wq, bp);
  1064. return n;
  1065. default:
  1066. return devbwrite(ch, bp, offset);
  1067. }
  1068. }
  1069. Dev ipdevtab = {
  1070. 'I',
  1071. "ip",
  1072. ipreset,
  1073. devinit,
  1074. devshutdown,
  1075. ipattach,
  1076. ipwalk,
  1077. ipstat,
  1078. ipopen,
  1079. ipcreate,
  1080. ipclose,
  1081. ipread,
  1082. ipbread,
  1083. ipwrite,
  1084. ipbwrite,
  1085. ipremove,
  1086. ipwstat,
  1087. };
  1088. int
  1089. Fsproto(Fs *f, Proto *p)
  1090. {
  1091. if(f->np >= Maxproto)
  1092. return -1;
  1093. p->f = f;
  1094. if(p->ipproto > 0){
  1095. if(f->t2p[p->ipproto] != nil)
  1096. return -1;
  1097. f->t2p[p->ipproto] = p;
  1098. }
  1099. p->qid.type = QTDIR;
  1100. p->qid.path = QID(f->np, 0, Qprotodir);
  1101. p->conv = malloc(sizeof(Conv*)*(p->nc+1));
  1102. if(p->conv == nil)
  1103. panic("Fsproto");
  1104. p->x = f->np;
  1105. p->nextport = 0;
  1106. p->nextrport = 600;
  1107. f->p[f->np++] = p;
  1108. return 0;
  1109. }
  1110. /*
  1111. * return true if this protocol is
  1112. * built in
  1113. */
  1114. int
  1115. Fsbuiltinproto(Fs* f, uchar proto)
  1116. {
  1117. return f->t2p[proto] != nil;
  1118. }
  1119. /*
  1120. * called with protocol locked
  1121. */
  1122. Conv*
  1123. Fsprotoclone(Proto *p, char *user)
  1124. {
  1125. Conv *c, **pp, **ep;
  1126. retry:
  1127. c = nil;
  1128. ep = &p->conv[p->nc];
  1129. for(pp = p->conv; pp < ep; pp++) {
  1130. c = *pp;
  1131. if(c == nil){
  1132. c = malloc(sizeof(Conv));
  1133. if(c == nil)
  1134. error(Enomem);
  1135. qlock(c);
  1136. c->p = p;
  1137. c->x = pp - p->conv;
  1138. if(p->ptclsize != 0){
  1139. c->ptcl = malloc(p->ptclsize);
  1140. if(c->ptcl == nil) {
  1141. free(c);
  1142. error(Enomem);
  1143. }
  1144. }
  1145. *pp = c;
  1146. p->ac++;
  1147. c->eq = qopen(1024, Qmsg, 0, 0);
  1148. (*p->create)(c);
  1149. break;
  1150. }
  1151. if(canqlock(c)){
  1152. /*
  1153. * make sure both processes and protocol
  1154. * are done with this Conv
  1155. */
  1156. if(c->inuse == 0 && (p->inuse == nil || (*p->inuse)(c) == 0))
  1157. break;
  1158. qunlock(c);
  1159. }
  1160. }
  1161. if(pp >= ep) {
  1162. if(p->gc != nil && (*p->gc)(p))
  1163. goto retry;
  1164. return nil;
  1165. }
  1166. c->inuse = 1;
  1167. kstrdup(&c->owner, user);
  1168. c->perm = 0660;
  1169. c->state = Idle;
  1170. ipmove(c->laddr, IPnoaddr);
  1171. ipmove(c->raddr, IPnoaddr);
  1172. c->r = nil;
  1173. c->rgen = 0;
  1174. c->lport = 0;
  1175. c->rport = 0;
  1176. c->restricted = 0;
  1177. c->ttl = MAXTTL;
  1178. qreopen(c->rq);
  1179. qreopen(c->wq);
  1180. qreopen(c->eq);
  1181. qunlock(c);
  1182. return c;
  1183. }
  1184. int
  1185. Fsconnected(Conv* c, char* msg)
  1186. {
  1187. if(msg != nil && *msg != '\0')
  1188. strncpy(c->cerr, msg, ERRMAX-1);
  1189. switch(c->state){
  1190. case Announcing:
  1191. c->state = Announced;
  1192. break;
  1193. case Connecting:
  1194. c->state = Connected;
  1195. break;
  1196. }
  1197. wakeup(&c->cr);
  1198. return 0;
  1199. }
  1200. Proto*
  1201. Fsrcvpcol(Fs* f, uchar proto)
  1202. {
  1203. if(f->ipmux)
  1204. return f->ipmux;
  1205. else
  1206. return f->t2p[proto];
  1207. }
  1208. Proto*
  1209. Fsrcvpcolx(Fs *f, uchar proto)
  1210. {
  1211. return f->t2p[proto];
  1212. }
  1213. /*
  1214. * called with protocol locked
  1215. */
  1216. Conv*
  1217. Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport, uchar version)
  1218. {
  1219. Conv *nc;
  1220. Conv **l;
  1221. int i;
  1222. qlock(c);
  1223. i = 0;
  1224. for(l = &c->incall; *l; l = &(*l)->next)
  1225. i++;
  1226. if(i >= Maxincall) {
  1227. qunlock(c);
  1228. return nil;
  1229. }
  1230. /* find a free conversation */
  1231. nc = Fsprotoclone(c->p, network);
  1232. if(nc == nil) {
  1233. qunlock(c);
  1234. return nil;
  1235. }
  1236. ipmove(nc->raddr, raddr);
  1237. nc->rport = rport;
  1238. ipmove(nc->laddr, laddr);
  1239. nc->lport = lport;
  1240. nc->next = nil;
  1241. *l = nc;
  1242. nc->state = Connected;
  1243. nc->ipversion = version;
  1244. qunlock(c);
  1245. wakeup(&c->listenr);
  1246. return nc;
  1247. }
  1248. long
  1249. ndbwrite(Fs *f, char *a, ulong off, int n)
  1250. {
  1251. if(off > strlen(f->ndb))
  1252. error(Eio);
  1253. if(off+n >= sizeof(f->ndb))
  1254. error(Eio);
  1255. memmove(f->ndb+off, a, n);
  1256. f->ndb[off+n] = 0;
  1257. f->ndbvers++;
  1258. f->ndbmtime = seconds();
  1259. return n;
  1260. }
  1261. ulong
  1262. scalednconv(void)
  1263. {
  1264. if(cpuserver && conf.npage*BY2PG >= 128*MB)
  1265. return Nchans*4;
  1266. return Nchans;
  1267. }