ethermedium.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  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.h"
  8. #include "ipv6.h"
  9. typedef struct Etherhdr Etherhdr;
  10. struct Etherhdr
  11. {
  12. uchar d[6];
  13. uchar s[6];
  14. uchar t[2];
  15. };
  16. static uchar ipbroadcast[IPaddrlen] = {
  17. 0xff,0xff,0xff,0xff,
  18. 0xff,0xff,0xff,0xff,
  19. 0xff,0xff,0xff,0xff,
  20. 0xff,0xff,0xff,0xff,
  21. };
  22. static uchar etherbroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  23. static void etherread4(void *a);
  24. static void etherread6(void *a);
  25. static void etherbind(Ipifc *ifc, int argc, char **argv);
  26. static void etherunbind(Ipifc *ifc);
  27. static void etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip);
  28. static void etheraddmulti(Ipifc *ifc, uchar *a, uchar *ia);
  29. static void etherremmulti(Ipifc *ifc, uchar *a, uchar *ia);
  30. static Block* multicastarp(Fs *f, Arpent *a, Medium*, uchar *mac);
  31. static void sendarp(Ipifc *ifc, Arpent *a);
  32. static void sendgarp(Ipifc *ifc, uchar*);
  33. static int multicastea(uchar *ea, uchar *ip);
  34. static void recvarpproc(void*);
  35. static void resolveaddr6(Ipifc *ifc, Arpent *a);
  36. static void etherpref2addr(uchar *pref, uchar *ea);
  37. Medium ethermedium =
  38. {
  39. .name= "ether",
  40. .hsize= 14,
  41. .mintu= 60,
  42. .maxtu= 1514,
  43. .maclen= 6,
  44. .bind= etherbind,
  45. .unbind= etherunbind,
  46. .bwrite= etherbwrite,
  47. .addmulti= etheraddmulti,
  48. .remmulti= etherremmulti,
  49. .ares= arpenter,
  50. .areg= sendgarp,
  51. .pref2addr= etherpref2addr,
  52. };
  53. Medium gbemedium =
  54. {
  55. .name= "gbe",
  56. .hsize= 14,
  57. .mintu= 60,
  58. .maxtu= 9014,
  59. .maclen= 6,
  60. .bind= etherbind,
  61. .unbind= etherunbind,
  62. .bwrite= etherbwrite,
  63. .addmulti= etheraddmulti,
  64. .remmulti= etherremmulti,
  65. .ares= arpenter,
  66. .areg= sendgarp,
  67. .pref2addr= etherpref2addr,
  68. };
  69. typedef struct Etherrock Etherrock;
  70. struct Etherrock
  71. {
  72. Fs *f; /* file system we belong to */
  73. Proc *arpp; /* arp process */
  74. Proc *read4p; /* reading process (v4)*/
  75. Proc *read6p; /* reading process (v6)*/
  76. Chan *mchan4; /* Data channel for v4 */
  77. Chan *achan; /* Arp channel */
  78. Chan *cchan4; /* Control channel for v4 */
  79. Chan *mchan6; /* Data channel for v6 */
  80. Chan *cchan6; /* Control channel for v6 */
  81. };
  82. /*
  83. * ethernet arp request
  84. */
  85. enum
  86. {
  87. ETARP = 0x0806,
  88. ETIP4 = 0x0800,
  89. ETIP6 = 0x86DD,
  90. ARPREQUEST = 1,
  91. ARPREPLY = 2,
  92. };
  93. typedef struct Etherarp Etherarp;
  94. struct Etherarp
  95. {
  96. uchar d[6];
  97. uchar s[6];
  98. uchar type[2];
  99. uchar hrd[2];
  100. uchar pro[2];
  101. uchar hln;
  102. uchar pln;
  103. uchar op[2];
  104. uchar sha[6];
  105. uchar spa[4];
  106. uchar tha[6];
  107. uchar tpa[4];
  108. };
  109. static char *nbmsg = "nonblocking";
  110. /*
  111. * called to bind an IP ifc to an ethernet device
  112. * called with ifc wlock'd
  113. */
  114. static void
  115. etherbind(Ipifc *ifc, int argc, char **argv)
  116. {
  117. Chan *mchan4, *cchan4, *achan, *mchan6, *cchan6, *schan;
  118. char addr[Maxpath]; //char addr[2*KNAMELEN];
  119. char dir[Maxpath]; //char dir[2*KNAMELEN];
  120. char *buf;
  121. int n;
  122. char *ptr;
  123. Etherrock *er;
  124. if(argc < 2)
  125. error(Ebadarg);
  126. mchan4 = cchan4 = achan = mchan6 = cchan6 = nil;
  127. buf = nil;
  128. if(waserror()){
  129. if(mchan4 != nil)
  130. cclose(mchan4);
  131. if(cchan4 != nil)
  132. cclose(cchan4);
  133. if(achan != nil)
  134. cclose(achan);
  135. if(mchan6 != nil)
  136. cclose(mchan6);
  137. if(cchan6 != nil)
  138. cclose(cchan6);
  139. if(buf != nil)
  140. free(buf);
  141. nexterror();
  142. }
  143. /*
  144. * open ip converstation
  145. *
  146. * the dial will fail if the type is already open on
  147. * this device.
  148. */
  149. snprint(addr, sizeof(addr), "%s!0x800", argv[2]);
  150. mchan4 = chandial(addr, nil, dir, &cchan4);
  151. /*
  152. * make it non-blocking
  153. */
  154. devtab[cchan4->type]->write(cchan4, nbmsg, strlen(nbmsg), 0);
  155. /*
  156. * get mac address and speed
  157. */
  158. snprint(addr, sizeof(addr), "%s/stats", argv[2]);
  159. buf = smalloc(512);
  160. schan = namec(addr, Aopen, OREAD, 0);
  161. if(waserror()){
  162. cclose(schan);
  163. nexterror();
  164. }
  165. n = devtab[schan->type]->read(schan, buf, 511, 0);
  166. cclose(schan);
  167. poperror();
  168. buf[n] = 0;
  169. ptr = strstr(buf, "addr: ");
  170. if(!ptr)
  171. error(Eio);
  172. ptr += 6;
  173. parsemac(ifc->mac, ptr, 6);
  174. ptr = strstr(buf, "mbps: ");
  175. if(ptr){
  176. ptr += 6;
  177. ifc->mbps = atoi(ptr);
  178. } else
  179. ifc->mbps = 100;
  180. /*
  181. * open arp conversation
  182. */
  183. snprint(addr, sizeof(addr), "%s!0x806", argv[2]);
  184. achan = chandial(addr, nil, nil, nil);
  185. /*
  186. * open ip conversation
  187. *
  188. * the dial will fail if the type is already open on
  189. * this device.
  190. */
  191. snprint(addr, sizeof(addr), "%s!0x86DD", argv[2]);
  192. mchan6 = chandial(addr, nil, dir, &cchan6);
  193. /*
  194. * make it non-blocking
  195. */
  196. devtab[cchan6->type]->write(cchan6, nbmsg, strlen(nbmsg), 0);
  197. er = smalloc(sizeof(*er));
  198. er->mchan4 = mchan4;
  199. er->cchan4 = cchan4;
  200. er->achan = achan;
  201. er->mchan6 = mchan6;
  202. er->cchan6 = cchan6;
  203. er->f = ifc->conv->p->f;
  204. ifc->arg = er;
  205. free(buf);
  206. poperror();
  207. kproc("etherread4", etherread4, ifc);
  208. kproc("recvarpproc", recvarpproc, ifc);
  209. kproc("etherread6", etherread6, ifc);
  210. }
  211. /*
  212. * called with ifc wlock'd
  213. */
  214. static void
  215. etherunbind(Ipifc *ifc)
  216. {
  217. Etherrock *er = ifc->arg;
  218. if(er->read4p)
  219. postnote(er->read4p, 1, "unbind", 0);
  220. if(er->read6p)
  221. postnote(er->read6p, 1, "unbind", 0);
  222. if(er->arpp)
  223. postnote(er->arpp, 1, "unbind", 0);
  224. /* wait for readers to die */
  225. while(er->arpp != 0 || er->read4p != 0 || er->read6p != 0)
  226. tsleep(&up->sleep, return0, 0, 300);
  227. if(er->mchan4 != nil)
  228. cclose(er->mchan4);
  229. if(er->achan != nil)
  230. cclose(er->achan);
  231. if(er->cchan4 != nil)
  232. cclose(er->cchan4);
  233. if(er->mchan6 != nil)
  234. cclose(er->mchan6);
  235. if(er->cchan6 != nil)
  236. cclose(er->cchan6);
  237. free(er);
  238. }
  239. /*
  240. * called by ipoput with a single block to write with ifc rlock'd
  241. */
  242. static void
  243. etherbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip)
  244. {
  245. Etherhdr *eh;
  246. Arpent *a;
  247. uchar mac[6];
  248. Etherrock *er = ifc->arg;
  249. /* get mac address of destination */
  250. a = arpget(er->f->arp, bp, version, ifc, ip, mac);
  251. if(a){
  252. /* check for broadcast or multicast */
  253. bp = multicastarp(er->f, a, ifc->m, mac);
  254. if(bp==nil){
  255. switch(version){
  256. case V4:
  257. sendarp(ifc, a);
  258. break;
  259. case V6:
  260. resolveaddr6(ifc, a);
  261. break;
  262. default:
  263. panic("etherbwrite: version %d", version);
  264. }
  265. return;
  266. }
  267. }
  268. /* make it a single block with space for the ether header */
  269. bp = padblock(bp, ifc->m->hsize);
  270. if(bp->next)
  271. bp = concatblock(bp);
  272. if(BLEN(bp) < ifc->mintu)
  273. bp = adjustblock(bp, ifc->mintu);
  274. eh = (Etherhdr*)bp->rp;
  275. /* copy in mac addresses and ether type */
  276. memmove(eh->s, ifc->mac, sizeof(eh->s));
  277. memmove(eh->d, mac, sizeof(eh->d));
  278. switch(version){
  279. case V4:
  280. eh->t[0] = 0x08;
  281. eh->t[1] = 0x00;
  282. devtab[er->mchan4->type]->bwrite(er->mchan4, bp, 0);
  283. break;
  284. case V6:
  285. eh->t[0] = 0x86;
  286. eh->t[1] = 0xDD;
  287. devtab[er->mchan6->type]->bwrite(er->mchan6, bp, 0);
  288. break;
  289. default:
  290. panic("etherbwrite2: version %d", version);
  291. }
  292. ifc->out++;
  293. }
  294. /*
  295. * process to read from the ethernet
  296. */
  297. static void
  298. etherread4(void *a)
  299. {
  300. Ipifc *ifc;
  301. Block *bp;
  302. Etherrock *er;
  303. ifc = a;
  304. er = ifc->arg;
  305. er->read4p = up; /* hide identity under a rock for unbind */
  306. if(waserror()){
  307. er->read4p = 0;
  308. pexit("hangup", 1);
  309. }
  310. for(;;){
  311. bp = devtab[er->mchan4->type]->bread(er->mchan4, ifc->maxtu, 0);
  312. if(!canrlock(ifc)){
  313. freeb(bp);
  314. continue;
  315. }
  316. if(waserror()){
  317. runlock(ifc);
  318. nexterror();
  319. }
  320. ifc->in++;
  321. bp->rp += ifc->m->hsize;
  322. if(ifc->lifc == nil)
  323. freeb(bp);
  324. else
  325. ipiput4(er->f, ifc, bp);
  326. runlock(ifc);
  327. poperror();
  328. }
  329. }
  330. /*
  331. * process to read from the ethernet, IPv6
  332. */
  333. static void
  334. etherread6(void *a)
  335. {
  336. Ipifc *ifc;
  337. Block *bp;
  338. Etherrock *er;
  339. ifc = a;
  340. er = ifc->arg;
  341. er->read6p = up; /* hide identity under a rock for unbind */
  342. if(waserror()){
  343. er->read6p = 0;
  344. pexit("hangup", 1);
  345. }
  346. for(;;){
  347. bp = devtab[er->mchan6->type]->bread(er->mchan6, ifc->maxtu, 0);
  348. if(!canrlock(ifc)){
  349. freeb(bp);
  350. continue;
  351. }
  352. if(waserror()){
  353. runlock(ifc);
  354. nexterror();
  355. }
  356. ifc->in++;
  357. bp->rp += ifc->m->hsize;
  358. if(ifc->lifc == nil)
  359. freeb(bp);
  360. else
  361. ipiput6(er->f, ifc, bp);
  362. runlock(ifc);
  363. poperror();
  364. }
  365. }
  366. static void
  367. etheraddmulti(Ipifc *ifc, uchar *a, uchar *)
  368. {
  369. uchar mac[6];
  370. char buf[64];
  371. Etherrock *er = ifc->arg;
  372. int version;
  373. version = multicastea(mac, a);
  374. sprint(buf, "addmulti %E", mac);
  375. switch(version){
  376. case V4:
  377. devtab[er->cchan4->type]->write(er->cchan4, buf, strlen(buf), 0);
  378. break;
  379. case V6:
  380. devtab[er->cchan6->type]->write(er->cchan6, buf, strlen(buf), 0);
  381. break;
  382. default:
  383. panic("etheraddmulti: version %d", version);
  384. }
  385. }
  386. static void
  387. etherremmulti(Ipifc *ifc, uchar *a, uchar *)
  388. {
  389. uchar mac[6];
  390. char buf[64];
  391. Etherrock *er = ifc->arg;
  392. int version;
  393. version = multicastea(mac, a);
  394. sprint(buf, "remmulti %E", mac);
  395. switch(version){
  396. case V4:
  397. devtab[er->cchan4->type]->write(er->cchan4, buf, strlen(buf), 0);
  398. break;
  399. case V6:
  400. devtab[er->cchan6->type]->write(er->cchan6, buf, strlen(buf), 0);
  401. break;
  402. default:
  403. panic("etherremmulti: version %d", version);
  404. }
  405. }
  406. /*
  407. * send an ethernet arp
  408. * (only v4, v6 uses the neighbor discovery, rfc1970)
  409. */
  410. static void
  411. sendarp(Ipifc *ifc, Arpent *a)
  412. {
  413. int n;
  414. Block *bp;
  415. Etherarp *e;
  416. Etherrock *er = ifc->arg;
  417. /* don't do anything if it's been less than a second since the last */
  418. if(NOW - a->ctime < 1000){
  419. arprelease(er->f->arp, a);
  420. return;
  421. }
  422. /* remove all but the last message */
  423. while((bp = a->hold) != nil){
  424. if(bp == a->last)
  425. break;
  426. a->hold = bp->list;
  427. freeblist(bp);
  428. }
  429. /* try to keep it around for a second more */
  430. a->ctime = NOW;
  431. arprelease(er->f->arp, a);
  432. n = sizeof(Etherarp);
  433. if(n < a->type->mintu)
  434. n = a->type->mintu;
  435. bp = allocb(n);
  436. memset(bp->rp, 0, n);
  437. e = (Etherarp*)bp->rp;
  438. memmove(e->tpa, a->ip+IPv4off, sizeof(e->tpa));
  439. ipv4local(ifc, e->spa);
  440. memmove(e->sha, ifc->mac, sizeof(e->sha));
  441. memset(e->d, 0xff, sizeof(e->d)); /* ethernet broadcast */
  442. memmove(e->s, ifc->mac, sizeof(e->s));
  443. hnputs(e->type, ETARP);
  444. hnputs(e->hrd, 1);
  445. hnputs(e->pro, ETIP4);
  446. e->hln = sizeof(e->sha);
  447. e->pln = sizeof(e->spa);
  448. hnputs(e->op, ARPREQUEST);
  449. bp->wp += n;
  450. n = devtab[er->achan->type]->bwrite(er->achan, bp, 0);
  451. if(n < 0)
  452. print("arp: send: %r\n");
  453. }
  454. static void
  455. resolveaddr6(Ipifc *ifc, Arpent *a)
  456. {
  457. int sflag;
  458. Block *bp;
  459. Etherrock *er = ifc->arg;
  460. uchar ipsrc[IPaddrlen];
  461. /* don't do anything if it's been less than a second since the last */
  462. if(NOW - a->ctime < ReTransTimer){
  463. arprelease(er->f->arp, a);
  464. return;
  465. }
  466. /* remove all but the last message */
  467. while((bp = a->hold) != nil){
  468. if(bp == a->last)
  469. break;
  470. a->hold = bp->list;
  471. freeblist(bp);
  472. }
  473. /* try to keep it around for a second more */
  474. a->ctime = NOW;
  475. a->rtime = NOW + ReTransTimer;
  476. if(a->rxtsrem <= 0) {
  477. arprelease(er->f->arp, a);
  478. return;
  479. }
  480. a->rxtsrem--;
  481. arprelease(er->f->arp, a);
  482. if(sflag = ipv6anylocal(ifc, ipsrc))
  483. icmpns(er->f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac);
  484. }
  485. /*
  486. * send a gratuitous arp to refresh arp caches
  487. */
  488. static void
  489. sendgarp(Ipifc *ifc, uchar *ip)
  490. {
  491. int n;
  492. Block *bp;
  493. Etherarp *e;
  494. Etherrock *er = ifc->arg;
  495. /* don't arp for our initial non address */
  496. if(ipcmp(ip, IPnoaddr) == 0)
  497. return;
  498. n = sizeof(Etherarp);
  499. if(n < ifc->m->mintu)
  500. n = ifc->m->mintu;
  501. bp = allocb(n);
  502. memset(bp->rp, 0, n);
  503. e = (Etherarp*)bp->rp;
  504. memmove(e->tpa, ip+IPv4off, sizeof(e->tpa));
  505. memmove(e->spa, ip+IPv4off, sizeof(e->spa));
  506. memmove(e->sha, ifc->mac, sizeof(e->sha));
  507. memset(e->d, 0xff, sizeof(e->d)); /* ethernet broadcast */
  508. memmove(e->s, ifc->mac, sizeof(e->s));
  509. hnputs(e->type, ETARP);
  510. hnputs(e->hrd, 1);
  511. hnputs(e->pro, ETIP4);
  512. e->hln = sizeof(e->sha);
  513. e->pln = sizeof(e->spa);
  514. hnputs(e->op, ARPREQUEST);
  515. bp->wp += n;
  516. n = devtab[er->achan->type]->bwrite(er->achan, bp, 0);
  517. if(n < 0)
  518. print("garp: send: %r\n");
  519. }
  520. static void
  521. recvarp(Ipifc *ifc)
  522. {
  523. int n;
  524. Block *ebp, *rbp;
  525. Etherarp *e, *r;
  526. uchar ip[IPaddrlen];
  527. static uchar eprinted[4];
  528. Etherrock *er = ifc->arg;
  529. ebp = devtab[er->achan->type]->bread(er->achan, ifc->maxtu, 0);
  530. if(ebp == nil) {
  531. print("arp: rcv: %r\n");
  532. return;
  533. }
  534. e = (Etherarp*)ebp->rp;
  535. switch(nhgets(e->op)) {
  536. default:
  537. break;
  538. case ARPREPLY:
  539. /* check for machine using my ip address */
  540. v4tov6(ip, e->spa);
  541. if(iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)){
  542. if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0){
  543. print("arprep: 0x%E/0x%E also has ip addr %V\n",
  544. e->s, e->sha, e->spa);
  545. break;
  546. }
  547. }
  548. /* make sure we're not entering broadcast addresses */
  549. if(ipcmp(ip, ipbroadcast) == 0 ||
  550. !memcmp(e->sha, etherbroadcast, sizeof(e->sha))){
  551. print("arprep: 0x%E/0x%E cannot register broadcast address %I\n",
  552. e->s, e->sha, e->spa);
  553. break;
  554. }
  555. arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 0);
  556. break;
  557. case ARPREQUEST:
  558. /* don't answer arps till we know who we are */
  559. if(ifc->lifc == 0)
  560. break;
  561. /* check for machine using my ip or ether address */
  562. v4tov6(ip, e->spa);
  563. if(iplocalonifc(ifc, ip) || ipproxyifc(er->f, ifc, ip)){
  564. if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) != 0){
  565. if (memcmp(eprinted, e->spa, sizeof(e->spa))){
  566. /* print only once */
  567. print("arpreq: 0x%E also has ip addr %V\n", e->sha, e->spa);
  568. memmove(eprinted, e->spa, sizeof(e->spa));
  569. }
  570. }
  571. } else {
  572. if(memcmp(e->sha, ifc->mac, sizeof(e->sha)) == 0){
  573. print("arpreq: %V also has ether addr %E\n", e->spa, e->sha);
  574. break;
  575. }
  576. }
  577. /* refresh what we know about sender */
  578. arpenter(er->f, V4, e->spa, e->sha, sizeof(e->sha), 1);
  579. /* answer only requests for our address or systems we're proxying for */
  580. v4tov6(ip, e->tpa);
  581. if(!iplocalonifc(ifc, ip))
  582. if(!ipproxyifc(er->f, ifc, ip))
  583. break;
  584. n = sizeof(Etherarp);
  585. if(n < ifc->mintu)
  586. n = ifc->mintu;
  587. rbp = allocb(n);
  588. r = (Etherarp*)rbp->rp;
  589. memset(r, 0, sizeof(Etherarp));
  590. hnputs(r->type, ETARP);
  591. hnputs(r->hrd, 1);
  592. hnputs(r->pro, ETIP4);
  593. r->hln = sizeof(r->sha);
  594. r->pln = sizeof(r->spa);
  595. hnputs(r->op, ARPREPLY);
  596. memmove(r->tha, e->sha, sizeof(r->tha));
  597. memmove(r->tpa, e->spa, sizeof(r->tpa));
  598. memmove(r->sha, ifc->mac, sizeof(r->sha));
  599. memmove(r->spa, e->tpa, sizeof(r->spa));
  600. memmove(r->d, e->sha, sizeof(r->d));
  601. memmove(r->s, ifc->mac, sizeof(r->s));
  602. rbp->wp += n;
  603. n = devtab[er->achan->type]->bwrite(er->achan, rbp, 0);
  604. if(n < 0)
  605. print("arp: write: %r\n");
  606. }
  607. freeb(ebp);
  608. }
  609. static void
  610. recvarpproc(void *v)
  611. {
  612. Ipifc *ifc = v;
  613. Etherrock *er = ifc->arg;
  614. er->arpp = up;
  615. if(waserror()){
  616. er->arpp = 0;
  617. pexit("hangup", 1);
  618. }
  619. for(;;)
  620. recvarp(ifc);
  621. }
  622. static int
  623. multicastea(uchar *ea, uchar *ip)
  624. {
  625. int x;
  626. switch(x = ipismulticast(ip)){
  627. case V4:
  628. ea[0] = 0x01;
  629. ea[1] = 0x00;
  630. ea[2] = 0x5e;
  631. ea[3] = ip[13] & 0x7f;
  632. ea[4] = ip[14];
  633. ea[5] = ip[15];
  634. break;
  635. case V6:
  636. ea[0] = 0x33;
  637. ea[1] = 0x33;
  638. ea[2] = ip[12];
  639. ea[3] = ip[13];
  640. ea[4] = ip[14];
  641. ea[5] = ip[15];
  642. break;
  643. }
  644. return x;
  645. }
  646. /*
  647. * fill in an arp entry for broadcast or multicast
  648. * addresses. Return the first queued packet for the
  649. * IP address.
  650. */
  651. static Block*
  652. multicastarp(Fs *f, Arpent *a, Medium *medium, uchar *mac)
  653. {
  654. /* is it broadcast? */
  655. switch(ipforme(f, a->ip)){
  656. case Runi:
  657. return nil;
  658. case Rbcast:
  659. memset(mac, 0xff, 6);
  660. return arpresolve(f->arp, a, medium, mac);
  661. default:
  662. break;
  663. }
  664. /* if multicast, fill in mac */
  665. switch(multicastea(mac, a->ip)){
  666. case V4:
  667. case V6:
  668. return arpresolve(f->arp, a, medium, mac);
  669. }
  670. /* let arp take care of it */
  671. return nil;
  672. }
  673. void
  674. ethermediumlink(void)
  675. {
  676. addipmedium(&ethermedium);
  677. addipmedium(&gbemedium);
  678. }
  679. static void
  680. etherpref2addr(uchar *pref, uchar *ea)
  681. {
  682. pref[8] = ea[0] | 0x2;
  683. pref[9] = ea[1];
  684. pref[10] = ea[2];
  685. pref[11] = 0xFF;
  686. pref[12] = 0xFE;
  687. pref[13] = ea[3];
  688. pref[14] = ea[4];
  689. pref[15] = ea[5];
  690. }