2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1982, 1986, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * @(#)if_loop.c 8.1 (Berkeley) 6/10/93
58 * $FreeBSD: src/sys/net/if_loop.c,v 1.47.2.5 2001/07/03 11:01:41 ume Exp $
62 * Loopback interface driver for protocol testing and timing.
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/kernel.h>
71 #include <sys/socket.h>
72 #include <sys/sockio.h>
75 #include <net/if_types.h>
76 #include <net/netisr.h>
77 #include <net/route.h>
79 #include <sys/malloc.h>
82 #include <netinet/in.h>
83 #include <netinet/in_var.h>
87 #include <netipx/ipx.h>
88 #include <netipx/ipx_if.h>
93 #include <netinet/in.h>
95 #include <netinet6/in6_var.h>
96 #include <netinet/ip6.h>
102 extern struct ifqueue atalkintrq
;
105 #include "bpfilter.h"
107 #include <net/bpfdesc.h>
110 #define NLOOP_ATTACHMENTS (NLOOP * 12)
112 struct lo_statics_str
{
114 int (*bpf_callback
)(struct ifnet
*, struct mbuf
*);
117 static struct if_proto
*lo_array
[NLOOP_ATTACHMENTS
];
118 static struct lo_statics_str lo_statics
[NLOOP
];
123 #define LOMTU (1024+512)
128 struct ifnet loif
[NLOOP
];
130 void lo_reg_if_mods();
135 int lo_demux(ifp
, m
, frame_header
, proto
)
139 struct if_proto
**proto
;
142 struct if_proto
**proto_ptr
;
144 proto_ptr
= mtod(m
, struct if_proto
**);
146 m_adj(m
, sizeof(u_long
));
151 int lo_framer(ifp
, m
, dest
, dest_linkaddr
, frame_type
)
154 struct sockaddr
*dest
;
161 M_PREPEND(*m
, (4 * sizeof(u_long
)), M_WAITOK
);
162 to_ptr
= mtod(*m
, char *);
163 bcopy(dest_linkaddr
, to_ptr
, (4 * sizeof(u_long
)));
168 int lo_add_if(struct ifnet
*ifp
)
170 ifp
->if_demux
= lo_demux
;
171 ifp
->if_framer
= lo_framer
;
177 int lo_del_if(struct ifnet
*ifp
)
186 int lo_add_proto(struct ddesc_head_str
*desc_head
, struct if_proto
*proto
, u_long dl_tag
)
190 for (i
=0; i
< lo_count
; i
++)
191 if (lo_array
[i
] == 0) {
192 lo_array
[lo_count
] = proto
;
196 if ((i
== lo_count
) && (lo_count
== NLOOP_ATTACHMENTS
))
197 panic("lo_add_proto -- Too many attachments\n");
199 lo_array
[lo_count
++] = proto
;
205 int lo_del_proto(struct if_proto
*proto
, u_long dl_tag
)
209 for (i
=0; i
< lo_count
; i
++)
210 if (lo_array
[i
] == proto
) {
221 register struct mbuf
*m
;
222 { u_int
*prepend_ptr
;
224 u_long saved_header
[3];
226 if ((m
->m_flags
& M_PKTHDR
) == 0)
227 panic("lo_output: no HDR");
230 * Don't overwrite the rcvif field if it is in use.
231 * This is used to match multicast packets, sent looping
232 * back, with the appropriate group record on input.
234 if (m
->m_pkthdr
.rcvif
== NULL
)
235 m
->m_pkthdr
.rcvif
= ifp
;
236 prepend_ptr
= mtod(m
, u_int
*);
238 m_adj(m
, sizeof(u_int
));
242 if (lo_statics
[ifp
->if_unit
].bpf_mode
!= BPF_TAP_DISABLE
) {
245 bcopy(mtod(m
, caddr_t
), &saved_header
[0], (3 * sizeof(u_long
)));
246 m_adj(m
, (3 * sizeof(u_long
)));
249 if (ifp
->if_bpf
->bif_dlt
== DLT_NULL
) {
251 * We need to prepend the address family as
252 * a four byte field. Cons up a dummy header
253 * to pacify bpf. This is safe because bpf
254 * will only read from the mbuf (i.e., it won't
255 * try to free it or keep a pointer a to it).
259 m0
.m_data
= (char *)&af
;
263 (*lo_statics
[ifp
->if_unit
].bpf_callback
)(ifp
, n
);
265 M_PREPEND(m
, (3 * sizeof(u_long
)), M_WAITOK
);
266 bcopy(&saved_header
[0], mtod(m
, caddr_t
), (3 * sizeof(u_long
)));
271 ifp
->if_ibytes
+= m
->m_pkthdr
.len
;
272 ifp
->if_obytes
+= m
->m_pkthdr
.len
;
277 m
->m_pkthdr
.header
= mtod(m
, char *);
278 m
->m_pkthdr
.csum_data
= 0xffff; /* loopback checksums are always OK */
279 m
->m_pkthdr
.csum_flags
= CSUM_DATA_VALID
| CSUM_PSEUDO_HDR
|
280 CSUM_IP_CHECKED
| CSUM_IP_VALID
;
281 return dlil_input(ifp
, m
, m
);
286 * This is a common pre-output route used by INET, AT, etc. This could
287 * (should?) be split into separate pre-output routines for each protocol.
291 lo_pre_output(ifp
, m
, dst
, route
, frame_type
, dst_addr
, dl_tag
)
293 register struct mbuf
**m
;
294 struct sockaddr
*dst
;
302 register struct ifqueue
*ifq
= 0;
304 register struct rtentry
*rt
= (struct rtentry
*) route
;
306 prepend_ptr
= (u_long
*) dst_addr
;
307 if (((*m
)->m_flags
& M_PKTHDR
) == 0)
308 panic("looutput no HDR");
310 if (rt
&& rt
->rt_flags
& (RTF_REJECT
|RTF_BLACKHOLE
)) {
311 if (rt
->rt_flags
& RTF_BLACKHOLE
) {
316 return ((rt
->rt_flags
& RTF_HOST
) ? EHOSTUNREACH
: ENETUNREACH
);
319 switch (dst
->sa_family
) {
328 (*m
)->m_flags
|= M_LOOP
;
354 isr
= NETISR_APPLETALK
;
358 return (EAFNOSUPPORT
);
361 *prepend_ptr
++ = dst
->sa_family
; /* For lo_output(BPF) */
362 *prepend_ptr
++ = dlttoproto(dl_tag
); /* For lo_demux */
363 *prepend_ptr
++ = (u_long
) ifq
; /* For lo_input */
364 *prepend_ptr
= isr
; /* For lo_input */
373 * lo_input - This should work for all attached protocols that use the
374 * ifq/schednetisr input mechanism.
379 lo_input(m
, fh
, ifp
, dl_tag
, sync_ok
)
380 register struct mbuf
*m
;
389 register struct ifqueue
*ifq
= 0;
391 prepend_ptr
= mtod(m
, u_long
*);
392 ifq
= (struct ifqueue
*) *prepend_ptr
++;
394 m_adj(m
, (2 * sizeof(u_long
)));
401 return (EJUSTRETURN
);
415 lortrequest(cmd
, rt
, sa
)
421 rt
->rt_rmx
.rmx_mtu
= rt
->rt_ifp
->if_mtu
; /* for ISO */
423 * For optimal performance, the send and receive buffers
424 * should be at least twice the MTU plus a little more for
427 rt
->rt_rmx
.rmx_recvpipe
=
428 rt
->rt_rmx
.rmx_sendpipe
= 3 * LOMTU
;
433 * Process an ioctl request.
436 lo_if_ioctl(struct ifnet
*ifp
, u_long cmd
, void * data
)
438 register struct ifaddr
*ifa
;
439 register struct ifreq
*ifr
= (struct ifreq
*)data
;
440 register int error
= 0;
445 ifp
->if_flags
|= IFF_UP
| IFF_RUNNING
;
446 ifa
= (struct ifaddr
*)data
;
447 ifa
->ifa_rtrequest
= lortrequest
;
449 * Everything else is done at a higher level.
456 error
= EAFNOSUPPORT
; /* XXX */
459 switch (ifr
->ifr_addr
.sa_family
) {
471 error
= EAFNOSUPPORT
;
477 ifp
->if_mtu
= ifr
->ifr_mtu
;
491 loioctl(u_long dl_tag
, struct ifnet
*ifp
, u_long cmd
, caddr_t data
)
493 return (lo_if_ioctl(ifp
, cmd
, data
));
496 #endif /* NLOOP > 0 */
504 int lo_attach_inet(struct ifnet
*ifp
, u_long
*dl_tag
)
506 struct dlil_proto_reg_str reg
;
507 struct dlil_demux_desc desc
;
512 for (i
=0; i
< lo_count
; i
++) {
513 if ((lo_array
[i
]) && (lo_array
[i
]->ifp
== ifp
)) {
514 if (lo_array
[i
]->protocol_family
== PF_INET
) {
515 *dl_tag
= lo_array
[i
]->dl_tag
;
521 TAILQ_INIT(®
.demux_desc_head
);
522 desc
.type
= DLIL_DESC_RAW
;
523 desc
.variants
.bitmask
.proto_id_length
= 0;
524 desc
.variants
.bitmask
.proto_id
= 0;
525 desc
.variants
.bitmask
.proto_id_mask
= 0;
526 desc
.native_type
= (char *) &native
;
527 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
528 reg
.interface_family
= ifp
->if_family
;
529 reg
.unit_number
= ifp
->if_unit
;
530 reg
.input
= lo_input
;
531 reg
.pre_output
= lo_pre_output
;
535 reg
.default_proto
= 0;
536 reg
.protocol_family
= PF_INET
;
538 stat
= dlil_attach_protocol(®
, dl_tag
);
541 printf("lo_attach_inet: dlil_attach_protocol returned=%d\n", stat
);
546 int lo_attach_inet6(struct ifnet
*ifp
, u_long
*dl_tag
)
548 struct dlil_proto_reg_str reg
;
549 struct dlil_demux_desc desc
;
554 for (i
=0; i
< lo_count
; i
++) {
555 if ((lo_array
[i
]) && (lo_array
[i
]->ifp
== ifp
)) {
556 if (lo_array
[i
]->protocol_family
== PF_INET6
) {
557 *dl_tag
= lo_array
[i
]->dl_tag
;
563 TAILQ_INIT(®
.demux_desc_head
);
564 desc
.type
= DLIL_DESC_RAW
;
565 desc
.variants
.bitmask
.proto_id_length
= 0;
566 desc
.variants
.bitmask
.proto_id
= 0;
567 desc
.variants
.bitmask
.proto_id_mask
= 0;
568 desc
.native_type
= (char *) &native
;
569 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
570 reg
.interface_family
= ifp
->if_family
;
571 reg
.unit_number
= ifp
->if_unit
;
572 reg
.input
= lo_input
;
573 reg
.pre_output
= lo_pre_output
;
577 reg
.default_proto
= 0;
578 reg
.protocol_family
= PF_INET6
;
580 stat
= dlil_attach_protocol(®
, dl_tag
);
583 printf("lo_attach_inet6: dlil_attach_protocol returned=%d\n", stat
);
588 void lo_reg_if_mods()
590 struct dlil_ifmod_reg_str lo_ifmod
;
591 struct dlil_protomod_reg_str lo_protoreg
;
594 bzero(&lo_ifmod
, sizeof(lo_ifmod
));
595 lo_ifmod
.add_if
= lo_add_if
;
596 lo_ifmod
.del_if
= lo_del_if
;
597 lo_ifmod
.add_proto
= lo_add_proto
;
598 lo_ifmod
.del_proto
= lo_del_proto
;
599 lo_ifmod
.ifmod_ioctl
= 0;
600 lo_ifmod
.shutdown
= lo_shutdown
;
602 if (dlil_reg_if_modules(APPLE_IF_FAM_LOOPBACK
, &lo_ifmod
))
603 panic("Couldn't register lo modules\n");
605 /* Register protocol registration functions */
607 bzero(&lo_protoreg
, sizeof(lo_protoreg
));
608 lo_protoreg
.attach_proto
= lo_attach_inet
;
609 lo_protoreg
.detach_proto
= NULL
; /* no detach function for loopback */
611 if ( error
= dlil_reg_proto_module(PF_INET
, APPLE_IF_FAM_LOOPBACK
, &lo_protoreg
) != 0)
612 printf("dlil_reg_proto_module failed for AF_INET error=%d\n", error
);
614 lo_protoreg
.attach_proto
= lo_attach_inet6
;
615 lo_protoreg
.detach_proto
= NULL
;
617 if ( error
= dlil_reg_proto_module(PF_INET6
, APPLE_IF_FAM_LOOPBACK
, &lo_protoreg
) != 0)
618 printf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error
);
622 int lo_set_bpf_tap(struct ifnet
*ifp
, int mode
, int (*bpf_callback
)(struct ifnet
*, struct mbuf
*))
626 * NEED MUTEX HERE XXX
628 if (mode
== BPF_TAP_DISABLE
) {
629 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
630 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
633 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
634 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
646 register struct ifnet
*ifp
;
649 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
652 for (ifp
= loif
; i
< NLOOP
; ifp
++) {
653 lo_statics
[i
].bpf_callback
= 0;
654 lo_statics
[i
].bpf_mode
= BPF_TAP_DISABLE
;
656 ifp
->if_family
= APPLE_IF_FAM_LOOPBACK
;
659 ifp
->if_flags
= IFF_LOOPBACK
| IFF_MULTICAST
;
660 ifp
->if_ioctl
= lo_if_ioctl
;
661 ifp
->if_set_bpf_tap
= lo_set_bpf_tap
;
662 ifp
->if_output
= lo_output
;
663 ifp
->if_type
= IFT_LOOP
;
664 ifp
->if_hwassist
= 0; /* HW cksum on send side breaks Classic loopback */
667 bpfattach(ifp
, DLT_NULL
, sizeof(u_int
));
670 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);