1 /* $OpenBSD: if_ethersubr.c,v 1.296 2025/01/15 06:15:44 dlg 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 #include <netinet/ip.h>
102 #include <netinet/ip6.h>
103 #include <netinet/tcp.h>
104 #include <netinet/udp.h>
105
106 #if NBPFILTER > 0
107 #include <net/bpf.h>
108 #endif
109
110 #include "vlan.h"
111 #if NVLAN > 0
112 #include <net/if_vlan_var.h>
113 #endif
114
115 #include "carp.h"
116 #if NCARP > 0
117 #include <netinet/ip_carp.h>
118 #endif
119
120 #include "pppoe.h"
121 #if NPPPOE > 0
122 #include <net/if_pppoe.h>
123 #endif
124
125 #include "bpe.h"
126 #if NBPE > 0
127 #include <net/if_bpe.h>
128 #endif
129
130 #ifdef INET6
131 #include <netinet6/in6_var.h>
132 #include <netinet6/nd6.h>
133 #endif
134
135 #ifdef PIPEX
136 #include <net/pipex.h>
137 #endif
138
139 #ifdef MPLS
140 #include <netmpls/mpls.h>
141 #endif /* MPLS */
142
143 #include "af_frame.h"
144 #if NAF_FRAME > 0
145 #include <net/frame.h>
146
147 static struct mbuf *
148 ether_frm_input(struct ifnet *, struct mbuf *, uint64_t, uint16_t);
149 #endif
150
151 /* #define ETHERDEBUG 1 */
152 #ifdef ETHERDEBUG
153 int etherdebug = ETHERDEBUG;
154 #define DNPRINTF(level, fmt, args...) \
155 do { \
156 if (etherdebug >= level) \
157 printf("%s: " fmt "\n", __func__, ## args); \
158 } while (0)
159 #else
160 #define DNPRINTF(level, fmt, args...) \
161 do { } while (0)
162 #endif
163 #define DPRINTF(fmt, args...) DNPRINTF(1, fmt, args)
164
165 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
166 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
167 u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
168 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
169 #define senderr(e) { error = (e); goto bad;}
170
171 int
ether_ioctl(struct ifnet * ifp,struct arpcom * arp,u_long cmd,caddr_t data)172 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data)
173 {
174 struct ifreq *ifr = (struct ifreq *)data;
175 int error = 0;
176
177 switch (cmd) {
178 case SIOCSIFADDR:
179 break;
180
181 case SIOCSIFMTU:
182 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
183 error = EINVAL;
184 else
185 ifp->if_mtu = ifr->ifr_mtu;
186 break;
187
188 case SIOCADDMULTI:
189 case SIOCDELMULTI:
190 if (ifp->if_flags & IFF_MULTICAST) {
191 error = (cmd == SIOCADDMULTI) ?
192 ether_addmulti(ifr, arp) :
193 ether_delmulti(ifr, arp);
194 } else
195 error = ENOTTY;
196 break;
197
198 default:
199 error = ENOTTY;
200 }
201
202 return (error);
203 }
204
205
206 void
ether_rtrequest(struct ifnet * ifp,int req,struct rtentry * rt)207 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
208 {
209 if (rt == NULL)
210 return;
211
212 switch (rt_key(rt)->sa_family) {
213 case AF_INET:
214 arp_rtrequest(ifp, req, rt);
215 break;
216 #ifdef INET6
217 case AF_INET6:
218 nd6_rtrequest(ifp, req, rt);
219 break;
220 #endif
221 default:
222 break;
223 }
224 }
225
226 int
ether_resolve(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt,struct ether_header * eh)227 ether_resolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
228 struct rtentry *rt, struct ether_header *eh)
229 {
230 struct arpcom *ac = (struct arpcom *)ifp;
231 sa_family_t af = dst->sa_family;
232 int error = 0;
233
234 if (!ISSET(ifp->if_flags, IFF_RUNNING))
235 senderr(ENETDOWN);
236
237 KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
238 af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
239
240 #ifdef DIAGNOSTIC
241 if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
242 printf("%s: trying to send packet on wrong domain. "
243 "if %d vs. mbuf %d\n", ifp->if_xname,
244 ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
245 }
246 #endif
247
248 switch (af) {
249 case AF_INET:
250 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
251 if (error)
252 return (error);
253 eh->ether_type = htons(ETHERTYPE_IP);
254
255 /*
256 * If broadcasting on a simplex interface, loopback a copy.
257 * The checksum must be calculated in software. Keep the
258 * condition in sync with in_ifcap_cksum().
259 */
260 if (ISSET(m->m_flags, M_BCAST) &&
261 ISSET(ifp->if_flags, IFF_SIMPLEX) &&
262 !m->m_pkthdr.pf.routed) {
263 struct mbuf *mcopy;
264
265 /* XXX Should we input an unencrypted IPsec packet? */
266 mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
267 if (mcopy != NULL)
268 if_input_local(ifp, mcopy, af);
269 }
270 break;
271 #ifdef INET6
272 case AF_INET6:
273 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
274 if (error)
275 return (error);
276 eh->ether_type = htons(ETHERTYPE_IPV6);
277 break;
278 #endif
279 #ifdef MPLS
280 case AF_MPLS:
281 if (rt == NULL)
282 senderr(EHOSTUNREACH);
283
284 if (!ISSET(ifp->if_xflags, IFXF_MPLS))
285 senderr(ENETUNREACH);
286
287 dst = ISSET(rt->rt_flags, RTF_GATEWAY) ?
288 rt->rt_gateway : rt_key(rt);
289
290 switch (dst->sa_family) {
291 case AF_LINK:
292 if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost))
293 senderr(EHOSTUNREACH);
294 memcpy(eh->ether_dhost, LLADDR(satosdl(dst)),
295 sizeof(eh->ether_dhost));
296 break;
297 #ifdef INET6
298 case AF_INET6:
299 error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
300 if (error)
301 return (error);
302 break;
303 #endif
304 case AF_INET:
305 error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
306 if (error)
307 return (error);
308 break;
309 default:
310 senderr(EHOSTUNREACH);
311 }
312 /* XXX handling for simplex devices in case of M/BCAST ?? */
313 if (m->m_flags & (M_BCAST | M_MCAST))
314 eh->ether_type = htons(ETHERTYPE_MPLS_MCAST);
315 else
316 eh->ether_type = htons(ETHERTYPE_MPLS);
317 break;
318 #endif /* MPLS */
319 case pseudo_AF_HDRCMPLT:
320 /* take the whole header from the sa */
321 memcpy(eh, dst->sa_data, sizeof(*eh));
322 return (0);
323
324 case AF_UNSPEC:
325 /* take the dst and type from the sa, but get src below */
326 memcpy(eh, dst->sa_data, sizeof(*eh));
327 break;
328
329 default:
330 printf("%s: can't handle af%d\n", ifp->if_xname, af);
331 senderr(EAFNOSUPPORT);
332 }
333
334 memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost));
335
336 return (0);
337
338 bad:
339 m_freem(m);
340 return (error);
341 }
342
343 struct mbuf*
ether_encap(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt,int * errorp)344 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
345 struct rtentry *rt, int *errorp)
346 {
347 struct ether_header eh;
348 int error;
349
350 error = ether_resolve(ifp, m, dst, rt, &eh);
351 switch (error) {
352 case 0:
353 break;
354 case EAGAIN:
355 error = 0;
356 default:
357 *errorp = error;
358 return (NULL);
359 }
360
361 m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT);
362 if (m == NULL) {
363 *errorp = ENOBUFS;
364 return (NULL);
365 }
366
367 m_adj(m, ETHER_ALIGN);
368 memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh));
369
370 return (m);
371 }
372
373 int
ether_output(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt)374 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
375 struct rtentry *rt)
376 {
377 int error;
378
379 m = ether_encap(ifp, m, dst, rt, &error);
380 if (m == NULL)
381 return (error);
382
383 return (if_enqueue(ifp, m));
384 }
385
386 /*
387 * Process a received Ethernet packet.
388 *
389 * Ethernet input has several "phases" of filtering packets to
390 * support virtual/pseudo interfaces before actual layer 3 protocol
391 * handling.
392 *
393 * First phase:
394 *
395 * The first phase supports drivers that aggregate multiple Ethernet
396 * ports into a single logical interface, ie, aggr(4) and trunk(4).
397 * These drivers intercept packets by swapping out the if_input handler
398 * on the "port" interfaces to steal the packets before they get here
399 * to ether_input().
400 */
401 void
ether_input(struct ifnet * ifp,struct mbuf * m)402 ether_input(struct ifnet *ifp, struct mbuf *m)
403 {
404 struct ether_header *eh;
405 void (*input)(struct ifnet *, struct mbuf *);
406 u_int16_t etype;
407 struct arpcom *ac;
408 const struct ether_brport *eb;
409 unsigned int sdelim = 0;
410 uint64_t dst, self;
411
412 /* Drop short frames */
413 if (m->m_len < ETHER_HDR_LEN)
414 goto dropanyway;
415
416 /*
417 * Second phase: service delimited packet filtering.
418 *
419 * Let vlan(4) and svlan(4) look at "service delimited"
420 * packets. If a virtual interface does not exist to take
421 * those packets, they're returned to ether_input() so a
422 * bridge can have a go at forwarding them.
423 */
424
425 eh = mtod(m, struct ether_header *);
426 dst = ether_addr_to_e64((struct ether_addr *)eh->ether_dhost);
427 etype = ntohs(eh->ether_type);
428
429 if (ISSET(m->m_flags, M_VLANTAG) ||
430 etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ) {
431 #if NVLAN > 0
432 m = vlan_input(ifp, m, &sdelim);
433 if (m == NULL)
434 return;
435 #else
436 sdelim = 1;
437 #endif
438 }
439
440 /*
441 * Third phase: bridge processing.
442 *
443 * Give the packet to a bridge interface, ie, bridge(4),
444 * veb(4), or tpmr(4), if it is configured. A bridge
445 * may take the packet and forward it to another port, or it
446 * may return it here to ether_input() to support local
447 * delivery to this port.
448 */
449
450 ac = (struct arpcom *)ifp;
451
452 smr_read_enter();
453 eb = SMR_PTR_GET(&ac->ac_brport);
454 if (eb != NULL)
455 eb->eb_port_take(eb->eb_port);
456 smr_read_leave();
457 if (eb != NULL) {
458 m = (*eb->eb_input)(ifp, m, dst, eb->eb_port);
459 eb->eb_port_rele(eb->eb_port);
460 if (m == NULL) {
461 return;
462 }
463 }
464
465 /*
466 * Fourth phase: drop service delimited packets.
467 *
468 * If the packet has a tag, and a bridge didn't want it,
469 * it's not for this port.
470 */
471
472 if (sdelim)
473 goto dropanyway;
474
475 /*
476 * Fifth phase: destination address check.
477 *
478 * Is the packet specifically addressed to this port?
479 */
480
481 eh = mtod(m, struct ether_header *);
482 self = ether_addr_to_e64((struct ether_addr *)ac->ac_enaddr);
483 if (dst != self) {
484 #if NCARP > 0
485 /*
486 * If it's not for this port, it could be for carp(4).
487 */
488 if (ifp->if_type != IFT_CARP &&
489 !SRPL_EMPTY_LOCKED(&ifp->if_carp)) {
490 m = carp_input(ifp, m, dst);
491 if (m == NULL)
492 return;
493
494 eh = mtod(m, struct ether_header *);
495 }
496 #endif
497
498 /*
499 * If not, it must be multicast or broadcast to go further.
500 */
501 if (!ETH64_IS_MULTICAST(dst))
502 goto dropanyway;
503
504 /*
505 * If this is not a simplex interface, drop the packet
506 * if it came from us.
507 */
508 if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
509 uint64_t src = ether_addr_to_e64(
510 (struct ether_addr *)eh->ether_shost);
511 if (self == src)
512 goto dropanyway;
513 }
514
515 SET(m->m_flags, ETH64_IS_BROADCAST(dst) ? M_BCAST : M_MCAST);
516 ifp->if_imcasts++;
517 }
518
519 /*
520 * Sixth phase: protocol demux.
521 *
522 * At this point it is known that the packet is destined
523 * for layer 3 protocol handling on the local port.
524 */
525 etype = ntohs(eh->ether_type);
526
527 switch (etype) {
528 case ETHERTYPE_IP:
529 input = ipv4_input;
530 break;
531
532 case ETHERTYPE_ARP:
533 if (ifp->if_flags & IFF_NOARP)
534 goto dropanyway;
535 input = arpinput;
536 break;
537
538 case ETHERTYPE_REVARP:
539 if (ifp->if_flags & IFF_NOARP)
540 goto dropanyway;
541 input = revarpinput;
542 break;
543
544 #ifdef INET6
545 /*
546 * Schedule IPv6 software interrupt for incoming IPv6 packet.
547 */
548 case ETHERTYPE_IPV6:
549 input = ipv6_input;
550 break;
551 #endif /* INET6 */
552 #if NPPPOE > 0 || defined(PIPEX)
553 case ETHERTYPE_PPPOEDISC:
554 case ETHERTYPE_PPPOE:
555 if (m->m_flags & (M_MCAST | M_BCAST))
556 goto dropanyway;
557 #ifdef PIPEX
558 if (pipex_enable) {
559 struct pipex_session *session;
560
561 if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
562 pipex_pppoe_input(m, session);
563 pipex_rele_session(session);
564 return;
565 }
566 }
567 #endif
568 if (etype == ETHERTYPE_PPPOEDISC) {
569 if (mq_enqueue(&pppoediscinq, m) == 0)
570 schednetisr(NETISR_PPPOE);
571 } else {
572 m = pppoe_vinput(ifp, m);
573 if (m != NULL && mq_enqueue(&pppoeinq, m) == 0)
574 schednetisr(NETISR_PPPOE);
575 }
576 return;
577 #endif
578 #ifdef MPLS
579 case ETHERTYPE_MPLS:
580 case ETHERTYPE_MPLS_MCAST:
581 input = mpls_input;
582 break;
583 #endif
584 #if NBPE > 0
585 case ETHERTYPE_PBB:
586 bpe_input(ifp, m);
587 return;
588 #endif
589 default:
590 #if NAF_FRAME > 0
591 m = ether_frm_input(ifp, m, dst, etype);
592 #endif
593 goto dropanyway;
594 }
595
596 m_adj(m, sizeof(*eh));
597 (*input)(ifp, m);
598 return;
599 dropanyway:
600 m_freem(m);
601 return;
602 }
603
604 int
ether_brport_isset(struct ifnet * ifp)605 ether_brport_isset(struct ifnet *ifp)
606 {
607 struct arpcom *ac = (struct arpcom *)ifp;
608
609 KERNEL_ASSERT_LOCKED();
610 if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL)
611 return (EBUSY);
612
613 return (0);
614 }
615
616 void
ether_brport_set(struct ifnet * ifp,const struct ether_brport * eb)617 ether_brport_set(struct ifnet *ifp, const struct ether_brport *eb)
618 {
619 struct arpcom *ac = (struct arpcom *)ifp;
620
621 KERNEL_ASSERT_LOCKED();
622 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL,
623 "%s setting an already set brport", ifp->if_xname);
624
625 SMR_PTR_SET_LOCKED(&ac->ac_brport, eb);
626 }
627
628 void
ether_brport_clr(struct ifnet * ifp)629 ether_brport_clr(struct ifnet *ifp)
630 {
631 struct arpcom *ac = (struct arpcom *)ifp;
632
633 KERNEL_ASSERT_LOCKED();
634 KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL,
635 "%s clearing an already clear brport", ifp->if_xname);
636
637 SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL);
638 }
639
640 const struct ether_brport *
ether_brport_get(struct ifnet * ifp)641 ether_brport_get(struct ifnet *ifp)
642 {
643 struct arpcom *ac = (struct arpcom *)ifp;
644 SMR_ASSERT_CRITICAL();
645 return (SMR_PTR_GET(&ac->ac_brport));
646 }
647
648 const struct ether_brport *
ether_brport_get_locked(struct ifnet * ifp)649 ether_brport_get_locked(struct ifnet *ifp)
650 {
651 struct arpcom *ac = (struct arpcom *)ifp;
652 KERNEL_ASSERT_LOCKED();
653 return (SMR_PTR_GET_LOCKED(&ac->ac_brport));
654 }
655
656 /*
657 * Convert Ethernet address to printable (loggable) representation.
658 */
659 static char digits[] = "0123456789abcdef";
660 char *
ether_sprintf(u_char * ap)661 ether_sprintf(u_char *ap)
662 {
663 int i;
664 static char etherbuf[ETHER_ADDR_LEN * 3];
665 char *cp = etherbuf;
666
667 for (i = 0; i < ETHER_ADDR_LEN; i++) {
668 *cp++ = digits[*ap >> 4];
669 *cp++ = digits[*ap++ & 0xf];
670 *cp++ = ':';
671 }
672 *--cp = 0;
673 return (etherbuf);
674 }
675
676 /*
677 * Generate a (hopefully) acceptable MAC address, if asked.
678 */
679 void
ether_fakeaddr(struct ifnet * ifp)680 ether_fakeaddr(struct ifnet *ifp)
681 {
682 static int unit;
683 int rng = arc4random();
684
685 /* Non-multicast; locally administered address */
686 ((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
687 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
688 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
689 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
690 ((struct arpcom *)ifp)->ac_enaddr[4] = rng;
691 ((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
692 }
693
694 /*
695 * Perform common duties while attaching to interface list
696 */
697 void
ether_ifattach(struct ifnet * ifp)698 ether_ifattach(struct ifnet *ifp)
699 {
700 struct arpcom *ac = (struct arpcom *)ifp;
701
702 /*
703 * Any interface which provides a MAC address which is obviously
704 * invalid gets whacked, so that users will notice.
705 */
706 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
707 ether_fakeaddr(ifp);
708
709 ifp->if_type = IFT_ETHER;
710 ifp->if_addrlen = ETHER_ADDR_LEN;
711 ifp->if_hdrlen = ETHER_HDR_LEN;
712 ifp->if_mtu = ETHERMTU;
713 ifp->if_input = ether_input;
714 if (ifp->if_output == NULL)
715 ifp->if_output = ether_output;
716 ifp->if_rtrequest = ether_rtrequest;
717
718 if (ifp->if_hardmtu == 0)
719 ifp->if_hardmtu = ETHERMTU;
720
721 if_alloc_sadl(ifp);
722 memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen);
723 LIST_INIT(&ac->ac_multiaddrs);
724 #if NBPFILTER > 0
725 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
726 #endif
727 }
728
729 void
ether_ifdetach(struct ifnet * ifp)730 ether_ifdetach(struct ifnet *ifp)
731 {
732 struct arpcom *ac = (struct arpcom *)ifp;
733 struct ether_multi *enm;
734
735 /* Undo pseudo-driver changes. */
736 if_deactivate(ifp);
737
738 while (!LIST_EMPTY(&ac->ac_multiaddrs)) {
739 enm = LIST_FIRST(&ac->ac_multiaddrs);
740 LIST_REMOVE(enm, enm_list);
741 free(enm, M_IFMADDR, sizeof *enm);
742 }
743 }
744
745 #if 0
746 /*
747 * This is for reference. We have table-driven versions of the
748 * crc32 generators, which are faster than the double-loop.
749 */
750 u_int32_t __pure
751 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
752 {
753 u_int32_t c, carry;
754 size_t i, j;
755
756 for (i = 0; i < len; i++) {
757 c = buf[i];
758 for (j = 0; j < 8; j++) {
759 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
760 crc >>= 1;
761 c >>= 1;
762 if (carry)
763 crc = (crc ^ ETHER_CRC_POLY_LE);
764 }
765 }
766
767 return (crc);
768 }
769
770 u_int32_t __pure
771 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
772 {
773 u_int32_t c, carry;
774 size_t i, j;
775
776 for (i = 0; i < len; i++) {
777 c = buf[i];
778 for (j = 0; j < 8; j++) {
779 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
780 crc <<= 1;
781 c >>= 1;
782 if (carry)
783 crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
784 }
785 }
786
787 return (crc);
788 }
789 #else
790 u_int32_t __pure
ether_crc32_le_update(u_int32_t crc,const u_int8_t * buf,size_t len)791 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len)
792 {
793 static const u_int32_t crctab[] = {
794 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
795 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
796 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
797 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
798 };
799 size_t i;
800
801 for (i = 0; i < len; i++) {
802 crc ^= buf[i];
803 crc = (crc >> 4) ^ crctab[crc & 0xf];
804 crc = (crc >> 4) ^ crctab[crc & 0xf];
805 }
806
807 return (crc);
808 }
809
810 u_int32_t __pure
ether_crc32_be_update(u_int32_t crc,const u_int8_t * buf,size_t len)811 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len)
812 {
813 static const u_int8_t rev[] = {
814 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
815 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
816 };
817 static const u_int32_t crctab[] = {
818 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
819 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
820 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
821 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
822 };
823 size_t i;
824 u_int8_t data;
825
826 for (i = 0; i < len; i++) {
827 data = buf[i];
828 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
829 crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
830 }
831
832 return (crc);
833 }
834 #endif
835
836 u_int32_t
ether_crc32_le(const u_int8_t * buf,size_t len)837 ether_crc32_le(const u_int8_t *buf, size_t len)
838 {
839 return ether_crc32_le_update(0xffffffff, buf, len);
840 }
841
842 u_int32_t
ether_crc32_be(const u_int8_t * buf,size_t len)843 ether_crc32_be(const u_int8_t *buf, size_t len)
844 {
845 return ether_crc32_be_update(0xffffffff, buf, len);
846 }
847
848 u_char ether_ipmulticast_min[ETHER_ADDR_LEN] =
849 { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
850 u_char ether_ipmulticast_max[ETHER_ADDR_LEN] =
851 { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
852
853 #ifdef INET6
854 u_char ether_ip6multicast_min[ETHER_ADDR_LEN] =
855 { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
856 u_char ether_ip6multicast_max[ETHER_ADDR_LEN] =
857 { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
858 #endif
859
860 /*
861 * Convert a sockaddr into an Ethernet address or range of Ethernet
862 * addresses.
863 */
864 int
ether_multiaddr(struct sockaddr * sa,u_int8_t addrlo[ETHER_ADDR_LEN],u_int8_t addrhi[ETHER_ADDR_LEN])865 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
866 u_int8_t addrhi[ETHER_ADDR_LEN])
867 {
868 struct sockaddr_in *sin;
869 #ifdef INET6
870 struct sockaddr_in6 *sin6;
871 #endif /* INET6 */
872
873 switch (sa->sa_family) {
874
875 case AF_UNSPEC:
876 memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN);
877 memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
878 break;
879
880 case AF_INET:
881 sin = satosin(sa);
882 if (sin->sin_addr.s_addr == INADDR_ANY) {
883 /*
884 * An IP address of INADDR_ANY means listen to
885 * or stop listening to all of the Ethernet
886 * multicast addresses used for IP.
887 * (This is for the sake of IP multicast routers.)
888 */
889 memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN);
890 memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN);
891 } else {
892 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
893 memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
894 }
895 break;
896 #ifdef INET6
897 case AF_INET6:
898 sin6 = satosin6(sa);
899 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
900 /*
901 * An IP6 address of 0 means listen to or stop
902 * listening to all of the Ethernet multicast
903 * address used for IP6.
904 *
905 * (This might not be healthy, given IPv6's reliance on
906 * multicast for things like neighbor discovery.
907 * Perhaps initializing all-nodes, solicited nodes, and
908 * possibly all-routers for this interface afterwards
909 * is not a bad idea.)
910 */
911
912 memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN);
913 memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN);
914 } else {
915 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
916 memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
917 }
918 break;
919 #endif
920
921 default:
922 return (EAFNOSUPPORT);
923 }
924 return (0);
925 }
926
927 /*
928 * Add an Ethernet multicast address or range of addresses to the list for a
929 * given interface.
930 */
931 int
ether_addmulti(struct ifreq * ifr,struct arpcom * ac)932 ether_addmulti(struct ifreq *ifr, struct arpcom *ac)
933 {
934 struct ether_multi *enm;
935 u_char addrlo[ETHER_ADDR_LEN];
936 u_char addrhi[ETHER_ADDR_LEN];
937 int s = splnet(), error;
938
939 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
940 if (error != 0) {
941 splx(s);
942 return (error);
943 }
944
945 /*
946 * Verify that we have valid Ethernet multicast addresses.
947 */
948 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
949 splx(s);
950 return (EINVAL);
951 }
952 /*
953 * See if the address range is already in the list.
954 */
955 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
956 if (enm != NULL) {
957 /*
958 * Found it; just increment the reference count.
959 */
960 refcnt_take(&enm->enm_refcnt);
961 splx(s);
962 return (0);
963 }
964 /*
965 * New address or range; malloc a new multicast record
966 * and link it into the interface's multicast list.
967 */
968 enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
969 if (enm == NULL) {
970 splx(s);
971 return (ENOBUFS);
972 }
973 memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN);
974 memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN);
975 refcnt_init_trace(&enm->enm_refcnt, DT_REFCNT_IDX_ETHMULTI);
976 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
977 ac->ac_multicnt++;
978 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
979 ac->ac_multirangecnt++;
980 splx(s);
981 /*
982 * Return ENETRESET to inform the driver that the list has changed
983 * and its reception filter should be adjusted accordingly.
984 */
985 return (ENETRESET);
986 }
987
988 /*
989 * Delete a multicast address record.
990 */
991 int
ether_delmulti(struct ifreq * ifr,struct arpcom * ac)992 ether_delmulti(struct ifreq *ifr, struct arpcom *ac)
993 {
994 struct ether_multi *enm;
995 u_char addrlo[ETHER_ADDR_LEN];
996 u_char addrhi[ETHER_ADDR_LEN];
997 int s = splnet(), error;
998
999 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1000 if (error != 0) {
1001 splx(s);
1002 return (error);
1003 }
1004
1005 /*
1006 * Look up the address in our list.
1007 */
1008 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1009 if (enm == NULL) {
1010 splx(s);
1011 return (ENXIO);
1012 }
1013 if (refcnt_rele(&enm->enm_refcnt) == 0) {
1014 /*
1015 * Still some claims to this record.
1016 */
1017 splx(s);
1018 return (0);
1019 }
1020 /*
1021 * No remaining claims to this record; unlink and free it.
1022 */
1023 LIST_REMOVE(enm, enm_list);
1024 free(enm, M_IFMADDR, sizeof *enm);
1025 ac->ac_multicnt--;
1026 if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
1027 ac->ac_multirangecnt--;
1028 splx(s);
1029 /*
1030 * Return ENETRESET to inform the driver that the list has changed
1031 * and its reception filter should be adjusted accordingly.
1032 */
1033 return (ENETRESET);
1034 }
1035
1036 uint64_t
ether_addr_to_e64(const struct ether_addr * ea)1037 ether_addr_to_e64(const struct ether_addr *ea)
1038 {
1039 uint64_t e64 = 0;
1040 size_t i;
1041
1042 for (i = 0; i < nitems(ea->ether_addr_octet); i++) {
1043 e64 <<= 8;
1044 e64 |= ea->ether_addr_octet[i];
1045 }
1046
1047 return (e64);
1048 }
1049
1050 void
ether_e64_to_addr(struct ether_addr * ea,uint64_t e64)1051 ether_e64_to_addr(struct ether_addr *ea, uint64_t e64)
1052 {
1053 size_t i = nitems(ea->ether_addr_octet);
1054
1055 do {
1056 ea->ether_addr_octet[--i] = e64;
1057 e64 >>= 8;
1058 } while (i > 0);
1059 }
1060
1061 /* Parse different TCP/IP protocol headers for a quick view inside an mbuf. */
1062 void
ether_extract_headers(struct mbuf * m0,struct ether_extracted * ext)1063 ether_extract_headers(struct mbuf *m0, struct ether_extracted *ext)
1064 {
1065 struct mbuf *m;
1066 size_t hlen, iplen;
1067 int hoff;
1068 uint8_t ipproto;
1069 uint16_t ether_type;
1070 /* gcc 4.2.1 on sparc64 may create 32 bit loads on unaligned mbuf */
1071 union {
1072 u_char hc_data;
1073 #if _BYTE_ORDER == _LITTLE_ENDIAN
1074 struct {
1075 u_int hl:4, /* header length */
1076 v:4; /* version */
1077 } hc_ip;
1078 struct {
1079 u_int x2:4, /* (unused) */
1080 off:4; /* data offset */
1081 } hc_th;
1082 #endif
1083 #if _BYTE_ORDER == _BIG_ENDIAN
1084 struct {
1085 u_int v:4, /* version */
1086 hl:4; /* header length */
1087 } hc_ip;
1088 struct {
1089 u_int off:4, /* data offset */
1090 x2:4; /* (unused) */
1091 } hc_th;
1092 #endif
1093 } hdrcpy;
1094
1095 /* Return NULL if header was not recognized. */
1096 memset(ext, 0, sizeof(*ext));
1097
1098 KASSERT(ISSET(m0->m_flags, M_PKTHDR));
1099 ext->paylen = m0->m_pkthdr.len;
1100
1101 if (m0->m_len < sizeof(*ext->eh)) {
1102 DPRINTF("m_len %d, eh %zu", m0->m_len, sizeof(*ext->eh));
1103 return;
1104 }
1105 ext->eh = mtod(m0, struct ether_header *);
1106 ether_type = ntohs(ext->eh->ether_type);
1107 hlen = sizeof(*ext->eh);
1108 if (ext->paylen < hlen) {
1109 DPRINTF("paylen %u, ehlen %zu", ext->paylen, hlen);
1110 ext->eh = NULL;
1111 return;
1112 }
1113 ext->paylen -= hlen;
1114
1115 #if NVLAN > 0
1116 if (ether_type == ETHERTYPE_VLAN) {
1117 if (m0->m_len < sizeof(*ext->evh)) {
1118 DPRINTF("m_len %d, evh %zu",
1119 m0->m_len, sizeof(*ext->evh));
1120 return;
1121 }
1122 ext->evh = mtod(m0, struct ether_vlan_header *);
1123 ether_type = ntohs(ext->evh->evl_proto);
1124 hlen = sizeof(*ext->evh);
1125 if (sizeof(*ext->eh) + ext->paylen < hlen) {
1126 DPRINTF("paylen %zu, evhlen %zu",
1127 sizeof(*ext->eh) + ext->paylen, hlen);
1128 ext->evh = NULL;
1129 return;
1130 }
1131 ext->paylen = sizeof(*ext->eh) + ext->paylen - hlen;
1132 }
1133 #endif
1134
1135 switch (ether_type) {
1136 case ETHERTYPE_IP:
1137 m = m_getptr(m0, hlen, &hoff);
1138 if (m == NULL || m->m_len - hoff < sizeof(*ext->ip4)) {
1139 DPRINTF("m_len %d, hoff %d, ip4 %zu",
1140 m ? m->m_len : -1, hoff, sizeof(*ext->ip4));
1141 return;
1142 }
1143 ext->ip4 = (struct ip *)(mtod(m, caddr_t) + hoff);
1144
1145 memcpy(&hdrcpy.hc_data, ext->ip4, 1);
1146 hlen = hdrcpy.hc_ip.hl << 2;
1147 if (m->m_len - hoff < hlen) {
1148 DPRINTF("m_len %d, hoff %d, iphl %zu",
1149 m ? m->m_len : -1, hoff, hlen);
1150 ext->ip4 = NULL;
1151 return;
1152 }
1153 if (ext->paylen < hlen) {
1154 DPRINTF("paylen %u, ip4hlen %zu", ext->paylen, hlen);
1155 ext->ip4 = NULL;
1156 return;
1157 }
1158 iplen = ntohs(ext->ip4->ip_len);
1159 if (ext->paylen < iplen) {
1160 DPRINTF("paylen %u, ip4len %zu", ext->paylen, iplen);
1161 ext->ip4 = NULL;
1162 return;
1163 }
1164 if (iplen < hlen) {
1165 DPRINTF("ip4len %zu, ip4hlen %zu", iplen, hlen);
1166 ext->ip4 = NULL;
1167 return;
1168 }
1169 ext->iplen = iplen;
1170 ext->iphlen = hlen;
1171 ext->paylen -= hlen;
1172 ipproto = ext->ip4->ip_p;
1173
1174 if (ISSET(ntohs(ext->ip4->ip_off), IP_MF|IP_OFFMASK))
1175 return;
1176 break;
1177 #ifdef INET6
1178 case ETHERTYPE_IPV6:
1179 m = m_getptr(m0, hlen, &hoff);
1180 if (m == NULL || m->m_len - hoff < sizeof(*ext->ip6)) {
1181 DPRINTF("m_len %d, hoff %d, ip6 %zu",
1182 m ? m->m_len : -1, hoff, sizeof(*ext->ip6));
1183 return;
1184 }
1185 ext->ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff);
1186
1187 hlen = sizeof(*ext->ip6);
1188 if (ext->paylen < hlen) {
1189 DPRINTF("paylen %u, ip6hlen %zu", ext->paylen, hlen);
1190 ext->ip6 = NULL;
1191 return;
1192 }
1193 iplen = hlen + ntohs(ext->ip6->ip6_plen);
1194 if (ext->paylen < iplen) {
1195 DPRINTF("paylen %u, ip6len %zu", ext->paylen, iplen);
1196 ext->ip6 = NULL;
1197 return;
1198 }
1199 ext->iplen = iplen;
1200 ext->iphlen = hlen;
1201 ext->paylen -= hlen;
1202 ipproto = ext->ip6->ip6_nxt;
1203 break;
1204 #endif
1205 default:
1206 return;
1207 }
1208
1209 switch (ipproto) {
1210 case IPPROTO_TCP:
1211 m = m_getptr(m, hoff + hlen, &hoff);
1212 if (m == NULL || m->m_len - hoff < sizeof(*ext->tcp)) {
1213 DPRINTF("m_len %d, hoff %d, tcp %zu",
1214 m ? m->m_len : -1, hoff, sizeof(*ext->tcp));
1215 return;
1216 }
1217 ext->tcp = (struct tcphdr *)(mtod(m, caddr_t) + hoff);
1218
1219 memcpy(&hdrcpy.hc_data, &ext->tcp->th_flags - 1, 1);
1220 hlen = hdrcpy.hc_th.off << 2;
1221 if (m->m_len - hoff < hlen) {
1222 DPRINTF("m_len %d, hoff %d, thoff %zu",
1223 m ? m->m_len : -1, hoff, hlen);
1224 ext->tcp = NULL;
1225 return;
1226 }
1227 if (ext->iplen - ext->iphlen < hlen) {
1228 DPRINTF("iplen %u, iphlen %u, tcphlen %zu",
1229 ext->iplen, ext->iphlen, hlen);
1230 ext->tcp = NULL;
1231 return;
1232 }
1233 ext->tcphlen = hlen;
1234 ext->paylen -= hlen;
1235 break;
1236
1237 case IPPROTO_UDP:
1238 m = m_getptr(m, hoff + hlen, &hoff);
1239 if (m == NULL || m->m_len - hoff < sizeof(*ext->udp)) {
1240 DPRINTF("m_len %d, hoff %d, tcp %zu",
1241 m ? m->m_len : -1, hoff, sizeof(*ext->tcp));
1242 return;
1243 }
1244 ext->udp = (struct udphdr *)(mtod(m, caddr_t) + hoff);
1245
1246 hlen = sizeof(*ext->udp);
1247 if (ext->iplen - ext->iphlen < hlen) {
1248 DPRINTF("iplen %u, iphlen %u, udphlen %zu",
1249 ext->iplen, ext->iphlen, hlen);
1250 ext->udp = NULL;
1251 return;
1252 }
1253 break;
1254 }
1255
1256 DNPRINTF(2, "%s%s%s%s%s%s ip %u, iph %u, tcph %u, payl %u",
1257 ext->eh ? "eh," : "", ext->evh ? "evh," : "",
1258 ext->ip4 ? "ip4," : "", ext->ip6 ? "ip6," : "",
1259 ext->tcp ? "tcp," : "", ext->udp ? "udp," : "",
1260 ext->iplen, ext->iphlen, ext->tcphlen, ext->paylen);
1261 }
1262
1263 #if NAF_FRAME > 0
1264
1265 #include <sys/socket.h>
1266 #include <sys/protosw.h>
1267 #include <sys/domain.h>
1268
1269 /*
1270 * lock order is:
1271 *
1272 * - socket lock
1273 * - ether_pcb_lock
1274 * - socket buffer mtx
1275 */
1276
1277 struct ether_pcb;
1278
1279 struct ether_pcb_group {
1280 TAILQ_ENTRY(ether_pcb_group)
1281 epg_entry;
1282 struct ether_pcb *
1283 epg_pcb;
1284 unsigned int epg_ifindex;
1285 uint8_t epg_addr[ETHER_ADDR_LEN];
1286 struct task epg_hook;
1287 };
1288
1289 TAILQ_HEAD(ether_pcb_groups, ether_pcb_group);
1290
1291 struct ether_pcb {
1292 TAILQ_ENTRY(ether_pcb)
1293 ep_entry;
1294 struct rwlock ep_lock;
1295
1296 struct socket *ep_socket;
1297
1298 uint64_t ep_laddr;
1299 uint64_t ep_faddr;
1300 unsigned int ep_ifindex;
1301 uint16_t ep_etype;
1302
1303 uint64_t ep_options;
1304 int ep_txprio;
1305
1306 struct ether_pcb_groups
1307 ep_groups;
1308 };
1309
1310 TAILQ_HEAD(ether_pcb_list, ether_pcb);
1311
1312 static int ether_frm_attach(struct socket *, int, int);
1313 static int ether_frm_detach(struct socket *);
1314 static int ether_frm_bind(struct socket *, struct mbuf *, struct proc *);
1315 static int ether_frm_connect(struct socket *, struct mbuf *);
1316 static int ether_frm_disconnect(struct socket *);
1317 static int ether_frm_shutdown(struct socket *);
1318 static int ether_frm_send(struct socket *, struct mbuf *, struct mbuf *,
1319 struct mbuf *);
1320 static int ether_frm_sockaddr(struct socket *, struct mbuf *);
1321 static int ether_frm_peeraddr(struct socket *, struct mbuf *);
1322
1323 const struct pr_usrreqs ether_frm_usrreqs = {
1324 .pru_attach = ether_frm_attach,
1325 .pru_detach = ether_frm_detach,
1326 .pru_bind = ether_frm_bind,
1327 .pru_connect = ether_frm_connect,
1328 .pru_disconnect = ether_frm_disconnect,
1329 .pru_shutdown = ether_frm_shutdown,
1330 .pru_send = ether_frm_send,
1331 .pru_sockaddr = ether_frm_sockaddr,
1332 .pru_peeraddr = ether_frm_peeraddr,
1333 };
1334
1335 static struct rwlock ether_pcb_lock = RWLOCK_INITIALIZER("ethsocks");
1336 static struct ether_pcb_list ether_pcbs = TAILQ_HEAD_INITIALIZER(ether_pcbs);
1337
1338 static int
ether_frm_valid_etype(uint16_t etype)1339 ether_frm_valid_etype(uint16_t etype)
1340 {
1341 switch (etype) {
1342 case ETHERTYPE_LLDP:
1343 case ETHERTYPE_EAPOL:
1344 return (1);
1345 }
1346
1347 return (0);
1348 }
1349
1350 static int
ether_frm_nam2sfrm(struct sockaddr_frame ** sfrmp,const struct mbuf * nam)1351 ether_frm_nam2sfrm(struct sockaddr_frame **sfrmp, const struct mbuf *nam)
1352 {
1353 struct sockaddr_frame *sfrm;
1354
1355 if (nam->m_len != sizeof(*sfrm))
1356 return (EINVAL);
1357
1358 sfrm = mtod(nam, struct sockaddr_frame *);
1359 if (sfrm->sfrm_family != AF_FRAME)
1360 return (EAFNOSUPPORT);
1361 *sfrmp = sfrm;
1362 return (0);
1363 }
1364
1365 static int
ether_frm_ifp(struct ifnet ** ifpp,const struct sockaddr_frame * sfrm)1366 ether_frm_ifp(struct ifnet **ifpp, const struct sockaddr_frame *sfrm)
1367 {
1368 struct ifnet *ifp;
1369
1370 if (sfrm->sfrm_ifindex != 0)
1371 ifp = if_get(sfrm->sfrm_ifindex);
1372 else if (sfrm->sfrm_ifname[0] != '\0') {
1373 KERNEL_LOCK();
1374 ifp = if_unit(sfrm->sfrm_ifname);
1375 KERNEL_UNLOCK();
1376 } else {
1377 *ifpp = NULL;
1378 return (0);
1379 }
1380
1381 if (ifp == NULL)
1382 return (ENXIO);
1383
1384 if (ifp->if_type != IFT_ETHER) {
1385 if_put(ifp);
1386 return (EAFNOSUPPORT);
1387 }
1388
1389 *ifpp = ifp;
1390 return (0);
1391 }
1392
1393 static int
ether_frm_attach(struct socket * so,int proto,int wait)1394 ether_frm_attach(struct socket *so, int proto, int wait)
1395 {
1396 struct ether_pcb *ep;
1397 int error;
1398
1399 if (so->so_pcb != NULL)
1400 return (EINVAL);
1401
1402 error = suser(curproc);
1403 if (error != 0)
1404 return (error);
1405
1406 error = soreserve(so, MCLBYTES, MCLBYTES);
1407 if (error != 0)
1408 return (error);
1409
1410 ep = malloc(sizeof(*ep), M_PCB, (wait ? M_WAITOK : M_NOWAIT) | M_ZERO);
1411 if (ep == NULL)
1412 return (ENOMEM);
1413
1414 rw_init(&ep->ep_lock, "ethsock");
1415
1416 so->so_pcb = ep;
1417 ep->ep_socket = so; /* shares a ref with the list */
1418
1419 ep->ep_txprio = IF_HDRPRIO_PACKET;
1420 TAILQ_INIT(&ep->ep_groups);
1421
1422 /* give the ref to the list */
1423 rw_enter_write(ðer_pcb_lock);
1424 TAILQ_INSERT_TAIL(ðer_pcbs, ep, ep_entry);
1425 rw_exit_write(ðer_pcb_lock);
1426
1427 return (0);
1428 }
1429
1430 static int
ether_frm_detach(struct socket * so)1431 ether_frm_detach(struct socket *so)
1432 {
1433 struct ether_pcb *ep;
1434 struct ether_pcb_group *epg, *nepg;
1435 struct ifnet *ifp;
1436
1437 soassertlocked(so);
1438
1439 ep = so->so_pcb;
1440
1441 /* take the ref from the list */
1442 rw_enter_write(ðer_pcb_lock);
1443 TAILQ_REMOVE(ðer_pcbs, ep, ep_entry);
1444 rw_exit_write(ðer_pcb_lock);
1445
1446 so->so_pcb = NULL; /* shares a ref with the list */
1447
1448 /* XXX locking */
1449 TAILQ_FOREACH_SAFE(epg, &ep->ep_groups, epg_entry, nepg) {
1450 ifp = if_get(epg->epg_ifindex);
1451 if (ifp != NULL) {
1452 struct ifreq ifr;
1453 struct sockaddr *sa;
1454
1455 if_detachhook_del(ifp, &epg->epg_hook);
1456
1457 memset(&ifr, 0, sizeof(ifr));
1458 strlcpy(ifr.ifr_name, ifp->if_xname,
1459 sizeof(ifr.ifr_name));
1460 sa = &ifr.ifr_addr;
1461 sa->sa_family = AF_UNSPEC;
1462 memcpy(sa->sa_data, &epg->epg_addr, ETHER_ADDR_LEN);
1463
1464 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
1465 }
1466 if_put(ifp);
1467
1468 TAILQ_REMOVE(&ep->ep_groups, epg, epg_entry);
1469 free(epg, M_PCB, sizeof(*epg));
1470 }
1471
1472 free(ep, M_PCB, sizeof(*ep));
1473
1474 return (0);
1475 }
1476
1477 static int
ether_frm_bind(struct socket * so,struct mbuf * nam,struct proc * p)1478 ether_frm_bind(struct socket *so, struct mbuf *nam, struct proc *p)
1479 {
1480 struct sockaddr_frame *sfrm;
1481 struct ether_pcb *ep;
1482 struct ether_pcb *epe;
1483 struct ifnet *ifp = NULL;
1484 unsigned int ifindex = 0;
1485 uint16_t etype;
1486 uint64_t laddr;
1487 int error;
1488
1489 soassertlocked(so);
1490
1491 error = ether_frm_nam2sfrm(&sfrm, nam);
1492 if (error != 0)
1493 return (error);
1494
1495 etype = ntohs(sfrm->sfrm_proto);
1496 if (!ether_frm_valid_etype(etype))
1497 return (EADDRNOTAVAIL);
1498
1499 ep = so->so_pcb;
1500 if (ep->ep_etype != 0)
1501 return (EINVAL);
1502
1503 error = ether_frm_ifp(&ifp, sfrm);
1504 if (error != 0)
1505 return (error);
1506 if (ifp != NULL)
1507 ifindex = ifp->if_index;
1508
1509 laddr = ether_addr_to_e64((struct ether_addr *)sfrm->sfrm_addr);
1510
1511 rw_enter_write(ðer_pcb_lock);
1512 TAILQ_FOREACH(epe, ðer_pcbs, ep_entry) {
1513 if (ep == epe)
1514 continue;
1515
1516 /* XXX check stuff */
1517 }
1518
1519 if (error == 0) {
1520 /* serialised by the socket lock */
1521 ep->ep_etype = etype;
1522 ep->ep_ifindex = ifindex;
1523 ep->ep_laddr = laddr;
1524 }
1525 rw_exit_write(ðer_pcb_lock);
1526
1527 if_put(ifp);
1528 return (error);
1529 }
1530
1531 static int
ether_frm_connect(struct socket * so,struct mbuf * nam)1532 ether_frm_connect(struct socket *so, struct mbuf *nam)
1533 {
1534 struct sockaddr_frame *sfrm;
1535 struct ether_pcb *ep;
1536 struct ether_pcb *epe;
1537 struct ifnet *ifp = NULL;
1538 uint64_t faddr;
1539 uint16_t etype;
1540 int error;
1541
1542 soassertlocked(so);
1543
1544 error = ether_frm_nam2sfrm(&sfrm, nam);
1545 if (error != 0)
1546 return (error);
1547
1548 etype = ntohs(sfrm->sfrm_proto);
1549 if (!ether_frm_valid_etype(etype))
1550 return (EADDRNOTAVAIL);
1551
1552 faddr = ether_addr_to_e64((struct ether_addr *)sfrm->sfrm_addr);
1553 if (faddr == 0)
1554 return (EADDRNOTAVAIL);
1555
1556 error = ether_frm_ifp(&ifp, sfrm);
1557 if (error != 0)
1558 return (error);
1559 if (ifp == NULL)
1560 return (EADDRNOTAVAIL);
1561
1562 ep = so->so_pcb;
1563 if (ep->ep_etype != 0) {
1564 if (ep->ep_faddr != 0 ||
1565 ep->ep_etype != etype) {
1566 error = EISCONN;
1567 goto put;
1568 }
1569 }
1570 if (ep->ep_ifindex != 0) {
1571 if (ep->ep_ifindex != ifp->if_index) {
1572 error = EADDRNOTAVAIL;
1573 goto put;
1574 }
1575 }
1576
1577 rw_enter_write(ðer_pcb_lock);
1578 TAILQ_FOREACH(epe, ðer_pcbs, ep_entry) {
1579 if (ep == epe)
1580 continue;
1581 /* XXX check stuff */
1582 }
1583
1584 if (error == 0) {
1585 /* serialised by the socket lock */
1586 ep->ep_etype = etype;
1587 ep->ep_ifindex = ifp->if_index;
1588 ep->ep_faddr = faddr;
1589 }
1590 rw_exit_write(ðer_pcb_lock);
1591
1592 put:
1593 if_put(ifp);
1594 return (error);
1595 }
1596
1597 static int
ether_frm_disconnect(struct socket * so)1598 ether_frm_disconnect(struct socket *so)
1599 {
1600 struct ether_pcb *ep;
1601
1602 soassertlocked(so);
1603
1604 ep = so->so_pcb;
1605 if (ep->ep_faddr == 0)
1606 return (ENOTCONN);
1607
1608 rw_enter_write(ðer_pcb_lock);
1609 ep->ep_ifindex = 0;
1610 ep->ep_etype = 0;
1611 ep->ep_laddr = 0;
1612 ep->ep_faddr = 0;
1613 rw_exit_write(ðer_pcb_lock);
1614
1615 return (0);
1616 }
1617
1618 static int
ether_frm_shutdown(struct socket * so)1619 ether_frm_shutdown(struct socket *so)
1620 {
1621 soassertlocked(so);
1622 socantsendmore(so);
1623 return (0);
1624 }
1625
1626 static int
ether_frm_send(struct socket * so,struct mbuf * m,struct mbuf * nam,struct mbuf * control)1627 ether_frm_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
1628 struct mbuf *control)
1629 {
1630 struct ether_pcb *ep;
1631 int error;
1632 uint16_t etype;
1633 uint64_t laddr;
1634 uint64_t faddr;
1635 struct ifnet *ifp = NULL;
1636 struct arpcom *ac;
1637 struct ether_header *eh;
1638 int txprio;
1639
1640 soassertlocked_readonly(so);
1641
1642 ep = so->so_pcb;
1643 KASSERTMSG(ep != NULL, "%s: NULL pcb on socket %p", __func__, so);
1644 txprio = ep->ep_txprio;
1645
1646 /* XXX get prio out of a cmsg */
1647 m_freem(control);
1648
1649 if (nam != NULL) {
1650 struct sockaddr_frame *sfrm;
1651
1652 error = ether_frm_nam2sfrm(&sfrm, nam);
1653 if (error != 0)
1654 goto drop;
1655
1656 etype = ntohs(sfrm->sfrm_proto);
1657 if (!ether_frm_valid_etype(etype)) {
1658 error = EADDRNOTAVAIL;
1659 goto drop;
1660 }
1661
1662 if (ep->ep_faddr != 0) {
1663 error = EISCONN;
1664 goto drop;
1665 }
1666 faddr = ether_addr_to_e64((struct ether_addr *)sfrm->sfrm_addr);
1667 if (faddr == 0) {
1668 error = EADDRNOTAVAIL;
1669 goto drop;
1670 }
1671
1672 error = ether_frm_ifp(&ifp, sfrm);
1673 if (error != 0)
1674 goto drop;
1675 if (ifp == NULL) {
1676 ifp = if_get(ep->ep_ifindex);
1677 if (ifp == NULL) {
1678 error = EADDRNOTAVAIL;
1679 goto drop;
1680 }
1681 } else {
1682 if (ep->ep_ifindex != 0 &&
1683 ep->ep_ifindex != ifp->if_index) {
1684 error = EADDRNOTAVAIL;
1685 goto drop;
1686 }
1687 }
1688
1689 if (ep->ep_etype != etype) {
1690 if (ep->ep_etype == 0) {
1691 /* this is cheeky */
1692 rw_enter_write(ðer_pcb_lock);
1693 ep->ep_etype = etype;
1694 rw_exit_write(ðer_pcb_lock);
1695 } else {
1696 error = EADDRNOTAVAIL;
1697 goto drop;
1698 }
1699 }
1700 } else {
1701 faddr = ep->ep_faddr;
1702 if (faddr == 0) {
1703 error = ENOTCONN;
1704 goto drop;
1705 }
1706
1707 ifp = if_get(ep->ep_ifindex);
1708 if (ifp == NULL) {
1709 error = ENXIO;
1710 goto drop;
1711 }
1712
1713 etype = ep->ep_etype;
1714 }
1715
1716 if (ifp->if_type != IFT_ETHER) {
1717 error = EAFNOSUPPORT;
1718 goto drop;
1719 }
1720
1721 ac = (struct arpcom *)ifp;
1722
1723 laddr = ether_addr_to_e64((struct ether_addr *)ac->ac_enaddr);
1724 if (ep->ep_laddr != laddr) {
1725 if (ep->ep_laddr != 0) {
1726 error = EADDRNOTAVAIL;
1727 goto drop;
1728 }
1729 }
1730
1731 m = m_prepend(m, ETHER_ALIGN + sizeof(*eh), M_NOWAIT);
1732 if (m == NULL)
1733 goto drop;
1734 m_adj(m, ETHER_ALIGN);
1735
1736 if (txprio != IF_HDRPRIO_PACKET)
1737 m->m_pkthdr.pf.prio = txprio;
1738
1739 eh = mtod(m, struct ether_header *);
1740 ether_e64_to_addr((struct ether_addr *)eh->ether_dhost, faddr);
1741 ether_e64_to_addr((struct ether_addr *)eh->ether_shost, laddr);
1742 eh->ether_type = htons(etype);
1743
1744 error = if_enqueue(ifp, m);
1745 m = NULL;
1746
1747 drop:
1748 if_put(ifp);
1749 m_freem(m);
1750 return (error);
1751 }
1752
1753 static int
ether_frm_sockaddr_frame(struct ether_pcb * ep,struct mbuf * nam,uint64_t addr)1754 ether_frm_sockaddr_frame(struct ether_pcb *ep, struct mbuf *nam, uint64_t addr)
1755 {
1756 struct sockaddr_frame *sfrm;
1757 struct ifnet *ifp;
1758
1759 nam->m_len = sizeof(*sfrm);
1760 sfrm = mtod(nam, struct sockaddr_frame *);
1761 memset(sfrm, 0, sizeof(*sfrm));
1762 sfrm->sfrm_len = sizeof(*sfrm);
1763 sfrm->sfrm_family = AF_FRAME;
1764
1765 ether_e64_to_addr((struct ether_addr *)sfrm->sfrm_addr, addr);
1766
1767 if (ep->ep_etype) {
1768 sfrm->sfrm_proto = htons(ep->ep_etype);
1769 sfrm->sfrm_ifindex = ep->ep_ifindex;
1770
1771 ifp = if_get(ep->ep_ifindex);
1772 if (ifp != NULL) {
1773 strlcpy(sfrm->sfrm_ifname, ifp->if_xname,
1774 sizeof(sfrm->sfrm_ifname));
1775 }
1776 if_put(ifp);
1777 }
1778
1779 return (0);
1780 }
1781
1782 static int
ether_frm_sockaddr(struct socket * so,struct mbuf * nam)1783 ether_frm_sockaddr(struct socket *so, struct mbuf *nam)
1784 {
1785 struct ether_pcb *ep = so->so_pcb;
1786
1787 return (ether_frm_sockaddr_frame(ep, nam, ep->ep_laddr));
1788 }
1789
1790 static int
ether_frm_peeraddr(struct socket * so,struct mbuf * nam)1791 ether_frm_peeraddr(struct socket *so, struct mbuf *nam)
1792 {
1793 struct ether_pcb *ep = so->so_pcb;
1794
1795 return (ether_frm_sockaddr_frame(ep, nam, ep->ep_faddr));
1796 }
1797
1798 static void
ether_frm_group_detach(void * arg)1799 ether_frm_group_detach(void *arg)
1800 {
1801 struct ether_pcb_group *epg = arg;
1802 struct ether_pcb *ep = epg->epg_pcb;
1803 struct socket *so = ep->ep_socket;
1804 struct ifnet *ifp;
1805
1806 ifp = if_get(epg->epg_ifindex);
1807
1808 /* XXX locking^Wreference counts */
1809 solock(so);
1810 if (ifp != NULL)
1811 if_detachhook_del(ifp, &epg->epg_hook);
1812 TAILQ_REMOVE(&ep->ep_groups, epg, epg_entry);
1813 sounlock(so);
1814
1815 if_put(ifp);
1816 free(epg, M_PCB, sizeof(*epg));
1817 }
1818
1819 static int
ether_frm_group(struct socket * so,int optname,struct mbuf * m)1820 ether_frm_group(struct socket *so, int optname, struct mbuf *m)
1821 {
1822 struct frame_mreq *fmr;
1823 struct ifreq ifr;
1824 struct sockaddr *sa;
1825 struct ifnet *ifp;
1826 struct ether_pcb *ep;
1827 struct ether_pcb_group *epg;
1828 u_long cmd;
1829 int error;
1830
1831 soassertlocked(so);
1832
1833 if (m->m_len != sizeof(*fmr))
1834 return (EINVAL);
1835
1836 fmr = mtod(m, struct frame_mreq *);
1837 if (!ETHER_IS_MULTICAST(fmr->fmr_addr))
1838 return (EADDRNOTAVAIL);
1839
1840 if (fmr->fmr_ifindex == 0) {
1841 KERNEL_LOCK();
1842 ifp = if_unit(fmr->fmr_ifname);
1843 KERNEL_UNLOCK();
1844 } else
1845 ifp = if_get(fmr->fmr_ifindex);
1846 if (ifp == NULL)
1847 return (ENXIO);
1848
1849 if (ifp->if_type != IFT_ETHER) {
1850 error = EADDRNOTAVAIL;
1851 goto put;
1852 }
1853
1854 if (ETHER_IS_BROADCAST(fmr->fmr_addr)) {
1855 error = 0;
1856 goto put;
1857 }
1858
1859 ep = so->so_pcb;
1860 TAILQ_FOREACH(epg, &ep->ep_groups, epg_entry) {
1861 if (epg->epg_ifindex != ifp->if_index)
1862 continue;
1863 if (!ETHER_IS_EQ(epg->epg_addr, fmr->fmr_addr))
1864 continue;
1865
1866 break;
1867 }
1868
1869 switch (optname) {
1870 case FRAME_ADD_MEMBERSHIP:
1871 if (epg != NULL) {
1872 error = EISCONN;
1873 goto put;
1874 }
1875 epg = malloc(sizeof(*epg), M_PCB, M_DONTWAIT);
1876 if (epg == NULL) {
1877 error = ENOMEM;
1878 goto put;
1879 }
1880
1881 epg->epg_pcb = ep;
1882 epg->epg_ifindex = ifp->if_index;
1883 memcpy(&epg->epg_addr, fmr->fmr_addr, sizeof(epg->epg_addr));
1884 task_set(&epg->epg_hook, ether_frm_group_detach, epg);
1885
1886 cmd = SIOCADDMULTI;
1887 break;
1888 case FRAME_DEL_MEMBERSHIP:
1889 if (epg == NULL) {
1890 error = ENOTCONN;
1891 goto put;
1892 }
1893 cmd = SIOCDELMULTI;
1894 break;
1895 default:
1896 panic("%s: unexpected optname %d", __func__, optname);
1897 /* NOTREACHED */
1898 }
1899
1900 memset(&ifr, 0, sizeof(ifr));
1901 strlcpy(ifr.ifr_name, ifp->if_xname, sizeof(ifr.ifr_name));
1902 sa = &ifr.ifr_addr;
1903 sa->sa_family = AF_UNSPEC;
1904 memcpy(sa->sa_data, fmr->fmr_addr, ETHER_ADDR_LEN);
1905
1906 /* XXX soref? */
1907 /* this could lead to multiple epgs for the same if/group */
1908 sounlock(so);
1909 KERNEL_LOCK();
1910 NET_LOCK();
1911 error = (*ifp->if_ioctl)(ifp, cmd, (caddr_t)&ifr);
1912 NET_UNLOCK();
1913 KERNEL_UNLOCK();
1914 solock(so);
1915
1916 switch (optname) {
1917 case FRAME_ADD_MEMBERSHIP:
1918 if (error != 0) {
1919 free(epg, M_PCB, sizeof(*epg));
1920 break;
1921 }
1922
1923 TAILQ_INSERT_TAIL(&ep->ep_groups, epg, epg_entry);
1924 if_detachhook_add(ifp, &epg->epg_hook);
1925 break;
1926 case FRAME_DEL_MEMBERSHIP:
1927 if (error != 0)
1928 break;
1929
1930 if_detachhook_del(ifp, &epg->epg_hook);
1931 TAILQ_REMOVE(&ep->ep_groups, epg, epg_entry);
1932 free(epg, M_PCB, sizeof(*epg));
1933 break;
1934 }
1935 put:
1936 if_put(ifp);
1937
1938 return (error);
1939 }
1940
1941 #define ETHER_PCB_OPTM(_v) (1ULL << (_v))
1942
1943 #define ETHER_PCB_OPTS \
1944 ETHER_PCB_OPTM(FRAME_RECVDSTADDR) | \
1945 ETHER_PCB_OPTM(FRAME_RECVPRIO)
1946
1947 static int
ether_frm_setopt(struct ether_pcb * ep,int optname,struct mbuf * m)1948 ether_frm_setopt(struct ether_pcb *ep, int optname, struct mbuf *m)
1949 {
1950 uint64_t optm = ETHER_PCB_OPTM(optname);
1951 int opt;
1952
1953 if (!ISSET(ETHER_PCB_OPTS, optm))
1954 return (ENOPROTOOPT);
1955
1956 if (m->m_len != sizeof(opt))
1957 return (EINVAL);
1958
1959 opt = *mtod(m, int *);
1960 if (opt)
1961 SET(ep->ep_options, optm);
1962 else
1963 CLR(ep->ep_options, optm);
1964
1965 return (0);
1966 }
1967
1968 static int
ether_frm_setsockopt(struct socket * so,int optname,struct mbuf * m)1969 ether_frm_setsockopt(struct socket *so, int optname, struct mbuf *m)
1970 {
1971 struct ether_pcb *ep = so->so_pcb;
1972 int error = ENOPROTOOPT;
1973 int v;
1974
1975 if (optname >= 0 && optname < 64)
1976 return (ether_frm_setopt(ep, optname, m));
1977
1978 switch (optname) {
1979 case FRAME_ADD_MEMBERSHIP:
1980 case FRAME_DEL_MEMBERSHIP:
1981 error = ether_frm_group(so, optname, m);
1982 break;
1983 case FRAME_SENDPRIO:
1984 if (m->m_len != sizeof(v)) {
1985 error = EINVAL;
1986 break;
1987 }
1988 v = *mtod(m, int *);
1989 error = if_txhprio_l2_check(v);
1990 if (error != 0)
1991 break;
1992 ep->ep_txprio = v;
1993 break;
1994
1995 default:
1996 break;
1997 }
1998
1999 return (error);
2000 }
2001
2002 static int
ether_frm_getopt(struct ether_pcb * ep,int optname,struct mbuf * m)2003 ether_frm_getopt(struct ether_pcb *ep, int optname, struct mbuf *m)
2004 {
2005 uint64_t optm = ETHER_PCB_OPTM(optname);
2006 int opt;
2007
2008 if (!ISSET(ETHER_PCB_OPTS, optm))
2009 return (ENOPROTOOPT);
2010
2011 opt = !!ISSET(ep->ep_options, optm);
2012
2013 m->m_len = sizeof(opt);
2014 *mtod(m, int *) = opt;
2015
2016 return (0);
2017 }
2018
2019 static int
ether_frm_getsockopt(struct socket * so,int optname,struct mbuf * m)2020 ether_frm_getsockopt(struct socket *so, int optname, struct mbuf *m)
2021 {
2022 struct ether_pcb *ep = so->so_pcb;
2023 int error = ENOPROTOOPT;
2024
2025 if (optname >= 0 && optname < 64)
2026 return (ether_frm_getopt(ep, optname, m));
2027
2028 switch (optname) {
2029 default:
2030 break;
2031 }
2032
2033 return (error);
2034 }
2035
2036 int
ether_frm_ctloutput(int op,struct socket * so,int level,int optname,struct mbuf * m)2037 ether_frm_ctloutput(int op, struct socket *so, int level, int optname,
2038 struct mbuf *m)
2039 {
2040 int error = 0;
2041
2042 if (level != IFT_ETHER)
2043 return (EINVAL);
2044
2045 switch (op) {
2046 case PRCO_SETOPT:
2047 error = ether_frm_setsockopt(so, optname, m);
2048 break;
2049 case PRCO_GETOPT:
2050 error = ether_frm_getsockopt(so, optname, m);
2051 break;
2052 }
2053
2054 return (error);
2055 }
2056
2057 static struct mbuf *
ether_frm_cmsg(struct mbuf * cmsgs,const void * data,size_t datalen,int type,int level)2058 ether_frm_cmsg(struct mbuf *cmsgs, const void *data, size_t datalen,
2059 int type, int level)
2060 {
2061 struct mbuf *cm;
2062
2063 cm = sbcreatecontrol(data, datalen, type, level);
2064 if (cm != NULL) {
2065 cm->m_next = cmsgs;
2066 cmsgs = cm;
2067 }
2068
2069 return (cmsgs);
2070 }
2071
2072 static void
ether_frm_recv(struct socket * so,struct mbuf * m0,const struct sockaddr_frame * sfrm)2073 ether_frm_recv(struct socket *so, struct mbuf *m0,
2074 const struct sockaddr_frame *sfrm)
2075 {
2076 struct ether_pcb *ep = so->so_pcb;
2077 struct mbuf *m;
2078 struct mbuf *cmsgs = NULL;
2079 int ok;
2080
2081 /* offset 0 and m_adj cos sbappendaddr needs m_pkthdr.len */
2082 m = m_copym(m0, 0, M_COPYALL, M_DONTWAIT);
2083 if (m == NULL)
2084 return;
2085 m_adj(m, sizeof(struct ether_header));
2086
2087 if (ISSET(ep->ep_options, ETHER_PCB_OPTM(FRAME_RECVPRIO))) {
2088 int rxprio = m0->m_pkthdr.pf.prio;
2089 cmsgs = ether_frm_cmsg(cmsgs, &rxprio, sizeof(rxprio),
2090 FRAME_RECVPRIO, IFT_ETHER);
2091 }
2092
2093 if (ISSET(ep->ep_options, ETHER_PCB_OPTM(FRAME_RECVDSTADDR))) {
2094 struct ether_header *eh = mtod(m0, struct ether_header *);
2095 cmsgs = ether_frm_cmsg(cmsgs, eh->ether_dhost, ETHER_ADDR_LEN,
2096 FRAME_RECVDSTADDR, IFT_ETHER);
2097 }
2098
2099 if (ISSET(so->so_options, SO_TIMESTAMP)) {
2100 struct timeval tv;
2101 m_microtime(m0, &tv);
2102 cmsgs = ether_frm_cmsg(cmsgs, &tv, sizeof(tv),
2103 SCM_TIMESTAMP, SOL_SOCKET);
2104 }
2105
2106 mtx_enter(&so->so_rcv.sb_mtx);
2107 ok = sbappendaddr(so, &so->so_rcv, (struct sockaddr *)sfrm, m, cmsgs);
2108 mtx_leave(&so->so_rcv.sb_mtx);
2109
2110 if (!ok) {
2111 m_freem(m);
2112 m_freem(cmsgs);
2113 return;
2114 }
2115
2116 sorwakeup(so);
2117 }
2118
2119 static struct mbuf *
ether_frm_input(struct ifnet * ifp,struct mbuf * m,uint64_t dst,uint16_t etype)2120 ether_frm_input(struct ifnet *ifp, struct mbuf *m, uint64_t dst, uint16_t etype)
2121 {
2122 struct sockaddr_frame sfrm = { .sfrm_family = AF_UNSPEC };
2123 struct ether_pcb *ep;
2124 struct ether_header *eh;
2125 uint64_t src;
2126
2127 if (TAILQ_EMPTY(ðer_pcbs))
2128 return (m);
2129
2130 eh = mtod(m, struct ether_header *);
2131 src = ether_addr_to_e64((struct ether_addr *)eh->ether_shost);
2132 if (src == 0)
2133 return (m);
2134
2135 rw_enter_read(ðer_pcb_lock);
2136 TAILQ_FOREACH(ep, ðer_pcbs, ep_entry) {
2137 if (ep->ep_etype == 0) /* bound? */
2138 continue;
2139 if (ep->ep_etype != etype)
2140 continue;
2141 if (ep->ep_ifindex != 0) {
2142 if (ep->ep_ifindex != ifp->if_index)
2143 continue;
2144 }
2145
2146 if (ep->ep_laddr != 0) {
2147 if (ep->ep_laddr != dst)
2148 continue;
2149 }
2150 /* ether_input says dst is valid for local delivery */
2151
2152 if (ep->ep_faddr != 0) { /* connected? */
2153 if (ep->ep_faddr != src)
2154 continue;
2155 }
2156
2157 if (sfrm.sfrm_family == AF_UNSPEC) {
2158 sfrm.sfrm_len = sizeof(sfrm);
2159 sfrm.sfrm_family = AF_FRAME;
2160 sfrm.sfrm_proto = htons(etype);
2161 sfrm.sfrm_ifindex = ifp->if_index;
2162 ether_e64_to_addr((struct ether_addr *)sfrm.sfrm_addr,
2163 src);
2164 strlcpy(sfrm.sfrm_ifname, ifp->if_xname,
2165 sizeof(sfrm.sfrm_ifname));
2166 }
2167
2168 ether_frm_recv(ep->ep_socket, m, &sfrm);
2169 }
2170 rw_exit_read(ðer_pcb_lock);
2171
2172 return (m);
2173 }
2174
2175 #endif /* NAF_FRAME */
2176