summaryrefslogtreecommitdiff
path: root/emulators/klh10
diff options
context:
space:
mode:
authorryoon <ryoon>2013-10-17 15:41:09 +0000
committerryoon <ryoon>2013-10-17 15:41:09 +0000
commit079b41b2fd2a8781b89c0953ccccc726b6857b18 (patch)
tree6be304fe3696caf56825128a449087945047ff4a /emulators/klh10
parent51f7c5cf6589bfb376d5e5c3723a5cb3f47413e3 (diff)
downloadpkgsrc-079b41b2fd2a8781b89c0953ccccc726b6857b18.tar.gz
Import klh10-2.0h as emulators/klh10.
PDP-10 KL10B model emulator. KL10B model supports extended addressing. Tap networking support is from http://www.falu.nl/~rhialto/klh-diffs2 . This package is potentially built on i386, amd64, arm, alpha, sparc, and powerpc platforms. But this package supports i386 and amd64 only now, and only amd64 build is tested, due to lack of my test environments.
Diffstat (limited to 'emulators/klh10')
-rw-r--r--emulators/klh10/DESCR2
-rw-r--r--emulators/klh10/MESSAGE21
-rw-r--r--emulators/klh10/Makefile32
-rw-r--r--emulators/klh10/PLIST77
-rw-r--r--emulators/klh10/distinfo16
-rw-r--r--emulators/klh10/patches/patch-doc_install.txt60
-rw-r--r--emulators/klh10/patches/patch-run_klt20_klt20.ini20
-rw-r--r--emulators/klh10/patches/patch-src_Makefile.mk28
-rw-r--r--emulators/klh10/patches/patch-src_Mk-nbx86.mk15
-rw-r--r--emulators/klh10/patches/patch-src_dpimp.c17
-rw-r--r--emulators/klh10/patches/patch-src_dpni20.c141
-rw-r--r--emulators/klh10/patches/patch-src_klh10.c30
-rw-r--r--emulators/klh10/patches/patch-src_kn10def.h15
-rw-r--r--emulators/klh10/patches/patch-src_kn10ops.c24
-rw-r--r--emulators/klh10/patches/patch-src_osdnet.c442
-rw-r--r--emulators/klh10/patches/patch-src_osdnet.h39
16 files changed, 979 insertions, 0 deletions
diff --git a/emulators/klh10/DESCR b/emulators/klh10/DESCR
new file mode 100644
index 00000000000..b64fc084f97
--- /dev/null
+++ b/emulators/klh10/DESCR
@@ -0,0 +1,2 @@
+PDP-10 KL10B model emulator. KL10B model supports extended addressing.
+Tap networking support is from http://www.falu.nl/~rhialto/klh-diffs2 .
diff --git a/emulators/klh10/MESSAGE b/emulators/klh10/MESSAGE
new file mode 100644
index 00000000000..a0914c86d73
--- /dev/null
+++ b/emulators/klh10/MESSAGE
@@ -0,0 +1,21 @@
+===========================================================================
+$NetBSD: MESSAGE,v 1.1 2013/10/17 15:41:09 ryoon Exp $
+
+To boot TOPS-20 with TCP/IP support, you will need to perform the
+following steps.
+
+In detail see ${PREFIX}/share/klh10/klt20.txt for TOPS-20 installation, and
+http://bitsavers.trailing-edge.com/pdf/dec/pdp10/TOPS20/V7/INSTALL.MEM.txt
+for TCP/IP installation.
+
+In short, you should download the following magtape images from
+http://pdp-10.trailing-edge.com/tapes/ .
+bb-h137f-bm.tap.bz2 for TOPS-20, and bb-ev83b-bm_longer.tap.bz2 for TCP/IP.
+
+To run kn10-kl command, you should copy all binary in
+${PREFIX}/share/klh10/bin to your TOPS-10 directory. And run
+./kn10-kl configfile.ini .
+
+To enable tap networking support, kn10-kl command may be run with root
+privilege.
+===========================================================================
diff --git a/emulators/klh10/Makefile b/emulators/klh10/Makefile
new file mode 100644
index 00000000000..2501819bb3a
--- /dev/null
+++ b/emulators/klh10/Makefile
@@ -0,0 +1,32 @@
+# $NetBSD: Makefile,v 1.1 2013/10/17 15:41:09 ryoon Exp $
+
+DISTNAME= panda-dist
+PKGNAME= klh10-2.0h
+CATEGORIES= emulators
+MASTER_SITES= http://panda.trailing-edge.com/
+
+MAINTAINER= ryoon@NetBSD.org
+HOMEPAGE= http://panda.trailing-edge.com/
+COMMENT= PDP-10 KL10B CPU model emulator
+#LICENSE= # KLH10 Free-Fork License
+
+DIST_SUBDIR= ${PKGNAME_NOREV}
+
+WRKSRC= ${WRKDIR}/${DISTNAME}/klh10-2.0h
+
+USE_TOOLS+= pax
+
+BUILD_DIRS= bld/nbx86
+BUILD_TARGET= base-kl
+
+CFLAGS+= -DKLH10_NET_TAP_BRIDGE
+
+INSTALL_MAKE_FLAGS+= KLH10_HOME=${DESTDIR}${PREFIX}/share/klh10/bin
+
+post-install:
+ cd ${WRKSRC}/run; ${FIND} . -type f \! -name '*.orig' -print | \
+ pax -rw ${DESTDIR}${PREFIX}/share/klh10
+ cd ${WRKSRC}/doc; ${FIND} . -type f \! -name '*.orig' -print | \
+ pax -rw ${DESTDIR}${PREFIX}/share/klh10
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/emulators/klh10/PLIST b/emulators/klh10/PLIST
new file mode 100644
index 00000000000..d7c1cd87b43
--- /dev/null
+++ b/emulators/klh10/PLIST
@@ -0,0 +1,77 @@
+@comment $NetBSD: PLIST,v 1.1 2013/10/17 15:41:09 ryoon Exp $
+share/klh10/Intro.txt
+share/klh10/backgrnd.txt
+share/klh10/bin/dpni20
+share/klh10/bin/dprpxx
+share/klh10/bin/dptm03
+share/klh10/bin/kn10-kl
+share/klh10/bin/tapedd
+share/klh10/bin/uexbconv
+share/klh10/bin/vdkfmt
+share/klh10/bin/wfconv
+share/klh10/bin/wxtest
+share/klh10/bugs.txt
+share/klh10/cmdref.txt
+share/klh10/cmdsum.txt
+share/klh10/coding.txt
+share/klh10/dfkfb.txt
+share/klh10/dfkfb/README
+share/klh10/dfkfb/dfkfb
+share/klh10/dfkfb/dfkfb-all.savh
+share/klh10/dfkfb/dfkfb.ini
+share/klh10/dvhost.txt
+share/klh10/history.txt
+share/klh10/install.txt
+share/klh10/kldiff.txt
+share/klh10/klnic/README
+share/klh10/klnic/boot-nic.sav
+share/klh10/klnic/dist-klnic.ini
+share/klh10/klnic/dist51-klnic.ini
+share/klh10/klnic/klh10.ini
+share/klh10/klnic/mtboot-nic.sav
+share/klh10/klt10.txt
+share/klh10/klt10/README
+share/klh10/klt10/klbddt.exe
+share/klh10/klt10/klboot.exe
+share/klh10/klt10/klt10.ini
+share/klh10/klt10/twonky.ini
+share/klh10/klt20.txt
+share/klh10/klt20/README
+share/klh10/klt20/boot.sav
+share/klh10/klt20/inst-klt20.ini
+share/klh10/klt20/klt20.ini
+share/klh10/klt20/mtboot.sav
+share/klh10/ksits.txt
+share/klh10/ksits/@.ddt-u
+share/klh10/ksits/@.its-647kn-u
+share/klh10/ksits/@.its-647md-u
+share/klh10/ksits/@.its-647pi-u
+share/klh10/ksits/@.nsalv-260-u
+share/klh10/ksits/README
+share/klh10/ksits/itsbin.647kn-u
+share/klh10/ksits/itsbin.647md-u
+share/klh10/ksits/itsbin.647pi-u
+share/klh10/ksits/klh10-kn.ini
+share/klh10/ksits/klh10-md.ini
+share/klh10/ksits/klh10-pi.ini
+share/klh10/ksits/pubits/adm/hosts.its
+share/klh10/ksits/pubits/adm/its.ipfw
+share/klh10/ksits/pubits/adm/rc.firewall-its
+share/klh10/ksits/pubits/adm/router.notes
+share/klh10/ksits/pubits/doc/bootload.files
+share/klh10/ksits/pubits/doc/distrib.its
+share/klh10/ksits/pubits/doc/dumpsys.help
+share/klh10/kst10.txt
+share/klh10/kst10/README
+share/klh10/kst10/ksbddt.exe
+share/klh10/kst10/ksboot.exe
+share/klh10/kst20.txt
+share/klh10/kst20/README
+share/klh10/kst20/inst-kst20.ini
+share/klh10/kst20/kst20.ini
+share/klh10/kst20/smboot-k.sav
+share/klh10/kst20/smmtbt-k.sav
+share/klh10/news.txt
+share/klh10/usage.txt
+share/klh10/utils.txt
+share/klh10/vtape.txt
diff --git a/emulators/klh10/distinfo b/emulators/klh10/distinfo
new file mode 100644
index 00000000000..e2af465ba15
--- /dev/null
+++ b/emulators/klh10/distinfo
@@ -0,0 +1,16 @@
+$NetBSD: distinfo,v 1.1 2013/10/17 15:41:09 ryoon Exp $
+
+SHA1 (klh10-2.0h/panda-dist.tar.gz) = b32b8d64145a6376326dc6ac1bf68ada4f2d7313
+RMD160 (klh10-2.0h/panda-dist.tar.gz) = ca779c295c5cd3a3be3dd0141aed86f1c2c08aa5
+Size (klh10-2.0h/panda-dist.tar.gz) = 221145391 bytes
+SHA1 (patch-doc_install.txt) = 84f89d148a7c3d4af11ddc708d592899807ee1b6
+SHA1 (patch-run_klt20_klt20.ini) = c48dc5d9360ff0cd1a7afc7ab85ad6de15585c29
+SHA1 (patch-src_Makefile.mk) = 3733e70306cb5f1dcec53cbe959332fd2200d3cb
+SHA1 (patch-src_Mk-nbx86.mk) = aba5e293f8d6674cff8fd1494f678cb11de2b888
+SHA1 (patch-src_dpimp.c) = a0f2059624f47f65d020a9a941fa5964825fe443
+SHA1 (patch-src_dpni20.c) = 375051de6fe813f07b2f7a7b4560c0b56bd23ca9
+SHA1 (patch-src_klh10.c) = 674b50f83913b37c9bc8bbccfa67b546019622fe
+SHA1 (patch-src_kn10def.h) = fbc77ff07342c00f635ff404669613b8433e60bf
+SHA1 (patch-src_kn10ops.c) = 6683baacd2f96dd64eceddc487151e264964e5e9
+SHA1 (patch-src_osdnet.c) = e7400876eb3b6e462c1db36a98ab209623a769de
+SHA1 (patch-src_osdnet.h) = d6f49bf4a0b58a6278e3e3195ad3976287ef4106
diff --git a/emulators/klh10/patches/patch-doc_install.txt b/emulators/klh10/patches/patch-doc_install.txt
new file mode 100644
index 00000000000..6a67f575d0c
--- /dev/null
+++ b/emulators/klh10/patches/patch-doc_install.txt
@@ -0,0 +1,60 @@
+$NetBSD: patch-doc_install.txt,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- doc/install.txt.orig 2001-11-19 12:12:06.000000000 +0000
++++ doc/install.txt
+@@ -175,6 +175,16 @@ config file if they don't already exist
+ pseudo-device bpf 1 # Need at least one for NI20 or IMP
+ pseudo-device tun 1 # Need at least one for IMP
+
++NetBSD
++------
++ See The NetBSD Guide, chapter 17.9 "Kernel Tuning" for information on
++how to recompile a kernel. You need at least these options (as of 3.0):
++
++ options SYSVSHM # System V-like memory sharing
++ options SHMMAXPGS=10240 # 2048 pages is the default, >8192 for KLH10
++
++ pseudo-device tap # cloning device for NI20
++ pseudo-device bridge # cloning device for NI20
+
+ Linux
+ -----
+@@ -1116,6 +1126,36 @@ mistakenly "fixed" to disallow it (FreeB
+ other host before telnetting back into the KN10. A better solution
+ would be to fix those OSes that are open-source, and push to have
+ these fixes incorporated in the standard releases.
++ For NetBSD (it may work on FreeBSD too) there exists a better
++solution. A special configuration is created with a virtual ethernet
++segment that has its host-side in the form of the interface tap0 (as in
++the example below). The tap0 interface is bridged to the real network
++interface. The NI20 is at the "other end" of the virtual ethernet.
++(This differs from the other connectivity methods where the named
++interface is the one that is basically used as the NI20). The NI20 is
++therefore a dedicated interface:
++
++ devdef ni0 564 ni20 ipaddr=10.0.0.51 ifc=tap0 dedic=true
++
++If the named tap interface already exists, no further changes to its
++configuration are made. You can use this for alternative connectivity,
++such as routed on the 10.0.1.0/24 subnet (instead of bridged):
++
++ # To the shell, suppose your real network is 10.0.0.0/24,
++ # create a 10.0.1.0/24 network for KLH:
++ ifconfig tap0 create inet 10.0.1.1 netmask 255.255.255.0 up
++ ; in .ini file:
++ devdef ni0 564 ni20 ipaddr=10.0.1.51 ifc=tap0 dedic=true
++ ! in SYSTEM:INTERNET.ADDRESS on TOPS-20 v7.0
++ IPNI#0,10 0 1 51,PACKET-SIZE:1500,DEFAULT,PREFERRED
++ ! in SYSTEM:INTERNET.ADDRESS on TOPS-20 v7.1
++ IPNI#0,10.0.1.51,PACKET-SIZE:1500,LOGICAL-HOST-MASK:255.255.255.0,DEFAULT,PREFERRED
++ ! in SYSTEM:INTERNET.GATEWAYS on TOPS-20 v7.x
++ PRIME 10.0.1.1
++
++(If TOPS-20 v7.0 can't do subnetting it might be better to use a
++192.168.2.0/24 network)
++
+
+ LHDH (IMP): (KS-ITS only)
+
diff --git a/emulators/klh10/patches/patch-run_klt20_klt20.ini b/emulators/klh10/patches/patch-run_klt20_klt20.ini
new file mode 100644
index 00000000000..2d882b980e9
--- /dev/null
+++ b/emulators/klh10/patches/patch-run_klt20_klt20.ini
@@ -0,0 +1,20 @@
+$NetBSD: patch-run_klt20_klt20.ini,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- run/klt20/klt20.ini.orig 2001-09-26 16:05:52.000000000 +0000
++++ run/klt20/klt20.ini
+@@ -12,7 +12,12 @@ devdef mta0 rh1.0 tm03 type=tu45
+
+ ; Need KLNI to avoid LAPRBF BUGCHKs - use valid address if known
+ ;
+-devdef ni0 564 ni20 ipaddr=10.0.0.51
++; devdef ni0 564 ni20 ipaddr=10.0.0.51
++; The (NetBSD/FreeBSD) version with tap(4) and bridge(4) creates the named
++; tap device dynamically and bridges it to the default interface.
++; If you want it differently (for instance routed instead of bridged),
++; you can create the tap yourself and it will be used as it is.
++devdef ni0 564 ni20 ipaddr=10.0.0.51 ifc=tap0 dedic=true
+
+ ; Load disk bootstrap directly
+ load boot.sav
diff --git a/emulators/klh10/patches/patch-src_Makefile.mk b/emulators/klh10/patches/patch-src_Makefile.mk
new file mode 100644
index 00000000000..dd3ea27a290
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_Makefile.mk
@@ -0,0 +1,28 @@
+$NetBSD: patch-src_Makefile.mk,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/Makefile.mk.orig 2005-02-21 23:16:14.000000000 +0000
++++ src/Makefile.mk
+@@ -249,20 +249,7 @@ clean:
+ #
+ install-unix:
+ @echo "Copying binaries into ${KLH10_HOME}"
+- @-rm -rf ${KLH10_HOME}/flushed
+- @-mkdir ${KLH10_HOME}/flushed
+- @if [ -x ${KLH10_HOME}/kn10-ks ]; then \
+- mv ${KLH10_HOME}/kn10-ks ${KLH10_HOME}/flushed; fi
+- @if [ -x ${KLH10_HOME}/kn10-kl ]; then \
+- mv ${KLH10_HOME}/kn10-kl ${KLH10_HOME}/flushed; fi
+- @if [ -x ${KLH10_HOME}/dprpxx ]; then \
+- mv ${KLH10_HOME}/dprpxx ${KLH10_HOME}/flushed; fi
+- @if [ -x ${KLH10_HOME}/dptm03 ]; then \
+- mv ${KLH10_HOME}/dptm03 ${KLH10_HOME}/flushed; fi
+- @if [ -x ${KLH10_HOME}/dpni20 ]; then \
+- mv ${KLH10_HOME}/dpni20 ${KLH10_HOME}/flushed; fi
+- @if [ -x ${KLH10_HOME}/dpimp ]; then \
+- mv ${KLH10_HOME}/dpimp ${KLH10_HOME}/flushed; fi
++ @-mkdir ${KLH10_HOME}
+ @if [ -x kn10-ks ]; then cp -p kn10-ks ${KLH10_HOME}/; fi
+ @if [ -x kn10-kl ]; then cp -p kn10-kl ${KLH10_HOME}/; fi
+ @if [ -x dprpxx ]; then cp -p dprpxx ${KLH10_HOME}/; fi
diff --git a/emulators/klh10/patches/patch-src_Mk-nbx86.mk b/emulators/klh10/patches/patch-src_Mk-nbx86.mk
new file mode 100644
index 00000000000..921336a6367
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_Mk-nbx86.mk
@@ -0,0 +1,15 @@
+$NetBSD: patch-src_Mk-nbx86.mk,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/Mk-nbx86.mk.orig 2002-04-25 22:56:48.000000000 +0000
++++ src/Mk-nbx86.mk
+@@ -21,7 +21,7 @@
+
+ # Build definitions
+ SRC = ../../src
+-CFLAGS = -c -g3 -O3
++CFLAGS += -c -g3 -O3
+ CFLAGS_LINT = -ansi -pedantic -Wall -Wshadow \
+ -Wstrict-prototypes -Wmissing-prototypes \
+ -Wmissing-declarations -Wredundant-decls
diff --git a/emulators/klh10/patches/patch-src_dpimp.c b/emulators/klh10/patches/patch-src_dpimp.c
new file mode 100644
index 00000000000..423de48a2f5
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_dpimp.c
@@ -0,0 +1,17 @@
+$NetBSD: patch-src_dpimp.c,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/dpimp.c.orig 2003-02-23 10:07:35.000000000 +0000
++++ src/dpimp.c
+@@ -228,6 +228,10 @@ default for every OS that implements /de
+ #include <sys/resource.h> /* For setpriority() */
+ #include <sys/mman.h> /* For mlockall() */
+
++#if CENV_SYS_NETBSD
++#include <poll.h>
++#endif
++
+ #include "dpimp.h" /* DPIMP specific defs, grabs DPSUP if needed */
+
+ #ifdef RCSID
diff --git a/emulators/klh10/patches/patch-src_dpni20.c b/emulators/klh10/patches/patch-src_dpni20.c
new file mode 100644
index 00000000000..dc681699fdd
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_dpni20.c
@@ -0,0 +1,141 @@
+$NetBSD: patch-src_dpni20.c,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/dpni20.c.orig 2003-02-23 10:07:50.000000000 +0000
++++ src/dpni20.c
+@@ -170,4 +170,5 @@ The following general situations are pos
+ #endif
+
++
+ /* Globals */
+
+@@ -433,4 +434,6 @@ main(int argc, char **argv)
+ tentoeth(dpni); /* Parent process handles output to net */
+
++ osn_pfdeinit();
++
+ return 1; /* Never returns, but placate compiler */
+ }
+@@ -499,4 +502,5 @@ void net_init(register struct dpni20_s *
+ }
+
++
+ /* Now set any return info values in shared struct.
+ */
+@@ -997,5 +1001,5 @@ pfshow(struct OSN_PFSTRUCT *pf)
+ /* LNX packetfilter initialization */
+
+-#if KLH10_NET_LNX
++#if KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
+
+ /*
+@@ -1093,4 +1097,8 @@ int lnx_filter(register struct dpni20_s
+ void eth_adrset(register struct dpni20_s *dpni)
+ {
++#if OSN_USE_IPONLY
++ dbprintln("\"%s\" multicast table ignored - IP-only interface",
++ dpni->dpni_ifnam);
++#else
+ unsigned char rdea[ETHER_ADRSIZ];
+ char old[OSN_EASTRSIZ];
+@@ -1158,4 +1166,5 @@ void eth_adrset(register struct dpni20_s
+ }
+
++#endif
+ /* Assume succeeded since call succeeded, and clobber our address! */
+ memcpy(dpni->dpni_eth, dpni->dpni_rqeth, ETHER_ADRSIZ);
+@@ -1176,4 +1185,8 @@ void eth_adrset(register struct dpni20_s
+ void eth_mcatset(register struct dpni20_s *dpni)
+ {
++#if OSN_USE_IPONLY
++ dbprintln("\"%s\" multicast table ignored - IP-only interface",
++ dpni->dpni_ifnam);
++#else
+ ossock_t s;
+ int i, n, j;
+@@ -1250,4 +1263,5 @@ void eth_mcatset(register struct dpni20_
+ nmcats = n;
+ memcpy(ethmcat[0], dpni->dpni_mcat[0], (n * 6));
++#endif
+ }
+
+@@ -1362,5 +1376,7 @@ int arp_myreply(register unsigned char *
+ if (swstatus) {
+ char ipstr[OSN_IPSTRSIZ];
+- dbprintln("ARP MyReply %s", ip_adrsprint(ipstr, ife->ife_ipchr));
++ char ethstr[OSN_EASTRSIZ];
++ dbprintln("ARP MyReply %s %s", ip_adrsprint(ipstr, ife->ife_ipchr),
++ eth_adrsprint(ethstr, ife->ife_ea));
+ }
+
+@@ -1373,4 +1389,7 @@ int arp_myreply(register unsigned char *
+ }
+ #else
++ /* XXX
++ * Why is this sent to the packet filter (= host) and not to the -10?????
++ */
+ (void)write(pffd, pktbuf, sizeof(pktbuf));
+ #endif
+@@ -1442,5 +1461,5 @@ void ethtoten(register struct dpni20_s *
+ /* Else cnt must be -1 as call failed */
+ }
+-#elif KLH10_NET_NIT || KLH10_NET_PFLT || KLH10_NET_LNX
++#elif KLH10_NET_NIT || KLH10_NET_PFLT || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
+ cnt = read(pffd, buff, max);
+ #elif KLH10_NET_BPF
+@@ -1500,15 +1519,18 @@ void ethtoten(register struct dpni20_s *
+ dbprint("Read=%d", cnt);
+ }
+-#if KLH10_NET_LNX
++#if KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
+ /* Linux has no packet filtering, thus must apply manual check to
+ each and every packet read, unless dedicated. Ugh!
+ */
+- if (!dpni->dpni_dedic) {
++ if (KLH10_NET_TAP_BRIDGE || !dpni->dpni_dedic) {
+ /* Sharing interface. Check for IP, DECNET, 802.3 */
+- if (!lnx_filter(dpni, buff, cnt))
++ if (!lnx_filter(dpni, buff, cnt)) {
++ if (DBGFLG)
++ dbprint("Dropped");
+ continue; /* Drop packet, continue reading */
++ }
+ }
+ #endif /* KLH10_NET_LNX */
+-#if KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX
++#if KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
+ #if 0
+ if (DBGFLG)
+@@ -1522,5 +1544,5 @@ void ethtoten(register struct dpni20_s *
+ dbprint("sent RPKT");
+
+-#endif /* KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX */
++#endif /* KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_PFLT || KLH10_NET_LNX || NET_TAP_BRIDGE */
+
+ #if KLH10_NET_BPF
+@@ -1595,5 +1617,9 @@ void tentoeth(register struct dpni20_s *
+ ** at least one entry in our table of host's IP interfaces.
+ */
++#if KLH10_NET_TAP_BRIDGE
++ doarpchk = 0;
++#else
+ doarpchk = (dpni->dpni_doarp & DPNI_ARPF_OCHK) && (osn_nifents() > 0);
++#endif
+
+ dpx = dp_dpxto(&dp); /* Get ptr to "To-DP" xfer stuff */
+@@ -1641,5 +1667,5 @@ void tentoeth(register struct dpni20_s *
+ #else
+ cnt = write(pffd, buff, rcnt);
+-#endif
++#endif /* else KLH10_NET_DLPI */
+ if (cnt != rcnt) {
+ if ((cnt < 0) && (errno == EINTR)) {
+@@ -1702,4 +1728,7 @@ void dumppkt(unsigned char *ucp, int cnt
+ }
+ }
++
++
++
+
+ /* Add OSDNET shared code here */
diff --git a/emulators/klh10/patches/patch-src_klh10.c b/emulators/klh10/patches/patch-src_klh10.c
new file mode 100644
index 00000000000..bae727ba279
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_klh10.c
@@ -0,0 +1,30 @@
+$NetBSD: patch-src_klh10.c,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/klh10.c.orig 2005-02-21 23:20:34.000000000 +0000
++++ src/klh10.c
+@@ -337,6 +337,7 @@ CMDDEF(cd_lights, fc_lights, CMRF_TLI
+ KEYSBEGIN(fectbkeys)
+ KEYDEF("?", cd_ques)
+ KEYDEF("help", cd_help)
++ KEYDEF("exit", cd_quit)
+ KEYDEF("quit", cd_quit)
+ KEYDEF("load", cd_load)
+ KEYDEF("dump", cd_dump)
+@@ -2765,6 +2766,7 @@ fc_dump(struct cmd_s *cm)
+ static void
+ fc_lights(struct cmd_s *cm)
+ {
++#if KLH10_DEV_LITES /* Moby conditional for entire file */
+ unsigned long port = 0;
+ int c;
+ char *sloc = cm->cmd_arglin;
+@@ -2783,6 +2785,7 @@ fc_lights(struct cmd_s *cm)
+ }
+ }
+ printf("?Bad address\n");
++#endif /* KLH10_DEV_LITES */
+ }
+
+ /* Instruction printing routines */
diff --git a/emulators/klh10/patches/patch-src_kn10def.h b/emulators/klh10/patches/patch-src_kn10def.h
new file mode 100644
index 00000000000..7cbe2043335
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_kn10def.h
@@ -0,0 +1,15 @@
+$NetBSD: patch-src_kn10def.h,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/kn10def.h.orig 2006-06-15 17:30:59.000000000 +0000
++++ src/kn10def.h
+@@ -235,7 +235,7 @@ typedef int pcinc_t; /* Type of all
+ #if KLH10_EXTADR
+ # define PC_ADDXCT(x) { register pcinc_t i__ = (x); if (i__) PC_ADD(i__); }
+ #else
+-# define PC_ADDXCT(x) (cpu.mr_PC += (x)) /* For now; fix up later? */
++# define PC_ADDXCT(x) { volatile pcinc_t i__ = (x); cpu.mr_PC += i__; }
+ #endif
+
+ /* Macros for putting PC into a word.
diff --git a/emulators/klh10/patches/patch-src_kn10ops.c b/emulators/klh10/patches/patch-src_kn10ops.c
new file mode 100644
index 00000000000..4200b784f8b
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_kn10ops.c
@@ -0,0 +1,24 @@
+$NetBSD: patch-src_kn10ops.c,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/kn10ops.c.orig 2001-11-10 13:29:09.000000000 +0000
++++ src/kn10ops.c
+@@ -759,7 +759,7 @@ dw10_t op10ashc(register dw10_t d,
+ ** must be done to the argument prior to the call!
+ */
+ static dw10_t
+-x_ashc(register dw10_t d,
++x_ashc(/*register*/ dw10_t d,
+ register int i)
+ {
+ #endif /* IFFLAGS */
+@@ -3238,7 +3238,7 @@ static int qdivstep(qw10_t *aq,
+ register dw10_t d,
+ register int nmagbits)
+ {
+- register qw10_t qw;
++ /*register*/ qw10_t qw;
+ dw10_t quot;
+ register int qbit;
+
diff --git a/emulators/klh10/patches/patch-src_osdnet.c b/emulators/klh10/patches/patch-src_osdnet.c
new file mode 100644
index 00000000000..c13adc8f657
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_osdnet.c
@@ -0,0 +1,442 @@
+$NetBSD: patch-src_osdnet.c,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/osdnet.c.orig 2005-04-28 22:01:04.000000000 +0000
++++ src/osdnet.c
+@@ -68,7 +68,7 @@ int
+ osn_ifsock(char *ifnam, ossock_t *as)
+ {
+ #if (KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
+- KLH10_NET_TUN || KLH10_NET_LNX)
++ KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
+ return ((*as = socket(AF_INET, SOCK_DGRAM, 0)) >= 0);
+ #else
+ # error OSD implementation needed for osn_ifsock
+@@ -79,7 +79,7 @@ int
+ osn_ifclose(ossock_t s)
+ {
+ #if (KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
+- KLH10_NET_TUN || KLH10_NET_LNX)
++ KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
+ return (close(s) >= 0);
+ #else
+ # error OSD implementation needed for osn_ifclose
+@@ -161,6 +161,12 @@ or alternatively:
+ ? (sizeof(struct ifreq) - sizeof(struct sockaddr) + (ifr).ifr_addr.sa_len) \
+ : sizeof(struct ifreq))
+
++ This has been made trickier by NetBSD 5.0, which doesn't put a sockaddr
++ but a (union with as largest member a) sockaddr_storage in the ifreq.
++ Now the size is always the same again, but not sizeof(struct sockaddr).
++ This can (probably) be recognised by the existence of
++ #define ifr_space ifr_ifru.ifru_space / * sockaddr_storage * /
++
+ */
+ /*
+ Note that searching for AF_INET or IP addresses only finds interfaces that
+@@ -288,7 +294,7 @@ osn_iftab_pass(int opts, int npass, int
+ uses a variable-size "ifreq" entry! Choke...
+ */
+ ifnext = ifp + 1; /* Assume normal entry at first */
+-#if NETIF_HAS_SALEN
++#if NETIF_HAS_SALEN && !defined(ifr_space)
+ if (ifp->ifr_addr.sa_len > sizeof(struct sockaddr)) {
+ offset = ifp->ifr_addr.sa_len - sizeof(struct sockaddr);
+ ifnext = (struct ifreq *)((char *)ifnext + offset);
+@@ -382,6 +388,8 @@ osn_iftab_pass(int opts, int npass, int
+ }
+ }
+
++#include <stddef.h>
++
+ void
+ osn_ifctab_show(FILE *f, struct ifconf *ifc)
+ {
+@@ -393,7 +401,14 @@ osn_ifctab_show(FILE *f, struct ifconf *
+ int nents = 0;
+ int nvary = 0;
+
+- fprintf(f, "Interface table: %ld bytes (%d entries if std addr len %d)\n",
++ fprintf(f, "sizeof struct ifreq = %d\r\n", (int) sizeof(struct ifreq));
++ fprintf(f, "IFNAMSIZ = %d\r\n", (int) IFNAMSIZ);
++ fprintf(f, "offset of struct sockaddr_storage = %d\r\n", (int) offsetof(struct ifreq, ifr_space));
++ fprintf(f, "sizeof struct sockaddr = %d\r\n", (int) sizeof(struct sockaddr));
++ fprintf(f, "sizeof struct sockaddr_storage = %d\r\n", (int) sizeof(struct sockaddr_storage));
++ fprintf(f, "sizeof union ifr_ifru = %d\r\n", (int) sizeof(ifr->ifr_ifru));
++
++ fprintf(f, "Interface table: %ld bytes (%d entries if std addr len %d)\r\n",
+ (long)ifc->ifc_len, ifc->ifc_len/sizeof(struct ifreq),
+ (int)sizeof(struct sockaddr));
+
+@@ -408,18 +423,19 @@ osn_ifctab_show(FILE *f, struct ifconf *
+ len = sizeof(struct sockaddr);
+ #endif
+
++ fprintf(f, "offset: %d\r\n", (int)((char *)ifr - (char *)ifc->ifc_req));
+ /* Output entry data */
+- fprintf(f, "%2d: \"%.*s\" fam %d, len %d",
++ fprintf(f, "%2d: \"%.*s\" sockaddr.sa_family %d, .sa_len %d",
+ i, (int)sizeof(ifr->ifr_name), ifr->ifr_name,
+ ifr->ifr_addr.sa_family, len);
+ if (len) {
+ cp = (unsigned char *) ifr->ifr_addr.sa_data;
+- fprintf(f, " = %x", *cp);
++ fprintf(f, " = (sockaddr.sa_data) %x", *cp);
+ for (--len; len > 0; --len) {
+ fprintf(f, ":%x", *++cp);
+ }
+ }
+- fprintf(f, "\n");
++ fprintf(f, "\r\n");
+
+ cp = (unsigned char *) ifr->ifr_addr.sa_data;
+ switch (ifr->ifr_addr.sa_family) {
+@@ -429,7 +445,7 @@ osn_ifctab_show(FILE *f, struct ifconf *
+ struct in_addr *in = &skin->sin_addr;
+ unsigned char *ucp = (unsigned char *) &in->s_addr;
+
+- fprintf(f, " AF_INET = port %d, IP %d.%d.%d.%d\n",
++ fprintf(f, " AF_INET = port %d, IP %d.%d.%d.%d\r\n",
+ (int)skin->sin_port,
+ ucp[0], ucp[1], ucp[2], ucp[3]);
+ }
+@@ -439,7 +455,7 @@ osn_ifctab_show(FILE *f, struct ifconf *
+ case AF_LINK:
+ {
+ struct sockaddr_dl *dla = (struct sockaddr_dl *) &ifr->ifr_addr;
+- fprintf(f, " AF_LINK = type %d, alen %d",
++ fprintf(f, " AF_LINK = type %d, sdl_alen %d",
+ dla->sdl_type, dla->sdl_alen);
+ if (len = dla->sdl_alen) {
+ cp = (unsigned char *) LLADDR(dla);
+@@ -448,18 +464,23 @@ osn_ifctab_show(FILE *f, struct ifconf *
+ fprintf(f, ":%x", *++cp);
+ }
+ }
+- fprintf(f, "\n");
++ fprintf(f, "\r\n");
+ }
+ break;
+ #endif
+
++#if defined(AF_INET6)
++ case AF_INET6:
++ fprintf(f, " AF_INET6 (No handler for this)\r\n");
++ break;
++#endif
+ default:
+- fprintf(f, " No handler for this family\n");
++ fprintf(f, " No handler for this family\r\n");
+ }
+
+
+ /* Move onto next entry */
+-#if NETIF_HAS_SALEN
++#if NETIF_HAS_SALEN && !defined(ifr_space)
+ if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) {
+ ++nvary;
+ ifr = (struct ifreq *)((char *)(ifr + 1) +
+@@ -469,10 +490,10 @@ osn_ifctab_show(FILE *f, struct ifconf *
+ ifr++;
+ }
+ if (nvary)
+- fprintf(f, "Interface summary: %d entries of varying length\n",
++ fprintf(f, "Interface summary: %d entries of varying length\r\n",
+ nents);
+ else
+- fprintf(f, "Interface summary: %d entries of std length %d\n",
++ fprintf(f, "Interface summary: %d entries of std length %d\r\n",
+ nents, (int)sizeof(struct ifreq));
+ }
+
+@@ -483,7 +504,7 @@ osn_iftab_show(FILE *f, struct ifent *if
+ register struct ifent *ife;
+ int i;
+
+- fprintf(f, "Filtered IFE table: %d entries\n", nents);
++ fprintf(f, "Filtered IFE table: %d entries\r\n", nents);
+
+ for (i = 0, ife = ifents; i < nents; ++i, ++ife) {
+ fprintf(f, "%2d: \"%s\"", i, ife->ife_name);
+@@ -502,7 +523,7 @@ osn_iftab_show(FILE *f, struct ifent *if
+ fprintf(f, " (Other: fam %d)",
+ ife->ife_pother->ifr_addr.sa_family);
+ }
+- fprintf(f, "\n");
++ fprintf(f, "\r\n");
+ }
+ }
+
+@@ -897,6 +918,9 @@ osn_ifeaget(int s, /* Socket for (AF_IN
+ return TRUE;
+ }
+
++static struct eth_addr emhost_ea = /* Emulated host ether addr for tap */
++ { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
++
+ /* OSN_PFEAGET - get physical ethernet address for an open packetfilter FD.
+ *
+ * Also not well documented, but generally easier to perform.
+@@ -945,8 +969,20 @@ osn_pfeaget(int pfs, /* Packetfilter so
+ }
+ ea_set(eap, endp.end_addr);
+
+-#elif KLH10_NET_BPF && !CENV_SYS_NETBSD && !CENV_SYS_FREEBSD
+- /* NetBSD no longer seems to support this */
++#elif KLH10_NET_TAP_BRIDGE
++ /* If we do tap(4) + bridge(4), the ether address of the tap is wholly
++ * irrelevant, it is on the other side of the "wire".
++ * Our own address is something we can make up completely.
++ */
++ if (emhost_ea.ea_octets[5] == 0xFF) {
++ time_t t = time(NULL);
++ emhost_ea.ea_octets[5] = t & 0xFE;
++ emhost_ea.ea_octets[4] = (t >> 8) & 0xFF;
++ emhost_ea.ea_octets[3] = (t >> 16) & 0xFF;
++ }
++ ea_set(eap, &emhost_ea); /* Return the ether address */
++#elif (KLH10_NET_BPF && !CENV_SYS_NETBSD && !CENV_SYS_FREEBSD)
++ /* NetBSD no longer seems to support this (on bpf) */
+ struct ifreq ifr;
+
+ strncpy(ifr.ifr_name, ifnam, sizeof(ifr.ifr_name));
+@@ -1131,7 +1167,7 @@ osn_ifeaset(int s, /* Socket for (AF_IN
+ char *ifnam, /* Interface name */
+ unsigned char *newpa) /* New ether address */
+ {
+-#if CENV_SYS_DECOSF || KLH10_NET_LNX \
++#if CENV_SYS_DECOSF || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE \
+ || (CENV_SYS_FREEBSD && defined(SIOCSIFLLADDR))
+
+ /* Common preamble code */
+@@ -1190,6 +1226,8 @@ osn_ifeaset(int s, /* Socket for (AF_IN
+ if (ownsock) close(s);
+ return FALSE;
+ }
++# elif KLH10_NET_TAP_BRIDGE
++ ea_set(&emhost_ea, newpa);
+ # else
+ # error "Unimplemented OS routine osn_ifeaset()"
+ # endif
+@@ -1338,6 +1376,7 @@ pfopen(void)
+ }
+
+ #endif /* KLH10_NET_PFLT || KLH10_NET_BPF */
++
+
+ #if KLH10_NET_PFLT
+
+@@ -1916,6 +1955,212 @@ osn_pfinit(struct osnpf *osnpf, void *ar
+ }
+ #endif /* KLH10_NET_NIT */
+
++/*
++ * Too bad that this is never called...
++ */
++osn_pfdeinit()
++{
++#if KLH10_NET_TAP_BRIDGE
++ void tap_bridge_close();
++ tap_bridge_close();
++#endif
++}
++
++#if KLH10_NET_TAP_BRIDGE
++
++osn_pfinit(register struct osnpf *osnpf, void *arg)
++{
++ int fd;
++ char *ifnam = osnpf->osnpf_ifnam;
++
++ /* No "default interface" concept here */
++ if (!ifnam || !ifnam[0])
++ esfatal(1, "Packetfilter interface must be specified");
++
++ fd = tap_bridge_open(ifnam);
++
++ /* Now get our fresh new virtual interface's ethernet address.
++ */
++ (void) osn_pfeaget(fd, ifnam, (unsigned char *)&(osnpf->osnpf_ea));
++
++ return fd;
++}
++
++#include <net/if_tap.h>
++#include <net/if_bridgevar.h>
++#include <stdint.h>
++
++static struct ifreq br_ifr;
++static struct ifreq tap_ifr;
++static int my_tap;
++
++/*
++ * A TAP is a virtual ethernet interface, much like TUN is a virtual IP
++ * interface. We can use it to inject packets into the Unix input stream,
++ * provided it is UP and the host side has a matching IP address and
++ * netmask (also much like TUN), or that it is bridged to another interface.
++ *
++ * Here we try to create the user-given interface and then bridge it to
++ * the "default" interface. This is probably the most common configuration.
++ * If something else is desired, the user can set up the tap herself,
++ * and we'll just use it as it is. This is useful for a routed approach,
++ * for instance.
++ */
++int
++tap_bridge_open(char *ifnam)
++{
++ int tapfd;
++ int res;
++ union ipaddr netmask;
++ char cmdbuff[128];
++ struct ifent *ife;
++ int s;
++ int i;
++ struct ifbreq br_req;
++ struct ifdrv br_ifd;
++
++ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
++ esfatal(1, "tap_bridge_open: socket() failed");
++ }
++
++ /* try to create tapN as specified by the user */
++ memset(&tap_ifr, 0, sizeof(tap_ifr));
++ strcpy(tap_ifr.ifr_name, ifnam);
++ res = ioctl(s, SIOCIFCREATE, &tap_ifr);
++ if (res == 0) {
++ my_tap = 1;
++ dbprintln("Created host-side tap \"%s\"", ifnam);
++ } else {
++ if (errno != EEXIST)
++ esfatal(1, "tap_bridge_open: can't create tap \"%s\"?", ifnam);
++ my_tap = 0;
++ dbprintln("Host-side tap \"%s\" alread exists; use it as-is", ifnam);
++ }
++
++ sprintf(cmdbuff, "/dev/%s", ifnam);
++ tapfd = open(cmdbuff, O_RDWR, 0);
++
++ if (tapfd < 0) {
++ /* Note possible error meanings:
++ ENOENT - no such filename
++ ENXIO - not configured in kernel
++ */
++ esfatal(1, "Couldn't find or open 10-side tap \"%s\"", cmdbuff);
++ }
++
++ dbprintln("Opened 10-side tap \"%s\"", cmdbuff);
++
++ /* Finally, turn on IFF_UP just in case the above didn't do it.
++ Note interface name is still there from the SIOCIFCREATE.
++ */
++ if (ioctl(s, SIOCGIFFLAGS, &tap_ifr) < 0) {
++ esfatal(1, "tap_bridge_open tap SIOCGIFFLAGS failed");
++ }
++ if (!(tap_ifr.ifr_flags & IFF_UP)) {
++ tap_ifr.ifr_flags |= IFF_UP;
++ if (ioctl(s, SIOCSIFFLAGS, &tap_ifr) < 0) {
++ esfatal(1, "tap_bridge_open tap SIOCSIFFLAGS failed");
++ }
++ if (DP_DBGFLG)
++ dbprint("tap_bridge_open tap did SIOCSIFFLAGS");
++ }
++
++ if (my_tap) {
++ for (i = 0; i < 1000; i++) {
++ /* try to create bridge%d */
++ memset(&br_ifr, 0, sizeof(br_ifr));
++ sprintf(br_ifr.ifr_name, "bridge%d", i);
++ res = ioctl(s, SIOCIFCREATE, &br_ifr);
++ if (res == 0)
++ break;
++ if (errno != EEXIST)
++ esfatal(1, "tap_bridge_open: can't create bridge \"%s\"?", br_ifr.ifr_name);
++ }
++ dbprintln("Created bridge \"%s\"", br_ifr.ifr_name);
++
++ /*
++ * Find default IP interface to bridge with.
++ * It might find the wrong one if there is more than one.
++ */
++
++ ife = osn_ipdefault();
++ if (!ife)
++ esfatal(0, "Couldn't find default interface");
++
++ if (swstatus)
++ dbprintln("Bridging with default interface \"%s\"", ife->ife_name);
++
++ if (1) {
++ sprintf(cmdbuff, "/sbin/brconfig %s add %s add %s up",
++ br_ifr.ifr_name, ife->ife_name, ifnam);
++ res = system(cmdbuff);
++ dbprintln("%s => %d", cmdbuff, res);
++ } else {
++ /* do whatever brconfig bridge0 add intf0 does... */
++ memset(&br_ifd, 0, sizeof(br_ifd));
++ memset(&br_req, 0, sizeof(br_req));
++
++ /* set name of the bridge */
++ strcpy(br_ifd.ifd_name, br_ifr.ifr_name);
++ br_ifd.ifd_cmd = BRDGADD;
++ br_ifd.ifd_len = sizeof(br_req);
++ br_ifd.ifd_data = &br_req;
++
++ /* brconfig bridge0 add tap0 (the virtual interface) */
++ strcpy(br_req.ifbr_ifsname, ifnam);
++ res = ioctl(s, SIOCSDRVSPEC, &br_ifd);
++ if (res == -1)
++ esfatal(1, "tap_bridge_open: can't add virtual intf to bridge?");
++
++ /* brconfig bridge0 add vr0 (the hardware interface) */
++ strcpy(br_req.ifbr_ifsname, ife->ife_name);
++ res = ioctl(s, SIOCSDRVSPEC, &br_ifd);
++ if (res == -1)
++ esfatal(1, "tap_bridge_open: can't add real intf to bridge?");
++
++ /* Finally, turn on IFF_UP just in case the above didn't do it.
++ * Note interface name is still there.
++ */
++ if (ioctl(s, SIOCGIFFLAGS, &br_ifr) < 0) {
++ esfatal(1, "tap_bridge_open bridge SIOCGIFFLAGS failed");
++ }
++ if (!(br_ifr.ifr_flags & IFF_UP)) {
++ br_ifr.ifr_flags |= IFF_UP;
++ if (ioctl(s, SIOCSIFFLAGS, &br_ifr) < 0) {
++ esfatal(1, "tap_bridge_open bridge SIOCSIFFLAGS failed");
++ }
++ if (DP_DBGFLG)
++ dbprint("tap_bridge_open bridge did SIOCSIFFLAGS");
++ }
++
++ }
++ }
++ close(s);
++
++ return tapfd; /* Success! */
++}
++
++void
++tap_bridge_close()
++{
++ if (my_tap) {
++ int s, res;
++ struct ifreq tap_ifr;
++
++ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
++ esfatal(1, "tap_bridge_close: socket() failed");
++ }
++
++ /* Destroy bridge */
++ res = ioctl(s, SIOCIFDESTROY, &br_ifr);
++ res = ioctl(s, SIOCIFDESTROY, &tap_ifr);
++
++ close(s);
++ }
++}
++
++#endif /* KLH10_NET_TAP_BRIDGE */
++
+ #if KLH10_NET_DLPI
+
+ /* DLPI packetfilter initialization */
diff --git a/emulators/klh10/patches/patch-src_osdnet.h b/emulators/klh10/patches/patch-src_osdnet.h
new file mode 100644
index 00000000000..fa8d5b4401e
--- /dev/null
+++ b/emulators/klh10/patches/patch-src_osdnet.h
@@ -0,0 +1,39 @@
+$NetBSD: patch-src_osdnet.h,v 1.1 2013/10/17 15:41:10 ryoon Exp $
+
+http://www.falu.nl/~rhialto/klh-diffs2
+
+--- src/osdnet.h.orig 2001-11-19 02:34:01.000000000 +0000
++++ src/osdnet.h
+@@ -59,6 +59,9 @@
+ #ifndef KLH10_NET_DLPI /* Solaris Data Link Provider Interface */
+ # define KLH10_NET_DLPI 0
+ #endif
++#ifndef KLH10_NET_TAP_BRIDGE /* BSD Ethernet Tunnel device + a bridge */
++# define KLH10_NET_TAP_BRIDGE 0
++#endif
+ #ifndef KLH10_NET_TUN /* BSD IP Tunnel device */
+ # define KLH10_NET_TUN 0
+ #endif
+@@ -67,14 +70,18 @@
+ #endif
+
+ #if !(KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
+- KLH10_NET_TUN || KLH10_NET_LNX)
++ KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
+ /* None explicitly specified, pick a reasonable default */
+-# if (CENV_SYS_FREEBSD && OSN_USE_IPONLY)
++# if ((CENV_SYS_NETBSD || CENV_SYS_FREEBSD) && OSN_USE_IPONLY)
+ # undef KLH10_NET_TUN
+ # define KLH10_NET_TUN 1
+ # elif (CENV_SYS_NETBSD || CENV_SYS_FREEBSD)
+-# undef KLH10_NET_BPF
+-# define KLH10_NET_BPF 1
++/*
++ * # undef KLH10_NET_BPF
++ * # define KLH10_NET_BPF 1
++ */
++# undef KLH10_NET_TAP_BRIDGE
++# define KLH10_NET_TAP_BRIDGE 1
+ # elif CENV_SYS_DECOSF
+ # undef KLH10_NET_PFLT
+ # define KLH10_NET_PFLT 1