159d8d13fSGarrett Wollman /* 259d8d13fSGarrett Wollman * Copyright (c) 1982, 1986, 1993 359d8d13fSGarrett Wollman * The Regents of the University of California. All rights reserved. 459d8d13fSGarrett Wollman * 559d8d13fSGarrett Wollman * Redistribution and use in source and binary forms, with or without 659d8d13fSGarrett Wollman * modification, are permitted provided that the following conditions 759d8d13fSGarrett Wollman * are met: 859d8d13fSGarrett Wollman * 1. Redistributions of source code must retain the above copyright 959d8d13fSGarrett Wollman * notice, this list of conditions and the following disclaimer. 1059d8d13fSGarrett Wollman * 2. Redistributions in binary form must reproduce the above copyright 1159d8d13fSGarrett Wollman * notice, this list of conditions and the following disclaimer in the 1259d8d13fSGarrett Wollman * documentation and/or other materials provided with the distribution. 1359d8d13fSGarrett Wollman * 3. All advertising materials mentioning features or use of this software 1459d8d13fSGarrett Wollman * must display the following acknowledgement: 1559d8d13fSGarrett Wollman * This product includes software developed by the University of 1659d8d13fSGarrett Wollman * California, Berkeley and its contributors. 1759d8d13fSGarrett Wollman * 4. Neither the name of the University nor the names of its contributors 1859d8d13fSGarrett Wollman * may be used to endorse or promote products derived from this software 1959d8d13fSGarrett Wollman * without specific prior written permission. 2059d8d13fSGarrett Wollman * 2159d8d13fSGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259d8d13fSGarrett Wollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359d8d13fSGarrett Wollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459d8d13fSGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559d8d13fSGarrett Wollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659d8d13fSGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759d8d13fSGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859d8d13fSGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959d8d13fSGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059d8d13fSGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159d8d13fSGarrett Wollman * SUCH DAMAGE. 3259d8d13fSGarrett Wollman * 3359d8d13fSGarrett Wollman * From: @(#)if_loop.c 8.1 (Berkeley) 6/10/93 34c3aac50fSPeter Wemm * $FreeBSD$ 3559d8d13fSGarrett Wollman */ 3659d8d13fSGarrett Wollman 3759d8d13fSGarrett Wollman /* 3859d8d13fSGarrett Wollman * Discard interface driver for protocol testing and timing. 3959d8d13fSGarrett Wollman * (Based on the loopback.) 4059d8d13fSGarrett Wollman */ 4159d8d13fSGarrett Wollman 4259d8d13fSGarrett Wollman #include <sys/param.h> 4359d8d13fSGarrett Wollman #include <sys/systm.h> 4459d8d13fSGarrett Wollman #include <sys/kernel.h> 452b120974SPeter Wemm #include <sys/module.h> 4659d8d13fSGarrett Wollman #include <sys/mbuf.h> 4759d8d13fSGarrett Wollman #include <sys/socket.h> 4851a53488SBruce Evans #include <sys/sockio.h> 4959d8d13fSGarrett Wollman 5059d8d13fSGarrett Wollman #include <net/if.h> 5159d8d13fSGarrett Wollman #include <net/if_types.h> 5259d8d13fSGarrett Wollman #include <net/route.h> 5359d8d13fSGarrett Wollman #include <net/bpf.h> 5459d8d13fSGarrett Wollman 551d5e9e22SEivind Eklund #include "opt_inet.h" 56cfa1ca9dSYoshinobu Inoue #include "opt_inet6.h" 5759d8d13fSGarrett Wollman 5859d8d13fSGarrett Wollman #ifdef TINY_DSMTU 5959d8d13fSGarrett Wollman #define DSMTU (1024+512) 6059d8d13fSGarrett Wollman #else 6159d8d13fSGarrett Wollman #define DSMTU 65532 6259d8d13fSGarrett Wollman #endif 6359d8d13fSGarrett Wollman 64eb6bd594SMark Murray static void discattach(void); 65b6f5c0b8SBruce Evans 66537ad974SEivind Eklund static struct ifnet discif; 67eb6bd594SMark Murray static int discoutput(struct ifnet *, struct mbuf *, 68eb6bd594SMark Murray struct sockaddr *, struct rtentry *); 698071913dSRuslan Ermilov static void discrtrequest(int, struct rtentry *, struct rt_addrinfo *); 70537ad974SEivind Eklund static int discioctl(struct ifnet *, u_long, caddr_t); 7159d8d13fSGarrett Wollman 7259d8d13fSGarrett Wollman static void 73eb6bd594SMark Murray discattach(void) 7459d8d13fSGarrett Wollman { 75eb6bd594SMark Murray struct ifnet *ifp = &discif; 7659d8d13fSGarrett Wollman 7759d8d13fSGarrett Wollman ifp->if_name = "ds"; 7859d8d13fSGarrett Wollman ifp->if_mtu = DSMTU; 7959d8d13fSGarrett Wollman ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; 80537ad974SEivind Eklund ifp->if_ioctl = discioctl; 81537ad974SEivind Eklund ifp->if_output = discoutput; 8259d8d13fSGarrett Wollman ifp->if_type = IFT_LOOP; 8359d8d13fSGarrett Wollman ifp->if_hdrlen = 0; 8459d8d13fSGarrett Wollman ifp->if_addrlen = 0; 85422fd76fSPoul-Henning Kamp ifp->if_snd.ifq_maxlen = 20; 8659d8d13fSGarrett Wollman if_attach(ifp); 879b44ff22SGarrett Wollman bpfattach(ifp, DLT_NULL, sizeof(u_int)); 8859d8d13fSGarrett Wollman } 8959d8d13fSGarrett Wollman 9059d8d13fSGarrett Wollman static int 912b120974SPeter Wemm disc_modevent(module_t mod, int type, void *data) 922b120974SPeter Wemm { 932b120974SPeter Wemm switch (type) { 942b120974SPeter Wemm case MOD_LOAD: 952b120974SPeter Wemm discattach(); 962b120974SPeter Wemm break; 972b120974SPeter Wemm case MOD_UNLOAD: 982b120974SPeter Wemm printf("if_disc module unload - not possible for this module type\n"); 992b120974SPeter Wemm return EINVAL; 1002b120974SPeter Wemm } 1012b120974SPeter Wemm return 0; 1022b120974SPeter Wemm } 1032b120974SPeter Wemm 1042b120974SPeter Wemm static moduledata_t disc_mod = { 1052b120974SPeter Wemm "if_disc", 1062b120974SPeter Wemm disc_modevent, 1072b120974SPeter Wemm NULL 1082b120974SPeter Wemm }; 1092b120974SPeter Wemm 1102b120974SPeter Wemm DECLARE_MODULE(if_disc, disc_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 1112b120974SPeter Wemm 1122b120974SPeter Wemm static int 113eb6bd594SMark Murray discoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 114eb6bd594SMark Murray struct rtentry *rt) 11559d8d13fSGarrett Wollman { 11659d8d13fSGarrett Wollman if ((m->m_flags & M_PKTHDR) == 0) 117537ad974SEivind Eklund panic("discoutput no HDR"); 118963e4c2aSGarrett Wollman /* BPF write needs to be handled specially */ 119963e4c2aSGarrett Wollman if (dst->sa_family == AF_UNSPEC) { 120963e4c2aSGarrett Wollman dst->sa_family = *(mtod(m, int *)); 121963e4c2aSGarrett Wollman m->m_len -= sizeof(int); 122963e4c2aSGarrett Wollman m->m_pkthdr.len -= sizeof(int); 123963e4c2aSGarrett Wollman m->m_data += sizeof(int); 124963e4c2aSGarrett Wollman } 125963e4c2aSGarrett Wollman 126537ad974SEivind Eklund if (discif.if_bpf) { 12759d8d13fSGarrett Wollman /* 12859d8d13fSGarrett Wollman * We need to prepend the address family as 12959d8d13fSGarrett Wollman * a four byte field. Cons up a dummy header 13059d8d13fSGarrett Wollman * to pacify bpf. This is safe because bpf 13159d8d13fSGarrett Wollman * will only read from the mbuf (i.e., it won't 13259d8d13fSGarrett Wollman * try to free it or keep a pointer a to it). 13359d8d13fSGarrett Wollman */ 13459d8d13fSGarrett Wollman struct mbuf m0; 13559d8d13fSGarrett Wollman u_int af = dst->sa_family; 13659d8d13fSGarrett Wollman 13759d8d13fSGarrett Wollman m0.m_next = m; 13859d8d13fSGarrett Wollman m0.m_len = 4; 13959d8d13fSGarrett Wollman m0.m_data = (char *)⁡ 14059d8d13fSGarrett Wollman 141537ad974SEivind Eklund bpf_mtap(&discif, &m0); 14259d8d13fSGarrett Wollman } 14359d8d13fSGarrett Wollman m->m_pkthdr.rcvif = ifp; 14459d8d13fSGarrett Wollman 14559d8d13fSGarrett Wollman ifp->if_opackets++; 14659d8d13fSGarrett Wollman ifp->if_obytes += m->m_pkthdr.len; 14759d8d13fSGarrett Wollman 14859d8d13fSGarrett Wollman m_freem(m); 14959d8d13fSGarrett Wollman return 0; 15059d8d13fSGarrett Wollman } 15159d8d13fSGarrett Wollman 15259d8d13fSGarrett Wollman /* ARGSUSED */ 15359d8d13fSGarrett Wollman static void 1548071913dSRuslan Ermilov discrtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info) 15559d8d13fSGarrett Wollman { 15659d8d13fSGarrett Wollman if (rt) 15759d8d13fSGarrett Wollman rt->rt_rmx.rmx_mtu = DSMTU; 15859d8d13fSGarrett Wollman } 15959d8d13fSGarrett Wollman 16059d8d13fSGarrett Wollman /* 16159d8d13fSGarrett Wollman * Process an ioctl request. 16259d8d13fSGarrett Wollman */ 16388e2f526SBruce Evans static int 164eb6bd594SMark Murray discioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 16559d8d13fSGarrett Wollman { 166eb6bd594SMark Murray struct ifaddr *ifa; 167eb6bd594SMark Murray struct ifreq *ifr = (struct ifreq *)data; 168eb6bd594SMark Murray int error = 0; 16959d8d13fSGarrett Wollman 17059d8d13fSGarrett Wollman switch (cmd) { 17159d8d13fSGarrett Wollman 17259d8d13fSGarrett Wollman case SIOCSIFADDR: 17359d8d13fSGarrett Wollman ifp->if_flags |= IFF_UP; 17459d8d13fSGarrett Wollman ifa = (struct ifaddr *)data; 17559d8d13fSGarrett Wollman if (ifa != 0) 176537ad974SEivind Eklund ifa->ifa_rtrequest = discrtrequest; 17759d8d13fSGarrett Wollman /* 17859d8d13fSGarrett Wollman * Everything else is done at a higher level. 17959d8d13fSGarrett Wollman */ 18059d8d13fSGarrett Wollman break; 18159d8d13fSGarrett Wollman 18259d8d13fSGarrett Wollman case SIOCADDMULTI: 18359d8d13fSGarrett Wollman case SIOCDELMULTI: 18459d8d13fSGarrett Wollman if (ifr == 0) { 18559d8d13fSGarrett Wollman error = EAFNOSUPPORT; /* XXX */ 18659d8d13fSGarrett Wollman break; 18759d8d13fSGarrett Wollman } 18859d8d13fSGarrett Wollman switch (ifr->ifr_addr.sa_family) { 18959d8d13fSGarrett Wollman 19059d8d13fSGarrett Wollman #ifdef INET 19159d8d13fSGarrett Wollman case AF_INET: 19259d8d13fSGarrett Wollman break; 19359d8d13fSGarrett Wollman #endif 194cfa1ca9dSYoshinobu Inoue #ifdef INET6 195cfa1ca9dSYoshinobu Inoue case AF_INET6: 196cfa1ca9dSYoshinobu Inoue break; 197cfa1ca9dSYoshinobu Inoue #endif 19859d8d13fSGarrett Wollman 19959d8d13fSGarrett Wollman default: 20059d8d13fSGarrett Wollman error = EAFNOSUPPORT; 20159d8d13fSGarrett Wollman break; 20259d8d13fSGarrett Wollman } 20359d8d13fSGarrett Wollman break; 20459d8d13fSGarrett Wollman 20559d8d13fSGarrett Wollman case SIOCSIFMTU: 20659d8d13fSGarrett Wollman ifp->if_mtu = ifr->ifr_mtu; 20759d8d13fSGarrett Wollman break; 20859d8d13fSGarrett Wollman 20959d8d13fSGarrett Wollman default: 21059d8d13fSGarrett Wollman error = EINVAL; 21159d8d13fSGarrett Wollman } 21264b15424SJonathan Lemon return (error); 21359d8d13fSGarrett Wollman } 214