Quick actions

cmd+k|ctrl+k

Navigation

Languages

Untitled

Snippet info

Language

Raku

Visibility

unlisted

Author

legacy-anonymous

Created

2026-01-08T11:23:53.071966Z

Updated

2026-01-08T11:23:53.071966Z

#!/usr/bin/env raku

# Zig Glue
###########
use NativeCall;

enum Action <ALLOW DENY REJECT>;
enum Proto  <TCP UDP>;

class Rule is repr('CStruct') {
    has uint8  $!action;
    has uint8  $!proto;
    has uint32 $!port;

    method gist   { (Action($!action), Proto($!proto), $!port).join(' ') }
    method to-hex { nativecast(CArray[uint8], self)[^nativesizeof(self)].fmt("%02x", "") }

    submethod TWEAK(*%opt) { ($!action, $!proto, $!port) = %opt<action proto port> }
}

sub apply_rule(Rule --> bool) is native('./libfirewall.so') {*}

# Firewall Config Grammar
#########################
grammar Firewall {
    token TOP    { <rule>+ %% \n+ }
    token rule   { <action> \s+ <proto> \s+ <port> }
    token action { 'ALLOW' | 'DENY' | 'REJECT' }
    token proto  { 'TCP' | 'UDP' }
    token port   { \d+ }
}

class FirewallAction {
    method TOP($/)  { make $<rule>>>.made }
    method rule($/) { 
        make Rule.new(
            :action(Action::{$<action>}),
            :proto(Proto::{$<proto>}),
            :port($<port>.Int)
        );
    }
}

# CLI Handling
##############
sub MAIN (
    $file where *.IO.f, #= Firewall Config File
) {
    my @rules = Firewall.parse($file.IO.slurp, :actions(FirewallAction.new)).made;
    @rules.map: { say "[R] ", $^rule, " => ", $^rule.to-hex and apply_rule($^rule) };
}
INFO