xref: /freebsd/sys/net/if_ethersubr.c (revision a14a0223ae1b172e96dd2a1d849e22026a98b692)
1 /*
2  * Copyright (c) 1982, 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)if_ethersubr.c	8.1 (Berkeley) 6/10/93
34  * $FreeBSD$
35  */
36 
37 #include "opt_atalk.h"
38 #include "opt_inet.h"
39 #include "opt_ipx.h"
40 #include "opt_bdg.h"
41 #include "opt_netgraph.h"
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/mbuf.h>
48 #include <sys/socket.h>
49 #include <sys/sockio.h>
50 #include <sys/sysctl.h>
51 
52 #include <net/if.h>
53 #include <net/netisr.h>
54 #include <net/route.h>
55 #include <net/if_llc.h>
56 #include <net/if_dl.h>
57 #include <net/if_types.h>
58 
59 #ifdef INET
60 #include <netinet/in.h>
61 #include <netinet/in_var.h>
62 #include <netinet/if_ether.h>
63 #endif
64 
65 #ifdef IPX
66 #include <netipx/ipx.h>
67 #include <netipx/ipx_if.h>
68 #endif
69 
70 #ifdef NS
71 #include <netns/ns.h>
72 #include <netns/ns_if.h>
73 ushort ns_nettype;
74 int ether_outputdebug = 0;
75 int ether_inputdebug = 0;
76 #endif
77 
78 #ifdef ISO
79 #include <netiso/argo_debug.h>
80 #include <netiso/iso.h>
81 #include <netiso/iso_var.h>
82 #include <netiso/iso_snpac.h>
83 #endif
84 
85 /*#ifdef LLC
86 #include <netccitt/dll.h>
87 #include <netccitt/llc_var.h>
88 #endif*/
89 
90 #if defined(LLC) && defined(CCITT)
91 extern struct ifqueue pkintrq;
92 #endif
93 
94 #ifdef NETATALK
95 #include <netatalk/at.h>
96 #include <netatalk/at_var.h>
97 #include <netatalk/at_extern.h>
98 
99 #define llc_snap_org_code llc_un.type_snap.org_code
100 #define llc_snap_ether_type llc_un.type_snap.ether_type
101 
102 extern u_char	at_org_code[3];
103 extern u_char	aarp_org_code[3];
104 #endif /* NETATALK */
105 
106 #ifdef BRIDGE
107 #include <net/bridge.h>
108 #endif
109 
110 #include "vlan.h"
111 #if NVLAN > 0
112 #include <net/if_vlan_var.h>
113 #endif /* NVLAN > 0 */
114 
115 static	int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
116 				    struct sockaddr *));
117 u_char	etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
118 #define senderr(e) do { error = (e); goto bad;} while (0)
119 #define IFP2AC(IFP) ((struct arpcom *)IFP)
120 
121 #ifdef NETGRAPH
122 #include <netgraph/ng_ether.h>
123 #include <netgraph/ng_message.h>
124 #include <netgraph/netgraph.h>
125 
126 static	void	ngether_init(void* ignored);
127 static void	ngether_send(struct arpcom *ac,
128 			struct ether_header *eh, struct mbuf *m);
129 static	ng_constructor_t	ngether_constructor;
130 static	ng_rcvmsg_t		ngether_rcvmsg;
131 static	ng_shutdown_t		ngether_rmnode;
132 static	ng_newhook_t		ngether_newhook;
133 static	ng_connect_t		ngether_connect;
134 static	ng_rcvdata_t		ngether_rcvdata;
135 static	ng_disconnect_t		ngether_disconnect;
136 
137 static struct ng_type typestruct = {
138 	NG_VERSION,
139 	NG_ETHER_NODE_TYPE,
140 	NULL,
141 	ngether_constructor,
142 	ngether_rcvmsg,
143 	ngether_rmnode,
144 	ngether_newhook,
145 	NULL,
146 	ngether_connect,
147 	ngether_rcvdata,
148 	ngether_rcvdata,
149 	ngether_disconnect
150 };
151 
152 #define AC2NG(AC) ((node_p)((AC)->ac_ng))
153 #define NGEF_DIVERT NGF_TYPE1	/* all packets sent to netgraph */
154 #endif /* NETGRAPH */
155 
156 /*
157  * Ethernet output routine.
158  * Encapsulate a packet of type family for the local net.
159  * Use trailer local net encapsulation if enough data in first
160  * packet leaves a multiple of 512 bytes of data in remainder.
161  * Assumes that ifp is actually pointer to arpcom structure.
162  */
163 int
164 ether_output(ifp, m0, dst, rt0)
165 	register struct ifnet *ifp;
166 	struct mbuf *m0;
167 	struct sockaddr *dst;
168 	struct rtentry *rt0;
169 {
170 	short type;
171 	int s, error = 0, hdrcmplt = 0;
172  	u_char esrc[6], edst[6];
173 	register struct mbuf *m = m0;
174 	register struct rtentry *rt;
175 	register struct ether_header *eh;
176 	int off, len = m->m_pkthdr.len, loop_copy = 0;
177 	int hlen;	/* link layer header lenght */
178 	struct arpcom *ac = IFP2AC(ifp);
179 
180 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
181 		senderr(ENETDOWN);
182 	rt = rt0;
183 	if (rt) {
184 		if ((rt->rt_flags & RTF_UP) == 0) {
185 			rt0 = rt = rtalloc1(dst, 1, 0UL);
186 			if (rt0)
187 				rt->rt_refcnt--;
188 			else
189 				senderr(EHOSTUNREACH);
190 		}
191 		if (rt->rt_flags & RTF_GATEWAY) {
192 			if (rt->rt_gwroute == 0)
193 				goto lookup;
194 			if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
195 				rtfree(rt); rt = rt0;
196 			lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
197 							  0UL);
198 				if ((rt = rt->rt_gwroute) == 0)
199 					senderr(EHOSTUNREACH);
200 			}
201 		}
202 		if (rt->rt_flags & RTF_REJECT)
203 			if (rt->rt_rmx.rmx_expire == 0 ||
204 			    time_second < rt->rt_rmx.rmx_expire)
205 				senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
206 	}
207 	hlen = ETHER_HDR_LEN;
208 	switch (dst->sa_family) {
209 #ifdef INET
210 	case AF_INET:
211 		if (!arpresolve(ac, rt, m, dst, edst, rt0))
212 			return (0);	/* if not yet resolved */
213 		off = m->m_pkthdr.len - m->m_len;
214 		type = htons(ETHERTYPE_IP);
215 		break;
216 #endif
217 #ifdef IPX
218 	case AF_IPX:
219 		type = htons(ETHERTYPE_IPX);
220  		bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
221 		    (caddr_t)edst, sizeof (edst));
222 		break;
223 #endif
224 #ifdef NETATALK
225 	case AF_APPLETALK:
226 	  {
227 	    struct at_ifaddr *aa;
228 
229 	    if ((aa = at_ifawithnet((struct sockaddr_at *)dst)) == NULL) {
230 		    goto bad;
231 	    }
232 	    if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst))
233 		    return (0);
234 	    /*
235 	     * In the phase 2 case, need to prepend an mbuf for the llc header.
236 	     * Since we must preserve the value of m, which is passed to us by
237 	     * value, we m_copy() the first mbuf, and use it for our llc header.
238 	     */
239 	    if ( aa->aa_flags & AFA_PHASE2 ) {
240 		struct llc llc;
241 
242 		M_PREPEND(m, sizeof(struct llc), M_WAIT);
243 		len += sizeof(struct llc);
244 		llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
245 		llc.llc_control = LLC_UI;
246 		bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code));
247 		llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
248 		bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
249 		type = htons(m->m_pkthdr.len);
250 		hlen = sizeof(struct llc) + ETHER_HDR_LEN;
251 	    } else {
252 		type = htons(ETHERTYPE_AT);
253 	    }
254 	    break;
255 	  }
256 #endif NETATALK
257 #ifdef NS
258 	case AF_NS:
259 		switch(ns_nettype){
260 		default:
261 		case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
262 			type = 0x8137;
263 			break;
264 		case 0x0: /* Novell 802.3 */
265 			type = htons( m->m_pkthdr.len);
266 			break;
267 		case 0xe0e0: /* Novell 802.2 and Token-Ring */
268 			M_PREPEND(m, 3, M_WAIT);
269 			type = htons( m->m_pkthdr.len);
270 			cp = mtod(m, u_char *);
271 			*cp++ = 0xE0;
272 			*cp++ = 0xE0;
273 			*cp++ = 0x03;
274 			break;
275 		}
276  		bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
277 		    (caddr_t)edst, sizeof (edst));
278 		/*
279 		 * XXX if ns_thishost is the same as the node's ethernet
280 		 * address then just the default code will catch this anyhow.
281 		 * So I'm not sure if this next clause should be here at all?
282 		 * [JRE]
283 		 */
284 		if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){
285 			m->m_pkthdr.rcvif = ifp;
286 			schednetisr(NETISR_NS);
287 			inq = &nsintrq;
288 			s = splimp();
289 			if (IF_QFULL(inq)) {
290 				IF_DROP(inq);
291 				m_freem(m);
292 			} else
293 				IF_ENQUEUE(inq, m);
294 			splx(s);
295 			return (error);
296 		}
297 		if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){
298 			m->m_flags |= M_BCAST;
299 		}
300 		break;
301 #endif /* NS */
302 #ifdef	ISO
303 	case AF_ISO: {
304 		int	snpalen;
305 		struct	llc *l;
306 		register struct sockaddr_dl *sdl;
307 
308 		if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
309 		    sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
310 			bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
311 		} else if (error =
312 			    iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
313 					    (char *)edst, &snpalen))
314 			goto bad; /* Not Resolved */
315 		/* If broadcasting on a simplex interface, loopback a copy */
316 		if (*edst & 1)
317 			m->m_flags |= (M_BCAST|M_MCAST);
318 		M_PREPEND(m, 3, M_DONTWAIT);
319 		if (m == NULL)
320 			return (0);
321 		type = htons(m->m_pkthdr.len);
322 		l = mtod(m, struct llc *);
323 		l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
324 		l->llc_control = LLC_UI;
325 		len += 3;
326 		IFDEBUG(D_ETHER)
327 			int i;
328 			printf("unoutput: sending pkt to: ");
329 			for (i=0; i<6; i++)
330 				printf("%x ", edst[i] & 0xff);
331 			printf("\n");
332 		ENDDEBUG
333 		} break;
334 #endif /* ISO */
335 #ifdef	LLC
336 /*	case AF_NSAP: */
337 	case AF_CCITT: {
338 		register struct sockaddr_dl *sdl =
339 			(struct sockaddr_dl *) rt -> rt_gateway;
340 
341 		if (sdl && sdl->sdl_family == AF_LINK
342 		    && sdl->sdl_alen > 0) {
343 			bcopy(LLADDR(sdl), (char *)edst, sizeof(edst));
344 		} else goto bad; /* Not a link interface ? Funny ... */
345 		if (*edst & 1)
346 			loop_copy = 1;
347 		type = htons(m->m_pkthdr.len);
348 #ifdef LLC_DEBUG
349 		{
350 			int i;
351 			register struct llc *l = mtod(m, struct llc *);
352 
353 			printf("ether_output: sending LLC2 pkt to: ");
354 			for (i=0; i<6; i++)
355 				printf("%x ", edst[i] & 0xff);
356 			printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
357 			       type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff,
358 			       l->llc_control & 0xff);
359 
360 		}
361 #endif /* LLC_DEBUG */
362 		} break;
363 #endif /* LLC */
364 
365 	case pseudo_AF_HDRCMPLT:
366 		hdrcmplt = 1;
367 		eh = (struct ether_header *)dst->sa_data;
368 		(void)memcpy(esrc, eh->ether_shost, sizeof (esrc));
369 		/* FALLTHROUGH */
370 
371 	case AF_UNSPEC:
372 		loop_copy = -1; /* if this is for us, don't do it */
373 		eh = (struct ether_header *)dst->sa_data;
374  		(void)memcpy(edst, eh->ether_dhost, sizeof (edst));
375 		type = eh->ether_type;
376 		break;
377 
378 	default:
379 		printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
380 			dst->sa_family);
381 		senderr(EAFNOSUPPORT);
382 	}
383 
384 	/*
385 	 * Add local net header.  If no space in first mbuf,
386 	 * allocate another.
387 	 */
388 	M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
389 	if (m == 0)
390 		senderr(ENOBUFS);
391 	eh = mtod(m, struct ether_header *);
392 	(void)memcpy(&eh->ether_type, &type,
393 		sizeof(eh->ether_type));
394  	(void)memcpy(eh->ether_dhost, edst, sizeof (edst));
395 	if (hdrcmplt)
396 		(void)memcpy(eh->ether_shost, esrc,
397 			sizeof(eh->ether_shost));
398 	else
399 		(void)memcpy(eh->ether_shost, ac->ac_enaddr,
400 			sizeof(eh->ether_shost));
401 
402 	/*
403 	 * If a simplex interface, and the packet is being sent to our
404 	 * Ethernet address or a broadcast address, loopback a copy.
405 	 * XXX To make a simplex device behave exactly like a duplex
406 	 * device, we should copy in the case of sending to our own
407 	 * ethernet address (thus letting the original actually appear
408 	 * on the wire). However, we don't do that here for security
409 	 * reasons and compatibility with the original behavior.
410 	 */
411 	if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) {
412 		if ((m->m_flags & M_BCAST) || (loop_copy > 0)) {
413 			struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
414 
415 			(void) if_simloop(ifp, n, dst, hlen);
416 		} else if (bcmp(eh->ether_dhost,
417 		    eh->ether_shost, ETHER_ADDR_LEN) == 0) {
418 			(void) if_simloop(ifp, m, dst, hlen);
419 			return (0);	/* XXX */
420 		}
421 	}
422 #ifdef BRIDGE
423 	if (do_bridge) {
424 		struct mbuf *m0 = m ;
425 
426 		if (m->m_pkthdr.rcvif)
427 			m->m_pkthdr.rcvif = NULL ;
428 		ifp = bridge_dst_lookup(m);
429 		bdg_forward(&m0, ifp);
430 		if (m0)
431 			m_freem(m0);
432 		return (0);
433 	}
434 #endif
435 	s = splimp();
436 	/*
437 	 * Queue message on interface, and start output if interface
438 	 * not yet active.
439 	 */
440 	if (IF_QFULL(&ifp->if_snd)) {
441 		IF_DROP(&ifp->if_snd);
442 		splx(s);
443 		senderr(ENOBUFS);
444 	}
445 	IF_ENQUEUE(&ifp->if_snd, m);
446 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
447 		(*ifp->if_start)(ifp);
448 	splx(s);
449 	ifp->if_obytes += len + sizeof (struct ether_header);
450 	if (m->m_flags & M_MCAST)
451 		ifp->if_omcasts++;
452 	return (error);
453 
454 bad:
455 	if (m)
456 		m_freem(m);
457 	return (error);
458 }
459 
460 /*
461  * Process a received Ethernet packet;
462  * the packet is in the mbuf chain m without
463  * the ether header, which is provided separately.
464  */
465 void
466 ether_input(ifp, eh, m)
467 	struct ifnet *ifp;
468 	register struct ether_header *eh;
469 	struct mbuf *m;
470 {
471 	register struct ifqueue *inq;
472 	u_short ether_type;
473 	int s;
474 #if defined (ISO) || defined (LLC) || defined(NETATALK)
475 	register struct llc *l;
476 #endif
477 
478 	if ((ifp->if_flags & IFF_UP) == 0) {
479 		m_freem(m);
480 		return;
481 	}
482 	ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
483 	if (eh->ether_dhost[0] & 1) {
484 		if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
485 			 sizeof(etherbroadcastaddr)) == 0)
486 			m->m_flags |= M_BCAST;
487 		else
488 			m->m_flags |= M_MCAST;
489 	}
490 	if (m->m_flags & (M_BCAST|M_MCAST))
491 		ifp->if_imcasts++;
492 
493 	ether_type = ntohs(eh->ether_type);
494 
495 #ifdef	NETGRAPH
496 	{
497 		struct arpcom *ac = IFP2AC(ifp);
498 		if (AC2NG(ac) && (AC2NG(ac)->flags & NGEF_DIVERT)) {
499 			ngether_send(ac, eh, m);
500 			return;
501 		}
502 	}
503 #endif	/* NETGRAPH */
504 
505 #if NVLAN > 0
506 	if (ether_type == vlan_proto) {
507 		if (vlan_input(eh, m) < 0)
508 			ifp->if_data.ifi_noproto++;
509 		return;
510 	}
511 #endif /* NVLAN > 0 */
512 
513 	switch (ether_type) {
514 #ifdef INET
515 	case ETHERTYPE_IP:
516 		if (ipflow_fastforward(m))
517 			return;
518 		schednetisr(NETISR_IP);
519 		inq = &ipintrq;
520 		break;
521 
522 	case ETHERTYPE_ARP:
523 		schednetisr(NETISR_ARP);
524 		inq = &arpintrq;
525 		break;
526 #endif
527 #ifdef IPX
528 	case ETHERTYPE_IPX:
529 		schednetisr(NETISR_IPX);
530 		inq = &ipxintrq;
531 		break;
532 #endif
533 #ifdef NS
534 	case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
535 		schednetisr(NETISR_NS);
536 		inq = &nsintrq;
537 		break;
538 
539 #endif /* NS */
540 #ifdef NETATALK
541         case ETHERTYPE_AT:
542                 schednetisr(NETISR_ATALK);
543                 inq = &atintrq1;
544                 break;
545         case ETHERTYPE_AARP:
546 		/* probably this should be done with a NETISR as well */
547                 aarpinput(IFP2AC(ifp), m); /* XXX */
548                 return;
549 #endif NETATALK
550 	default:
551 #ifdef NS
552 		checksum = mtod(m, ushort *);
553 		/* Novell 802.3 */
554 		if ((ether_type <= ETHERMTU) &&
555 			((*checksum == 0xffff) || (*checksum == 0xE0E0))){
556 			if(*checksum == 0xE0E0) {
557 				m->m_pkthdr.len -= 3;
558 				m->m_len -= 3;
559 				m->m_data += 3;
560 			}
561 				schednetisr(NETISR_NS);
562 				inq = &nsintrq;
563 				break;
564 		}
565 #endif /* NS */
566 #if defined (ISO) || defined (LLC) || defined(NETATALK)
567 		if (ether_type > ETHERMTU)
568 			goto dropanyway;
569 		l = mtod(m, struct llc *);
570 		switch (l->llc_dsap) {
571 #ifdef NETATALK
572 		case LLC_SNAP_LSAP:
573 		    switch (l->llc_control) {
574 		    case LLC_UI:
575 			if (l->llc_ssap != LLC_SNAP_LSAP)
576 			    goto dropanyway;
577 
578 			if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,
579 				   sizeof(at_org_code)) == 0 &&
580 			     ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
581 			    inq = &atintrq2;
582 			    m_adj( m, sizeof( struct llc ));
583 			    schednetisr(NETISR_ATALK);
584 			    break;
585 			}
586 
587 			if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
588 				   sizeof(aarp_org_code)) == 0 &&
589 			     ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
590 			    m_adj( m, sizeof( struct llc ));
591 			    aarpinput(IFP2AC(ifp), m); /* XXX */
592 			    return;
593 			}
594 
595 		    default:
596 			goto dropanyway;
597 		    }
598 		    break;
599 #endif NETATALK
600 #ifdef	ISO
601 		case LLC_ISO_LSAP:
602 			switch (l->llc_control) {
603 			case LLC_UI:
604 				/* LLC_UI_P forbidden in class 1 service */
605 				if ((l->llc_dsap == LLC_ISO_LSAP) &&
606 				    (l->llc_ssap == LLC_ISO_LSAP)) {
607 					/* LSAP for ISO */
608 					if (m->m_pkthdr.len > ether_type)
609 						m_adj(m, ether_type - m->m_pkthdr.len);
610 					m->m_data += 3;		/* XXX */
611 					m->m_len -= 3;		/* XXX */
612 					m->m_pkthdr.len -= 3;	/* XXX */
613 					M_PREPEND(m, sizeof *eh, M_DONTWAIT);
614 					if (m == 0)
615 						return;
616 					*mtod(m, struct ether_header *) = *eh;
617 					IFDEBUG(D_ETHER)
618 						printf("clnp packet");
619 					ENDDEBUG
620 					schednetisr(NETISR_ISO);
621 					inq = &clnlintrq;
622 					break;
623 				}
624 				goto dropanyway;
625 
626 			case LLC_XID:
627 			case LLC_XID_P:
628 				if(m->m_len < 6)
629 					goto dropanyway;
630 				l->llc_window = 0;
631 				l->llc_fid = 9;
632 				l->llc_class = 1;
633 				l->llc_dsap = l->llc_ssap = 0;
634 				/* Fall through to */
635 			case LLC_TEST:
636 			case LLC_TEST_P:
637 			{
638 				struct sockaddr sa;
639 				register struct ether_header *eh2;
640 				int i;
641 				u_char c = l->llc_dsap;
642 
643 				l->llc_dsap = l->llc_ssap;
644 				l->llc_ssap = c;
645 				if (m->m_flags & (M_BCAST | M_MCAST))
646 					bcopy((caddr_t)ac->ac_enaddr,
647 					      (caddr_t)eh->ether_dhost, 6);
648 				sa.sa_family = AF_UNSPEC;
649 				sa.sa_len = sizeof(sa);
650 				eh2 = (struct ether_header *)sa.sa_data;
651 				for (i = 0; i < 6; i++) {
652 					eh2->ether_shost[i] = c = eh->ether_dhost[i];
653 					eh2->ether_dhost[i] =
654 						eh->ether_dhost[i] = eh->ether_shost[i];
655 					eh->ether_shost[i] = c;
656 				}
657 				ifp->if_output(ifp, m, &sa, NULL);
658 				return;
659 			}
660 			default:
661 				m_freem(m);
662 				return;
663 			}
664 			break;
665 #endif /* ISO */
666 #ifdef LLC
667 		case LLC_X25_LSAP:
668 		{
669 			if (m->m_pkthdr.len > ether_type)
670 				m_adj(m, ether_type - m->m_pkthdr.len);
671 			M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
672 			if (m == 0)
673 				return;
674 			if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
675 					    eh->ether_dhost, LLC_X25_LSAP, 6,
676 					    mtod(m, struct sdl_hdr *)))
677 				panic("ETHER cons addr failure");
678 			mtod(m, struct sdl_hdr *)->sdlhdr_len = ether_type;
679 #ifdef LLC_DEBUG
680 				printf("llc packet\n");
681 #endif /* LLC_DEBUG */
682 			schednetisr(NETISR_CCITT);
683 			inq = &llcintrq;
684 			break;
685 		}
686 #endif /* LLC */
687 		dropanyway:
688 		default:
689 #ifdef	NETGRAPH
690 			ngether_send(IFP2AC(ifp), eh, m);
691 #else	/* NETGRAPH */
692 			m_freem(m);
693 #endif	/* NETGRAPH */
694 			return;
695 		}
696 #else /* ISO || LLC || NETATALK */
697 #ifdef	NETGRAPH
698 	    ngether_send(IFP2AC(ifp), eh, m);
699 #else	/* NETGRAPH */
700 	    m_freem(m);
701 #endif	/* NETGRAPH */
702 	    return;
703 #endif /* ISO || LLC || NETATALK */
704 	}
705 
706 	s = splimp();
707 	if (IF_QFULL(inq)) {
708 		IF_DROP(inq);
709 		m_freem(m);
710 	} else
711 		IF_ENQUEUE(inq, m);
712 	splx(s);
713 }
714 
715 /*
716  * Perform common duties while attaching to interface list
717  */
718 void
719 ether_ifattach(ifp)
720 	register struct ifnet *ifp;
721 {
722 	register struct ifaddr *ifa;
723 	register struct sockaddr_dl *sdl;
724 
725 	ifp->if_type = IFT_ETHER;
726 	ifp->if_addrlen = 6;
727 	ifp->if_hdrlen = 14;
728 	ifp->if_mtu = ETHERMTU;
729 	ifp->if_resolvemulti = ether_resolvemulti;
730 	if (ifp->if_baudrate == 0)
731 	    ifp->if_baudrate = 10000000;
732 	ifa = ifnet_addrs[ifp->if_index - 1];
733 	if (ifa == 0) {
734 		printf("ether_ifattach: no lladdr!\n");
735 		return;
736 	}
737 	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
738 	sdl->sdl_type = IFT_ETHER;
739 	sdl->sdl_alen = ifp->if_addrlen;
740 	bcopy((IFP2AC(ifp))->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
741 #ifdef	NETGRAPH
742 	ngether_init(ifp);
743 #endif /* NETGRAPH */
744 }
745 
746 SYSCTL_DECL(_net_link);
747 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
748 
749 int
750 ether_ioctl(ifp, command, data)
751 	struct ifnet *ifp;
752 	int command;
753 	caddr_t data;
754 {
755 	struct ifaddr *ifa = (struct ifaddr *) data;
756 	struct ifreq *ifr = (struct ifreq *) data;
757 	int error = 0;
758 
759 	switch (command) {
760 	case SIOCSIFADDR:
761 		ifp->if_flags |= IFF_UP;
762 
763 		switch (ifa->ifa_addr->sa_family) {
764 #ifdef INET
765 		case AF_INET:
766 			ifp->if_init(ifp->if_softc);	/* before arpwhohas */
767 			arp_ifinit(IFP2AC(ifp), ifa);
768 			break;
769 #endif
770 #ifdef IPX
771 		/*
772 		 * XXX - This code is probably wrong
773 		 */
774 		case AF_IPX:
775 			{
776 			register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
777 			struct arpcom *ac = IFP2AC(ifp);
778 
779 			if (ipx_nullhost(*ina))
780 				ina->x_host =
781 				    *(union ipx_host *)
782 			            ac->ac_enaddr;
783 			else {
784 				bcopy((caddr_t) ina->x_host.c_host,
785 				      (caddr_t) ac->ac_enaddr,
786 				      sizeof(ac->ac_enaddr));
787 			}
788 
789 			/*
790 			 * Set new address
791 			 */
792 			ifp->if_init(ifp->if_softc);
793 			break;
794 			}
795 #endif
796 #ifdef NS
797 		/*
798 		 * XXX - This code is probably wrong
799 		 */
800 		case AF_NS:
801 		{
802 			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
803 			struct arpcom *ac = IFP2AC(ifp);
804 
805 			if (ns_nullhost(*ina))
806 				ina->x_host =
807 				    *(union ns_host *) (ac->ac_enaddr);
808 			else {
809 				bcopy((caddr_t) ina->x_host.c_host,
810 				      (caddr_t) ac->ac_enaddr,
811 				      sizeof(ac->ac_enaddr));
812 			}
813 
814 			/*
815 			 * Set new address
816 			 */
817 			ifp->if_init(ifp->if_softc);
818 			break;
819 		}
820 #endif
821 		default:
822 			ifp->if_init(ifp->if_softc);
823 			break;
824 		}
825 		break;
826 
827 	case SIOCGIFADDR:
828 		{
829 			struct sockaddr *sa;
830 
831 			sa = (struct sockaddr *) & ifr->ifr_data;
832 			bcopy(IFP2AC(ifp)->ac_enaddr,
833 			      (caddr_t) sa->sa_data, ETHER_ADDR_LEN);
834 		}
835 		break;
836 
837 	case SIOCSIFMTU:
838 		/*
839 		 * Set the interface MTU.
840 		 */
841 		if (ifr->ifr_mtu > ETHERMTU) {
842 			error = EINVAL;
843 		} else {
844 			ifp->if_mtu = ifr->ifr_mtu;
845 		}
846 		break;
847 	}
848 	return (error);
849 }
850 
851 int
852 ether_resolvemulti(ifp, llsa, sa)
853 	struct ifnet *ifp;
854 	struct sockaddr **llsa;
855 	struct sockaddr *sa;
856 {
857 	struct sockaddr_dl *sdl;
858 	struct sockaddr_in *sin;
859 	u_char *e_addr;
860 
861 	switch(sa->sa_family) {
862 	case AF_LINK:
863 		/*
864 		 * No mapping needed. Just check that it's a valid MC address.
865 		 */
866 		sdl = (struct sockaddr_dl *)sa;
867 		e_addr = LLADDR(sdl);
868 		if ((e_addr[0] & 1) != 1)
869 			return EADDRNOTAVAIL;
870 		*llsa = 0;
871 		return 0;
872 
873 #ifdef INET
874 	case AF_INET:
875 		sin = (struct sockaddr_in *)sa;
876 		if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
877 			return EADDRNOTAVAIL;
878 		MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
879 		       M_WAITOK);
880 		sdl->sdl_len = sizeof *sdl;
881 		sdl->sdl_family = AF_LINK;
882 		sdl->sdl_index = ifp->if_index;
883 		sdl->sdl_type = IFT_ETHER;
884 		sdl->sdl_nlen = 0;
885 		sdl->sdl_alen = ETHER_ADDR_LEN;
886 		sdl->sdl_slen = 0;
887 		e_addr = LLADDR(sdl);
888 		ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr);
889 		*llsa = (struct sockaddr *)sdl;
890 		return 0;
891 #endif
892 
893 	default:
894 		/*
895 		 * Well, the text isn't quite right, but it's the name
896 		 * that counts...
897 		 */
898 		return EAFNOSUPPORT;
899 	}
900 }
901 
902 #ifdef	NETGRAPH
903 
904 /***********************************************************************
905  * This section contains the methods for the Netgraph interface
906  ***********************************************************************/
907 /* It's Ascii-art time!
908  * The ifnet is the first part of the arpcom which must be
909  * the first part of the device's softc.. yuk.
910  *
911  *      +--------------------------+-----+---------+
912  *      |   struct ifnet (*ifp)    |     |         |
913  *      |                          |     |         |
914  *      +--------------------------+     |         |
915  *   +--|[ac_ng]     struct arpcom (*ac) |         |
916  *   |  +--------------------------------+         |
917  *   |  |   struct softc (*ifp->if_softc) (device) |
918  *   |  +------------------------------------------+
919  *   |               ^
920  * AC2NG()           |
921  *   |               v
922  *   |       +----------------------+
923  *   |       |   [private] [flags]  |
924  *   +------>| struct ng_node       |
925  *           |    [hooks]           | ** we only allow one hook
926  *           +----------------------+
927  *                   ^
928  *                   |
929  *                   v
930  *           +-------------+
931  *           |    [node]   |
932  *           |    hook     |
933  *           |    [private]|-- *unused*
934  *           +-------------+
935  */
936 
937 /*
938  * called during interface attaching
939  */
940 static void
941 ngether_init(void *ifpvoid)
942 {
943 	struct	ifnet *ifp = ifpvoid;
944 	struct arpcom *ac = IFP2AC(ifp);
945 	static int	ngether_done_init;
946 	char	namebuf[32];
947 	node_p node;
948 
949 	/*
950 	 * we have found a node, make sure our 'type' is availabe.
951 	 */
952 	if (ngether_done_init == 0) {
953 		if (ng_newtype(&typestruct)) {
954 			printf("ngether install failed\n");
955 			return;
956 		}
957 		ngether_done_init = 1;
958 	}
959 	if (ng_make_node_common(&typestruct, &node) != 0)
960 		return;
961 	ac->ac_ng = node;
962 	node->private = ifp;
963 	sprintf(namebuf, "%s%d", ifp->if_name, ifp->if_unit);
964 	ng_name_node(AC2NG(ac), namebuf);
965 }
966 
967 /*
968  * It is not possible or allowable to create a node of this type.
969  * If the hardware exists, it will already have created it.
970  */
971 static	int
972 ngether_constructor(node_p *nodep)
973 {
974 	return (EINVAL);
975 }
976 
977 /*
978  * Give our ok for a hook to be added...
979  *
980  * Allow one hook at a time (rawdata).
981  * It can eiteh rdivert everything or only unclaimed packets.
982  */
983 static	int
984 ngether_newhook(node_p node, hook_p hook, const char *name)
985 {
986 
987 	/* check if there is already a hook */
988 	if (LIST_FIRST(&(node->hooks)))
989 		return(EISCONN);
990 	/*
991 	 * Check for which mode hook we want.
992 	 */
993 	if (strcmp(name, NG_ETHER_HOOK_ORPHAN) != 0) {
994 		if (strcmp(name, NG_ETHER_HOOK_DIVERT) != 0) {
995 			return (EINVAL);
996 		}
997 		node->flags |= NGEF_DIVERT;
998 	} else {
999 		node->flags &= ~NGEF_DIVERT;
1000 	}
1001 	return (0);
1002 }
1003 
1004 /*
1005  * incoming messages.
1006  * Just respond to the generic TEXT_STATUS message
1007  */
1008 static	int
1009 ngether_rcvmsg(node_p node,
1010 	struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp)
1011 {
1012 	struct ifnet	*ifp;
1013 	int error = 0;
1014 
1015 	ifp = node->private;
1016 	switch (msg->header.typecookie) {
1017 	    case	NGM_ETHER_COOKIE:
1018 		error = EINVAL;
1019 		break;
1020 	    case	NGM_GENERIC_COOKIE:
1021 		switch(msg->header.cmd) {
1022 		    case NGM_TEXT_STATUS: {
1023 			    char	*arg;
1024 			    int pos = 0;
1025 			    int resplen = sizeof(struct ng_mesg) + 512;
1026 			    MALLOC(*resp, struct ng_mesg *, resplen,
1027 					M_NETGRAPH, M_NOWAIT);
1028 			    if (*resp == NULL) {
1029 				error = ENOMEM;
1030 				break;
1031 			    }
1032 			    bzero(*resp, resplen);
1033 			    arg = (*resp)->data;
1034 
1035 			    /*
1036 			     * Put in the throughput information.
1037 			     */
1038 			    pos = sprintf(arg, "%ld bytes in, %ld bytes out\n",
1039 			    ifp->if_ibytes, ifp->if_obytes);
1040 			    pos += sprintf(arg + pos,
1041 				"%ld output errors\n",
1042 			    	ifp->if_oerrors);
1043 			    pos += sprintf(arg + pos,
1044 				"ierrors = %ld\n",
1045 			    	ifp->if_ierrors);
1046 
1047 			    (*resp)->header.version = NG_VERSION;
1048 			    (*resp)->header.arglen = strlen(arg) + 1;
1049 			    (*resp)->header.token = msg->header.token;
1050 			    (*resp)->header.typecookie = NGM_ETHER_COOKIE;
1051 			    (*resp)->header.cmd = msg->header.cmd;
1052 			    strncpy((*resp)->header.cmdstr, "status",
1053 					NG_CMDSTRLEN);
1054 			}
1055 			break;
1056 	    	    default:
1057 		 	error = EINVAL;
1058 		 	break;
1059 		    }
1060 		break;
1061 	    default:
1062 		error = EINVAL;
1063 		break;
1064 	}
1065 	free(msg, M_NETGRAPH);
1066 	return (error);
1067 }
1068 
1069 /*
1070  * Receive a completed ethernet packet.
1071  * Queue it for output.
1072  */
1073 static	int
1074 ngether_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
1075 {
1076 	struct ifnet *ifp;
1077 	int	error = 0;
1078 	int	s;
1079 	struct ether_header *eh;
1080 
1081 	ifp = hook->node->private;
1082 
1083 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
1084 		senderr(ENETDOWN);
1085 	/*
1086 	 * If a simplex interface, and the packet is being sent to our
1087 	 * Ethernet address or a broadcast address, loopback a copy.
1088 	 * XXX To make a simplex device behave exactly like a duplex
1089 	 * device, we should copy in the case of sending to our own
1090 	 * ethernet address (thus letting the original actually appear
1091 	 * on the wire). However, we don't do that here for security
1092 	 * reasons and compatibility with the original behavior.
1093 	 */
1094 	if (ifp->if_flags & IFF_SIMPLEX) {
1095 		eh = mtod(m, struct ether_header *);
1096 		if (m->m_flags & M_BCAST) {
1097 			struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
1098 
1099 			ng_queue_data(hook, n, meta);
1100 		} else if (bcmp(eh->ether_dhost,
1101 		    eh->ether_shost, ETHER_ADDR_LEN) == 0) {
1102 			ng_queue_data(hook, m, meta);
1103 			return (0);	/* XXX */
1104 		}
1105 	}
1106 	s = splimp();
1107 	/*
1108 	 * Queue message on interface, and start output if interface
1109 	 * not yet active.
1110 	 * XXX if we lookead at the priority in the meta data we could
1111 	 * queue high priority items at the head.
1112 	 */
1113 	if (IF_QFULL(&ifp->if_snd)) {
1114 		IF_DROP(&ifp->if_snd);
1115 		splx(s);
1116 		senderr(ENOBUFS);
1117 	}
1118 	IF_ENQUEUE(&ifp->if_snd, m);
1119 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
1120 		(*ifp->if_start)(ifp);
1121 	splx(s);
1122 	ifp->if_obytes += m->m_pkthdr.len;
1123 	if (m->m_flags & M_MCAST)
1124 		ifp->if_omcasts++;
1125 	return (error);
1126 
1127 bad:
1128 	NG_FREE_DATA(m, meta);
1129 	return (error);
1130 }
1131 
1132 /*
1133  * pass an mbuf out to the connected hook
1134  * More complicated than just an m_prepend, as it tries to save later nodes
1135  * from needing to do lots of m_pullups.
1136  */
1137 static void
1138 ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
1139 {
1140 	int room;
1141 	node_p node = AC2NG(ac);
1142 	struct ether_header *eh2;
1143 
1144 	if (node && LIST_FIRST(&(node->hooks))) {
1145 		/*
1146 		 * Possibly the header is already on the front,
1147 		 */
1148 		eh2 = mtod(m, struct ether_header *) - 1;
1149 		if ( eh == eh2) {
1150 			/*
1151 			 * This is the case so just move the markers back to
1152 			 * re-include it. We lucked out.
1153 			 * This allows us to avoid a yucky m_pullup
1154 			 * in later nodes if it works.
1155 			 */
1156 			m->m_len += sizeof(*eh);
1157 			m->m_data -= sizeof(*eh);
1158 			m->m_pkthdr.len += sizeof(*eh);
1159 		} else {
1160 			/*
1161 			 * Alternatively there may be room even though
1162 			 * it is stored somewhere else. If so, copy it in.
1163 			 * This only safe because we KNOW that this packet has
1164 			 * just been generated by an ethernet card, so there
1165 			 * are no aliases to the buffer. (unlike in outgoing
1166 			 * packets).
1167 			 * Nearly all ethernet cards will end up producing mbufs
1168 			 * that fall into these cases. So we are not optimising
1169 			 * contorted cases.
1170 			 */
1171 
1172 			if (m->m_flags & M_EXT) {
1173 				room = (mtod(m, caddr_t) - m->m_ext.ext_buf);
1174 				if (room > m->m_ext.ext_size) /* garbage */
1175 					room = 0; /* fail immediatly */
1176 			} else {
1177 				room = (mtod(m, caddr_t) - m->m_pktdat);
1178 			}
1179 			if (room > sizeof (*eh)) {
1180 				/* we have room, just copy it and adjust */
1181 				m->m_len += sizeof(*eh);
1182 				m->m_data -= sizeof(*eh);
1183 				m->m_pkthdr.len += sizeof(*eh);
1184 				bcopy ((caddr_t)eh, (caddr_t)eh2, sizeof(*eh));
1185 			} else {
1186 				/*
1187 				 * Doing anything more is likely to get more
1188 				 * expensive than it's worth..
1189 				 * it's probable that everything else is in one
1190 				 * big lump. The next node will do an m_pullup()
1191 				 * for exactly the amount of data it needs and
1192 				 * hopefully everything after that will not
1193 				 * need one. So let's just use m_prepend.
1194 				 */
1195 				m = m_prepend(m, MHLEN, M_DONTWAIT);
1196 				if (m == NULL)
1197 					return;
1198 			}
1199 		}
1200 		ng_queue_data(LIST_FIRST(&(node->hooks)), m, NULL);
1201 	} else {
1202 		m_freem(m);
1203 	}
1204 }
1205 
1206 /*
1207  * do local shutdown processing..
1208  * This node will refuse to go away, unless the hardware says to..
1209  * don't unref the node, or remove our name. just clear our links up.
1210  */
1211 static	int
1212 ngether_rmnode(node_p node)
1213 {
1214 	ng_cutlinks(node);
1215 	node->flags &= ~NG_INVALID; /* bounce back to life */
1216 	return (0);
1217 }
1218 
1219 /* already linked */
1220 static	int
1221 ngether_connect(hook_p hook)
1222 {
1223 	/* be really amiable and just say "YUP that's OK by me! " */
1224 	return (0);
1225 }
1226 
1227 /*
1228  * notify on hook disconnection (destruction)
1229  *
1230  * For this type, removal of the last lins no effect. The interface can run
1231  * independently.
1232  * Since we have no per-hook information, this is rather simple.
1233  */
1234 static	int
1235 ngether_disconnect(hook_p hook)
1236 {
1237 	hook->node->flags &= ~NGEF_DIVERT;
1238 	return (0);
1239 }
1240 #endif /* NETGRAPH */
1241 
1242 /********************************** END *************************************/
1243