module Network.Wai.Logger.IP (
NumericAddress, showSockAddr
) where
import Data.Bits (shift, (.&.))
import Data.Word (Word32)
import Network.Socket (SockAddr(..))
import System.ByteOrder (ByteOrder(..), byteOrder)
import Text.Printf (printf)
type NumericAddress = String
showIPv4 :: Word32 -> Bool -> NumericAddress
showIPv4 :: Word32 -> Bool -> NumericAddress
showIPv4 w32 :: Word32
w32 little :: Bool
little
| Bool
little = Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b1 NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ "." NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b2 NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ "." NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b3 NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ "." NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b4
| Bool
otherwise = Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b4 NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ "." NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b3 NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ "." NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b2 NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ "." NumericAddress -> NumericAddress -> NumericAddress
forall a. [a] -> [a] -> [a]
++ Word32 -> NumericAddress
forall a. Show a => a -> NumericAddress
show Word32
b1
where
t1 :: Word32
t1 = Word32
w32
t2 :: Word32
t2 = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shift Word32
t1 (-8)
t3 :: Word32
t3 = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shift Word32
t2 (-8)
t4 :: Word32
t4 = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shift Word32
t3 (-8)
b1 :: Word32
b1 = Word32
t1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. 0x000000ff
b2 :: Word32
b2 = Word32
t2 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. 0x000000ff
b3 :: Word32
b3 = Word32
t3 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. 0x000000ff
b4 :: Word32
b4 = Word32
t4 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. 0x000000ff
showIPv6 :: (Word32,Word32,Word32,Word32) -> String
showIPv6 :: (Word32, Word32, Word32, Word32) -> NumericAddress
showIPv6 (w1 :: Word32
w1,w2 :: Word32
w2,w3 :: Word32
w3,w4 :: Word32
w4) =
NumericAddress
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> NumericAddress
forall r. PrintfType r => NumericAddress -> r
printf "%x:%x:%x:%x:%x:%x:%x:%x" Word32
s1 Word32
s2 Word32
s3 Word32
s4 Word32
s5 Word32
s6 Word32
s7 Word32
s8
where
(s1 :: Word32
s1,s2 :: Word32
s2) = Word32 -> (Word32, Word32)
forall a. (Bits a, Num a) => a -> (a, a)
split16 Word32
w1
(s3 :: Word32
s3,s4 :: Word32
s4) = Word32 -> (Word32, Word32)
forall a. (Bits a, Num a) => a -> (a, a)
split16 Word32
w2
(s5 :: Word32
s5,s6 :: Word32
s6) = Word32 -> (Word32, Word32)
forall a. (Bits a, Num a) => a -> (a, a)
split16 Word32
w3
(s7 :: Word32
s7,s8 :: Word32
s8) = Word32 -> (Word32, Word32)
forall a. (Bits a, Num a) => a -> (a, a)
split16 Word32
w4
split16 :: a -> (a, a)
split16 w :: a
w = (a
h1,a
h2)
where
h1 :: a
h1 = a -> Int -> a
forall a. Bits a => a -> Int -> a
shift a
w (-16) a -> a -> a
forall a. Bits a => a -> a -> a
.&. 0x0000ffff
h2 :: a
h2 = a
w a -> a -> a
forall a. Bits a => a -> a -> a
.&. 0x0000ffff
showSockAddr :: SockAddr -> NumericAddress
showSockAddr :: SockAddr -> NumericAddress
showSockAddr (SockAddrInet _ addr4 :: Word32
addr4) = Word32 -> Bool -> NumericAddress
showIPv4 Word32
addr4 (ByteOrder
byteOrder ByteOrder -> ByteOrder -> Bool
forall a. Eq a => a -> a -> Bool
== ByteOrder
LittleEndian)
showSockAddr (SockAddrInet6 _ _ (0,0,0x0000ffff,addr4 :: Word32
addr4) _) = Word32 -> Bool -> NumericAddress
showIPv4 Word32
addr4 Bool
False
showSockAddr (SockAddrInet6 _ _ (0,0,0,1) _) = "::1"
showSockAddr (SockAddrInet6 _ _ addr6 :: (Word32, Word32, Word32, Word32)
addr6 _) = (Word32, Word32, Word32, Word32) -> NumericAddress
showIPv6 (Word32, Word32, Word32, Word32)
addr6
showSockAddr _ = "unknownSocket"