Add the source code for /usr/src/usr.bin from the Net/2 tape
[unix-history] / usr / src / sys.386bsd / net / if_loop.c
CommitLineData
b688fc87
WJ
1/*
2 * Copyright (c) 1982, 1986 Regents of the University of California.
3 * 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_loop.c 7.13 (Berkeley) 4/26/91
3a1876f4
DG
34 *
35 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
36 * -------------------- ----- ----------------------
37 * CURRENT PATCH LEVEL: 1 00112
38 * -------------------- ----- ----------------------
39 *
40 * 14 Mar 93 David Greenman Upgrade bpf to match tcpdump 2.2.1
b688fc87
WJ
41 */
42
43/*
44 * Loopback interface driver for protocol testing and timing.
45 */
46
47#include "param.h"
48#include "systm.h"
49#include "mbuf.h"
50#include "socket.h"
51#include "errno.h"
52#include "ioctl.h"
53
54#include "../net/if.h"
55#include "../net/if_types.h"
56#include "../net/netisr.h"
57#include "../net/route.h"
58
59#include "machine/mtpr.h"
60
61#ifdef INET
62#include "../netinet/in.h"
63#include "../netinet/in_systm.h"
64#include "../netinet/in_var.h"
65#include "../netinet/ip.h"
66#endif
67
68#ifdef NS
69#include "../netns/ns.h"
70#include "../netns/ns_if.h"
71#endif
72
73#ifdef ISO
74#include "../netiso/iso.h"
75#include "../netiso/iso_var.h"
76#endif
77
3a1876f4
DG
78#include "bpfilter.h"
79#if NBPFILTER > 0
80#include <sys/time.h>
81#include <net/bpf.h>
82static caddr_t lo_bpf;
83#endif
84
b688fc87
WJ
85#define LOMTU (1024+512)
86
87struct ifnet loif;
88int looutput(), loioctl();
89
90loattach()
91{
92 register struct ifnet *ifp = &loif;
93
94 ifp->if_name = "lo";
95 ifp->if_mtu = LOMTU;
96 ifp->if_flags = IFF_LOOPBACK;
97 ifp->if_ioctl = loioctl;
98 ifp->if_output = looutput;
99 ifp->if_type = IFT_LOOP;
100 ifp->if_hdrlen = 0;
101 ifp->if_addrlen = 0;
102 if_attach(ifp);
3a1876f4
DG
103#if NBPFILTER > 0
104 bpfattach(&lo_bpf, ifp, DLT_NULL, sizeof(u_int));
105#endif
b688fc87
WJ
106}
107
108looutput(ifp, m, dst, rt)
109 struct ifnet *ifp;
110 register struct mbuf *m;
111 struct sockaddr *dst;
112 register struct rtentry *rt;
113{
114 int s, isr;
115 register struct ifqueue *ifq = 0;
116
117 if ((m->m_flags & M_PKTHDR) == 0)
118 panic("looutput no HDR");
3a1876f4
DG
119#if NBPFILTER > 0
120 if (lo_bpf) {
121 /*
122 * We need to prepend the address family as
123 * a four byte field. Cons up a dummy header
124 * to pacify bpf. This is safe because bpf
125 * will only read from the mbuf (i.e., it won't
126 * try to free it or keep a pointer to it).
127 */
128 struct mbuf m0;
129 u_int af = dst->sa_family;
130
131 m0.m_next = m;
132 m0.m_len = 4;
133 m0.m_data = (char *)&af;
134
135 bpf_mtap(lo_bpf, &m0);
136 }
137#endif
b688fc87
WJ
138 m->m_pkthdr.rcvif = ifp;
139
140 if (rt && rt->rt_flags & RTF_REJECT) {
141 m_freem(m);
142 return (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
143 }
144 ifp->if_opackets++;
145 ifp->if_obytes += m->m_pkthdr.len;
146 switch (dst->sa_family) {
147
148#ifdef INET
149 case AF_INET:
150 ifq = &ipintrq;
151 isr = NETISR_IP;
152 break;
153#endif
154#ifdef NS
155 case AF_NS:
156 ifq = &nsintrq;
157 isr = NETISR_NS;
158 break;
159#endif
160#ifdef ISO
161 case AF_ISO:
162 ifq = &clnlintrq;
163 isr = NETISR_ISO;
164 break;
165#endif
166 default:
167 printf("lo%d: can't handle af%d\n", ifp->if_unit,
168 dst->sa_family);
169 m_freem(m);
170 return (EAFNOSUPPORT);
171 }
172 s = splimp();
173 if (IF_QFULL(ifq)) {
174 IF_DROP(ifq);
175 m_freem(m);
176 splx(s);
177 return (ENOBUFS);
178 }
179 IF_ENQUEUE(ifq, m);
180 schednetisr(isr);
181 ifp->if_ipackets++;
182 ifp->if_ibytes += m->m_pkthdr.len;
183 splx(s);
184 return (0);
185}
186
187/* ARGSUSED */
188lortrequest(cmd, rt, sa)
189struct rtentry *rt;
190struct sockaddr *sa;
191{
192 if (rt)
193 rt->rt_rmx.rmx_mtu = LOMTU;
194}
195
196/*
197 * Process an ioctl request.
198 */
199/* ARGSUSED */
200loioctl(ifp, cmd, data)
201 register struct ifnet *ifp;
202 int cmd;
203 caddr_t data;
204{
205 register struct ifaddr *ifa;
206 int error = 0;
207
208 switch (cmd) {
209
210 case SIOCSIFADDR:
211 ifp->if_flags |= IFF_UP;
212 ifa = (struct ifaddr *)data;
213 if (ifa != 0 && ifa->ifa_addr->sa_family == AF_ISO)
214 ifa->ifa_rtrequest = lortrequest;
215 /*
216 * Everything else is done at a higher level.
217 */
218 break;
219
220 default:
221 error = EINVAL;
222 }
223 return (error);
224}