if_ethersubr.c revision 1.41.6.2 1 /* $NetBSD: if_ethersubr.c,v 1.41.6.2 1999/11/30 13:35:02 itojun Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1982, 1989, 1993
34 * The Regents of the University of California. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the University of
47 * California, Berkeley and its contributors.
48 * 4. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
63 *
64 * @(#)if_ethersubr.c 8.2 (Berkeley) 4/4/96
65 */
66
67 #include "opt_inet.h"
68 #include "opt_atalk.h"
69 #include "opt_ccitt.h"
70 #include "opt_llc.h"
71 #include "opt_iso.h"
72 #include "opt_ns.h"
73 #include "opt_gateway.h"
74
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/kernel.h>
78 #include <sys/malloc.h>
79 #include <sys/mbuf.h>
80 #include <sys/protosw.h>
81 #include <sys/socket.h>
82 #include <sys/ioctl.h>
83 #include <sys/errno.h>
84 #include <sys/syslog.h>
85
86 #include <machine/cpu.h>
87
88 #include <net/if.h>
89 #include <net/netisr.h>
90 #include <net/route.h>
91 #include <net/if_llc.h>
92 #include <net/if_dl.h>
93 #include <net/if_types.h>
94
95 #include <net/if_ether.h>
96
97 #include <netinet/in.h>
98 #ifdef INET
99 #include <netinet/in_var.h>
100 #endif
101 #include <netinet/if_inarp.h>
102
103 #ifdef INET6
104 #ifndef INET
105 #include <netinet/in.h>
106 #endif
107 #include <netinet6/in6_var.h>
108 #include <netinet6/nd6.h>
109 #include <netinet6/in6_ifattach.h>
110 #endif
111
112 #ifdef NS
113 #include <netns/ns.h>
114 #include <netns/ns_if.h>
115 #endif
116
117 #ifdef IPX
118 #include <netipx/ipx.h>
119 #include <netipx/ipx_if.h>
120 #endif
121
122 #ifdef ISO
123 #include <netiso/argo_debug.h>
124 #include <netiso/iso.h>
125 #include <netiso/iso_var.h>
126 #include <netiso/iso_snpac.h>
127 #endif
128
129 #ifdef LLC
130 #include <netccitt/dll.h>
131 #include <netccitt/llc_var.h>
132 #endif
133
134 #if defined(LLC) && defined(CCITT)
135 extern struct ifqueue pkintrq;
136 #endif
137
138 #ifdef NETATALK
139 #include <netatalk/at.h>
140 #include <netatalk/at_var.h>
141 #include <netatalk/at_extern.h>
142
143 #define llc_snap_org_code llc_un.type_snap.org_code
144 #define llc_snap_ether_type llc_un.type_snap.ether_type
145
146 extern u_char at_org_code[3];
147 extern u_char aarp_org_code[3];
148 #endif /* NETATALK */
149
150 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
151 #define senderr(e) { error = (e); goto bad;}
152
153 #define SIN(x) ((struct sockaddr_in *)x)
154
155 /*
156 * Ethernet output routine.
157 * Encapsulate a packet of type family for the local net.
158 * Assumes that ifp is actually pointer to ethercom structure.
159 */
160 int
161 ether_output(ifp, m0, dst, rt0)
162 struct ifnet *ifp;
163 struct mbuf *m0;
164 struct sockaddr *dst;
165 struct rtentry *rt0;
166 {
167 u_int16_t etype;
168 int s, error = 0, hdrcmplt = 0;
169 u_char esrc[6], edst[6];
170 struct mbuf *m = m0;
171 struct rtentry *rt;
172 struct mbuf *mcopy = (struct mbuf *)0;
173 struct ether_header *eh;
174 #ifdef INET
175 struct arphdr *ah;
176 #endif /* INET */
177 #ifdef NETATALK
178 struct at_ifaddr *aa;
179 #endif /* NETATALK */
180 #ifdef ALTQ
181 struct pr_hdr pr_hdr;
182 #endif
183
184 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
185 senderr(ENETDOWN);
186 ifp->if_lastchange = time;
187 if ((rt = rt0) != NULL) {
188 if ((rt->rt_flags & RTF_UP) == 0) {
189 if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) {
190 rt->rt_refcnt--;
191 if (rt->rt_ifp != ifp)
192 return (*rt->rt_ifp->if_output)
193 (ifp, m0, dst, rt);
194 } else
195 senderr(EHOSTUNREACH);
196 }
197 if ((rt->rt_flags & RTF_GATEWAY) && dst->sa_family != AF_NS) {
198 if (rt->rt_gwroute == 0)
199 goto lookup;
200 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
201 rtfree(rt); rt = rt0;
202 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
203 if ((rt = rt->rt_gwroute) == 0)
204 senderr(EHOSTUNREACH);
205 /* the "G" test below also prevents rt == rt0 */
206 if ((rt->rt_flags & RTF_GATEWAY) ||
207 (rt->rt_ifp != ifp)) {
208 rt->rt_refcnt--;
209 rt0->rt_gwroute = 0;
210 senderr(EHOSTUNREACH);
211 }
212 }
213 }
214 if (rt->rt_flags & RTF_REJECT)
215 if (rt->rt_rmx.rmx_expire == 0 ||
216 time.tv_sec < rt->rt_rmx.rmx_expire)
217 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
218 }
219 #ifdef ALTQ
220 /*
221 * save a pointer to the protocol level header before adding
222 * link headers.
223 */
224 pr_hdr.ph_family = dst->sa_family;
225 pr_hdr.ph_hdr = mtod(m, caddr_t);
226 #endif /* ALTQ */
227 switch (dst->sa_family) {
228
229 #ifdef INET
230 case AF_INET:
231 if (m->m_flags & M_BCAST)
232 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst,
233 sizeof(edst));
234
235 else if (m->m_flags & M_MCAST) {
236 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr,
237 (caddr_t)edst)
238
239 } else if (!arpresolve(ifp, rt, m, dst, edst))
240 return (0); /* if not yet resolved */
241 /* If broadcasting on a simplex interface, loopback a copy */
242 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
243 mcopy = m_copy(m, 0, (int)M_COPYALL);
244 etype = htons(ETHERTYPE_IP);
245 break;
246
247 case AF_ARP:
248 ah = mtod(m, struct arphdr *);
249 if (m->m_flags & M_BCAST)
250 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst,
251 sizeof(edst));
252 else
253 bcopy((caddr_t)ar_tha(ah),
254 (caddr_t)edst, sizeof(edst));
255
256 ah->ar_hrd = htons(ARPHRD_ETHER);
257
258 switch(ntohs(ah->ar_op)) {
259 case ARPOP_REVREQUEST:
260 case ARPOP_REVREPLY:
261 etype = htons(ETHERTYPE_REVARP);
262 break;
263
264 case ARPOP_REQUEST:
265 case ARPOP_REPLY:
266 default:
267 etype = htons(ETHERTYPE_ARP);
268 }
269
270 break;
271 #endif
272 #ifdef INET6
273 case AF_INET6:
274 #ifdef OLDIP6OUTPUT
275 if (!nd6_resolve(ifp, rt, m, dst, (u_char *)edst))
276 return(0); /* if not yet resolves */
277 #else
278 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst)){
279 /* this must be impossible, so we bark */
280 printf("nd6_storelladdr failed\n");
281 return(0);
282 }
283 #endif /* OLDIP6OUTPUT */
284 etype = htons(ETHERTYPE_IPV6);
285 break;
286 #endif
287 #ifdef NETATALK
288 case AF_APPLETALK:
289 if (!aarpresolve(ifp, m, (struct sockaddr_at *)dst, edst)) {
290 #ifdef NETATALKDEBUG
291 printf("aarpresolv failed\n");
292 #endif /* NETATALKDEBUG */
293 return (0);
294 }
295 /*
296 * ifaddr is the first thing in at_ifaddr
297 */
298 aa = (struct at_ifaddr *) at_ifawithnet(
299 (struct sockaddr_at *)dst, ifp);
300 if (aa == NULL)
301 goto bad;
302
303 /*
304 * In the phase 2 case, we need to prepend an mbuf for the
305 * llc header. Since we must preserve the value of m,
306 * which is passed to us by value, we m_copy() the first
307 * mbuf, and use it for our llc header.
308 */
309 if (aa->aa_flags & AFA_PHASE2) {
310 struct llc llc;
311
312 M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
313 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
314 llc.llc_control = LLC_UI;
315 bcopy(at_org_code, llc.llc_snap_org_code,
316 sizeof(llc.llc_snap_org_code));
317 llc.llc_snap_ether_type = htons(ETHERTYPE_ATALK);
318 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
319 etype = htons(m->m_pkthdr.len);
320 } else {
321 etype = htons(ETHERTYPE_ATALK);
322 }
323 break;
324 #endif /* NETATALK */
325 #ifdef NS
326 case AF_NS:
327 etype = htons(ETHERTYPE_NS);
328 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
329 (caddr_t)edst, sizeof (edst));
330 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
331 return (looutput(ifp, m, dst, rt));
332 /* If broadcasting on a simplex interface, loopback a copy */
333 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
334 mcopy = m_copy(m, 0, (int)M_COPYALL);
335 break;
336 #endif
337 #ifdef IPX
338 case AF_IPX:
339 etype = htons(ETHERTYPE_IPX);
340 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
341 (caddr_t)edst, sizeof (edst));
342 /* If broadcasting on a simplex interface, loopback a copy */
343 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
344 mcopy = m_copy(m, 0, (int)M_COPYALL);
345 break;
346 #endif
347 #ifdef ISO
348 case AF_ISO: {
349 int snpalen;
350 struct llc *l;
351 struct sockaddr_dl *sdl;
352
353 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
354 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
355 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
356 } else {
357 error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
358 (char *)edst, &snpalen);
359 if (error)
360 goto bad; /* Not Resolved */
361 }
362 /* If broadcasting on a simplex interface, loopback a copy */
363 if (*edst & 1)
364 m->m_flags |= (M_BCAST|M_MCAST);
365 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
366 (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
367 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
368 if (mcopy) {
369 eh = mtod(mcopy, struct ether_header *);
370 bcopy((caddr_t)edst,
371 (caddr_t)eh->ether_dhost, sizeof (edst));
372 bcopy(LLADDR(ifp->if_sadl),
373 (caddr_t)eh->ether_shost, sizeof (edst));
374 }
375 }
376 M_PREPEND(m, 3, M_DONTWAIT);
377 if (m == NULL)
378 return (0);
379 etype = htons(m->m_pkthdr.len);
380 l = mtod(m, struct llc *);
381 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
382 l->llc_control = LLC_UI;
383 #ifdef ARGO_DEBUG
384 if (argo_debug[D_ETHER]) {
385 int i;
386 printf("unoutput: sending pkt to: ");
387 for (i=0; i<6; i++)
388 printf("%x ", edst[i] & 0xff);
389 printf("\n");
390 }
391 #endif
392 } break;
393 #endif /* ISO */
394 #ifdef LLC
395 /* case AF_NSAP: */
396 case AF_CCITT: {
397 struct sockaddr_dl *sdl =
398 (struct sockaddr_dl *) rt -> rt_gateway;
399
400 if (sdl && sdl->sdl_family == AF_LINK
401 && sdl->sdl_alen > 0) {
402 bcopy(LLADDR(sdl), (char *)edst,
403 sizeof(edst));
404 } else goto bad; /* Not a link interface ? Funny ... */
405 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
406 (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
407 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
408 if (mcopy) {
409 eh = mtod(mcopy, struct ether_header *);
410 bcopy((caddr_t)edst,
411 (caddr_t)eh->ether_dhost, sizeof (edst));
412 bcopy(LLADDR(ifp->if_sadl),
413 (caddr_t)eh->ether_shost, sizeof (edst));
414 }
415 }
416 etype = htons(m->m_pkthdr.len);
417 #ifdef LLC_DEBUG
418 {
419 int i;
420 struct llc *l = mtod(m, struct llc *);
421
422 printf("ether_output: sending LLC2 pkt to: ");
423 for (i=0; i<6; i++)
424 printf("%x ", edst[i] & 0xff);
425 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
426 m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff,
427 l->llc_control & 0xff);
428
429 }
430 #endif /* LLC_DEBUG */
431 } break;
432 #endif /* LLC */
433
434 case pseudo_AF_HDRCMPLT:
435 hdrcmplt = 1;
436 eh = (struct ether_header *)dst->sa_data;
437 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc));
438 /* FALLTHROUGH */
439
440 case AF_UNSPEC:
441 eh = (struct ether_header *)dst->sa_data;
442 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
443 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */
444 etype = eh->ether_type;
445 break;
446
447 default:
448 printf("%s: can't handle af%d\n", ifp->if_xname,
449 dst->sa_family);
450 senderr(EAFNOSUPPORT);
451 }
452
453 if (mcopy)
454 (void) looutput(ifp, mcopy, dst, rt);
455
456 /*
457 * Add local net header. If no space in first mbuf,
458 * allocate another.
459 */
460 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
461 if (m == 0)
462 senderr(ENOBUFS);
463 eh = mtod(m, struct ether_header *);
464 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type,
465 sizeof(eh->ether_type));
466 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
467 if (hdrcmplt)
468 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost,
469 sizeof(eh->ether_shost));
470 else
471 bcopy(LLADDR(ifp->if_sadl), (caddr_t)eh->ether_shost,
472 sizeof(eh->ether_shost));
473 #ifdef ALTQ
474 if (ALTQ_IS_ON(ifp)) {
475 s = splimp();
476 error = (*ifp->if_altqenqueue)(ifp, m, &pr_hdr, ALTEQ_NORMAL);
477 splx(s);
478 if (error) {
479 IF_DROP(&ifp->if_snd);
480 }
481 else {
482 ifp->if_obytes += m->m_pkthdr.len;
483 if (m->m_flags & M_MCAST)
484 ifp->if_omcasts++;
485 }
486 return (error);
487 }
488 #endif /* ALTQ */
489 s = splimp();
490 /*
491 * Queue message on interface, and start output if interface
492 * not yet active.
493 */
494 if (IF_QFULL(&ifp->if_snd)) {
495 IF_DROP(&ifp->if_snd);
496 #ifdef ALTQ_ACCOUNT
497 ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCDROP);
498 #endif
499 splx(s);
500 senderr(ENOBUFS);
501 }
502 ifp->if_obytes += m->m_pkthdr.len;
503 IF_ENQUEUE(&ifp->if_snd, m);
504 #ifdef ALTQ_ACCOUNT
505 ALTQ_ACCOUNTING(ifp, m, &pr_hdr, ALTEQ_ACCOK);
506 #endif
507 if ((ifp->if_flags & IFF_OACTIVE) == 0)
508 (*ifp->if_start)(ifp);
509 splx(s);
510 if (m->m_flags & M_MCAST)
511 ifp->if_omcasts++;
512 return (error);
513
514 bad:
515 if (m)
516 m_freem(m);
517 return (error);
518 }
519
520 /*
521 * Process a received Ethernet packet;
522 * the packet is in the mbuf chain m without
523 * the ether header, which is provided separately.
524 */
525 void
526 ether_input(ifp, eh, m)
527 struct ifnet *ifp;
528 struct ether_header *eh;
529 struct mbuf *m;
530 {
531 struct ifqueue *inq;
532 u_int16_t etype;
533 int s;
534 #if defined (ISO) || defined (LLC) || defined(NETATALK)
535 struct llc *l;
536 #endif
537
538 if ((ifp->if_flags & IFF_UP) == 0) {
539 m_freem(m);
540 return;
541 }
542 ifp->if_lastchange = time;
543 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
544 if (eh->ether_dhost[0] & 1) {
545 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
546 sizeof(etherbroadcastaddr)) == 0)
547 m->m_flags |= M_BCAST;
548 else
549 m->m_flags |= M_MCAST;
550 }
551 if (m->m_flags & (M_BCAST|M_MCAST))
552 ifp->if_imcasts++;
553
554 etype = ntohs(eh->ether_type);
555 switch (etype) {
556 #ifdef INET
557 case ETHERTYPE_IP:
558 #ifdef GATEWAY
559 if (ipflow_fastforward(m))
560 return;
561 #endif
562 schednetisr(NETISR_IP);
563 inq = &ipintrq;
564 break;
565
566 case ETHERTYPE_ARP:
567 schednetisr(NETISR_ARP);
568 inq = &arpintrq;
569 break;
570
571 case ETHERTYPE_REVARP:
572 revarpinput(m); /* XXX queue? */
573 return;
574 #endif
575 #ifdef INET6
576 case ETHERTYPE_IPV6:
577 schednetisr(NETISR_IPV6);
578 inq = &ip6intrq;
579 break;
580 #endif
581 #ifdef NS
582 case ETHERTYPE_NS:
583 schednetisr(NETISR_NS);
584 inq = &nsintrq;
585 break;
586
587 #endif
588 #ifdef IPX
589 case ETHERTYPE_IPX:
590 schednetisr(NETISR_IPX);
591 inq = &ipxintrq;
592 break;
593 #endif
594 #ifdef NETATALK
595 case ETHERTYPE_ATALK:
596 schednetisr(NETISR_ATALK);
597 inq = &atintrq1;
598 break;
599 case ETHERTYPE_AARP:
600 /* probably this should be done with a NETISR as well */
601 aarpinput(ifp, m); /* XXX */
602 return;
603 #endif /* NETATALK */
604 default:
605 #if defined (ISO) || defined (LLC) || defined (NETATALK)
606 if (etype > ETHERMTU)
607 goto dropanyway;
608 l = mtod(m, struct llc *);
609 switch (l->llc_dsap) {
610 #ifdef NETATALK
611 case LLC_SNAP_LSAP:
612 switch (l->llc_control) {
613 case LLC_UI:
614 if (l->llc_ssap != LLC_SNAP_LSAP) {
615 goto dropanyway;
616 }
617
618 if (Bcmp(&(l->llc_snap_org_code)[0],
619 at_org_code, sizeof(at_org_code)) == 0 &&
620 ntohs(l->llc_snap_ether_type) ==
621 ETHERTYPE_ATALK) {
622 inq = &atintrq2;
623 m_adj(m, sizeof(struct llc));
624 schednetisr(NETISR_ATALK);
625 break;
626 }
627
628 if (Bcmp(&(l->llc_snap_org_code)[0],
629 aarp_org_code,
630 sizeof(aarp_org_code)) == 0 &&
631 ntohs(l->llc_snap_ether_type) ==
632 ETHERTYPE_AARP) {
633 m_adj( m, sizeof(struct llc));
634 aarpinput(ifp, m); /* XXX */
635 return;
636 }
637
638 default:
639 goto dropanyway;
640 }
641 break;
642 #endif /* NETATALK */
643 #ifdef ISO
644 case LLC_ISO_LSAP:
645 switch (l->llc_control) {
646 case LLC_UI:
647 /* LLC_UI_P forbidden in class 1 service */
648 if ((l->llc_dsap == LLC_ISO_LSAP) &&
649 (l->llc_ssap == LLC_ISO_LSAP)) {
650 /* LSAP for ISO */
651 if (m->m_pkthdr.len > etype)
652 m_adj(m, etype - m->m_pkthdr.len);
653 m->m_data += 3; /* XXX */
654 m->m_len -= 3; /* XXX */
655 m->m_pkthdr.len -= 3; /* XXX */
656 M_PREPEND(m, sizeof *eh, M_DONTWAIT);
657 if (m == 0)
658 return;
659 *mtod(m, struct ether_header *) = *eh;
660 #ifdef ARGO_DEBUG
661 if (argo_debug[D_ETHER])
662 printf("clnp packet");
663 #endif
664 schednetisr(NETISR_ISO);
665 inq = &clnlintrq;
666 break;
667 }
668 goto dropanyway;
669
670 case LLC_XID:
671 case LLC_XID_P:
672 if(m->m_len < 6)
673 goto dropanyway;
674 l->llc_window = 0;
675 l->llc_fid = 9;
676 l->llc_class = 1;
677 l->llc_dsap = l->llc_ssap = 0;
678 /* Fall through to */
679 case LLC_TEST:
680 case LLC_TEST_P:
681 {
682 struct sockaddr sa;
683 struct ether_header *eh2;
684 int i;
685 u_char c = l->llc_dsap;
686
687 l->llc_dsap = l->llc_ssap;
688 l->llc_ssap = c;
689 if (m->m_flags & (M_BCAST | M_MCAST))
690 bcopy(LLADDR(ifp->if_sadl),
691 (caddr_t)eh->ether_dhost, 6);
692 sa.sa_family = AF_UNSPEC;
693 sa.sa_len = sizeof(sa);
694 eh2 = (struct ether_header *)sa.sa_data;
695 for (i = 0; i < 6; i++) {
696 eh2->ether_shost[i] = c =
697 eh->ether_dhost[i];
698 eh2->ether_dhost[i] =
699 eh->ether_dhost[i] =
700 eh->ether_shost[i];
701 eh->ether_shost[i] = c;
702 }
703 ifp->if_output(ifp, m, &sa, NULL);
704 return;
705 }
706 default:
707 m_freem(m);
708 return;
709 }
710 break;
711 #endif /* ISO */
712 #ifdef LLC
713 case LLC_X25_LSAP:
714 {
715 if (m->m_pkthdr.len > etype)
716 m_adj(m, etype - m->m_pkthdr.len);
717 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
718 if (m == 0)
719 return;
720 if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
721 eh->ether_dhost, LLC_X25_LSAP, 6,
722 mtod(m, struct sdl_hdr *)))
723 panic("ETHER cons addr failure");
724 mtod(m, struct sdl_hdr *)->sdlhdr_len = etype;
725 #ifdef LLC_DEBUG
726 printf("llc packet\n");
727 #endif /* LLC_DEBUG */
728 schednetisr(NETISR_CCITT);
729 inq = &llcintrq;
730 break;
731 }
732 #endif /* LLC */
733 dropanyway:
734 default:
735 m_freem(m);
736 return;
737 }
738 #else /* ISO || LLC || NETATALK*/
739 m_freem(m);
740 return;
741 #endif /* ISO || LLC || NETATALK*/
742 }
743
744 s = splimp();
745 if (IF_QFULL(inq)) {
746 IF_DROP(inq);
747 m_freem(m);
748 } else
749 IF_ENQUEUE(inq, m);
750 splx(s);
751 }
752
753 /*
754 * Convert Ethernet address to printable (loggable) representation.
755 */
756 static char digits[] = "0123456789abcdef";
757 char *
758 ether_sprintf(ap)
759 const u_char *ap;
760 {
761 static char etherbuf[18];
762 char *cp = etherbuf;
763 int i;
764
765 for (i = 0; i < 6; i++) {
766 *cp++ = digits[*ap >> 4];
767 *cp++ = digits[*ap++ & 0xf];
768 *cp++ = ':';
769 }
770 *--cp = 0;
771 return (etherbuf);
772 }
773
774 /*
775 * Perform common duties while attaching to interface list
776 */
777 void
778 ether_ifattach(ifp, lla)
779 struct ifnet *ifp;
780 const u_int8_t *lla;
781 {
782 struct sockaddr_dl *sdl;
783
784 ifp->if_type = IFT_ETHER;
785 ifp->if_addrlen = 6;
786 ifp->if_hdrlen = 14;
787 ifp->if_mtu = ETHERMTU;
788 ifp->if_output = ether_output;
789 if ((sdl = ifp->if_sadl) &&
790 sdl->sdl_family == AF_LINK) {
791 sdl->sdl_type = IFT_ETHER;
792 sdl->sdl_alen = ifp->if_addrlen;
793 bcopy(lla, LLADDR(sdl), ifp->if_addrlen);
794 }
795 LIST_INIT(&((struct ethercom *)ifp)->ec_multiaddrs);
796 ifp->if_broadcastaddr = etherbroadcastaddr;
797 #ifdef INET6
798 in6_ifattach_getifid(ifp);
799 #endif
800 }
801
802 u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
803 u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
804 #ifdef INET6
805 u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
806 u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
807 #endif
808 /*
809 * Add an Ethernet multicast address or range of addresses to the list for a
810 * given interface.
811 */
812 int
813 ether_addmulti(ifr, ec)
814 struct ifreq *ifr;
815 struct ethercom *ec;
816 {
817 struct ether_multi *enm;
818 #ifdef INET
819 struct sockaddr_in *sin;
820 #endif /* INET */
821 #ifdef INET6
822 struct sockaddr_in6 *sin6;
823 #endif /* INET6 */
824 u_char addrlo[6];
825 u_char addrhi[6];
826 int s = splimp();
827
828 switch (ifr->ifr_addr.sa_family) {
829
830 case AF_UNSPEC:
831 bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
832 bcopy(addrlo, addrhi, 6);
833 break;
834
835 #ifdef INET
836 case AF_INET:
837 sin = (struct sockaddr_in *)&(ifr->ifr_addr);
838 if (sin->sin_addr.s_addr == INADDR_ANY) {
839 /*
840 * An IP address of INADDR_ANY means listen to all
841 * of the Ethernet multicast addresses used for IP.
842 * (This is for the sake of IP multicast routers.)
843 */
844 bcopy(ether_ipmulticast_min, addrlo, 6);
845 bcopy(ether_ipmulticast_max, addrhi, 6);
846 }
847 else {
848 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
849 bcopy(addrlo, addrhi, 6);
850 }
851 break;
852 #endif
853 #ifdef INET6
854 case AF_INET6:
855 sin6 = (struct sockaddr_in6 *)
856 &(((struct in6_ifreq *)ifr)->ifr_addr);
857 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
858 /*
859 * An IP6 address of 0 means listen to all
860 * of the Ethernet multicast address used for IP6.
861 * (This is used for multicast routers.)
862 */
863 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
864 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
865 #if 0
866 set_allmulti = 1;
867 #endif
868 } else {
869 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
870 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
871 }
872 break;
873 #endif
874
875 default:
876 splx(s);
877 return (EAFNOSUPPORT);
878 }
879
880 /*
881 * Verify that we have valid Ethernet multicast addresses.
882 */
883 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
884 splx(s);
885 return (EINVAL);
886 }
887 /*
888 * See if the address range is already in the list.
889 */
890 ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm);
891 if (enm != NULL) {
892 /*
893 * Found it; just increment the reference count.
894 */
895 ++enm->enm_refcount;
896 splx(s);
897 return (0);
898 }
899 /*
900 * New address or range; malloc a new multicast record
901 * and link it into the interface's multicast list.
902 */
903 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
904 if (enm == NULL) {
905 splx(s);
906 return (ENOBUFS);
907 }
908 bcopy(addrlo, enm->enm_addrlo, 6);
909 bcopy(addrhi, enm->enm_addrhi, 6);
910 enm->enm_ec = ec;
911 enm->enm_refcount = 1;
912 LIST_INSERT_HEAD(&ec->ec_multiaddrs, enm, enm_list);
913 ec->ec_multicnt++;
914 splx(s);
915 /*
916 * Return ENETRESET to inform the driver that the list has changed
917 * and its reception filter should be adjusted accordingly.
918 */
919 return (ENETRESET);
920 }
921
922 /*
923 * Delete a multicast address record.
924 */
925 int
926 ether_delmulti(ifr, ec)
927 struct ifreq *ifr;
928 struct ethercom *ec;
929 {
930 struct ether_multi *enm;
931 #ifdef INET
932 struct sockaddr_in *sin;
933 #endif /* INET */
934 #ifdef INET6
935 struct sockaddr_in6 *sin6;
936 #endif /* INET6 */
937 u_char addrlo[6];
938 u_char addrhi[6];
939 int s = splimp();
940
941 switch (ifr->ifr_addr.sa_family) {
942
943 case AF_UNSPEC:
944 bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
945 bcopy(addrlo, addrhi, 6);
946 break;
947
948 #ifdef INET
949 case AF_INET:
950 sin = (struct sockaddr_in *)&(ifr->ifr_addr);
951 if (sin->sin_addr.s_addr == INADDR_ANY) {
952 /*
953 * An IP address of INADDR_ANY means stop listening
954 * to the range of Ethernet multicast addresses used
955 * for IP.
956 */
957 bcopy(ether_ipmulticast_min, addrlo, 6);
958 bcopy(ether_ipmulticast_max, addrhi, 6);
959 }
960 else {
961 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
962 bcopy(addrlo, addrhi, 6);
963 }
964 break;
965 #endif
966 #ifdef INET6
967 case AF_INET6:
968 sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
969 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
970 /*
971 * An IP6 address of all 0 means stop listening
972 * to the range of Ethernet multicast addresses used
973 * for IP6
974 */
975 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
976 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
977 } else {
978 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
979 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
980 }
981 break;
982 #endif
983
984 default:
985 splx(s);
986 return (EAFNOSUPPORT);
987 }
988
989 /*
990 * Look up the address in our list.
991 */
992 ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm);
993 if (enm == NULL) {
994 splx(s);
995 return (ENXIO);
996 }
997 if (--enm->enm_refcount != 0) {
998 /*
999 * Still some claims to this record.
1000 */
1001 splx(s);
1002 return (0);
1003 }
1004 /*
1005 * No remaining claims to this record; unlink and free it.
1006 */
1007 LIST_REMOVE(enm, enm_list);
1008 free(enm, M_IFMADDR);
1009 ec->ec_multicnt--;
1010 splx(s);
1011 /*
1012 * Return ENETRESET to inform the driver that the list has changed
1013 * and its reception filter should be adjusted accordingly.
1014 */
1015 return (ENETRESET);
1016 }
1017