Skip to content

Instantly share code, notes, and snippets.

@xandkar
Created October 20, 2012 05:00
Show Gist options
  • Save xandkar/3922070 to your computer and use it in GitHub Desktop.
Save xandkar/3922070 to your computer and use it in GitHub Desktop.
Concurrent port scanner in Haskell
-- http://blog.moertel.com/articles/2004/03/13/concurrent-port-scanner-in-haskell
module Main (main) where
import Control.Concurrent
import Control.Exception
import Data.Maybe
import Network
import Network.BSD
import System.Environment
import System.Exit
import System.IO
main :: IO ()
main = do
args <- getArgs
case args of
[host, from, to] -> withSocketsDo $
scanRange host [read from .. read to]
_ -> usage
usage = do
hPutStrLn stderr "Usage: Portscan host from_port to_port"
exitFailure
scanRange host ports =
mapM (threadWithChannel . scanPort host . fromIntegral) ports >>=
mapM_ hitCheck
where
hitCheck mvar = takeMVar mvar >>= maybe (return ()) printHit
printHit port = putStrLn =<< showService port
threadWithChannel action = do
mvar <- newEmptyMVar
forkIO (action >>= putMVar mvar)
return mvar
scanPort host port =
withDefault Nothing (tryPort >> return (Just port))
where
tryPort = connectTo host (PortNumber port) >>= hClose
showService port =
withDefault (show port) $ do
service <- getServiceByPort port "tcp"
return (show port ++ " " ++ serviceName service)
withDefault defaultVal action =
handle (const $ return defaultVal) action
-- Local Variables: ***
-- compile-command: "ghc -o Portscan --make Portscan.hs" ***
-- End: ***
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment