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
55 * $FreeBSD: src/sys/net/if_loop.c,v 1.47.2.5 2001/07/03 11:01:41 ume Exp $
59 * Loopback interface driver for protocol testing and timing.
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/kernel.h>
68 #include <sys/socket.h>
69 #include <sys/sockio.h>
72 #include <net/if_types.h>
73 #include <net/netisr.h>
74 #include <net/route.h>
76 #include <sys/malloc.h>
79 #include <netinet/in.h>
80 #include <netinet/in_var.h>
84 #include <netipx/ipx.h>
85 #include <netipx/ipx_if.h>
90 #include <netinet/in.h>
92 #include <netinet6/in6_var.h>
93 #include <netinet/ip6.h>
99 extern struct ifqueue atalkintrq
;
102 #include "bpfilter.h"
104 #include <net/bpfdesc.h>
107 #define NLOOP_ATTACHMENTS (NLOOP * 12)
109 struct lo_statics_str
{
111 int (*bpf_callback
)(struct ifnet
*, struct mbuf
*);
114 static struct if_proto
*lo_array
[NLOOP_ATTACHMENTS
];
115 static struct lo_statics_str lo_statics
[NLOOP
];
120 #define LOMTU (1024+512)
125 struct ifnet loif
[NLOOP
];
127 void lo_reg_if_mods();
132 int lo_demux(ifp
, m
, frame_header
, proto
)
136 struct if_proto
**proto
;
139 struct if_proto
**proto_ptr
;
141 proto_ptr
= mtod(m
, struct if_proto
**);
143 m_adj(m
, sizeof(u_long
));
148 int lo_framer(ifp
, m
, dest
, dest_linkaddr
, frame_type
)
151 struct sockaddr
*dest
;
158 M_PREPEND(*m
, (4 * sizeof(u_long
)), M_WAITOK
);
159 to_ptr
= mtod(*m
, char *);
160 bcopy(dest_linkaddr
, to_ptr
, (4 * sizeof(u_long
)));
165 int lo_add_if(struct ifnet
*ifp
)
167 ifp
->if_demux
= lo_demux
;
168 ifp
->if_framer
= lo_framer
;
174 int lo_del_if(struct ifnet
*ifp
)
183 int lo_add_proto(struct ddesc_head_str
*desc_head
, struct if_proto
*proto
, u_long dl_tag
)
187 for (i
=0; i
< lo_count
; i
++)
188 if (lo_array
[i
] == 0) {
189 lo_array
[lo_count
] = proto
;
193 if ((i
== lo_count
) && (lo_count
== NLOOP_ATTACHMENTS
))
194 panic("lo_add_proto -- Too many attachments\n");
196 lo_array
[lo_count
++] = proto
;
202 int lo_del_proto(struct if_proto
*proto
, u_long dl_tag
)
206 for (i
=0; i
< lo_count
; i
++)
207 if (lo_array
[i
] == proto
) {
218 register struct mbuf
*m
;
219 { u_int
*prepend_ptr
;
221 u_long saved_header
[3];
223 if ((m
->m_flags
& M_PKTHDR
) == 0)
224 panic("lo_output: no HDR");
227 * Don't overwrite the rcvif field if it is in use.
228 * This is used to match multicast packets, sent looping
229 * back, with the appropriate group record on input.
231 if (m
->m_pkthdr
.rcvif
== NULL
)
232 m
->m_pkthdr
.rcvif
= ifp
;
233 prepend_ptr
= mtod(m
, u_int
*);
235 m_adj(m
, sizeof(u_int
));
239 if (lo_statics
[ifp
->if_unit
].bpf_mode
!= BPF_TAP_DISABLE
) {
242 bcopy(mtod(m
, caddr_t
), &saved_header
[0], (3 * sizeof(u_long
)));
243 m_adj(m
, (3 * sizeof(u_long
)));
246 if (ifp
->if_bpf
->bif_dlt
== DLT_NULL
) {
248 * We need to prepend the address family as
249 * a four byte field. Cons up a dummy header
250 * to pacify bpf. This is safe because bpf
251 * will only read from the mbuf (i.e., it won't
252 * try to free it or keep a pointer a to it).
256 m0
.m_data
= (char *)&af
;
260 (*lo_statics
[ifp
->if_unit
].bpf_callback
)(ifp
, n
);
262 M_PREPEND(m
, (3 * sizeof(u_long
)), M_WAITOK
);
263 bcopy(&saved_header
[0], mtod(m
, caddr_t
), (3 * sizeof(u_long
)));
268 ifp
->if_ibytes
+= m
->m_pkthdr
.len
;
269 ifp
->if_obytes
+= m
->m_pkthdr
.len
;
274 m
->m_pkthdr
.header
= mtod(m
, char *);
275 m
->m_pkthdr
.csum_data
= 0xffff; /* loopback checksums are always OK */
276 m
->m_pkthdr
.csum_flags
= CSUM_DATA_VALID
| CSUM_PSEUDO_HDR
|
277 CSUM_IP_CHECKED
| CSUM_IP_VALID
;
278 return dlil_input(ifp
, m
, m
);
283 * This is a common pre-output route used by INET, AT, etc. This could
284 * (should?) be split into separate pre-output routines for each protocol.
288 lo_pre_output(ifp
, m
, dst
, route
, frame_type
, dst_addr
, dl_tag
)
290 register struct mbuf
**m
;
291 struct sockaddr
*dst
;
299 register struct ifqueue
*ifq
= 0;
301 register struct rtentry
*rt
= (struct rtentry
*) route
;
303 prepend_ptr
= (u_long
*) dst_addr
;
304 if (((*m
)->m_flags
& M_PKTHDR
) == 0)
305 panic("looutput no HDR");
307 if (rt
&& rt
->rt_flags
& (RTF_REJECT
|RTF_BLACKHOLE
)) {
308 if (rt
->rt_flags
& RTF_BLACKHOLE
) {
313 return ((rt
->rt_flags
& RTF_HOST
) ? EHOSTUNREACH
: ENETUNREACH
);
316 switch (dst
->sa_family
) {
325 (*m
)->m_flags
|= M_LOOP
;
351 isr
= NETISR_APPLETALK
;
355 return (EAFNOSUPPORT
);
358 *prepend_ptr
++ = dst
->sa_family
; /* For lo_output(BPF) */
359 *prepend_ptr
++ = dlttoproto(dl_tag
); /* For lo_demux */
360 *prepend_ptr
++ = (u_long
) ifq
; /* For lo_input */
361 *prepend_ptr
= isr
; /* For lo_input */
370 * lo_input - This should work for all attached protocols that use the
371 * ifq/schednetisr input mechanism.
376 lo_input(m
, fh
, ifp
, dl_tag
, sync_ok
)
377 register struct mbuf
*m
;
386 register struct ifqueue
*ifq
= 0;
388 prepend_ptr
= mtod(m
, u_long
*);
389 ifq
= (struct ifqueue
*) *prepend_ptr
++;
391 m_adj(m
, (2 * sizeof(u_long
)));
398 return (EJUSTRETURN
);
412 lortrequest(cmd
, rt
, sa
)
418 rt
->rt_rmx
.rmx_mtu
= rt
->rt_ifp
->if_mtu
; /* for ISO */
420 * For optimal performance, the send and receive buffers
421 * should be at least twice the MTU plus a little more for
424 rt
->rt_rmx
.rmx_recvpipe
=
425 rt
->rt_rmx
.rmx_sendpipe
= 3 * LOMTU
;
430 * Process an ioctl request.
434 loioctl(dl_tag
, ifp
, cmd
, data
)
436 register struct ifnet
*ifp
;
440 register struct ifaddr
*ifa
;
441 register struct ifreq
*ifr
= (struct ifreq
*)data
;
442 register int error
= 0;
447 ifp
->if_flags
|= IFF_UP
| IFF_RUNNING
;
448 ifa
= (struct ifaddr
*)data
;
449 ifa
->ifa_rtrequest
= lortrequest
;
451 * Everything else is done at a higher level.
458 error
= EAFNOSUPPORT
; /* XXX */
461 switch (ifr
->ifr_addr
.sa_family
) {
473 error
= EAFNOSUPPORT
;
479 ifp
->if_mtu
= ifr
->ifr_mtu
;
490 #endif /* NLOOP > 0 */
499 void lo_reg_if_mods()
501 struct dlil_ifmod_reg_str lo_ifmod
;
503 bzero(&lo_ifmod
, sizeof(lo_ifmod
));
504 lo_ifmod
.add_if
= lo_add_if
;
505 lo_ifmod
.del_if
= lo_del_if
;
506 lo_ifmod
.add_proto
= lo_add_proto
;
507 lo_ifmod
.del_proto
= lo_del_proto
;
508 lo_ifmod
.ifmod_ioctl
= 0;
509 lo_ifmod
.shutdown
= lo_shutdown
;
511 if (dlil_reg_if_modules(APPLE_IF_FAM_LOOPBACK
, &lo_ifmod
))
512 panic("Couldn't register lo modules\n");
516 u_long
lo_attach_inet(struct ifnet
*ifp
)
518 struct dlil_proto_reg_str reg
;
519 struct dlil_demux_desc desc
;
525 for (i
=0; i
< lo_count
; i
++) {
526 if ((lo_array
[i
]) && (lo_array
[i
]->ifp
== ifp
)) {
527 if (lo_array
[i
]->protocol_family
== PF_INET
)
528 return lo_array
[i
]->dl_tag
;
532 TAILQ_INIT(®
.demux_desc_head
);
533 desc
.type
= DLIL_DESC_RAW
;
534 desc
.variants
.bitmask
.proto_id_length
= 0;
535 desc
.variants
.bitmask
.proto_id
= 0;
536 desc
.variants
.bitmask
.proto_id_mask
= 0;
537 desc
.native_type
= (char *) &native
;
538 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
539 reg
.interface_family
= ifp
->if_family
;
540 reg
.unit_number
= ifp
->if_unit
;
541 reg
.input
= lo_input
;
542 reg
.pre_output
= lo_pre_output
;
546 reg
.default_proto
= 0;
547 reg
.protocol_family
= PF_INET
;
549 stat
= dlil_attach_protocol(®
, &dl_tag
);
551 panic("lo_attach_inet can't attach interface\n");
557 u_long
lo_attach_inet6(struct ifnet
*ifp
)
559 struct dlil_proto_reg_str reg
;
560 struct dlil_demux_desc desc
;
566 for (i
=0; i
< lo_count
; i
++) {
567 if ((lo_array
[i
]) && (lo_array
[i
]->ifp
== ifp
)) {
568 if (lo_array
[i
]->protocol_family
== PF_INET6
)
569 return lo_array
[i
]->dl_tag
;
573 TAILQ_INIT(®
.demux_desc_head
);
574 desc
.type
= DLIL_DESC_RAW
;
575 desc
.variants
.bitmask
.proto_id_length
= 0;
576 desc
.variants
.bitmask
.proto_id
= 0;
577 desc
.variants
.bitmask
.proto_id_mask
= 0;
578 desc
.native_type
= (char *) &native
;
579 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
580 reg
.interface_family
= ifp
->if_family
;
581 reg
.unit_number
= ifp
->if_unit
;
582 reg
.input
= lo_input
;
583 reg
.pre_output
= lo_pre_output
;
587 reg
.default_proto
= 0;
588 reg
.protocol_family
= PF_INET6
;
590 stat
= dlil_attach_protocol(®
, &dl_tag
);
592 panic("lo_attach_inet6 can't attach interface\n");
599 int lo_set_bpf_tap(struct ifnet
*ifp
, int mode
, int (*bpf_callback
)(struct ifnet
*, struct mbuf
*))
603 * NEED MUTEX HERE XXX
605 if (mode
== BPF_TAP_DISABLE
) {
606 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
607 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
610 lo_statics
[ifp
->if_unit
].bpf_callback
= bpf_callback
;
611 lo_statics
[ifp
->if_unit
].bpf_mode
= mode
;
623 register struct ifnet
*ifp
;
626 thread_funnel_switch(KERNEL_FUNNEL
, NETWORK_FUNNEL
);
629 for (ifp
= loif
; i
< NLOOP
; ifp
++) {
630 lo_statics
[i
].bpf_callback
= 0;
631 lo_statics
[i
].bpf_mode
= BPF_TAP_DISABLE
;
633 ifp
->if_family
= APPLE_IF_FAM_LOOPBACK
;
636 ifp
->if_flags
= IFF_LOOPBACK
| IFF_MULTICAST
;
637 ifp
->if_ioctl
= loioctl
;
638 ifp
->if_set_bpf_tap
= lo_set_bpf_tap
;
639 ifp
->if_output
= lo_output
;
640 ifp
->if_type
= IFT_LOOP
;
641 ifp
->if_hwassist
= 0; /* HW cksum on send side breaks Classic loopback */
644 bpfattach(ifp
, DLT_NULL
, sizeof(u_int
));
647 thread_funnel_switch(NETWORK_FUNNEL
, KERNEL_FUNNEL
);