diff --git a/Etherbunny.cabal b/Etherbunny.cabal
new file mode 100644
--- /dev/null
+++ b/Etherbunny.cabal
@@ -0,0 +1,18 @@
+Name:           Etherbunny
+Version:        0.2
+Author:         Nick Burlett
+Maintainer:     nickburlett@mac.com
+Description:    A network analysis toolkit for haskell, based on the Network.Pcap library. Currently not very useful, but getting there.
+Synopsis:       A network analysis toolkit for haskell
+License:        GPL
+License-file:   LICENSE
+Category:       Network
+Build-Depends:   
+        base, network, haskell98, pcap, binary
+Exposed-modules:
+        Network.Etherbunny.Packet, Network.Etherbunny.Ethernet, Network.Etherbunny.Ip, Network.Etherbunny.Tcp
+
+Executable:     etherbunny
+Main-Is:        etherbunny.hs
+Extra-libraries: 
+                pcap
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Network/Etherbunny/Ethernet.hs b/Network/Etherbunny/Ethernet.hs
new file mode 100644
--- /dev/null
+++ b/Network/Etherbunny/Ethernet.hs
@@ -0,0 +1,114 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Etherbunny.Ethernet
+-- Copyright   :  (c) Nicholas Burlett 2007
+-- License     :  GPL (see the file LICENSE)
+--
+-- Maintainer  :  nickburlett@mac.com
+-- Stability   :  experimental
+-- Portability :  ghc
+--
+-- Ethernet Packet access for Etherbunny.
+-- 
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -fglasgow-exts -funbox-strict-fields #-}
+
+module Network.Etherbunny.Ethernet (
+    -- * Types
+    MACAddr,
+    EthType,
+    EtherPkt,
+    
+    -- * Functions
+    getEtherPacket -- :: ByteString -> EthPkt
+) where
+    
+import Network.Etherbunny.Ip
+import Network.Etherbunny.Packet
+    
+import Data.Word
+import qualified Data.ByteString as B
+import Data.Binary.Get
+import Numeric
+import Bits
+
+-- |
+--   The MACAddr type gives a useful interface to MAC Addresses
+--
+
+newtype MACAddr = MACAddr Word64
+    deriving (Eq, Ord, Bits, Num, Integral, Enum, Real)
+
+instance Show MACAddr where
+    showsPrec _ (MACAddr m) = 
+        foldr (\i a -> showsHexByte (getWord m i)  ":" . a) (showsHexByte (getWord m 0)  "") $ [5,4..1]
+        where
+            getWord x i = (x `shiftR` (i*8)) .&. 0xff
+            showsHexByte x a = showString $ tail $ showHex (16^2+x) a
+
+macFromList :: [Word8] -> MACAddr
+macFromList  = wordsToInt 6 
+
+
+-- |
+--   The EthType type is designed to show the type of payload in an Ethernet packet
+--
+
+newtype EthType = EthType Word16
+    deriving (Num, Eq)
+
+instance Show EthType where
+    showsPrec _ (EthType e) =
+        showString $ tail $ showHex (16^4+ 0x0800) $ " " ++ etherTypeName e
+
+etherTypeName e 
+    | e == 0x0800   = "IP"
+    | otherwise     = "Unknown"
+
+ethTypeFromList :: [Word8] -> EthType
+ethTypeFromList [f, f2] = EthType $ (fromIntegral f) `shiftL` 8 .|. (fromIntegral f2) 
+
+
+data EtherPayload = IPPkt IPPkt
+    deriving (Show)
+
+-- | 
+--   The EthPkt type defines an Ethernet II packet with another Packet payload
+--
+
+data EtherPkt = EtherPkt { 
+                 ethDestination :: !MACAddr,    -- ^ destination MAC address
+                 ethSource      :: !MACAddr,    -- ^ source MAC address
+                 ethType        :: !EthType,    -- ^ payload type
+                 ethPayload     :: !(Maybe EtherPayload),      -- ^ payload
+                 ethRemainder   :: !([Word8])     -- ^ anything remaining
+               }
+
+instance Show EtherPkt where
+   showsPrec p pkt = 
+       showString "Ethernet II dest: " . showsPrec p (ethDestination pkt)
+           . showString " src: " . showsPrec p (ethSource pkt)
+           . showString " type: " . showsPrec p (ethType pkt)
+           . showsPrec p (ethPayload pkt)
+           . showsPrec p (ethRemainder pkt)
+
+getMacAddress = do
+    mac <- getByteString 6 
+    return $ macFromList $ B.unpackList mac
+
+getEtherPacket :: Get EtherPkt
+getEtherPacket = do
+    dst <- getMacAddress
+    src <- getMacAddress
+    typ <- getWord16be
+    payload <- do 
+        case typ of
+            0x0800    -> do 
+                payload <- getIPPacket
+                return $ Just $ IPPkt payload
+            otherwise -> undefined
+    numRemain <- remaining
+    remaining <- getByteString $ fromIntegral numRemain
+    return $ EtherPkt dst src (EthType typ) payload (B.unpack remaining)
+    
diff --git a/Network/Etherbunny/Ip.hs b/Network/Etherbunny/Ip.hs
new file mode 100644
--- /dev/null
+++ b/Network/Etherbunny/Ip.hs
@@ -0,0 +1,186 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Etherbunny.Ip
+-- Copyright   :  (c) Nicholas Burlett 2007
+-- License     :  GPL (see the file LICENSE)
+--
+-- Maintainer  :  nickburlett@mac.com
+-- Stability   :  experimental
+-- Portability :  ghc
+--
+-- IP Packet access for Etherbunny.
+--
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -fglasgow-exts -funbox-strict-fields #-}
+
+module Network.Etherbunny.Ip (
+    -- * Types
+    IPPkt,
+    IPVerIHL,
+    
+    -- * Functions
+    getIPPacket,
+) where
+    
+import Network.Etherbunny.Packet
+import Network.Etherbunny.Tcp
+    
+import Data.Word
+import Numeric
+import Bits
+import Network.Socket (HostAddress) 
+import Data.Binary.Get
+import qualified Data.ByteString as B
+
+    
+-- |
+--   Represents both the IP version and IP Header Length as a single Word8
+--
+
+newtype IPVerIHL = IPVerIHL Word8
+    deriving (Eq, Ord, Bits, Num, Integral, Enum, Real, Show)
+
+-- |
+--   Get the IP Version
+-- 
+
+ipVersion (IPVerIHL v) = v `shiftR` 4
+
+-- |
+--   Get the IP Header Length
+-- 
+
+ipHeaderLength (IPVerIHL v) = v .&. 0x0f
+   
+   
+
+-- |
+--   Represents both the IP flags and IP fragment version a single Word8
+--
+
+newtype IPFlagsFragment = IPFlagsFragment Word16
+    deriving (Eq, Ord, Bits, Num, Integral, Enum, Real, Show)
+
+-- |
+--   Get the IP Version
+-- 
+
+ipFlags (IPFlagsFragment v) = v `shiftR` 13
+
+-- |
+--   Get the IP Header Length
+-- 
+
+ipFragmentOffset (IPFlagsFragment v) = v .&. 0x1fffffff   
+    
+ 
+-- |
+--   The protocol for the data in an IP packet
+--
+
+newtype IPProtocol = IPProtocol Word8
+    deriving (Eq, Ord, Bits, Num, Integral, Enum, Real, Show)
+    
+ipProtocolFromList = wordsToWord16
+ 
+    
+-- |
+--   The Type of Service
+--
+
+newtype IPTOS = IPTOS Word8
+    deriving (Eq, Ord, Bits, Num, Integral, Enum, Real, Show)
+
+ipTosFromList = wordsToWord32
+    
+
+-- |
+--  The IPPayload type is used to store each of the possible payload 
+--  that etherbunny knows about
+--    
+    
+data IPPayload = Foo
+    
+-- |
+--   The IPPkt type gives an interface to Internet Protocol packets
+--
+
+data IPPkt = IPPkt { 
+         ipVerIHL           :: !IPVerIHL,   -- ^ version and header length
+         ipTOS              :: !IPTOS,      -- ^ type of service
+         ipTotalLength      :: !Word16,     -- ^ total length of the datagram
+         ipIdentification   :: !Word16,     -- ^ identification for all fragments of this datagram
+         ipFlagsFragment    :: !IPFlagsFragment, -- ^ both the flags and the fragment offset
+         ipTTL              :: !Word8,      -- ^ time to live
+         ipProtocol         :: !IPProtocol, -- ^ protocol 
+         ipHeaderChecksum   :: !Word16,     -- ^ checksum of the header and options
+         ipSource           :: !HostAddress, -- ^ source address
+         ipDestination      :: !HostAddress, -- ^ destination address
+         ipOptions          :: ![Word8],     -- ^ options
+         ipPayload          :: !(Maybe TCPPkt)      -- ^ payload
+       }
+
+-- |
+--  Show ip addresses in a nicer format
+--
+showsIP m = 
+    foldr (\i a -> shows (getWord m i) . showString "." . a) (shows (getWord m 0) ) $ [3,2,1]
+    where
+        getWord x i = (x `shiftR` (i*8)) .&. 0xff
+        showsHexByte x a = showString $ tail $ showHex (16^2+x) a
+
+       
+instance Show IPPkt where
+  showsPrec p pkt = 
+            showString "\n  IP: Ip Version " . showsPrec p (ipVersion $ ipVerIHL pkt)
+          . showString "\n      Header length " . showsPrec p (ipHeaderLength $ ipVerIHL pkt)
+          . showString "\n      TOS: " . showsPrec p (ipTOS pkt)
+          . showString "\n      totalLength: " . showsPrec p (ipTotalLength pkt)
+          . showString "\n      Frag Ident: " . showsPrec p (ipIdentification pkt)
+          . showString "\n      flags/fragment offset: " . showsPrec p (ipFlagsFragment pkt)
+          . showString "\n      TTL: " . showsPrec p (ipTTL pkt)
+          . showString "\n      Protocol: " . showsPrec p (ipProtocol pkt)
+          . showString "\n      Header Checksum: " . showHex (ipHeaderChecksum pkt)
+          . showString "\n      Source: " . showsIP (ipSource pkt)
+          . showString "\n      Destination: " . showsIP (ipDestination pkt)
+          . showString "\n      Options: " . showsPrec p (ipOptions pkt)
+          . showString "\n      Payload: " . showsPrec p (ipPayload pkt)
+          . showString "\n"
+       
+
+getIPPacket :: Get IPPkt
+getIPPacket = do
+    verihl  <- getWord8
+    iptos   <- getWord8
+    tlength <- getWord16be
+    ident   <- getWord16be
+    flgfrag <- getWord16be
+    ttl     <- getWord8
+    ipprot  <- getWord8
+    hdrcksm <- getWord16be
+    srcip   <- getWord32be
+    dstip   <- getWord32be
+    let hl = ipHeaderLength $ IPVerIHL verihl
+    options <- getByteString $ fromIntegral $ hl - 5
+    payload <- case ipprot of
+        6 -> do 
+            let tcplen = fromIntegral $  tlength - (fromIntegral (hl*4))
+            tcp <- getTCPPacket tcplen srcip dstip
+            return $ Just tcp
+        otherwise -> do 
+            skip $ (fromIntegral $ tlength - (fromIntegral hl)*4)
+            return Nothing
+    return $ IPPkt
+        (IPVerIHL verihl)
+        (IPTOS iptos)
+        tlength
+        ident
+        (IPFlagsFragment flgfrag)
+        ttl
+        (IPProtocol ipprot)
+        hdrcksm
+        srcip
+        dstip
+        (B.unpack options)
+        payload
diff --git a/Network/Etherbunny/Packet.hs b/Network/Etherbunny/Packet.hs
new file mode 100644
--- /dev/null
+++ b/Network/Etherbunny/Packet.hs
@@ -0,0 +1,48 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Etherbunny.Packet
+-- Copyright   :  (c) Nicholas Burlett 2007
+-- License     :  GPL (see the file LICENSE)
+--
+-- Maintainer  :  nickburlett@mac.com
+-- Stability   :  experimental
+-- Portability :  ghc
+--
+-- General Packet support Etherbunny.
+--
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -fglasgow-exts -funbox-strict-fields #-}
+
+module Network.Etherbunny.Packet (
+    -- * Type Classes
+    Pkt,
+    
+    -- * Utility functions
+    wordsToInt,
+    wordsToWord16,
+    wordsToWord32
+) where
+
+import Data.Word
+import Bits
+
+wordsToInt :: Bits a => Int -> [Word8] -> a
+wordsToInt i l = 
+    let z5 = reverse [0..i-1] 
+        shifted = zipWith (\ b c -> (fromIntegral c) `shiftL`  (b * 8) ) z5 l
+    in
+        foldr1 (.|.) shifted
+
+wordsToWord16 :: [Word8] -> Word16
+wordsToWord16 = wordsToInt 2
+
+wordsToWord32 :: [Word8] -> Word32
+wordsToWord32 = wordsToInt 4
+
+    
+class Pkt a where
+    headerLength :: a -> Int
+
+instance Pkt Int where
+    headerLength = const 0
diff --git a/Network/Etherbunny/Tcp.hs b/Network/Etherbunny/Tcp.hs
new file mode 100644
--- /dev/null
+++ b/Network/Etherbunny/Tcp.hs
@@ -0,0 +1,151 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Etherbunny.Tcp
+-- Copyright   :  (c) Nicholas Burlett 2007
+-- License     :  GPL (see the file LICENSE)
+--
+-- Maintainer  :  nickburlett@mac.com
+-- Stability   :  experimental
+-- Portability :  ghc
+--
+-- TCP Packet access for Etherbunny.
+--
+-----------------------------------------------------------------------------
+
+{-# OPTIONS_GHC -fglasgow-exts -funbox-strict-fields #-}
+
+module Network.Etherbunny.Tcp (
+    -- * Types
+    TCPPkt,
+    
+    -- * Functions
+    getTCPPacket,
+) where
+    
+import Network.Etherbunny.Packet
+    
+import Data.Word
+import Numeric
+import Bits
+import Network (PortNumber) 
+import Data.Binary.Get
+import qualified Data.ByteString as B
+
+    
+-- |
+--   Represents the Data Offset, ECN, and Control Bits
+--
+
+newtype TCPDOECNCB = TCPDOECNCB Word16
+    deriving (Eq, Ord, Bits, Num, Integral, Enum, Real, Show)
+
+-- |
+--   Get the Data Offset
+-- 
+
+tcpDataOffset (TCPDOECNCB v) = v `shiftR` 12
+
+-- |
+--   Get the TCP ECN
+-- 
+
+tcpECN (TCPDOECNCB v) = (v `shiftR` 6) .&. 0x0f
+   
+  
+-- |
+--   Get the TCP Control Bits
+-- 
+
+tcpControlBits (TCPDOECNCB v) = v .&. 0x2f
+ 
+ 
+-- |
+--   Compute a TCP checksum, given a starting sum value
+--
+
+checksum :: Word16 -> B.ByteString -> Word16
+checksum c b = fromIntegral $ (cb .&. 0xFFFF) + (cb `shiftR` 16) where
+    cb = checksum' (fromIntegral c) 0 b 
+    checksum' :: Word32 -> Int -> B.ByteString -> Word32
+    checksum' c r b = if r >= B.length b
+        then fromIntegral c
+        else
+            if r == (B.length b) -1
+                then c + (fromIntegral (B.index b r) `shiftL` 8)
+                else let h = (fromIntegral $ B.index b r) :: Word32
+                         l = (fromIntegral $ B.index b $ r+1) :: Word32
+                         s = (h `shiftL` 8 .|. l) + c
+                     in checksum' s (r+2) b
+ 
+
+data TCPPayload = Foo
+    
+-- |
+--   The IPPkt type gives an interface to Internet Protocol packets
+--
+
+data TCPPkt = TCPPkt { 
+         tcpSourcePort      :: !Word16, -- ^ version and header length
+         tcpDestinationPort :: !Word16, -- ^ type of service
+         tcpSequenceNumber  :: !Word32,     -- ^ total length of the datagram
+         tcpAcknowledgement :: !Word32,     -- ^ identification for all fragments of this datagram
+         tcpDOECNCB         :: !TCPDOECNCB, -- ^ Data Offset, ECN, Control Bits
+         tcpWindow          :: !Word16,     -- ^ time to live
+         tcpChecksum        :: !Word16,     -- ^ checksum of the header and options 
+         tcpChecksumCorrect :: !Bool,       -- ^ true if the checksum is correct
+         tcpUrgentPointer   :: !Word16,     -- ^ pointer to the end seq of urgent data
+         tcpOptions         :: ![Word8],    -- ^ tcp options
+         tcpPayload         :: !(Maybe TCPPayload)      -- ^ payload
+       }
+
+       
+instance Show TCPPkt where
+  showsPrec p pkt = 
+            showString "\n  TCP: Source Port " . showsPrec p (tcpSourcePort pkt)
+          . showString "\n       Destination Port " . showsPrec p (tcpDestinationPort pkt)
+          . showString "\n       Sequence Number: " . showsPrec p (tcpSequenceNumber pkt)
+          . showString "\n       Ack Number: " . showsPrec p (tcpAcknowledgement pkt)
+          . showString "\n       Data Offset: " . showsPrec p (tcpDataOffset $ tcpDOECNCB pkt)
+          . showString "\n       ECN: " . showsPrec p (tcpECN $ tcpDOECNCB pkt)
+          . showString "\n       Control Bits: " . showsPrec p (tcpControlBits $ tcpDOECNCB pkt)
+          . showString "\n       Window: " . showsPrec p (tcpWindow pkt)
+          . showString "\n       Checksum: " . showHex (tcpChecksum pkt)
+                              . showString " correct? " . showsPrec p (tcpChecksumCorrect pkt)
+          . showString "\n       Urgent Pointer: " . showsPrec p (tcpUrgentPointer pkt)
+          . showString "\n       Options: " . showsPrec p (tcpOptions pkt)
+          -- . showString "\n       Payload: " . showsPrec p (ipPayload pkt)
+       
+
+getTCPPacket :: Int -> Word32 -> Word32 -> Get TCPPkt
+getTCPPacket len srcip dstip = do
+    r <- remaining 
+    fullBytes <- lookAhead $ getByteString $ fromIntegral r
+    let headersum = srcip + dstip + (fromIntegral len) + 6
+    let headersum16 = (headersum .&. 0xFFFF) + (headersum `shiftR` 16)
+    let headersum16' = fromIntegral $ (headersum16 .&. 0xFFFF) + (headersum16 `shiftR` 16)
+    let computedChecksum = checksum headersum16' fullBytes
+    sp <- getWord16be
+    dp <- getWord16be
+    seqnum <- getWord32be
+    ack <- getWord32be
+    doecncb <- getWord16be
+    window <- getWord16be
+    cksum <- getWord16be
+    urg <- getWord16be
+    let doffset = fromIntegral $ tcpDataOffset $ TCPDOECNCB doecncb
+    let optlength = (doffset*4) - 20
+    opt <- getByteString optlength
+    skip $ len - (doffset*4)
+    return $ TCPPkt
+        sp
+        dp
+        seqnum
+        ack
+        (TCPDOECNCB doecncb)
+        window
+        cksum
+        (computedChecksum == 0xffff)
+        urg
+        (B.unpack opt)
+        (Nothing)
+        
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/etherbunny.hs b/etherbunny.hs
new file mode 100644
--- /dev/null
+++ b/etherbunny.hs
@@ -0,0 +1,110 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Etherbunny.Ethernet
+-- Copyright   :  (c) Nicholas Burlett 2007
+-- License     :  GPL (see the file LICENSE)
+--
+-- Maintainer  :  nickburlett@mac.com
+-- Stability   :  experimental
+-- Portability :  ghc
+--
+-- Example program for using etherbunny.
+-- 
+-----------------------------------------------------------------------------
+
+
+{-# OPTIONS_GHC -fglasgow-exts -funbox-strict-fields #-}
+
+module Main where
+
+import Network.Etherbunny.Ethernet
+import Network.Etherbunny.Packet
+
+import Network.Pcap
+
+import Foreign
+import Data.Word
+import qualified Data.ByteString as B8
+import qualified Data.ByteString.Lazy as B8L
+import Data.Binary.Get
+import System.IO.Unsafe
+import Monad
+import System.Console.GetOpt
+import Data.Maybe ( fromMaybe )
+import System.Environment(getArgs)
+import List 
+import IO 
+
+version = "0.2"
+
+main = do
+    argv <- getArgs
+    (o,_) <- etherbunnyOpts argv 
+    print o
+    hSetBuffering stdout NoBuffering
+    p <- openFromOptions o
+    withForeignPtr p $ \ptr -> do
+        pkts <- packets ptr
+        let pkts' = map process pkts
+        mapM print pkts'
+    return ()
+        
+packets p = do
+    (ph, bytep) <- next p
+    if bytep == nullPtr
+        then return []
+        else do rest <- (unsafeInterleaveIO $ packets p)
+                return $ (ph, bytep) : rest
+    
+process (ph, bytep) = runGet getEtherPacket $ B8L.fromChunks [a]
+    where a = B8.packCStringLen (castPtr bytep, fromIntegral (caplen ph))
+
+data Flag 
+    = Version | InputFile String | InputDevice String 
+      deriving Show
+
+openFromOptions o = do
+    let f = find isInputFile o `mplus` find isInputDevice o
+    case f of
+        Just (InputFile fname)   -> openOffline fname
+        Just (InputDevice iname) -> openLive iname 1 False 10000
+        otherwise -> ioError $ userError $ "unexpected argument error in otherwise case of openFromOptions"
+
+isInputFile (InputFile _) = True
+isInputFile _ = False
+
+isInputDevice (InputDevice _) = True
+isInputDevice _ = False
+
+infile :: Maybe String -> Flag
+infile  = InputFile . fromMaybe "-"
+
+indev :: Maybe String -> Flag
+indev = InputDevice . fromMaybe ""
+
+options :: [OptDescr Flag]
+options =
+    [ Option ['V','?'] ["version"] (NoArg Version)            "show version number"
+    , Option ['r']     ["file"]    (OptArg infile "FILE")     "read packets from FILE"
+    , Option ['i']     ["device"]  (OptArg indev "INTERFACE") "read packets from INTERFACE"
+    ]
+    
+
+etherbunnyOpts :: [String] -> IO ([Flag], [String])
+etherbunnyOpts argv = 
+   case getOpt Permute options argv of
+      (o,n,[]  ) -> case checkOptions o of 
+                        [] -> return (o,n)
+                        errs  -> ioError $ userError $ concat errs ++ usageInfo header options
+      (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options))
+  where header = "Usage: etherbunny [OPTION...]"
+
+checkOptions :: [Flag] -> [String]
+checkOptions opts = 
+    let hasFile = any isInputFile opts
+        hasDevice = any isInputDevice opts
+    in case (hasDevice, hasFile) of 
+        (True, True) -> ["Must specify only one Interface or File"]
+        (False, False) -> ["Must specify an Interface or File"]
+        otherwise -> []
+        
