|
Packit |
fc2124 |
{-# LANGUAGE OverloadedStrings #-}
|
|
Packit |
fc2124 |
import Network.Socks5
|
|
Packit |
fc2124 |
import Network.Socket hiding (recv, sClose)
|
|
Packit |
fc2124 |
import Network.Socket.ByteString
|
|
Packit |
fc2124 |
import Network.BSD
|
|
Packit |
fc2124 |
import Network
|
|
Packit |
fc2124 |
import Data.ByteString.Char8 ()
|
|
Packit |
fc2124 |
import qualified Data.ByteString.Char8 as BC
|
|
Packit |
fc2124 |
|
|
Packit |
fc2124 |
import System.IO (hClose, hFlush)
|
|
Packit |
fc2124 |
import System.Environment (getArgs)
|
|
Packit |
fc2124 |
|
|
Packit |
fc2124 |
main = do
|
|
Packit |
fc2124 |
args <- getArgs
|
|
Packit |
fc2124 |
let serverName = "localhost"
|
|
Packit |
fc2124 |
let serverPort = 1080
|
|
Packit |
fc2124 |
let destinationName = case args of
|
|
Packit |
fc2124 |
[] -> "www.google.com"
|
|
Packit |
fc2124 |
(x:_) -> x
|
|
Packit |
fc2124 |
-- socks server is expected to be running on localhost port 1080
|
|
Packit |
fc2124 |
he <- getHostByName serverName
|
|
Packit |
fc2124 |
let socksServerAddr = SockAddrInet serverPort (head $ hostAddresses he)
|
|
Packit |
fc2124 |
|
|
Packit |
fc2124 |
example1 socksServerAddr destinationName
|
|
Packit |
fc2124 |
example2 socksServerAddr destinationName
|
|
Packit |
fc2124 |
|
|
Packit |
fc2124 |
example3 serverName serverPort destinationName 80
|
|
Packit |
fc2124 |
|
|
Packit |
fc2124 |
where
|
|
Packit |
fc2124 |
-- connect to @destName on port 80 through the socks server
|
|
Packit |
fc2124 |
-- www.google.com get resolve on the client here and then the sockaddr is
|
|
Packit |
fc2124 |
-- passed to socksConnectAddr
|
|
Packit |
fc2124 |
example1 socksServerAddr destName = do
|
|
Packit |
fc2124 |
socket <- socket AF_INET Stream defaultProtocol
|
|
Packit |
fc2124 |
socksConnectWithSocket socket (defaultSocksConfFromSockAddr socksServerAddr)
|
|
Packit |
fc2124 |
(SocksAddress (SocksAddrDomainName $ BC.pack destName) 80)
|
|
Packit |
fc2124 |
|
|
Packit |
fc2124 |
sendAll socket "GET / HTTP/1.0\r\n\r\n"
|
|
Packit |
fc2124 |
recv socket 4096 >>= putStrLn . show
|
|
Packit |
fc2124 |
sClose socket
|
|
Packit |
fc2124 |
-- connect to @destName on port 80 through the socks server
|
|
Packit |
fc2124 |
-- the server is doing the resolution itself
|
|
Packit |
fc2124 |
example2 socksServerAddr destName = do
|
|
Packit |
fc2124 |
socket <- socket AF_INET Stream defaultProtocol
|
|
Packit |
fc2124 |
socksConnectName socket socksServerAddr destName 80
|
|
Packit |
fc2124 |
sendAll socket "GET / HTTP/1.0\r\n\r\n"
|
|
Packit |
fc2124 |
recv socket 4096 >>= putStrLn . show
|
|
Packit |
fc2124 |
sClose socket
|
|
Packit |
fc2124 |
|
|
Packit |
fc2124 |
example3 sname sport dname dport = do
|
|
Packit |
fc2124 |
handle <- socksConnectTo sname (PortNumber sport) dname (PortNumber dport)
|
|
Packit |
fc2124 |
BC.hPut handle "GET / HTTP/1.0\r\n\r\n"
|
|
Packit |
fc2124 |
hFlush handle
|
|
Packit |
fc2124 |
BC.hGet handle 1024 >>= putStrLn . show
|
|
Packit |
fc2124 |
hClose handle
|