]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/if_disc.c
41c2be131d38c75556fc644b463806817817845e
[apple/xnu.git] / bsd / net / if_disc.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Copyright (c) 1982, 1986, 1993
25 * The Regents of the University of California. All rights reserved.
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 * From: @(#)if_loop.c 8.1 (Berkeley) 6/10/93
56 * $FreeBSD: src/sys/net/if_disc.c,v 1.26.2.1 2001/03/06 00:32:09 obrien Exp $
57 */
58
59 /*
60 * Discard interface driver for protocol testing and timing.
61 * (Based on the loopback.)
62 */
63
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/kernel.h>
67 #include <sys/mbuf.h>
68 #include <sys/socket.h>
69 #include <sys/sockio.h>
70
71 #include <net/if.h>
72 #include <net/if_types.h>
73 #include <net/route.h>
74 #include <net/bpf.h>
75
76 #ifdef TINY_DSMTU
77 #define DSMTU (1024+512)
78 #else
79 #define DSMTU 65532
80 #endif
81
82 static void discattach(void);
83
84 static struct ifnet discif;
85 static int discoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
86 struct rtentry *);
87 static void discrtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa);
88 static int discioctl(struct ifnet *, u_long, caddr_t);
89
90 /* ARGSUSED */
91 static void
92 discattach()
93 {
94 register struct ifnet *ifp = &discif;
95
96 ifp->if_name = "ds";
97 ifp->if_family = APPLE_IF_FAM_DISC;
98 ifp->if_mtu = DSMTU;
99 ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
100 ifp->if_ioctl = discioctl;
101 ifp->if_output = discoutput;
102 ifp->if_type = IFT_LOOP;
103 ifp->if_hdrlen = 0;
104 ifp->if_addrlen = 0;
105 if_attach(ifp);
106 bpfattach(ifp, DLT_NULL, sizeof(u_int));
107 }
108
109 #ifndef __APPLE__
110 static int
111 disc_modevent(module_t mod, int type, void *data)
112 {
113 switch (type) {
114 case MOD_LOAD:
115 discattach();
116 break;
117 case MOD_UNLOAD:
118 printf("if_disc module unload - not possible for this module type\n");
119 return EINVAL;
120 }
121 return 0;
122 }
123
124 static moduledata_t disc_mod = {
125 "if_disc",
126 disc_modevent,
127 NULL
128 };
129
130 DECLARE_MODULE(if_disc, disc_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
131 #endif
132
133 static int
134 discoutput(ifp, m, dst, rt)
135 struct ifnet *ifp;
136 register struct mbuf *m;
137 struct sockaddr *dst;
138 register struct rtentry *rt;
139 {
140 if ((m->m_flags & M_PKTHDR) == 0)
141 panic("discoutput no HDR");
142 /* BPF write needs to be handled specially */
143 if (dst->sa_family == AF_UNSPEC) {
144 dst->sa_family = *(mtod(m, int *));
145 m->m_len -= sizeof(int);
146 m->m_pkthdr.len -= sizeof(int);
147 m->m_data += sizeof(int);
148 }
149
150 if (discif.if_bpf) {
151 /*
152 * We need to prepend the address family as
153 * a four byte field. Cons up a dummy header
154 * to pacify bpf. This is safe because bpf
155 * will only read from the mbuf (i.e., it won't
156 * try to free it or keep a pointer a to it).
157 */
158 struct mbuf m0;
159 u_int af = dst->sa_family;
160
161 m0.m_next = m;
162 m0.m_len = 4;
163 m0.m_data = (char *)&af;
164
165 bpf_mtap(&discif, &m0);
166 }
167 m->m_pkthdr.rcvif = ifp;
168
169 ifp->if_opackets++;
170 ifp->if_obytes += m->m_pkthdr.len;
171
172 m_freem(m);
173 return 0;
174 }
175
176 /* ARGSUSED */
177 static void
178 discrtrequest(cmd, rt, sa)
179 int cmd;
180 struct rtentry *rt;
181 struct sockaddr *sa;
182 {
183 if (rt)
184 rt->rt_rmx.rmx_mtu = DSMTU;
185 }
186
187 /*
188 * Process an ioctl request.
189 */
190 /* ARGSUSED */
191 static int
192 discioctl(ifp, cmd, data)
193 register struct ifnet *ifp;
194 u_long cmd;
195 caddr_t data;
196 {
197 register struct ifaddr *ifa;
198 register struct ifreq *ifr = (struct ifreq *)data;
199 register int error = 0;
200
201 switch (cmd) {
202
203 case SIOCSIFADDR:
204 ifnet_set_flags(ifp, IFF_UP, IFF_UP);
205 ifa = (struct ifaddr *)data;
206 if (ifa != 0)
207 ifa->ifa_rtrequest = discrtrequest;
208 /*
209 * Everything else is done at a higher level.
210 */
211 break;
212
213 case SIOCADDMULTI:
214 case SIOCDELMULTI:
215 if (ifr == 0) {
216 error = EAFNOSUPPORT; /* XXX */
217 break;
218 }
219 switch (ifr->ifr_addr.sa_family) {
220
221 #if INET
222 case AF_INET:
223 break;
224 #endif
225 #if INET6
226 case AF_INET6:
227 break;
228 #endif
229
230 default:
231 error = EAFNOSUPPORT;
232 break;
233 }
234 break;
235
236 case SIOCSIFMTU:
237 ifp->if_mtu = ifr->ifr_mtu;
238 break;
239
240 default:
241 error = EINVAL;
242 }
243 return (error);
244 }