{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE OverloadedStrings #-} module Main where import Hans import Hans.Dns import Hans.Device import Hans.Nat import Hans.Socket import Hans.IP4.Packet (pattern WildcardIP4) import Hans.IP4.Dhcp.Client (DhcpLease(..),defaultDhcpConfig,dhcpClient) import Control.Concurrent (forkIO,threadDelay) import Control.Exception import Control.Monad (forever) import qualified Data.ByteString.Char8 as S8 import qualified Data.ByteString.Lazy.Char8 as L8 import System.Environment (getArgs) import System.Exit (exitFailure) main :: IO () main = do args <- getArgs (name,dhcp) <- case args of [name,"dhcp"] -> return (S8.pack name,True) name:_ -> return (S8.pack name,False) _ -> fail "Expected a device name" ns <- newNetworkStack defaultConfig dev <- addDevice ns name defaultDeviceConfig _ <- forkIO (showExceptions "processPackets" (processPackets ns)) -- start receiving data startDevice dev if dhcp then do mbLease <- dhcpClient ns defaultDhcpConfig dev case mbLease of Just lease -> do putStrLn ("Assigned IP: " ++ show (unpackIP4 (dhcpAddr lease))) print =<< getHostByName ns "galois.com" Nothing -> do putStrLn "Dhcp failed" exitFailure else do putStrLn "Static IP: 192.168.71.11/24" addIP4Route ns False Route { routeNetwork = IP4Mask (packIP4 192 168 71 11) 24 , routeType = Direct , routeDevice = dev } addIP4Route ns True Route { routeNetwork = IP4Mask (packIP4 192 168 71 11) 0 , routeType = Indirect (packIP4 192 168 71 1) , routeDevice = dev } forwardTcpPort ns WildcardIP4 22 (packIP4 172 16 181 1) 22 forwardUdpPort ns WildcardIP4 9090 (packIP4 172 16 181 128) 9090 sock <- sListen ns defaultSocketConfig WildcardIP4 9001 10 _ <- forkIO $ forever $ do putStrLn "Waiting for a client" client <- sAccept (sock :: TcpListenSocket IP4) putStrLn "Got a client" _ <- forkIO (handleClient client) return () threadDelay (300 * 1000000) dumpStats (devStats dev) showExceptions :: String -> IO a -> IO a showExceptions l m = m `catch` \ e -> do print (l, e :: SomeException) throwIO e handleClient :: TcpSocket IP4 -> IO () handleClient sock = loop `finally` sClose sock where loop = do str <- sRead sock 1024 if L8.null str then putStrLn "Closing client" else do _ <- sWrite sock str loop