devip.c 25 KB

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