1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)if_loop.c 7.1 (Berkeley) 6/4/86
7: */
8:
9: /*
10: * Loopback interface driver for protocol testing and timing.
11: */
12:
13: #include "param.h"
14: #include "systm.h"
15: #include "mbuf.h"
16: #include "socket.h"
17: #include "errno.h"
18: #include "ioctl.h"
19:
20: #include "../net/if.h"
21: #include "../net/netisr.h"
22: #include "../net/route.h"
23:
24: #ifdef INET
25: #include "../netinet/in.h"
26: #include "../netinet/in_systm.h"
27: #include "../netinet/in_var.h"
28: #include "../netinet/ip.h"
29: #endif
30:
31: #ifdef vax
32: #include "../vax/mtpr.h"
33: #endif
34:
35: #ifdef NS
36: #include "../netns/ns.h"
37: #include "../netns/ns_if.h"
38: #endif
39:
40: #define LOMTU (1024+512)
41:
42: struct ifnet loif;
43: int looutput(), loioctl();
44:
45: loattach()
46: {
47: register struct ifnet *ifp = &loif;
48:
49: ifp->if_name = "lo";
50: ifp->if_mtu = LOMTU;
51: ifp->if_flags = IFF_LOOPBACK;
52: ifp->if_ioctl = loioctl;
53: ifp->if_output = looutput;
54: if_attach(ifp);
55: }
56:
57: looutput(ifp, m0, dst)
58: struct ifnet *ifp;
59: register struct mbuf *m0;
60: struct sockaddr *dst;
61: {
62: int s;
63: register struct ifqueue *ifq;
64: struct mbuf *m;
65:
66: /*
67: * Place interface pointer before the data
68: * for the receiving protocol.
69: */
70: if (m0->m_off <= MMAXOFF &&
71: m0->m_off >= MMINOFF + sizeof(struct ifnet *)) {
72: m0->m_off -= sizeof(struct ifnet *);
73: m0->m_len += sizeof(struct ifnet *);
74: } else {
75: MGET(m, M_DONTWAIT, MT_HEADER);
76: if (m == (struct mbuf *)0)
77: return (ENOBUFS);
78: m->m_off = MMINOFF;
79: m->m_len = sizeof(struct ifnet *);
80: m->m_next = m0;
81: m0 = m;
82: }
83: *(mtod(m0, struct ifnet **)) = ifp;
84: s = splimp();
85: ifp->if_opackets++;
86: switch (dst->sa_family) {
87:
88: #ifdef INET
89: case AF_INET:
90: ifq = &ipintrq;
91: if (IF_QFULL(ifq)) {
92: IF_DROP(ifq);
93: m_freem(m0);
94: splx(s);
95: return (ENOBUFS);
96: }
97: IF_ENQUEUE(ifq, m0);
98: schednetisr(NETISR_IP);
99: break;
100: #endif
101: #ifdef NS
102: case AF_NS:
103: ifq = &nsintrq;
104: if (IF_QFULL(ifq)) {
105: IF_DROP(ifq);
106: m_freem(m0);
107: splx(s);
108: return (ENOBUFS);
109: }
110: IF_ENQUEUE(ifq, m0);
111: schednetisr(NETISR_NS);
112: break;
113: #endif
114: default:
115: splx(s);
116: printf("lo%d: can't handle af%d\n", ifp->if_unit,
117: dst->sa_family);
118: m_freem(m0);
119: return (EAFNOSUPPORT);
120: }
121: ifp->if_ipackets++;
122: splx(s);
123: return (0);
124: }
125:
126: /*
127: * Process an ioctl request.
128: */
129: /* ARGSUSED */
130: loioctl(ifp, cmd, data)
131: register struct ifnet *ifp;
132: int cmd;
133: caddr_t data;
134: {
135: int error = 0;
136:
137: switch (cmd) {
138:
139: case SIOCSIFADDR:
140: ifp->if_flags |= IFF_UP;
141: /*
142: * Everything else is done at a higher level.
143: */
144: break;
145:
146: default:
147: error = EINVAL;
148: }
149: return (error);
150: }
Defined functions
Defined variables
loif
defined in line
42; used 8 times
Defined macros
LOMTU
defined in line
40; used 1 times