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.
437 loioctl(dl_tag
, ifp
, cmd
, data
)
439 register struct ifnet
*ifp
;
443 register struct ifaddr
*ifa
;
444 register struct ifreq
*ifr
= (struct ifreq
*)data
;
445 register int error
= 0;
450 ifp
->if_flags
|= IFF_UP
| IFF_RUNNING
;
451 ifa
= (struct ifaddr
*)data
;
452 ifa
->ifa_rtrequest
= lortrequest
;
454 * Everything else is done at a higher level.
461 error
= EAFNOSUPPORT
; /* XXX */
464 switch (ifr
->ifr_addr
.sa_family
) {
476 error
= EAFNOSUPPORT
;
482 ifp
->if_mtu
= ifr
->ifr_mtu
;
493 #endif /* NLOOP > 0 */
502 void lo_reg_if_mods()
504 struct dlil_ifmod_reg_str lo_ifmod
;
506 bzero(&lo_ifmod
, sizeof(lo_ifmod
));
507 lo_ifmod
.add_if
= lo_add_if
;
508 lo_ifmod
.del_if
= lo_del_if
;
509 lo_ifmod
.add_proto
= lo_add_proto
;
510 lo_ifmod
.del_proto
= lo_del_proto
;
511 lo_ifmod
.ifmod_ioctl
= 0;
512 lo_ifmod
.shutdown
= lo_shutdown
;
514 if (dlil_reg_if_modules(APPLE_IF_FAM_LOOPBACK
, &lo_ifmod
))
515 panic("Couldn't register lo modules\n");
519 u_long
lo_attach_inet(struct ifnet
*ifp
)
521 struct dlil_proto_reg_str reg
;
522 struct dlil_demux_desc desc
;
528 for (i
=0; i
< lo_count
; i
++) {
529 if ((lo_array
[i
]) && (lo_array
[i
]->ifp
== ifp
)) {
530 if (lo_array
[i
]->protocol_family
== PF_INET
)
531 return lo_array
[i
]->dl_tag
;
535 TAILQ_INIT(®
.demux_desc_head
);
536 desc
.type
= DLIL_DESC_RAW
;
537 desc
.variants
.bitmask
.proto_id_length
= 0;
538 desc
.variants
.bitmask
.proto_id
= 0;
539 desc
.variants
.bitmask
.proto_id_mask
= 0;
540 desc
.native_type
= (char *) &native
;
541 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
542 reg
.interface_family
= ifp
->if_family
;
543 reg
.unit_number
= ifp
->if_unit
;
544 reg
.input
= lo_input
;
545 reg
.pre_output
= lo_pre_output
;
549 reg
.default_proto
= 0;
550 reg
.protocol_family
= PF_INET
;
552 stat
= dlil_attach_protocol(®
, &dl_tag
);
554 panic("lo_attach_inet can't attach interface\n");
560 u_long
lo_attach_inet6(struct ifnet
*ifp
)
562 struct dlil_proto_reg_str reg
;
563 struct dlil_demux_desc desc
;
569 for (i
=0; i
< lo_count
; i
++) {
570 if ((lo_array
[i
]) && (lo_array
[i
]->ifp
== ifp
)) {
571 if (lo_array
[i
]->protocol_family
== PF_INET6
)
572 return lo_array
[i
]->dl_tag
;
576 TAILQ_INIT(®
.demux_desc_head
);
577 desc
.type
= DLIL_DESC_RAW
;
578 desc
.variants
.bitmask
.proto_id_length
= 0;
579 desc
.variants
.bitmask
.proto_id
= 0;
580 desc
.variants
.bitmask
.proto_id_mask
= 0;
581 desc
.native_type
= (char *) &native
;
582 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
583 reg
.interface_family
= ifp
->if_family
;
584 reg
.unit_number
= ifp
->if_unit
;
585 reg
.input
= lo_input
;
586 reg
.pre_output
= lo_pre_output
;
590 reg
.default_proto
= 0;
591 reg
.protocol_family
= PF_INET6
;
593 stat
= dlil_attach_protocol(®
, &dl_tag
);
595 panic("lo_attach_inet6 can't attach interface\n");
602 int lo_set_bpf_tap(struct ifnet
*ifp
, int mode
, int (*bpf_callback
)(struct ifnet
*, struct mbuf
*))
606 * NEED MUTEX HERE XXX
608 if (mode
== BPF_TAP_DISABLE
) {
609 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
610 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
613 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
614 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
626 register struct ifnet
*ifp
;
629 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
632 for (ifp
= loif
; i
< NLOOP
; ifp
++) {
633 lo_statics
[i
].bpf_callback
= 0;
634 lo_statics
[i
].bpf_mode
= BPF_TAP_DISABLE
;
636 ifp
->if_family
= APPLE_IF_FAM_LOOPBACK
;
639 ifp
->if_flags
= IFF_LOOPBACK
| IFF_MULTICAST
;
640 ifp
->if_ioctl
= loioctl
;
641 ifp
->if_set_bpf_tap
= lo_set_bpf_tap
;
642 ifp
->if_output
= lo_output
;
643 ifp
->if_type
= IFT_LOOP
;
644 ifp
->if_hwassist
= 0; /* HW cksum on send side breaks Classic loopback */
647 bpfattach(ifp
, DLT_NULL
, sizeof(u_int
));
650 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);