2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1982, 1986, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * @(#)if_loop.c 8.1 (Berkeley) 6/10/93
58 * Loopback interface driver for protocol testing and timing.
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
67 #include <sys/socket.h>
68 #include <sys/sockio.h>
71 #include <net/if_types.h>
72 #include <net/netisr.h>
73 #include <net/route.h>
75 #include <sys/malloc.h>
78 #include <netinet/in.h>
79 #include <netinet/in_var.h>
83 #include <netipx/ipx.h>
84 #include <netipx/ipx_if.h>
89 #include <netinet/in.h>
91 #include <netinet6/in6_var.h>
92 #include <netinet/ip6.h>
97 #include <netns/ns_if.h>
101 #include <netiso/iso.h>
102 #include <netiso/iso_var.h>
105 #include <net/dlil.h>
108 extern struct ifqueue atalkintrq
;
111 #include "bpfilter.h"
113 #include <net/bpfdesc.h>
116 #define NLOOP_ATTACHMENTS (NLOOP * 12)
118 struct lo_statics_str
{
120 int (*bpf_callback
)(struct ifnet
*, struct mbuf
*);
123 static struct if_proto
*lo_array
[NLOOP_ATTACHMENTS
];
124 static struct lo_statics_str lo_statics
[NLOOP
];
129 #define LOMTU (1024+512)
134 struct ifnet loif
[NLOOP
];
136 void lo_reg_if_mods();
141 int lo_demux(ifp
, m
, frame_header
, proto
)
145 struct if_proto
**proto
;
148 struct if_proto
**proto_ptr
;
150 proto_ptr
= mtod(m
, struct if_proto
**);
152 m_adj(m
, sizeof(u_long
));
157 int lo_framer(ifp
, m
, dest
, dest_linkaddr
, frame_type
)
160 struct sockaddr
*dest
;
167 M_PREPEND(*m
, (4 * sizeof(u_long
)), M_WAITOK
);
168 to_ptr
= mtod(*m
, char *);
169 bcopy(dest_linkaddr
, to_ptr
, (4 * sizeof(u_long
)));
174 int lo_add_if(struct ifnet
*ifp
)
176 ifp
->if_demux
= lo_demux
;
177 ifp
->if_framer
= lo_framer
;
183 int lo_del_if(struct ifnet
*ifp
)
192 int lo_add_proto(struct ddesc_head_str
*desc_head
, struct if_proto
*proto
, u_long dl_tag
)
196 for (i
=0; i
< lo_count
; i
++)
197 if (lo_array
[i
] == 0) {
198 lo_array
[lo_count
] = proto
;
202 if ((i
== lo_count
) && (lo_count
== NLOOP_ATTACHMENTS
))
203 panic("lo_add_proto -- Too many attachments\n");
205 lo_array
[lo_count
++] = proto
;
211 int lo_del_proto(struct if_proto
*proto
, u_long dl_tag
)
215 for (i
=0; i
< lo_count
; i
++)
216 if (lo_array
[i
] == proto
) {
227 register struct mbuf
*m
;
228 { u_int
*prepend_ptr
;
230 u_long saved_header
[3];
232 if ((m
->m_flags
& M_PKTHDR
) == 0)
233 panic("lo_output: no HDR");
236 * Don't overwrite the rcvif field if it is in use.
237 * This is used to match multicast packets, sent looping
238 * back, with the appropriate group record on input.
240 if (m
->m_pkthdr
.rcvif
== NULL
)
241 m
->m_pkthdr
.rcvif
= ifp
;
242 prepend_ptr
= mtod(m
, u_int
*);
244 m_adj(m
, sizeof(u_int
));
248 if (lo_statics
[ifp
->if_unit
].bpf_mode
!= BPF_TAP_DISABLE
) {
251 bcopy(mtod(m
, caddr_t
), &saved_header
[0], (3 * sizeof(u_long
)));
252 m_adj(m
, (3 * sizeof(u_long
)));
255 if (ifp
->if_bpf
->bif_dlt
== DLT_NULL
) {
257 * We need to prepend the address family as
258 * a four byte field. Cons up a dummy header
259 * to pacify bpf. This is safe because bpf
260 * will only read from the mbuf (i.e., it won't
261 * try to free it or keep a pointer a to it).
265 m0
.m_data
= (char *)&af
;
269 (*lo_statics
[ifp
->if_unit
].bpf_callback
)(ifp
, n
);
271 M_PREPEND(m
, (3 * sizeof(u_long
)), M_WAITOK
);
272 bcopy(&saved_header
[0], mtod(m
, caddr_t
), (3 * sizeof(u_long
)));
277 ifp
->if_ibytes
+= m
->m_pkthdr
.len
;
278 ifp
->if_obytes
+= m
->m_pkthdr
.len
;
284 * This won't work for loopbacked multicast
286 m
->m_pkthdr
.header
= mtod(m
, char *);
287 m
->m_pkthdr
.aux
= ifp
; /* HACKERY */
288 return dlil_input(ifp
, m
, m
);
293 * This is a common pre-output route used by INET, AT, etc. This could
294 * (should?) be split into separate pre-output routines for each protocol.
298 lo_pre_output(ifp
, m
, dst
, route
, frame_type
, dst_addr
, dl_tag
)
300 register struct mbuf
**m
;
301 struct sockaddr
*dst
;
309 register struct ifqueue
*ifq
= 0;
311 register struct rtentry
*rt
= (struct rtentry
*) route
;
313 prepend_ptr
= (u_long
*) dst_addr
;
314 if (((*m
)->m_flags
& M_PKTHDR
) == 0)
315 panic("looutput no HDR");
317 if (rt
&& rt
->rt_flags
& (RTF_REJECT
|RTF_BLACKHOLE
)) {
318 if (rt
->rt_flags
& RTF_BLACKHOLE
) {
323 return ((rt
->rt_flags
& RTF_HOST
) ? EHOSTUNREACH
: ENETUNREACH
);
326 switch (dst
->sa_family
) {
360 isr
= NETISR_APPLETALK
;
364 return (EAFNOSUPPORT
);
367 *prepend_ptr
++ = dst
->sa_family
; /* For lo_output(BPF) */
368 *prepend_ptr
++ = dlttoproto(dl_tag
); /* For lo_demux */
369 *prepend_ptr
++ = (u_long
) ifq
; /* For lo_input */
370 *prepend_ptr
= isr
; /* For lo_input */
379 * lo_input - This should work for all attached protocols that use the
380 * ifq/schednetisr input mechanism.
385 lo_input(m
, fh
, ifp
, dl_tag
, sync_ok
)
386 register struct mbuf
*m
;
395 register struct ifqueue
*ifq
= 0;
397 prepend_ptr
= mtod(m
, u_long
*);
398 ifq
= (struct ifqueue
*) *prepend_ptr
++;
400 m_adj(m
, (2 * sizeof(u_long
)));
407 return (EJUSTRETURN
);
421 lortrequest(cmd
, rt
, sa
)
427 rt
->rt_rmx
.rmx_mtu
= rt
->rt_ifp
->if_mtu
; /* for ISO */
429 * For optimal performance, the send and receive buffers
430 * should be at least twice the MTU plus a little more for
433 rt
->rt_rmx
.rmx_recvpipe
=
434 rt
->rt_rmx
.rmx_sendpipe
= 3 * LOMTU
;
439 * Process an ioctl request.
443 loioctl(dl_tag
, ifp
, cmd
, data
)
445 register struct ifnet
*ifp
;
449 register struct ifaddr
*ifa
;
450 register struct ifreq
*ifr
= (struct ifreq
*)data
;
451 register int error
= 0;
456 ifp
->if_flags
|= IFF_UP
| IFF_RUNNING
;
457 ifa
= (struct ifaddr
*)data
;
458 ifa
->ifa_rtrequest
= lortrequest
;
460 * Everything else is done at a higher level.
467 error
= EAFNOSUPPORT
; /* XXX */
470 switch (ifr
->ifr_addr
.sa_family
) {
482 error
= EAFNOSUPPORT
;
488 ifp
->if_mtu
= ifr
->ifr_mtu
;
499 #endif /* NLOOP > 0 */
508 void lo_reg_if_mods()
510 struct dlil_ifmod_reg_str lo_ifmod
;
512 lo_ifmod
.add_if
= lo_add_if
;
513 lo_ifmod
.del_if
= lo_del_if
;
514 lo_ifmod
.add_proto
= lo_add_proto
;
515 lo_ifmod
.del_proto
= lo_del_proto
;
516 lo_ifmod
.ifmod_ioctl
= 0;
517 lo_ifmod
.shutdown
= lo_shutdown
;
519 if (dlil_reg_if_modules(APPLE_IF_FAM_LOOPBACK
, &lo_ifmod
))
520 panic("Couldn't register lo modules\n");
524 u_long
lo_attach_inet(struct ifnet
*ifp
)
526 struct dlil_proto_reg_str reg
;
527 struct dlil_demux_desc desc
;
533 for (i
=0; i
< lo_count
; i
++) {
534 if ((lo_array
[i
]) && (lo_array
[i
]->ifp
== ifp
)) {
535 if (lo_array
[i
]->protocol_family
== PF_INET
)
536 return lo_array
[i
]->dl_tag
;
540 TAILQ_INIT(®
.demux_desc_head
);
541 desc
.type
= DLIL_DESC_RAW
;
542 desc
.variants
.bitmask
.proto_id_length
= 0;
543 desc
.variants
.bitmask
.proto_id
= 0;
544 desc
.variants
.bitmask
.proto_id_mask
= 0;
545 desc
.native_type
= (char *) &native
;
546 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
547 reg
.interface_family
= ifp
->if_family
;
548 reg
.unit_number
= ifp
->if_unit
;
549 reg
.input
= lo_input
;
550 reg
.pre_output
= lo_pre_output
;
554 reg
.default_proto
= 0;
555 reg
.protocol_family
= PF_INET
;
557 stat
= dlil_attach_protocol(®
, &dl_tag
);
559 panic("lo_attach_inet can't attach interface\n");
566 int lo_set_bpf_tap(struct ifnet
*ifp
, int mode
, int (*bpf_callback
)(struct ifnet
*, struct mbuf
*))
570 * NEED MUTEX HERE XXX
572 if (mode
== BPF_TAP_DISABLE
) {
573 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
574 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
577 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
578 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
590 register struct ifnet
*ifp
;
593 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
596 for (ifp
= loif
; i
< NLOOP
; ifp
++) {
597 lo_statics
[i
].bpf_callback
= 0;
598 lo_statics
[i
].bpf_mode
= BPF_TAP_DISABLE
;
600 ifp
->if_family
= APPLE_IF_FAM_LOOPBACK
;
603 ifp
->if_flags
= IFF_LOOPBACK
| IFF_MULTICAST
;
605 ifp
->if_set_bpf_tap
= lo_set_bpf_tap
;
606 ifp
->if_output
= lo_output
;
607 ifp
->if_type
= IFT_LOOP
;
610 bpfattach(ifp
, DLT_NULL
, sizeof(u_int
));
613 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);