1 /* $OpenBSD: if_ethersubr.c,v 1.286 2023/01/26 07:32:40 deraadt Exp $ */
2 /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
3
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1982, 1989, 1993
35 * The Regents of the University of California. All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
62 */
63
64 /*
65 %%% portions-copyright-nrl-95
66 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
67 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
68 Reserved. All rights under this copyright have been assigned to the US
69 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
70 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
71 software.
72 You should have received a copy of the license with this software. If you
73 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
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/socket.h>
84 #include <sys/ioctl.h>
85 #include <sys/errno.h>
86 #include <sys/syslog.h>
87 #include <sys/timeout.h>
88 #include <sys/smr.h>
89
90 #include <net/if.h>
91 #include <net/netisr.h>
92 #include <net/route.h>
93 #include <net/if_llc.h>
94 #include <net/if_dl.h>
95 #include <net/if_media.h>
96 #include <net/if_types.h>
97
98 #include <netinet/in.h>
99 #include <netinet/if_ether.h>
100 #include <netinet/ip_ipsp.h>
101
102 #if NBPFILTER > 0
103 #include <net/bpf.h>
104 #endif
105
106 #include "vlan.h"
107 #if NVLAN > 0
108 #include <net/if_vlan_var.h>
109 #endif
110
111 #include "carp.h"
112 #if NCARP > 0
113 #include <netinet/ip_carp.h>
114 #endif
115
116 #include "pppoe.h"
117 #if NPPPOE > 0
118 #include <net/if_pppoe.h>
119 #endif
120
121 #include "bpe.h"
122 #if NBPE > 0
123 #include <net/if_bpe.h>
124 #endif
125
126 #ifdef INET6
127 #include <netinet6/in6_var.h>
128 #include <netinet6/nd6.h>
129 #endif
130
131 #ifdef PIPEX
132 #include <net/pipex.h>
133 #endif
134
135 #ifdef MPLS
136 #include <netmpls/mpls.h>
137 #endif /* MPLS */
138
139 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
140 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
141 u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
142 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
143 #define senderr(e) { error = (e); goto bad;}
144
145 int
146 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data)
147 {
148 struct ifreq *ifr = (struct ifreq *)data;
149 int error = 0;
150
151 switch (cmd) {
152 case SIOCSIFADDR:
153 break;
154
155 case SIOCSIFMTU:
156 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
157 error = EINVAL;
158 else
159 ifp->if_mtu = ifr->ifr_mtu;
160 break;
161
162 case SIOCADDMULTI:
163 case SIOCDELMULTI:
164 if (ifp->if_flags & IFF_MULTICAST) {
165 error = (cmd == SIOCADDMULTI) ?
166 ether_addmulti(ifr, arp) :
167 ether_delmulti(ifr, arp);
168 } else
169 error = ENOTTY;
170 break;
171
172 default:
173 error = ENOTTY;
174 }
175
176 return (error);
177 }
178
179
180 void
181 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
182 {
183 if (rt == NULL)
184 return;
185
186 switch (rt_key(rt)->sa_family) {
187 case AF_INET:
188 arp_rtrequest(ifp, req, rt);
189 break;
190 #ifdef INET6
191 case AF_INET6:
192 nd6_rtrequest(ifp, req, rt);
193 break;
194 #endif
195 default:
196 break;
197 }
198 }
199
200 int
201 ether_resolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
202 struct rtentry *rt, struct ether_header *eh)
203 {
204 struct arpcom *ac = (struct arpcom *)ifp;
205 sa_family_t af = dst->sa_family;
206 int error = 0;
207
208 if (!ISSET(ifp->if_flags, IFF_RUNNING))
209 senderr(ENETDOWN);
210
211 KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
212 af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
213
214 #ifdef DIAGNOSTIC
215 if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
216 printf("%s: trying to send packet on wrong domain. "
217 "if %d vs. mbuf %d\n", ifp->if_xname,
218 ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
219 }
220 #endif
221
222 switch (af) {
223 case AF_INET:
224 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
225 if (error)
226 return (error);
227 eh->ether_type = htons(ETHERTYPE_IP);
228
229 /*
230 * If broadcasting on a simplex interface, loopback a copy.
231 * The checksum must be calculated in software. Keep the
232 * condition in sync with in_ifcap_cksum().
233 */
234 if (ISSET(m->m_flags, M_BCAST) &&
235 ISSET(ifp->if_flags, IFF_SIMPLEX) &&
236 !m->m_pkthdr.pf.routed) {
237 struct mbuf *mcopy;
238
239 /* XXX Should we input an unencrypted IPsec packet? */
240 mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
241 if (mcopy != NULL)
242 if_input_local(ifp, mcopy, af);
243 }
244 break;
245 #ifdef INET6
246 case AF_INET6:
247 KERNEL_LOCK();
248 /* XXXSMP there is a MP race in nd6_resolve() */
249 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
250 KERNEL_UNLOCK();
251 if (error)
252 return (error);
253 eh->ether_type = htons(ETHERTYPE_IPV6);
254 break;
255 #endif
256 #ifdef MPLS
257 case AF_MPLS:
258 if (rt == NULL)
259 senderr(EHOSTUNREACH);
260
261 if (!ISSET(ifp->if_xflags, IFXF_MPLS))
262 senderr(ENETUNREACH);
263
264 dst = ISSET(rt->rt_flags, RTF_GATEWAY) ?
265 rt->rt_gateway : rt_key(rt);
266
267 switch (dst->sa_family) {
268 case AF_LINK:
269 if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost))
270 senderr(EHOSTUNREACH);
271 memcpy(eh->ether_dhost, LLADDR(satosdl(dst)),
272 sizeof(eh->ether_dhost));
273 break;
274 #ifdef INET6
275 case AF_INET6:
276 KERNEL_LOCK();
277 /* XXXSMP there is a MP race in nd6_resolve() */
278 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
279 KERNEL_UNLOCK();
280 if (error)
281 return (error);
282 break;
283 #endif
284 case AF_INET:
285 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
286 if (error)
287 return (error);
288 break;
289 default:
290 senderr(EHOSTUNREACH);
291 }
292 /* XXX handling for simplex devices in case of M/BCAST ?? */
293 if (m->m_flags & (M_BCAST | M_MCAST))
294 eh->ether_type = htons(ETHERTYPE_MPLS_MCAST);
295 else
296 eh->ether_type = htons(ETHERTYPE_MPLS);
297 break;
298 #endif /* MPLS */
299 case pseudo_AF_HDRCMPLT:
300 /* take the whole header from the sa */
301 memcpy(eh, dst->sa_data, sizeof(*eh));
302 return (0);
303
304 case AF_UNSPEC:
305 /* take the dst and type from the sa, but get src below */
306 memcpy(eh, dst->sa_data, sizeof(*eh));
307 break;
308
309 default:
310 printf("%s: can't handle af%d\n", ifp->if_xname, af);
311 senderr(EAFNOSUPPORT);
312 }
313
314 memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost));
315
316 return (0);
317
318 bad:
319 m_freem(m);
320 return (error);
321 }
322
323 struct mbuf*
324 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
325 struct rtentry *rt, int *errorp)
326 {
327 struct ether_header eh;
328 int error;
329
330 error = ether_resolve(ifp, m, dst, rt, &eh);
331 switch (error) {
332 case 0:
333 break;
334 case EAGAIN:
335 error = 0;
336 default:
337 *errorp = error;
338 return (NULL);
339 }
340
341 m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT);
342 if (m == NULL) {
343 *errorp = ENOBUFS;
344 return (NULL);
345 }
346
347 m_adj(m, ETHER_ALIGN);
348 memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh));
349
350 return (m);
351 }
352
353 int
354 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
355 struct rtentry *rt)
356 {
357 int error;
358
359 m = ether_encap(ifp, m, dst, rt, &error);
360 if (m == NULL)
361 return (error);
362
363 return (if_enqueue(ifp, m));
364 }
365
366 /*
367 * Process a received Ethernet packet.
368 *
369 * Ethernet input has several "phases" of filtering packets to
370 * support virtual/pseudo interfaces before actual layer 3 protocol
371 * handling.
372 *
373 * First phase:
374 *
375 * The first phase supports drivers that aggregate multiple Ethernet
376 * ports into a single logical interface, ie, aggr(4) and trunk(4).
377 * These drivers intercept packets by swapping out the if_input handler
378 * on the "port" interfaces to steal the packets before they get here
379 * to ether_input().
380 */
381 void
382 ether_input(struct ifnet *ifp, struct mbuf *m)
383 {
384 struct ether_header *eh;
385 void (*input)(struct ifnet *, struct mbuf *);
386 u_int16_t etype;
387 struct arpcom *ac;
388 const struct ether_brport *eb;
389 unsigned int sdelim = 0;
390 uint64_t dst, self;
391
392 /* Drop short frames */
393 if (m->m_len < ETHER_HDR_LEN)
394 goto dropanyway;
395
396 /*
397 * Second phase: service delimited packet filtering.
398 *
399 * Let vlan(4) and svlan(4) look at "service delimited"
400 * packets. If a virtual interface does not exist to take
401 * those packets, they're returned to ether_input() so a
402 * bridge can have a go at forwarding them.
403 */
404
405 eh = mtod(m, struct ether_header *);
406 dst = ether_addr_to_e64((struct ether_addr *)eh->ether_dhost);
407 etype = ntohs(eh->ether_type);
408
409 if (ISSET(m->m_flags, M_VLANTAG) ||
410 etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ) {
411 #if NVLAN > 0
412 m = vlan_input(ifp, m, &sdelim);
413 if (m == NULL)
414 return;
415 #else
416 sdelim = 1;
417 #endif
418 }
419
420 /*
421 * Third phase: bridge processing.
422 *
423 * Give the packet to a bridge interface, ie, bridge(4),
424 * veb(4), or tpmr(4), if it is configured. A bridge
425 * may take the packet and forward it to another port, or it
426 * may return it here to ether_input() to support local
427 * delivery to this port.
428 */
429
430 ac = (struct arpcom *)ifp;
431
432 smr_read_enter();
433 eb = SMR_PTR_GET(&ac->ac_brport);
434 if (eb != NULL)
435 eb->eb_port_take(eb->eb_port);
436 smr_read_leave();
437 if (eb != NULL) {
438 m = (*eb->eb_input)(ifp, m, dst, eb->eb_port);
439 eb->eb_port_rele(eb->eb_port);
440 if (m == NULL) {
441 return;
442 }
443 }
444
445 /*
446 * Fourth phase: drop service delimited packets.
447 *
448 * If the packet has a tag, and a bridge didn't want it,
449 * it's not for this port.
450 */
451
452 if (sdelim)
453 goto dropanyway;
454
455 /*
456 * Fifth phase: destination address check.
457 *
458 * Is the packet specifically addressed to this port?
459 */
460
461 eh = mtod(m, struct ether_header *);
462 self = ether_addr_to_e64((struct ether_addr *)ac->ac_enaddr);
463 if (dst != self) {
464 #if NCARP > 0
465 /*
466 * If it's not for this port, it could be for carp(4).
467 */
468 if (ifp->if_type != IFT_CARP &&
469 !SRPL_EMPTY_LOCKED(&ifp->if_carp)) {
470 m = carp_input(ifp, m, dst);
471 if (m == NULL)
472 return;
473
474 eh = mtod(m, struct ether_header *);
475 }
476 #endif
477
478 /*
479 * If not, it must be multicast or broadcast to go further.
480 */
481 if (!ETH64_IS_MULTICAST(dst))
482 goto dropanyway;
483
484 /*
485 * If this is not a simplex interface, drop the packet
486 * if it came from us.
487 */
488 if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
489 uint64_t src = ether_addr_to_e64(
490 (struct ether_addr *)eh->ether_shost);
491 if (self == src)
492 goto dropanyway;
493 }
494
495 SET(m->m_flags, ETH64_IS_BROADCAST(dst) ? M_BCAST : M_MCAST);
496 ifp->if_imcasts++;
497 }
498
499 /*
500 * Sixth phase: protocol demux.
501 *
502 * At this point it is known that the packet is destined
503 * for layer 3 protocol handling on the local port.
504 */
505 etype = ntohs(eh->ether_type);
506
507 switch (etype) {
508 case ETHERTYPE_IP:
509 input = ipv4_input;
510 break;
511
512 case ETHERTYPE_ARP:
513 if (ifp->if_flags & IFF_NOARP)
514 goto dropanyway;
515 input = arpinput;
516 break;
517
518 case ETHERTYPE_REVARP:
519 if (ifp->if_flags & IFF_NOARP)
520 goto dropanyway;
521 input = revarpinput;
522 break;
523
524 #ifdef INET6
525 /*
526 * Schedule IPv6 software interrupt for incoming IPv6 packet.
527 */
528 case ETHERTYPE_IPV6:
529 input = ipv6_input;
530 break;
531 #endif /* INET6 */
532 #if NPPPOE > 0 || defined(PIPEX)
533 case ETHERTYPE_PPPOEDISC:
534 case ETHERTYPE_PPPOE:
535 if (m->m_flags & (M_MCAST | M_BCAST))
536 goto dropanyway;
537 #ifdef PIPEX
538 if (pipex_enable) {
539 struct pipex_session *session;
540
541 if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
542 pipex_pppoe_input(m, session);
543 pipex_rele_session(session);
544 return;
545 }
546 }
547 #endif
548 if (etype == ETHERTYPE_PPPOEDISC) {
549 if (mq_enqueue(&pppoediscinq, m) == 0)
550 schednetisr(NETISR_PPPOE);
551 } else {
552 if (mq_enqueue(&pppoeinq, m) == 0)
553 schednetisr(NETISR_PPPOE);
554 }
555 return;
556 #endif
557 #ifdef MPLS
558 case ETHERTYPE_MPLS:
559 case ETHERTYPE_MPLS_MCAST:
560 input = mpls_input;
561 break;
562 #endif
563 #if NBPE > 0
564 case ETHERTYPE_PBB:
565 bpe_input(ifp, m);
566 return;
567 #endif
568 default:
569 goto dropanyway;
570 }
571
572 m_adj(m, sizeof(*eh));
573 (*input)(ifp, m);
574 return;
575 dropanyway:
576 m_freem(m);
577 return;
578 }
579
580 int
581 ether_brport_isset(struct ifnet *ifp)
582 {
583 struct arpcom *ac = (struct arpcom *)ifp;
584
585 KERNEL_ASSERT_LOCKED();
586 if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL)
587 return (EBUSY);
588
589 return (0);
590 }
591
592 void
593 ether_brport_set(struct ifnet *ifp, const struct ether_brport *eb)
594 {
595 struct arpcom *ac = (struct arpcom *)ifp;
596
597 KERNEL_ASSERT_LOCKED();
598 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL,
599 "%s setting an already set brport", ifp->if_xname);
600
601 SMR_PTR_SET_LOCKED(&ac->ac_brport, eb);
602 }
603
604 void
605 ether_brport_clr(struct ifnet *ifp)
606 {
607 struct arpcom *ac = (struct arpcom *)ifp;
608
609 KERNEL_ASSERT_LOCKED();
610 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL,
611 "%s clearing an already clear brport", ifp->if_xname);
612
613 SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL);
614 }
615
616 const struct ether_brport *
617 ether_brport_get(struct ifnet *ifp)
618 {
619 struct arpcom *ac = (struct arpcom *)ifp;
620 SMR_ASSERT_CRITICAL();
621 return (SMR_PTR_GET(&ac->ac_brport));
622 }
623
624 const struct ether_brport *
625 ether_brport_get_locked(struct ifnet *ifp)
626 {
627 struct arpcom *ac = (struct arpcom *)ifp;
628 KERNEL_ASSERT_LOCKED();
629 return (SMR_PTR_GET_LOCKED(&ac->ac_brport));
630 }
631
632 /*
633 * Convert Ethernet address to printable (loggable) representation.
634 */
635 static char digits[] = "0123456789abcdef";
636 char *
637 ether_sprintf(u_char *ap)
638 {
639 int i;
640 static char etherbuf[ETHER_ADDR_LEN * 3];
641 char *cp = etherbuf;
642
643 for (i = 0; i < ETHER_ADDR_LEN; i++) {
644 *cp++ = digits[*ap >> 4];
645 *cp++ = digits[*ap++ & 0xf];
646 *cp++ = ':';
647 }
648 *--cp = 0;
649 return (etherbuf);
650 }
651
652 /*
653 * Generate a (hopefully) acceptable MAC address, if asked.
654 */
655 void
656 ether_fakeaddr(struct ifnet *ifp)
657 {
658 static int unit;
659 int rng = arc4random();
660
661 /* Non-multicast; locally administered address */
662 ((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
663 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
664 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
665 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
666 ((struct arpcom *)ifp)->ac_enaddr[4] = rng;
667 ((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
668 }
669
670 /*
671 * Perform common duties while attaching to interface list
672 */
673 void
674 ether_ifattach(struct ifnet *ifp)
675 {
676 struct arpcom *ac = (struct arpcom *)ifp;
677
678 /*
679 * Any interface which provides a MAC address which is obviously
680 * invalid gets whacked, so that users will notice.
681 */
682 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
683 ether_fakeaddr(ifp);
684
685 ifp->if_type = IFT_ETHER;
686 ifp->if_addrlen = ETHER_ADDR_LEN;
687 ifp->if_hdrlen = ETHER_HDR_LEN;
688 ifp->if_mtu = ETHERMTU;
689 ifp->if_input = ether_input;
690 if (ifp->if_output == NULL)
691 ifp->if_output = ether_output;
692 ifp->if_rtrequest = ether_rtrequest;
693
694 if (ifp->if_hardmtu == 0)
695 ifp->if_hardmtu = ETHERMTU;
696
697 if_alloc_sadl(ifp);
698 memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen);
699 LIST_INIT(&ac->ac_multiaddrs);
700 #if NBPFILTER > 0
701 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
702 #endif
703 }
704
705 void
706 ether_ifdetach(struct ifnet *ifp)
707 {
708 struct arpcom *ac = (struct arpcom *)ifp;
709 struct ether_multi *enm;
710
711 /* Undo pseudo-driver changes. */
712 if_deactivate(ifp);
713
714 for (enm = LIST_FIRST(&ac->ac_multiaddrs);
715 enm != NULL;
716 enm = LIST_FIRST(&ac->ac_multiaddrs)) {
717 LIST_REMOVE(enm, enm_list);
718 free(enm, M_IFMADDR, sizeof *enm);
719 }
720 }
721
722 #if 0
723 /*
724 * This is for reference. We have table-driven versions of the
725 * crc32 generators, which are faster than the double-loop.
726 */
727 u_int32_t __pure
728 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
729 {
730 u_int32_t c, carry;
731 size_t i, j;
732
733 for (i = 0; i < len; i++) {
734 c = buf[i];
735 for (j = 0; j < 8; j++) {
736 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
737 crc >>= 1;
738 c >>= 1;
739 if (carry)
740 crc = (crc ^ ETHER_CRC_POLY_LE);
741 }
742 }
743
744 return (crc);
745 }
746
747 u_int32_t __pure
748 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
749 {
750 u_int32_t c, carry;
751 size_t i, j;
752
753 for (i = 0; i < len; i++) {
754 c = buf[i];
755 for (j = 0; j < 8; j++) {
756 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
757 crc <<= 1;
758 c >>= 1;
759 if (carry)
760 crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
761 }
762 }
763
764 return (crc);
765 }
766 #else
767 u_int32_t __pure
768 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len)
769 {
770 static const u_int32_t crctab[] = {
771 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
772 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
773 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
774 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
775 };
776 size_t i;
777
778 for (i = 0; i < len; i++) {
779 crc ^= buf[i];
780 crc = (crc >> 4) ^ crctab[crc & 0xf];
781 crc = (crc >> 4) ^ crctab[crc & 0xf];
782 }
783
784 return (crc);
785 }
786
787 u_int32_t __pure
788 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len)
789 {
790 static const u_int8_t rev[] = {
791 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
792 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
793 };
794 static const u_int32_t crctab[] = {
795 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
796 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
797 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
798 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
799 };
800 size_t i;
801 u_int8_t data;
802
803 for (i = 0; i < len; i++) {
804 data = buf[i];
805 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
806 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
807 }
808
809 return (crc);
810 }
811 #endif
812
813 u_int32_t
814 ether_crc32_le(const u_int8_t *buf, size_t len)
815 {
816 return ether_crc32_le_update(0xffffffff, buf, len);
817 }
818
819 u_int32_t
820 ether_crc32_be(const u_int8_t *buf, size_t len)
821 {
822 return ether_crc32_be_update(0xffffffff, buf, len);
823 }
824
825 u_char ether_ipmulticast_min[ETHER_ADDR_LEN] =
826 { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
827 u_char ether_ipmulticast_max[ETHER_ADDR_LEN] =
828 { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
829
830 #ifdef INET6
831 u_char ether_ip6multicast_min[ETHER_ADDR_LEN] =
832 { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
833 u_char ether_ip6multicast_max[ETHER_ADDR_LEN] =
834 { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
835 #endif
836
837 /*
838 * Convert a sockaddr into an Ethernet address or range of Ethernet
839 * addresses.
840 */
841 int
842 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
843 u_int8_t addrhi[ETHER_ADDR_LEN])
844 {
845 struct sockaddr_in *sin;
846 #ifdef INET6
847 struct sockaddr_in6 *sin6;
848 #endif /* INET6 */
849
850 switch (sa->sa_family) {
851
852 case AF_UNSPEC:
853 memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN);
854 memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
855 break;
856
857 case AF_INET:
858 sin = satosin(sa);
859 if (sin->sin_addr.s_addr == INADDR_ANY) {
860 /*
861 * An IP address of INADDR_ANY means listen to
862 * or stop listening to all of the Ethernet
863 * multicast addresses used for IP.
864 * (This is for the sake of IP multicast routers.)
865 */
866 memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN);
867 memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN);
868 } else {
869 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
870 memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
871 }
872 break;
873 #ifdef INET6
874 case AF_INET6:
875 sin6 = satosin6(sa);
876 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
877 /*
878 * An IP6 address of 0 means listen to or stop
879 * listening to all of the Ethernet multicast
880 * address used for IP6.
881 *
882 * (This might not be healthy, given IPv6's reliance on
883 * multicast for things like neighbor discovery.
884 * Perhaps initializing all-nodes, solicited nodes, and
885 * possibly all-routers for this interface afterwards
886 * is not a bad idea.)
887 */
888
889 memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN);
890 memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN);
891 } else {
892 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
893 memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
894 }
895 break;
896 #endif
897
898 default:
899 return (EAFNOSUPPORT);
900 }
901 return (0);
902 }
903
904 /*
905 * Add an Ethernet multicast address or range of addresses to the list for a
906 * given interface.
907 */
908 int
909 ether_addmulti(struct ifreq *ifr, struct arpcom *ac)
910 {
911 struct ether_multi *enm;
912 u_char addrlo[ETHER_ADDR_LEN];
913 u_char addrhi[ETHER_ADDR_LEN];
914 int s = splnet(), error;
915
916 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
917 if (error != 0) {
918 splx(s);
919 return (error);
920 }
921
922 /*
923 * Verify that we have valid Ethernet multicast addresses.
924 */
925 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
926 splx(s);
927 return (EINVAL);
928 }
929 /*
930 * See if the address range is already in the list.
931 */
932 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
933 if (enm != NULL) {
934 /*
935 * Found it; just increment the reference count.
936 */
937 ++enm->enm_refcount;
938 splx(s);
939 return (0);
940 }
941 /*
942 * New address or range; malloc a new multicast record
943 * and link it into the interface's multicast list.
944 */
945 enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
946 if (enm == NULL) {
947 splx(s);
948 return (ENOBUFS);
949 }
950 memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN);
951 memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN);
952 enm->enm_refcount = 1;
953 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
954 ac->ac_multicnt++;
955 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
956 ac->ac_multirangecnt++;
957 splx(s);
958 /*
959 * Return ENETRESET to inform the driver that the list has changed
960 * and its reception filter should be adjusted accordingly.
961 */
962 return (ENETRESET);
963 }
964
965 /*
966 * Delete a multicast address record.
967 */
968 int
969 ether_delmulti(struct ifreq *ifr, struct arpcom *ac)
970 {
971 struct ether_multi *enm;
972 u_char addrlo[ETHER_ADDR_LEN];
973 u_char addrhi[ETHER_ADDR_LEN];
974 int s = splnet(), error;
975
976 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
977 if (error != 0) {
978 splx(s);
979 return (error);
980 }
981
982 /*
983 * Look up the address in our list.
984 */
985 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
986 if (enm == NULL) {
987 splx(s);
988 return (ENXIO);
989 }
990 if (--enm->enm_refcount != 0) {
991 /*
992 * Still some claims to this record.
993 */
994 splx(s);
995 return (0);
996 }
997 /*
998 * No remaining claims to this record; unlink and free it.
999 */
1000 LIST_REMOVE(enm, enm_list);
1001 free(enm, M_IFMADDR, sizeof *enm);
1002 ac->ac_multicnt--;
1003 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
1004 ac->ac_multirangecnt--;
1005 splx(s);
1006 /*
1007 * Return ENETRESET to inform the driver that the list has changed
1008 * and its reception filter should be adjusted accordingly.
1009 */
1010 return (ENETRESET);
1011 }
1012
1013 uint64_t
1014 ether_addr_to_e64(const struct ether_addr *ea)
1015 {
1016 uint64_t e64 = 0;
1017 size_t i;
1018
1019 for (i = 0; i < nitems(ea->ether_addr_octet); i++) {
1020 e64 <<= 8;
1021 e64 |= ea->ether_addr_octet[i];
1022 }
1023
1024 return (e64);
1025 }
1026
1027 void
1028 ether_e64_to_addr(struct ether_addr *ea, uint64_t e64)
1029 {
1030 size_t i = nitems(ea->ether_addr_octet);
1031
1032 do {
1033 ea->ether_addr_octet[--i] = e64;
1034 e64 >>= 8;
1035 } while (i > 0);
1036 }
Cache object: 3e8ba1f8b3a087c8f48f367d0fc8e2d3
|