ethermedium.c 15 KB

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