if_disc.c revision 32350
1221163Sadrian/*
2221163Sadrian * Copyright (c) 1982, 1986, 1993
3221163Sadrian *	The Regents of the University of California.  All rights reserved.
4221163Sadrian *
5221163Sadrian * Redistribution and use in source and binary forms, with or without
6221163Sadrian * modification, are permitted provided that the following conditions
7221163Sadrian * are met:
8221163Sadrian * 1. Redistributions of source code must retain the above copyright
9221163Sadrian *    notice, this list of conditions and the following disclaimer.
10221163Sadrian * 2. Redistributions in binary form must reproduce the above copyright
11221163Sadrian *    notice, this list of conditions and the following disclaimer in the
12221163Sadrian *    documentation and/or other materials provided with the distribution.
13221163Sadrian * 3. All advertising materials mentioning features or use of this software
14221163Sadrian *    must display the following acknowledgement:
15221163Sadrian *	This product includes software developed by the University of
16221163Sadrian *	California, Berkeley and its contributors.
17221163Sadrian * 4. Neither the name of the University nor the names of its contributors
18221163Sadrian *    may be used to endorse or promote products derived from this software
19221163Sadrian *    without specific prior written permission.
20221163Sadrian *
21221163Sadrian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22221163Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23221163Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24221163Sadrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25221163Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26221163Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27221163Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28221163Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29221163Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30221163Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31221163Sadrian * SUCH DAMAGE.
32221163Sadrian *
33221163Sadrian *	From: @(#)if_loop.c	8.1 (Berkeley) 6/10/93
34221163Sadrian *	$Id: if_disc.c,v 1.18 1997/08/02 14:32:36 bde Exp $
35221163Sadrian */
36221163Sadrian
37221163Sadrian/*
38221163Sadrian * Discard interface driver for protocol testing and timing.
39221163Sadrian * (Based on the loopback.)
40221163Sadrian */
41221163Sadrian
42221163Sadrian#include <sys/param.h>
43221163Sadrian#include <sys/systm.h>
44221163Sadrian#include <sys/kernel.h>
45221163Sadrian#include <sys/mbuf.h>
46221163Sadrian#include <sys/socket.h>
47221163Sadrian#include <sys/sockio.h>
48221163Sadrian
49221163Sadrian#include <net/if.h>
50221163Sadrian#include <net/if_types.h>
51221163Sadrian#include <net/route.h>
52221163Sadrian#include <net/bpf.h>
53221163Sadrian
54221163Sadrian#include "bpfilter.h"
55221163Sadrian#include "opt_inet.h"
56221163Sadrian
57221163Sadrian#ifdef TINY_DSMTU
58221163Sadrian#define	DSMTU	(1024+512)
59221163Sadrian#else
60221163Sadrian#define DSMTU	65532
61221163Sadrian#endif
62221163Sadrian
63221163Sadrianstatic void discattach __P((void *dummy));
64221163SadrianPSEUDO_SET(discattach, if_disc);
65221163Sadrian
66221163Sadrianstatic struct	ifnet dsif;
67221163Sadrianstatic int dsoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
68221163Sadrian		    struct rtentry *);
69221163Sadrianstatic void dsrtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa);
70221163Sadrianstatic int dsioctl(struct ifnet *, int, caddr_t);
71221163Sadrian
72221163Sadrian/* ARGSUSED */
73221163Sadrianstatic void
74221163Sadriandiscattach(dummy)
75221163Sadrian	void *dummy;
76221163Sadrian{
77221163Sadrian	register struct ifnet *ifp = &dsif;
78221163Sadrian
79221163Sadrian	ifp->if_name = "ds";
80221163Sadrian	ifp->if_mtu = DSMTU;
81221163Sadrian	ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
82221163Sadrian	ifp->if_ioctl = dsioctl;
83221163Sadrian	ifp->if_output = dsoutput;
84221163Sadrian	ifp->if_type = IFT_LOOP;
85221163Sadrian	ifp->if_hdrlen = 0;
86221163Sadrian	ifp->if_addrlen = 0;
87221163Sadrian	if_attach(ifp);
88221163Sadrian#if NBPFILTER > 0
89221163Sadrian	bpfattach(ifp, DLT_NULL, sizeof(u_int));
90221163Sadrian#endif
91221163Sadrian}
92221163Sadrian
93221163Sadrianstatic int
94221163Sadriandsoutput(ifp, m, dst, rt)
95221163Sadrian	struct ifnet *ifp;
96221163Sadrian	register struct mbuf *m;
97221163Sadrian	struct sockaddr *dst;
98221163Sadrian	register struct rtentry *rt;
99221163Sadrian{
100221163Sadrian	if ((m->m_flags & M_PKTHDR) == 0)
101221163Sadrian		panic("dsoutput no HDR");
102221163Sadrian#if NBPFILTER > 0
103221163Sadrian	/* BPF write needs to be handled specially */
104221163Sadrian	if (dst->sa_family == AF_UNSPEC) {
105221163Sadrian		dst->sa_family = *(mtod(m, int *));
106221163Sadrian		m->m_len -= sizeof(int);
107221163Sadrian		m->m_pkthdr.len -= sizeof(int);
108221163Sadrian		m->m_data += sizeof(int);
109221163Sadrian	}
110221163Sadrian
111221163Sadrian	if (dsif.if_bpf) {
112221163Sadrian		/*
113221163Sadrian		 * We need to prepend the address family as
114221163Sadrian		 * a four byte field.  Cons up a dummy header
115221163Sadrian		 * to pacify bpf.  This is safe because bpf
116221163Sadrian		 * will only read from the mbuf (i.e., it won't
117221163Sadrian		 * try to free it or keep a pointer a to it).
118221163Sadrian		 */
119221163Sadrian		struct mbuf m0;
120221163Sadrian		u_int af = dst->sa_family;
121221163Sadrian
122221163Sadrian		m0.m_next = m;
123221163Sadrian		m0.m_len = 4;
124221163Sadrian		m0.m_data = (char *)&af;
125221163Sadrian
126221163Sadrian		bpf_mtap(&dsif, &m0);
127221163Sadrian	}
128221163Sadrian#endif
129221163Sadrian	m->m_pkthdr.rcvif = ifp;
130221163Sadrian
131221163Sadrian	ifp->if_opackets++;
132221163Sadrian	ifp->if_obytes += m->m_pkthdr.len;
133221163Sadrian
134221163Sadrian	m_freem(m);
135221163Sadrian	return 0;
136221163Sadrian}
137221163Sadrian
138221163Sadrian/* ARGSUSED */
139221163Sadrianstatic void
140221163Sadriandsrtrequest(cmd, rt, sa)
141221163Sadrian	int cmd;
142221163Sadrian	struct rtentry *rt;
143221163Sadrian	struct sockaddr *sa;
144221163Sadrian{
145221163Sadrian	if (rt)
146221163Sadrian		rt->rt_rmx.rmx_mtu = DSMTU;
147221163Sadrian}
148221163Sadrian
149221163Sadrian/*
150221163Sadrian * Process an ioctl request.
151221163Sadrian */
152221163Sadrian/* ARGSUSED */
153221163Sadrianstatic int
154221163Sadriandsioctl(ifp, cmd, data)
155221163Sadrian	register struct ifnet *ifp;
156221163Sadrian	int cmd;
157221163Sadrian	caddr_t data;
158221163Sadrian{
159221163Sadrian	register struct ifaddr *ifa;
160221163Sadrian	register struct ifreq *ifr = (struct ifreq *)data;
161221163Sadrian	register int error = 0;
162221163Sadrian
163221163Sadrian	switch (cmd) {
164221163Sadrian
165221163Sadrian	case SIOCSIFADDR:
166221163Sadrian		ifp->if_flags |= IFF_UP;
167221163Sadrian		ifa = (struct ifaddr *)data;
168221163Sadrian		if (ifa != 0)
169221163Sadrian			ifa->ifa_rtrequest = dsrtrequest;
170221163Sadrian		/*
171221163Sadrian		 * Everything else is done at a higher level.
172221163Sadrian		 */
173221163Sadrian		break;
174221163Sadrian
175221163Sadrian	case SIOCADDMULTI:
176221163Sadrian	case SIOCDELMULTI:
177221163Sadrian		if (ifr == 0) {
178221163Sadrian			error = EAFNOSUPPORT;		/* XXX */
179221163Sadrian			break;
180221163Sadrian		}
181221163Sadrian		switch (ifr->ifr_addr.sa_family) {
182221163Sadrian
183221163Sadrian#ifdef INET
184221163Sadrian		case AF_INET:
185221163Sadrian			break;
186221163Sadrian#endif
187221163Sadrian
188221163Sadrian		default:
189221163Sadrian			error = EAFNOSUPPORT;
190221163Sadrian			break;
191221163Sadrian		}
192221163Sadrian		break;
193221163Sadrian
194221163Sadrian	case SIOCSIFMTU:
195221163Sadrian		ifp->if_mtu = ifr->ifr_mtu;
196221163Sadrian		break;
197221163Sadrian
198221163Sadrian	default:
199221163Sadrian		error = EINVAL;
200221163Sadrian	}
201221163Sadrian	return (error);
202221163Sadrian}
203221163Sadrian