diff options
author | nsayer <nsayer@FreeBSD.org> | 2000-07-20 17:01:10 +0000 |
---|---|---|
committer | nsayer <nsayer@FreeBSD.org> | 2000-07-20 17:01:10 +0000 |
commit | 14503a8247dc9e15f6d248a31949e5e8033da4a0 (patch) | |
tree | a432fe692d09ec4039d50d441e00afe94a7c54fa /sys/net | |
parent | b7fd852ec4b27e86f5a18ccc623da33062abcfb2 (diff) | |
download | FreeBSD-src-14503a8247dc9e15f6d248a31949e5e8033da4a0.zip FreeBSD-src-14503a8247dc9e15f6d248a31949e5e8033da4a0.tar.gz |
Add the tap driver.
The tap driver is used to present a virtual Ethernet interface to the
system. Packets presented by the network stack to the interface are
made available to a character device in /dev. With tap and the bridge
code, you can make remote bridge configurations where both sides of
the bridge are separated by userland daemons.
This driver also has a special naming hack to allow it to serve a similar
purpose to the vmware port.
Submitted by: myevmenkin@att.com, vsilyaev@mindspring.com
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_tap.c | 785 | ||||
-rw-r--r-- | sys/net/if_tap.h | 73 | ||||
-rw-r--r-- | sys/net/if_tapvar.h | 61 |
3 files changed, 919 insertions, 0 deletions
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c new file mode 100644 index 0000000..7b73dbf --- /dev/null +++ b/sys/net/if_tap.c @@ -0,0 +1,785 @@ +/* + * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * BASED ON: + * ------------------------------------------------------------------------- + * + * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> + * Nottingham University 1987. + */ + +/* + * $FreeBSD$ + * $Id: if_tap.c,v 0.19 2000/07/20 02:32:27 max Exp $ + */ + +#include "opt_inet.h" + +#include <sys/param.h> +#include <sys/conf.h> +#include <sys/filedesc.h> +#include <sys/filio.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/poll.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/socket.h> +#include <sys/sockio.h> +#include <sys/sysctl.h> +#include <sys/systm.h> +#include <sys/ttycom.h> +#include <sys/uio.h> +#include <sys/vnode.h> + +#include <net/bpf.h> +#include <net/ethernet.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <net/route.h> + +#include <netinet/in.h> + +#include <net/if_tapvar.h> +#include <net/if_tap.h> + + +#define CDEV_NAME "tap" +#define CDEV_MAJOR 149 +#define TAPDEBUG if (tapdebug) printf + +#define TAP "tap" +#define VMNET "vmnet" +#define VMNET_DEV_MASK 0x00010000 + +/* module */ +static int tapmodevent __P((module_t, int, void *)); + +/* device */ +static void tapcreate __P((dev_t)); + +/* network interface */ +static void tapifstart __P((struct ifnet *)); +static int tapifioctl __P((struct ifnet *, u_long, caddr_t)); +static void tapifinit __P((void *)); + +/* character device */ +static d_open_t tapopen; +static d_close_t tapclose; +static d_read_t tapread; +static d_write_t tapwrite; +static d_ioctl_t tapioctl; +static d_poll_t tappoll; + +static struct cdevsw tap_cdevsw = { + /* open */ tapopen, + /* close */ tapclose, + /* read */ tapread, + /* write */ tapwrite, + /* ioctl */ tapioctl, + /* poll */ tappoll, + /* mmap */ nommap, + /* startegy */ nostrategy, + /* dev name */ CDEV_NAME, + /* dev major */ CDEV_MAJOR, + /* dump */ nodump, + /* psize */ nopsize, + /* flags */ 0, + /* bmaj */ -1 +}; + +static int taprefcnt = 0; /* module ref. counter */ +static int taplastunit = -1; /* max. open unit number */ +static int tapdebug = 0; /* debug flag */ + +MALLOC_DECLARE(M_TAP); +MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface"); +SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, ""); +DEV_MODULE(if_tap, tapmodevent, NULL); + +/* + * tapmodevent + * + * module event handler + */ +static int +tapmodevent(mod, type, data) + module_t mod; + int type; + void *data; +{ + static int attached = 0; + struct ifnet *ifp = NULL; + int unit, s; + + switch (type) { + case MOD_LOAD: + if (attached) + return (EEXIST); + + cdevsw_add(&tap_cdevsw); + attached = 1; + break; + + case MOD_UNLOAD: + if (taprefcnt > 0) + return (EBUSY); + + cdevsw_remove(&tap_cdevsw); + + unit = 0; + while (unit <= taplastunit) { + s = splimp(); + TAILQ_FOREACH(ifp, &ifnet, if_link) + if ((strcmp(ifp->if_name, TAP) == 0) || + (strcmp(ifp->if_name, VMNET) == 0)) + if (ifp->if_unit == unit) + break; + splx(s); + + if (ifp != NULL) { + struct tap_softc *tp = ifp->if_softc; + + TAPDEBUG("detaching %s%d. taplastunit = %d\n", + ifp->if_name, unit, taplastunit); + + ether_ifdetach(ifp, 1); + destroy_dev(tp->tap_dev); + FREE(tp, M_TAP); + } + else + unit ++; + } + + attached = 0; + break; + + default: + return (EOPNOTSUPP); + } + + return (0); +} /* tapmodevent */ + + +/* + * tapcreate + * + * to create interface + */ +static void +tapcreate(dev) + dev_t dev; +{ + struct ifnet *ifp = NULL; + struct tap_softc *tp = NULL; + unsigned short macaddr_hi; + int unit; + char *name = NULL; + + /* allocate driver storage and create device */ + MALLOC(tp, struct tap_softc *, sizeof(*tp), M_TAP, M_WAITOK); + bzero(tp, sizeof(*tp)); + + /* select device: tap or vmnet */ + if (minor(dev) & VMNET_DEV_MASK) { + name = VMNET; + unit = lminor(dev) & 0xff; + } + else { + name = TAP; + unit = lminor(dev); + } + + tp->tap_dev = make_dev(&tap_cdevsw, minor(dev), UID_UUCP, GID_DIALER, + 0600, "%s%d", name, unit); + tp->tap_dev->si_drv1 = dev->si_drv1 = tp; + + /* generate fake MAC address: 00 bd xx xx xx unit_no */ + macaddr_hi = htons(0x00bd); + bcopy(&macaddr_hi, &tp->arpcom.ac_enaddr[0], sizeof(short)); + bcopy(&ticks, &tp->arpcom.ac_enaddr[2], sizeof(long)); + tp->arpcom.ac_enaddr[5] = (u_char)unit; + + /* fill the rest and attach interface */ + ifp = &tp->tap_if; + ifp->if_softc = tp; + + ifp->if_unit = unit; + if (unit > taplastunit) + taplastunit = unit; + + ifp->if_name = name; + ifp->if_init = tapifinit; + ifp->if_output = ether_output; + ifp->if_start = tapifstart; + ifp->if_ioctl = tapifioctl; + ifp->if_mtu = ETHERMTU; + ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); + ifp->if_snd.ifq_maxlen = ifqmaxlen; + + ether_ifattach(ifp, 1); + + tp->tap_flags = TAP_INITED; +} /* tapcreate */ + + +/* + * tapopen + * + * to open tunnel. must be superuser + */ +static int +tapopen(dev, flag, mode, p) + dev_t dev; + int flag; + int mode; + struct proc *p; +{ + struct tap_softc *tp = NULL; + int error; + + if ((error = suser(p)) != 0) + return (error); + + tp = dev->si_drv1; + if (tp == NULL) { + tapcreate(dev); + tp = dev->si_drv1; + } + + if (tp->tap_flags & TAP_OPEN) + return (EBUSY); + + tp->tap_pid = p->p_pid; + tp->tap_flags |= TAP_OPEN; + taprefcnt ++; + + TAPDEBUG("%s%d is open. refcnt = %d, taplastunit = %d\n", + tp->tap_if.if_name, tp->tap_if.if_unit, taprefcnt, taplastunit); + + return (0); +} /* tapopen */ + + +/* + * tapclose + * + * close the device - mark i/f down & delete routing info + */ +static int +tapclose(dev, foo, bar, p) + dev_t dev; + int foo; + int bar; + struct proc *p; +{ + int s; + struct tap_softc *tp = dev->si_drv1; + struct ifnet *ifp = &tp->tap_if; + struct mbuf *m = NULL; + + /* junk all pending output */ + + s = splimp(); + do { + IF_DEQUEUE(&ifp->if_snd, m); + if (m != NULL) + m_freem(m); + } while (m != NULL); + splx(s); + + if (ifp->if_flags & IFF_UP) { + s = splimp(); + if_down(ifp); + if (ifp->if_flags & IFF_RUNNING) { + /* find internet addresses and delete routes */ + struct ifaddr *ifa = NULL; + + for (ifa = ifp->if_addrhead.tqh_first; ifa; + ifa = ifa->ifa_link.tqe_next) { + if (ifa->ifa_addr->sa_family == AF_INET) { + rtinit(ifa, (int)RTM_DELETE, 0); + + /* remove address from interface */ + bzero(ifa->ifa_addr, + sizeof(*(ifa->ifa_addr))); + bzero(ifa->ifa_dstaddr, + sizeof(*(ifa->ifa_dstaddr))); + bzero(ifa->ifa_netmask, + sizeof(*(ifa->ifa_netmask))); + } + } + + ifp->if_flags &= ~IFF_RUNNING; + } + splx(s); + } + + funsetown(tp->tap_sigio); + selwakeup(&tp->tap_rsel); + + tp->tap_flags &= ~TAP_OPEN; + tp->tap_pid = 0; + + taprefcnt --; + if (taprefcnt < 0) { + taprefcnt = 0; + printf("%s%d refcnt = %d is out of sync. set refcnt to 0\n", + ifp->if_name, ifp->if_unit, taprefcnt); + } + + TAPDEBUG("%s%d is closed. refcnt = %d, taplastunit = %d\n", + ifp->if_name, ifp->if_unit, taprefcnt, taplastunit); + + return (0); +} /* tapclose */ + + +/* + * tapifinit + * + * network interface initialization function + */ +static void +tapifinit(xtp) + void *xtp; +{ + struct tap_softc *tp = (struct tap_softc *)xtp; + struct ifnet *ifp = &tp->tap_if; + + TAPDEBUG("initializing %s%d\n", ifp->if_name, ifp->if_unit); + + ifp->if_flags |= IFF_RUNNING; + ifp->if_flags &= ~IFF_OACTIVE; + + /* attempt to start output */ + tapifstart(ifp); +} /* tapifinit */ + + +/* + * tapifioctl + * + * Process an ioctl request on network interface + */ +int +tapifioctl(ifp, cmd, data) + struct ifnet *ifp; + u_long cmd; + caddr_t data; +{ + struct tap_softc *tp = (struct tap_softc *)(ifp->if_softc); + struct ifstat *ifs = NULL; + int s, dummy; + + switch (cmd) { + case SIOCSIFADDR: + case SIOCGIFADDR: + case SIOCSIFMTU: + s = splimp(); + dummy = ether_ioctl(ifp, cmd, data); + splx(s); + return (dummy); + + case SIOCSIFFLAGS: /* XXX -- just like vmnet does */ + case SIOCADDMULTI: + case SIOCDELMULTI: + break; + + case SIOCGIFSTATUS: + s = splimp(); + ifs = (struct ifstat *)data; + dummy = strlen(ifs->ascii); + if (tp->tap_pid != 0 && dummy < sizeof(ifs->ascii)) + snprintf(ifs->ascii + dummy, + sizeof(ifs->ascii) - dummy, + "\tOpened by PID %d\n", tp->tap_pid); + splx(s); + break; + + default: + return (EINVAL); + } + + return (0); +} /* tapifioctl */ + + +/* + * tapifstart + * + * queue packets from higher level ready to put out + */ +static void +tapifstart(ifp) + struct ifnet *ifp; +{ + struct tap_softc *tp = ifp->if_softc; + int s; + + TAPDEBUG("%s%d starting\n", ifp->if_name, ifp->if_unit); + + if ((tp->tap_flags & TAP_READY) != TAP_READY) { + struct mbuf *m = NULL; + + TAPDEBUG("%s%d not ready. tap_flags = 0x%x\n", + ifp->if_name, ifp->if_unit, tp->tap_flags); + + s = splimp(); + do { + IF_DEQUEUE(&ifp->if_snd, m); + if (m != NULL) + m_freem(m); + ifp->if_oerrors ++; + } while (m != NULL); + splx(s); + + return; + } + + s = splimp(); + ifp->if_flags |= IFF_OACTIVE; + + if (ifp->if_snd.ifq_len != 0) { + if (tp->tap_flags & TAP_RWAIT) { + tp->tap_flags &= ~TAP_RWAIT; + wakeup((caddr_t)tp); + } + + if ((tp->tap_flags & TAP_ASYNC) && (tp->tap_sigio != NULL)) + pgsigio(tp->tap_sigio, SIGIO, 0); + + selwakeup(&tp->tap_rsel); + ifp->if_opackets ++; /* obytes are counted in ether_output */ + } + + ifp->if_flags &= ~IFF_OACTIVE; + splx(s); +} /* tapifstart */ + + +/* + * tapioctl + * + * the cdevsw interface is now pretty minimal + */ +static int +tapioctl(dev, cmd, data, flag, p) + dev_t dev; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + struct tap_softc *tp = dev->si_drv1; + struct ifnet *ifp = &tp->tap_if; + struct tapinfo *tapp = NULL; + int s; + + switch (cmd) { + case TAPSIFINFO: + s = splimp(); + tapp = (struct tapinfo *)data; + ifp->if_mtu = tapp->mtu; + ifp->if_type = tapp->type; + ifp->if_baudrate = tapp->baudrate; + splx(s); + break; + + case TAPGIFINFO: + tapp = (struct tapinfo *)data; + tapp->mtu = ifp->if_mtu; + tapp->type = ifp->if_type; + tapp->baudrate = ifp->if_baudrate; + break; + + case TAPSDEBUG: + tapdebug = *(int *)data; + break; + + case TAPGDEBUG: + *(int *)data = tapdebug; + break; + + case FIONBIO: + break; + + case FIOASYNC: + if (*(int *)data) + tp->tap_flags |= TAP_ASYNC; + else + tp->tap_flags &= ~TAP_ASYNC; + break; + + case FIONREAD: + s = splimp(); + if (ifp->if_snd.ifq_head) { + struct mbuf *mb = ifp->if_snd.ifq_head; + + for(*(int *)data = 0; mb != 0; mb = mb->m_next) + *(int *)data += mb->m_len; + } + else + *(int *)data = 0; + splx(s); + break; + + case FIOSETOWN: + return (fsetown(*(int *)data, &tp->tap_sigio)); + + case FIOGETOWN: + *(int *)data = fgetown(tp->tap_sigio); + return (0); + + /* this is deprecated, FIOSETOWN should be used instead */ + case TIOCSPGRP: + return (fsetown(-(*(int *)data), &tp->tap_sigio)); + + /* this is deprecated, FIOGETOWN should be used instead */ + case TIOCGPGRP: + *(int *)data = -fgetown(tp->tap_sigio); + return (0); + + /* VMware/VMnet port ioctl's */ + + case SIOCGIFFLAGS: /* get ifnet flags */ + bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags)); + break; + + case VMIO_SIOCSIFFLAGS: { /* VMware/VMnet SIOCSIFFLAGS */ + short f = *(short *)data; + + f &= 0x0fff; + f &= ~IFF_CANTCHANGE; + f |= IFF_UP; + + s = splimp(); + ifp->if_flags = f | (ifp->if_flags & IFF_CANTCHANGE); + splx(s); + } break; + + case OSIOCGIFADDR: /* get MAC address */ + case SIOCGIFADDR: + bcopy(tp->arpcom.ac_enaddr, data, ETHER_ADDR_LEN); + break; + + case SIOCSIFADDR: /* set MAC address */ + s = splimp(); + bcopy(data, tp->arpcom.ac_enaddr, ETHER_ADDR_LEN); + splx(s); + break; + + default: + return (ENOTTY); + } + return (0); +} /* tapioctl */ + + +/* + * tapread + * + * the cdevsw read interface - reads a packet at a time, or at + * least as much of a packet as can be read + */ +static int +tapread(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + struct tap_softc *tp = dev->si_drv1; + struct ifnet *ifp = &tp->tap_if; + struct mbuf *m = NULL, *m0 = NULL; + int error = 0, len, s; + + TAPDEBUG("%s%d reading\n", ifp->if_name, ifp->if_unit); + + if ((tp->tap_flags & TAP_READY) != TAP_READY) { + TAPDEBUG("%s%d not ready. tap_flags = 0x%x\n", + ifp->if_name, ifp->if_unit, tp->tap_flags); + return (EHOSTDOWN); + } + + tp->tap_flags &= ~TAP_RWAIT; + + /* sleep until we get a packet */ + do { + s = splimp(); + IF_DEQUEUE(&ifp->if_snd, m0); + splx(s); + + if (m0 == NULL) { + if (flag & IO_NDELAY) + return (EWOULDBLOCK); + + tp->tap_flags |= TAP_RWAIT; + error = tsleep((caddr_t)tp,PCATCH|(PZERO+1),"taprd",0); + if (error) + return (error); + } + } while (m0 == 0); + + /* feed packet to bpf */ + if (ifp->if_bpf != NULL) + bpf_mtap(ifp, m0); + + /* xfer packet to user space */ + while ((m0 != NULL) && (uio->uio_resid > 0) && (error == 0)) { + len = min(uio->uio_resid, m0->m_len); + if (len == 0) + break; + + error = uiomove(mtod(m0, caddr_t), len, uio); + MFREE(m0, m); + m0 = m; + } + + if (m0 != NULL) { + TAPDEBUG("%s%d dropping mbuf\n", ifp->if_name, ifp->if_unit); + m_freem(m0); + } + + return (error); +} /* tapread */ + + +/* + * tapwrite + * + * the cdevsw write interface - an atomic write is a packet - or else! + */ +static int +tapwrite(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + struct tap_softc *tp = dev->si_drv1; + struct ifnet *ifp = &tp->tap_if; + struct mbuf *top = NULL, **mp = NULL, *m = NULL; + struct ether_header *eh = NULL; + int error = 0, tlen, mlen; + + TAPDEBUG("%s%d writting\n", ifp->if_name, ifp->if_unit); + + if (uio->uio_resid == 0) + return (0); + + if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) { + TAPDEBUG("%s%d invalid packet len = %d\n", + ifp->if_name, ifp->if_unit, uio->uio_resid); + return (EIO); + } + tlen = uio->uio_resid; + + /* get a header mbuf */ + MGETHDR(m, M_DONTWAIT, MT_DATA); + if (m == NULL) + return (ENOBUFS); + mlen = MHLEN; + + top = 0; + mp = ⊤ + while ((error == 0) && (uio->uio_resid > 0)) { + m->m_len = min(mlen, uio->uio_resid); + error = uiomove(mtod(m, caddr_t), m->m_len, uio); + *mp = m; + mp = &m->m_next; + if (uio->uio_resid > 0) { + MGET(m, M_DONTWAIT, MT_DATA); + if (m == 0) { + error = ENOBUFS; + break; + } + mlen = MLEN; + } + } + if (error) { + ifp->if_ierrors ++; + if (top) + m_freem(top); + return (error); + } + + top->m_pkthdr.len = tlen; + top->m_pkthdr.rcvif = ifp; + + /* + * Ethernet bridge and bpf are handled in ether_input + * + * adjust mbuf and give packet to the ether_input + */ + + eh = mtod(top, struct ether_header *); + m_adj(top, sizeof(struct ether_header)); + ether_input(ifp, eh, top); + ifp->if_ipackets ++; /* ibytes are counted in ether_input */ + + return (0); +} /* tapwrite */ + + +/* + * tappoll + * + * the poll interface, this is only useful on reads + * really. the write detect always returns true, write never blocks + * anyway, it either accepts the packet or drops it + */ +static int +tappoll(dev, events, p) + dev_t dev; + int events; + struct proc *p; +{ + struct tap_softc *tp = dev->si_drv1; + struct ifnet *ifp = &tp->tap_if; + int s, revents = 0; + + TAPDEBUG("%s%d polling\n", ifp->if_name, ifp->if_unit); + + s = splimp(); + if (events & (POLLIN | POLLRDNORM)) { + if (ifp->if_snd.ifq_len > 0) { + TAPDEBUG("%s%d have data in queue. len = %d\n", + ifp->if_name,ifp->if_unit, ifp->if_snd.ifq_len); + revents |= (events & (POLLIN | POLLRDNORM)); + } + else { + TAPDEBUG("%s%d waiting for data\n", + ifp->if_name, ifp->if_unit); + selrecord(p, &tp->tap_rsel); + } + } + + if (events & (POLLOUT | POLLWRNORM)) + revents |= (events & (POLLOUT | POLLWRNORM)); + + splx(s); + return (revents); +} /* tappoll */ diff --git a/sys/net/if_tap.h b/sys/net/if_tap.h new file mode 100644 index 0000000..30f7421 --- /dev/null +++ b/sys/net/if_tap.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * BASED ON: + * ------------------------------------------------------------------------- + * + * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> + * Nottingham University 1987. + */ + +/* + * $FreeBSD$ + * $Id: if_tap.h,v 0.7 2000/07/12 04:12:51 max Exp $ + */ + +#ifndef _NET_IF_TAP_H_ +#define _NET_IF_TAP_H_ + +/* refer to if_tapvar.h for the softc stuff */ + +/* maximum receive packet size (hard limit) */ +#define TAPMRU 16384 + +struct tapinfo { + int baudrate; /* linespeed */ + short mtu; /* maximum transmission unit */ + u_char type; /* ethernet, tokenring, etc. */ + u_char dummy; /* place holder */ +}; + +/* ioctl's for get/set debug */ +#define TAPSDEBUG _IOW('t', 90, int) +#define TAPGDEBUG _IOR('t', 89, int) +#define TAPSIFINFO _IOW('t', 91, struct tapinfo) +#define TAPGIFINFO _IOR('t', 92, struct tapinfo) + +/* VMware ioctl's */ +#define VMIO_SIOCSIFFLAGS _IO('V', 0) +#define VMIO_SIOCSKEEP _IO('V', 1) +#define VMIO_SIOCSIFBR _IO('V', 2) +#define VMIO_SIOCSLADRF _IO('V', 3) + +/* XXX -- unimplemented */ +#define VMIO_SIOCSETMACADDR _IO('V', 4) + +/* XXX -- not used? */ +#define VMIO_SIOCPORT _IO('V', 5) +#define VMIO_SIOCBRIDGE _IO('V', 6) +#define VMIO_SIOCNETIF _IO('V', 7) + +#endif /* !_NET_IF_TAP_H_ */ diff --git a/sys/net/if_tapvar.h b/sys/net/if_tapvar.h new file mode 100644 index 0000000..c48ff1c --- /dev/null +++ b/sys/net/if_tapvar.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * BASED ON: + * ------------------------------------------------------------------------- + * + * Copyright (c) 1998 Brian Somers <brian@Awfulhak.org> + * All rights reserved. + * + * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> + * Nottingham University 1987. + */ + +/* + * $FreeBSD$ + * $Id: if_tapvar.h,v 0.6 2000/07/11 02:16:08 max Exp $ + */ + +#ifndef _NET_IF_TAPVAR_H_ +#define _NET_IF_TAPVAR_H_ + +struct tap_softc { + struct arpcom arpcom; /* ethernet common data */ +#define tap_if arpcom.ac_if + dev_t tap_dev; /* device */ + + u_short tap_flags; /* misc flags */ +#define TAP_OPEN (1 << 0) +#define TAP_INITED (1 << 1) +#define TAP_RWAIT (1 << 2) +#define TAP_ASYNC (1 << 3) +#define TAP_READY (TAP_OPEN|TAP_INITED) + + pid_t tap_pid; /* PID of process to open */ + struct sigio *tap_sigio; /* information for async I/O */ + struct selinfo tap_rsel; /* read select */ +}; + +#endif /* !_NET_IF_TAPVAR_H_ */ |