if_disc.c revision 53115
1155192Srwatson/* 2155192Srwatson * Copyright (c) 1982, 1986, 1993 3155192Srwatson * The Regents of the University of California. All rights reserved. 4155192Srwatson * 5155192Srwatson * Redistribution and use in source and binary forms, with or without 6155192Srwatson * modification, are permitted provided that the following conditions 7155192Srwatson * are met: 8155192Srwatson * 1. Redistributions of source code must retain the above copyright 9155192Srwatson * notice, this list of conditions and the following disclaimer. 10155192Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11155192Srwatson * notice, this list of conditions and the following disclaimer in the 12155192Srwatson * documentation and/or other materials provided with the distribution. 13155192Srwatson * 3. All advertising materials mentioning features or use of this software 14155192Srwatson * must display the following acknowledgement: 15155192Srwatson * This product includes software developed by the University of 16155192Srwatson * California, Berkeley and its contributors. 17155192Srwatson * 4. Neither the name of the University nor the names of its contributors 18155192Srwatson * may be used to endorse or promote products derived from this software 19155192Srwatson * without specific prior written permission. 20155192Srwatson * 21155192Srwatson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25155192Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29155192Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30155192Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31155192Srwatson * SUCH DAMAGE. 32155192Srwatson * 33155192Srwatson * From: @(#)if_loop.c 8.1 (Berkeley) 6/10/93 34155192Srwatson * $FreeBSD: head/sys/net/if_disc.c 53115 1999-11-12 19:30:08Z phk $ 35155192Srwatson */ 36155192Srwatson 37155192Srwatson/* 38155192Srwatson * Discard interface driver for protocol testing and timing. 39160136Swsalamon * (Based on the loopback.) 40155192Srwatson */ 41155192Srwatson 42155192Srwatson#include <sys/param.h> 43155192Srwatson#include <sys/systm.h> 44155192Srwatson#include <sys/kernel.h> 45155192Srwatson#include <sys/mbuf.h> 46155192Srwatson#include <sys/socket.h> 47155192Srwatson#include <sys/sockio.h> 48155192Srwatson 49155192Srwatson#include <net/if.h> 50155192Srwatson#include <net/if_types.h> 51155192Srwatson#include <net/route.h> 52155192Srwatson#include <net/bpf.h> 53155192Srwatson 54155192Srwatson#include "opt_inet.h" 55155192Srwatson 56155192Srwatson#ifdef TINY_DSMTU 57155192Srwatson#define DSMTU (1024+512) 58155192Srwatson#else 59155192Srwatson#define DSMTU 65532 60155192Srwatson#endif 61155192Srwatson 62155192Srwatsonstatic void discattach __P((void *dummy)); 63155192SrwatsonPSEUDO_SET(discattach, if_disc); 64155192Srwatson 65155192Srwatsonstatic struct ifnet discif; 66155192Srwatsonstatic int discoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 67155192Srwatson struct rtentry *); 68155192Srwatsonstatic void discrtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa); 69155192Srwatsonstatic int discioctl(struct ifnet *, u_long, caddr_t); 70155192Srwatson 71155192Srwatson/* ARGSUSED */ 72156889Srwatsonstatic void 73156889Srwatsondiscattach(dummy) 74156889Srwatson void *dummy; 75156889Srwatson{ 76156889Srwatson register struct ifnet *ifp = &discif; 77156889Srwatson 78155192Srwatson ifp->if_name = "ds"; 79156889Srwatson ifp->if_mtu = DSMTU; 80155192Srwatson ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; 81156889Srwatson ifp->if_ioctl = discioctl; 82155192Srwatson ifp->if_output = discoutput; 83162466Srwatson ifp->if_type = IFT_LOOP; 84155192Srwatson ifp->if_hdrlen = 0; 85155192Srwatson ifp->if_addrlen = 0; 86155192Srwatson ifp->if_snd.ifq_maxlen = 20; 87155192Srwatson if_attach(ifp); 88155192Srwatson bpfattach(ifp, DLT_NULL, sizeof(u_int)); 89155192Srwatson} 90155192Srwatson 91155192Srwatsonstatic int 92155192Srwatsondiscoutput(ifp, m, dst, rt) 93156889Srwatson struct ifnet *ifp; 94155192Srwatson register struct mbuf *m; 95155192Srwatson struct sockaddr *dst; 96155192Srwatson register struct rtentry *rt; 97155192Srwatson{ 98155192Srwatson if ((m->m_flags & M_PKTHDR) == 0) 99155192Srwatson panic("discoutput no HDR"); 100155192Srwatson /* BPF write needs to be handled specially */ 101155192Srwatson if (dst->sa_family == AF_UNSPEC) { 102155192Srwatson dst->sa_family = *(mtod(m, int *)); 103155192Srwatson m->m_len -= sizeof(int); 104155192Srwatson m->m_pkthdr.len -= sizeof(int); 105155192Srwatson m->m_data += sizeof(int); 106155192Srwatson } 107155192Srwatson 108155192Srwatson if (discif.if_bpf) { 109155192Srwatson /* 110155192Srwatson * We need to prepend the address family as 111155192Srwatson * a four byte field. Cons up a dummy header 112155192Srwatson * to pacify bpf. This is safe because bpf 113155192Srwatson * will only read from the mbuf (i.e., it won't 114155192Srwatson * try to free it or keep a pointer a to it). 115156889Srwatson */ 116161635Srwatson struct mbuf m0; 117162466Srwatson u_int af = dst->sa_family; 118170196Srwatson 119162466Srwatson m0.m_next = m; 120162466Srwatson m0.m_len = 4; 121162466Srwatson m0.m_data = (char *)⁡ 122162466Srwatson 123155192Srwatson bpf_mtap(&discif, &m0); 124162466Srwatson } 125162466Srwatson m->m_pkthdr.rcvif = ifp; 126155192Srwatson 127162466Srwatson ifp->if_opackets++; 128162466Srwatson ifp->if_obytes += m->m_pkthdr.len; 129162466Srwatson 130162466Srwatson m_freem(m); 131162466Srwatson return 0; 132155192Srwatson} 133155192Srwatson 134155192Srwatson/* ARGSUSED */ 135155192Srwatsonstatic void 136156889Srwatsondiscrtrequest(cmd, rt, sa) 137156889Srwatson int cmd; 138155192Srwatson struct rtentry *rt; 139155192Srwatson struct sockaddr *sa; 140155192Srwatson{ 141155192Srwatson if (rt) 142155192Srwatson rt->rt_rmx.rmx_mtu = DSMTU; 143155192Srwatson} 144156889Srwatson 145155192Srwatson/* 146155192Srwatson * Process an ioctl request. 147155192Srwatson */ 148155192Srwatson/* ARGSUSED */ 149156889Srwatsonstatic int 150155192Srwatsondiscioctl(ifp, cmd, data) 151155192Srwatson register struct ifnet *ifp; 152156889Srwatson u_long cmd; 153155192Srwatson caddr_t data; 154155192Srwatson{ 155155192Srwatson register struct ifaddr *ifa; 156155192Srwatson register struct ifreq *ifr = (struct ifreq *)data; 157155192Srwatson register int error = 0; 158170196Srwatson 159155192Srwatson switch (cmd) { 160155192Srwatson 161155192Srwatson case SIOCSIFADDR: 162155192Srwatson ifp->if_flags |= IFF_UP; 163155192Srwatson ifa = (struct ifaddr *)data; 164155192Srwatson if (ifa != 0) 165155192Srwatson ifa->ifa_rtrequest = discrtrequest; 166155192Srwatson /* 167155192Srwatson * Everything else is done at a higher level. 168155192Srwatson */ 169155192Srwatson break; 170155192Srwatson 171155192Srwatson case SIOCADDMULTI: 172155192Srwatson case SIOCDELMULTI: 173155192Srwatson if (ifr == 0) { 174155192Srwatson error = EAFNOSUPPORT; /* XXX */ 175155192Srwatson break; 176155192Srwatson } 177155192Srwatson switch (ifr->ifr_addr.sa_family) { 178155192Srwatson 179155192Srwatson#ifdef INET 180155192Srwatson case AF_INET: 181155192Srwatson break; 182155192Srwatson#endif 183155192Srwatson 184155192Srwatson default: 185155192Srwatson error = EAFNOSUPPORT; 186155192Srwatson break; 187155192Srwatson } 188155192Srwatson break; 189155192Srwatson 190155192Srwatson case SIOCSIFMTU: 191155192Srwatson ifp->if_mtu = ifr->ifr_mtu; 192155192Srwatson break; 193155192Srwatson 194155192Srwatson default: 195155192Srwatson error = EINVAL; 196155192Srwatson } 197155192Srwatson return (error); 198155192Srwatson} 199155192Srwatson