2 * ip tunnel/ethertap device for MacOSX. Common functionality of tap_interface and tun_interface.
4 * tuntap_interface class definition
7 * Copyright (c) 2004, 2005, 2006, 2007, 2008 Mattias Nissler <mattias.nissler@gmx.de>
9 * Redistribution and use in source and binary forms, with or without modification, are permitted
10 * provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright notice, this list of
13 * conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
15 * conditions and the following disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products derived from this
18 * software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #define dprintf(...) log(LOG_INFO, __VA_ARGS__)
41 #include <sys/syslog.h>
42 #include <sys/param.h>
43 #include <sys/filio.h>
44 #include <sys/sockio.h>
45 #include <sys/fcntl.h>
46 #include <sys/kpi_socket.h>
48 #include <vm/vm_kern.h>
50 #include <net/if_types.h>
51 #include <net/if_var.h>
52 #include <net/if_dl.h>
53 #include <net/if_arp.h>
55 #include <miscfs/devfs/devfs.h>
61 /* interface service functions that delegate to the appropriate tuntap_interface instance */
63 tuntap_if_output(ifnet_t ifp
, mbuf_t m
)
66 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
68 return ttif
->if_output(m
);
78 tuntap_if_ioctl(ifnet_t ifp
, u_int32_t cmd
, void *arg
)
81 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
83 return ttif
->if_ioctl(cmd
, arg
);
90 tuntap_if_set_bpf_tap(ifnet_t ifp
, bpf_tap_mode mode
, int (*cb
)(ifnet_t
, mbuf_t
))
93 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
95 return ttif
->if_set_bpf_tap(mode
, cb
);
102 tuntap_if_demux(ifnet_t ifp
, mbuf_t m
, char *header
, protocol_family_t
*proto
)
105 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
107 return ttif
->if_demux(m
, header
, proto
);
114 tuntap_if_framer(ifnet_t ifp
, mbuf_t
*m
, const struct sockaddr
*dest
, const char *dest_linkaddr
,
115 const char *frame_type
)
118 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
120 return ttif
->if_framer(m
, dest
, dest_linkaddr
, frame_type
);
127 tuntap_if_add_proto(ifnet_t ifp
, protocol_family_t proto
, const struct ifnet_demux_desc
*ddesc
,
131 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
133 return ttif
->if_add_proto(proto
, ddesc
, ndesc
);
140 tuntap_if_del_proto(ifnet_t ifp
, protocol_family_t proto
)
143 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
145 return ttif
->if_del_proto(proto
);
152 tuntap_if_check_multi(ifnet_t ifp
, const struct sockaddr
* maddr
)
156 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
158 return ttif
->if_check_multi(maddr
);
165 tuntap_if_detached(ifnet_t ifp
)
168 tuntap_interface
*ttif
= (tuntap_interface
*) ifnet_softc(ifp
);
175 tuntap_if_noop_output(ifnet_t
, mbuf_t
)
181 tuntap_if_noop_demux(ifnet_t
, mbuf_t
, char*, protocol_family_t
*)
187 tuntap_if_noop_add_proto(ifnet_t
, protocol_family_t
, const struct ifnet_demux_desc
*, u_int32_t
)
193 tuntap_if_noop_del_proto(ifnet_t
, protocol_family_t
)
200 /* tuntap_mbuf_queue */
201 tuntap_mbuf_queue::tuntap_mbuf_queue()
207 tuntap_mbuf_queue::~tuntap_mbuf_queue()
213 tuntap_mbuf_queue::enqueue(mbuf_t mb
)
215 if (size
== QUEUE_SIZE
)
218 mbuf_setnextpkt(mb
, NULL
);
223 mbuf_setnextpkt(tail
, mb
);
232 tuntap_mbuf_queue::dequeue()
236 /* check wether there is a packet in the queue */
242 head
= mbuf_nextpkt(head
);
243 mbuf_setnextpkt(ret
, NULL
);
250 tuntap_mbuf_queue::clear()
252 /* free mbufs that are in the queue */
254 mbuf_freem_list(head
);
261 /* tuntap_interface members */
262 tuntap_interface::tuntap_interface()
264 /* initialize the members */
270 selthreadclear(&rsel
);
271 bpf_mode
= BPF_MODE_DISABLED
;
273 bzero(unique_id
, UIDLEN
);
276 tuntap_interface::~tuntap_interface()
281 tuntap_interface::register_chardev(unsigned short major
)
283 /* register character device */
284 dev_handle
= devfs_make_node(makedev(major
, unit
), DEVFS_CHAR
, 0, 0, 0660, "%s%d",
285 family_name
, (int) unit
);
287 if (dev_handle
== NULL
) {
288 log(LOG_ERR
, "tuntap: could not make /dev/%s%d\n", family_name
, (int) unit
);
296 tuntap_interface::unregister_chardev()
298 dprintf("unregistering character device\n");
300 /* unregister character device */
301 if (dev_handle
!= NULL
)
302 devfs_remove(dev_handle
);
307 tuntap_interface::register_interface(const struct sockaddr_dl
* lladdr
, void *bcaddr
,
310 struct ifnet_init_params ip
;
313 dprintf("register_interface\n");
315 /* initialize an initialization info struct */
316 ip
.uniqueid_len
= UIDLEN
;
317 ip
.uniqueid
= unique_id
;
318 ip
.name
= family_name
;
322 ip
.output
= tuntap_if_output
;
323 ip
.demux
= tuntap_if_demux
;
324 ip
.add_proto
= tuntap_if_add_proto
;
325 ip
.del_proto
= tuntap_if_del_proto
;
326 ip
.check_multi
= tuntap_if_check_multi
;
327 ip
.framer
= tuntap_if_framer
;
329 ip
.ioctl
= tuntap_if_ioctl
;
330 ip
.set_bpf_tap
= tuntap_if_set_bpf_tap
;
331 ip
.detach
= tuntap_if_detached
;
333 ip
.broadcast_addr
= bcaddr
;
334 ip
.broadcast_len
= bcaddrlen
;
336 dprintf("tuntap: tuntap_if_check_multi is at 0x%08x\n", (void*) tuntap_if_check_multi
);
338 /* allocate the interface */
339 err
= ifnet_allocate(&ip
, &ifp
);
341 log(LOG_ERR
, "tuntap: could not allocate interface for %s%d: %d\n", family_name
,
347 /* activate the interface */
348 err
= ifnet_attach(ifp
, lladdr
);
350 log(LOG_ERR
, "tuntap: could not attach interface %s%d: %d\n", family_name
,
357 dprintf("setting interface flags\n");
359 /* set interface flags */
360 ifnet_set_flags(ifp
, IFF_RUNNING
| IFF_MULTICAST
| IFF_SIMPLEX
, (u_int16_t
) ~0UL);
362 dprintf("flags: %x\n", ifnet_flags(ifp
));
368 tuntap_interface::unregister_interface()
372 dprintf("unregistering network interface\n");
375 interface_detached
= false;
377 /* detach interface */
378 err
= ifnet_detach(ifp
);
380 log(LOG_ERR
, "tuntap: error detaching interface %s%d: %d\n",
381 family_name
, unit
, err
);
383 dprintf("interface detaching\n");
385 /* Wait until the interface has completely been detached. */
387 while (!interface_detached
)
388 detach_lock
.sleep(&interface_detached
, NULL
);
389 detach_lock
.unlock();
391 dprintf("interface detached\n");
393 /* release the interface */
399 /* Here goes another hack that we need to prevent darwin from crashing.
400 * Unfortunately, not all of the interface service function pointers are cleared on
401 * detach properly. In particular, I had crashes from calling the demux() interface
402 * function after the kernel module had been unloaded. So we need to make sure all
403 * our function pointers get out of the ifnet struct. We do that by allocating the
404 * interface again, this time passing NULLs for the optional functions and pointers
405 * to noop-dummies for the required functions. Then, we release the interface again.
407 struct ifnet_init_params ip
;
410 dprintf("re-registering interface\n");
412 /* initialize an initialization info struct */
413 ip
.uniqueid_len
= UIDLEN
;
414 ip
.uniqueid
= unique_id
;
415 ip
.name
= family_name
;
419 ip
.output
= tuntap_if_noop_output
;
420 ip
.demux
= tuntap_if_noop_demux
;
421 ip
.add_proto
= tuntap_if_noop_add_proto
;
422 ip
.del_proto
= tuntap_if_noop_del_proto
;
423 ip
.check_multi
= NULL
;
427 ip
.set_bpf_tap
= NULL
;
430 ip
.broadcast_addr
= NULL
;
431 ip
.broadcast_len
= 0;
433 /* re-register the interface */
434 err
= ifnet_allocate(&ip
, &ifp
);
436 log(LOG_ERR
, "tuntap: dummy-allocate interface for %s%d: %d\n", family_name
,
438 /* well, bail out. this error shouldn't occur anyway. */
451 dprintf("network interface unregistered\n");
455 tuntap_interface::cleanup_interface()
463 /* mark the interface down */
464 ifnet_set_flags(ifp
, 0, IFF_UP
| IFF_RUNNING
);
466 /* Unregister all interface addresses. This works around a deficiency in the Darwin kernel.
467 * If we don't remove all IP addresses that are attached to the interface it can happen that
468 * the IP code fails to clean them up itself. When the interface is recycled, the IP code
469 * might then think some addresses are still attached to the interface...
472 err
= ifnet_get_address_list(ifp
, &addrs
);
475 /* Execute a SIOCDIFADDR ioctl for each address. For technical reasons, we can only
476 * do that with a socket of the appropriate family. So try to create a dummy socket.
477 * I know this is a little expensive, but better than crashing...
481 for (a
= addrs
; *a
!= NULL
; a
++) {
482 /* initialize the request parameters */
483 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
484 ifnet_name(ifp
), ifnet_unit(ifp
));
485 ifaddr_address(*a
, &(ifr
.ifr_addr
), sizeof(ifr
.ifr_addr
));
487 dprintf("trying to delete address of family %d\n", ifr
.ifr_addr
.sa_family
);
489 /* create the dummy socket. */
490 err
= sock_socket(ifr
.ifr_addr
.sa_family
, SOCK_RAW
, 0, NULL
, NULL
, &sock
);
492 /* failed to create the socket? Ignore this address... */
495 /* issue the ioctl */
496 err
= sock_ioctl(sock
, SIOCDIFADDR
, &ifr
);
498 dprintf("ifnet_ioctl returned %d\n", err
);
500 /* get rid of the socket */
504 /* release the address list */
505 ifnet_free_address_list(addrs
);
510 tuntap_interface::idle()
516 tuntap_interface::notify_bpf(mbuf_t mb
, bool out
)
518 auto_lock
l(&bpf_lock
);
520 if ((out
&& bpf_mode
== BPF_MODE_OUTPUT
)
521 || (!out
&& bpf_mode
== BPF_MODE_INPUT
)
522 || (bpf_mode
== BPF_MODE_INPUT_OUTPUT
))
523 (*bpf_callback
)(ifp
, mb
);
526 /* character device service methods */
528 tuntap_interface::cdev_open(int flags
, int devtype
, proc_t p
)
530 dprintf("tuntap: cdev_open()\n");
532 /* grab the lock so that there can only be one thread inside */
535 /* check wether it is already open */
539 /* bring the network interface up */
540 int error
= initialize_interface();
551 tuntap_interface::cdev_close(int flags
, int devtype
, proc_t p
)
553 dprintf("tuntap: cdev_close()\n");
560 /* shut down the network interface */
561 shutdown_interface();
563 /* clear the queue */
566 /* wakeup the cdev thread and notify selects */
577 tuntap_interface::cdev_read(uio_t uio
, int ioflag
)
584 dprintf("tuntap: cdev read\n");
586 if (!open
|| ifp
== NULL
|| !(ifnet_flags(ifp
) & IFF_UP
))
589 /* fetch a new mbuf from the queue if necessary */
590 mbuf_t cur_mbuf
= NULL
;
591 while (cur_mbuf
== NULL
) {
592 dprintf("tuntap: fetching new mbuf\n");
594 cur_mbuf
= send_queue
.dequeue();
595 if (cur_mbuf
== NULL
) {
596 /* nothing in queue, block or return */
598 dprintf("tuntap: aborting (nbio)\n");
602 dprintf("tuntap: waiting\n");
603 /* release the lock while waiting */
605 error
= msleep(this, NULL
, PZERO
| PCATCH
, "tuntap", NULL
);
612 /* see whether the device was closed in the meantime */
613 if (!open
|| ifp
== NULL
|| !(ifnet_flags(ifp
) & IFF_UP
))
621 notify_bpf(cur_mbuf
, true);
623 /* output what we have */
625 dprintf("tuntap: got new mbuf: %p uio_resid: %d\n", cur_mbuf
, uio_resid(uio
));
627 /* now we have an mbuf */
628 int chunk_len
= min(mbuf_len(cur_mbuf
), uio_resid(uio
));
629 error
= uiomove((char *) mbuf_data(cur_mbuf
), chunk_len
, uio
);
631 mbuf_freem(cur_mbuf
);
636 dprintf("tuntap: moved %d bytes to userspace uio_resid: %d\n", chunk_len
,
639 /* update cur_mbuf */
640 cur_mbuf
= mbuf_free(cur_mbuf
);
642 } while (uio_resid(uio
) > 0 && cur_mbuf
!= NULL
);
644 /* update statistics */
645 ifnet_stat_increment_out(ifp
, 1, nb
, 0);
647 /* still data left? forget about that ;-) */
648 if (cur_mbuf
!= NULL
)
649 mbuf_freem(cur_mbuf
);
651 dprintf("tuntap: read done\n");
657 tuntap_interface::cdev_write(uio_t uio
, int ioflag
)
661 if (!open
|| ifp
== NULL
|| !(ifnet_flags(ifp
) & IFF_UP
))
664 dprintf("tuntap: cdev write. uio_resid: %d\n", uio_resid(uio
));
666 /* pack the data into an mbuf chain */
669 /* first we need an mbuf having a header */
670 mbuf_gethdr(MBUF_WAITOK
, MBUF_TYPE_DATA
, &first
);
672 log(LOG_ERR
, "tuntap: could not get mbuf.\n");
675 mbuf_setlen(first
, 0);
677 unsigned int mlen
= mbuf_maxlen(first
);
678 unsigned int chunk_len
;
679 unsigned int copied
= 0;
682 /* stuff the data into the mbuf(s) */
684 while (uio_resid(uio
) > 0) {
685 /* copy a chunk. enforce mtu (don't know if this is correct behaviour) */
686 chunk_len
= min(ifnet_mtu(ifp
), min(uio_resid(uio
), mlen
));
687 error
= uiomove((caddr_t
) mbuf_data(mb
), chunk_len
, uio
);
689 log(LOG_ERR
, "tuntap: could not copy data from userspace: %d\n", error
);
694 dprintf("tuntap: copied %d bytes, uio_resid %d\n", chunk_len
,
698 mbuf_setlen(mb
, mbuf_len(mb
) + chunk_len
);
701 /* if done, break the loop */
702 if (uio_resid(uio
) <= 0 || copied
>= ifnet_mtu(ifp
))
705 /* allocate a new mbuf if the current is filled */
708 mbuf_get(MBUF_WAITOK
, MBUF_TYPE_DATA
, &next
);
710 log(LOG_ERR
, "tuntap: could not get mbuf.\n");
714 mbuf_setnext(mb
, next
);
717 mlen
= mbuf_maxlen(mb
);
721 /* fill in header info */
722 mbuf_pkthdr_setrcvif(first
, ifp
);
723 mbuf_pkthdr_setlen(first
, copied
);
724 mbuf_pkthdr_setheader(first
, mbuf_data(first
));
725 mbuf_set_csum_performed(first
, 0, 0);
727 /* update statistics */
728 ifnet_stat_increment_in(ifp
, 1, copied
, 0);
730 dprintf("tuntap: mbuf chain constructed. first: %p mb: %p len: %d data: %p\n",
731 first
, mb
, mbuf_len(first
), mbuf_data(first
));
734 notify_bpf(first
, false);
736 /* need to adjust the data pointer to point directly behind the linklevel header. The header
737 * itself is later accessed via m_pkthdr.header. Well, if something is ugly, here is it.
739 mbuf_adj(first
, ifnet_hdrlen(ifp
));
741 /* pass the packet over to the network stack */
742 error
= ifnet_input(ifp
, first
, NULL
);
745 log(LOG_ERR
, "tuntap: could not input packet into network stack.\n");
754 tuntap_interface::cdev_ioctl(u_long cmd
, caddr_t data
, int fflag
, proc_t p
)
758 dprintf("tuntap: cdev ioctl: %d\n", (int) (cmd
& 0xff));
763 block_io
= *((int *) data
) ? false : true;
766 /* don't allow switching it on */
776 tuntap_interface::cdev_select(int which
, void *wql
, proc_t p
)
782 dprintf("tuntap: select. which: %d\n", which
);
786 /* check wether data is available */
788 if (!send_queue
.empty())
791 dprintf("tuntap: select: waiting\n");
792 selrecord(p
, &rsel
, wql
);
797 /* we are always writeable */
804 /* interface service methods */
806 tuntap_interface::if_output(mbuf_t m
)
810 dprintf("tuntap: if output\n");
812 /* just to be sure */
816 if (!open
|| ifp
== NULL
|| !(ifnet_flags(ifp
) & IFF_UP
)) {
821 /* check whether packet has a header */
822 if ((mbuf_flags(m
) & MBUF_PKTHDR
) == 0) {
823 log(LOG_ERR
, "tuntap: packet to be output has no mbuf header.\n");
828 /* put the packet(s) into the output queue */
830 /* keep pointer, iterate */
833 mbuf_setnextpkt(pkt
, NULL
);
837 if (!send_queue
.enqueue(pkt
)) {
844 /* protect the wakeup calls with the lock, not sure they are safe. */
848 /* wakeup the cdev thread and notify selects */
857 tuntap_interface::if_ioctl(u_int32_t cmd
, void *arg
)
859 dprintf("tuntap: if ioctl: %d\n", (int) (cmd
& 0xff));
863 dprintf("tuntap: if_ioctl: SIOCSIFADDR\n");
865 /* Unfortunately, ifconfig sets the address family field of an INET netmask
866 * to zero. However, this makes mDNSresponder ignore the interface. Fix that
867 * here. This one is of the category "ugly workaround". Dumb Darwin...
869 * Btw. If you configure other network interfaces using ifconfig, you run
870 * into the same problem. I still don't know how to make the tap devices
871 * show up in the network configuration panel...
873 struct ifaddr
*ifa
= (struct ifaddr
*) arg
;
874 if (ifa
!= NULL
&& ifa
->ifa_netmask
!= NULL
&& ifa
->ifa_addr
!= NULL
) {
876 dprintf("tuntap: if_ioctl: addr af %d netmask af %d\n",
877 ifa
->ifa_netmask
->sa_family
,
878 ifa
->ifa_addr
->sa_family
);
880 if (ifa
->ifa_netmask
->sa_family
!= ifa
->ifa_addr
->sa_family
)
882 /* Fix the address family field of the netmask */
883 dprintf("tuntap: if_ioctl: fixing netmask af.\n");
884 ifa
->ifa_netmask
->sa_family
= ifa
->ifa_addr
->sa_family
;
894 struct ifstat
*stat
= (struct ifstat
*) arg
;
902 len
= strlen(stat
->ascii
);
903 p
= stat
->ascii
+ len
;
905 snprintf(p
, IFSTATMAX
- len
, "\topen (pid %u)\n", pid
);
907 snprintf(p
, IFSTATMAX
- len
, "\tclosed\n");
915 struct ifreq
*ifr
= (struct ifreq
*) arg
;
920 ifnet_set_mtu(ifp
, ifr
->ifr_mtu
);
934 tuntap_interface::if_set_bpf_tap(bpf_tap_mode mode
, int (*cb
)(ifnet_t
, mbuf_t
))
936 dprintf("tuntap: mode %d\n", mode
);
938 auto_lock
l(&bpf_lock
);
947 tuntap_interface::if_check_multi(const struct sockaddr
*maddr
)
949 dprintf("tuntap: if_check_multi\n");
955 tuntap_interface::if_detached()
957 dprintf("tuntap: if_detached\n");
959 /* wake unregister_interface() */
961 interface_detached
= true;
962 detach_lock
.wakeup(&interface_detached
);
963 detach_lock
.unlock();
965 dprintf("if_detached done\n");