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