Annotation of sys/net/if_ethersubr.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_ethersubr.c,v 1.110 2007/06/06 10:04:36 henning 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/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 /* NVLAN > 0 */
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 /* NETATALK */
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: /* Nothing to do. */
175: break;
176: #endif /* NETATALK */
177: }
178: break;
179: default:
180: break;
181: }
182:
183: return error;
184: }
185:
186: /*
187: * Ethernet output routine.
188: * Encapsulate a packet of type family for the local net.
189: * Assumes that ifp is actually pointer to arpcom structure.
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: /* loop back if this is going to the carp interface */
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 /* NCARP > 0 */
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); /* if not yet resolved */
264: /* If broadcasting on a simplex interface, loopback a copy */
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); /* it must be impossible, but... */
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 /* NETATALKDEBUG */
287: return (0);
288: }
289:
290: /*
291: * ifaddr is the first thing in at_ifaddr
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: * In the phase 2 case, we need to prepend an mbuf for the llc
301: * header. Since we must preserve the value of m, which is
302: * passed to us by value, we m_copy() the first mbuf,
303: * and use it for our llc header.
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: * FreeBSD doesn't count the LLC len in
313: * ifp->obytes, so they increment a length
314: * field here. We don't do this.
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 /* NETATALK */
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: /* FALLTHROUGH */
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: /* AF_UNSPEC doesn't swap the byte order of the ether_type. */
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: /* XXX Should we feed-back an unencrypted IPsec packet ? */
348: if (mcopy)
349: (void) looutput(ifp, mcopy, dst, rt);
350:
351: /*
352: * Add local net header. If no space in first mbuf,
353: * allocate another.
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: * Interfaces that are bridge members need special handling
380: * for output.
381: */
382: if (ifp->if_bridge) {
383: struct m_tag *mtag;
384:
385: /*
386: * Check if this packet has already been sent out through
387: * this bridge, in which case we simply send it out
388: * without further bridge processing.
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: /* Check that the information is there */
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: /* Attach a tag so we can detect loops */
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: * Queue message on interface, and start output if interface
423: * not yet active.
424: */
425: IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
426: if (error) {
427: /* mbuf is already freed */
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 /* NCARP > 0 */
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: * Process a received Ethernet packet;
451: * the packet is in the mbuf chain m without
452: * the ether header, which is provided separately.
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: /* Handle input from a trunk port */
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: /* Has been set to the trunk interface */
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: * If this is not a simplex interface, drop the packet
509: * if it came from us.
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: * Tap the packet off here for a bridge, if configured and
538: * active for this interface. bridge_input returns
539: * NULL if it has consumed the packet, otherwise, it
540: * gets processed as normal.
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: /* The bridge has determined it's for us. */
550: ifp = m->m_pkthdr.rcvif;
551: }
552: }
553: #endif
554:
555: #if NVLAN > 0
556: if (etype == ETHERTYPE_VLAN) {
557: /* The bridge did not want the vlan frame either, drop it. */
558: ifp->if_noproto++;
559: m_freem(m);
560: return;
561: }
562: #endif /* NVLAN > 0 */
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: /* Always clear multicast flags if received on a carp address */
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 /* NCARP > 0 */
579:
580: ac = (struct arpcom *)ifp;
581:
582: /*
583: * If packet has been filtered by the bpf listener, drop it now
584: */
585: if (m->m_flags & M_FILDROP) {
586: m_free(m);
587: return;
588: }
589:
590: /*
591: * If packet is unicast and we're in promiscuous mode, make sure it
592: * is for us. Drop otherwise.
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); /* XXX queue? */
623: return;
624:
625: #endif
626: #ifdef INET6
627: /*
628: * Schedule IPv6 software interrupt for incoming IPv6 packet.
629: */
630: case ETHERTYPE_IPV6:
631: schednetisr(NETISR_IPV6);
632: inq = &ip6intrq;
633: break;
634: #endif /* INET6 */
635: #ifdef NETATALK
636: case ETHERTYPE_AT:
637: schednetisr(NETISR_ATALK);
638: inq = &atintrq1;
639: break;
640: case ETHERTYPE_AARP:
641: /* probably this should be done with a NETISR as well */
642: /* XXX queue this */
643: aarpinput((struct arpcom *)ifp, m);
644: return;
645: #endif
646: #if NPPPOE > 0
647: case ETHERTYPE_PPPOEDISC:
648: case ETHERTYPE_PPPOE:
649: /* XXX we dont have this flag */
650: /*
651: if (m->m_flags & M_PROMISC) {
652: m_freem(m);
653: return;
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 /* NPPPOE > 0 */
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: * Some protocols (like Appletalk) need special
687: * handling depending on if they are type II
688: * or SNAP encapsulated. Everything else
689: * gets handled by stripping off the SNAP header
690: * and going back up to decapsulate.
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: /* XXX Really this should use netisr too */
710: aarpinput((struct arpcom *)ifp, m);
711: return;
712: }
713: #endif /* NETATALK */
714: if (l->llc_control == LLC_UI &&
715: l->llc_dsap == LLC_SNAP_LSAP &&
716: l->llc_ssap == LLC_SNAP_LSAP) {
717: /* SNAP */
718: if (m->m_pkthdr.len > etype)
719: m_adj(m, etype - m->m_pkthdr.len);
720: m->m_data += 6; /* XXX */
721: m->m_len -= 6; /* XXX */
722: m->m_pkthdr.len -= 6; /* XXX */
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: * Convert Ethernet address to printable (loggable) representation.
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: * Perform common duties while attaching to interface list
765: */
766: void
767: ether_ifattach(ifp)
768: struct ifnet *ifp;
769: {
770:
771: /*
772: * Any interface which provides a MAC address which is obviously
773: * invalid gets whacked, so that users will notice.
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: * XXX use of random() by anything except the scheduler is
783: * normally invalid, but this is boot time, so pre-scheduler,
784: * and the random subsystem is not alive yet
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: /* moved to if_detach() */
823: if_free_sadl(ifp);
824: #endif
825: }
826:
827: #if 0
828: /*
829: * This is for reference. We have table-driven versions of the
830: * crc32 generators, which are faster than the double-loop.
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; /* initial value */
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; /* initial value */
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; /* initial value */
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; /* initial value */
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: * Convert a sockaddr into an Ethernet address or range of Ethernet
943: * addresses.
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 /* INET */
952: #ifdef INET6
953: struct sockaddr_in6 *sin6;
954: #endif /* INET6 */
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: * An IP address of INADDR_ANY means listen to
969: * or stop listening to all of the Ethernet
970: * multicast addresses used for IP.
971: * (This is for the sake of IP multicast routers.)
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: * An IP6 address of 0 means listen to or stop
987: * listening to all of the Ethernet multicast
988: * address used for IP6.
989: *
990: * (This might not be healthy, given IPv6's reliance on
991: * multicast for things like neighbor discovery.
992: * Perhaps initializing all-nodes, solicited nodes, and
993: * possibly all-routers for this interface afterwards
994: * is not a bad idea.)
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: * Add an Ethernet multicast address or range of addresses to the list for a
1014: * given interface.
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: * Verify that we have valid Ethernet multicast addresses.
1034: */
1035: if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
1036: splx(s);
1037: return (EINVAL);
1038: }
1039: /*
1040: * See if the address range is already in the list.
1041: */
1042: ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1043: if (enm != NULL) {
1044: /*
1045: * Found it; just increment the reference count.
1046: */
1047: ++enm->enm_refcount;
1048: splx(s);
1049: return (0);
1050: }
1051: /*
1052: * New address or range; malloc a new multicast record
1053: * and link it into the interface's multicast list.
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: * Return ENETRESET to inform the driver that the list has changed
1071: * and its reception filter should be adjusted accordingly.
1072: */
1073: return (ENETRESET);
1074: }
1075:
1076: /*
1077: * Delete a multicast address record.
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: * Look up the address in our list.
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: * Still some claims to this record.
1106: */
1107: splx(s);
1108: return (0);
1109: }
1110: /*
1111: * No remaining claims to this record; unlink and free it.
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: * Return ENETRESET to inform the driver that the list has changed
1121: * and its reception filter should be adjusted accordingly.
1122: */
1123: return (ENETRESET);
1124: }
CVSweb