Bochs/bochs/patches/patch.ethlinux-bogdand
2001-06-25 20:51:43 +00:00

1170 lines
39 KiB
Plaintext

----------------------------------------------------------------------
Patch name: patch.ethlinux-bogdand
RCS Id: $Id: patch.ethlinux-bogdand,v 1.3 2001-06-25 20:51:43 bdenney Exp $
Author: Bogdan Diaconescu <bogdand@rds.ro>
adapted for Bochs by Bryce Denney <bryce.denney@bigfoot.com>
Date: Mon, 25 Jun 2001 18:38:31 -0200
Detailed description:
I have done a patch to make the network for plex86-Linux working.
The patch could be added to the last CVS version and it implements
eth_linux.cc using Linux Socket Filtering. I used a thread to make
readings from the socket in an infinite loop. I tested this
networking stuff only on Linux so if you test it on other OSes
please tell me what happend. I did small changes on ne2k.cc source
and I don't know if the changes works also on Free BSD where they
worked before.
Updated Mon Jun 25 16:43:09 EDT 2001 by Bryce to add bpf.h header file.
Patch was created with:
diff -urN
Apply patch to what version:
current cvs
Instructions:
To patch, go to main bochs directory.
Type "patch -p1 < THIS_PATCH_FILE".
For now, you must manually add "eth_linux.o" to the list of
BX_HW_IODEV_OBJS.
----------------------------------------------------------------------
--- bochs-clean/configure Mon Jun 25 14:06:44 2001
+++ bochs-ethlinux/configure Mon Jun 25 12:22:31 2001
@@ -3196,6 +3196,7 @@
echo "$ac_t""no" 1>&6
fi
+ use_ne2k=yes
else
echo "$ac_t""no" 1>&6
cat >> confdefs.h <<\EOF
@@ -3203,6 +3204,7 @@
EOF
NE2K_OBJS=''
+ use_ne2k=no
fi
else
@@ -3212,6 +3214,7 @@
EOF
NE2K_OBJS=''
+ use_ne2k=no
fi
@@ -3220,7 +3223,7 @@
echo $ac_n "checking for i440FX PCI support""... $ac_c" 1>&6
-echo "configure:3224: checking for i440FX PCI support" >&5
+echo "configure:3227: checking for i440FX PCI support" >&5
# Check whether --enable-pci or --disable-pci was given.
if test "${enable_pci+set}" = set; then
enableval="$enable_pci"
@@ -3255,7 +3258,7 @@
echo $ac_n "checking for port e9 hack""... $ac_c" 1>&6
-echo "configure:3259: checking for port e9 hack" >&5
+echo "configure:3262: checking for port e9 hack" >&5
# Check whether --enable-port-e9-hack or --disable-port-e9-hack was given.
if test "${enable_port_e9_hack+set}" = set; then
enableval="$enable_port_e9_hack"
@@ -3286,7 +3289,7 @@
echo $ac_n "checking for use of .cpp as suffix""... $ac_c" 1>&6
-echo "configure:3290: checking for use of .cpp as suffix" >&5
+echo "configure:3293: checking for use of .cpp as suffix" >&5
# Check whether --enable-cpp or --disable-cpp was given.
if test "${enable_cpp+set}" = set; then
enableval="$enable_cpp"
@@ -3328,7 +3331,7 @@
echo $ac_n "checking for Bochs internal debugger support""... $ac_c" 1>&6
-echo "configure:3332: checking for Bochs internal debugger support" >&5
+echo "configure:3335: checking for Bochs internal debugger support" >&5
# Check whether --enable-debugger or --disable-debugger was given.
if test "${enable_debugger+set}" = set; then
enableval="$enable_debugger"
@@ -3366,7 +3369,7 @@
echo $ac_n "checking for disassembler support""... $ac_c" 1>&6
-echo "configure:3370: checking for disassembler support" >&5
+echo "configure:3373: checking for disassembler support" >&5
# Check whether --enable-disasm or --disable-disasm was given.
if test "${enable_disasm+set}" = set; then
enableval="$enable_disasm"
@@ -3413,7 +3416,7 @@
echo $ac_n "checking whether to use readline""... $ac_c" 1>&6
-echo "configure:3417: checking whether to use readline" >&5
+echo "configure:3420: checking whether to use readline" >&5
# Check whether --enable-readline or --disable-readline was given.
if test "${enable_readline+set}" = set; then
enableval="$enable_readline"
@@ -3435,7 +3438,7 @@
if test "$want_readline" = yes; then
echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
-echo "configure:3439: checking for readline in -lreadline" >&5
+echo "configure:3442: checking for readline in -lreadline" >&5
ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3443,7 +3446,7 @@
ac_save_LIBS="$LIBS"
LIBS="-lreadline $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3447 "configure"
+#line 3450 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3454,7 +3457,7 @@
readline()
; return 0; }
EOF
-if { (eval echo configure:3458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3489,17 +3492,17 @@
ac_safe=`echo "readline/history.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for readline/history.h""... $ac_c" 1>&6
-echo "configure:3493: checking for readline/history.h" >&5
+echo "configure:3496: checking for readline/history.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3498 "configure"
+#line 3501 "configure"
#include "confdefs.h"
#include <readline/history.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3503: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3506: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -3527,7 +3530,7 @@
echo $ac_n "checking for loader support""... $ac_c" 1>&6
-echo "configure:3531: checking for loader support" >&5
+echo "configure:3534: checking for loader support" >&5
# Check whether --enable-loader or --disable-loader was given.
if test "${enable_loader+set}" = set; then
enableval="$enable_loader"
@@ -3565,7 +3568,7 @@
INSTRUMENT_DIR='instrument/stubs'
echo $ac_n "checking for instrumentation support""... $ac_c" 1>&6
-echo "configure:3569: checking for instrumentation support" >&5
+echo "configure:3572: checking for instrumentation support" >&5
# Check whether --enable-instrumentation or --disable-instrumentation was given.
if test "${enable_instrumentation+set}" = set; then
enableval="$enable_instrumentation"
@@ -3700,7 +3703,7 @@
echo $ac_n "checking for VGA emulation""... $ac_c" 1>&6
-echo "configure:3704: checking for VGA emulation" >&5
+echo "configure:3707: checking for VGA emulation" >&5
# Check whether --enable-vga or --disable-vga was given.
if test "${enable_vga+set}" = set; then
enableval="$enable_vga"
@@ -3734,7 +3737,7 @@
echo $ac_n "checking for FPU emulation""... $ac_c" 1>&6
-echo "configure:3738: checking for FPU emulation" >&5
+echo "configure:3741: checking for FPU emulation" >&5
FPU_VAR=''
FPU_GLUE_OBJ=''
# Check whether --enable-fpu or --disable-fpu was given.
@@ -3779,7 +3782,7 @@
echo $ac_n "checking for x86 debugger support""... $ac_c" 1>&6
-echo "configure:3783: checking for x86 debugger support" >&5
+echo "configure:3786: checking for x86 debugger support" >&5
# Check whether --enable-x86-debugger or --disable-x86-debugger was given.
if test "${enable_x86_debugger+set}" = set; then
enableval="$enable_x86_debugger"
@@ -3815,7 +3818,7 @@
echo $ac_n "checking for CDROM support""... $ac_c" 1>&6
-echo "configure:3819: checking for CDROM support" >&5
+echo "configure:3822: checking for CDROM support" >&5
# Check whether --enable-cdrom or --disable-cdrom was given.
if test "${enable_cdrom+set}" = set; then
enableval="$enable_cdrom"
@@ -3857,7 +3860,7 @@
echo $ac_n "checking for Sound Blaster 16 support""... $ac_c" 1>&6
-echo "configure:3861: checking for Sound Blaster 16 support" >&5
+echo "configure:3864: checking for Sound Blaster 16 support" >&5
# Check whether --enable-sb16 or --disable-sb16 was given.
if test "${enable_sb16+set}" = set; then
enableval="$enable_sb16"
@@ -4006,7 +4009,7 @@
echo $ac_n "checking for gui library to use""... $ac_c" 1>&6
-echo "configure:4010: checking for gui library to use" >&5
+echo "configure:4013: checking for gui library to use" >&5
if (test "$with_x11" != yes) && \
(test "$with_beos" != yes) && \
@@ -4152,7 +4155,7 @@
if test "$use_curses" = yes; then
echo $ac_n "checking for mvaddch in -lcurses""... $ac_c" 1>&6
-echo "configure:4156: checking for mvaddch in -lcurses" >&5
+echo "configure:4159: checking for mvaddch in -lcurses" >&5
ac_lib_var=`echo curses'_'mvaddch | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4160,7 +4163,7 @@
ac_save_LIBS="$LIBS"
LIBS="-lcurses $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4164 "configure"
+#line 4167 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4171,7 +4174,7 @@
mvaddch()
; return 0; }
EOF
-if { (eval echo configure:4175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4192,7 +4195,7 @@
fi
echo $ac_n "checking for mvaddch in -lncurses""... $ac_c" 1>&6
-echo "configure:4196: checking for mvaddch in -lncurses" >&5
+echo "configure:4199: checking for mvaddch in -lncurses" >&5
ac_lib_var=`echo ncurses'_'mvaddch | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4200,7 +4203,7 @@
ac_save_LIBS="$LIBS"
LIBS="-lncurses $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4204 "configure"
+#line 4207 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4211,7 +4214,7 @@
mvaddch()
; return 0; }
EOF
-if { (eval echo configure:4215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4232,7 +4235,7 @@
fi
echo $ac_n "checking for mvaddch in -ltermlib""... $ac_c" 1>&6
-echo "configure:4236: checking for mvaddch in -ltermlib" >&5
+echo "configure:4239: checking for mvaddch in -ltermlib" >&5
ac_lib_var=`echo termlib'_'mvaddch | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4240,7 +4243,7 @@
ac_save_LIBS="$LIBS"
LIBS="-ltermlib $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4244 "configure"
+#line 4247 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4251,7 +4254,7 @@
mvaddch()
; return 0; }
EOF
-if { (eval echo configure:4255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4277,21 +4280,21 @@
fi
fi
-if test "$with_rfb" = yes; then
+if test "$with_rfb" = yes -o "$use_ne2k" = yes; then
# first see if compiler takes "-pthread" argument
echo $ac_n "checking for -pthread arg to compiler""... $ac_c" 1>&6
-echo "configure:4284: checking for -pthread arg to compiler" >&5
+echo "configure:4287: checking for -pthread arg to compiler" >&5
CFLAGS_SAVE="$CFLAGS"
CFLAGS="$CFLAGS -pthread"
cat > conftest.$ac_ext <<EOF
-#line 4288 "configure"
+#line 4291 "configure"
#include "confdefs.h"
#include <pthread.h>
int main() {
pthread_create(0,0,0,0);
; return 0; }
EOF
-if { (eval echo configure:4295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
# it compiles with -pthread
@@ -4307,7 +4310,7 @@
# now try with -lpthread
CFLAGS="$CFLAGS_SAVE"
echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:4311: checking for pthread_create in -lpthread" >&5
+echo "configure:4314: checking for pthread_create in -lpthread" >&5
ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4315,7 +4318,7 @@
ac_save_LIBS="$LIBS"
LIBS="-lpthread $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4319 "configure"
+#line 4322 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4326,7 +4329,7 @@
pthread_create()
; return 0; }
EOF
-if { (eval echo configure:4330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4378,7 +4381,7 @@
# Extract the first word of "gzip", so it can be a program name with args.
set dummy gzip; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4382: checking for $ac_word" >&5
+echo "configure:4385: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GZIP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4413,7 +4416,7 @@
# Extract the first word of "tar", so it can be a program name with args.
set dummy tar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4417: checking for $ac_word" >&5
+echo "configure:4420: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_TAR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
--- bochs-clean/configure.in Mon Jun 25 14:06:44 2001
+++ bochs-ethlinux/configure.in Mon Jun 25 12:22:27 2001
@@ -311,15 +311,18 @@
AC_DEFINE(BX_NE2K_SUPPORT, 1)
NE2K_OBJS='ne2k.o eth.o eth_null.o'
AC_CHECK_HEADER(net/bpf.h, NE2K_OBJS="$NE2K_OBJS eth_fbsd.o")
+ use_ne2k=yes
else
AC_MSG_RESULT(no)
AC_DEFINE(BX_NE2K_SUPPORT, 0)
NE2K_OBJS=''
+ use_ne2k=no
fi],
[
AC_MSG_RESULT(no)
AC_DEFINE(BX_NE2K_SUPPORT, 0)
NE2K_OBJS=''
+ use_ne2k=no
]
)
AC_SUBST(NE2K_OBJS)
@@ -891,7 +894,7 @@
fi
fi
-if test "$with_rfb" = yes; then
+if test "$with_rfb" = yes -o "$use_ne2k" = yes; then
# first see if compiler takes "-pthread" argument
AC_MSG_CHECKING(for -pthread arg to compiler)
CFLAGS_SAVE="$CFLAGS"
--- bochs-clean/iodev/eth.h Mon Jun 25 14:06:46 2001
+++ bochs-ethlinux/iodev/eth.h Mon Jun 25 12:32:08 2001
@@ -75,6 +75,6 @@
#if defined(__FreeBSD__) || defined(__OpenBSD__)
#define ETH_FBSD 1
#endif
-#if (0 && defined(linux))
+#if defined(linux)
#define ETH_LINUX 1
#endif
--- bochs-clean/iodev/eth_linux.cc Mon Jun 25 14:14:17 2001
+++ bochs-ethlinux/iodev/eth_linux.cc Mon Jun 25 12:19:04 2001
@@ -0,0 +1,272 @@
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+// eth_linux.cc - linux code for an ethernet pktmover
+
+// Bogdan Diaconescu (bogdand@rds.ro) coded all of this
+// NE2000/ether stuff.
+//
+// eth_linux.cc is a Linux implementation of the ethernet packetmover. It uses
+// Linux Socket Filtering which is very close to BPF. I used a thread to poll
+// the socket in an infinite loop. Anyway there are somme problems with the
+// approach I choosed to implement the guest<->host interface:
+// - the guestOS is not able to connect with the hostOS.
+// - the host ethernet interface is put in promiscuous mode.
+//
+// ne2k: ioaddr=0x280, irq=10, mac=00:a:b:c:1:2, ethmod=linux, ethdev=eth0
+
+#include "bochs.h"
+
+#define LOG_THIS bx_ne2k.
+
+extern "C" {
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <linux/if_ether.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netpacket/packet.h>
+#include <pcap/net/bpf.h>
+#include <errno.h>
+#include <pthread.h>
+};
+
+#define BX_BPF_INSNSIZ 8 // number of bpf insns
+
+static const struct bpf_insn macfilter[] = {
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2),
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0xaaaaaaaa, 0, 2),
+ BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 0),
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0000aaaa, 2, 0),
+ BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 0),
+ BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x01, 0, 1),
+ BPF_STMT(BPF_RET, 1514),
+ BPF_STMT(BPF_RET, 0),
+};
+
+#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
+#define ARPHRD_EETHER 2 /* Experimental Ethernet */
+
+pthread_t pt;
+void* recv_th(void*);
+
+//
+// define the class. This is private to this module
+//
+
+class bx_linux_pktmover_c : public eth_pktmover_c {
+public:
+ bx_linux_pktmover_c(const char *netif, const char *macaddr,
+ eth_rx_handler_t rxh,
+ void *rxarg);
+ void sendpkt(void *buf, unsigned io_len);
+ void rx_timer(void);
+private:
+ char* linux_macaddr[6];
+ int bpf_fd;
+ struct bpf_insn filter[BX_BPF_INSNSIZ];
+ Bit8u* rxbuf;
+};
+
+
+bx_linux_pktmover_c* this_ptr;
+
+//
+// Define the static class that registers the derived pktmover class,
+// and allocates one on request.
+//
+class bx_linux_locator_c : public eth_locator_c {
+public:
+ bx_linux_locator_c(void) : eth_locator_c("linux") {}
+protected:
+ eth_pktmover_c *allocate(const char *netif, const char *macaddr,
+ eth_rx_handler_t rxh,
+ void *rxarg) {
+ return (new bx_linux_pktmover_c(netif, macaddr, rxh, rxarg));
+ }
+} bx_linux_match;
+
+
+//
+// Define the methods for the bx_linux_pktmover derived class
+//
+
+// the constructor
+//
+// Open a socket and bind it to the interface
+//
+bx_linux_pktmover_c::bx_linux_pktmover_c(const char *netif,
+ const char *macaddr,
+ eth_rx_handler_t rxh,
+ void *rxarg)
+{
+ char device[sizeof "ethXX"];
+ struct ifreq ifr, saved_ifr;
+ struct sockaddr_ll sl;
+ int linktype;
+ int mtu;
+ struct bpf_program bp;
+
+ memcpy(linux_macaddr, macaddr, 6);
+ strcpy(device, netif);
+ bpf_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if (this->bpf_fd < 0) {
+ BX_ERROR (("ne2k: could not open socket: %s\n", strerror(errno)));
+ return;
+ }
+
+ /* get the interface index */
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(this->bpf_fd, SIOCGIFINDEX, &ifr) < 0 ) {
+ BX_ERROR(("ne2k: SIOCGIFINDEX: %s\n", strerror(errno)));
+ close(this->bpf_fd);
+ return;
+ }
+ BX_INFO(("ne2k: interface index is %i\n", ifr.ifr_ifindex));
+
+ /* bind the socket to the interface */
+ memset(&sl, 0, sizeof(sl));
+ sl.sll_family = AF_PACKET;
+ sl.sll_protocol = htonl(ETH_P_ALL);
+ sl.sll_ifindex = ifr.ifr_ifindex;
+ if (bind(this->bpf_fd, (struct sockaddr*)&sl, sizeof(sl))) {
+ BX_ERROR (("error binding interface %s: %s\n", device, strerror(errno));
+ close(this->bpf_fd));
+ return;
+ }
+
+ /* get the media link type */
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(this->bpf_fd, SIOCGIFHWADDR, &ifr) < 0 ) {
+ BX_ERROR (("ne2k: SIOCGIFHWADDR: %s\n", strerror(errno)));
+ close(this->bpf_fd);
+ return;
+ }
+ switch (ifr.ifr_hwaddr.sa_family) {
+ case ARPHRD_ETHER:
+ case ARPHRD_EETHER:
+ linktype = DLT_EN10MB;
+ break;
+ default:
+ BX_ERROR (("ne2k: found unknown media!\n"));
+ return;
+ }
+
+ /* Base the buffer size on the interface MTU */
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(this->bpf_fd, SIOCGIFMTU, &ifr) < 0 ) {
+ BX_ERROR(("ne2k: SIOCGIFMTU: %s", strerror(errno)));
+ close(this->bpf_fd);
+ return;
+ }
+ mtu = ifr.ifr_mtu;
+ BX_INFO (("ne2k: MTU is %i\n", ifr.ifr_mtu));
+ /* alloc the RX buffer */
+ this->rxbuf = (Bit8u*)malloc(mtu + 64);
+
+ /* put the interface in promiscuous mode */
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, device);
+ if (ioctl(this->bpf_fd, SIOCGIFFLAGS, &ifr) < 0 ) {
+ BX_ERROR(("ne2k: SIOCGIFFLAGS: %s", strerror(errno)));
+ close(this->bpf_fd);
+ return;
+ }
+ saved_ifr = ifr;
+ ifr.ifr_flags |= IFF_PROMISC;
+ if (ioctl(this->bpf_fd, SIOCSIFFLAGS, &ifr) < 0 ) {
+ BX_ERROR(("ne2k: SIOCSIFFLAGS: %s", strerror(errno)));
+ close(this->bpf_fd);
+ return;
+ }
+ ifr.ifr_flags &= ~IFF_PROMISC;
+ BX_INFO (("ne2k: interface %s in promisc mode now\n", device));
+
+ /* now install the filter */
+ memcpy(&this->filter, macfilter, sizeof(macfilter));
+ this->filter[1].k = (macaddr[2] & 0xff) << 24 |
+ (macaddr[3] & 0xff) << 16 |
+ (macaddr[4] & 0xff) << 8 |
+ (macaddr[5] & 0xff);
+ this->filter[3].k = (macaddr[0] & 0xff) << 8 |
+ (macaddr[1] & 0xff);
+ bp.bf_len = 8;
+ bp.bf_insns = &this->filter[0];
+ int ret;
+ ret = setsockopt(this->bpf_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bp, sizeof(bp)); if (ret < 0){
+ BX_ERROR(("ne2k: setsockopt: %s\n", strerror(errno)));
+ close(this->bpf_fd);
+ return;
+ }
+ BX_INFO (("ne2k: bpf filter registered\n"));
+
+ /* start the RX poll using a thread */
+ pthread_create(&pt, NULL, recv_th, NULL);
+ this_ptr = this;
+
+ this->rxh = rxh;
+ this->rxarg = rxarg;
+}
+
+// the output routine - called with pre-formatted ethernet frame.
+void
+bx_linux_pktmover_c::sendpkt(void *buf, unsigned io_len)
+{
+ int status = 0;
+
+ if (this->bpf_fd != -1)
+ status = write(this->bpf_fd, buf, io_len);
+ if (status < 0)
+ BX_ERROR(("ne2k: error on write packet: %s\n", strerror(errno)));
+}
+
+
+void
+bx_linux_pktmover_c::rx_timer(void)
+{
+ int nbytes = 0;
+
+ nbytes = read(this->bpf_fd, this->rxbuf, 2048);
+ if (nbytes < 0)
+ BX_ERROR(("ne2k: error on receive packet: %s\n", strerror(errno)));
+
+#ifdef undef
+ printf("packet rx (%d bytes):\n\t", nbytes);
+ for (int i = 0; i < nbytes; i++) {
+ printf("%02x ", rxbuf[i]);
+ if (i && (((i+1) % 16) == 0))
+ printf("\n\t");
+ }
+ printf("\n");
+#endif
+
+ if (nbytes > 0) {
+ (*rxh)(rxarg, rxbuf, nbytes);
+ }
+
+}
+
+
+void* recv_th(void* args){
+ int i = 0;
+ do{
+ this_ptr->rx_timer();
+ i++;
+ }while(1);
+}
--- bochs-clean/iodev/ne2k.cc Mon Jun 25 14:06:48 2001
+++ bochs-ethlinux/iodev/ne2k.cc Mon Jun 25 12:24:21 2001
@@ -124,6 +124,7 @@
if (value & 0x01) {
BX_NE2K_THIS s.ISR.reset = 1;
BX_NE2K_THIS s.CR.stop = 1;
+ BX_NE2K_THIS s.CR.start = 0;
} else {
BX_NE2K_THIS s.CR.stop = 0;
}
@@ -134,9 +135,9 @@
// must be cleared
if ((value & 0x02) && !BX_NE2K_THIS s.CR.start) {
BX_NE2K_THIS s.ISR.reset = 0;
+ BX_NE2K_THIS s.CR.start = ((value & 0x02) == 0x02);
}
- BX_NE2K_THIS s.CR.start = ((value & 0x02) == 0x02);
BX_NE2K_THIS s.CR.pgsel = (value & 0xc0) >> 6;
// Check for start-tx
@@ -185,7 +186,7 @@
BX_NE2K_THIS s.remote_bytes == 0) {
BX_NE2K_THIS s.ISR.rdma_done = 1;
if (BX_NE2K_THIS s.IMR.rdma_inte) {
- BX_NE2K_THIS devices->pic->trigger_irq(BX_NE2K_THIS s.base_irq);
+ raise_interrupt();
}
}
}
@@ -267,7 +268,7 @@
// registers must have been initialised.
//
if (io_len != (1 + BX_NE2K_THIS s.DCR.wdsize))
- BX_PANIC(("dma read, wrong size %d", io_len));
+ BX_ERROR(("dma read, wrong size %d", io_len));
if (BX_NE2K_THIS s.remote_bytes == 0)
BX_PANIC(("ne2K: dma read, byte count 0"));
@@ -880,7 +881,7 @@
// Generate an interrupt if not masked and not one in progress
if (BX_NE2K_THIS s.IMR.tx_inte && !BX_NE2K_THIS s.ISR.pkt_tx) {
BX_NE2K_THIS s.ISR.pkt_tx = 1;
- BX_NE2K_THIS devices->pic->trigger_irq(BX_NE2K_THIS s.base_irq);
+ raise_interrupt();
}
BX_NE2K_THIS s.tx_timer_active = 0;
}
@@ -1147,7 +1148,7 @@
BX_NE2K_THIS s.ISR.pkt_rx = 1;
if (BX_NE2K_THIS s.IMR.rx_inte) {
- BX_NE2K_THIS devices->pic->trigger_irq(BX_NE2K_THIS s.base_irq);
+ raise_interrupt();
}
}
@@ -1234,4 +1235,10 @@
BX_PANIC(("could not locate null module"));
}
}
+}
+
+void
+bx_ne2k_c::raise_interrupt()
+{
+ bx_devices.pic->trigger_irq (BX_NE2K_THIS s.base_irq);
}
--- bochs-clean/iodev/ne2k.h Mon Jun 25 14:06:48 2001
+++ bochs-ethlinux/iodev/ne2k.h Mon Jun 25 11:49:15 2001
@@ -202,6 +202,8 @@
eth_pktmover_c *ethdev;
+ BX_NE2K_SMF void raise_interrupt();
+
BX_NE2K_SMF void reset_device(void);
BX_NE2K_SMF Bit32u read_cr(void);
BX_NE2K_SMF void write_cr(Bit32u value);
----------------------------------------------------------------------
diff -urN bochs-clean/iodev/pcap-bpf.h bochs-ethlinux/iodev/pcap-bpf.h
--- bochs-clean/iodev/pcap-bpf.h Wed Dec 31 19:00:00 1969
+++ bochs-ethlinux/iodev/pcap-bpf.h Mon Jun 25 16:34:35 2001
@@ -0,0 +1,388 @@
+//
+// iodev/pcap-bpf.h
+// $Id: patch.ethlinux-bogdand,v 1.3 2001-06-25 20:51:43 bdenney Exp $
+//
+// This file is copied from the sources of libpcap-0.6.2, in the net/bpf.h
+// directory. libpcap is distributed under a BSD license, as shown below.
+//
+
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)bpf.h 7.1 (Berkeley) 5/7/91
+ *
+ * @(#) $Header: /home/volker/Archiv/bochs-cvs-rsync-20110222/bochs/patches/patch.ethlinux-bogdand,v 1.3 2001-06-25 20:51:43 bdenney Exp $ (LBL)
+ */
+
+#ifndef BPF_MAJOR_VERSION
+
+/* BSD style release date */
+#define BPF_RELEASE 199606
+
+typedef int bpf_int32;
+typedef u_int bpf_u_int32;
+
+/*
+ * Alignment macros. BPF_WORDALIGN rounds up to the next
+ * even multiple of BPF_ALIGNMENT.
+ */
+#ifndef __NetBSD__
+#define BPF_ALIGNMENT sizeof(bpf_int32)
+#else
+#define BPF_ALIGNMENT sizeof(long)
+#endif
+#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
+
+#define BPF_MAXINSNS 512
+#define BPF_MAXBUFSIZE 0x8000
+#define BPF_MINBUFSIZE 32
+
+/*
+ * Structure for BIOCSETF.
+ */
+struct bpf_program {
+ u_int bf_len;
+ struct bpf_insn *bf_insns;
+};
+
+/*
+ * Struct returned by BIOCGSTATS.
+ */
+struct bpf_stat {
+ u_int bs_recv; /* number of packets received */
+ u_int bs_drop; /* number of packets dropped */
+};
+
+/*
+ * Struct return by BIOCVERSION. This represents the version number of
+ * the filter language described by the instruction encodings below.
+ * bpf understands a program iff kernel_major == filter_major &&
+ * kernel_minor >= filter_minor, that is, if the value returned by the
+ * running kernel has the same major number and a minor number equal
+ * equal to or less than the filter being downloaded. Otherwise, the
+ * results are undefined, meaning an error may be returned or packets
+ * may be accepted haphazardly.
+ * It has nothing to do with the source code version.
+ */
+struct bpf_version {
+ u_short bv_major;
+ u_short bv_minor;
+};
+/* Current version number of filter architecture. */
+#define BPF_MAJOR_VERSION 1
+#define BPF_MINOR_VERSION 1
+
+/*
+ * BPF ioctls
+ *
+ * The first set is for compatibility with Sun's pcc style
+ * header files. If your using gcc, we assume that you
+ * have run fixincludes so the latter set should work.
+ */
+#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
+#define BIOCGBLEN _IOR(B,102, u_int)
+#define BIOCSBLEN _IOWR(B,102, u_int)
+#define BIOCSETF _IOW(B,103, struct bpf_program)
+#define BIOCFLUSH _IO(B,104)
+#define BIOCPROMISC _IO(B,105)
+#define BIOCGDLT _IOR(B,106, u_int)
+#define BIOCGETIF _IOR(B,107, struct ifreq)
+#define BIOCSETIF _IOW(B,108, struct ifreq)
+#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
+#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
+#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
+#define BIOCIMMEDIATE _IOW(B,112, u_int)
+#define BIOCVERSION _IOR(B,113, struct bpf_version)
+#define BIOCSTCPF _IOW(B,114, struct bpf_program)
+#define BIOCSUDPF _IOW(B,115, struct bpf_program)
+#else
+#define BIOCGBLEN _IOR('B',102, u_int)
+#define BIOCSBLEN _IOWR('B',102, u_int)
+#define BIOCSETF _IOW('B',103, struct bpf_program)
+#define BIOCFLUSH _IO('B',104)
+#define BIOCPROMISC _IO('B',105)
+#define BIOCGDLT _IOR('B',106, u_int)
+#define BIOCGETIF _IOR('B',107, struct ifreq)
+#define BIOCSETIF _IOW('B',108, struct ifreq)
+#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
+#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
+#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
+#define BIOCIMMEDIATE _IOW('B',112, u_int)
+#define BIOCVERSION _IOR('B',113, struct bpf_version)
+#define BIOCSTCPF _IOW('B',114, struct bpf_program)
+#define BIOCSUDPF _IOW('B',115, struct bpf_program)
+#endif
+
+/*
+ * Structure prepended to each packet.
+ */
+struct bpf_hdr {
+ struct timeval bh_tstamp; /* time stamp */
+ bpf_u_int32 bh_caplen; /* length of captured portion */
+ bpf_u_int32 bh_datalen; /* original length of packet */
+ u_short bh_hdrlen; /* length of bpf header (this struct
+ plus alignment padding) */
+};
+/*
+ * Because the structure above is not a multiple of 4 bytes, some compilers
+ * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
+ * Only the kernel needs to know about it; applications use bh_hdrlen.
+ */
+#if defined(KERNEL) || defined(_KERNEL)
+#define SIZEOF_BPF_HDR 18
+#endif
+
+/*
+ * Data-link level type codes.
+ */
+
+/*
+ * These are the types that are the same on all platforms; on other
+ * platforms, a <net/bpf.h> should be supplied that defines the additional
+ * DLT_* codes appropriately for that platform (the BSDs, for example,
+ * should not just pick up this version of "bpf.h"; they should also define
+ * the additional DLT_* codes used by their kernels, as well as the values
+ * defined here - and, if the values they use for particular DLT_ types
+ * differ from those here, they should use their values, not the ones
+ * here).
+ */
+#define DLT_NULL 0 /* no link-layer encapsulation */
+#define DLT_EN10MB 1 /* Ethernet (10Mb) */
+#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
+#define DLT_AX25 3 /* Amateur Radio AX.25 */
+#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
+#define DLT_CHAOS 5 /* Chaos */
+#define DLT_IEEE802 6 /* IEEE 802 Networks */
+#define DLT_ARCNET 7 /* ARCNET */
+#define DLT_SLIP 8 /* Serial Line IP */
+#define DLT_PPP 9 /* Point-to-point Protocol */
+#define DLT_FDDI 10 /* FDDI */
+
+/*
+ * These are values from the traditional libpcap "bpf.h".
+ * Ports of this to particular platforms should replace these definitions
+ * with the ones appropriate to that platform, if the values are
+ * different on that platform.
+ */
+#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
+#define DLT_RAW 12 /* raw IP */
+
+/*
+ * These are values from BSD/OS's "bpf.h".
+ * These are not the same as the values from the traditional libpcap
+ * "bpf.h"; however, these values shouldn't be generated by any
+ * OS other than BSD/OS, so the correct values to use here are the
+ * BSD/OS values.
+ *
+ * Platforms that have already assigned these values to other
+ * DLT_ codes, however, should give these codes the values
+ * from that platform, so that programs that use these codes will
+ * continue to compile - even though they won't correctly read
+ * files of these types.
+ */
+#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
+#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
+
+#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
+
+/*
+ * This value is defined by NetBSD; other platforms should refrain from
+ * using it for other purposes, so that NetBSD savefiles with a link
+ * type of 50 can be read as this type on all platforms.
+ */
+#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
+
+/*
+ * This value was defined by libpcap 0.5; platforms that have defined
+ * it with a different value should define it here with that value -
+ * a link type of 104 in a save file will be mapped to DLT_C_HDLC,
+ * whatever value that happens to be, so programs will correctly
+ * handle files with that link type regardless of the value of
+ * DLT_C_HDLC.
+ *
+ * The name DLT_C_HDLC was used by BSD/OS; we use that name for source
+ * compatibility with programs written for BSD/OS.
+ *
+ * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
+ * for source compatibility with programs written for libpcap 0.5.
+ */
+#define DLT_C_HDLC 104 /* Cisco HDLC */
+#define DLT_CHDLC DLT_C_HDLC
+
+/*
+ * Reserved for future use.
+ * Do not pick other numerical value for these unless you have also
+ * picked up the tcpdump.org top-of-CVS-tree version of "savefile.c",
+ * which will arrange that capture files for these DLT_ types have
+ * the same "network" value on all platforms, regardless of what
+ * value is chosen for their DLT_ type (thus allowing captures made
+ * on one platform to be read on other platforms, even if the two
+ * platforms don't use the same numerical values for all DLT_ types).
+ */
+#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
+
+/*
+ * Values between 106 and 107 are used in capture file headers as
+ * link-layer types corresponding to DLT_ types that might differ
+ * between platforms; don't use those values for new DLT_ new types.
+ */
+
+/*
+ * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
+ * that the AF_ type in the link-layer header is in network byte order.
+ *
+ * OpenBSD defines it as 12, but that collides with DLT_RAW, so we
+ * define it as 108 here. If OpenBSD picks up this file, it should
+ * define DLT_LOOP as 12 in its version, as per the comment above -
+ * and should not use 108 for any purpose.
+ */
+#define DLT_LOOP 108
+
+/*
+ * Values between 109 and 112 are used in capture file headers as
+ * link-layer types corresponding to DLT_ types that might differ
+ * between platforms; don't use those values for new DLT_ new types.
+ */
+
+/*
+ * This is for Linux cooked sockets.
+ */
+#define DLT_LINUX_SLL 113
+
+/*
+ * The instruction encodings.
+ */
+/* instruction classes */
+#define BPF_CLASS(code) ((code) & 0x07)
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code) ((code) & 0x18)
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+#define BPF_MODE(code) ((code) & 0xe0)
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+/* alu/jmp fields */
+#define BPF_OP(code) ((code) & 0xf0)
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+#define BPF_SRC(code) ((code) & 0x08)
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+/* ret - BPF_K and BPF_X also apply */
+#define BPF_RVAL(code) ((code) & 0x18)
+#define BPF_A 0x10
+
+/* misc */
+#define BPF_MISCOP(code) ((code) & 0xf8)
+#define BPF_TAX 0x00
+#define BPF_TXA 0x80
+
+/*
+ * The instruction data structure.
+ */
+struct bpf_insn {
+ u_short code;
+ u_char jt;
+ u_char jf;
+ bpf_int32 k;
+};
+
+/*
+ * Macros for insn array initializers.
+ */
+#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
+#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
+
+#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL))
+/*
+ * Systems based on non-BSD kernels don't have ifnet's (or they don't mean
+ * anything if it is in <net/if.h>) and won't work like this.
+ */
+# if __STDC__
+extern void bpf_tap(struct ifnet *, u_char *, u_int);
+extern void bpf_mtap(struct ifnet *, struct mbuf *);
+extern void bpfattach(struct ifnet *, u_int, u_int);
+extern void bpfilterattach(int);
+# else
+extern void bpf_tap();
+extern void bpf_mtap();
+extern void bpfattach();
+extern void bpfilterattach();
+# endif /* __STDC__ */
+#endif /* BSD && (_KERNEL || KERNEL) */
+#if __STDC__
+extern int bpf_validate(struct bpf_insn *, int);
+extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
+#else
+extern int bpf_validate();
+extern u_int bpf_filter();
+#endif
+
+/*
+ * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
+ */
+#define BPF_MEMWORDS 16
+
+#endif