summaryrefslogtreecommitdiff
path: root/src/Network/UPNP.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/UPNP.hs')
-rw-r--r--src/Network/UPNP.hs39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/Network/UPNP.hs b/src/Network/UPNP.hs
new file mode 100644
index 00000000..fff1ba5b
--- /dev/null
+++ b/src/Network/UPNP.hs
@@ -0,0 +1,39 @@
1module Network.UPNP where
2
3import Data.Maybe
4import Network.Address (sockAddrPort)
5import Network.Socket
6import System.Directory
7import System.IO
8import System.Process as Process
9
10protocols :: SocketType -> [String]
11protocols Stream = ["tcp"]
12protocols Datagram = ["udp"]
13protocols _ = ["udp","tcp"]
14
15upnpc :: FilePath
16upnpc = "/usr/bin/upnpc"
17
18-- | Invokes the miniupnpc command line program to request ports from a UPNP
19-- wifi router. Returns the process handle on success.
20requestPorts :: String -- ^ Description stored on router, currently ignored.
21 -> [(SocketType, SockAddr)] -- ^ Protocol-port pairs to request.
22 -> IO (Maybe ProcessHandle)
23requestPorts description binds = do
24 let requests = do
25 (stype,saddr) <- binds
26 proto <- protocols stype
27 port <- maybeToList (sockAddrPort saddr)
28 [ show port, proto ]
29 bail = return Nothing
30 case requests of
31 [] -> bail
32 _ -> do
33 gotMiniUPNPC <- doesFileExist upnpc
34 if gotMiniUPNPC then do
35 phandle <- spawnProcess upnpc $ "-r" : requests
36 return $ Just phandle
37 else do
38 hPutStrLn stderr $ "Warning: unable to find miniupnpc client at "++upnpc++"."
39 bail