ethermedium.c 15 KB

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