Click and the OSKit

Leigh Stoller stoller at fast.cs.utah.edu
Thu Dec 16 13:15:51 EST 1999


Hi Folks. Jay asked me to send along the Oskit diffs to Click. They are
appended below. Most of the changes are contained within two new subdirs;
click/oskit and click/elements/oskit. There are a few minor OSKit ifdefs
scattered around, and some not so minor ifdefs in the packet and timer
code, since that stuff needs to interact with the OSKit primitives more
closely than anything else. There are some changes to configure too.
Oh, you can probably ignore the changes to icmpping.cc ...

Comments and suggestions are welcome of course. Yesterday I had the IP
router configuration running quite nicely on a test network, and was able
to flood it with ping packets and UDP packets.

Please let me know what you prefer wrt keeping the OSKit version in sync.
Its easy for me to track the Click changes at the moment since its not
changing that much.

Thanks!
Lbs

---------------------------------------------------------------------------
Leigh B. Stoller                     Computer Science - Flux Research Group
stoller at cs.utah.edu                  University of Utah
http://www.cs.utah.edu/~stoller      Salt Lake City, Utah 84112
Voice: (541) 758-6252                FAX: (801) 585-3743
---------------------------------------------------------------------------


diff -Nr -c click-0.6/Makefile.in click/Makefile.in
*** click-0.6/Makefile.in	Fri Dec 10 09:10:44 1999
--- click/Makefile.in	Thu Dec 16 11:01:58 1999
***************
*** 31,36 ****
--- 31,38 ----
  	@cd exopc && $(MAKE) all
  tools: Makefile
  	@cd tools && $(MAKE) all
+ oskit: Makefile
+ 	@cd oskit && $(MAKE) all
  
  install:
  	@-for d in @TARGETS@ tools doc; do (cd $$d && $(MAKE) install); done
***************
*** 160,163 ****
  
  .PHONY: all elemlist elemlists elemlist-simple \
  	linuxmodule userlevel exopc tools clean distclean dist distdir \
! 	install install-man
--- 162,165 ----
  
  .PHONY: all elemlist elemlists elemlist-simple \
  	linuxmodule userlevel exopc tools clean distclean dist distdir \
! 	install install-man oskit
diff -Nr -c click-0.6/README.OSKIT click/README.OSKIT
*** click-0.6/README.OSKIT	Wed Dec 31 16:00:00 1969
--- click/README.OSKIT	Sat Dec 11 20:39:11 1999
***************
*** 0 ****
--- 1,121 ----
+ This README file describes the installation and use of the OSKit
+ version of Click. This will allow you to run Click router graphs on
+ "bare metal" (x86 and StrongARM) using the OSKit component libraries.
+ 
+ The OSKit home page can be found at:
+ 
+ 	http://www.cs.utah.edu/flux/oskit/
+ 
+ The Click home page and the SOSP'99 paper describing Click can be found at:
+ 
+ 	http://www.pdos.lcs.mit.edu/click/
+ 
+ 
+ *** What was added to Click:
+ 
+ There are two new directories.
+ 
+ 1) elements/oskit - contains some simple Click elements that implement
+    the interface to the OSKit networking support. That interface is
+    based on the OSKit's "netio" object, which is the basic mechanism
+    for passing packets between components in the OSKit. The
+    "FromNetIO" Click element is the interface used to receive packets
+    from an interface, and the "ToNetIO" Click element is used to send
+    packets to an interface. The argument is an integer, which roughly
+    corresponds to the interface card in the order in which it was
+    found, much the same as FromDevice(eth0). So, to receive packets
+    from the interface card 0, you would use FromNetIO(0). To send
+    packets to interface card 1, you would use ToNetIO(1).
+ 
+ 2) oskit - contains the additional support necessary to build an OSKit
+    kernel, linking the Click code against the OSKit libraries. Also
+    included are 2 simple demonstration programs that illustrate how to
+    combine the OSKit with Click via the "oskit_clicker" COM object
+    interface. The Makefile contains the necessary modifications to
+    build OSKit/Click kernels using the OSKit compiler front end (see
+    below).
+ 
+ 
+ *** What you need:
+ 
+ 1) You need to download and install a recent version of the OSKit from
+    the OSKit webpage: http://www.cs.utah.edu/flux/oskit/, where "recent"
+    means snapshot 19991124 ``Butterball'' or later.  See the web page for
+    instructions on this process.
+ 
+ 2) GCC version 2.95 or better
+ 
+ 
+ *** How to configure:
+ 
+ The configuration process is a little arcane at the moment. The next
+ release will hopefully improve upon this, but for the moment you must
+ go through these hoops. First off, you need to setup a few environment
+ variables. The first two refer to the results of your OSKit build and
+ installation, and tell configure where to find the OSKit tools and
+ libraries. The CXX variable is needed if you do not have gcc (g++)
+ 2.95 installed as your default compiler.
+ 
+ 	setenv OSKIT_CC  /build/oskit/install/bin/i386-oskit-gcc
+ 	setenv OSKIT_DIR /build/oskit/install
+ 	setenv CXX       /build/tools/bin/g++
+ 
+ Configure Click with the following command:
+ 
+ 	cd /build/click
+ 	/src/click/configure --enable-oskit --disable-radio
+ 
+ where "/build/click" is any directory of your choice.
+ 
+ 
+ *** How to build:
+ 
+ 	cd /build/click/oskit
+ 	make
+ 
+ This will leave you with click.a, which you can use to build more
+ OSKit kernels. You will also have a simple demonstration kernel called
+ "example1," which inputs a router configuration file named ping.click,
+ and functions as a trivial ping packet bouncer.  The intent is simply
+ to demonstrate how you would use Click in an OSKit kernel.
+ 
+ 
+ *** How to run:
+ 
+ The example1 kernel is a multiboot image that can be booted with a
+ multiboot compliant boot program such as netboot or grub. Since you
+ also need to provide a text file containing the router graph, the
+ makefile also creates an example1.image, which is also a multiboot
+ image that includes the appropriate kernel, as well as the ping.click
+ router graph. This kernel can be booted directly with a multiboot
+ compliant loader.
+ 
+ Once you boot it, it will sit around for 30 seconds responding to ping
+ packets, and then reboot. You can edit the ping.click file to make it
+ more verbose, or to change the NetIO interfaces it uses.
+ 
+ --------------------------------------------------------------------------
+ 
+ Contact information for OSKit-related issues:
+ 
+ Send comments, suggestions, bugs, and fixes to oskit-users at cs.utah.edu.
+ 
+ For messages just to the Utah developers send to oskit at flux.cs.utah.edu.
+ 
+ To be added to appropriate mailing lists, send mail to:
+   oskit-users-request at cs.utah.edu		(oskit users/hackers)
+   oskit-announce-request at cs.utah.edu		(major announcements only)
+ You do not have to be on both lists at once; mail to the announce list
+ also goes to the users list (but not vice versa, of course.)
+ 
+ Archives of the mailing lists are available in
+   ftp://flux.cs.utah.edu/flux/oskit/mail/html/index.html	(HTML)
+   ftp://flux.cs.utah.edu/flux/oskit/mail/index.html		(mbox)
+ 
+ 
+ Have fun!
+ 
+ The Flux Research Group
+ Department of Computer Science
+ University of Utah
+ http://www.cs.utah.edu/flux/
diff -Nr -c click-0.6/configure click/configure
*** click-0.6/configure	Wed Dec  8 12:07:36 1999
--- click/configure	Mon Dec 13 16:16:49 1999
***************
*** 23,28 ****
--- 23,30 ----
    --enable-ipsec          include IP security elements (no)"
  ac_help="$ac_help
    --enable-radio          include radio elements (yes)"
+ ac_help="$ac_help
+   --enable-oskit       Build for OSKit kernel"
  
  # Initialize some variables set by options.
  # The variables have the same names as the options, with
***************
*** 551,557 ****
  # Extract the first word of "gcc", so it can be a program name with args.
  set dummy gcc; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:555: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 553,559 ----
  # Extract the first word of "gcc", so it can be a program name with args.
  set dummy gcc; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:557: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 581,587 ****
    # Extract the first word of "cc", so it can be a program name with args.
  set dummy cc; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:585: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 583,589 ----
    # Extract the first word of "cc", so it can be a program name with args.
  set dummy cc; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:587: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 632,638 ****
        # Extract the first word of "cl", so it can be a program name with args.
  set dummy cl; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:636: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 634,640 ----
        # Extract the first word of "cl", so it can be a program name with args.
  set dummy cl; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:638: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 664,670 ****
  fi
  
  echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
! echo "configure:668: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
  
  ac_ext=c
  # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
--- 666,672 ----
  fi
  
  echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
! echo "configure:670: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
  
  ac_ext=c
  # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
***************
*** 675,686 ****
  
  cat > conftest.$ac_ext << EOF
  
! #line 679 "configure"
  #include "confdefs.h"
  
  main(){return(0);}
  EOF
