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