Commit | Line | Data |
---|---|---|
b11be056 | 1 | /* if_loop.c 6.1 83/07/29 */ |
0a486d2b BJ |
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" | |
1cc8c949 | 11 | #include "../h/errno.h" |
639a8848 | 12 | #include "../h/ioctl.h" |
1cc8c949 | 13 | |
0a486d2b | 14 | #include "../net/if.h" |
fcfe450e | 15 | #include "../net/netisr.h" |
1cc8c949 SL |
16 | #include "../net/route.h" |
17 | ||
18 | #include "../netinet/in.h" | |
19 | #include "../netinet/in_systm.h" | |
fcfe450e BJ |
20 | #include "../netinet/ip.h" |
21 | #include "../netinet/ip_var.h" | |
1cc8c949 | 22 | |
b152d3c4 SL |
23 | #ifdef vax |
24 | #include "../vax/mtpr.h" | |
25 | #endif | |
0a486d2b | 26 | |
0939c871 | 27 | #define LONET 127 |
40a41e8b | 28 | #define LOHOST 1 /* can't be 0, that's broadcast */ |
56e0df97 | 29 | #define LOMTU (1024+512) |
0a486d2b BJ |
30 | |
31 | struct ifnet loif; | |
639a8848 | 32 | int looutput(), loioctl(); |
0a486d2b BJ |
33 | |
34 | loattach() | |
35 | { | |
36 | register struct ifnet *ifp = &loif; | |
ee787340 | 37 | register struct sockaddr_in *sin; |
0a486d2b | 38 | |
b454c3ea | 39 | ifp->if_name = "lo"; |
0a486d2b BJ |
40 | ifp->if_mtu = LOMTU; |
41 | ifp->if_net = LONET; | |
40a41e8b | 42 | ifp->if_host[0] = LOHOST; |
ee787340 SL |
43 | sin = (struct sockaddr_in *)&ifp->if_addr; |
44 | sin->sin_family = AF_INET; | |
639a8848 SL |
45 | sin->sin_addr = if_makeaddr(LONET, LOHOST); |
46 | ifp->if_flags = IFF_UP | IFF_RUNNING; | |
47 | ifp->if_ioctl = loioctl; | |
0a486d2b | 48 | ifp->if_output = looutput; |
405c9168 | 49 | if_attach(ifp); |
a13c006d | 50 | if_rtinit(ifp, RTF_UP); |
0a486d2b BJ |
51 | } |
52 | ||
ee787340 | 53 | looutput(ifp, m0, dst) |
0a486d2b BJ |
54 | struct ifnet *ifp; |
55 | struct mbuf *m0; | |
ee787340 | 56 | struct sockaddr *dst; |
0a486d2b BJ |
57 | { |
58 | int s = splimp(); | |
1e977657 | 59 | register struct ifqueue *ifq; |
0a486d2b | 60 | |
b454c3ea | 61 | ifp->if_opackets++; |
ee787340 | 62 | switch (dst->sa_family) { |
0a486d2b BJ |
63 | |
64 | #ifdef INET | |
ee787340 | 65 | case AF_INET: |
1e977657 BJ |
66 | ifq = &ipintrq; |
67 | if (IF_QFULL(ifq)) { | |
68 | IF_DROP(ifq); | |
ee787340 | 69 | m_freem(m0); |
1e977657 | 70 | splx(s); |
4c5902e0 | 71 | return (ENOBUFS); |
1e977657 BJ |
72 | } |
73 | IF_ENQUEUE(ifq, m0); | |
9c8692e9 | 74 | schednetisr(NETISR_IP); |
0a486d2b BJ |
75 | break; |
76 | #endif | |
0a486d2b BJ |
77 | default: |
78 | splx(s); | |
ee787340 SL |
79 | printf("lo%d: can't handle af%d\n", ifp->if_unit, |
80 | dst->sa_family); | |
81 | m_freem(m0); | |
4c5902e0 | 82 | return (EAFNOSUPPORT); |
0a486d2b | 83 | } |
b454c3ea | 84 | ifp->if_ipackets++; |
0a486d2b | 85 | splx(s); |
4c5902e0 | 86 | return (0); |
0a486d2b | 87 | } |
639a8848 SL |
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 | } |