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