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