if_disc.c revision 54263
137Srgrimes/* 250472Speter * Copyright (c) 1982, 1986, 1993 337Srgrimes * The Regents of the University of California. All rights reserved. 418912Sjoerg * 518912Sjoerg * Redistribution and use in source and binary forms, with or without 668171Sandreas * modification, are permitted provided that the following conditions 768171Sandreas * are met: 818912Sjoerg * 1. Redistributions of source code must retain the above copyright 968171Sandreas * notice, this list of conditions and the following disclaimer. 1068171Sandreas * 2. Redistributions in binary form must reproduce the above copyright 1118912Sjoerg * notice, this list of conditions and the following disclaimer in the 1218912Sjoerg * documentation and/or other materials provided with the distribution. 1318912Sjoerg * 3. All advertising materials mentioning features or use of this software 1418912Sjoerg * must display the following acknowledgement: 1518912Sjoerg * This product includes software developed by the University of 1668171Sandreas * California, Berkeley and its contributors. 1718912Sjoerg * 4. Neither the name of the University nor the names of its contributors 1868171Sandreas * may be used to endorse or promote products derived from this software 1918912Sjoerg * without specific prior written permission. 2068171Sandreas * 2168171Sandreas * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2232241Ssteve * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23130151Sschweikh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2418912Sjoerg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25112623Strhodes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2668171Sandreas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2768171Sandreas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2868171Sandreas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2968171Sandreas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3068171Sandreas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3168171Sandreas * SUCH DAMAGE. 3268171Sandreas * 3368171Sandreas * From: @(#)if_loop.c 8.1 (Berkeley) 6/10/93 3468171Sandreas * $FreeBSD: head/sys/net/if_disc.c 54263 1999-12-07 17:39:16Z shin $ 3568171Sandreas */ 3668171Sandreas 3768171Sandreas/* 3818912Sjoerg * Discard interface driver for protocol testing and timing. 3968171Sandreas * (Based on the loopback.) 4068171Sandreas */ 4168171Sandreas 4268171Sandreas#include <sys/param.h> 4318912Sjoerg#include <sys/systm.h> 4418912Sjoerg#include <sys/kernel.h> 4532241Ssteve#include <sys/mbuf.h> 4668171Sandreas#include <sys/socket.h> 4768171Sandreas#include <sys/sockio.h> 4833089Sache 4933089Sache#include <net/if.h> 5033089Sache#include <net/if_types.h> 5133089Sache#include <net/route.h> 5233089Sache#include <net/bpf.h> 5333089Sache 5433089Sache#include "opt_inet.h" 55#include "opt_inet6.h" 56 57#ifdef TINY_DSMTU 58#define DSMTU (1024+512) 59#else 60#define DSMTU 65532 61#endif 62 63static void discattach __P((void *dummy)); 64PSEUDO_SET(discattach, if_disc); 65 66static struct ifnet discif; 67static int discoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 68 struct rtentry *); 69static void discrtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa); 70static int discioctl(struct ifnet *, u_long, caddr_t); 71 72/* ARGSUSED */ 73static void 74discattach(dummy) 75 void *dummy; 76{ 77 register struct ifnet *ifp = &discif; 78 79 ifp->if_name = "ds"; 80 ifp->if_mtu = DSMTU; 81 ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; 82 ifp->if_ioctl = discioctl; 83 ifp->if_output = discoutput; 84 ifp->if_type = IFT_LOOP; 85 ifp->if_hdrlen = 0; 86 ifp->if_addrlen = 0; 87 ifp->if_snd.ifq_maxlen = 20; 88 if_attach(ifp); 89 bpfattach(ifp, DLT_NULL, sizeof(u_int)); 90} 91 92static int 93discoutput(ifp, m, dst, rt) 94 struct ifnet *ifp; 95 register struct mbuf *m; 96 struct sockaddr *dst; 97 register struct rtentry *rt; 98{ 99 if ((m->m_flags & M_PKTHDR) == 0) 100 panic("discoutput no HDR"); 101 /* BPF write needs to be handled specially */ 102 if (dst->sa_family == AF_UNSPEC) { 103 dst->sa_family = *(mtod(m, int *)); 104 m->m_len -= sizeof(int); 105 m->m_pkthdr.len -= sizeof(int); 106 m->m_data += sizeof(int); 107 } 108 109 if (discif.if_bpf) { 110 /* 111 * We need to prepend the address family as 112 * a four byte field. Cons up a dummy header 113 * to pacify bpf. This is safe because bpf 114 * will only read from the mbuf (i.e., it won't 115 * try to free it or keep a pointer a to it). 116 */ 117 struct mbuf m0; 118 u_int af = dst->sa_family; 119 120 m0.m_next = m; 121 m0.m_len = 4; 122 m0.m_data = (char *)⁡ 123 124 bpf_mtap(&discif, &m0); 125 } 126 m->m_pkthdr.rcvif = ifp; 127 128 ifp->if_opackets++; 129 ifp->if_obytes += m->m_pkthdr.len; 130 131 m_freem(m); 132 return 0; 133} 134 135/* ARGSUSED */ 136static void 137discrtrequest(cmd, rt, sa) 138 int cmd; 139 struct rtentry *rt; 140 struct sockaddr *sa; 141{ 142 if (rt) 143 rt->rt_rmx.rmx_mtu = DSMTU; 144} 145 146/* 147 * Process an ioctl request. 148 */ 149/* ARGSUSED */ 150static int 151discioctl(ifp, cmd, data) 152 register struct ifnet *ifp; 153 u_long cmd; 154 caddr_t data; 155{ 156 register struct ifaddr *ifa; 157 register struct ifreq *ifr = (struct ifreq *)data; 158 register int error = 0; 159 160 switch (cmd) { 161 162 case SIOCSIFADDR: 163 ifp->if_flags |= IFF_UP; 164 ifa = (struct ifaddr *)data; 165 if (ifa != 0) 166 ifa->ifa_rtrequest = discrtrequest; 167 /* 168 * Everything else is done at a higher level. 169 */ 170 break; 171 172 case SIOCADDMULTI: 173 case SIOCDELMULTI: 174 if (ifr == 0) { 175 error = EAFNOSUPPORT; /* XXX */ 176 break; 177 } 178 switch (ifr->ifr_addr.sa_family) { 179 180#ifdef INET 181 case AF_INET: 182 break; 183#endif 184#ifdef INET6 185 case AF_INET6: 186 break; 187#endif 188 189 default: 190 error = EAFNOSUPPORT; 191 break; 192 } 193 break; 194 195 case SIOCSIFMTU: 196 ifp->if_mtu = ifr->ifr_mtu; 197 break; 198 199 default: 200 error = EINVAL; 201 } 202 return (error); 203} 204