diff --git a/Data/IP.hs b/Data/IP.hs
--- a/Data/IP.hs
+++ b/Data/IP.hs
@@ -1,21 +1,19 @@
 {-# LANGUAGE DisambiguateRecordFields, FlexibleInstances, MultiParamTypeClasses #-}
-{- |The Data.IP library exports IPv4 and IPv6 address and header structures.
-
-   Patches to add more parsing and pretty printing are welcome.
+{- |The Data.IP library exports IPv4 address and header structures.
 
    FIXME:
    There is currently no support for options fields of the IP header.
  -}
 module Data.IP
-	( IPv4 (..)
-	, IPv4Header (..)
-	, IPv4Flag (..)
+	( IPv4(..)
+	, IPv4Header(..)
+	, IPv4Flag(..)
 	, dummyIPv4Header
 	, module Data.IPv6
 	, ipv4
 	) where
 
-import Control.Monad (sequence)
+import Control.Monad (sequence, when)
 import qualified Data.ByteString.Lazy as B
 import Data.Binary
 import Data.Binary.Put
@@ -52,12 +50,12 @@
 -- |This IPv4 header structure lacks support for options.  Ints are used
 -- for most integral data types and the binary instance hands the bit packing.
 --
--- No warning is provided if a field is overflowed!
+-- No warning is provided if a value is trunkated when packed!
 data IPv4Header =
 	IPv4Hdr { hdrLength		:: Int
 		, version		:: Int
 		, tos			:: Int
-		, payloadLength		:: Int
+		, totalLength		:: Int
 		, ipID			:: Int
 		, flags			:: [IPv4Flag]
 		, fragmentOffset	:: Int
@@ -121,7 +119,7 @@
 		put (dst h)
 		putWord8 0
 		pW8 $ fromIntegral (protocol h)
-		pW16 (payloadLength h))
+		pW16 (totalLength h))
 	computeChecksum h = csum16 (encode (zeroChecksum h))
 
 instance L3Address IPv4 IPv4Header where
@@ -132,6 +130,8 @@
 instance Pretty IPv4 where
 	pPrint (IPv4 i) = cat . intersperse (char '.') . map (int . fromIntegral) $ (B.unpack i)
 
+-- |Parsec parser for IPv4 strings (ex: "33.44.255.17")
+ipv4 :: GenParser Char st IPv4
 ipv4 = do
 	a <- octet
 	P.char '.'
@@ -142,9 +142,13 @@
 	d <- octet
 	return $ IPv4 $ B.pack [a, b, c, d]
 	<?>
-	"Expected IPv4 Address"
+	"IPv4 Address"
 
 octet = do
 	d <- P.many1 P.digit
-	let s = toEnum $ read d
+	let n = read d :: Int
+	when (n > 255) (fail "IPv4 octet invalid")
+	let s = toEnum n
 	return s
+	<?>
+	"IPv4 digits for an octet"
diff --git a/Data/IPv6.hs b/Data/IPv6.hs
--- a/Data/IPv6.hs
+++ b/Data/IPv6.hs
@@ -2,19 +2,20 @@
 
 module Data.IPv6
 	( IPv6 (..)
+	, ipv6
 	) where
 
-import Control.Monad (sequence)
+import Control.Monad (sequence, when)
 import qualified Data.ByteString.Lazy as B
 import Data.Binary
 import Data.Binary.Put
 import Data.Binary.Get
 import Data.Bits
-import Numeric (showHex)
+import Data.List (group)
+import Numeric (showHex, readHex)
 import Text.PrettyPrint
 import Text.PrettyPrint.HughesPJClass
 import Text.ParserCombinators.Parsec as P
-import Data.Maybe (maybeToList)
 
 gW8 = getWord8 >>= return . fromIntegral
 gW16 = getWord16be >>= return . fromIntegral
@@ -68,7 +69,7 @@
 	get = return E
 	put _ = return ()
 
--- TODO: Header and Address instanes
+-- TODO: Header and Address instances
 
 instance Pretty IPv6 where
 	pPrint (IPv6 i) = cat . alternate colon . map (pHex 2) $ (B.unpack i)
@@ -84,27 +85,25 @@
   go (a:b:c:xs) = a : b : f : go (c:xs)
   go x = x
 
-second :: GenParser Char st [String]
-second = do
-		P.char ':'
-		x <- many1 hexDigit
-		xs <- second
-		return (x : xs)
-	 <|>
-		return []
-
-first :: GenParser Char st [String]
-first = do
-	x <- many1 hexDigit
-	(do	P.char ':'
-		xs <- first
-		return (x:xs)
-	 <|> return [x])
-	<|> return []
-
 ipv6 :: GenParser Char st IPv6
-ipv6 = do error "blah"
+ipv6 = do
+	blocks <- sepBy1 (many hexDigit) (P.char ':')
+	let blocks' = expand blocks
+	    vals = map (fst . head . readHex) blocks'
+	    -- bs = runPut (mapM_ putWord16be vals)
+	    cblks = combine blocks
+	    bs = runPut . mapM_ putWord16be . map (fst . head . readHex) . expand $ cblks
+	when (1 < length (filter (=="") cblks)) (fail "IPv6 Address with only one :: entry")
+	when (B.length bs /= 16) (fail "IPv6 Address of proper length")
+	return (IPv6 bs)
   where
-  replace :: (Eq a) => a -> [a] -> [a] -> [a]
-  replace _ _ [] = []
-  replace n r (x:xs) = if n == x then r ++ xs else x : replace n r xs
+  expand :: [String] -> [String]
+  expand as = replace (replicate (8 - length as + 1) "0") as
+
+replace :: (Eq a) => [[a]] -> [[a]] -> [[a]]
+replace _ [] = []
+replace r ([]:xs) = r ++ xs
+replace r (x:xs)  = x : replace r xs
+
+combine :: (Eq a) => [[a]] -> [[a]]
+combine = concat . map (\x -> if [] `elem` x then [[]] else x) . group
diff --git a/Data/UDP.hs b/Data/UDP.hs
--- a/Data/UDP.hs
+++ b/Data/UDP.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}
 module Data.UDP
-	( UDPPort
+	( UDPPort(..)
 	, UDPHeader (..)
 	) where
 
diff --git a/network-data.cabal b/network-data.cabal
--- a/network-data.cabal
+++ b/network-data.cabal
@@ -1,5 +1,5 @@
 name:		network-data
-version:	0.0.2
+version:	0.1.0
 license:	BSD3
 license-file:	LICENSE
 author:		Thomas DuBuisson <thomas.dubuisson@gmail.com>
@@ -9,7 +9,7 @@
 		Data type/functions for full packets, better typeclass setup, and a more agreeable interface
 		with a berkeley sockets like API should be coming soon.  Also, test cases - this code is
 		untested as of yet.
-category:	Data, Networking
+category:	Data, Network
 stability:	stable
 build-type:	Simple
 cabal-version:	>= 1.2
@@ -20,10 +20,12 @@
   Description: Choose the split-up base package.
 
 Library
-  if flag(small_base)
-    Build-Depends: base >= 3, bytestring >= 0.9 && < 1.0, binary >= 0.4.0 && < 0.5.0, prettyclass, pretty, parsec
-  else
-    Build-Depends: base >= 3, bytestring >= 0.9 && < 1.0, binary >= 0.4.0 && <0.5.0, prettyclass, pretty, parsec
+  Build-Depends: base >= 3 && < 5,
+                   bytestring >= 0.9 && < 1.0,
+                   binary >= 0.5.0 && < 0.6.0,
+                   prettyclass >= 1.0.0.0 && < 1.1,
+                   pretty >= 1.0.0 && < 1.1.0,
+                   parsec >= 3 && < 4
   hs-source-dirs:
   exposed-modules: Data.IP, Data.IPv6, Data.Header, Data.TCP, Data.UDP, Data.CSum
   ghc-options: 
