Commit | Line | Data |
---|---|---|
8ae0e4b4 KM |
1 | /* |
2 | * Copyright (c) 1982 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
484ee22e | 6 | * @(#)if_loop.c 6.9 (Berkeley) %G% |
8ae0e4b4 | 7 | */ |
0a486d2b BJ |
8 | |
9 | /* | |
10 | * Loopback interface driver for protocol testing and timing. | |
11 | */ | |
12 | ||
20666ad3 JB |
13 | #include "param.h" |
14 | #include "systm.h" | |
15 | #include "mbuf.h" | |
16 | #include "socket.h" | |
17 | #include "errno.h" | |
18 | #include "ioctl.h" | |
1cc8c949 | 19 | |
0a486d2b | 20 | #include "../net/if.h" |
fcfe450e | 21 | #include "../net/netisr.h" |
1cc8c949 SL |
22 | #include "../net/route.h" |
23 | ||
dbc42650 MK |
24 | #ifdef INET |
25 | #include "../netinet/in.h" | |
26 | #include "../netinet/in_systm.h" | |
27 | #include "../netinet/ip.h" | |
28 | #include "../netinet/ip_var.h" | |
29 | #endif | |
1cc8c949 | 30 | |
b152d3c4 SL |
31 | #ifdef vax |
32 | #include "../vax/mtpr.h" | |
33 | #endif | |
0a486d2b | 34 | |
edecfd58 KS |
35 | #ifdef NS |
36 | #include "../netns/ns.h" | |
37 | #include "../netns/ns_if.h" | |
38 | #endif | |
39 | ||
56e0df97 | 40 | #define LOMTU (1024+512) |
0a486d2b BJ |
41 | |
42 | struct ifnet loif; | |
639a8848 | 43 | int looutput(), loioctl(); |
0a486d2b BJ |
44 | |
45 | loattach() | |
46 | { | |
47 | register struct ifnet *ifp = &loif; | |
48 | ||
b454c3ea | 49 | ifp->if_name = "lo"; |
0a486d2b | 50 | ifp->if_mtu = LOMTU; |
484ee22e | 51 | ifp->if_flags = IFF_LOOPBACK; |
639a8848 | 52 | ifp->if_ioctl = loioctl; |
0a486d2b | 53 | ifp->if_output = looutput; |
405c9168 | 54 | if_attach(ifp); |
0a486d2b BJ |
55 | } |
56 | ||
ee787340 | 57 | looutput(ifp, m0, dst) |
0a486d2b | 58 | struct ifnet *ifp; |
dbc42650 | 59 | register struct mbuf *m0; |
ee787340 | 60 | struct sockaddr *dst; |
0a486d2b | 61 | { |
dbc42650 | 62 | int s; |
1e977657 | 63 | register struct ifqueue *ifq; |
dbc42650 MK |
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(); | |
b454c3ea | 85 | ifp->if_opackets++; |
ee787340 | 86 | switch (dst->sa_family) { |
0a486d2b BJ |
87 | |
88 | #ifdef INET | |
ee787340 | 89 | case AF_INET: |
1e977657 BJ |
90 | ifq = &ipintrq; |
91 | if (IF_QFULL(ifq)) { | |
92 | IF_DROP(ifq); | |
ee787340 | 93 | m_freem(m0); |
1e977657 | 94 | splx(s); |
4c5902e0 | 95 | return (ENOBUFS); |
1e977657 BJ |
96 | } |
97 | IF_ENQUEUE(ifq, m0); | |
9c8692e9 | 98 | schednetisr(NETISR_IP); |
0a486d2b | 99 | break; |
edecfd58 KS |
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; | |
0a486d2b | 113 | #endif |
0a486d2b BJ |
114 | default: |
115 | splx(s); | |
ee787340 SL |
116 | printf("lo%d: can't handle af%d\n", ifp->if_unit, |
117 | dst->sa_family); | |
118 | m_freem(m0); | |
4c5902e0 | 119 | return (EAFNOSUPPORT); |
0a486d2b | 120 | } |
b454c3ea | 121 | ifp->if_ipackets++; |
0a486d2b | 122 | splx(s); |
4c5902e0 | 123 | return (0); |
0a486d2b | 124 | } |
639a8848 SL |
125 | |
126 | /* | |
127 | * Process an ioctl request. | |
128 | */ | |
bba52753 | 129 | /* ARGSUSED */ |
639a8848 SL |
130 | loioctl(ifp, cmd, data) |
131 | register struct ifnet *ifp; | |
132 | int cmd; | |
133 | caddr_t data; | |
134 | { | |
bba52753 | 135 | int error = 0; |
639a8848 SL |
136 | |
137 | switch (cmd) { | |
138 | ||
139 | case SIOCSIFADDR: | |
bba52753 MK |
140 | ifp->if_flags |= IFF_UP; |
141 | /* | |
142 | * Everything else is done at a higher level. | |
143 | */ | |
639a8848 SL |
144 | break; |
145 | ||
146 | default: | |
147 | error = EINVAL; | |
148 | } | |
639a8848 SL |
149 | return (error); |
150 | } |