i made this script-like code
This commit is contained in:
commit
d504ccf992
5 changed files with 123 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
*.hi
|
||||||
|
*.o
|
||||||
|
input
|
||||||
7
README.md
Normal file
7
README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
VERY dumb and simple attempt to catch some computers online if they're connected to you through the Yggdrasil and you're the peer to them.
|
||||||
|
|
||||||
|
Use with command
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo journalctl -xeu yggdrasil --no-pager -o json-pretty | jq ".MESSAGE" -r | cut -f3- -d' ' | sed 's/inbound:/Inbound/; s/outbound:/Outbound/' | cut -f1 -d@ | sed 's/$/"/;' | ./yggscraper
|
||||||
|
```
|
||||||
12
shell.nix
Normal file
12
shell.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
pkgs.jq
|
||||||
|
(pkgs.haskellPackages.ghcWithPackages (p: with p; [
|
||||||
|
ip
|
||||||
|
haskell-language-server
|
||||||
|
]))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
BIN
yggscraper
Executable file
BIN
yggscraper
Executable file
Binary file not shown.
101
yggscraper.hs
Normal file
101
yggscraper.hs
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
module Main where
|
||||||
|
|
||||||
|
import Net.IP ( IP )
|
||||||
|
import qualified Net.IP as IP
|
||||||
|
import qualified Net.IPv4 as NIPv4
|
||||||
|
import qualified Net.IPv6 as NIPv6
|
||||||
|
import qualified Data.Text as T
|
||||||
|
|
||||||
|
import System.Directory
|
||||||
|
( doesFileExist, getXdgDirectory, XdgDirectory(XdgConfig) )
|
||||||
|
import System.FilePath ((</>))
|
||||||
|
|
||||||
|
import Data.Set (empty, Set, insert, delete, toList)
|
||||||
|
import Data.String ( IsString(fromString) )
|
||||||
|
import Data.Maybe (catMaybes)
|
||||||
|
|
||||||
|
data Bound
|
||||||
|
= Inbound
|
||||||
|
| Outbound
|
||||||
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
|
data LogRecord
|
||||||
|
= Connected Bound IP
|
||||||
|
| Disconnected Bound IP
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
parseBound :: String -> Maybe Bound
|
||||||
|
parseBound "Inbound" = Just Inbound
|
||||||
|
parseBound "Outbound" = Just Outbound
|
||||||
|
parseBound _ = Nothing
|
||||||
|
|
||||||
|
parseLogRecord :: String -> Maybe LogRecord
|
||||||
|
parseLogRecord s =
|
||||||
|
case words s of
|
||||||
|
["Connected", b, ipTxt] -> do
|
||||||
|
bound <- parseBound b
|
||||||
|
ip <- IP.decode . fromString $ ipTxt
|
||||||
|
pure (Connected bound ip)
|
||||||
|
["Disconnected", b, ipTxt] -> do
|
||||||
|
bound <- parseBound b
|
||||||
|
ip <- IP.decode . fromString $ ipTxt
|
||||||
|
pure (Disconnected bound ip)
|
||||||
|
_ -> Nothing
|
||||||
|
|
||||||
|
type Connection = (Bound, IP)
|
||||||
|
|
||||||
|
data SuperIP
|
||||||
|
= Address IP
|
||||||
|
| Range4 NIPv4.IPv4Range
|
||||||
|
| Range6 NIPv6.IPv6Range
|
||||||
|
|
||||||
|
inSuper :: SuperIP -> IP -> Bool
|
||||||
|
inSuper (Address i0) i1 = i0 == i1
|
||||||
|
inSuper (Range4 r4) ip =
|
||||||
|
IP.case_
|
||||||
|
(\ip4 -> NIPv4.member ip4 r4)
|
||||||
|
(\_ -> False)
|
||||||
|
ip
|
||||||
|
inSuper (Range6 r6) ip =
|
||||||
|
IP.case_
|
||||||
|
(\_ -> False)
|
||||||
|
(\ip6 -> NIPv6.member ip6 r6)
|
||||||
|
ip
|
||||||
|
|
||||||
|
instance Read SuperIP where
|
||||||
|
readsPrec :: Int -> ReadS SuperIP
|
||||||
|
readsPrec _ c
|
||||||
|
| Just i <- IP.decode s = [(Address i, "")]
|
||||||
|
| Just r4 <- NIPv4.decodeRange s = [(Range4 r4, "")]
|
||||||
|
| Just r6 <- NIPv6.decodeRange s = [(Range6 r6, "")]
|
||||||
|
| otherwise = []
|
||||||
|
where
|
||||||
|
s = fromString c
|
||||||
|
|
||||||
|
instance Show SuperIP where
|
||||||
|
show (Address ip) = show ip
|
||||||
|
show (Range4 r) = show r
|
||||||
|
show (Range6 r) = show r
|
||||||
|
|
||||||
|
f :: Set Connection -> LogRecord -> Set Connection
|
||||||
|
f s (Connected b ip) = insert (b, ip) s
|
||||||
|
f s (Disconnected b ip) = delete (b, ip) s
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
dir <- getXdgDirectory XdgConfig "yggscraper"
|
||||||
|
let path = dir </> "blacklist"
|
||||||
|
exists <- doesFileExist path
|
||||||
|
blacklist <- if exists
|
||||||
|
then do
|
||||||
|
blacklistFile <- readFile (dir </> "blacklist")
|
||||||
|
return . map (\x -> read x :: SuperIP) . lines $ blacklistFile
|
||||||
|
else
|
||||||
|
return []
|
||||||
|
|
||||||
|
strs <- getContents
|
||||||
|
let xs = catMaybes . map parseLogRecord . lines $ strs
|
||||||
|
online = toList $ foldl' f empty xs
|
||||||
|
finder (_, ip) = any (\x -> inSuper x ip)
|
||||||
|
notBlacklisted = [x | x <- online, not $ finder x blacklist]
|
||||||
|
putStrLn . T.unpack . T.unlines . map (IP.encode . snd) $ notBlacklisted
|
||||||
Loading…
Add table
Add a link
Reference in a new issue