devip.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412
  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. break;
  130. case Qbootp:
  131. p = "bootp";
  132. break;
  133. case Qndb:
  134. p = "ndb";
  135. len = strlen(f->ndb);
  136. q.vers = f->ndbvers;
  137. break;
  138. case Qiproute:
  139. p = "iproute";
  140. break;
  141. case Qipselftab:
  142. p = "ipselftab";
  143. prot = 0444;
  144. break;
  145. case Qlog:
  146. p = "log";
  147. break;
  148. }
  149. devdir(c, q, p, len, network, prot, dp);
  150. if(i == Qndb && f->ndbmtime > kerndate)
  151. dp->mtime = f->ndbmtime;
  152. return 1;
  153. }
  154. static int
  155. ipgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
  156. {
  157. Qid q;
  158. Conv *cv;
  159. Fs *f;
  160. f = ipfs[c->dev];
  161. switch(TYPE(c->qid)) {
  162. case Qtopdir:
  163. if(s == DEVDOTDOT){
  164. mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
  165. sprint(up->genbuf, "#I%lud", c->dev);
  166. devdir(c, q, up->genbuf, 0, network, 0555, dp);
  167. return 1;
  168. }
  169. if(s < f->np) {
  170. if(f->p[s]->connect == nil)
  171. return 0; /* protocol with no user interface */
  172. mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
  173. devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
  174. return 1;
  175. }
  176. s -= f->np;
  177. return ip1gen(c, s+Qtopbase, dp);
  178. case Qarp:
  179. case Qbootp:
  180. case Qndb:
  181. case Qlog:
  182. case Qiproute:
  183. case Qipselftab:
  184. return ip1gen(c, TYPE(c->qid), dp);
  185. case Qprotodir:
  186. if(s == DEVDOTDOT){
  187. mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
  188. sprint(up->genbuf, "#I%lud", c->dev);
  189. devdir(c, q, up->genbuf, 0, network, 0555, dp);
  190. return 1;
  191. }
  192. if(s < f->p[PROTO(c->qid)]->ac) {
  193. cv = f->p[PROTO(c->qid)]->conv[s];
  194. sprint(up->genbuf, "%d", s);
  195. mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR);
  196. devdir(c, q, up->genbuf, 0, cv->owner, 0555, dp);
  197. return 1;
  198. }
  199. s -= f->p[PROTO(c->qid)]->ac;
  200. return ip2gen(c, s+Qprotobase, dp);
  201. case Qclone:
  202. case Qstats:
  203. return ip2gen(c, TYPE(c->qid), dp);
  204. case Qconvdir:
  205. if(s == DEVDOTDOT){
  206. s = PROTO(c->qid);
  207. mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
  208. devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
  209. return 1;
  210. }
  211. return ip3gen(c, s+Qconvbase, dp);
  212. case Qctl:
  213. case Qdata:
  214. case Qerr:
  215. case Qlisten:
  216. case Qlocal:
  217. case Qremote:
  218. case Qstatus:
  219. case Qsnoop:
  220. return ip3gen(c, TYPE(c->qid), dp);
  221. }
  222. return -1;
  223. }
  224. static void
  225. ipreset(void)
  226. {
  227. nullmediumlink();
  228. pktmediumlink();
  229. fmtinstall('i', eipfmt);
  230. fmtinstall('I', eipfmt);
  231. fmtinstall('E', eipfmt);
  232. fmtinstall('V', eipfmt);
  233. fmtinstall('M', eipfmt);
  234. }
  235. static Fs*
  236. ipgetfs(int dev)
  237. {
  238. extern void (*ipprotoinit[])(Fs*);
  239. Fs *f;
  240. int i;
  241. if(dev >= Nfs)
  242. return nil;
  243. qlock(&fslock);
  244. if(ipfs[dev] == nil){
  245. f = smalloc(sizeof(Fs));
  246. ip_init(f);
  247. arpinit(f);
  248. netloginit(f);
  249. for(i = 0; ipprotoinit[i]; i++)
  250. ipprotoinit[i](f);
  251. f->dev = dev;
  252. ipfs[dev] = f;
  253. }
  254. qunlock(&fslock);
  255. return ipfs[dev];
  256. }
  257. IPaux*
  258. newipaux(char *owner, char *tag)
  259. {
  260. IPaux *a;
  261. int n;
  262. a = smalloc(sizeof(*a));
  263. kstrdup(&a->owner, owner);
  264. memset(a->tag, ' ', sizeof(a->tag));
  265. n = strlen(tag);
  266. if(n > sizeof(a->tag))
  267. n = sizeof(a->tag);
  268. memmove(a->tag, tag, n);
  269. return a;
  270. }
  271. #define ATTACHER(c) (((IPaux*)((c)->aux))->owner)
  272. static Chan*
  273. ipattach(char* spec)
  274. {
  275. Chan *c;
  276. int dev;
  277. dev = atoi(spec);
  278. if(dev >= Nfs)
  279. error("bad specification");
  280. ipgetfs(dev);
  281. c = devattach('I', spec);
  282. mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR);
  283. c->dev = dev;
  284. c->aux = newipaux(commonuser(), "none");
  285. return c;
  286. }
  287. static Walkqid*
  288. ipwalk(Chan* c, Chan *nc, char **name, int nname)
  289. {
  290. IPaux *a = c->aux;
  291. Walkqid* w;
  292. w = devwalk(c, nc, name, nname, nil, 0, ipgen);
  293. if(w != nil && w->clone != nil)
  294. w->clone->aux = newipaux(a->owner, a->tag);
  295. return w;
  296. }
  297. static int
  298. ipstat(Chan* c, uchar* db, int n)
  299. {
  300. return devstat(c, db, n, nil, 0, ipgen);
  301. }
  302. static int
  303. incoming(void* arg)
  304. {
  305. Conv *conv;
  306. conv = arg;
  307. return conv->incall != nil;
  308. }
  309. static int m2p[] = {
  310. [OREAD] 4,
  311. [OWRITE] 2,
  312. [ORDWR] 6
  313. };
  314. static Chan*
  315. ipopen(Chan* c, int omode)
  316. {
  317. Conv *cv, *nc;
  318. Proto *p;
  319. int perm;
  320. Fs *f;
  321. perm = m2p[omode&3];
  322. f = ipfs[c->dev];
  323. switch(TYPE(c->qid)) {
  324. default:
  325. break;
  326. case Qndb:
  327. if(omode & (OWRITE|OTRUNC) && !iseve())
  328. error(Eperm);
  329. if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
  330. f->ndb[0] = 0;
  331. break;
  332. case Qlog:
  333. netlogopen(f);
  334. break;
  335. case Qiproute:
  336. break;
  337. case Qtopdir:
  338. case Qprotodir:
  339. case Qconvdir:
  340. case Qstatus:
  341. case Qremote:
  342. case Qlocal:
  343. case Qstats:
  344. case Qbootp:
  345. case Qipselftab:
  346. if(omode != OREAD)
  347. error(Eperm);
  348. break;
  349. case Qsnoop:
  350. if(omode != OREAD)
  351. error(Eperm);
  352. p = f->p[PROTO(c->qid)];
  353. cv = p->conv[CONV(c->qid)];
  354. if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
  355. error(Eperm);
  356. incref(&cv->snoopers);
  357. break;
  358. case Qclone:
  359. p = f->p[PROTO(c->qid)];
  360. qlock(p);
  361. if(waserror()){
  362. qunlock(p);
  363. nexterror();
  364. }
  365. cv = Fsprotoclone(p, ATTACHER(c));
  366. qunlock(p);
  367. poperror();
  368. if(cv == nil) {
  369. error(Enodev);
  370. break;
  371. }
  372. mkqid(&c->qid, QID(p->x, cv->x, Qctl), 0, QTFILE);
  373. break;
  374. case Qdata:
  375. case Qctl:
  376. case Qerr:
  377. p = f->p[PROTO(c->qid)];
  378. qlock(p);
  379. cv = p->conv[CONV(c->qid)];
  380. qlock(cv);
  381. if(waserror()) {
  382. qunlock(cv);
  383. qunlock(p);
  384. nexterror();
  385. }
  386. if((perm & (cv->perm>>6)) != perm) {
  387. if(strcmp(ATTACHER(c), cv->owner) != 0)
  388. error(Eperm);
  389. if((perm & cv->perm) != perm)
  390. error(Eperm);
  391. }
  392. cv->inuse++;
  393. if(cv->inuse == 1){
  394. kstrdup(&cv->owner, ATTACHER(c));
  395. cv->perm = 0660;
  396. }
  397. qunlock(cv);
  398. qunlock(p);
  399. poperror();
  400. break;
  401. case Qlisten:
  402. cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
  403. if((perm & (cv->perm>>6)) != perm) {
  404. if(strcmp(ATTACHER(c), cv->owner) != 0)
  405. error(Eperm);
  406. if((perm & cv->perm) != perm)
  407. error(Eperm);
  408. }
  409. if(cv->state != Announced)
  410. error("not announced");
  411. if(waserror()){
  412. closeconv(cv);
  413. nexterror();
  414. }
  415. qlock(cv);
  416. cv->inuse++;
  417. qunlock(cv);
  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. closeconv(cv);
  442. poperror();
  443. break;
  444. }
  445. c->mode = openmode(omode);
  446. c->flag |= COPEN;
  447. c->offset = 0;
  448. return c;
  449. }
  450. static void
  451. ipcreate(Chan*, char*, int, ulong)
  452. {
  453. error(Eperm);
  454. }
  455. static void
  456. ipremove(Chan*)
  457. {
  458. error(Eperm);
  459. }
  460. static int
  461. ipwstat(Chan *c, uchar *dp, int n)
  462. {
  463. Dir d;
  464. Conv *cv;
  465. Fs *f;
  466. Proto *p;
  467. f = ipfs[c->dev];
  468. switch(TYPE(c->qid)) {
  469. default:
  470. error(Eperm);
  471. break;
  472. case Qctl:
  473. case Qdata:
  474. break;
  475. }
  476. n = convM2D(dp, n, &d, nil);
  477. if(n > 0){
  478. p = f->p[PROTO(c->qid)];
  479. cv = p->conv[CONV(c->qid)];
  480. if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0)
  481. error(Eperm);
  482. if(d.uid[0])
  483. kstrdup(&cv->owner, d.uid);
  484. cv->perm = d.mode & 0777;
  485. }
  486. return n;
  487. }
  488. void
  489. closeconv(Conv *cv)
  490. {
  491. Conv *nc;
  492. Ipmulti *mp;
  493. qlock(cv);
  494. if(--cv->inuse > 0) {
  495. qunlock(cv);
  496. return;
  497. }
  498. /* close all incoming calls since no listen will ever happen */
  499. for(nc = cv->incall; nc; nc = cv->incall){
  500. cv->incall = nc->next;
  501. closeconv(nc);
  502. }
  503. cv->incall = nil;
  504. kstrdup(&cv->owner, network);
  505. cv->perm = 0660;
  506. while((mp = cv->multi) != nil)
  507. ipifcremmulti(cv, mp->ma, mp->ia);
  508. cv->r = nil;
  509. cv->rgen = 0;
  510. cv->p->close(cv);
  511. cv->state = Idle;
  512. qunlock(cv);
  513. }
  514. static void
  515. ipclose(Chan* c)
  516. {
  517. Fs *f;
  518. f = ipfs[c->dev];
  519. switch(TYPE(c->qid)) {
  520. default:
  521. break;
  522. case Qlog:
  523. if(c->flag & COPEN)
  524. netlogclose(f);
  525. break;
  526. case Qdata:
  527. case Qctl:
  528. case Qerr:
  529. if(c->flag & COPEN)
  530. closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]);
  531. break;
  532. case Qsnoop:
  533. if(c->flag & COPEN)
  534. decref(&f->p[PROTO(c->qid)]->conv[CONV(c->qid)]->snoopers);
  535. break;
  536. }
  537. free(((IPaux*)c->aux)->owner);
  538. free(c->aux);
  539. }
  540. enum
  541. {
  542. Statelen= 32*1024,
  543. };
  544. static long
  545. ipread(Chan *ch, void *a, long n, vlong off)
  546. {
  547. Conv *c;
  548. Proto *x;
  549. char *buf, *p;
  550. long rv;
  551. Fs *f;
  552. ulong offset = off;
  553. f = ipfs[ch->dev];
  554. p = a;
  555. switch(TYPE(ch->qid)) {
  556. default:
  557. error(Eperm);
  558. case Qtopdir:
  559. case Qprotodir:
  560. case Qconvdir:
  561. return devdirread(ch, a, n, 0, 0, ipgen);
  562. case Qarp:
  563. return arpread(f->arp, a, offset, n);
  564. case Qbootp:
  565. return bootpread(a, offset, n);
  566. case Qndb:
  567. return readstr(offset, a, n, f->ndb);
  568. case Qiproute:
  569. return routeread(f, a, offset, n);
  570. case Qipselftab:
  571. return ipselftabread(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. break;
  877. case 2:
  878. return setladdrport(c, argv[1], 1);
  879. }
  880. return "bad args to announce";
  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. break;
  923. case 2:
  924. return setladdrport(c, argv[1], 0);
  925. }
  926. return "bad args to bind";
  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. }