|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution is only permitted until one year after the first shipment
6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
7: * binary forms are permitted provided that: (1) source distributions retain
8: * this entire copyright notice and comment, and (2) distributions including
9: * binaries display the following acknowledgement: This product includes
10: * software developed by the University of California, Berkeley and its
11: * contributors'' in the documentation or other materials provided with the
12: * distribution and in all advertising materials mentioning features or use
13: * of this software. Neither the name of the University nor the names of
14: * its contributors may be used to endorse or promote products derived from
15: * this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: *
20: * @(#)if_loop.c 7.10 (Berkeley) 6/28/90
21: */
22:
23: /*
24: * Loopback interface driver for protocol testing and timing.
25: */
26:
27: #include "param.h"
28: #include "systm.h"
29: #include "mbuf.h"
30: #include "socket.h"
31: #include "errno.h"
32: #include "ioctl.h"
33:
34: #include "../net/if.h"
35: #include "../net/if_types.h"
36: #include "../net/netisr.h"
37: #include "../net/route.h"
38:
39: #include "machine/mtpr.h"
40:
41: #ifdef INET
42: #include "../netinet/in.h"
43: #include "../netinet/in_systm.h"
44: #include "../netinet/in_var.h"
45: #include "../netinet/ip.h"
46: #endif
47:
48: #ifdef NS
49: #include "../netns/ns.h"
50: #include "../netns/ns_if.h"
51: #endif
52:
53: #ifdef ISO
54: #include "../netiso/iso.h"
55: #include "../netiso/iso_var.h"
56: #endif
57:
58: #define LOMTU (1024+512)
59:
60: struct ifnet loif;
61: int looutput(), loioctl();
62:
63: loattach()
64: {
65: register struct ifnet *ifp = &loif;
66:
67: ifp->if_name = "lo";
68: ifp->if_mtu = LOMTU;
69: ifp->if_flags = IFF_LOOPBACK;
70: ifp->if_ioctl = loioctl;
71: ifp->if_output = looutput;
72: ifp->if_type = IFT_LOOP;
73: ifp->if_hdrlen = 0;
74: ifp->if_addrlen = 0;
75: if_attach(ifp);
76: }
77:
78: struct mbuf *Loop_Sanity;
79:
80: looutput(ifp, m, dst)
81: struct ifnet *ifp;
82: register struct mbuf *m;
83: struct sockaddr *dst;
84: {
85: int s;
86: register struct ifqueue *ifq;
87:
88: if ((m->m_flags & M_PKTHDR) == 0)
89: panic("looutput no HDR");
90: m->m_pkthdr.rcvif = ifp;
91:
92: {struct mbuf *mm; int mlen = 0;
93: for (mm = m; m; m = m->m_next) /* XXX debugging code -- sklower */
94: mlen += m->m_len;
95: m = mm;
96: if (mlen != m->m_pkthdr.len) {
97: if (Loop_Sanity)
98: m_freem(Loop_Sanity);
99: Loop_Sanity = m_copy(m, 0, (int)M_COPYALL);
100: }
101: }
102:
103: s = splimp();
104: ifp->if_opackets++;
105: ifp->if_obytes += m->m_pkthdr.len;
106: switch (dst->sa_family) {
107:
108: #ifdef INET
109: case AF_INET:
110: ifq = &ipintrq;
111: if (IF_QFULL(ifq)) {
112: IF_DROP(ifq);
113: m_freem(m);
114: splx(s);
115: return (ENOBUFS);
116: }
117: IF_ENQUEUE(ifq, m);
118: schednetisr(NETISR_IP);
119: break;
120: #endif
121: #ifdef NS
122: case AF_NS:
123: ifq = &nsintrq;
124: if (IF_QFULL(ifq)) {
125: IF_DROP(ifq);
126: m_freem(m);
127: splx(s);
128: return (ENOBUFS);
129: }
130: IF_ENQUEUE(ifq, m);
131: schednetisr(NETISR_NS);
132: break;
133: #endif
134: #ifdef ISO
135: case AF_ISO:
136: ifq = &clnlintrq;
137: if (IF_QFULL(ifq)) {
138: IF_DROP(ifq);
139: m_freem(m);
140: splx(s);
141: return (ENOBUFS);
142: }
143: IF_ENQUEUE(ifq, m);
144: schednetisr(NETISR_ISO);
145: break;
146: #endif
147: default:
148: splx(s);
149: printf("lo%d: can't handle af%d\n", ifp->if_unit,
150: dst->sa_family);
151: m_freem(m);
152: return (EAFNOSUPPORT);
153: }
154: ifp->if_ipackets++;
155: ifp->if_ibytes += m->m_pkthdr.len;
156: splx(s);
157: return (0);
158: }
159:
160: /*
161: * Process an ioctl request.
162: */
163: /* ARGSUSED */
164: loioctl(ifp, cmd, data)
165: register struct ifnet *ifp;
166: int cmd;
167: caddr_t data;
168: {
169: int error = 0;
170:
171: switch (cmd) {
172:
173: case SIOCSIFADDR:
174: ifp->if_flags |= IFF_UP;
175: /*
176: * Everything else is done at a higher level.
177: */
178: break;
179:
180: default:
181: error = EINVAL;
182: }
183: return (error);
184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.