{-# INCLUDE <pcap.h> #-}
{-# INCLUDE <pcap-bpf.h> #-}
{-# INCLUDE <netinet/in.h> #-}
{-# INCLUDE <sys/socket.h> #-}
{-# INCLUDE "config.h" #-}
{-# LINE 1 "Network/Pcap.hsc" #-}
------------------------------------------------------------------------------
{-# LINE 2 "Network/Pcap.hsc" #-}
-- |
--  Module	: Network.Pcap
--  Copyright	: (c) Antiope Associates LLC 2004
--  License	: BSD-style (see the file libraries/network/license)
--
--  Maintainer	: nickburlett@mac.com, dominic.steinitz@blueyonder.co.uk 
--  Stability	: experimental
--  Portability	: non-portable
--
--  The "Pcap" modules is a binding to all of the functions in
--  libpcap (See <http://www.tcpdump.org> for more information.)
--
--  Only a minimum of mashalling is done; for light duty applications,
--  the user can extract the length of the captured buffer
--  from the packet header record and use 'peekArray' to convert the
--  captured data to a list. For illustration:
--
-- >	import Pcap
-- >	import Foreign
-- >
-- >	main = do
-- >		let
-- >			printIt :: PktHdr -> Ptr Word8 -> IO ()
-- >			printIt ph bytep = do
-- >	        		a <- peekArray (fromIntegral (caplen ph)) bytep 
-- >	       			print a
-- >
-- >	        p <- openLive "em0" 100 True 10000
-- >	        s <- withForeignPtr p $ \ptr -> do
-- >	                dispatch ptr (-1) printIt
-- >	        return ()
-- >
--
--  Users requiring higher perfomance (such as O(1) access to any byte
--  in a packet) should roll their own marshalling functions.
--
--  Note that the SockAddr exported here is not the SockAddr from
--  Network.Socket. The SockAddr from Network.Socket corresponds to
--  @struct sockaddr_in@ in BSD terminology. The SockAddr record here
--  is BDS's @struct sockaddr@. See W.R.Stevens, TCP Illustrated, volume 2,
--  for further eluciadation.
--
--  This binding should be portable for systems that can use the libpcap
--  from tcpdump.org. It will not work with Winpcap, a similar library
--  for Windows, although adapting it should not prove difficult.
--
------------------------------------------------------------------------------


module Network.Pcap (

	-- * Types
	Pcap,
	Pdump,
	BpfProgram,
	Callback,
	Link(..),
	Interface(..),
	PcapAddr(..),
	SockAddr(..),
	Network(..),
	PktHdr(..),
	Statistics(..),

	-- * Device opening
	openOffline,		-- :: String -> IO Pcap
	openLive,		-- :: String -> Int -> Bool -> Int -> IO Pcap
	openDead,		-- :: Int    -> Int -> IO Pcap
	openDump,		-- :: Ptr PcapTag -> String -> IO Pdump

	-- * Filter handling
	setFilter,		-- :: Ptr PcapTag -> String -> Bool -> Word32 -> IO ()
	compileFilter,		-- :: Int -> Int  -> String -> Bool -> Word32 -> IO BpfProgram

	-- * Device utilities
	lookupDev,		-- :: IO String
	findAllDevs,		-- :: IO [Interface]
	lookupNet,		-- :: String -> IO Network

	-- * Interface control
	-- ** Blocking mode
	setNonBlock,		-- :: Ptr PcapTag -> Bool -> IO ()
	getNonBlock,		-- :: Ptr PcapTag -> IO Bool

	-- ** Link layer utilities
	datalink,		-- :: Ptr PcapTag -> IO Link
	setDatalink,		-- :: Ptr PcapTag -> Link -> IO ()
	listDatalinks,		-- :: Ptr PcapTag -> IO [Link]

	-- * Packet processing
	dispatch,		-- :: Ptr PcapTag -> Int -> Callback -> IO Int
	loop,			-- :: Ptr PcapTag -> Int -> Callback -> IO Int
	next,			-- :: Ptr PcapTag -> IO (PktHdr, Ptr Word8)
	dump,			-- :: Ptr PcapDumpTag -> Ptr PktHdr -> Ptr Word8 -> IO ()

	-- * Miscellaneous
	statistics,		-- :: Ptr PcapTag -> IO Statistics
	majorVersion,		-- :: Ptr PcapTag -> IO Int
	minorVersion,		-- :: Ptr PcapTag -> IO Int
	isSwapped,		-- :: Ptr PcapTag -> IO Bool
	snapshotLen,		-- :: Ptr PcapTag -> IO Int
) where

import Maybe (isNothing, fromJust  )
import Data.Word ( Word8, Word32 )
import Foreign.Ptr ( Ptr, plusPtr, nullPtr, FunPtr, freeHaskellFunPtr )
import Foreign.C.String ( peekCString, withCString )
import Foreign.C.Types ( CInt, CUInt, CChar, CUChar, CLong )
import Foreign.ForeignPtr ( ForeignPtr, FinalizerPtr, newForeignPtr )
import Foreign.Marshal.Alloc ( alloca, allocaBytes, free )
import Foreign.Marshal.Array ( allocaArray, peekArray )
import Foreign.Marshal.Utils ( fromBool, toBool )
import Foreign.Storable ( Storable(..) )
import Network.Socket ( Family(..), unpackFamily)
import System.IO.Error ( userError )


{-# LINE 119 "Network/Pcap.hsc" #-}

{-# LINE 120 "Network/Pcap.hsc" #-}

{-# LINE 121 "Network/Pcap.hsc" #-}

{-# LINE 122 "Network/Pcap.hsc" #-}


{-# LINE 124 "Network/Pcap.hsc" #-}


data BpfProgramTag
-- | Compiled Berkeley Packet Filter program
type BpfProgram = ForeignPtr BpfProgramTag

data PcapTag
-- | packet capture descriptor
type Pcap  = ForeignPtr PcapTag

data PcapDumpTag
-- | savefile descriptor
type Pdump = ForeignPtr PcapDumpTag

data PktHdr    = PktHdr    { sec    :: Word32,	-- ^ timestamp (seconds)
			     usec   :: Word32,	-- ^ timestamp (microseconds)
			     caplen :: Word32,	-- ^ number of bytes present in capture
			     len    :: Word32 	-- ^ number of bytes on the wire
			   }
		deriving (Show)

data Statistics = Statistics { recv   :: Word32,	-- ^ packets received
			       drop   :: Word32,	-- ^ packets dropped by libpcap
			       ifdrop :: Word32		-- ^ packets dropped by the interface
			     }
		deriving (Show)


--
-- Data types for interface list
--

-- | The interface structure
data Interface = Interface { ifName        :: String,		-- ^ the interface name
                             ifDescription :: String,		-- ^ interface description string (if any)
                             ifAddresses   :: [PcapAddr],	-- ^ address families supported by this interface
                             ifFlags       :: Word32
                           }
		deriving (Read, Show)

-- | The address structure
data PcapAddr = PcapAddr { ifAddr  :: SockAddr,		-- ^ interface address
                           ifMask  :: Maybe SockAddr,	-- ^ network mask
                           ifBcast :: Maybe SockAddr,	-- ^ broadcast address
                           ifPeer  :: Maybe SockAddr	-- ^ address of peer, of a point-to-point link
                         }
		deriving (Read, Show)

-- |
--   The socket address record. Note that this is not the same as
--   SockAddr from Network.Sockets. (That is a Haskell version of
--   struct sockaddr_in. This is the real struct sockaddr from the BSD
--   network stack.)
--
data SockAddr = SockAddr { sockAddrFamily  :: Family,	-- ^ an address family exported by Network.Socket
			   sockAddrAddr    :: [Word8]
			 }
		deriving (Read, Show)

-- | The network address record. Both the address and mask are in
--   network byte order.
data Network = Network { netAddr :: Word32,	-- ^ IPv4 network address
			 netMask :: Word32	-- ^ IPv4 netmask
		       }
		deriving (Read, Show)


--
-- Open a device
--

-- |
--   openOffline opens a \"savefile\" for reading. The file foramt is the
--   as used for tcpdump. The string \"-\" is a synonym for stdin.
--
openOffline
	:: String	-- ^ filename
	-> IO Pcap
openOffline name =
        withCString name                      $ \namePtr ->
        allocaArray (256) $ \errPtr  -> do
{-# LINE 205 "Network/Pcap.hsc" #-}
                ptr <- pcap_open_offline namePtr errPtr
                if ptr == nullPtr
                        then peekCString errPtr >>= ioError . userError
                        else do
                                final <- h2c pcap_close
                                newForeignPtr final ptr

-- |
--  openLive is used to get a packet descriptor that can be used to
--  look at packates on the network. The arguments are the device name,
--  the snapshot legnth (in bytes), the promiscuity of the interface
--  (True == promiscuous) and a timeout in milliseconds.
--
--  Using \"any\" as the device name will capture packets from all interfaces.
--  On some systems, reading from the \"any\" device is incompatible with
--  setting the interfaces into promiscuous mode. In that case, only packets
--  whose link layer addresses match those of the interfaces are captured.
--
openLive
	:: String	-- ^ device name
	-> Int		-- ^ snapshot length
	-> Bool		-- ^ set to promiscuous mode?
	-> Int		-- ^ timeout in milliseconds
	-> IO Pcap
openLive name snaplen promisc timeout =
        withCString name                      $ \namePtr ->
        allocaArray (256) $ \errPtr  -> do
{-# LINE 232 "Network/Pcap.hsc" #-}
                ptr <- pcap_open_live namePtr
				      (fromIntegral snaplen)
				      (fromBool promisc)
				      (fromIntegral timeout)
				      errPtr
                if ptr == nullPtr
                        then peekCString errPtr >>= ioError . userError
                        else do
                                final <- h2c pcap_close
                                newForeignPtr final ptr

-- |
--   openDead is used to get a packet capture descriptor without opening
--   a file or device. It is typically used to test packet filter compilation
--   by setFilter. The arguments are the linktype and the snapshot length.
--
openDead
	:: Link		-- ^ datalink type
	-> Int		-- ^ snapshot length
	-> IO Pcap	-- ^ packet capture descriptor
openDead link snaplen = 
        do
                ptr <- pcap_open_dead (packLink link)
				      (fromIntegral snaplen)
                if ptr == nullPtr
                        then ioError $ userError "Can't open dead pcap device"
                        else do
                                final <- h2c pcap_close
                                newForeignPtr final ptr


foreign import ccall unsafe pcap_open_offline :: Ptr CChar   -> Ptr CChar -> IO (Ptr PcapTag)
foreign import ccall unsafe pcap_close        :: Ptr PcapTag -> IO ()
foreign import ccall unsafe pcap_open_live    :: Ptr CChar -> CInt -> CInt -> CInt -> Ptr CChar -> IO (Ptr PcapTag)
foreign import ccall unsafe pcap_open_dead    :: CInt -> CInt -> IO (Ptr PcapTag)

foreign import ccall "wrapper" h2c            :: (Ptr PcapTag -> IO()) -> IO (FinalizerPtr a)



--
-- Open a dump device
--

-- |
--   openDump opens a \"savefile\" for writing. This savefile is written to
--   by the dump function. The arguments are a raw packet capture descriptor
--   and the filename, with \"-\" as a synonym for stdout.
--
openDump
	:: Ptr PcapTag	-- ^ packet capture descriptor
	-> String	-- ^ savefile name
	-> IO Pdump	-- ^ davefile descriptor
openDump hdl name =
        withCString name $ \namePtr -> do
                ptr <- pcap_dump_open hdl namePtr
		if (ptr == nullPtr) then
			throwPcapError hdl
		    else do
			final <- h2c' pcap_dump_close
			newForeignPtr final ptr

foreign import ccall unsafe pcap_dump_open  :: Ptr PcapTag -> Ptr CChar -> IO (Ptr PcapDumpTag)
foreign import ccall unsafe pcap_dump_close :: Ptr PcapDumpTag -> IO ()

foreign import ccall "wrapper" h2c'         :: (Ptr PcapDumpTag -> IO()) -> IO (FinalizerPtr a)


--
-- Set the filter
--

-- |
--   Set a filter on the specified packet capture descriptor. Valid filter
--   strings are those accepted by tcpdump.
--
setFilter
	:: Ptr PcapTag	-- ^ packet capture descriptor
	-> String	-- ^ filter string
	-> Bool		-- ^ optimize?
	-> Word32	-- ^ IPv4 network mask
	-> IO ()
setFilter hdl filt opt mask =
        withCString filt $ \filter -> do
		allocaBytes ((8)) $ \bpfp -> do
{-# LINE 317 "Network/Pcap.hsc" #-}
			ret <- pcap_compile hdl
					    bpfp
					    filter
					    (fromBool opt)
					    (fromIntegral mask)
			if ret == (-1) then
				throwPcapError hdl
		    	    else do
				ret <- pcap_setfilter hdl bpfp
				if ret == (-1) then
					throwPcapError hdl
			 	  else
					pcap_freecode bpfp

-- |
--   Compile a filter for use by another program using the Berkeley Packet
--   Filter library.
--
compileFilter
	:: Int		-- ^ snapshot length
	-> Link		-- ^ datalink type
	-> String	-- ^ filter string
	-> Bool		-- ^ optimize?
	-> Word32	-- ^ IPv4 network mask
	-> IO BpfProgram
compileFilter snaplen link filt opt mask =
	withCString filt $ \filter ->
		allocaBytes ((8)) $ \bpfp -> do
{-# LINE 345 "Network/Pcap.hsc" #-}
			ret  <- pcap_compile_nopcap (fromIntegral snaplen)
				 		    (packLink link)
						    bpfp
				        	    filter
						    (fromBool opt)
						    (fromIntegral mask)
			if ret == (-1) then
				ioError $ userError "Pcap.compileFilter error"
		 	   else do
                         	final <- h2c'' pcap_freecode
                         	newForeignPtr final bpfp
	

foreign import ccall pcap_compile
	:: Ptr PcapTag  -> Ptr BpfProgramTag -> Ptr CChar -> CInt -> CInt -> IO CInt
foreign import ccall pcap_compile_nopcap
        :: CInt -> CInt -> Ptr BpfProgramTag -> Ptr CChar -> CInt -> CInt -> IO CInt
foreign import ccall pcap_setfilter
	:: Ptr PcapTag  -> Ptr BpfProgramTag -> IO CInt
foreign import ccall pcap_freecode
	:: Ptr BpfProgramTag -> IO ()

foreign import ccall "wrapper" h2c''
	:: (Ptr BpfProgramTag -> IO ()) -> IO (FinalizerPtr a)



--
-- Find devices
--

data DevBuf
data DevAddr


-- |
--   lookupDev returns the name of a device suitable for use with
--   openLive and lookupNet. If you only have one interface, it is the
--   function of choice. If not, see findAllDevs.
--
lookupDev :: IO String
lookupDev =
        allocaArray (256) $ \errPtr  -> do
{-# LINE 388 "Network/Pcap.hsc" #-}
                ptr <- pcap_lookupdev errPtr
                if ptr == nullPtr
                        then peekCString errPtr >>= ioError . userError
                        else peekCString ptr


-- |
--   findAllDevs returns a list of all the network devices that can
--   be opened by openLive. It returns only those devices that the
--   calling process has sufficient privileges to open, so it may not
--   find every device on the system.
--
findAllDevs :: IO [Interface]
findAllDevs = 
	alloca $ \dptr -> do
		allocaArray (256) $ \errPtr -> do
{-# LINE 404 "Network/Pcap.hsc" #-}
		        ret <- pcap_findalldevs dptr errPtr
		        if (ret == -1) then
                                peekCString errPtr >>= ioError . userError
                      	    else do
				dbuf <- peek dptr
				dl   <- devs2list dbuf
			        pcap_freealldevs dbuf
				return dl


devs2list :: Ptr DevBuf -> IO [Interface]
devs2list dbuf
	| dbuf == nullPtr       = do return []
	| otherwise		= do
		nextdev <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) dbuf
{-# LINE 419 "Network/Pcap.hsc" #-}
		ds      <- devs2list nextdev
		d       <- oneDev dbuf
		return (d : ds)


oneDev :: Ptr DevBuf -> IO Interface
oneDev dbuf =
	do
		name  <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) dbuf
{-# LINE 428 "Network/Pcap.hsc" #-}
		desc  <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) dbuf
{-# LINE 429 "Network/Pcap.hsc" #-}
		addrs <- ((\hsc_ptr -> peekByteOff hsc_ptr 12)) dbuf
{-# LINE 430 "Network/Pcap.hsc" #-}
		flags <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) dbuf
{-# LINE 431 "Network/Pcap.hsc" #-}

		name' <- peekCString name
		desc' <- if desc /= nullPtr then
				peekCString desc
			     else
				return ""

		addrs' <- addrs2list addrs

		return (Interface name' desc' addrs' (fromIntegral (flags :: CUInt)))


addrs2list :: Ptr DevAddr -> IO [PcapAddr]
addrs2list abuf
	| abuf == nullPtr       = do return []
	| otherwise		= do
		nextaddr <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) abuf
{-# LINE 448 "Network/Pcap.hsc" #-}
		as       <- addrs2list nextaddr
		a        <- oneAddr abuf
		return (a : as)


oneAddr :: Ptr DevAddr -> IO PcapAddr
oneAddr abuf =
	let
		socka :: Ptr a -> IO (Maybe SockAddr)
		socka sa =
			if sa /= nullPtr then
				do

{-# LINE 463 "Network/Pcap.hsc" #-}
                                        l <- return ((16)) :: IO CUChar
{-# LINE 464 "Network/Pcap.hsc" #-}

{-# LINE 465 "Network/Pcap.hsc" #-}
					f <- (((\hsc_ptr -> peekByteOff hsc_ptr 0)) sa) :: IO CUChar
{-# LINE 466 "Network/Pcap.hsc" #-}
					
					addr <- peekArray ((fromIntegral l) - ((2)))
{-# LINE 468 "Network/Pcap.hsc" #-}
							   ((plusPtr sa ((2))) :: Ptr Word8)
{-# LINE 469 "Network/Pcap.hsc" #-}

					return (Just (SockAddr (unpackFamily (fromIntegral f)) addr))
		    	    else
				return Nothing
	in	
		do
			addr  <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) abuf      >>= socka
{-# LINE 476 "Network/Pcap.hsc" #-}
			mask  <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) abuf   >>= socka
{-# LINE 477 "Network/Pcap.hsc" #-}
			bcast <- ((\hsc_ptr -> peekByteOff hsc_ptr 12)) abuf >>= socka
{-# LINE 478 "Network/Pcap.hsc" #-}
			peer  <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) abuf   >>= socka
{-# LINE 479 "Network/Pcap.hsc" #-}

			if isNothing addr then
				ioError $ userError "Pcap.oneAddr: null address"
			    else
				return (PcapAddr (fromJust addr) mask bcast peer)


-- | Return the network address and mask for the specified interface
--   name. Only valid for IPv4. For other protocols,
--   use findAllDevs and search the Address list for the associated
--   network mask.
--
lookupNet
	:: String	-- ^ device name
	-> IO Network
lookupNet dev =
	withCString dev $ \name  ->
		alloca  $ \netp  ->
		alloca  $ \maskp -> do
			allocaArray (256) $ \errPtr -> do
{-# LINE 499 "Network/Pcap.hsc" #-}
				ret  <- pcap_lookupnet name netp maskp errPtr
				if ret == (-1) then
					peekCString errPtr >>= ioError . userError
			            else do
					net  <- peek netp
					mask <- peek maskp

					return (Network (fromIntegral net)
							(fromIntegral mask) )


foreign import ccall unsafe pcap_lookupdev   :: Ptr CChar        -> IO (Ptr CChar)
foreign import ccall unsafe pcap_findalldevs :: Ptr (Ptr DevBuf) -> Ptr CChar -> IO CInt
foreign import ccall unsafe pcap_freealldevs :: Ptr DevBuf       -> IO ()
foreign import ccall unsafe pcap_lookupnet   :: Ptr CChar        -> Ptr CUInt -> Ptr CUInt -> Ptr CChar -> IO CInt



--
-- Set or read the device mode (blocking/nonblocking)
--

-- | Set a packet capture descriptor into non-blocking mode, if the
--   second argument is True, otherwise put it in blocking mode. Note
--   that the packet capture descripto must have been obtaine from openLive.
--
setNonBlock :: Ptr PcapTag -> Bool -> IO ()
setNonBlock ptr block = 
        allocaArray (256) $ \errPtr  -> do
{-# LINE 528 "Network/Pcap.hsc" #-}
                ret <- pcap_setnonblock ptr (fromBool block) errPtr
                if ret == (-1)
                        then peekCString errPtr >>= ioError . userError
                        else return ()

--
-- | Return the blocking status of the packet capture descriptor. Ture
--   indicates that the descriptor is non-blocking. Descriptors referring
--   savefiles opened by openDump always reutre False.
--
getNonBlock :: Ptr PcapTag -> IO Bool
getNonBlock ptr = 
        allocaArray (256) $ \errPtr  -> do
{-# LINE 541 "Network/Pcap.hsc" #-}
                ret <- pcap_getnonblock ptr errPtr
                if ret == (-1)
                        then peekCString errPtr >>= ioError . userError
                        else return (toBool ret)


foreign import ccall unsafe pcap_setnonblock :: Ptr PcapTag -> CInt -> Ptr CChar -> IO CInt
foreign import ccall unsafe pcap_getnonblock :: Ptr PcapTag -> Ptr CChar -> IO CInt



--
-- Error handling
--

throwPcapError :: Ptr PcapTag -> IO a
throwPcapError hdl = do
        msg <- pcap_geterr hdl >>= peekCString
        ioError (userError msg)


foreign import ccall unsafe pcap_geterr :: Ptr PcapTag -> IO (Ptr CChar)



--
-- Reading packets
--

-- | the type of the callback function passed to dispatch or loop.
type Callback  = PktHdr    -> Ptr Word8  -> IO ()
type CCallback = Ptr Word8 -> Ptr PktHdr -> Ptr Word8 -> IO ()


exportCallback :: Callback -> IO (FunPtr CCallback)
exportCallback f = exportCCallback $ \_user hdr ptr -> do
        let ts = ((\hsc_ptr -> hsc_ptr `plusPtr` 0)) hdr
{-# LINE 578 "Network/Pcap.hsc" #-}

        s      <- ((\hsc_ptr -> peekByteOff hsc_ptr 0))  ts
{-# LINE 580 "Network/Pcap.hsc" #-}
        us     <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) ts
{-# LINE 581 "Network/Pcap.hsc" #-}
        caplen <- ((\hsc_ptr -> peekByteOff hsc_ptr 8))  hdr
{-# LINE 582 "Network/Pcap.hsc" #-}
        len    <- ((\hsc_ptr -> peekByteOff hsc_ptr 12))     hdr
{-# LINE 583 "Network/Pcap.hsc" #-}

	f
		(PktHdr
			(fromIntegral (s      :: CLong))
			(fromIntegral (us     :: CLong))
			(fromIntegral (caplen :: CUInt))
			(fromIntegral (len    :: CUInt)))
	 	ptr


-- |
--   Collect and process packets. The arguments are the packet capture
--   descriptor, the count and a callback function.
--
--   The count is the maximum number of packets to process before returning.
--   A count of -1 means process all of the packets received in one buffer
--   (if a live capture) or all of the packets in a savefile (if offline).
--
--   The callback function is passed two arguments, a packet header
--   record and a pointer to the packet data (Ptr Word8). THe header
--   record contains the number of bytes captured, whcih can be used
--   to marshal the data into a list or array.
--
dispatch
	:: Ptr PcapTag	-- ^ packet capture descriptor
	-> Int		-- ^ number of packets to process
	-> Callback	-- ^ packet processing function
	-> IO Int	-- ^ number of packets read
dispatch hdl count f = do
        handler <- exportCallback f
        result  <- pcap_dispatch hdl (fromIntegral count) handler nullPtr

        freeHaskellFunPtr handler

	if (result == -1) then
		throwPcapError hdl
	    else
	        return (fromIntegral result)


-- |
--   Similar to dispatch, but loop until the number of packets specified
--   by the second argument are read. A negative value loops forever.
--
--   It does not return when a live read tiemout occurs. Use dispatch instead
--   if you wnat to specify a timeout.
--
loop
	:: Ptr PcapTag	-- ^ packet cpature descriptor
	-> Int		-- ^ number of packet to read
	-> Callback	-- ^ packet processing function
	-> IO Int	-- ^ number of packets read
loop hdl count f = do
        handler <- exportCallback f
        result  <- pcap_loop hdl (fromIntegral count) handler nullPtr

        freeHaskellFunPtr handler

	if (result == -1) then
		throwPcapError hdl
	    else
	        return (fromIntegral result)


-- | 
--   Read the next packet (by calling dispatch with a count of 1).
--
next
	:: Ptr PcapTag			-- ^ packet capture descriptor
	-> IO (PktHdr, Ptr Word8)	-- ^ packet header and data of the next packet
next hdl =
        allocaBytes ((16)) $ \hdr -> do
{-# LINE 655 "Network/Pcap.hsc" #-}
                ptr <- pcap_next hdl hdr
                if (ptr == nullPtr) then
                        return (PktHdr 0 0 0 0, ptr)
                     else do
                        let ts = ((\hsc_ptr -> hsc_ptr `plusPtr` 0)) hdr
{-# LINE 660 "Network/Pcap.hsc" #-}

                        s      <- ((\hsc_ptr -> peekByteOff hsc_ptr 0))  ts
{-# LINE 662 "Network/Pcap.hsc" #-}
                        us     <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) ts
{-# LINE 663 "Network/Pcap.hsc" #-}
                        caplen <- ((\hsc_ptr -> peekByteOff hsc_ptr 8))  hdr
{-# LINE 664 "Network/Pcap.hsc" #-}
                        len    <- ((\hsc_ptr -> peekByteOff hsc_ptr 12))     hdr
{-# LINE 665 "Network/Pcap.hsc" #-}

		        return (PktHdr
			          (fromIntegral (s      :: CLong))
			          (fromIntegral (us     :: CLong))
			          (fromIntegral (caplen :: CUInt))
			          (fromIntegral (len    :: CUInt)),
                                ptr)
				

-- |
--   Write the packet data given by the second and third arguments
--   to a savefile opened by openDead. dump is designed so it can be
--   easily used as a default callback function by dispatch or loop.
--
dump
	:: Ptr PcapDumpTag	-- ^ savefile descriptor
	-> Ptr PktHdr		-- ^ packet header record
	-> Ptr Word8		-- ^ packet data
	-> IO ()
dump hdl hdr pkt = pcap_dump hdl hdr pkt



foreign import ccall "wrapper" exportCCallback
        :: CCallback -> IO (FunPtr CCallback)

foreign import ccall pcap_dispatch
        :: Ptr PcapTag -> CInt -> FunPtr CCallback -> Ptr Word8 -> IO CInt
foreign import ccall pcap_loop
        :: Ptr PcapTag -> CInt -> FunPtr CCallback -> Ptr Word8 -> IO CInt
foreign import ccall pcap_next
        :: Ptr PcapTag -> Ptr PktHdr -> IO (Ptr Word8)
foreign import ccall pcap_dump
	:: Ptr PcapDumpTag -> Ptr PktHdr -> Ptr Word8 -> IO ()


--
-- Datalink manipulation
--

-- |
--   Returns the datalink type associated with the given pcap descriptor.
--
datalink :: Ptr PcapTag -> IO Link
datalink hdl = do
	ret <- pcap_datalink hdl
	return (unpackLink ret)


-- |
--   Sets the datalink type for a given pcap descriptor.
--
setDatalink :: Ptr PcapTag -> Link -> IO ()
setDatalink hdl link = do
	ret <- pcap_set_datalink hdl (packLink link)
	if (ret == -1) then
		throwPcapError hdl
	   else
		return ()


-- |
--   List all the datalink types supported by a pcap descriptor. Entries
--   from the resulting list are valid arguments to setDatalink.
--
listDatalinks :: Ptr PcapTag -> IO [Link]
listDatalinks hdl =
	alloca $ \lptr -> do
		ret <- pcap_list_datalinks hdl lptr
		if (ret == -1) then
			throwPcapError hdl
	    	    else do
			dlbuf <- peek lptr
			dls   <- peekArray (fromIntegral (ret :: CInt)) dlbuf
			free dlbuf
			return (map unpackLink dls)
	
		
foreign import ccall unsafe pcap_datalink       :: Ptr PcapTag -> IO CInt
foreign import ccall unsafe pcap_set_datalink   :: Ptr PcapTag -> CInt -> IO CInt
foreign import ccall unsafe pcap_list_datalinks :: Ptr PcapTag -> Ptr (Ptr CInt) -> IO CInt


--
-- Statistics
--

data PcapStats = PcapStats

-- |
--   Returns the number of packets received, the number of packets
--   dropped by the packet filter and the number of packets dropped
--   by the interface (before processing by the packet filter).
--
statistics :: Ptr PcapTag -> IO Statistics
statistics hdl =
	allocaBytes ((12)) $ \stats -> do
{-# LINE 762 "Network/Pcap.hsc" #-}
                ret <- pcap_stats hdl stats
                if (ret == -1) then
			throwPcapError hdl
		    else do
			recv   <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) stats
{-# LINE 767 "Network/Pcap.hsc" #-}
			drop   <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) stats
{-# LINE 768 "Network/Pcap.hsc" #-}
			ifdrop <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) stats
{-# LINE 769 "Network/Pcap.hsc" #-}

			return (Statistics
				(fromIntegral (recv   :: CUInt))
				(fromIntegral (drop   :: CUInt))
				(fromIntegral (ifdrop :: CUInt)))

foreign import ccall unsafe pcap_stats :: Ptr PcapTag -> Ptr PcapStats -> IO Int



--
-- Version information
--

-- |
--   Major version number of the library.
--
majorVersion :: Ptr PcapTag -> IO Int
majorVersion ptr = do
	v <- pcap_major_version ptr
	return (fromIntegral (v :: CInt))


-- |
--   Minor version number of the library.
--
minorVersion :: Ptr PcapTag -> IO Int
minorVersion ptr = do
	v <- pcap_major_version ptr
	return (fromIntegral (v :: CInt))


-- |
--   isSwapped is True if the current savefile uses a different
--   byte order than the one native to the system.
--
isSwapped :: Ptr PcapTag -> IO Bool
isSwapped ptr = do
        sw <- pcap_is_swapped ptr
        return (toBool sw)


-- |
--   The snapshot length that was used in the call to openLive.
-- 
snapshotLen :: Ptr PcapTag -> IO Int
snapshotLen ptr = do
	l <- pcap_snapshot ptr
	return (fromIntegral (l :: CInt))


foreign import ccall pcap_major_version :: Ptr PcapTag -> IO CInt
foreign import ccall pcap_minor_version :: Ptr PcapTag -> IO CInt
foreign import ccall pcap_is_swapped    :: Ptr PcapTag -> IO CInt
foreign import ccall pcap_snapshot      :: Ptr PcapTag -> IO CInt


--
-- Utility functions for data link types
--

-- | Datalink types.
--
--   This covers all of the datalink types defined in bpf.h.
--   Types defined on your system may vary.
--
data Link 
	= DLT_NULL		-- ^ no link layer encapsulation

{-# LINE 838 "Network/Pcap.hsc" #-}
	| DLT_EN10MB		-- ^ 10 Mbit per second (or faster) ethernet

{-# LINE 840 "Network/Pcap.hsc" #-}

{-# LINE 841 "Network/Pcap.hsc" #-}
	| DLT_EN3MB		-- ^ original 3 Mbit per second ethernet

{-# LINE 843 "Network/Pcap.hsc" #-}

{-# LINE 844 "Network/Pcap.hsc" #-}
	| DLT_AX25		-- ^ amateur radio AX.25

{-# LINE 846 "Network/Pcap.hsc" #-}

{-# LINE 847 "Network/Pcap.hsc" #-}
	| DLT_PRONET		-- ^ Proteon ProNET Token Ring

{-# LINE 849 "Network/Pcap.hsc" #-}

{-# LINE 850 "Network/Pcap.hsc" #-}
	| DLT_CHAOS		-- ^ Chaos

{-# LINE 852 "Network/Pcap.hsc" #-}

{-# LINE 853 "Network/Pcap.hsc" #-}
	| DLT_IEEE802		-- ^ IEEE 802 networks

{-# LINE 855 "Network/Pcap.hsc" #-}

{-# LINE 856 "Network/Pcap.hsc" #-}
	| DLT_ARCNET		-- ^ ARCNET

{-# LINE 858 "Network/Pcap.hsc" #-}

{-# LINE 859 "Network/Pcap.hsc" #-}
	| DLT_SLIP		-- ^ Serial line IP

{-# LINE 861 "Network/Pcap.hsc" #-}

{-# LINE 862 "Network/Pcap.hsc" #-}
	| DLT_PPP		-- ^ Point-to-point protocol

{-# LINE 864 "Network/Pcap.hsc" #-}

{-# LINE 865 "Network/Pcap.hsc" #-}
	| DLT_FDDI		-- ^ FDDI

{-# LINE 867 "Network/Pcap.hsc" #-}

{-# LINE 868 "Network/Pcap.hsc" #-}
	| DLT_ATM_RFC1483	-- ^ LLC SNAP encapsulated ATM

{-# LINE 870 "Network/Pcap.hsc" #-}

{-# LINE 871 "Network/Pcap.hsc" #-}
	| DLT_RAW		-- ^ raw IP

{-# LINE 873 "Network/Pcap.hsc" #-}

{-# LINE 874 "Network/Pcap.hsc" #-}
	| DLT_SLIP_BSDOS	-- ^ BSD OS serial line IP

{-# LINE 876 "Network/Pcap.hsc" #-}

{-# LINE 877 "Network/Pcap.hsc" #-}
	| DLT_PPP_BSDOS		-- ^ BSD OS point-to-point protocol

{-# LINE 879 "Network/Pcap.hsc" #-}

{-# LINE 880 "Network/Pcap.hsc" #-}
	| DLT_ATM_CLIP		-- ^ Linux classical IP over ATM

{-# LINE 882 "Network/Pcap.hsc" #-}

{-# LINE 883 "Network/Pcap.hsc" #-}
	| DLT_PPP_SERIAL	-- ^ PPP over serial with HDLC encapsulation

{-# LINE 885 "Network/Pcap.hsc" #-}

{-# LINE 886 "Network/Pcap.hsc" #-}
	| DLT_PPP_ETHER		-- ^ PPP over ethernet

{-# LINE 888 "Network/Pcap.hsc" #-}

{-# LINE 889 "Network/Pcap.hsc" #-}
	| DLT_C_HDLC		-- ^ Cisco HDLC

{-# LINE 891 "Network/Pcap.hsc" #-}

{-# LINE 892 "Network/Pcap.hsc" #-}
	| DLT_IEEE802_11	-- ^ IEEE 802.11 wireless

{-# LINE 894 "Network/Pcap.hsc" #-}

{-# LINE 895 "Network/Pcap.hsc" #-}
	| DLT_LOOP		-- ^ OpenBSD loopback device

{-# LINE 897 "Network/Pcap.hsc" #-}

{-# LINE 898 "Network/Pcap.hsc" #-}
	| DLT_LINUX_SLL		-- ^ Linux cooked sockets

{-# LINE 900 "Network/Pcap.hsc" #-}

{-# LINE 901 "Network/Pcap.hsc" #-}
	| DLT_LTALK		-- ^ Apple LocalTalk

{-# LINE 903 "Network/Pcap.hsc" #-}

{-# LINE 904 "Network/Pcap.hsc" #-}
	| DLT_ECONET		-- ^ Acorn Econet

{-# LINE 906 "Network/Pcap.hsc" #-}

{-# LINE 907 "Network/Pcap.hsc" #-}
	| DLT_IPFILTER		-- ^ OpenBSD's old ipfilter

{-# LINE 909 "Network/Pcap.hsc" #-}

{-# LINE 910 "Network/Pcap.hsc" #-}
	| DLT_PFLOG		-- ^ OpenBSD's pflog

{-# LINE 912 "Network/Pcap.hsc" #-}

{-# LINE 913 "Network/Pcap.hsc" #-}
	| DLT_CISCO_IOS		-- ^ Cisco IOS

{-# LINE 915 "Network/Pcap.hsc" #-}

{-# LINE 916 "Network/Pcap.hsc" #-}
	| DLT_PRISM_HEADER	-- ^ Intersil Prism II wireless chips

{-# LINE 918 "Network/Pcap.hsc" #-}

{-# LINE 919 "Network/Pcap.hsc" #-}
	| DLT_AIRONET_HEADER	-- ^ Aironet (Cisco) 802.11 wireless

{-# LINE 921 "Network/Pcap.hsc" #-}
	deriving (Eq, Ord, Read, Show)


packLink :: Link -> CInt
packLink l = case l of
	DLT_NULL -> 0
{-# LINE 927 "Network/Pcap.hsc" #-}

{-# LINE 928 "Network/Pcap.hsc" #-}
	DLT_EN10MB	-> 1
{-# LINE 929 "Network/Pcap.hsc" #-}

{-# LINE 930 "Network/Pcap.hsc" #-}

{-# LINE 931 "Network/Pcap.hsc" #-}
	DLT_EN3MB	-> 2
{-# LINE 932 "Network/Pcap.hsc" #-}

{-# LINE 933 "Network/Pcap.hsc" #-}

{-# LINE 934 "Network/Pcap.hsc" #-}
	DLT_AX25	-> 3
{-# LINE 935 "Network/Pcap.hsc" #-}

{-# LINE 936 "Network/Pcap.hsc" #-}

{-# LINE 937 "Network/Pcap.hsc" #-}
	DLT_PRONET	-> 4
{-# LINE 938 "Network/Pcap.hsc" #-}

{-# LINE 939 "Network/Pcap.hsc" #-}

{-# LINE 940 "Network/Pcap.hsc" #-}
	DLT_CHAOS	-> 5
{-# LINE 941 "Network/Pcap.hsc" #-}

{-# LINE 942 "Network/Pcap.hsc" #-}

{-# LINE 943 "Network/Pcap.hsc" #-}
	DLT_IEEE802	-> 6
{-# LINE 944 "Network/Pcap.hsc" #-}

{-# LINE 945 "Network/Pcap.hsc" #-}

{-# LINE 946 "Network/Pcap.hsc" #-}
	DLT_ARCNET	-> 7
{-# LINE 947 "Network/Pcap.hsc" #-}

{-# LINE 948 "Network/Pcap.hsc" #-}

{-# LINE 949 "Network/Pcap.hsc" #-}
	DLT_SLIP	-> 8
{-# LINE 950 "Network/Pcap.hsc" #-}

{-# LINE 951 "Network/Pcap.hsc" #-}

{-# LINE 952 "Network/Pcap.hsc" #-}
	DLT_PPP		-> 9
{-# LINE 953 "Network/Pcap.hsc" #-}

{-# LINE 954 "Network/Pcap.hsc" #-}

{-# LINE 955 "Network/Pcap.hsc" #-}
	DLT_FDDI	-> 10
{-# LINE 956 "Network/Pcap.hsc" #-}

{-# LINE 957 "Network/Pcap.hsc" #-}

{-# LINE 958 "Network/Pcap.hsc" #-}
	DLT_ATM_RFC1483	-> 11
{-# LINE 959 "Network/Pcap.hsc" #-}

{-# LINE 960 "Network/Pcap.hsc" #-}

{-# LINE 961 "Network/Pcap.hsc" #-}
	DLT_RAW		-> 12
{-# LINE 962 "Network/Pcap.hsc" #-}

{-# LINE 963 "Network/Pcap.hsc" #-}

{-# LINE 964 "Network/Pcap.hsc" #-}
	DLT_SLIP_BSDOS	-> 15
{-# LINE 965 "Network/Pcap.hsc" #-}

{-# LINE 966 "Network/Pcap.hsc" #-}

{-# LINE 967 "Network/Pcap.hsc" #-}
	DLT_PPP_BSDOS	-> 16
{-# LINE 968 "Network/Pcap.hsc" #-}

{-# LINE 969 "Network/Pcap.hsc" #-}

{-# LINE 970 "Network/Pcap.hsc" #-}
	DLT_ATM_CLIP	-> 19
{-# LINE 971 "Network/Pcap.hsc" #-}

{-# LINE 972 "Network/Pcap.hsc" #-}

{-# LINE 973 "Network/Pcap.hsc" #-}
	DLT_PPP_SERIAL	-> 50
{-# LINE 974 "Network/Pcap.hsc" #-}

{-# LINE 975 "Network/Pcap.hsc" #-}

{-# LINE 976 "Network/Pcap.hsc" #-}
	DLT_PPP_ETHER	-> 51
{-# LINE 977 "Network/Pcap.hsc" #-}

{-# LINE 978 "Network/Pcap.hsc" #-}

{-# LINE 979 "Network/Pcap.hsc" #-}
	DLT_C_HDLC	-> 104
{-# LINE 980 "Network/Pcap.hsc" #-}

{-# LINE 981 "Network/Pcap.hsc" #-}

{-# LINE 982 "Network/Pcap.hsc" #-}
	DLT_IEEE802_11	-> 105
{-# LINE 983 "Network/Pcap.hsc" #-}

{-# LINE 984 "Network/Pcap.hsc" #-}

{-# LINE 985 "Network/Pcap.hsc" #-}
	DLT_LOOP	-> 108
{-# LINE 986 "Network/Pcap.hsc" #-}

{-# LINE 987 "Network/Pcap.hsc" #-}

{-# LINE 988 "Network/Pcap.hsc" #-}
	DLT_LINUX_SLL	-> 113
{-# LINE 989 "Network/Pcap.hsc" #-}

{-# LINE 990 "Network/Pcap.hsc" #-}

{-# LINE 991 "Network/Pcap.hsc" #-}
	DLT_LTALK	-> 114
{-# LINE 992 "Network/Pcap.hsc" #-}

{-# LINE 993 "Network/Pcap.hsc" #-}

{-# LINE 994 "Network/Pcap.hsc" #-}
	DLT_ECONET	-> 115
{-# LINE 995 "Network/Pcap.hsc" #-}

{-# LINE 996 "Network/Pcap.hsc" #-}

{-# LINE 997 "Network/Pcap.hsc" #-}
	DLT_IPFILTER	-> 116
{-# LINE 998 "Network/Pcap.hsc" #-}

{-# LINE 999 "Network/Pcap.hsc" #-}

{-# LINE 1000 "Network/Pcap.hsc" #-}
	DLT_PFLOG	-> 117
{-# LINE 1001 "Network/Pcap.hsc" #-}

{-# LINE 1002 "Network/Pcap.hsc" #-}

{-# LINE 1003 "Network/Pcap.hsc" #-}
	DLT_CISCO_IOS	-> 118
{-# LINE 1004 "Network/Pcap.hsc" #-}

{-# LINE 1005 "Network/Pcap.hsc" #-}

{-# LINE 1006 "Network/Pcap.hsc" #-}
	DLT_PRISM_HEADER -> 119
{-# LINE 1007 "Network/Pcap.hsc" #-}

{-# LINE 1008 "Network/Pcap.hsc" #-}

{-# LINE 1009 "Network/Pcap.hsc" #-}
	DLT_AIRONET_HEADER -> 120
{-# LINE 1010 "Network/Pcap.hsc" #-}

{-# LINE 1011 "Network/Pcap.hsc" #-}



unpackLink :: CInt -> Link
unpackLink l = case l of
	(0) 	-> DLT_NULL
{-# LINE 1017 "Network/Pcap.hsc" #-}

{-# LINE 1018 "Network/Pcap.hsc" #-}
	(1)	-> DLT_EN10MB
{-# LINE 1019 "Network/Pcap.hsc" #-}

{-# LINE 1020 "Network/Pcap.hsc" #-}

{-# LINE 1021 "Network/Pcap.hsc" #-}
	(2)	-> DLT_EN3MB
{-# LINE 1022 "Network/Pcap.hsc" #-}

{-# LINE 1023 "Network/Pcap.hsc" #-}

{-# LINE 1024 "Network/Pcap.hsc" #-}
	(3)	-> DLT_AX25
{-# LINE 1025 "Network/Pcap.hsc" #-}

{-# LINE 1026 "Network/Pcap.hsc" #-}

{-# LINE 1027 "Network/Pcap.hsc" #-}
	(4)	-> DLT_PRONET
{-# LINE 1028 "Network/Pcap.hsc" #-}

{-# LINE 1029 "Network/Pcap.hsc" #-}

{-# LINE 1030 "Network/Pcap.hsc" #-}
	(5)	-> DLT_CHAOS
{-# LINE 1031 "Network/Pcap.hsc" #-}

{-# LINE 1032 "Network/Pcap.hsc" #-}

{-# LINE 1033 "Network/Pcap.hsc" #-}
	(6)	-> DLT_IEEE802
{-# LINE 1034 "Network/Pcap.hsc" #-}

{-# LINE 1035 "Network/Pcap.hsc" #-}

{-# LINE 1036 "Network/Pcap.hsc" #-}
	(7)	-> DLT_ARCNET
{-# LINE 1037 "Network/Pcap.hsc" #-}

{-# LINE 1038 "Network/Pcap.hsc" #-}

{-# LINE 1039 "Network/Pcap.hsc" #-}
	(8)	-> DLT_SLIP
{-# LINE 1040 "Network/Pcap.hsc" #-}

{-# LINE 1041 "Network/Pcap.hsc" #-}

{-# LINE 1042 "Network/Pcap.hsc" #-}
	(9)	-> DLT_PPP
{-# LINE 1043 "Network/Pcap.hsc" #-}

{-# LINE 1044 "Network/Pcap.hsc" #-}

{-# LINE 1045 "Network/Pcap.hsc" #-}
	(10)	-> DLT_FDDI
{-# LINE 1046 "Network/Pcap.hsc" #-}

{-# LINE 1047 "Network/Pcap.hsc" #-}

{-# LINE 1048 "Network/Pcap.hsc" #-}
	(11) -> DLT_ATM_RFC1483
{-# LINE 1049 "Network/Pcap.hsc" #-}

{-# LINE 1050 "Network/Pcap.hsc" #-}

{-# LINE 1051 "Network/Pcap.hsc" #-}
	(12)	-> DLT_RAW
{-# LINE 1052 "Network/Pcap.hsc" #-}

{-# LINE 1053 "Network/Pcap.hsc" #-}

{-# LINE 1054 "Network/Pcap.hsc" #-}
	(15)	-> DLT_SLIP_BSDOS
{-# LINE 1055 "Network/Pcap.hsc" #-}

{-# LINE 1056 "Network/Pcap.hsc" #-}

{-# LINE 1057 "Network/Pcap.hsc" #-}
	(16)	-> DLT_PPP_BSDOS
{-# LINE 1058 "Network/Pcap.hsc" #-}

{-# LINE 1059 "Network/Pcap.hsc" #-}

{-# LINE 1060 "Network/Pcap.hsc" #-}
	(19)	-> DLT_ATM_CLIP
{-# LINE 1061 "Network/Pcap.hsc" #-}

{-# LINE 1062 "Network/Pcap.hsc" #-}

{-# LINE 1063 "Network/Pcap.hsc" #-}
	(50)	-> DLT_PPP_SERIAL
{-# LINE 1064 "Network/Pcap.hsc" #-}

{-# LINE 1065 "Network/Pcap.hsc" #-}

{-# LINE 1066 "Network/Pcap.hsc" #-}
	(51)	-> DLT_PPP_ETHER
{-# LINE 1067 "Network/Pcap.hsc" #-}

{-# LINE 1068 "Network/Pcap.hsc" #-}

{-# LINE 1069 "Network/Pcap.hsc" #-}
	(104)	-> DLT_C_HDLC
{-# LINE 1070 "Network/Pcap.hsc" #-}

{-# LINE 1071 "Network/Pcap.hsc" #-}

{-# LINE 1072 "Network/Pcap.hsc" #-}
	(105)	-> DLT_IEEE802_11
{-# LINE 1073 "Network/Pcap.hsc" #-}

{-# LINE 1074 "Network/Pcap.hsc" #-}

{-# LINE 1075 "Network/Pcap.hsc" #-}
	(108)	-> DLT_LOOP
{-# LINE 1076 "Network/Pcap.hsc" #-}

{-# LINE 1077 "Network/Pcap.hsc" #-}

{-# LINE 1078 "Network/Pcap.hsc" #-}
	(113)	-> DLT_LINUX_SLL
{-# LINE 1079 "Network/Pcap.hsc" #-}

{-# LINE 1080 "Network/Pcap.hsc" #-}

{-# LINE 1081 "Network/Pcap.hsc" #-}
	(114)	-> DLT_LTALK
{-# LINE 1082 "Network/Pcap.hsc" #-}

{-# LINE 1083 "Network/Pcap.hsc" #-}

{-# LINE 1084 "Network/Pcap.hsc" #-}
	(115)	-> DLT_ECONET
{-# LINE 1085 "Network/Pcap.hsc" #-}

{-# LINE 1086 "Network/Pcap.hsc" #-}

{-# LINE 1087 "Network/Pcap.hsc" #-}
	(116)	-> DLT_IPFILTER
{-# LINE 1088 "Network/Pcap.hsc" #-}

{-# LINE 1089 "Network/Pcap.hsc" #-}

{-# LINE 1090 "Network/Pcap.hsc" #-}
	(117)	-> DLT_PFLOG
{-# LINE 1091 "Network/Pcap.hsc" #-}

{-# LINE 1092 "Network/Pcap.hsc" #-}

{-# LINE 1093 "Network/Pcap.hsc" #-}
	(118)	-> DLT_CISCO_IOS
{-# LINE 1094 "Network/Pcap.hsc" #-}

{-# LINE 1095 "Network/Pcap.hsc" #-}

{-# LINE 1096 "Network/Pcap.hsc" #-}
	(119) -> DLT_PRISM_HEADER
{-# LINE 1097 "Network/Pcap.hsc" #-}

{-# LINE 1098 "Network/Pcap.hsc" #-}

{-# LINE 1099 "Network/Pcap.hsc" #-}
	(120) -> DLT_AIRONET_HEADER
{-# LINE 1100 "Network/Pcap.hsc" #-}

{-# LINE 1101 "Network/Pcap.hsc" #-}