This source file includes following definitions.
- ether_ioctl
- ether_output
- ether_input
- ether_sprintf
- ether_ifattach
- ether_ifdetach
- ether_crc32_le
- ether_crc32_be
- ether_crc32_le
- ether_crc32_be
- ether_multiaddr
- ether_addmulti
- ether_delmulti
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 #include "bpfilter.h"
77
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/kernel.h>
81 #include <sys/malloc.h>
82 #include <sys/mbuf.h>
83 #include <sys/protosw.h>
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
86 #include <sys/errno.h>
87 #include <sys/syslog.h>
88 #include <sys/timeout.h>
89
90 #include <machine/cpu.h>
91
92 #include <net/if.h>
93 #include <net/netisr.h>
94 #include <net/route.h>
95 #include <net/if_llc.h>
96 #include <net/if_dl.h>
97 #include <net/if_media.h>
98 #include <net/if_types.h>
99
100 #include <netinet/in.h>
101 #ifdef INET
102 #include <netinet/in_var.h>
103 #endif
104 #include <netinet/if_ether.h>
105 #include <netinet/ip_ipsp.h>
106
107 #if NBPFILTER > 0
108 #include <net/bpf.h>
109 #endif
110
111 #include "bridge.h"
112 #if NBRIDGE > 0
113 #include <net/if_bridge.h>
114 #endif
115
116 #include "vlan.h"
117 #if NVLAN > 0
118 #include <net/if_vlan_var.h>
119 #endif
120
121 #include "carp.h"
122 #if NCARP > 0
123 #include <netinet/ip_carp.h>
124 #endif
125
126 #include "pppoe.h"
127 #if NPPPOE > 0
128 #include <net/if_pppoe.h>
129 #endif
130
131 #include "trunk.h"
132 #if NTRUNK > 0
133 #include <net/if_trunk.h>
134 #endif
135
136 #ifdef INET6
137 #ifndef INET
138 #include <netinet/in.h>
139 #endif
140 #include <netinet6/in6_var.h>
141 #include <netinet6/nd6.h>
142 #endif
143
144 #ifdef NETATALK
145 #include <netatalk/at.h>
146 #include <netatalk/at_var.h>
147 #include <netatalk/at_extern.h>
148
149 extern u_char at_org_code[ 3 ];
150 extern u_char aarp_org_code[ 3 ];
151 #endif
152
153 u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
154 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
155 #define senderr(e) { error = (e); goto bad;}
156
157
158 int
159 ether_ioctl(ifp, arp, cmd, data)
160 struct ifnet *ifp;
161 struct arpcom *arp;
162 u_long cmd;
163 caddr_t data;
164 {
165 struct ifaddr *ifa = (struct ifaddr *)data;
166 int error = 0;
167
168 switch (cmd) {
169
170 case SIOCSIFADDR:
171 switch (ifa->ifa_addr->sa_family) {
172 #ifdef NETATALK
173 case AF_APPLETALK:
174
175 break;
176 #endif
177 }
178 break;
179 default:
180 break;
181 }
182
183 return error;
184 }
185
186
187
188
189
190
191 int
192 ether_output(ifp0, m0, dst, rt0)
193 struct ifnet *ifp0;
194 struct mbuf *m0;
195 struct sockaddr *dst;
196 struct rtentry *rt0;
197 {
198 u_int16_t etype;
199 int s, len, error = 0, hdrcmplt = 0;
200 u_char edst[ETHER_ADDR_LEN], esrc[ETHER_ADDR_LEN];
201 struct mbuf *m = m0;
202 struct rtentry *rt;
203 struct mbuf *mcopy = (struct mbuf *)0;
204 struct ether_header *eh;
205 struct arpcom *ac = (struct arpcom *)ifp0;
206 short mflags;
207 struct ifnet *ifp = ifp0;
208
209 #if NTRUNK > 0
210 if (ifp->if_type == IFT_IEEE8023ADLAG)
211 senderr(EBUSY);
212 #endif
213
214 #if NCARP > 0
215 if (ifp->if_type == IFT_CARP) {
216 struct ifaddr *ifa;
217
218
219 if (dst != NULL && LINK_STATE_IS_UP(ifp0->if_link_state) &&
220 (ifa = ifa_ifwithaddr(dst)) != NULL &&
221 ifa->ifa_ifp == ifp0)
222 return (looutput(ifp0, m, dst, rt0));
223
224 ifp = ifp->if_carpdev;
225 ac = (struct arpcom *)ifp;
226
227 if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
228 (IFF_UP|IFF_RUNNING))
229 senderr(ENETDOWN);
230 }
231 #endif
232
233 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
234 senderr(ENETDOWN);
235 if ((rt = rt0) != NULL) {
236 if ((rt->rt_flags & RTF_UP) == 0) {
237 if ((rt0 = rt = rtalloc1(dst, 1, 0)) != NULL)
238 rt->rt_refcnt--;
239 else
240 senderr(EHOSTUNREACH);
241 }
242 if (rt->rt_flags & RTF_GATEWAY) {
243 if (rt->rt_gwroute == 0)
244 goto lookup;
245 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
246 rtfree(rt); rt = rt0;
247 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 0);
248 if ((rt = rt->rt_gwroute) == 0)
249 senderr(EHOSTUNREACH);
250 }
251 }
252 if (rt->rt_flags & RTF_REJECT)
253 if (rt->rt_rmx.rmx_expire == 0 ||
254 time_second < rt->rt_rmx.rmx_expire)
255 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
256 }
257
258 switch (dst->sa_family) {
259
260 #ifdef INET
261 case AF_INET:
262 if (!arpresolve(ac, rt, m, dst, edst))
263 return (0);
264
265 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
266 !m->m_pkthdr.pf.routed)
267 mcopy = m_copy(m, 0, (int)M_COPYALL);
268 etype = htons(ETHERTYPE_IP);
269 break;
270 #endif
271 #ifdef INET6
272 case AF_INET6:
273 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst))
274 return (0);
275 etype = htons(ETHERTYPE_IPV6);
276 break;
277 #endif
278 #ifdef NETATALK
279 case AF_APPLETALK: {
280 struct at_ifaddr *aa;
281
282 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
283 #ifdef NETATALKDEBUG
284 extern char *prsockaddr(struct sockaddr *);
285 printf("aarpresolv: failed for %s\n", prsockaddr(dst));
286 #endif
287 return (0);
288 }
289
290
291
292
293 aa = (struct at_ifaddr *)at_ifawithnet(
294 (struct sockaddr_at *)dst,
295 TAILQ_FIRST(&ifp->if_addrlist));
296 if (aa == 0)
297 goto bad;
298
299
300
301
302
303
304
305 if (aa->aa_flags & AFA_PHASE2) {
306 struct llc llc;
307
308 M_PREPEND(m, AT_LLC_SIZE, M_DONTWAIT);
309 if (m == NULL)
310 return (0);
311
312
313
314
315
316 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
317 llc.llc_control = LLC_UI;
318 bcopy(at_org_code, llc.llc_snap.org_code,
319 sizeof(at_org_code));
320 llc.llc_snap.ether_type = htons( ETHERTYPE_AT );
321 bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE);
322 etype = htons(m->m_pkthdr.len);
323 } else {
324 etype = htons(ETHERTYPE_AT);
325 }
326 } break;
327 #endif
328 case pseudo_AF_HDRCMPLT:
329 hdrcmplt = 1;
330 eh = (struct ether_header *)dst->sa_data;
331 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof(esrc));
332
333
334 case AF_UNSPEC:
335 eh = (struct ether_header *)dst->sa_data;
336 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof(edst));
337
338 etype = eh->ether_type;
339 break;
340
341 default:
342 printf("%s: can't handle af%d\n", ifp->if_xname,
343 dst->sa_family);
344 senderr(EAFNOSUPPORT);
345 }
346
347
348 if (mcopy)
349 (void) looutput(ifp, mcopy, dst, rt);
350
351
352
353
354
355 M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT);
356 if (m == 0)
357 senderr(ENOBUFS);
358 eh = mtod(m, struct ether_header *);
359 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
360 sizeof(eh->ether_type));
361 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof(edst));
362 if (hdrcmplt)
363 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost,
364 sizeof(eh->ether_shost));
365 else
366 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost,
367 sizeof(eh->ether_shost));
368
369 #if NCARP > 0
370 if (ifp0 != ifp && ifp0->if_type == IFT_CARP &&
371 !(ifp0->if_flags & IFF_LINK1)) {
372 bcopy((caddr_t)((struct arpcom *)ifp0)->ac_enaddr,
373 (caddr_t)eh->ether_shost, sizeof(eh->ether_shost));
374 }
375 #endif
376
377 #if NBRIDGE > 0
378
379
380
381
382 if (ifp->if_bridge) {
383 struct m_tag *mtag;
384
385
386
387
388
389
390 for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
391 mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) {
392 #ifdef DEBUG
393
394 if (mtag->m_tag_len != sizeof(caddr_t)) {
395 error = EINVAL;
396 goto bad;
397 }
398 #endif
399 if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)))
400 break;
401 }
402 if (mtag == NULL) {
403
404 mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t),
405 M_NOWAIT);
406 if (mtag == NULL) {
407 error = ENOBUFS;
408 goto bad;
409 }
410 bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t));
411 m_tag_prepend(m, mtag);
412 error = bridge_output(ifp, m, NULL, NULL);
413 return (error);
414 }
415 }
416 #endif
417
418 mflags = m->m_flags;
419 len = m->m_pkthdr.len;
420 s = splnet();
421
422
423
424
425 IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
426 if (error) {
427
428 splx(s);
429 return (error);
430 }
431 ifp->if_obytes += len + ETHER_HDR_LEN;
432 #if NCARP > 0
433 if (ifp != ifp0)
434 ifp0->if_obytes += len + ETHER_HDR_LEN;
435 #endif
436 if (mflags & M_MCAST)
437 ifp->if_omcasts++;
438 if ((ifp->if_flags & IFF_OACTIVE) == 0)
439 (*ifp->if_start)(ifp);
440 splx(s);
441 return (error);
442
443 bad:
444 if (m)
445 m_freem(m);
446 return (error);
447 }
448
449
450
451
452
453
454 void
455 ether_input(ifp, eh, m)
456 struct ifnet *ifp;
457 struct ether_header *eh;
458 struct mbuf *m;
459 {
460 struct ifqueue *inq;
461 u_int16_t etype;
462 int s, llcfound = 0;
463 struct llc *l;
464 struct arpcom *ac;
465 #if NTRUNK > 0
466 int i = 0;
467 #endif
468 #if NPPPOE > 0
469 struct ether_header *eh_tmp;
470 #endif
471
472 if (eh == NULL) {
473 eh = mtod(m, struct ether_header *);
474 m_adj(m, ETHER_HDR_LEN);
475 }
476
477 #if NTRUNK > 0
478
479 while (ifp->if_type == IFT_IEEE8023ADLAG) {
480 if (++i > TRUNK_MAX_STACKING ||
481 trunk_input(ifp, eh, m) != 0) {
482 if (m)
483 m_freem(m);
484 return;
485 }
486
487
488 ifp = m->m_pkthdr.rcvif;
489 }
490 #endif
491
492 if ((ifp->if_flags & IFF_UP) == 0) {
493 m_freem(m);
494 return;
495 }
496 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
497 if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
498 struct ifaddr *ifa;
499 struct sockaddr_dl *sdl = NULL;
500
501 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
502 if ((sdl =
503 (struct sockaddr_dl *)ifa->ifa_addr) &&
504 sdl->sdl_family == AF_LINK)
505 break;
506 }
507
508
509
510
511 if (sdl && bcmp(LLADDR(sdl), eh->ether_shost,
512 ETHER_ADDR_LEN) == 0) {
513 m_freem(m);
514 return;
515 }
516 }
517
518 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
519 sizeof(etherbroadcastaddr)) == 0)
520 m->m_flags |= M_BCAST;
521 else
522 m->m_flags |= M_MCAST;
523 ifp->if_imcasts++;
524 }
525
526 ifp->if_ibytes += m->m_pkthdr.len + sizeof(*eh);
527
528 etype = ntohs(eh->ether_type);
529
530 #if NVLAN > 0
531 if (etype == ETHERTYPE_VLAN && (vlan_input(eh, m) == 0))
532 return;
533 #endif
534
535 #if NBRIDGE > 0
536
537
538
539
540
541
542 if (ifp->if_bridge) {
543 if (m->m_flags & M_PROTO1)
544 m->m_flags &= ~M_PROTO1;
545 else {
546 m = bridge_input(ifp, eh, m);
547 if (m == NULL)
548 return;
549
550 ifp = m->m_pkthdr.rcvif;
551 }
552 }
553 #endif
554
555 #if NVLAN > 0
556 if (etype == ETHERTYPE_VLAN) {
557
558 ifp->if_noproto++;
559 m_freem(m);
560 return;
561 }
562 #endif
563
564 #if NCARP > 0
565 if (ifp->if_carp) {
566 if (ifp->if_type != IFT_CARP &&
567 (carp_input(m, (u_int8_t *)&eh->ether_shost,
568 (u_int8_t *)&eh->ether_dhost, eh->ether_type) == 0))
569 return;
570
571 else if (ifp->if_type == IFT_CARP &&
572 ifp->if_flags & IFF_LINK2 &&
573 m->m_flags & (M_BCAST|M_MCAST) &&
574 !bcmp(((struct arpcom *)ifp)->ac_enaddr,
575 (caddr_t)eh->ether_dhost, ETHER_ADDR_LEN))
576 m->m_flags &= ~(M_BCAST|M_MCAST);
577 }
578 #endif
579
580 ac = (struct arpcom *)ifp;
581
582
583
584
585 if (m->m_flags & M_FILDROP) {
586 m_free(m);
587 return;
588 }
589
590
591
592
593
594 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
595 (ifp->if_flags & IFF_PROMISC)) {
596 if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost,
597 ETHER_ADDR_LEN)) {
598 m_freem(m);
599 return;
600 }
601 }
602
603 decapsulate:
604
605 switch (etype) {
606 #ifdef INET
607 case ETHERTYPE_IP:
608 schednetisr(NETISR_IP);
609 inq = &ipintrq;
610 break;
611
612 case ETHERTYPE_ARP:
613 if (ifp->if_flags & IFF_NOARP)
614 goto dropanyway;
615 schednetisr(NETISR_ARP);
616 inq = &arpintrq;
617 break;
618
619 case ETHERTYPE_REVARP:
620 if (ifp->if_flags & IFF_NOARP)
621 goto dropanyway;
622 revarpinput(m);
623 return;
624
625 #endif
626 #ifdef INET6
627
628
629
630 case ETHERTYPE_IPV6:
631 schednetisr(NETISR_IPV6);
632 inq = &ip6intrq;
633 break;
634 #endif
635 #ifdef NETATALK
636 case ETHERTYPE_AT:
637 schednetisr(NETISR_ATALK);
638 inq = &atintrq1;
639 break;
640 case ETHERTYPE_AARP:
641
642
643 aarpinput((struct arpcom *)ifp, m);
644 return;
645 #endif
646 #if NPPPOE > 0
647 case ETHERTYPE_PPPOEDISC:
648 case ETHERTYPE_PPPOE:
649
650
651
652
653
654
655
656 #ifndef PPPOE_SERVER
657 if (m->m_flags & (M_MCAST | M_BCAST)) {
658 m_freem(m);
659 return;
660 }
661 #endif
662 M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
663 if (m == NULL)
664 return;
665
666 eh_tmp = mtod(m, struct ether_header *);
667 bcopy(eh, eh_tmp, sizeof(struct ether_header));
668
669 if (etype == ETHERTYPE_PPPOEDISC)
670 inq = &ppoediscinq;
671 else
672 inq = &ppoeinq;
673
674 schednetisr(NETISR_PPPOE);
675 break;
676 #endif
677 default:
678 if (llcfound || etype > ETHERMTU)
679 goto dropanyway;
680 llcfound = 1;
681 l = mtod(m, struct llc *);
682 switch (l->llc_dsap) {
683 case LLC_SNAP_LSAP:
684 #ifdef NETATALK
685
686
687
688
689
690
691
692 if (l->llc_control == LLC_UI &&
693 l->llc_ssap == LLC_SNAP_LSAP &&
694 Bcmp(&(l->llc_snap.org_code)[0],
695 at_org_code, sizeof(at_org_code)) == 0 &&
696 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) {
697 inq = &atintrq2;
698 m_adj(m, AT_LLC_SIZE);
699 schednetisr(NETISR_ATALK);
700 break;
701 }
702
703 if (l->llc_control == LLC_UI &&
704 l->llc_ssap == LLC_SNAP_LSAP &&
705 Bcmp(&(l->llc_snap.org_code)[0],
706 aarp_org_code, sizeof(aarp_org_code)) == 0 &&
707 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) {
708 m_adj(m, AT_LLC_SIZE);
709
710 aarpinput((struct arpcom *)ifp, m);
711 return;
712 }
713 #endif
714 if (l->llc_control == LLC_UI &&
715 l->llc_dsap == LLC_SNAP_LSAP &&
716 l->llc_ssap == LLC_SNAP_LSAP) {
717
718 if (m->m_pkthdr.len > etype)
719 m_adj(m, etype - m->m_pkthdr.len);
720 m->m_data += 6;
721 m->m_len -= 6;
722 m->m_pkthdr.len -= 6;
723 M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
724 if (m == 0)
725 return;
726 *mtod(m, struct ether_header *) = *eh;
727 goto decapsulate;
728 }
729 goto dropanyway;
730 dropanyway:
731 default:
732 m_freem(m);
733 return;
734 }
735 }
736
737 s = splnet();
738 IF_INPUT_ENQUEUE(inq, m);
739 splx(s);
740 }
741
742
743
744
745 static char digits[] = "0123456789abcdef";
746 char *
747 ether_sprintf(ap)
748 u_char *ap;
749 {
750 int i;
751 static char etherbuf[ETHER_ADDR_LEN * 3];
752 char *cp = etherbuf;
753
754 for (i = 0; i < ETHER_ADDR_LEN; i++) {
755 *cp++ = digits[*ap >> 4];
756 *cp++ = digits[*ap++ & 0xf];
757 *cp++ = ':';
758 }
759 *--cp = 0;
760 return (etherbuf);
761 }
762
763
764
765
766 void
767 ether_ifattach(ifp)
768 struct ifnet *ifp;
769 {
770
771
772
773
774
775 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) {
776 ((struct arpcom *)ifp)->ac_enaddr[0] = 0x00;
777 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe;
778 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1;
779 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xba;
780 ((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0;
781
782
783
784
785
786 ((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)random() & 0xff;
787 }
788
789 ifp->if_type = IFT_ETHER;
790 ifp->if_addrlen = ETHER_ADDR_LEN;
791 ifp->if_hdrlen = ETHER_HDR_LEN;
792 ifp->if_mtu = ETHERMTU;
793 ifp->if_output = ether_output;
794
795 if (ifp->if_hardmtu == 0)
796 ifp->if_hardmtu = ETHERMTU;
797
798 if_alloc_sadl(ifp);
799 bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
800 LLADDR(ifp->if_sadl), ifp->if_addrlen);
801 LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
802 #if NBPFILTER > 0
803 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
804 #endif
805 }
806
807 void
808 ether_ifdetach(ifp)
809 struct ifnet *ifp;
810 {
811 struct arpcom *ac = (struct arpcom *)ifp;
812 struct ether_multi *enm;
813
814 for (enm = LIST_FIRST(&ac->ac_multiaddrs);
815 enm != LIST_END(&ac->ac_multiaddrs);
816 enm = LIST_FIRST(&ac->ac_multiaddrs)) {
817 LIST_REMOVE(enm, enm_list);
818 free(enm, M_IFMADDR);
819 }
820
821 #if 0
822
823 if_free_sadl(ifp);
824 #endif
825 }
826
827 #if 0
828
829
830
831
832 u_int32_t
833 ether_crc32_le(const u_int8_t *buf, size_t len)
834 {
835 u_int32_t c, crc, carry;
836 size_t i, j;
837
838 crc = 0xffffffffU;
839
840 for (i = 0; i < len; i++) {
841 c = buf[i];
842 for (j = 0; j < 8; j++) {
843 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
844 crc >>= 1;
845 c >>= 1;
846 if (carry)
847 crc = (crc ^ ETHER_CRC_POLY_LE);
848 }
849 }
850
851 return (crc);
852 }
853
854 u_int32_t
855 ether_crc32_be(const u_int8_t *buf, size_t len)
856 {
857 u_int32_t c, crc, carry;
858 size_t i, j;
859
860 crc = 0xffffffffU;
861
862 for (i = 0; i < len; i++) {
863 c = buf[i];
864 for (j = 0; j < 8; j++) {
865 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
866 crc <<= 1;
867 c >>= 1;
868 if (carry)
869 crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
870 }
871 }
872
873 return (crc);
874 }
875 #else
876 u_int32_t
877 ether_crc32_le(const u_int8_t *buf, size_t len)
878 {
879 static const u_int32_t crctab[] = {
880 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
881 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
882 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
883 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
884 };
885 size_t i;
886 u_int32_t crc;
887
888 crc = 0xffffffffU;
889
890 for (i = 0; i < len; i++) {
891 crc ^= buf[i];
892 crc = (crc >> 4) ^ crctab[crc & 0xf];
893 crc = (crc >> 4) ^ crctab[crc & 0xf];
894 }
895
896 return (crc);
897 }
898
899 u_int32_t
900 ether_crc32_be(const u_int8_t *buf, size_t len)
901 {
902 static const u_int8_t rev[] = {
903 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
904 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
905 };
906 static const u_int32_t crctab[] = {
907 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
908 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
909 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
910 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
911 };
912 size_t i;
913 u_int32_t crc;
914 u_int8_t data;
915
916 crc = 0xffffffffU;
917 for (i = 0; i < len; i++) {
918 data = buf[i];
919 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
920 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
921 }
922
923 return (crc);
924 }
925 #endif
926
927 #ifdef INET
928 u_char ether_ipmulticast_min[ETHER_ADDR_LEN] =
929 { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
930 u_char ether_ipmulticast_max[ETHER_ADDR_LEN] =
931 { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
932 #endif
933
934 #ifdef INET6
935 u_char ether_ip6multicast_min[ETHER_ADDR_LEN] =
936 { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
937 u_char ether_ip6multicast_max[ETHER_ADDR_LEN] =
938 { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
939 #endif
940
941
942
943
944
945 int
946 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
947 u_int8_t addrhi[ETHER_ADDR_LEN])
948 {
949 #ifdef INET
950 struct sockaddr_in *sin;
951 #endif
952 #ifdef INET6
953 struct sockaddr_in6 *sin6;
954 #endif
955
956 switch (sa->sa_family) {
957
958 case AF_UNSPEC:
959 bcopy(sa->sa_data, addrlo, ETHER_ADDR_LEN);
960 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
961 break;
962
963 #ifdef INET
964 case AF_INET:
965 sin = satosin(sa);
966 if (sin->sin_addr.s_addr == INADDR_ANY) {
967
968
969
970
971
972
973 bcopy(ether_ipmulticast_min, addrlo, ETHER_ADDR_LEN);
974 bcopy(ether_ipmulticast_max, addrhi, ETHER_ADDR_LEN);
975 } else {
976 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
977 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
978 }
979 break;
980 #endif
981 #ifdef INET6
982 case AF_INET6:
983 sin6 = satosin6(sa);
984 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
985
986
987
988
989
990
991
992
993
994
995
996
997 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
998 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
999 } else {
1000 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
1001 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
1002 }
1003 break;
1004 #endif
1005
1006 default:
1007 return (EAFNOSUPPORT);
1008 }
1009 return (0);
1010 }
1011
1012
1013
1014
1015
1016 int
1017 ether_addmulti(ifr, ac)
1018 struct ifreq *ifr;
1019 struct arpcom *ac;
1020 {
1021 struct ether_multi *enm;
1022 u_char addrlo[ETHER_ADDR_LEN];
1023 u_char addrhi[ETHER_ADDR_LEN];
1024 int s = splnet(), error;
1025
1026 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1027 if (error != 0) {
1028 splx(s);
1029 return (error);
1030 }
1031
1032
1033
1034
1035 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
1036 splx(s);
1037 return (EINVAL);
1038 }
1039
1040
1041
1042 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1043 if (enm != NULL) {
1044
1045
1046
1047 ++enm->enm_refcount;
1048 splx(s);
1049 return (0);
1050 }
1051
1052
1053
1054
1055 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
1056 if (enm == NULL) {
1057 splx(s);
1058 return (ENOBUFS);
1059 }
1060 bcopy(addrlo, enm->enm_addrlo, ETHER_ADDR_LEN);
1061 bcopy(addrhi, enm->enm_addrhi, ETHER_ADDR_LEN);
1062 enm->enm_ac = ac;
1063 enm->enm_refcount = 1;
1064 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
1065 ac->ac_multicnt++;
1066 if (bcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
1067 ac->ac_multirangecnt++;
1068 splx(s);
1069
1070
1071
1072
1073 return (ENETRESET);
1074 }
1075
1076
1077
1078
1079 int
1080 ether_delmulti(ifr, ac)
1081 struct ifreq *ifr;
1082 struct arpcom *ac;
1083 {
1084 struct ether_multi *enm;
1085 u_char addrlo[ETHER_ADDR_LEN];
1086 u_char addrhi[ETHER_ADDR_LEN];
1087 int s = splnet(), error;
1088
1089 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1090 if (error != 0) {
1091 splx(s);
1092 return (error);
1093 }
1094
1095
1096
1097
1098 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1099 if (enm == NULL) {
1100 splx(s);
1101 return (ENXIO);
1102 }
1103 if (--enm->enm_refcount != 0) {
1104
1105
1106
1107 splx(s);
1108 return (0);
1109 }
1110
1111
1112
1113 LIST_REMOVE(enm, enm_list);
1114 free(enm, M_IFMADDR);
1115 ac->ac_multicnt--;
1116 if (bcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
1117 ac->ac_multirangecnt--;
1118 splx(s);
1119
1120
1121
1122
1123 return (ENETRESET);
1124 }