diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/UPNP.hs | 39 |
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 @@ | |||
1 | module Network.UPNP where | ||
2 | |||
3 | import Data.Maybe | ||
4 | import Network.Address (sockAddrPort) | ||
5 | import Network.Socket | ||
6 | import System.Directory | ||
7 | import System.IO | ||
8 | import System.Process as Process | ||
9 | |||
10 | protocols :: SocketType -> [String] | ||
11 | protocols Stream = ["tcp"] | ||
12 | protocols Datagram = ["udp"] | ||
13 | protocols _ = ["udp","tcp"] | ||
14 | |||
15 | upnpc :: FilePath | ||
16 | upnpc = "/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. | ||
20 | requestPorts :: String -- ^ Description stored on router, currently ignored. | ||
21 | -> [(SocketType, SockAddr)] -- ^ Protocol-port pairs to request. | ||
22 | -> IO (Maybe ProcessHandle) | ||
23 | requestPorts 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 | ||