! if { (eval echo configure:684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    ac_cv_prog_cc_works=yes
    # If we can't run a trivial program, we are probably using a cross compiler.
    if (./conftest; exit) 2>/dev/null; then
--- 677,688 ----
  
  cat > conftest.$ac_ext << EOF
  
! #line 681 "configure"
  #include "confdefs.h"
  
  main(){return(0);}
  EOF
! if { (eval echo configure:686: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    ac_cv_prog_cc_works=yes
    # If we can't run a trivial program, we are probably using a cross compiler.
    if (./conftest; exit) 2>/dev/null; then
***************
*** 706,717 ****
    { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
  fi
  echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
! echo "configure:710: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
  echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
  cross_compiling=$ac_cv_prog_cc_cross
  
  echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
! echo "configure:715: checking whether we are using GNU C" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 708,719 ----
    { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
  fi
  echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
! echo "configure:712: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
  echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
  cross_compiling=$ac_cv_prog_cc_cross
  
  echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
! echo "configure:717: checking whether we are using GNU C" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 720,726 ****
    yes;
  #endif
  EOF
! if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:724: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
    ac_cv_prog_gcc=yes
  else
    ac_cv_prog_gcc=no
--- 722,728 ----
    yes;
  #endif
  EOF
! if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:726: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
    ac_cv_prog_gcc=yes
  else
    ac_cv_prog_gcc=no
***************
*** 739,745 ****
  ac_save_CFLAGS="$CFLAGS"
  CFLAGS=
  echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
! echo "configure:743: checking whether ${CC-cc} accepts -g" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 741,747 ----
  ac_save_CFLAGS="$CFLAGS"
  CFLAGS=
  echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
! echo "configure:745: checking whether ${CC-cc} accepts -g" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 771,777 ****
  fi
  
  echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
! echo "configure:775: checking how to run the C preprocessor" >&5
  # On Suns, sometimes $CPP names a directory.
  if test -n "$CPP" && test -d "$CPP"; then
    CPP=
--- 773,779 ----
  fi
  
  echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
! echo "configure:777: checking how to run the C preprocessor" >&5
  # On Suns, sometimes $CPP names a directory.
  if test -n "$CPP" && test -d "$CPP"; then
    CPP=
***************
*** 786,798 ****
    # On the NeXT, cc -E runs the code through the compiler's parser,
    # not just through cpp.
    cat > conftest.$ac_ext <<EOF
! #line 790 "configure"
  #include "confdefs.h"
  #include <assert.h>
  Syntax Error
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:796: \"$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
    :
--- 788,800 ----
    # On the NeXT, cc -E runs the code through the compiler's parser,
    # not just through cpp.
    cat > conftest.$ac_ext <<EOF
! #line 792 "configure"
  #include "confdefs.h"
  #include <assert.h>
  Syntax Error
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:798: \"$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
    :
***************
*** 803,815 ****
    rm -rf conftest*
    CPP="${CC-cc} -E -traditional-cpp"
    cat > conftest.$ac_ext <<EOF
! #line 807 "configure"
  #include "confdefs.h"
  #include <assert.h>
  Syntax Error
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:813: \"$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
    :
--- 805,817 ----
    rm -rf conftest*
    CPP="${CC-cc} -E -traditional-cpp"
    cat > conftest.$ac_ext <<EOF
! #line 809 "configure"
  #include "confdefs.h"
  #include <assert.h>
  Syntax Error
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:815: \"$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
    :
***************
*** 820,832 ****
    rm -rf conftest*
    CPP="${CC-cc} -nologo -E"
    cat > conftest.$ac_ext <<EOF
! #line 824 "configure"
  #include "confdefs.h"
  #include <assert.h>
  Syntax Error
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:830: \"$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
    :
--- 822,834 ----
    rm -rf conftest*
    CPP="${CC-cc} -nologo -E"
    cat > conftest.$ac_ext <<EOF
! #line 826 "configure"
  #include "confdefs.h"
  #include <assert.h>
  Syntax Error
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:832: \"$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
    :
***************
*** 854,860 ****
  # Extract the first word of "ranlib", so it can be a program name with args.
  set dummy ranlib; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:858: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 856,862 ----
  # Extract the first word of "ranlib", so it can be a program name with args.
  set dummy ranlib; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:860: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 912,918 ****
  # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
  # ./install, which can be erroneously created by make from ./install.sh.
  echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
! echo "configure:916: checking for a BSD compatible install" >&5
  if test -z "$INSTALL"; then
  if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
--- 914,920 ----
  # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
  # ./install, which can be erroneously created by make from ./install.sh.
  echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
! echo "configure:918: checking for a BSD compatible install" >&5
  if test -z "$INSTALL"; then
  if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
***************
*** 971,977 ****
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:975: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 973,979 ----
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:977: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1003,1009 ****
  
  
  echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
! echo "configure:1007: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
  
  ac_ext=C
  # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
--- 1005,1011 ----
  
  
  echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
! echo "configure:1009: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
  
  ac_ext=C
  # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
***************
*** 1014,1025 ****
  
  cat > conftest.$ac_ext << EOF
  
! #line 1018 "configure"
  #include "confdefs.h"
  
  int main(){return(0);}
  EOF
! if { (eval echo configure:1023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    ac_cv_prog_cxx_works=yes
    # If we can't run a trivial program, we are probably using a cross compiler.
    if (./conftest; exit) 2>/dev/null; then
--- 1016,1027 ----
  
  cat > conftest.$ac_ext << EOF
  
! #line 1020 "configure"
  #include "confdefs.h"
  
  int main(){return(0);}
  EOF
! if { (eval echo configure:1025: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    ac_cv_prog_cxx_works=yes
    # If we can't run a trivial program, we are probably using a cross compiler.
    if (./conftest; exit) 2>/dev/null; then
***************
*** 1045,1056 ****
    { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
  fi
  echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
! echo "configure:1049: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
  echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
  cross_compiling=$ac_cv_prog_cxx_cross
  
  echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
! echo "configure:1054: checking whether we are using GNU C++" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1047,1058 ----
    { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
  fi
  echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
! echo "configure:1051: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
  echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
  cross_compiling=$ac_cv_prog_cxx_cross
  
  echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
! echo "configure:1056: checking whether we are using GNU C++" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1059,1065 ****
    yes;
  #endif
  EOF
! if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1063: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
    ac_cv_prog_gxx=yes
  else
    ac_cv_prog_gxx=no
--- 1061,1067 ----
    yes;
  #endif
  EOF
! if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1065: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
    ac_cv_prog_gxx=yes
  else
    ac_cv_prog_gxx=no
***************
*** 1078,1084 ****
  ac_save_CXXFLAGS="$CXXFLAGS"
  CXXFLAGS=
  echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
! echo "configure:1082: checking whether ${CXX-g++} accepts -g" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1080,1086 ----
  ac_save_CXXFLAGS="$CXXFLAGS"
  CXXFLAGS=
  echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
! echo "configure:1084: checking whether ${CXX-g++} accepts -g" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1110,1116 ****
  fi
  
  echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
! echo "configure:1114: checking how to run the C++ preprocessor" >&5
  if test -z "$CXXCPP"; then
  if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
--- 1112,1118 ----
  fi
  
  echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
! echo "configure:1116: checking how to run the C++ preprocessor" >&5
  if test -z "$CXXCPP"; then
  if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
***************
*** 1123,1134 ****
  cross_compiling=$ac_cv_prog_cxx_cross
    CXXCPP="${CXX-g++} -E"
    cat > conftest.$ac_ext <<EOF
! #line 1127 "configure"
  #include "confdefs.h"
  #include <stdlib.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1132: \"$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
    :
--- 1125,1136 ----
  cross_compiling=$ac_cv_prog_cxx_cross
    CXXCPP="${CXX-g++} -E"
    cat > conftest.$ac_ext <<EOF
! #line 1129 "configure"
  #include "confdefs.h"
  #include <stdlib.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1134: \"$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
    :
***************
*** 1169,1180 ****
  cross_compiling=$ac_cv_prog_cxx_cross
  
  echo $ac_n "checking for recent version of C++""... $ac_c" 1>&6
! echo "configure:1173: checking for recent version of C++" >&5
  if eval "test \"`echo '$''{'ac_cv_good_cxx'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1178 "configure"
  #include "confdefs.h"
  
  int main() {
--- 1171,1182 ----
  cross_compiling=$ac_cv_prog_cxx_cross
  
  echo $ac_n "checking for recent version of C++""... $ac_c" 1>&6
! echo "configure:1175: checking for recent version of C++" >&5
  if eval "test \"`echo '$''{'ac_cv_good_cxx'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1180 "configure"
  #include "confdefs.h"
  
  int main() {
***************
*** 1186,1192 ****
  return 0;
  ; return 0; }
  EOF
! if { (eval echo configure:1190: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
    rm -rf conftest*
    ac_cv_good_cxx=yes
  else
--- 1188,1194 ----
  return 0;
  ; return 0; }
  EOF
! if { (eval echo configure:1192: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
    rm -rf conftest*
    ac_cv_good_cxx=yes
  else
***************
*** 1207,1213 ****
  
  
  echo $ac_n "checking for working new.h""... $ac_c" 1>&6
! echo "configure:1211: checking for working new.h" >&5
  if eval "test \"`echo '$''{'ac_cv_good_new_h'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1209,1215 ----
  
  
  echo $ac_n "checking for working new.h""... $ac_c" 1>&6
! echo "configure:1213: checking for working new.h" >&5
  if eval "test \"`echo '$''{'ac_cv_good_new_h'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1215,1221 ****
    ac_cv_good_new_h=no
  else
    cat > conftest.$ac_ext <<EOF
! #line 1219 "configure"
  #include "confdefs.h"
  #ifdef __cplusplus
  extern "C" void exit(int);
--- 1217,1223 ----
    ac_cv_good_new_h=no
  else
    cat > conftest.$ac_ext <<EOF
! #line 1221 "configure"
  #include "confdefs.h"
  #ifdef __cplusplus
  extern "C" void exit(int);
***************
*** 1227,1233 ****
    return 0;
  }
  EOF
! if { (eval echo configure:1231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
  then
    ac_cv_good_new_h=yes
  else
--- 1229,1235 ----
    return 0;
  }
  EOF
! if { (eval echo configure:1233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
  then
    ac_cv_good_new_h=yes
  else
***************
*** 1265,1271 ****
  missing_dir=`cd $srcdir && pwd`
  
  echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
! echo "configure:1269: checking for working autoheader" >&5
  if (autoheader --version) < /dev/null > /dev/null 2>&1; then
    AUTOHEADER=autoheader
    echo "$ac_t""found" 1>&6
--- 1267,1273 ----
  missing_dir=`cd $srcdir && pwd`
  
  echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
! echo "configure:1271: checking for working autoheader" >&5
  if (autoheader --version) < /dev/null > /dev/null 2>&1; then
    AUTOHEADER=autoheader
    echo "$ac_t""found" 1>&6
***************
*** 1275,1281 ****
  fi
  
  echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
! echo "configure:1279: checking for working autoconf" >&5
  if (autoconf --version) < /dev/null > conftest.out 2>&1; then
    if test `head -1 conftest.out | sed 's/.*2\.\([0-9]*\).*/\1/'` -ge 13 2>/dev/null; then
      AUTOCONF=autoconf
--- 1277,1283 ----
  fi
  
  echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
! echo "configure:1281: checking for working autoconf" >&5
  if (autoconf --version) < /dev/null > conftest.out 2>&1; then
    if test `head -1 conftest.out | sed 's/.*2\.\([0-9]*\).*/\1/'` -ge 13 2>/dev/null; then
      AUTOCONF=autoconf
***************
*** 1358,1363 ****
--- 1360,1381 ----
    element_groups="$element_groups radio"
  fi
  
+ oskit_enable="no"
+ # Check whether --enable-oskit or --disable-oskit was given.
+ if test "${enable_oskit+set}" = set; then
+   enableval="$enable_oskit"
+   if test "$enableval" = "yes"; then
+ 	oskit_enable="yes"
+ fi
+ fi
+ 
+ 
+ if test "x$enable_radio" = xyes; then
+ 	if test $oskit_enable = yes; then
+ 		{ echo "configure: error: Cannot build Radio elements with Oskit yet." 1>&2; exit 1; }
+ 	fi
+ fi
+ 
  elements_vpath=`echo "$element_groups" | sed -e 's/ \([^ ][^ ]*\)/:$(top_srcdir)\/elements\/\1/g'`
  
  
***************
*** 1371,1382 ****
  for ac_func in strerror
  do
  echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
! echo "configure:1375: checking for $ac_func" >&5
  if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1380 "configure"
  #include "confdefs.h"
  /* System header to define __stub macros and hopefully few prototypes,
      which can conflict with char $ac_func(); below.  */
--- 1389,1400 ----
  for ac_func in strerror
  do
  echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
! echo "configure:1393: checking for $ac_func" >&5
  if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1398 "configure"
  #include "confdefs.h"
  /* System header to define __stub macros and hopefully few prototypes,
      which can conflict with char $ac_func(); below.  */
***************
*** 1402,1408 ****
  
  ; return 0; }
  EOF
! if { (eval echo configure:1406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    eval "ac_cv_func_$ac_func=yes"
  else
--- 1420,1426 ----
  
  ; return 0; }
  EOF
! if { (eval echo configure:1424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    eval "ac_cv_func_$ac_func=yes"
  else
***************
*** 1434,1450 ****
  do
  ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
  echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
! echo "configure:1438: checking for $ac_hdr" >&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 1443 "configure"
  #include "confdefs.h"
  #include <$ac_hdr>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1448: \"$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*
--- 1452,1468 ----
  do
  ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
  echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
! echo "configure:1456: checking for $ac_hdr" >&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 1461 "configure"
  #include "confdefs.h"
  #include <$ac_hdr>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1466: \"$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*
***************
*** 1472,1483 ****
  
  DL_LIBRARY=
  echo $ac_n "checking for dlopen""... $ac_c" 1>&6
! echo "configure:1476: checking for dlopen" >&5
  if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1481 "configure"
  #include "confdefs.h"
  /* System header to define __stub macros and hopefully few prototypes,
      which can conflict with char dlopen(); below.  */
--- 1490,1501 ----
  
  DL_LIBRARY=
  echo $ac_n "checking for dlopen""... $ac_c" 1>&6
! echo "configure:1494: checking for dlopen" >&5
  if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1499 "configure"
  #include "confdefs.h"
  /* System header to define __stub macros and hopefully few prototypes,
      which can conflict with char dlopen(); below.  */
***************
*** 1503,1509 ****
  
  ; return 0; }
  EOF
! if { (eval echo configure:1507: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    eval "ac_cv_func_dlopen=yes"
  else
--- 1521,1527 ----
  
  ; return 0; }
  EOF
! if { (eval echo configure:1525: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    eval "ac_cv_func_dlopen=yes"
  else
***************
*** 1524,1530 ****
  else
    echo "$ac_t""no" 1>&6
  echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
! echo "configure:1528: checking for dlopen in -ldl" >&5
  ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
  if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
--- 1542,1548 ----
  else
    echo "$ac_t""no" 1>&6
  echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
! echo "configure:1546: checking for dlopen in -ldl" >&5
  ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
  if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
***************
*** 1532,1538 ****
    ac_save_LIBS="$LIBS"
  LIBS="-ldl  $LIBS"
  cat > conftest.$ac_ext <<EOF
! #line 1536 "configure"
  #include "confdefs.h"
  /* Override any gcc2 internal prototype to avoid an error.  */
  #ifdef __cplusplus
--- 1550,1556 ----
    ac_save_LIBS="$LIBS"
  LIBS="-ldl  $LIBS"
  cat > conftest.$ac_ext <<EOF
! #line 1554 "configure"
  #include "confdefs.h"
  /* Override any gcc2 internal prototype to avoid an error.  */
  #ifdef __cplusplus
***************
*** 1546,1552 ****
  dlopen()
  ; return 0; }
  EOF
! if { (eval echo configure:1550: \"$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
--- 1564,1570 ----
  dlopen()
  ; return 0; }
  EOF
! if { (eval echo configure:1568: \"$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
***************
*** 1576,1582 ****
  
  
  echo $ac_n "checking for Click Linux kernel extensions""... $ac_c" 1>&6
! echo "configure:1580: checking for Click Linux kernel extensions" >&5
  if eval "test \"`echo '$''{'ac_cv_click_kernel'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1594,1600 ----
  
  
  echo $ac_n "checking for Click Linux kernel extensions""... $ac_c" 1>&6
! echo "configure:1598: checking for Click Linux kernel extensions" >&5
  if eval "test \"`echo '$''{'ac_cv_click_kernel'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1594,1600 ****
  fi
  
  echo $ac_n "checking for read_net_skbcount kernel extension""... $ac_c" 1>&6
! echo "configure:1598: checking for read_net_skbcount kernel extension" >&5
  if eval "test \"`echo '$''{'ac_cv_read_net_skbcount'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1612,1618 ----
  fi
  
  echo $ac_n "checking for read_net_skbcount kernel extension""... $ac_c" 1>&6
! echo "configure:1616: checking for read_net_skbcount kernel extension" >&5
  if eval "test \"`echo '$''{'ac_cv_read_net_skbcount'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1614,1620 ****
  
  if test ${GMAKE-NO} = NO; then
    echo $ac_n "checking for GNU make""... $ac_c" 1>&6
! echo "configure:1618: checking for GNU make" >&5
  if eval "test \"`echo '$''{'ac_cv_gnu_make'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1632,1638 ----
  
  if test ${GMAKE-NO} = NO; then
    echo $ac_n "checking for GNU make""... $ac_c" 1>&6
! echo "configure:1636: checking for GNU make" >&5
  if eval "test \"`echo '$''{'ac_cv_gnu_make'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1647,1652 ****
--- 1665,1674 ----
    POSSIBLE_TARGETS="$POSSIBLE_TARGETS exopc"
  fi
  
+ if test $oskit_enable = yes; then
+   POSSIBLE_TARGETS="$POSSIBLE_TARGETS oskit"
+ fi
+ 
  
  TARGETS=
  
***************
*** 1654,1675 ****
  
  
  
  if test "${PCAP_HEADER_PATH-NO}" != NO; then
    ac_cv_pcap_header_path="$PCAP_HEADER_PATH"
  else
    saveflags="$CPPFLAGS"
    echo $ac_n "checking for pcap.h""... $ac_c" 1>&6
! echo "configure:1663: checking for pcap.h" >&5
  if eval "test \"`echo '$''{'ac_cv_pcap_header_path'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1668 "configure"
  #include "confdefs.h"
  #include <pcap.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1673: \"$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*
--- 1676,1734 ----
  
  
  
+ 
+ 
+ if test $oskit_enable = yes; then
+   echo $ac_n "checking for OSKit compiler front end""... $ac_c" 1>&6
+ echo "configure:1684: checking for OSKit compiler front end" >&5
+ if eval "test \"`echo '$''{'ac_cv_oskit_dir'+set}'`\" = set"; then
+   echo $ac_n "(cached) $ac_c" 1>&6
+ else
+   if test "x${OSKIT_DIR}" != x; then
+ 	ac_cv_oskit_dir="${OSKIT_DIR}"
+ else
+ 	{ echo "configure: error: Cannot find OSKit compiler front end. Setenv OSKIT_DIR" 1>&2; exit 1; }
+ fi
+ fi
+ 
+ echo "$ac_t""$ac_cv_oskit_dir" 1>&6
+ test "x${OSKIT_DIR}" != x || OSKIT_DIR="${ac_cv_oskit_dir}"
+ 
+   echo $ac_n "checking for OSKit compiler front end""... $ac_c" 1>&6
+ echo "configure:1699: checking for OSKit compiler front end" >&5
+ if eval "test \"`echo '$''{'ac_cv_oskit_cc'+set}'`\" = set"; then
+   echo $ac_n "(cached) $ac_c" 1>&6
+ else
+   if test "x${OSKIT_CC}" != x; then
+ 	ac_cv_oskit_cc="${OSKIT_CC}"
+ else
+ 	{ echo "configure: error: Cannot find OSKit compiler front end. Setenv OSKIT_CC" 1>&2; exit 1; }
+ fi
+ fi
+ 
+ echo "$ac_t""$ac_cv_oskit_cc" 1>&6
+ test "x${OSKIT_CC}" != x || OSKIT_CC="${ac_cv_oskit_cc}"
+ 
+ TARGETS="$TARGETS oskit"
+ fi
+ 
+ 
  if test "${PCAP_HEADER_PATH-NO}" != NO; then
    ac_cv_pcap_header_path="$PCAP_HEADER_PATH"
  else
    saveflags="$CPPFLAGS"
    echo $ac_n "checking for pcap.h""... $ac_c" 1>&6
! echo "configure:1722: checking for pcap.h" >&5
  if eval "test \"`echo '$''{'ac_cv_pcap_header_path'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    cat > conftest.$ac_ext <<EOF
! #line 1727 "configure"
  #include "confdefs.h"
  #include <pcap.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1732: \"$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*
***************
*** 1681,1692 ****
    rm -rf conftest*
    CPPFLAGS="$saveflags -I/usr/include/pcap"
       cat > conftest.$ac_ext <<EOF
! #line 1685 "configure"
  #include "confdefs.h"
  #include <pcap.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1690: \"$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*
--- 1740,1751 ----
    rm -rf conftest*
    CPPFLAGS="$saveflags -I/usr/include/pcap"
       cat > conftest.$ac_ext <<EOF
! #line 1744 "configure"
  #include "confdefs.h"
  #include <pcap.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1749: \"$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*
***************
*** 1698,1709 ****
    rm -rf conftest*
    CPPFLAGS="$saveflags -I/usr/local/include/pcap"
        cat > conftest.$ac_ext <<EOF
! #line 1702 "configure"
  #include "confdefs.h"
  #include <pcap.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1707: \"$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*
--- 1757,1768 ----
    rm -rf conftest*
    CPPFLAGS="$saveflags -I/usr/local/include/pcap"
        cat > conftest.$ac_ext <<EOF
! #line 1761 "configure"
  #include "confdefs.h"
  #include <pcap.h>
  EOF
  ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
! { (eval echo configure:1766: \"$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*
***************
*** 1739,1745 ****
    savelibs="$LIBS"
    LIBS="$savelibs -lpcap"
    echo $ac_n "checking for -lpcap""... $ac_c" 1>&6
! echo "configure:1743: checking for -lpcap" >&5
  if eval "test \"`echo '$''{'ac_cv_pcap_library_path'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1798,1804 ----
    savelibs="$LIBS"
    LIBS="$savelibs -lpcap"
    echo $ac_n "checking for -lpcap""... $ac_c" 1>&6
! echo "configure:1802: checking for -lpcap" >&5
  if eval "test \"`echo '$''{'ac_cv_pcap_library_path'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1751,1757 ****
  cross_compiling=$ac_cv_prog_cc_cross
  
      cat > conftest.$ac_ext <<EOF
! #line 1755 "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
--- 1810,1816 ----
  cross_compiling=$ac_cv_prog_cc_cross
  
      cat > conftest.$ac_ext <<EOF
! #line 1814 "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
***************
*** 1762,1768 ****
  pcap_open_live()
  ; return 0; }
  EOF
! if { (eval echo configure:1766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    ac_cv_pcap_library_path="found"
  else
--- 1821,1827 ----
  pcap_open_live()
  ; return 0; }
  EOF
! if { (eval echo configure:1825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    ac_cv_pcap_library_path="found"
  else
***************
*** 1771,1777 ****
    rm -rf conftest*
    LDFLAGS="$saveflags -L/usr/local/lib"
       cat > conftest.$ac_ext <<EOF
! #line 1775 "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
--- 1830,1836 ----
    rm -rf conftest*
    LDFLAGS="$saveflags -L/usr/local/lib"
       cat > conftest.$ac_ext <<EOF
! #line 1834 "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
***************
*** 1782,1788 ****
  pcap_open_live()
  ; return 0; }
  EOF
! if { (eval echo configure:1786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    ac_cv_pcap_library_path="-L/usr/local/lib"
  else
--- 1841,1847 ----
  pcap_open_live()
  ; return 0; }
  EOF
! if { (eval echo configure:1845: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
    rm -rf conftest*
    ac_cv_pcap_library_path="-L/usr/local/lib"
  else
***************
*** 1825,1831 ****
  
  if test `uname` = Linux; then
    echo $ac_n "checking for C++-includable system header files""... $ac_c" 1>&6
! echo "configure:1829: checking for C++-includable system header files" >&5
  if eval "test \"`echo '$''{'ac_cv_cxx_aware_system'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1884,1890 ----
  
  if test `uname` = Linux; then
    echo $ac_n "checking for C++-includable system header files""... $ac_c" 1>&6
! echo "configure:1888: checking for C++-includable system header files" >&5
  if eval "test \"`echo '$''{'ac_cv_cxx_aware_system'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1840,1846 ****
    ac_cv_cxx_aware_system=no
  else
    cat > conftest.$ac_ext <<EOF
! #line 1844 "configure"
  #include "confdefs.h"
  #ifdef __cplusplus
  extern "C" void exit(int);
--- 1899,1905 ----
    ac_cv_cxx_aware_system=no
  else
    cat > conftest.$ac_ext <<EOF
! #line 1903 "configure"
  #include "confdefs.h"
  #ifdef __cplusplus
  extern "C" void exit(int);
***************
*** 1850,1856 ****
    return 0;
  }
  EOF
! if { (eval echo configure:1854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
  then
    ac_cv_cxx_aware_system=yes
  else
--- 1909,1915 ----
    return 0;
  }
  EOF
! if { (eval echo configure:1913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
  then
    ac_cv_cxx_aware_system=yes
  else
***************
*** 1882,1888 ****
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:1886: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_ac_cv_perl5'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1941,1947 ----
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:1945: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_ac_cv_perl5'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 1918,1924 ****
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:1922: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_ac_cv_perl5_local'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
--- 1977,1983 ----
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
! echo "configure:1981: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_ac_cv_perl5_local'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 2125,2130 ****
--- 2184,2191 ----
  s%@POSSIBLE_TARGETS@%$POSSIBLE_TARGETS%g
  s%@TARGETS@%$TARGETS%g
  s%@TOOL_TARGETS@%$TOOL_TARGETS%g
+ s%@OSKIT_DIR@%$OSKIT_DIR%g
+ s%@OSKIT_CC@%$OSKIT_CC%g
  s%@PCAP_HEADER_PATH@%$PCAP_HEADER_PATH%g
  s%@PCAP_LIBRARY_PATH@%$PCAP_LIBRARY_PATH%g
  s%@PCAP_LIBRARY@%$PCAP_LIBRARY%g
diff -Nr -c click-0.6/configure.in click/configure.in
*** click-0.6/configure.in	Wed Dec  8 12:06:07 1999
--- click/configure.in	Mon Dec 13 16:16:49 1999
***************
*** 123,128 ****
--- 123,147 ----
  ELEMENTS_ARG_ENABLE(ipsec, [include IP security elements (no)], no)
  ELEMENTS_ARG_ENABLE(radio, [include radio elements (yes)], yes)
  
+ dnl
+ dnl Check for OSKit build.
+ dnl
+ oskit_enable="no"
+ AC_ARG_ENABLE(oskit,
+ [  --enable-oskit       Build for OSKit kernel],
+ [if test "$enableval" = "yes"; then
+ 	oskit_enable="yes"
+ fi])
+ 
+ dnl
+ dnl When Oskit build enabled, radio elements not allowed.
+ dnl
+ if test "x$enable_radio" = xyes; then
+ 	if test $oskit_enable = yes; then
+ 		AC_MSG_ERROR([Cannot build Radio elements with Oskit yet.])
+ 	fi
+ fi
+ 
  elements_vpath=`echo "$element_groups" | sed -e ['s/ \([^ ][^ ]*\)/:$(top_srcdir)\/elements\/\1/g']`
  AC_SUBST(elements_vpath)
  
***************
*** 209,214 ****
--- 228,240 ----
  fi
  
  dnl
+ dnl Oskit Build requires an OSKIT compiler
+ dnl
+ if test $oskit_enable = yes; then
+   POSSIBLE_TARGETS="$POSSIBLE_TARGETS oskit"
+ fi
+ 
+ dnl
  dnl default targets
  dnl
  
***************
*** 216,221 ****
--- 242,273 ----
  AC_SUBST(TARGETS)
  TOOL_TARGETS="click-align click-compile click-fastclassifier click-xform"
  AC_SUBST(TOOL_TARGETS)
+ 
+ dnl
+ dnl Check for oskit compiler front end.
+ dnl
+ AC_SUBST(OSKIT_DIR)
+ AC_SUBST(OSKIT_CC)
+ 
+ if test $oskit_enable = yes; then
+   AC_CACHE_CHECK(for OSKit compiler front end, ac_cv_oskit_dir, [dnl
+ if test "x${OSKIT_DIR}" != x; then
+ 	ac_cv_oskit_dir="${OSKIT_DIR}"
+ else
+ 	AC_MSG_ERROR(Cannot find OSKit compiler front end. Setenv OSKIT_DIR)
+ fi])
+ test "x${OSKIT_DIR}" != x || OSKIT_DIR="${ac_cv_oskit_dir}"
+ 
+   AC_CACHE_CHECK(for OSKit compiler front end, ac_cv_oskit_cc, [dnl
+ if test "x${OSKIT_CC}" != x; then
+ 	ac_cv_oskit_cc="${OSKIT_CC}"
+ else
+ 	AC_MSG_ERROR(Cannot find OSKit compiler front end. Setenv OSKIT_CC)
+ fi])
+ test "x${OSKIT_CC}" != x || OSKIT_CC="${ac_cv_oskit_cc}"
+ 
+ TARGETS="$TARGETS oskit"
+ fi
  
  dnl check userlevel for pcap library
  
diff -Nr -c click-0.6/elements/ip/icmpping.cc click/elements/ip/icmpping.cc
*** click-0.6/elements/ip/icmpping.cc	Wed Nov 17 08:53:41 1999
--- click/elements/ip/icmpping.cc	Thu Nov 18 15:10:46 1999
***************
*** 40,45 ****
--- 40,47 ----
    struct ether_header *eth_header = (struct ether_header *) p->data();
    click_ip *ip_header = (click_ip *) (eth_header+1);
    struct icmp_echo *icmp = (struct icmp_echo *) (ip_header+1);
+   static int ipid = 0xb;
+   int hlen = ip_header->ip_hl << 2;
  
    /* him */
    u_char tha[6]; 
***************
*** 63,72 ****
    icmp->icmp_type = ICMP_ECHO_REPLY;
    
    /* calculate ICMP checksum */
!   icmp->icmp_cksum = in_cksum((unsigned char *)icmp, sizeof(struct icmp_echo));
  
!   int pktlen = sizeof(struct ether_header)+ntohs(ip_header->ip_len);
!   p->take(p->length()-pktlen);
  }
  
  
--- 65,80 ----
    icmp->icmp_type = ICMP_ECHO_REPLY;
    
    /* calculate ICMP checksum */
!   icmp->icmp_cksum = 0;
!   icmp->icmp_cksum = in_cksum((unsigned char *)icmp,
! 			      ntohs(ip_header->ip_len) - hlen);
  
!   ip_header->ip_id  = htons(ipid++);
!   ip_header->ip_sum = 0;
!   ip_header->ip_sum = in_cksum((unsigned char *)ip_header, hlen);
! 
! /*  int pktlen = sizeof(struct ether_header)+ntohs(ip_header->ip_len);
!     p->take(p->length()-pktlen); */
  }
  
  
diff -Nr -c click-0.6/elements/oskit/fromnetio.cc click/elements/oskit/fromnetio.cc
*** click-0.6/elements/oskit/fromnetio.cc	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/fromnetio.cc	Fri Dec 10 07:32:49 1999
***************
*** 0 ****
--- 1,91 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * netio.{cc,hh} -- Read packets from OSKit netio, and pass along.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+ #include "fromnetio.hh"
+ #include "error.hh"
+ #include "packet.hh"
+ #include "confparse.hh"
+ #include "glue.hh"
+ #include <unistd.h>
+ #include "netio_guts.h"
+ 
+ FromNetIO::FromNetIO()
+   : _ifnum(-1)
+ {
+ 	add_output();
+ }
+ 
+ FromNetIO::~FromNetIO()
+ {
+ 	if (_ifnum >= 0)
+ 		(void) oskit_destroy_fromnetio(_ifnum, _priv);
+ }
+ 
+ FromNetIO *
+ FromNetIO::clone() const
+ {
+ 	return new FromNetIO;
+ }
+ 
+ int
+ FromNetIO::configure(const String &conf, ErrorHandler *errh)
+ {
+ 	if (cp_va_parse(conf, this, errh,
+ 			cpInteger, "interface number", &_ifnum,
+ 			cpEnd) < 0)
+ 		return -1;
+ 
+ 	return 0;
+ }
+ 
+ int
+ FromNetIO::initialize(ErrorHandler *)
+ {
+ 	return oskit_create_fromnetio(this, _ifnum, &_priv);
+ }
+ 
+ int
+ FromNetIO::got_packet(oskit_bufio_t *b)
+ {
+ 	/*
+ 	 * Make a packet out of the bufio data. If this succeeds, the
+ 	 * packet constructor will bump the bufio reference count.
+ 	 */
+ 	Packet* p = Packet::make(b);
+ 	output(0).push(p);
+ 	return 0;
+ }
+ 
+ /*
+  * This is the upcall from the netio code.
+  */
+ extern "C" int
+ click_FromNetio_in(void *obj, oskit_bufio_t *b, int)
+ {
+ 	FromNetIO	*netio = (FromNetIO *) obj;
+ 
+ 	return netio->got_packet(b);
+ }
+ 
+ EXPORT_ELEMENT(FromNetIO)
diff -Nr -c click-0.6/elements/oskit/fromnetio.hh click/elements/oskit/fromnetio.hh
*** click-0.6/elements/oskit/fromnetio.hh	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/fromnetio.hh	Fri Dec 10 07:32:49 1999
***************
*** 0 ****
--- 1,48 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #ifndef FROMNETIO_HH
+ #define FROMNETIO_HH
+ 
+ #include "element.hh"
+ #include "string.hh"
+ 
+ extern "C" {
+ #include <oskit/io/bufio.h>
+ }
+ 
+ class FromNetIO : public Element {
+ public:
+ 	FromNetIO();
+ 	~FromNetIO();
+   
+ 	const char *class_name() const		{ return "FromNetIO"; }
+ 	Processing default_processing() const	{ return PUSH; }
+   
+ 	FromNetIO *clone() const;
+ 	int configure(const String &, ErrorHandler *);
+ 	int initialize(ErrorHandler *);
+   
+ 	/* process a packet. return 0 if not wanted after all. */
+ 	int got_packet(oskit_bufio_t *b);
+ 
+ private:
+ 	int	_ifnum;
+ 	void	*_priv;
+ };
+ 
+ #endif /* FROMNETIO_HH */
diff -Nr -c click-0.6/elements/oskit/fromnull.cc click/elements/oskit/fromnull.cc
*** click-0.6/elements/oskit/fromnull.cc	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/fromnull.cc	Thu Dec 16 10:22:34 1999
***************
*** 0 ****
--- 1,65 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * fromnull.{cc,hh} -- A rather silly element that serves as a packet
+  * source that delivers no packets.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+ #include "fromnull.hh"
+ #include "error.hh"
+ #include "packet.hh"
+ #include "confparse.hh"
+ #include "glue.hh"
+ #include <unistd.h>
+ 
+ FromNull::FromNull()
+ {
+ 	add_output();
+ }
+ 
+ FromNull::~FromNull()
+ {
+ }
+ 
+ FromNull *
+ FromNull::clone() const
+ {
+ 	return new FromNull;
+ }
+ 
+ int
+ FromNull::configure(const String &conf, ErrorHandler *errh)
+ {
+ 	if (cp_va_parse(conf, this, errh,
+ 			cpInteger, "interface number", &_ifnum,
+ 			cpEnd) < 0)
+ 		return -1;
+ 
+ 	return 0;
+ }
+ 
+ int
+ FromNull::initialize(ErrorHandler *)
+ {
+ 	return 0;
+ }
+ 
+ EXPORT_ELEMENT(FromNull)
diff -Nr -c click-0.6/elements/oskit/fromnull.hh click/elements/oskit/fromnull.hh
*** click-0.6/elements/oskit/fromnull.hh	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/fromnull.hh	Thu Dec 16 10:22:02 1999
***************
*** 0 ****
--- 1,45 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * A rather silly element that serves as a packet source that delivers
+  * no packets.
+  */
+ 
+ #ifndef FROMNULL_HH
+ #define FROMNULL_HH
+ 
+ #include "element.hh"
+ #include "string.hh"
+ 
+ class FromNull : public Element {
+ public:
+ 	FromNull();
+ 	~FromNull();
+   
+ 	const char *class_name() const		{ return "FromNull"; }
+ 	Processing default_processing() const	{ return PUSH; }
+   
+ 	FromNull *clone() const;
+ 	int configure(const String &, ErrorHandler *);
+ 	int initialize(ErrorHandler *);
+ 
+ private:
+ 	int	_ifnum;
+ };
+ 
+ #endif /* FROMNULL_HH */
diff -Nr -c click-0.6/elements/oskit/netio_guts.c click/elements/oskit/netio_guts.c
*** click-0.6/elements/oskit/netio_guts.c	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/netio_guts.c	Fri Dec 10 07:32:49 1999
***************
*** 0 ****
--- 1,309 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #include <oskit/types.h>
+ #include <oskit/io/bufio.h>
+ #include <oskit/net/ether.h>
+ #include <oskit/dev/dev.h>
+ #include <oskit/dev/osenv.h>
+ #include <oskit/dev/net.h>
+ #include <oskit/dev/ethernet.h>
+ #include <oskit/startup.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <oskit/debug.h>
+ #include "netio_guts.h"
+ 
+ #define PRINTF(fmt, args... )  printf(__FUNCTION__  ":" fmt , ## args)
+ #if 1
+ #define DPRINTF(fmt, args... ) printf(__FUNCTION__  ":" fmt , ## args)
+ #else
+ #define DPRINTF(fmt, args... )
+ #endif
+ 
+ /*
+  * Private data structure for each opened device.
+  */
+ struct etherdev {
+ 	oskit_etherdev_t	*dev;
+ 	oskit_netio_t		*send_nio;
+ 	oskit_netio_t		*recv_nio;
+ 	oskit_devinfo_t		info;
+ 	unsigned char		haddr[OSKIT_ETHERDEV_ADDR_SIZE];
+ 	void			*obj;	/* C++ object to pass back */
+ 	char			send_inuse;
+ 	char			recv_inuse;
+ };
+ #define MAX_EDEVS	4
+ static struct etherdev	*myedevs[MAX_EDEVS];
+ static int		netio_init_guts(int ifnum);
+ static unsigned char	bcastaddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ 
+ /*
+  * The network callback. This will suck out a data pointer, and then
+  * pass that up to the c++ class callback.
+  */
+ static oskit_error_t
+ net_receive(void *data, oskit_bufio_t *b, oskit_size_t pkt_size)
+ {
+ 	struct etherdev		*edev = (struct etherdev *)data;
+ 	oskit_error_t		err;
+ 	void			*frame;
+ 	struct ether_header	*eth;
+ 	
+ 	err = oskit_bufio_map(b, (void **)&frame, 0, pkt_size);
+ 	assert(err == 0);
+ 	eth = (struct ether_header *)frame;
+ 
+ 	if (memcmp(eth->ether_dhost, &edev->haddr, sizeof(edev->haddr)) != 0
+ 	    && memcmp(eth->ether_dhost, bcastaddr, sizeof bcastaddr) != 0) 
+ 		return 0;
+ 
+ 	/*
+ 	 * Pass bufio up to C++ NetIO class. It will handle incrementing
+ 	 * the reference count if it decides to hang onto it.
+ 	 */
+ 	if (edev->recv_inuse)
+ 		click_FromNetio_in(edev->obj, b, (int) pkt_size);
+ 
+ 	return 0;
+ }
+ 
+ int
+ oskit_create_fromnetio(void *obj, int ifnum, void **priv)
+ {
+ 	struct etherdev		*edev;
+ 
+ 	if (ifnum < 0 || ifnum >= MAX_EDEVS) {
+ 		PRINTF("Bad ifnum:%d. Max ifnum is %d\n", ifnum, MAX_EDEVS);
+ 		return -1;
+ 	}
+ 	if ((edev = myedevs[ifnum]) == NULL) {
+ 		if (netio_init_guts(ifnum))
+ 			return -1;
+ 		edev = myedevs[ifnum];
+ 	}
+ 
+ 	/*
+ 	 * Not great, but lets see how we want to use this before we
+ 	 * get fancy about reference counting.
+ 	 */
+ 	if (edev->recv_inuse) {
+ 		PRINTF("ifnum:%d already in use.\n", ifnum);
+ 		return -1;
+ 	}
+ 
+ 	/*
+ 	 * Stash the object pointer for callback.
+ 	 */
+ 	edev->obj        = obj;
+ 	edev->recv_inuse = 1;
+ 	*priv            = (void *) edev;
+ 
+ 	return 0;
+ }
+ 
+ int
+ oskit_create_tonetio(void *obj, int ifnum, void **priv)
+ {
+ 	struct etherdev		*edev;
+ 
+ 	if (ifnum < 0 || ifnum >= MAX_EDEVS) {
+ 		PRINTF("Bad ifnum:%d. Max ifnum is %d\n", ifnum, MAX_EDEVS);
+ 		return -1;
+ 	}
+ 	if ((edev = myedevs[ifnum]) == NULL) {
+ 		if (netio_init_guts(ifnum))
+ 			return -1;
+ 		edev = myedevs[ifnum];
+ 	}
+ 
+ 	/*
+ 	 * Not great, but lets see how we want to use this before we
+ 	 * get fancy about reference counting.
+ 	 */
+ 	if (edev->send_inuse) {
+ 		PRINTF("ifnum:%d already in use.\n", ifnum);
+ 		return -1;
+ 	}
+ 
+ 	edev->send_inuse = 1;
+ 	*priv            = (void *) edev;
+ 
+ 	return 0;
+ }
+ 
+ int
+ oskit_destroy_fromnetio(int ifnum, void *priv)
+ {
+ 	struct etherdev		*edev;
+ 
+ 	if (ifnum < 0 || ifnum >= MAX_EDEVS) {
+ 		PRINTF("Bad ifnum:%d. Max ifnum is %d\n", ifnum, MAX_EDEVS);
+ 		return -1;
+ 	}
+ 	if ((edev = myedevs[ifnum]) == NULL) {
+ 		PRINTF("Bad ifnum:%d. Interface never used\n", ifnum);
+ 		return -1;
+ 	}
+ 
+ 	if (edev->recv_inuse == 0) {
+ 		PRINTF("Bad ifnum:%d. Interface never used\n", ifnum);
+ 		return -1;
+ 	}
+ 
+ 	edev->recv_inuse = 0;
+ 	if (edev->recv_inuse || edev->send_inuse)
+ 		return 0;
+ 
+ 	DPRINTF("Destroying NetIO %d ...\n", ifnum);
+ 
+ 	oskit_etherdev_release(edev->dev);
+ 	oskit_netio_release(edev->send_nio);
+ 	oskit_netio_release(edev->recv_nio);
+ 	free(edev);
+ 	myedevs[ifnum] = 0;
+ 
+ 	return 0;
+ }
+ 
+ oskit_destroy_tonetio(int ifnum, void *priv)
+ {
+ 	struct etherdev		*edev;
+ 
+ 	if (ifnum < 0 || ifnum >= MAX_EDEVS) {
+ 		PRINTF("Bad ifnum:%d. Max ifnum is %d\n", ifnum, MAX_EDEVS);
+ 		return -1;
+ 	}
+ 	if ((edev = myedevs[ifnum]) == NULL) {
+ 		PRINTF("Bad ifnum:%d. Interface never used\n", ifnum);
+ 		return -1;
+ 	}
+ 
+ 	if (edev->send_inuse == 0) {
+ 		PRINTF("Bad ifnum:%d. Interface never used\n", ifnum);
+ 		return -1;
+ 	}
+ 
+ 	edev->send_inuse = 0;
+ 	if (edev->recv_inuse || edev->send_inuse)
+ 		return 0;
+ 
+ 	DPRINTF("Destroying NetIO %d ...\n", ifnum);
+ 
+ 	oskit_etherdev_release(edev->dev);
+ 	oskit_netio_release(edev->send_nio);
+ 	oskit_netio_release(edev->recv_nio);
+ 	free(edev);
+ 	myedevs[ifnum] = 0;
+ 
+ 	return 0;
+ }
+ 
+ /*
+  * Click hands us a bufio to send. Push it out.
+  */
+ int
+ oskit_sendto_netio_withbufio(void *obj, oskit_bufio_t *b, int len)
+ {
+ 	struct etherdev	*edev = (struct etherdev *) obj;
+ 	
+ 	oskit_netio_push(edev->send_nio, b, len);
+ 	
+ 	return 0;
+ }
+ 
+ /*
+  * Initialize the netio interface for a specific (integer) interface.
+  * We pass back (through the priv pointer) a pointer to the etherdev.
+  */
+ static int
+ netio_init_guts(int ifnum)
+ {
+ 	oskit_error_t		err;
+ 	oskit_etherdev_t	**etherdev;
+ 	int			i, ndev;
+ 	struct etherdev		*edev;
+ 
+ 	/*
+ 	 * Find all the Ethernet device nodes.
+ 	 */
+ 	ndev = osenv_device_lookup(&oskit_etherdev_iid, (void***)&etherdev);
+ 	if (ndev <= 0) {
+ 		PRINTF("no Ethernet adaptors found!");
+ 		goto bad;
+ 	}
+ 	if (ifnum < 0 || ifnum >= ndev || ifnum >= MAX_EDEVS) {
+ 		PRINTF("Bad ifnum:%d. Max ifnum is %d\n", ifnum, ndev);
+ 		goto bad;
+ 	}
+ 
+ 	if ((edev = (struct etherdev *) malloc(sizeof(*edev))) == NULL) {
+ 		PRINTF("Out of memory allocating etherdev\n");
+ 		goto bad;
+ 	}
+ 	memset(edev, 0, sizeof(*edev));
+ 
+ 	err = oskit_etherdev_getinfo(etherdev[ifnum], &(edev->info));
+ 	if (err) {
+ 		PRINTF("Error getting info from ethercard %d", ifnum);
+ 		goto bad;
+ 	}
+ 	
+ 	oskit_etherdev_getaddr(etherdev[ifnum], edev->haddr);
+ 
+ 	/*
+ 	 * Show information about this adaptor
+ 	 */
+ 	DPRINTF("%-16s%-40s\n", edev->info.name,
+ 		edev->info.description ? edev->info.description : "");
+ 
+ 	edev->dev      = etherdev[ifnum];
+ 	edev->recv_nio = oskit_netio_create(net_receive, edev);
+ 	if (edev->recv_nio == NULL) {
+ 		PRINTF("unable to create recv_nio");
+ 		goto bad;
+ 	}
+ 	
+ 	err = oskit_etherdev_open(etherdev[ifnum],
+ 				  0, edev->recv_nio, &(edev->send_nio));
+ 
+ 	if (err) {
+ 		PRINTF("Error opening ethernet device: err:0x%x\n", err);
+ 		oskit_netio_release(edev->recv_nio);
+ 		goto bad;
+ 	}
+ 	/*
+ 	 * Release the devs we were not interested in.
+ 	 */
+ 	for (i = 0; i < ndev; i++) {
+ 		if (i != ifnum)
+ 			oskit_etherdev_release(etherdev[i]);
+ 	}
+ 
+ 	/*
+ 	 * Stash the edev away.
+ 	 */
+ 	myedevs[ifnum] = edev;
+ 	return 0;
+ 
+ bad:
+ 	for (i = 0; i < ndev; i++) {
+ 		oskit_etherdev_release(etherdev[i]);
+ 	}
+ 	return -1;
+ }
diff -Nr -c click-0.6/elements/oskit/netio_guts.h click/elements/oskit/netio_guts.h
*** click-0.6/elements/oskit/netio_guts.h	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/netio_guts.h	Fri Dec 10 07:32:49 1999
***************
*** 0 ****
--- 1,55 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #ifdef __cplusplus
+ #define EXTERN extern "C"
+ #else
+ #define EXTERN extern
+ #endif
+ 
+ /*
+  * Create and destroy from/to netio interfaces.
+  */
+ EXTERN int
+ oskit_create_fromnetio(void *obj, int ifnum, void **priv);
+ 
+ EXTERN int
+ oskit_create_tonetio(void *obj, int ifnum, void **priv);
+ 
+ EXTERN int
+ oskit_destroy_fromnetio(int ifnum, void *priv);
+ 
+ EXTERN int
+ oskit_destroy_tonetio(int ifnum, void *priv);
+ 
+ /*
+  * This is the push routine on the outgoing side. 
+  */
+ EXTERN int
+ oskit_sendto_netio(void *obj, void *data, int len);
+ 
+ /*
+  * Another push routine that takes a bufio.
+  */
+ EXTERN int
+ oskit_sendto_netio_withbufio(void *obj, oskit_bufio_t *b, int len);
+ 
+ /*
+  * This is the upcall from the netio code into FromNetIO.
+  */
+ EXTERN int
+ click_FromNetio_in(void *obj, oskit_bufio_t *b, int len);
diff -Nr -c click-0.6/elements/oskit/tonetio.cc click/elements/oskit/tonetio.cc
*** click-0.6/elements/oskit/tonetio.cc	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/tonetio.cc	Fri Dec 10 07:32:50 1999
***************
*** 0 ****
--- 1,93 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * tonetio.{cc,hh} -- Send packets to a OSKit netio.
+  */
+ 
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+ #include "tonetio.hh"
+ #include "error.hh"
+ #include "packet.hh"
+ #include "confparse.hh"
+ #include "glue.hh"
+ #include <unistd.h>
+ #include "netio_guts.h"
+ 
+ ToNetIO::ToNetIO()
+   : Element(1, 0), _ifnum(-1)
+ {
+ }
+ 
+ ToNetIO::~ToNetIO()
+ {
+ 	if (_ifnum >= 0)
+ 		(void) oskit_destroy_tonetio(_ifnum, _priv);
+ }
+ 
+ ToNetIO *
+ ToNetIO::clone() const
+ {
+ 	return new ToNetIO;
+ }
+ 
+ int
+ ToNetIO::configure(const String &conf, ErrorHandler *errh)
+ {
+ 	if (cp_va_parse(conf, this, errh,
+ 			cpInteger, "interface number", &_ifnum,
+ 			cpEnd) < 0)
+ 		return -1;
+ 
+ 	return 0;
+ }
+ 
+ int
+ ToNetIO::initialize(ErrorHandler *)
+ {
+ 	return oskit_create_tonetio(this, _ifnum, &_priv);
+ }
+ 
+ void
+ ToNetIO::push(int, Packet *p)
+ {
+ 	/*
+ 	 * Kludgey. 
+ 	 */
+ 	p->bufio_convert();
+ 	oskit_sendto_netio_withbufio(_priv, p->bufio(), p->length());
+ 	p->kill();
+ }
+ 
+ bool
+ ToNetIO::wants_packet_upstream() const
+ {
+   return input_is_pull(0);
+ }
+ 
+ void
+ ToNetIO::run_scheduled()
+ {
+   while (Packet *p = input(0).pull())
+     push(0, p);
+ }
+ 
+ 
+ 
+ EXPORT_ELEMENT(ToNetIO)
diff -Nr -c click-0.6/elements/oskit/tonetio.hh click/elements/oskit/tonetio.hh
*** click-0.6/elements/oskit/tonetio.hh	Wed Dec 31 16:00:00 1969
--- click/elements/oskit/tonetio.hh	Fri Dec 10 07:32:50 1999
***************
*** 0 ****
--- 1,46 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #ifndef TONETIO_HH
+ #define TONETIO_HH
+ 
+ #include "element.hh"
+ #include "string.hh"
+ 
+ class ToNetIO : public Element {
+ public:
+ 	ToNetIO();
+ 	~ToNetIO();
+   
+ 	const char *class_name() const		{ return "ToNetIO"; }
+ 	Processing default_processing() const	{ return AGNOSTIC; }
+   
+ 	ToNetIO *clone() const;
+ 	int configure(const String &, ErrorHandler *);
+ 	int initialize(ErrorHandler *);
+   
+ 	void push(int port, Packet *);
+ 
+ 	bool wants_packet_upstream() const;
+ 	void run_scheduled();
+ 
+ private:
+ 	int	_ifnum;
+ 	void	*_priv;
+ };
+ 
+ #endif /* NETIO_HH */
diff -Nr -c click-0.6/elements/standard/pulltopush.cc click/elements/standard/pulltopush.cc
*** click-0.6/elements/standard/pulltopush.cc	Fri Dec 10 20:56:39 1999
--- click/elements/standard/pulltopush.cc	Tue Dec 14 12:51:00 1999
***************
*** 26,32 ****
  void
  PullToPush::run_scheduled()
  {
! #ifdef __KERNEL__
    if (!scheduled()) schedule_tail();
  #endif
  
--- 26,32 ----
  void
  PullToPush::run_scheduled()
  {
! #if defined(__KERNEL__) || defined(OSKIT)
    if (!scheduled()) schedule_tail();
  #endif
  
diff -Nr -c click-0.6/lib/elemlink.hh click/lib/elemlink.hh
*** click-0.6/lib/elemlink.hh	Thu Oct 14 15:18:58 1999
--- click/lib/elemlink.hh	Tue Dec 14 18:22:46 1999
***************
*** 1,6 ****
--- 1,12 ----
  #ifndef ELEMLINK_HH
  #define ELEMLINK_HH
  
+ #ifdef OSKIT
+ extern "C" {
+ #include <oskit/dev/dev.h>
+ }
+ #endif
+ 
  class ElementLink {
    
    ElementLink *_prev;
***************
*** 37,52 ****
--- 43,72 ----
  inline void
  ElementLink::unschedule()
  {
+ #ifdef OSKIT
+   int enabled = osenv_intr_enabled();
+   if (enabled)
+     osenv_intr_disable();
+ #endif
    if (_next) {
      _next->_prev = _prev;
      _prev->_next = _next;
    }
    _next = _prev = 0;
+ #ifdef OSKIT
+   if (enabled)
+     osenv_intr_enable();
+ #endif
  }
  
  inline void
  ElementLink::schedule_head()
  {
+ #ifdef OSKIT
+   int enabled = osenv_intr_enabled();
+   if (enabled)
+     osenv_intr_disable();
+ #endif
    if (_next) {
      _next->_prev = _prev;
      _prev->_next = _next;
***************
*** 56,66 ****
--- 76,95 ----
    _prev = _list;
    _list->_next = this;
    n->_prev = this;
+ #ifdef OSKIT
+   if (enabled)
+     osenv_intr_enable();
+ #endif
  }
  
  inline void
  ElementLink::schedule_tail()
  {
+ #ifdef OSKIT
+   int enabled = osenv_intr_enabled();
+   if (enabled)
+     osenv_intr_disable();
+ #endif
    if (!_next) {
      ElementLink *p = _list->_prev;
      _next = _list;
***************
*** 68,73 ****
--- 97,106 ----
      _list->_prev = this;
      p->_next = this;
    }
+ #ifdef OSKIT
+   if (enabled)
+     osenv_intr_enable();
+ #endif
  }
  
  #endif
diff -Nr -c click-0.6/lib/packet.cc click/lib/packet.cc
*** click-0.6/lib/packet.cc	Thu Nov  4 20:33:17 1999
--- click/lib/packet.cc	Thu Dec 16 10:24:35 1999
***************
*** 18,23 ****
--- 18,30 ----
  #include "glue.hh"
  #include <assert.h>
  
+ #ifdef OSKIT
+ extern "C" {
+ #include <oskit/dev/dev.h>
+ void panic(const char *__format, ...);
+ }
+ #endif
+ 
  #ifdef __KERNEL__
  
  Packet::Packet()
***************
*** 56,61 ****
--- 63,71 ----
    _use_count = 1;
    _data_packet = 0;
    _head = _data = _tail = _end = 0;
+ #ifdef OSKIT
+   _bufio = 0;
+ #endif
    memset(_cb, 0, sizeof(_cb));
  }
  
***************
*** 64,70 ****
--- 74,87 ----
    if (_data_packet) {
      _data_packet->kill();
    } else if (_head) {
+ #ifdef OSKIT
+     if (_bufio)
+       oskit_bufio_release(_bufio);
+     else
+       osenv_mem_free((void *) _head, OSENV_AUTO_SIZE, 0);
+ #else
      delete[] _head;
+ #endif
      _head = _data = 0;
    }
  }
***************
*** 79,85 ****
--- 96,112 ----
  Packet::alloc_data(unsigned headroom, unsigned len, unsigned tailroom)
  {
    unsigned n = len + headroom + tailroom;
+ #ifdef OSKIT
+   /*
+    * Use wired down memory so it can be turned directly into a bufio later.
+    */
+   _head = (unsigned char *)
+ 	  osenv_mem_alloc(n, OSENV_PHYS_WIRED|OSENV_AUTO_SIZE, 0);
+   if (!_head)
+     panic("Packet::alloc_data no more memory");
+ #else
    _head = new unsigned char[n];
+ #endif
    _data = _head + headroom;
    _tail = _data + len;
    _end = _head + n;
***************
*** 96,101 ****
--- 123,187 ----
    }
    return p;
  }
+ 
+ #ifdef OSKIT
+ Packet *
+ Packet::make(oskit_bufio_t *b)
+ {
+   Packet *p = new Packet;
+   void *frame;
+   oskit_error_t err;
+   oskit_off_t len;
+ 
+   /*
+    * Map in the data. If it fails, we have to copy it instead.
+    */
+   oskit_bufio_getsize(b, &len);
+   err = oskit_bufio_map(b, (void **)&frame, 0, len);
+   if (err) {
+ 	  oskit_size_t actual;
+ 	  
+ 	  click_chatter("Packet::make could not map the bufio");
+ 	  p->alloc_data(default_headroom(), len, default_tailroom(len));
+ 	  oskit_bufio_read(b, p->data(), 0, len, &actual);
+ 	  return p;
+   }
+ 
+   /*
+    * We can map the data. Stuff it into the packet, but remember that
+    * there is no headroom or tailroom, so its possible the packet will
+    * get copied later anyway.
+    */
+   oskit_bufio_addref(b);
+   p->_bufio = b;
+   p->_head  = (unsigned char *) frame;
+   p->_data  = p->_head;
+   p->_tail  = p->_head + len;
+   p->_end   = p->_tail;
+ 
+   return p;
+ }
+ 
+ /*
+  * Turn the packet data into an external bufio.
+  */
+ void
+ Packet::bufio_free(void *head, void *)
+ {
+ /*  click_chatter("Packet::bufio_free Freeing up memory\n"); */
+   osenv_mem_free(head, OSENV_AUTO_SIZE, 0);
+ }
+ 
+ void
+ Packet::bufio_convert(void)
+ {
+   if (_bufio)
+     return;
+   
+   _bufio = oskit_create_extern_bufio(data(),
+ 				     length(), Packet::bufio_free, _head);
+ }
+ #endif
  
  #endif /* __KERNEL__ */
  
diff -Nr -c click-0.6/lib/packet.hh click/lib/packet.hh
*** click-0.6/lib/packet.hh	Thu Nov  4 09:12:38 1999
--- click/lib/packet.hh	Wed Dec  8 07:30:55 1999
***************
*** 4,9 ****
--- 4,15 ----
  #include "glue.hh"
  struct click_ip;
  
+ #ifdef OSKIT
+ extern "C" {
+ #include <oskit/io/bufio.h>
+ }
+ #endif
+ 
  class Packet {
  
    // Anno must fit in sk_buff's char cb[48].
***************
*** 28,33 ****
--- 34,42 ----
    unsigned char *_end;  /* one beyond end of allocated buffer */
    unsigned char _cb[48];
    click_ip *_nh_iph;
+ #ifdef OSKIT
+   oskit_bufio_t *_bufio;
+ #endif
  #endif
    
    Packet();
***************
*** 70,75 ****
--- 79,95 ----
    static Packet *make(struct sk_buff *);
    struct sk_buff *skb() const		{ return (struct sk_buff *)this; }
    struct sk_buff *steal_skb()		{ return skb(); }
+ #endif
+ #ifdef OSKIT
+   /*
+    * Wraps a Packet around an existing bufio's data.
+    * Packet now owns the bufio, and must be released when the packet
+    * is destroyed.
+    */
+   static Packet *make(oskit_bufio_t *);
+   void bufio_convert(void);
+   oskit_bufio_t *bufio(void) const { return _bufio; }
+   static void bufio_free(void *cookie, void *buf);
  #endif
  
  #ifdef __KERNEL__
diff -Nr -c click-0.6/lib/router.cc click/lib/router.cc
*** click-0.6/lib/router.cc	Thu Dec  9 14:14:05 1999
--- click/lib/router.cc	Mon Dec 13 16:16:50 1999
***************
*** 793,799 ****
  void
  Router::wait()
  {
! #ifndef __KERNEL__
    // Wait in select() for input or timer.
    // And call relevant elements' selected() methods.
    
--- 793,799 ----
  void
  Router::wait()
  {
! #if !defined(__KERNEL__) && !defined(OSKIT)
    // Wait in select() for input or timer.
    // And call relevant elements' selected() methods.
    
***************
*** 905,911 ****
  bool
  Router::driver()
  {
! #ifndef __KERNEL__
    Timer::run_timers();
  #endif
  
--- 905,911 ----
  bool
  Router::driver()
  {
! #if !defined(__KERNEL__) && !defined(OSKIT)
    Timer::run_timers();
  #endif
  
diff -Nr -c click-0.6/lib/timer.cc click/lib/timer.cc
*** click-0.6/lib/timer.cc	Wed Dec  8 15:30:32 1999
--- click/lib/timer.cc	Tue Dec 14 15:43:12 1999
***************
*** 17,22 ****
--- 17,139 ----
  #include "element.hh"
  #include "router.hh"
  
+ #ifdef OSKIT
+ /*
+  * The Timer callback. Call the actual routine.
+  */
+ int
+ Timer::handler(struct oskit_iunknown *, void *arg)
+ {
+ 	Timer	*Tp = (Timer *) arg;
+ 
+ 	Tp->_hook(Tp->_data);
+ 
+ 	return 0;
+ }
+ 
+ /*
+  * Create a Timer based on OSKit clock timers.
+  */
+ Timer::Timer(TimerHook hook, unsigned long thunk)
+ 	: _clock(0), _timer(0), _hook(0), _data(0), _scheduled(0)
+ {
+ 	oskit_listener_t	*l;
+ 		
+ 	/* Create the clock (only one, and its probably already created). */
+ 	_clock = oskit_clock_init();
+ 
+ 	/* Create a timer */
+ 	oskit_clock_createtimer(_clock, &_timer);
+ 
+ 	/* Create a listener */
+ 	l = oskit_create_listener(Timer::handler, (void *) this);
+ 
+ 	/* Set the listener */
+ 	oskit_timer_setlistener(_timer, l);
+ 	oskit_listener_release(l);
+ 
+ 	_hook = hook;
+ 	_data = thunk;
+ 	_scheduled = 0;
+ }
+ 
+ /*
+  * Create a timer for an element.
+  */
+ Timer::Timer(Element *f)
+ 	: _clock(0), _timer(0), _hook(0), _data(0), _scheduled(0)
+ {
+ 	oskit_listener_t	*l;
+ 		
+ 	/* Create the clock (only one, and its probably already created). */
+ 	_clock = oskit_clock_init();
+ 
+ 	/* Create a timer */
+ 	oskit_clock_createtimer(_clock, &_timer);
+ 
+ 	/* Create a listener */
+ 	l = oskit_create_listener(Timer::handler, (void *) this);
+ 
+ 	/* Set the listener */
+ 	oskit_timer_setlistener(_timer, l);
+ 	oskit_listener_release(l);
+ 
+ 	_hook = element_timer;
+ 	_data = (unsigned long) f;
+ 	_scheduled = 0;
+ }
+ 
+ /*
+  * Destroy a Timer.
+  */
+ Timer::~Timer()
+ {
+ 	if (_timer)
+ 		oskit_timer_release(_timer);
+ 	if (_clock)
+ 		oskit_clock_release(_clock);
+ }
+ 
+ /*
+  * Unschedule a Timer.
+  */
+ void
+ Timer::unschedule()
+ {
+ 	if (scheduled()) {
+ 		oskit_itimerspec_t	timespec = { {0, 0}, {0, 0} };
+ 
+ 		oskit_timer_settime(_timer, 0, &timespec);
+ 	}
+ }
+ 
+ /*
+  * Schedule a timer.
+  */
+ void
+ Timer::schedule_after_ms(int ms)
+ {
+ 	oskit_itimerspec_t	timespec;
+ 
+ 	timespec.it_value.tv_sec     = ms / 1000;
+ 	timespec.it_value.tv_nsec    = (ms % 1000) * 1000000;
+ 	timespec.it_interval.tv_sec  = 0;
+ 	timespec.it_interval.tv_nsec = 0;
+ 
+ 	_scheduled = 1;
+ 	
+ 	oskit_timer_settime(_timer, 0, &timespec);
+ }
+ 
+ void
+ Timer::element_timer(unsigned long thunk)
+ {
+ 	Element *f = (Element *)thunk;
+ 	f->schedule_tail(); // don't do anything - just put it on the work list
+ }
+ 
+ #else  /* OSKIT */
+ 
  void
  Timer::element_timer(unsigned long thunk)
  {
***************
*** 109,111 ****
--- 226,229 ----
  }
  
  #endif /* !__KERNEL__ */
+ #endif /* OSKIT */
diff -Nr -c click-0.6/lib/timer.hh click/lib/timer.hh
*** click-0.6/lib/timer.hh	Tue Oct 19 11:03:06 1999
--- click/lib/timer.hh	Tue Dec 14 15:40:50 1999
***************
*** 5,10 ****
--- 5,48 ----
  
  typedef void (*TimerHook)(unsigned long);
  
+ #ifdef OSKIT
+ /*
+  * Implement timers in terms of OSKit clock.
+  */
+ extern "C" {
+ #include <oskit/dev/clock.h>
+ #include <oskit/dev/timer.h>
+ #include <oskit/com/listener.h>
+ }
+ 
+ typedef void (*TimerHook)(unsigned long);
+ 
+ class Timer {
+ 	oskit_clock_t		*_clock; 
+   	oskit_timer_t		*_timer;
+ 	TimerHook		_hook;
+ 	unsigned long		_data;
+ 	bool			_scheduled;
+ 
+ 	Timer(const Timer &);
+ 	Timer &operator=(const Timer &);
+ 
+ 	static void element_timer(unsigned long);
+ 	static int  handler(struct oskit_iunknown *clock, void *arg);
+ 	
+ public:
+ 	Timer(TimerHook, unsigned long);
+ 	Timer(Element *);
+ 	~Timer();
+   
+ 	bool scheduled() const		{ return _scheduled; }
+ 	
+ 	void schedule_after_ms(int);
+ 	void unschedule();
+ };
+ 
+ #else  /* OSKIT */
+ 
  #ifdef __KERNEL__
  #include <linux/timer.h>
  
***************
*** 108,111 ****
--- 146,150 ----
  
  #endif /* __KERNEL__ */
  
+ #endif /* OSKIT */
  #endif
diff -Nr -c click-0.6/oskit/ANNOUNCE click/oskit/ANNOUNCE
*** click-0.6/oskit/ANNOUNCE	Wed Dec 31 16:00:00 1969
--- click/oskit/ANNOUNCE	Thu Dec 16 11:19:25 1999
***************
*** 0 ****
--- 1,62 ----
+ From: Leigh Stoller <stoller at fast.cs.utah.edu>
+ To: activenets_wire at ittc.ukans.edu, oskit-announce at fast.cs.utah.edu
+ Subject: Flux OSKit and MIT's Click Modular Router
+ 
+ This is to let people know that we upgraded our Click source code to
+ Version 0.6, which came out right about the time we were getting ready
+ to release the 0.51 code. There are also some important OSKit related
+ bug fixes in the new release. As before:
+ 
+ A slightly modified version of Click as well as the OSKit can be found
+ off the Flux group web page:
+ 
+ 	http://www.cs.utah.edu/flux/
+ 
+ The Click home page and MIT's paper describing Click, which was presented
+ at SOSP, can be found at:
+ 
+ 	http://www.pdos.lcs.mit.edu/click/
+ 
+ For a description of our changes, as well as how to configure and
+ build Click on the OSKit, look at README.OSKIT in our modified Click
+ distribution.
+ 
+ Have fun!
+ 
+ The Flux Research Group
+ Department of Computer Science
+ University of Utah
+ http://www.cs.utah.edu/flux/
+ 
+ ----------------------------------------------------------------------------
+ 
+ From: Leigh Stoller <stoller at fast.cs.utah.edu>
+ To: activenets_wire at ittc.ukans.edu, oskit-announce at fast.cs.utah.edu
+ Subject: Flux OSKit and MIT's Click Modular Router
+ 
+ We are pleased to announce the combination of MIT's Click Modular Router
+ and Utah's OSKit.  By combining Click and the OSKit, you can build
+ "flexible and configurable routers" (Click router graphs) that run on
+ x86 and StrongARM "bare metal", without requiring Linux.
+ 
+ A slightly modified version of Click as well as the OSKit can be found
+ off the Flux group web page:
+ 
+ 	http://www.cs.utah.edu/flux/
+ 
+ The Click home page and MIT's paper describing Click, to be presented
+ this coming week at SOSP, can be found at:
+ 
+ 	http://www.pdos.lcs.mit.edu/click/
+ 
+ For a description of our changes, as well as how to configure and
+ build Click on the OSKit, look at README.OSKIT in our modified Click
+ distribution.
+ 
+ Our thanks to the Click crew for their nifty little system.
+ Have fun!
+ 
+ The Flux Research Group
+ Department of Computer Science
+ University of Utah
+ http://www.cs.utah.edu/flux/
diff -Nr -c click-0.6/oskit/Makefile.in click/oskit/Makefile.in
*** click-0.6/oskit/Makefile.in	Wed Dec 31 16:00:00 1969
--- click/oskit/Makefile.in	Thu Dec 16 10:25:06 1999
***************
*** 0 ****
--- 1,139 ----
+ SHELL = @SHELL@
+ 
+ srcdir := @srcdir@
+ top_srcdir := @top_srcdir@
+ top_builddir := ..
+ subdir := oskit
+ 
+ prefix = @prefix@
+ exec_prefix = @exec_prefix@
+ bindir = @bindir@
+ sbindir = @sbindir@
+ libdir = @libdir@
+ 
+ VPATH = .:$(top_srcdir)/$(subdir):$(top_srcdir)/lib:$(top_srcdir)/elements/oskit at elements_vpath@
+ 
+ CC = @OSKIT_CC@ -posix-oskit
+ CPP = @CPP@
+ CXX = @CXX@
+ CXXCPP = @CXXCPP@
+ PACKAGE = @PACKAGE@
+ VERSION = @VERSION@
+ INSTALL = @INSTALL@
+ mkinstalldirs = @top_srcdir@/mkinstalldirs
+ 
+ .SUFFIXES:
+ .SUFFIXES: .S .c .cc .o .s
+ 
+ .c.o:
+ 	$(COMPILE) -c $<
+ .s.o:
+ 	$(COMPILE) -c $<
+ .S.o:
+ 	$(COMPILE) -c $<
+ .cc.o:
+ 	$(CXXCOMPILE) -c $<
+ 
+ 
+ GENERIC_OBJS = string.o straccum.o \
+ 	bitvector.o vectori.o vectorv.o hashmapi.o \
+ 	integers.o ipaddress.o etheraddress.o packet.o \
+ 	error.o glue.o timer.o \
+ 	element.o unlimelement.o timedelement.o errorelement.o \
+ 	confparse.o lexer.o elemfilter.o router.o \
+ 	crc32.o in_cksum.o iptable.o ewma.o
+ 
+ USERLEVEL_OBJS = click_com.o
+ 
+ -include elements.mk
+ 
+ OBJS = $(GENERIC_OBJS) $(ELEMENT_OBJS) $(USERLEVEL_OBJS) elements.o
+ 
+ CPPFLAGS = @CPPFLAGS@ -MMD -DOSKIT
+ CFLAGS = @CFLAGS@ -static
+ CXXFLAGS = @CXXFLAGS@ -fno-exceptions -fno-rtti -static
+ 
+ DEFS = @DEFS@ -I. -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) \
+ 	-I$(top_srcdir)/lib \
+ 	-isystem @OSKIT_DIR@/include/oskit/freebsd \
+ 	-I at OSKIT_DIR@/include -isystem @OSKIT_DIR@/include/oskit/c
+ 
+ LDFLAGS = @LDFLAGS@
+ 
+ PLIBS = \
+ 	-loskit_startup -loskit_clientos -loskit_fsnamespace_r \
+ 	-loskit_threads -loskit_svm -loskit_amm \
+ 	-loskit_bootp -loskit_memfs \
+ 	-loskit_freebsd_net -loskit_linux_dev -loskit_dev -loskit_kern
+ 
+ SLIBS = \
+ 	-loskit_startup -loskit_clientos -loskit_fsnamespace \
+ 	-loskit_bootp -loskit_memfs \
+ 	-loskit_freebsd_net -loskit_linux_dev -loskit_dev -loskit_kern
+ 
+ MKMB  = @OSKIT_DIR@/bin/mkmbimage
+ 
+ CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS)
+ CXXLD = $(CXX)
+ CXXLINK = $(CXXLD) $(CXXFLAGS) $(LDFLAGS) -o $@
+ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+ CCLD = $(CC)
+ LINK = $(CCLD) $(CFLAGS) $(LDFLAGS) -o $@
+ 
+ all: click.a example1 example2
+ 
+ example1: example1.o click.a Makefile $(srcdir)/ping.click
+ 	$(LINK) $@.o click.a $(SLIBS)
+ 	cp $@ $@.gdb
+ 	strip $@
+ 	$(MKMB) -o $@.image $@ $(srcdir)/ping.click:ping.click
+ 
+ example1.o:	example1.c
+ 	$(COMPILE) -pthread -static -c -O $<
+ 
+ example2: example2.o click.a Makefile $(srcdir)/ping.click
+ 	$(LINK) -pthread $@.o click.a $(PLIBS)
+ 	cp $@ $@.gdb
+ 	strip $@
+ 	$(MKMB) -o $@.image $@ $(srcdir)/ping.click:ping.click
+ 
+ example2.o:	example2.c
+ 	$(COMPILE) -static -c -O $<
+ 
+ click.a:	Makefile $(OBJS)
+ 	rm -f $@
+ 	ar rv $@ $(OBJS)
+ 	ranlib $@
+ 
+ netio_guts.o:	netio_guts.c
+ 	$(COMPILE) -c -O $<
+ 
+ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ 	cd $(top_builddir) \
+ 	  && CONFIG_FILES=$(subdir)/$@ CONFIG_ELEMLISTS=no CONFIG_HEADERS= $(SHELL) ./config.status
+ 
+ elemlist elements.conf:
+ 	echo "userlevel at element_groups@" | (cd $(top_srcdir); sh ./findelements.sh -x) > elements.conf
+ elements.mk: elements.conf $(top_srcdir)/findelements.sh
+ 	(cd $(top_srcdir); /bin/sh ./findelements.sh -m) < elements.conf > elements.mk
+ elements.cc: elements.conf $(top_srcdir)/findelements.sh
+ 	(cd $(top_srcdir); /bin/sh ./findelements.sh -c) < elements.conf > elements.cc
+ 	@rm -f elements.d
+ 
+ DEPFILES := $(wildcard *.d)
+ ifneq ($(DEPFILES),)
+ include $(DEPFILES)
+ endif
+ 
+ install: click
+ 	$(mkinstalldirs) $(bindir)
+ 	$(INSTALL) click $(bindir)/click
+ install-man:
+ 
+ clean:
+ 	rm -f *.d *.o example1 example2 *.gdb click.a elements.mk elements.cc
+ 	rm -f *.image
+ distclean: clean
+ 	-rm -f Makefile elements.conf
+ 
+ .PHONY: all clean distclean elemlist install install-man
diff -Nr -c click-0.6/oskit/click_com.cc click/oskit/click_com.cc
*** click-0.6/oskit/click_com.cc	Wed Dec 31 16:00:00 1969
--- click/oskit/click_com.cc	Mon Dec 13 16:26:43 1999
***************
*** 0 ****
--- 1,223 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * Click COM component.
+  */
+ 
+ extern "C" {
+ #include <oskit/c/malloc.h>
+ #include "click_com.h"
+ }
+ 
+ #include "lexer.hh"
+ #include "router.hh"
+ #include "error.hh"
+ #include "timer.hh"
+ #include "straccum.hh"
+ 
+ /*
+  * XXX Belongs elsewhere!
+  */
+ const struct oskit_guid oskit_clicker_iid = OSKIT_CLICKER_IID;
+ 
+ /*
+  * This is in the auto generated elements.cc file.
+  */
+ extern void export_elements(Lexer *);
+ 
+ /*
+  * The actual component. 
+  */
+ struct clicker {
+ 	oskit_clicker_t		ioi;		/* The COM interface */
+ 	int			count;		/* Ref count */
+ 	int			stop;		/* MAKE IT STOP! */
+ 	Lexer		       *lex;
+ 	Router		       *router;
+ };
+ 
+ static OSKIT_COMDECL
+ clickcon_query(oskit_clicker_t *c,
+ 	       const oskit_iid_t *iid, void **out_ihandle) 
+ {
+ 	struct clicker	 *clicker = (struct clicker *) c;
+ 
+ 	assert(clicker != NULL);
+ 	assert(clicker->count != 0);
+ 
+ 	if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
+ 	    memcmp(iid, &oskit_clicker_iid, sizeof(*iid)) == 0) {
+ 		*out_ihandle = &clicker->ioi;
+ 		++clicker->count;
+ 		
+ 		return 0;
+ 	}
+ 
+ 	*out_ihandle = NULL;
+ 	return OSKIT_E_NOINTERFACE;
+ }
+ 
+ static OSKIT_COMDECL_U
+ clickcon_addref(oskit_clicker_t *c)
+ {
+ 	struct clicker	 *clicker = (struct clicker *) c;
+ 
+ 	assert(clicker != NULL);
+ 	assert(clicker->count != 0);
+ 
+ 	return ++clicker->count;
+ }
+ 
+ static OSKIT_COMDECL_U
+ clickcon_release(oskit_clicker_t *c)
+ {
+ 	struct clicker	 *clicker = (struct clicker *) c;
+ 	unsigned newcount;
+ 
+ 	assert(clicker != NULL);
+ 	assert(clicker->count != 0);
+ 
+ 	if ((newcount = --clicker->count) == 0) {
+ 		delete clicker->router;
+ 		delete clicker->lex;
+ 		sfree(clicker, sizeof(*clicker));
+ 	}
+ 	return newcount;
+ }
+ 
+ static OSKIT_COMDECL
+ clickcon_config(oskit_clicker_t *c, char *config_file)
+ {
+ 	struct clicker	*clicker = (struct clicker *) c;
+ 	ErrorHandler	*errh    = ErrorHandler::default_handler();
+ 	FILE		*fp;
+ 	String		filename = config_file;
+ 
+ 	assert(clicker != NULL);
+ 	assert(clicker->count != 0);
+ 
+ 	if ((fp = fopen(config_file, "r")) == NULL)
+ 		errh->fatal("Could not open config file: %s", config_file);
+ 
+ 	/*
+ 	 * So, not sure why this like this. Must read the file first and
+ 	 * put it into String format.
+ 	 */
+ 	StringAccum	config_sa;
+ 	while (!feof(fp)) {
+ 		char	*x;
+ 		int	r;
+ 
+ 		if ((x = config_sa.reserve(512)) == NULL)
+ 			errh->fatal("Out of memory");
+ 		else {
+ 			r = fread(x, 1, 512, fp);
+ 			config_sa.forward(r);
+ 		}
+ 	}
+ 	fclose(fp);
+ 
+ 	Lexer *lex = new Lexer(errh);
+ 	export_elements(lex);
+ 	lex->save_element_types();
+   
+ 	lex->reset(config_sa.take_string(), filename);
+ 	while (lex->ystatement())
+ 		/* do nothing */;
+   
+ 	Router *router = lex->create_router();
+ 	lex->clear();
+ 
+ 	clicker->lex    = lex;
+ 	clicker->router = router;
+ 
+ 	return 0;
+ }
+ 
+ static OSKIT_COMDECL
+ clickcon_start(oskit_clicker_t *c)
+ {
+ 	struct clicker	*clicker = (struct clicker *) c;
+ 	ErrorHandler	*errh    = ErrorHandler::default_handler();
+ 	Router  	*router;
+ 
+ 	assert(clicker != NULL);
+ 	assert(clicker->count != 0);
+ 
+ 	router = clicker->router;
+ 	
+ 	if (router->initialize(errh) >= 0) {
+ 		errh->message("Router configuration structure:");
+ 		router->print_structure(errh);
+ 
+ 		while (router->driver() && !clicker->stop)
+ 			;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static OSKIT_COMDECL_V
+ clickcon_stop(oskit_clicker_t *c)
+ {
+ 	struct clicker	*clicker = (struct clicker *) c;
+ 
+ 	assert(clicker != NULL);
+ 	assert(clicker->count != 0);
+ 
+ 	clicker->stop = 1;
+ }
+ 
+ static struct oskit_clicker_ops clickcon_ops = {
+ 	clickcon_query,
+ 	clickcon_addref,
+ 	clickcon_release,
+ 	clickcon_config,
+ 	clickcon_start,
+ 	clickcon_stop,
+ };
+ 
+ /*
+  * Create an instance of a click object. The object is pretty much useless
+  * until it is configured, and then started.
+  */
+ oskit_clicker_t *
+ oskit_clicker_create(void)
+ {
+ 	struct clicker	*c;
+ 	static int	initialized;
+ 
+ 	if (! initialized) {
+ 		String::static_initialize();
+ 		ErrorHandler *errh = new FileErrorHandler(stderr, "");
+ 		ErrorHandler::static_initialize(errh);
+ 
+ 		initialized = 1;
+ 	}
+ 
+ 	c = (struct clicker *) smalloc(sizeof *c);
+ 	if (c == 0)
+ 		return 0;
+ 
+ 	c->ioi.ops = &clickcon_ops;
+ 	c->count   = 1;
+ 	c->stop    = 0;
+ 	
+ 	return &c->ioi;
+ }
+ 
diff -Nr -c click-0.6/oskit/click_com.h click/oskit/click_com.h
*** click-0.6/oskit/click_com.h	Wed Dec 31 16:00:00 1969
--- click/oskit/click_com.h	Fri Dec 10 07:32:50 1999
***************
*** 0 ****
--- 1,79 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * Click COM component.
+  */
+ 
+ #ifndef _CLICKER_H_
+ #define _CLICKER_H_
+ 
+ #include <oskit/types.h>
+ #include <oskit/com.h>
+ 
+ struct oskit_clicker {
+ 	struct oskit_clicker_ops *ops;
+ };
+ typedef struct oskit_clicker oskit_clicker_t;
+ 
+ struct oskit_clicker_ops {
+ 	/* COM-specified IUnknown interface operations. */
+ 	OSKIT_COMDECL_IUNKNOWN(oskit_clicker_t)
+ 
+ 	/*** Operations specific to the oskit_clicker interface ***/
+ 
+ 	/*
+ 	 * Configure a Click component using a configuration file.
+ 	 */
+ 	OSKIT_COMDECL	(*config)(oskit_clicker_t *c, char *config_file);
+ 
+ 	/*
+ 	 * Start the Click driver up.
+ 	 */
+ 	OSKIT_COMDECL	(*start)(oskit_clicker_t *c);
+ 
+ 	/*
+ 	 * Make it stop.
+ 	 */
+ 	OSKIT_COMDECL_V	(*stop)(oskit_clicker_t *c);
+ };
+ 
+ extern const struct oskit_guid oskit_clicker_iid;
+ #define OSKIT_CLICKER_IID OSKIT_GUID(0x4aa7dff8, 0x7c74, 0x11cf, \
+                 0xb5, 0x00, 0x08, 0x00, 0x09, 0x53, 0xad, 0xc2)
+ 
+ #define oskit_clicker_query(c, iid, out_ihandle) \
+ 	((c)->ops->query((oskit_clicker_t *)(c), (iid), (out_ihandle)))
+ #define oskit_clicker_addref(c) \
+ 	((c)->ops->addref((oskit_clicker_t *)(c)))
+ #define oskit_clicker_release(c) \
+ 	((c)->ops->release((oskit_clicker_t *)(c)))
+ 
+ #define oskit_clicker_config(c, file) \
+ 	((c)->ops->config((oskit_clicker_t *)(c), (file)))
+ #define oskit_clicker_start(c) \
+ 	((c)->ops->start((oskit_clicker_t *)(c)))
+ #define oskit_clicker_stop(c) \
+ 	((c)->ops->stop((oskit_clicker_t *)(c)))
+ 
+ /*
+  * Create an instance of a click object. The object is pretty much useless
+  * until it is configured, and then started.
+  */
+ oskit_clicker_t *oskit_clicker_create(void);
+ 
+ #endif /* _CLICKCOM_H_ */
diff -Nr -c click-0.6/oskit/cutthrough.click click/oskit/cutthrough.click
*** click-0.6/oskit/cutthrough.click	Wed Dec 31 16:00:00 1969
--- click/oskit/cutthrough.click	Thu Dec 16 10:27:56 1999
***************
*** 0 ****
--- 1,23 ----
+ // A "cut through" configuration that passes packets in each direction
+ // rewriting the source and destination address according to our test
+ // network setup. Handy for testing an almost minimal Click configuration.
+ // 
+ //
+ // Utah test network setup:
+ //  maybe(de1) <--> (de1)quirky(de2) <--> (de1)flaky
+ //  maybe(185) <--> (190)quirky(198) <--> (193)flaky
+ //  maybe(00:00:c0:1f:65:e4) <-->
+ //       (00:00:c0:47:0c:9f)quirky(00:00:c0:26:65:e4) <-->
+ //       (00:00:c0:3f:65:e4)flaky
+ 
+ FromNetIO(1) ->
+ //	Print(1) ->
+ 	Strip(14) ->
+ 	EtherEncap(0x0800, 00:00:c0:26:65:e4, 00:00:c0:3f:65:e4) ->
+ 	ToNetIO(2)
+ 
+ FromNetIO(2) ->
+ //	Print(2) ->
+ 	Strip(14) ->
+ 	EtherEncap(0x0800, 00:00:c0:47:0c:9f, 00:00:c0:1f:65:e4) ->
+ 	ToNetIO(1)
diff -Nr -c click-0.6/oskit/example1.c click/oskit/example1.c
*** click-0.6/oskit/example1.c	Wed Dec 31 16:00:00 1969
--- click/oskit/example1.c	Thu Dec 16 10:30:49 1999
***************
*** 0 ****
--- 1,90 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * Trivial little test program demonstrating the use of a Click COM object
+  * within a single threaded OSKit kernel.
+  */
+ 
+ #include <stdio.h>
+ #include <oskit/dev/dev.h>
+ #include <oskit/startup.h>
+ #include <oskit/clientos.h>
+ #include "click_com.h"
+ 
+ oskit_clicker_t	       *clicker;
+ 	
+ int
+ main(int argc, char **argv)
+ {
+ 	void		handler(void);
+ 	
+ 	oskit_clientos_init();
+ 	start_clock();
+ #ifdef OSKIT_UNIX
+ 	start_fs_native(".");
+ #else
+ 	start_fs_bmod();
+ #endif
+ 	start_net_devices();
+ 
+ 	/*
+ 	 * Use a simple timer to stop after 30 seconds.
+ 	 */
+ 	osenv_timer_init();
+ 	osenv_timer_register(handler, 100);
+ 
+ 	/*
+ 	 * Okay, lets create a Click object.
+ 	 */
+ 	clicker = oskit_clicker_create();
+ 
+ 	/*
+ 	 * Give it a configuration file
+ 	 */
+ 	oskit_clicker_config(clicker, "ping.click");
+ 
+ 	/*
+ 	 * Lets Click.
+ 	 */
+ 	oskit_clicker_start(clicker);
+ 
+ 	/*
+ 	 * Kill the clicker
+ 	 */
+ 	oskit_clicker_release(clicker);
+ 
+ 	printf("exiting ...\n");
+ 	exit(0);
+ }
+ 
+ void
+ handler(void)
+ {
+ 	static count = 0, sec=0;
+ 	if (++count >= 100) {
+ 		count = 0;
+ 		if (++sec > 90) {
+ 			
+ 			/*
+ 			 * Stop the Clicker.
+ 			 */
+ 			printf("Stopping the Clicker(s)\n");
+ 			oskit_clicker_stop(clicker);
+ 		}
+ 	}
+ }
diff -Nr -c click-0.6/oskit/example2.c click/oskit/example2.c
*** click-0.6/oskit/example2.c	Wed Dec 31 16:00:00 1969
--- click/oskit/example2.c	Fri Dec 10 07:32:50 1999
***************
*** 0 ****
--- 1,109 ----
+ /*
+  * Copyright (c) 1999 University of Utah and the Flux Group.
+  * All rights reserved.
+  * 
+  * This file is part of the Flux OSKit.  The OSKit is free software, also known
+  * as "open source;" you can redistribute it and/or modify it under the terms
+  * of the GNU General Public License (GPL), version 2, as published by the Free
+  * Software Foundation (FSF).  To explore alternate licensing terms, contact
+  * the University of Utah at csl-dist at cs.utah.edu or +1-801-585-3271.
+  * 
+  * The OSKit 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 GPL for more details.  You should have
+  * received a copy of the GPL along with the OSKit; see the file COPYING.  If
+  * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+  */
+ 
+ /*
+  * Trivial little test program demonstrating the use of a Click COM object
+  * within a multithreaded OSKit kernel.
+  */
+ 
+ #include <stdio.h>
+ #include <oskit/dev/dev.h>
+ #include <oskit/startup.h>
+ #include <oskit/clientos.h>
+ #include <oskit/threads/pthread.h>
+ #include "click_com.h"
+ 
+ oskit_clicker_t	       *clicker;
+ pthread_t		clicker_tid;
+ 	
+ int
+ main(int argc, char **argv)
+ {
+ 	void		handler(void);
+ 	void	       *clicker_thread(void *);
+ 	void		*stat;
+ 	
+ 	oskit_clientos_init_pthreads();
+ 	start_clock();
+ 	start_pthreads();
+ #ifdef OSKIT_UNIX
+ 	start_fs_native(".");
+ #else
+ 	start_fs_bmod_pthreads();
+ #endif
+ 	start_net_devices();
+ 
+ 	/*
+ 	 * Use a simple timer to stop after 30 seconds.
+ 	 */
+ 	osenv_timer_init();
+ 	osenv_timer_register(handler, 100);
+ 
+ 	/*
+ 	 * Create a single thread and wait for it to finish.
+ 	 */
+ 	pthread_create(&clicker_tid, 0, clicker_thread, (void *) 0);
+ 	pthread_join(clicker_tid, &stat);
+ 
+ 	oskit_pthread_sleep((long long) 100);
+ 	printf("exiting ...\n");
+ 	exit(0);
+ }
+ 
+ void *
+ clicker_thread(void *arg)
+ {
+ 	int	me = (int) arg;
+ 
+ 	/*
+ 	 * Okay, lets create a Click object.
+ 	 */
+ 	clicker = oskit_clicker_create();
+ 
+ 	/*
+ 	 * Give it a configuration file
+ 	 */
+ 	oskit_clicker_config(clicker, "ping.click");
+ 
+ 	/*
+ 	 * Lets Click.
+ 	 */
+ 	oskit_clicker_start(clicker);
+ 
+ 	/*
+ 	 * Kill the clicker
+ 	 */
+ 	oskit_clicker_release(clicker);
+ }
+ 
+ void
+ handler(void)
+ {
+ 	static count = 0, sec=0;
+ 	if (++count >= 100) {
+ 		count = 0;
+ 		if (++sec > 30) {
+ 			printf("Stopping the Clicker(s)\n");
+ 			
+ 			/*
+ 			 * Stop the Clicker.
+ 			 */
+ 			oskit_clicker_stop(clicker);
+ 		}
+ 	}
+ }
+ 
diff -Nr -c click-0.6/oskit/iprouter.click click/oskit/iprouter.click
*** click-0.6/oskit/iprouter.click	Wed Dec 31 16:00:00 1969
--- click/oskit/iprouter.click	Thu Dec 16 08:05:19 1999
***************
*** 0 ****
--- 1,77 ----
+ // Generated by make-ip-conf.pl
+ // 1 155.99.213.190 00:00:c0:47:0c:9f
+ // 2 155.99.213.198 00:00:c0:26:65:e4
+ 
+ t :: Tee(2);
+ 
+ c0 :: Classifier(12/0806 20/0001,
+                   12/0806 20/0002,
+                   12/0800,
+                   -);
+ FromNetIO(1) -> [0]c0;
+ out0 :: Queue(200) -> ToNetIO(1);
+ arpq0 :: ARPQuerier(155.99.213.190, 00:00:c0:47:0c:9f);
+ c0 [1] -> t;
+ t[0] -> [1]arpq0;
+ arpq0 -> out0;
+ ar0 :: ARPResponder(155.99.213.190 255.255.255.255 00:00:c0:47:0c:9f);
+ c0 [0] -> ar0 -> out0;
+ 
+ c1 :: Classifier(12/0806 20/0001,
+                   12/0806 20/0002,
+                   12/0800,
+                   -);
+ FromNetIO(2) -> [0]c1;
+ out1 :: Queue(200) -> ToNetIO(2);
+ arpq1 :: ARPQuerier(155.99.213.198, 00:00:c0:26:65:e4);
+ c1 [1] -> t;
+ t[1] -> [1]arpq1;
+ arpq1 -> out1;
+ ar1 :: ARPResponder(155.99.213.198 255.255.255.255 00:00:c0:26:65:e4);
+ c1 [0] -> ar1 -> out1;
+ 
+ rt :: LookupIPRoute(
+  155.99.213.190 255.255.255.255 0.0.0.0 0,
+  155.99.213.191 255.255.255.255 0.0.0.0 0,
+  155.99.213.184 255.255.255.255 0.0.0.0 0,
+  155.99.213.198 255.255.255.255 0.0.0.0 0,
+  155.99.213.199 255.255.255.255 0.0.0.0 0,
+  155.99.213.192 255.255.255.255 0.0.0.0 0,
+  155.99.213.184 255.255.255.248 0.0.0.0 1,
+  155.99.213.192 255.255.255.248 0.0.0.0 2,
+  255.255.255.255 255.255.255.255 0.0.0.0 0,
+  0.0.0.0 255.255.255.255 0.0.0.0 0,
+  0.0.0.0 0.0.0.0 18.26.4.1 1);
+ 
+ rt[0] -> Print(rt[0]) -> Discard;
+ ip ::  Strip(14)
+     -> CheckIPHeader(155.99.213.191 155.99.213.199 )
+     -> GetIPAddress(16)
+     -> [0]rt;
+ c0 [2] -> Paint(1) -> ip;
+ c1 [2] -> Paint(2) -> ip;
+ 
+ rt[1] -> DropBroadcasts
+         -> cp0 :: CheckPaint(1)
+         -> gio0 :: IPGWOptions(155.99.213.190)
+         -> FixIPSrc(155.99.213.190)
+         -> dt0 :: DecIPTTL
+         -> fr0 :: IPFragmenter(1500)
+         -> [0]arpq0;
+ dt0 [1] -> ICMPError(155.99.213.190, 11, 0) -> [0]rt;
+ fr0 [1] -> ICMPError(155.99.213.190, 3, 4) -> [0]rt;
+ gio0 [1] -> ICMPError(155.99.213.190, 12, 1) -> [0]rt;
+ cp0 [1] -> ICMPError(155.99.213.190, 5, 1) -> [0]rt;
+ c0 [3] -> Print(xx0) -> Discard;
+ rt[2] -> DropBroadcasts
+         -> cp1 :: CheckPaint(2)
+         -> gio1 :: IPGWOptions(155.99.213.198)
+         -> FixIPSrc(155.99.213.198)
+         -> dt1 :: DecIPTTL
+         -> fr1 :: IPFragmenter(1500)
+         -> [0]arpq1;
+ dt1 [1] -> ICMPError(155.99.213.198, 11, 0) -> [0]rt;
+ fr1 [1] -> ICMPError(155.99.213.198, 3, 4) -> [0]rt;
+ gio1 [1] -> ICMPError(155.99.213.198, 12, 1) -> [0]rt;
+ cp1 [1] -> ICMPError(155.99.213.198, 5, 1) -> [0]rt;
+ c1 [3] -> Print(xx1) -> Discard;
diff -Nr -c click-0.6/oskit/make-ip-conf.pl click/oskit/make-ip-conf.pl
*** click-0.6/oskit/make-ip-conf.pl	Wed Dec 31 16:00:00 1969
--- click/oskit/make-ip-conf.pl	Thu Dec 16 08:15:28 1999
***************
*** 0 ****
--- 1,149 ----
+ #!/usr/local/bin/perl -w
+ 
+ # make-ip-conf.pl -- make a Click IP router configuration
+ # Robert Morris
+ #
+ # Copyright (c) 1999 Massachusetts Institute of Technology.
+ #
+ # This software is being provided by the copyright holders under the GNU
+ # General Public License, either version 2 or, at your discretion, any later
+ # version. For more information, see the `COPYRIGHT' file in the source
+ # distribution.
+ 
+ # Make a Click IP router configuration.
+ # The output is only useful with the Oskit.
+ 
+ # Change this array to suit your router.
+ # One line per network interface, containing:
+ #  The interface name,
+ #  The router's IP address on that interface,
+ #  The netmask on that interface, and
+ #  The router's Ethernet address on that interface.
+ 
+ #
+ # Utah test network setup:
+ #       maybe(de1) <--> (de1)quirky(de2) <--> (de1)flaky
+ #     	maybe(185) <--> (190)quirky(198) <--> (193)flaky
+ #
+ # This interface list describes quirky, but of course.
+ #
+ my $ifs = [
+             [ "1", "155.99.213.190", "255.255.255.248", "00:00:c0:47:0c:9f" ],
+             [ "2", "155.99.213.198", "255.255.255.248", "00:00:c0:26:65:e4" ],
+           ];
+ 
+ my $nifs = $#$ifs + 1;
+ 
+ print "// Generated by make-ip-conf.pl\n";
+ my $i;
+ for($i = 0; $i < $nifs; $i++){
+     printf("// %s %s %s\n",
+            $ifs->[$i]->[0],
+            $ifs->[$i]->[1],
+            $ifs->[$i]->[3]);
+ }
+ print "\n";
+ 
+ printf("t :: Tee(%d);\n", $nifs);
+ print "\n";
+ 
+ for($i = 0; $i < $nifs; $i++){
+     my $eth = $ifs->[$i]->[0];
+     my $ip = $ifs->[$i]->[1];
+     my $ena = $ifs->[$i]->[3];
+     my $paint = $i + 1;
+     print <<EOF
+ c$i :: Classifier(12/0806 20/0001,
+                   12/0806 20/0002,
+                   12/0800,
+                   -);
+ FromNetIO($eth) -> [0]c$i;
+ out$i :: Queue(200) -> ToNetIO($eth);
+ arpq$i :: ARPQuerier($ip, $ena);
+ c$i [1] -> t;
+ t[$i] -> [1]arpq$i;
+ arpq$i -> out$i;
+ ar$i :: ARPResponder($ip 255.255.255.255 $ena);
+ c$i [0] -> ar$i -> out$i;
+ 
+ EOF
+ }
+ 
+ my $ipharg = "";
+ for($i = 0; $i < $nifs; $i++){
+     my $ii = ip2i($ifs->[$i]->[1]);
+     my $mask = ip2i($ifs->[$i]->[2]);
+     $ipharg .= i2ip(($ii & $mask) | ~$mask) . " ";
+ }
+ 
+ print "rt :: LookupIPRoute(\n";
+ for($i = 0; $i < $nifs; $i++){
+     my $ii = ip2i($ifs->[$i]->[1]);
+     my $mask = ip2i($ifs->[$i]->[2]);
+     printf(" %s 255.255.255.255 0.0.0.0 0,\n", $ifs->[$i]->[1]);
+     printf(" %s 255.255.255.255 0.0.0.0 0,\n",
+            i2ip(($ii & $mask) | ~$mask));
+     printf(" %s 255.255.255.255 0.0.0.0 0,\n",
+            i2ip($ii & $mask));
+ }
+ for($i = 0; $i < $nifs; $i++){
+     my $ii = ip2i($ifs->[$i]->[1]);
+     my $mask = ip2i($ifs->[$i]->[2]);
+     printf(" %s %s 0.0.0.0 %d,\n",
+            i2ip($ii & $mask),
+            i2ip($mask),
+            $i + 1);
+ }
+ print " 255.255.255.255 255.255.255.255 0.0.0.0 0,\n";
+ print " 0.0.0.0 255.255.255.255 0.0.0.0 0,\n";
+ print " 0.0.0.0 0.0.0.0 18.26.4.1 1);\n"; # XXX
+ 
+ print <<EOF;
+ 
+ rt[0] -> Print(rt[0]) -> Discard;
+ ip ::  Strip(14)
+     -> CheckIPHeader($ipharg)
+     -> GetIPAddress(16)
+     -> [0]rt;
+ EOF
+ 
+ for($i = 0; $i < $nifs; $i++){
+   my $paint = $i + 1;
+   print "c$i [2] -> Paint($paint) -> ip;\n";
+ }
+ print "\n";
+ 
+ for($i = 0; $i < $nifs; $i++){
+     my $i1 = $i + 1;
+     my $ipa = $ifs->[$i]->[1];
+     print <<EOF;
+ rt[$i1] -> DropBroadcasts
+         -> cp$i :: CheckPaint($i1)
+         -> gio$i :: IPGWOptions($ipa)
+         -> FixIPSrc($ipa)
+         -> dt$i :: DecIPTTL
+         -> fr$i :: IPFragmenter(1500)
+         -> [0]arpq$i;
+ dt$i [1] -> ICMPError($ipa, 11, 0) -> [0]rt;
+ fr$i [1] -> ICMPError($ipa, 3, 4) -> [0]rt;
+ gio$i [1] -> ICMPError($ipa, 12, 1) -> [0]rt;
+ cp$i [1] -> ICMPError($ipa, 5, 1) -> [0]rt;
+ c$i [3] -> Print(xx$i) -> Discard;
+ EOF
+ }
+ 
+ sub ip2i {
+     my($ip) = @_;
+     my @a = split(/\./, $ip);
+     my $i = ($a[0] << 24) + ($a[1] << 16) + ($a[2] << 8) + $a[3];
+     return($i);
+ }
+ sub i2ip {
+     my($i) = @_;
+     my $a = ($i >> 24) & 0xff;
+     my $b = ($i >> 16) & 0xff;
+     my $c = ($i >> 8) & 0xff;
+     my $d = $i & 0xff;
+     return sprintf("%d.%d.%d.%d", $a, $b, $c, $d);
+ }
+ 
diff -Nr -c click-0.6/oskit/ping.click click/oskit/ping.click
*** click-0.6/oskit/ping.click	Wed Dec 31 16:00:00 1969
--- click/oskit/ping.click	Wed Dec 15 13:45:44 1999
***************
*** 0 ****
--- 1,18 ----
+ // ping.click
+ 
+ // Tests whether Click can read packets from the an Oskit netio, send
+ // them through the ICMPPing element, and back out through a netio.
+ 
+ // Basic Ping
+ // FromNetIO(0) ->
+ //	Print(ok) ->
+ //	ICMPPing() -> ToNetIO(0)
+ 
+ // If you want packet scheduling instead of responding from the bottom half
+ // (which is really an interrupt context in OSKit). The Queue causes packet
+ // processing to stop and schedule the PullToPush element to pick it up,
+ // and that is run out of the driver loop context not the interrupt context.
+ FromNetIO(0) ->
+ 	Queue(200) -> PullToPush() ->
+ 	Print(ok) ->
+ 	ICMPPing() -> ToNetIO(0);



More information about the click mailing list