|
|
1.1 root 1: /* if_loop.c 6.1 83/07/29 */
2:
3: /*
4: * Loopback interface driver for protocol testing and timing.
5: */
6:
7: #include "../h/param.h"
8: #include "../h/systm.h"
9: #include "../h/mbuf.h"
10: #include "../h/socket.h"
11: #include "../h/errno.h"
12: #include "../h/ioctl.h"
13:
14: #include "../net/if.h"
15: #include "../net/netisr.h"
16: #include "../net/route.h"
17:
18: #include "../netinet/in.h"
19: #include "../netinet/in_systm.h"
20: #include "../netinet/ip.h"
21: #include "../netinet/ip_var.h"
22:
23: #ifdef vax
24: #include "../vax/mtpr.h"
25: #endif
26:
27: #define LONET 127
28: #define LOHOST 1 /* can't be 0, that's broadcast */
29: #define LOMTU (1024+512)
30:
31: struct ifnet loif;
32: int looutput(), loioctl();
33:
34: loattach()
35: {
36: register struct ifnet *ifp = &loif;
37: register struct sockaddr_in *sin;
38:
39: ifp->if_name = "lo";
40: ifp->if_mtu = LOMTU;
41: ifp->if_net = LONET;
42: ifp->if_host[0] = LOHOST;
43: sin = (struct sockaddr_in *)&ifp->if_addr;
44: sin->sin_family = AF_INET;
45: sin->sin_addr = if_makeaddr(LONET, LOHOST);
46: ifp->if_flags = IFF_UP | IFF_RUNNING;
47: ifp->if_ioctl = loioctl;
48: ifp->if_output = looutput;
49: if_attach(ifp);
50: if_rtinit(ifp, RTF_UP);
51: }
52:
53: looutput(ifp, m0, dst)
54: struct ifnet *ifp;
55: struct mbuf *m0;
56: struct sockaddr *dst;
57: {
58: int s = splimp();
59: register struct ifqueue *ifq;
60:
61: ifp->if_opackets++;
62: switch (dst->sa_family) {
63:
64: #ifdef INET
65: case AF_INET:
66: ifq = &ipintrq;
67: if (IF_QFULL(ifq)) {
68: IF_DROP(ifq);
69: m_freem(m0);
70: splx(s);
71: return (ENOBUFS);
72: }
73: IF_ENQUEUE(ifq, m0);
74: schednetisr(NETISR_IP);
75: break;
76: #endif
77: default:
78: splx(s);
79: printf("lo%d: can't handle af%d\n", ifp->if_unit,
80: dst->sa_family);
81: m_freem(m0);
82: return (EAFNOSUPPORT);
83: }
84: ifp->if_ipackets++;
85: splx(s);
86: return (0);
87: }
88:
89: /*
90: * Process an ioctl request.
91: */
92: loioctl(ifp, cmd, data)
93: register struct ifnet *ifp;
94: int cmd;
95: caddr_t data;
96: {
97: struct ifreq *ifr = (struct ifreq *)data;
98: struct sockaddr_in *sin;
99: int s = splimp(), error = 0;
100:
101: switch (cmd) {
102:
103: case SIOCSIFADDR:
104: if (ifp->if_flags & IFF_RUNNING)
105: if_rtinit(ifp, -1); /* delete previous route */
106: ifp->if_addr = ifr->ifr_addr;
107: sin = (struct sockaddr_in *)&ifp->if_addr;
108: ifp->if_net = in_netof(sin->sin_addr);
109: ifp->if_host[0] = in_lnaof(sin->sin_addr);
110: if_rtinit(ifp, RTF_UP);
111: break;
112:
113: default:
114: error = EINVAL;
115: }
116: splx(s);
117: return (error);
118: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.