#!/usr/bin/perl use Tk; use Tk::NoteBook; use Tk::HList; use Tk::ErrorDialog; use IPChains; use SNMP; $SNMP::save_descriptions=1; $SNMP::use_long_names=1; $SNMP::use_enums=1; SNMP::initMib(); $top = MainWindow->new(); $snmphost = "localhost"; $snmpport = "161"; $community = "public"; $fwpath = "."; $mibNum = 0; $mibTxt = ""; $currchain = ""; ## Build Menus $menubar = $top->Frame(-relief => "raised", -borderwidth => 2) ->pack(-anchor => "nw", -fill => "x"); # File menu $file_menu = $menubar->Menubutton(-text => "File", -underline => 0, -tearoff => 0) ->pack(-side => "left"); $file_menu->separator(); $file_menu->command(-label => "Exit", -command => sub { exit }); # Function Menu $func_menu = $menubar->Menubutton(-text => "Functions", -underline => 1, -tearoff => 0) ->pack(-side => "left"); $func_menu->checkbutton(-label => "IPChains", -variable => \$ipcon, -command => sub { if ($ipcon) { makeIPC(); } else { $book->delete("page1"); $ipc_menu->packForget; } }); $func_menu->checkbutton(-label => "SNMP", -variable => \$snmpon, -command => sub { if ($snmpon) { makeSNMP(); } else { $book->delete("page2"); $snmp_menu->packForget; } }); $func_menu->checkbutton(-label => "Network Monitor", -variable => \$netmonon, -command => sub { if ($netmonon) { makeNetMon(); } else { $book->delete("page3"); $net_menu->packForget; } }); $func_menu->checkbutton(-label => "Misc", -variable => \$miscon, -command => sub { if ($miscon) { makeMisc(); } else { $book->delete("page4"); $misc_menu->packForget; } }); # About Menu $about_menu = $menubar->Menubutton(-text => "About", -underline => 0) ->pack(-side => "right"); $about_menu->command(-label => "About jnet", -command => \&about); $book = $top->NoteBook(); $ipcon = 1; $snmpon = 1; makeIPC(); makeSNMP(); ################################################## sub makeSNMP { $book[2] = $book->add("page2", -label => "SNMP Utility"); $book->pack(); $hlist=$book[2]->Scrolled(qw(HList -itemtype imagetext -browsecmd main::showInfo -command main::showChildren -width 80 -height 15)); $hlist->pack(-side => 'top', -expand => 1, -fill => 'both'); foreach $i (qw(.1 .1.3 .1.3.6 .1.3.6.1)) { addMibOID($i); } showChildren("1.3.6.1"); $mFrame = $book[2]->Frame(-relief => 'raised', -borderwidth => 3) ->pack(-side => 'top', -fill => 'x'); $mibNum = $mFrame->Label(-text => '') ->pack(-side => 'left'); $mibTxt = $mFrame->Label(-text => '') ->pack(-side => 'right'); $bFrame = $book[2]->Frame(-relief => 'raised', -borderwidth => 3) ->pack(-side => 'top', -fill => 'x'); $bFrame->Button(-text => " Get ", -command => \&snmpget) ->pack(-side => 'left', -expand => 1, -fill => 'x'); $bFrame->Button(-text => " Get Next ", -command => \&snmpgetnext) ->pack(-side => 'left', -expand => 1, -fill => 'x'); $bFrame->Button(-text => " Get Table ", -command => \&snmpgettable) ->pack(-side => 'left', -expand => 1, -fill => 'x'); $bFrame->Button(-text => " MIB Walk ", -command => \&snmpwalk) ->pack(-side => 'left', -expand => 1, -fill => 'x'); $dFrame = $book[2]->Frame(-relief => 'raised', -borderwidth => 3); $descr = $dFrame->Scrolled(qw(Text -width 120 -height 4)); if ($showdesc) { $dFrame->pack(-side => 'top', -fill => 'x'); $descr->pack(-side => 'top', -fill => 'x'); } $rFrame = $book[2]->Frame(-relief => 'raised', -borderwidth => 3) ->pack(-side => 'top', -fill => 'x'); $result = $rFrame->Scrolled(qw(Text -width 120 -height 4)) ->pack(-side => 'top', -fill => 'x'); $snmp_menu = $menubar->Menubutton(-text => 'SNMP', -underline => 0, -tearoff => 0) ->pack(-side => "left"); $snmp_menu->checkbutton(-label => "Show Desc", -variable => \$showdesc, -command => sub { if ($showdesc) { $dFrame->pack(-side => 'top', -fill => 'x'); $descr->pack(-side => 'top', -fill => 'x'); } else { $descr->packForget; $dFrame->packForget; } }); $rFrame->Label(-text => "Hostname: ") ->pack(-side => "left"); $host_entry = $rFrame->Entry(-width => 30, -textvariable => \$snmphost) ->pack(-side => "left"); $rFrame->Label(-text => "Port: ") ->pack(-side => "left"); $port_entry = $rFrame->Entry(-width => 4, -textvariable => \$snmpport) ->pack(-side => "left"); $rFrame->Label(-text => "Community: ") ->pack(-side => "left"); $community_entry = $rFrame->Entry(-width => 15, -textvariable => \$community) ->pack(-side => "left"); $top->update; } ################################################## sub makeNetMon { $book[3] = $book->add("page3", -label => "Network Monitor"); $book->pack(); $net_menu = $menubar->Menubutton(-text => "NetMon", -underline => 0, -tearoff => 0) ->pack(-side => "left"); $top->update; } ################################################## sub makeMisc { $book[4] = $book->add("page4", -label => "Misc"); $book->pack(); $misc_menu = $menubar->Menubutton(-text => "Misc", -underline => 0, -tearoff => 0) ->pack(-side => "left"); $top->update; } ################################################## sub makeIPC { my @rules; my $rule; $book[1] = $book->add("page1", -label => "IPChains" ); $book->pack(); $ipc_menu = $menubar->Menubutton(-text => "IPChains", -underline => 0, -tearoff => 0) ->pack(-side => "left"); $ipc_menu->command(-label => "New Profile", -command => \&new_profile); $ipc_menu->command(-label => "New Rule", -command => \&new_rule); $ipc_menu->separator(); $load_menu = $ipc_menu->cascade(-label => "Load...", -tearoff => 0); $load_menu->command(-label => "Profile", -command => \&load_profile); $load_menu->command(-label => "Rule", -command => \&load_rule); $save_menu = $ipc_menu->cascade(-label => "Save...", -tearoff => 0); $save_menu->command(-label => "Profile", -command => \&save_profile); $save_menu->command(-label => "Rule", -command => \&save_rule); $save_menu->command(-label => "Rule To", -command => \&add_rule); $ipc_menu->separator(); $ipc_menu->command(-label => "Create Chain", -command => \&create_chain); $ipc_menu->command(-label => "Delete Chain", -command => \&delete_chain); $ipc_menu->command(-label => "List Chains", -command => sub { my $chain; my @chains = get_cnames(); my $list = $top->Toplevel(-width => 100, -height => 50); my $listBox = $list->Scrolled(qw(Text -width 20 -height 6))->pack(); foreach $chain (@chains) { $listBox->insert("end", "$chain\n"); } } ); $ipcMain = $book[1]->Frame() ->pack(-side => "top", -expand => 1, -fill => "both"); $ruleFrame = $ipcMain->Frame(-relief => "groove", -borderwidth => 3) ->pack(-side => "left", -anchor => "n", -fill => 'y'); my @chains = get_cnames(); my $chain; open(FWNAMES, "/proc/net/ip_fwnames"); while() { $_ =~ m/(^\w*) (\w*)/; $$1 = $ruleFrame->Button(-text => "$1\t$2", -command => [ \&show_rules, $1]) ->pack(-side => "top", -fill => "x"); } close(FWNAMES); $setoptsFrame = $ipcMain->Frame(-label => "\nRule Attributes\n", -relief => "sunken", -borderwidth => 3) ->pack(-side => "left", -fill => "both", -expand => 1); $addrFrame = $setoptsFrame->Frame() ->pack(-side => "top"); $addrFrame->Label(-text => "Source Address/Mask Port: ") ->grid(-row => 0, -column => 0, -sticky => "w"); $addrFrame->Entry(-width => 15, -textvariable => \$saddr) ->grid(-row => 0, -column => 1, -padx => "5"); $addrFrame->Label(-text => "/") ->grid(-row => 0, -column => 2); $addrFrame->Entry(-width => 15, -textvariable => \$smask) ->grid(-row => 0, -column => 3, -padx => "5"); $addrFrame->Entry(-width => 6, -textvariable => \$sport) ->grid(-row => 0, -column => 4, -padx => "5"); $addrFrame->Label(-text => "Destination Address/Mask Port: ") ->grid(-row => 1, -column => 0, -sticky => "w"); $addrFrame->Entry(-width => 15, -textvariable => \$daddr) ->grid(-row => 1, -column => 1); $addrFrame->Label(-text => "/") ->grid(-row => 1, -column => 2); $addrFrame->Entry(-width => 15, -textvariable => \$dmask) ->grid(-row => 1, -column => 3); $addrFrame->Entry(-width => 6, -textvariable => \$dport) ->grid(-row => 1, -column => 4); $daddr = $saddr = "0.0.0.0"; $dport = $sport = "0"; $dmask = $smask = "0.0.0.0"; $optsFrame = $setoptsFrame->Frame() ->pack(-side => "top", -fill => "x", -pady => 10); $optsFrame->Label(-text => "Protocol: ") ->grid(-row => 0, -column => 1, -ipadx => 5); my $i = 2; $prots{'ALL'} = 0; $prots{'TCP'} = 6; $prots{'ICMP'} = 1; $prots{'UDP'} = 17; foreach (qw(ALL TCP UDP ICMP)) { $optsFrame->Radiobutton(-text => $_, -value => $prots{"$_"}, -variable => \$protocol) ->grid(-row => 0, -column => $i, -pady => 8); $i++; } $protocol = "0"; $optsFrame->Label(-text => " ") ->grid(-row => 0, -column => $i++); $optsFrame->Button(-text => "Chain: ", -command => sub { my @chains = get_cnames(); my $cinput = $top->Toplevel(-width => 200, -height => 200); my $listbox = $cinput->Scrolled("Listbox", -scrollbars => "w", -selectmode => "single", -height => 4) ->pack(-side => "top"); $listbox->insert("end", @chains); my $okbutton = $cinput->Button(-text => "OK", -command => sub { $ipcchain = $listbox->get($listbox->curselection()); $cinput->destroy(); }) ->pack(-side => "top"); }) ->grid(-row => 1, -column => 0); $optsFrame->Entry(-width => 10, -textvariable => \$ipcchain) ->grid(-row => 1, -column => 1); $optsFrame->Label() ->grid(-row => 1, -column => 2); $optsFrame->Button(-text => "Target:", -command => sub { my @chains = get_cnames(); splice(@chains, 0, 3); unshift(@chains, qw(ACCEPT DENY REJECT MASQ REDIRECT RETURN)); my $tinput = $top->Toplevel(-width => 200, -height => 200); my $listbox = $tinput->Scrolled("Listbox", -scrollbars => "w", -selectmode => "single", -height => 4) ->pack(-side => "top"); $listbox->insert("end", @chains); my $okbutton = $tinput->Button(-text => "OK", -command => sub { $target = $listbox->get($listbox->curselection()); $tinput->destroy(); }) ->pack(-side => "top"); }) ->grid(-row => 1, -column => 3); $optsFrame->Entry(-width => 10, -textvariable => \$target) ->grid(-row => 1, -column => 4); $optsFrame->Label() ->grid(-row => 1, -column => 5); $optsFrame->Button(-text => "Iface: ", -command => sub { my @ifs = get_ifs(); my $iinput = $top->Toplevel(-width => 200, -height => 200); my $listbox = $iinput->Scrolled("Listbox", -scrollbars => "w", -selectmode => "single", -height => 4) ->pack(-side => "top"); $listbox->insert("end", @ifs); my $okbutton = $iinput->Button(-text => "OK", -command => sub { $ipciface = $listbox->get($listbox->curselection()); $iinput->destroy(); }) ->pack(-side => "top"); }) ->grid(-row => 1, -column => 6); $optsFrame->Entry(-width => 10, -textvariable => \$ipciface) ->grid(-row => 1, -column => 7); $advFrame = $setoptsFrame->Frame() ->pack(-side => "top", -fill => "x"); $advFrame->Button(-text => "TOS: ", -command => sub { my @tos = ("Minimum Delay", "Maximum Throughput", "Maximum Reliability", "Minimum Cost"); my $tinput = $top->Toplevel(-width => 200, -height => 200); my $listbox = $tinput->Scrolled("Listbox", -scrollbars => "w", -selectmode => "single", -height => 4) ->pack(-side => "top"); $listbox->insert("end", @tos); my $okbutton = $tinput->Button(-text => "OK", -command => sub { $tos = $listbox->get($listbox->curselection()); $tinput->destroy(); $tosand = "0x01"; if ( $tos eq "Minimum Delay" ) { $tosxor = "0x10"; } elsif ( $tos eq "Maximum Throughput" ) { $tosxor = "0x08"; } elsif ( $tos eq "Maximum Reliability" ) { $tosxor = "0x04"; } elsif ( $tos eq "Minimum Cost" ) { $tosxor = "0x02"; } }) ->pack(-side => "top"); }) ->grid(-row => 0, -column => 0); $advFrame->Entry(-width => 4, -textvariable => \$tosand) ->grid(-row => 0, -column => 1); $advFrame->Entry(-width => 4, -textvariable => \$tosxor) ->grid(-row => 0, -column => 2); $advFrame->Label(-text => " Mark: ") ->grid(-row => 0, -column => 3); $advFrame->Entry(-width => 2, -textvariable => \$ipcmark) ->grid(-row => 0, -column => 4); $optFrame = $setoptsFrame->Frame() ->pack(-side => 'top', -fill => 'x'); $optFrame->Checkbutton(-text => "Fragment ", -variable => \$fragment) ->grid(-row => 1, -column => 0); $optFrame->Checkbutton(-text => "Bidirectional ", -variable => \$bidir) ->grid(-row => 1, -column => 1); $optFrame->Checkbutton(-text => "Log ", -variable => \$log) ->grid(-row => 1, -column => 2); $optFrame->Checkbutton(-text => "Exact ", -variable => \$exact) ->grid(-row => 1, -column => 3); $optFrame->Checkbutton(-text => "SYN only ", -variable => \$syn) ->grid(-row => 1, -column => 4); # $advFrame->Checkbutton(-text => "Output:", # -variable => \$output) # ->grid(-row => 2, -column => 2); # $advFrame->Entry(-width => 2, -textvariable => \$maxoutput) # ->grid(-row => 2, -column => 3); $rulecmdFrame = $setoptsFrame->Frame() ->pack(-side => 'top', -fill => 'x', -pady => 10); $rulecmdFrame->Button(-text => "Insert", -command => sub { rule_parse("insert") }) ->grid(-row => 2, -column => 1); $rulecmdFrame->Button(-text => "Append", -command => sub { rule_parse("append") }) ->grid(-row => 2, -column => 2); $rulecmdFrame->Button(-text => "Delete", -command => sub { if ( $rulenum ne "" && $ipcchain ne "" ) { $fw = IPChains->new(); $fw->delete($ipcchain, $rulenum); show_rules($currchain); } else { $okbox = $top->Dialog(-text => "No rule selected for Delete."); $okbox->Show(); } }) ->grid(-row => 2, -column => 3); $rulecmdFrame->Label(-text => " RuleNumber: ") ->grid(-row => 2, -column => 4); $rulecmdFrame->Entry(-width => 2, -textvariable => \$rulenum) ->grid(-row => 2, -column => 5); $ruleList = $setoptsFrame->Scrolled("Listbox", -height => 4, -scrollbars => "se") ->pack(-side => "bottom", -fill => "x"); $optionFrame = $ipcMain->Frame( -relief => "groove", -borderwidth => 3) ->pack(-side => "top", -anchor => "e", -fill => "y", -expand => 1); $optionFrame->Label(-text => "Commands: ") ->pack(-side => "top", -fill => "x", -pady => 5); $refresh = $optionFrame->Button(-text => "Refresh Rules", -command => sub { if ( $currchain ne "" ) { show_rules($currchain); } }) ->pack(-side => "top", -fill => "x"); $flush = $optionFrame->Button(-text => "Flush Rules", -command => sub { my $fw = IPChains->new(); $fw->flush("$currchain"); show_rules("$currchain"); }) ->pack(-side => "top", -fill => "x"); $zero = $optionFrame->Button(-text => "Zero Counters", -command => sub { my $fw = IPChains->new(); $fw->zero("$currchain"); }) ->pack(-side => "top", -fill => "x"); $counters = $optionFrame->Button(-text => "Show Counters", -command => \&show_counters) ->pack(-side => "top", -fill => "x"); $showmasq = $optionFrame->Button(-text => "Show Masqueraded", -command => sub { # make masq top-like list for current connections w/ refresh opt. not_here(); }) ->pack(-side => "top", -fill => "x"); $newchain = $optionFrame->Button(-text => "Create Chain", -command => \&create_chain) ->pack(-side => "top", -fill => "x"); $deletechain = $optionFrame->Button(-text => "Delete Chain", -command => \&delete_chain) ->pack(-side => "top", -fill => "x"); $setdefault = $optionFrame->Button(-text => "Set Policy", -command => sub { # select default policy for specified rule # drop boxes w/ available rules/policies. not_here(); }) ->pack(-side => "top", -fill => "x"); $optionFrame->Label(-text => "Utilities: ") ->pack(-side => "top", -fill => "x", -pady => 5); $ipcalc = $optionFrame->Button(-text => "IP Calc", -command => sub { # gui interface to ipcalc in new toplevel not_here(); }) ->pack(-side => "top", -fill => "x"); $ipmasqadm = $optionFrame->Button(-text => "ipmasqadm", -command => sub { # new toplevel for interface to ipmasqadm functions not_here(); }) ->pack(-side => "top", -fill => "x"); $service = $optionFrame->Button(-text => "Service Lookup", -command => sub { # some sort of interface to give port and get service # and vice versa. getservent() or whatever. not_here(); }) ->pack(-side => "top", -fill => "x"); $ipcstatus = $book[1]->Label(-text => "This space intentionally left blank.", -relief => "raised", -borderwidth => 3) ->pack(-side => "top", -fill => "x"); } ################################################## MainLoop(); #### IPChains functions sub not_here { $okbox = $top->Dialog(-text => "This feature is not yet implemented."); $okbox->Show(); } sub rule_parse { my $command = shift; # ICMP => seems redundant, maybe it will just take it as sourceport? my $fw = IPChains->new( Source => "$saddr", Dest => "$daddr", SourceMask => "$smask", DestMask => "$dmask", Prot => "$protocol", Interface => "$ipciface", Rule => "$target", TOS => ["$tosand", "$tosxor"], Mark => "$ipcmark", Fragment => "$fragment", Bidir => "$bidir", Log => "$log", ); if ( $protocol = 6 && $SYN ) { $fw->attribute( "SYN", "$SYN" ); } elsif ( $protocol != 6 && $SYN ) { my $okbox = $top->Dialog(-text => "Must select protocol when specifying specific port(s)"); $okbox->Show(); } if ( $protocol != 0 ) { $fw->attribute( "SourcePort", "$sport" ); $fw->attribute( "DestPort", "$dport" ); } elsif ( ($protocol == 0 && $sport) || ($protocol == 0 && $dport) ) { my $okbox = $top->Dialog(-text => "Must select protocol when specifying specific port(s)"); $okbox->Show(); } $fw->$command("$ipcchain", "$rulenum"); } sub show_rule { my $rule = $ruleList->curselection(); my $chain = $currchain; my @rules = get_chains($chain); $rules[$rule]->{'source'} =~ m|(..)(..)(..)(..)/(..)(..)(..)(..)|; $saddr = join(".", hex($1), hex($2), hex($3), hex($4) ); $smask = join(".", hex($5), hex($6), hex($7), hex($8) ); $rules[$rule]->{'dest'} =~ m|(..)(..)(..)(..)/(..)(..)(..)(..)|; $daddr = join(".", hex($1), hex($2), hex($3), hex($4) ); $dmask = join(".", hex($5), hex($6), hex($7), hex($8) ); $protocol = $rules[$rule]->{'prot'}; $ipcchain = $rules[$rule]->{'chain'}; if ($rules[$rule]->{'iface'} eq "-" ) { $ipciface = ""; } else { $ipciface = $rules[$rule]->{'iface'}; } $rulenum = $rules[$rule]->{'rulenum'}; $target = $rules[$rule]->{'target'}; $tosand = $rules[$rule]->{'tosand'}; $tosxor = $rules[$rule]->{'tosxor'}; $ipcmark = $rules[$rule]->{'mark'}; # $maxoutput = $rules[$rule]->{'output'}; # need to add flags. } sub clearform { $saddr = $daddr = $smask = $dmask = "0.0.0.0"; $sport = $dport = "0"; $protocol = "0"; $ipcchain = ""; $ipciface = ""; $target = ""; $tosand = ""; $tosxor = ""; $ipcmark = ""; $fragment = $bidir = $log = $syn = $output = 0; # $maxoutput = ""; $rulenum = ""; } sub new_profile { my $chain; my @chains; my $fw = IPChains->new(); $fw->clopts(); $fw->flush("input"); $fw->flush("output"); $fw->flush("forward"); @chains = get_cnames(); splice(@chains, 0,3); foreach $chain (@chains) { $fw->flush("$chain"); $fw->del_chain("$chain"); $$chain->destroy; $ruleList->delete(0, "end"); } clearform(); } sub new_rule { my $fw = IPChains->new(); $fw->clopts(); clearform(); } sub save_profile { $fsel = $top->FileSelect(-directory => "$fwpath"); $psave = $fsel->Show(); if ( $psave eq "" ) { $errbox = $top->Dialog(-text => "No File Selected"); $errbox->Show(); } else { # needs to be redone with pipes. this is kludgy. maybe rewrite in perl. qx($fwpath/ipchains-save > $psave); my $okbox = $top->Dialog(-text => "Profile Saved"); $okbox->Show(); } } sub save_rule { not_here(); } sub add_rule { not_here(); } sub load_profile { my $chain; my @chains; $fsel = $top->FileSelect(); $pload = $fsel->Show(); if ( $pload eq "" ) { $errbox = $top->Dialog(-text => "No File Selected"); $errbox->Show(); } else { # needs to be redone with piples. this is kludgy. maybe rewrite in perl. new_profile(); qx($fwpath/ipchains-restore < $pload); @chains = get_cnames(); splice(@chains, 0,3); foreach $chain (@chains) { $$chain = $ruleFrame->Button(-text => "$chain", -command => [ \&show_rules, $chain]) ->pack(-side => "top", -fill => "x"); } # $okbox = $top->Dialog(-text => "Profile $pload Restored"); # $okbox->Show(); if ( $currchain ne "" ) { show_rules($currchain); } } } sub load_rule { not_here(); } sub create_chain { my $chain; my @chains; my $addchain; my $fw = IPChains->new(); my $cinput = $top->Toplevel(-width => 200, -height => 200); my $label = $cinput->Label(-text => "Create Chain: ") ->pack(-side => "top"); my $entry = $cinput->Entry() ->pack(-side => "top"); my $okbutton = $cinput->Button(-text => "OK", -command => sub { $addchain = $entry->get; @chains = get_cnames(); foreach $chain (@chains) { if ( "$addchain" eq "$chain" ) { my $existerr = $cinput->Dialog(-text => "Chain $addchain already exists"); $existerr->Show(); $addchain = ""; } } if ( length($addchain) > 8 ) { my $lenerr = $cinput->Dialog(-text => "Chain too long. 8 chars Max."); $lenerr->Show(); $addchain = ""; } if ( $addchain ne "" ) { $fw->new_chain("$addchain"); $cinput->destroy; $$addchain = $ruleFrame->Button(-text => "$addchain", -command => [ \&show_rules, $addchain]) ->pack(-side => "top", -fill => "x"); } } ) ->pack(-side => "top"); } sub delete_chain { my @chains; my $fw = IPChains->new(); my $cinput = $top->Toplevel(-width => 200, -height => 200); my $label = $cinput->Label(-text => "Delete Chain: ") ->pack(-side => "top"); my $listbox = $cinput->Scrolled("Listbox", -scrollbars => "w", -selectmode => "single", -height => 4) ->pack(); @chains = get_cnames(); splice(@chains, 0,3); $listbox->insert('end', @chains); # Need to add checking for refcnt before attempting to delete. my $okbutton = $cinput->Button(-text => "OK", -command => sub { $delchain = $listbox->get($listbox->curselection()); $fw->del_chain("$delchain"); $$delchain->destroy(); $cinput->destroy(); } ) ->pack(-side => "top"); } sub get_cnames { my @chains; my $i = 0; open(FWNAMES, "/proc/net/ip_fwnames"); while() { $_ =~ m/(^\w*)/; $chains[$i] = $1; $i++; } close(FWNAMES); return @chains; } sub list_cnames { my $fw = IPChains->new(); my ($chain, @chains); @chains = get_cnames(); foreach $chain (@chains) { $fw->list("$chain"); } } sub get_chains { my $chain = shift; my @chains; my $i = 0; open(FWCHAINS, "/proc/net/ip_fwchains"); while() { m{^\s*(.*) (.*/.*)->(.*/.*?) (\w*|-) (\d*) (\d*) (\d*) \d*\s*(\d*)\s*\d*\s*(\d*)\s*(\d*-\d*) (\d*-\d*) A(..) X(..) (\d*) (\d*) (\d*)\s*(\w*)}; if($1 eq $chain) { $chains[$i]->{rulenum} = ($i+1); $chains[$i]->{chain} = "$1"; $chains[$i]->{source} = "$2"; $chains[$i]->{dest} = "$3"; $chains[$i]->{iface} = "$4"; $chains[$i]->{flag} = "$5"; $chains[$i]->{invflag} = "$6"; $chains[$i]->{prot} = "$7"; $chains[$i]->{bytecnt} = "$8"; $chains[$i]->{pktcnt} = "$9"; $chains[$i]->{srcports} = "$10"; $chains[$i]->{dstports} = "$11"; $chains[$i]->{tosand} = "0x$12"; $chains[$i]->{tosxor} = "0x$13"; $chains[$i]->{redir} = "$14"; $chains[$i]->{mark} = "$15"; $chains[$i]->{output} = "$16"; $chains[$i]->{target} = "$17"; $i++; } } close(FWCHAINS); return @chains; } sub get_ifs { open(F, "/proc/net/dev"); my $i = 0; my @ifs; while() { m/\s*(.*?):.*/; if( defined($1) ) { $ifs[$i] = $1; $i++; } } close(F); return @ifs; } sub show_rules { my $chain = shift; if ( $currchain ne "" ) { $$currchain->configure(-background => "lightgray"); } $currchain = $chain; $$currchain->configure(-background => "lightblue"); my @rules = get_chains($chain); $ruleList->delete(0, 'end'); foreach $rule (@rules) { $rule->{source} =~ m|(..)(..)(..)(..)/(..)(..)(..)(..)|; my $saddr = join(".", hex($1), hex($2), hex($3), hex($4) ); my $smask = join(".", hex($5), hex($6), hex($7), hex($8) ); $rule->{dest} =~ m|(..)(..)(..)(..)/(..)(..)(..)(..)|; my $daddr = join(".", hex($1), hex($2), hex($3), hex($4) ); my $dmask = join(".", hex($5), hex($6), hex($7), hex($8) ); $ruleList->insert('end', "$rule->{rulenum} $saddr/$smask:$rule->{srcports} -> $daddr/$dmask:$rule->{dstports} $rule->{target}"); $ruleList->bind('', \&show_rule); } } sub show_counters { my @chains = get_cnames(); my $chains; if ( Exists($cnt) ) { $cnttxt->delete('0.0', 'end'); } else { $cnt = $top->Toplevel(-width => 50, -height => 50); $cnttxt = $cnt->Scrolled("Text", -scrollbars => "sw", -height => 10, -width => 50) ->pack(); $cnt->Button(-text => "Update", -command => \&show_counters) ->pack(-side => top); } $cnttxt->insert('end', "Chain\tRuleNum\tBytes\tPackets\n"); foreach $chain (@chains) { my @info = get_chains($chain); foreach $info (@info) { $cnttxt->insert('end', "$info->{chain}\t" . "$info->{rulenum}\t" . "$info->{bytecnt}\t" . "$info->{pktcnt}\n"); } } } #### About Menu Functions sub about { my $button; my $done; $dialog = $top->DialogBox(-title => "About jnet", -buttons => ["Ok"]); $dialog->add("Label", -text => "jnet v.01\n")->pack(); $dialog->add("Label", -text => "j's nifty warez..\n\n")->pack(); while ( ! $done ) { $button = $dialog->Show; if ( $button eq "Ok" ) { $done = 1; } } } #### SNMP Functions sub snmpsetup { my $oid = $hlist->selectionGet(); my $tag = SNMP::translateObj($oid); my $sess = new SNMP::Session(DestHost => $snmphost, Community => $community, RemotePort => $snmpport, UseLongNames => 1, Timeout => 5000000); my $var = new SNMP::Varbind([$oid]); $result->delete('0.0','end'); return ($oid, $sess, $var); } sub snmpget { (my $oid, my $sess, my $var) = snmpsetup(); my $val = $sess->get($var); if ($sess->{ErrorStr}) { $result->insert('end',"$sess->{ErrorStr}"); } else { $result->insert('end',"$var->[$SNMP::Varbind::val_f]\n"); } } sub snmpgetnext { (my $oid, my $sess, my $var) = snmpsetup(); my $val = $sess->getnext($var); if ($sess->{ErrorStr}) { $result->insert('end',"$sess->{ErrorStr}"); } else { $result->insert('end',"$var->[$SNMP::Varbind::val_f]\n"); } } sub initTable { $snmpTable->destroy(); $snmpTableTop->packPropagate(0); $snmpTable = $snmpTableTop->Table(-columns => shift, -width => 600, -height => 200, -fixedrows => 2, -fixedcolumns => 2) ->pack(-side => 'top', -fill => 'both', -expand => 1); } sub snmpgettable { (my $oid, my $sess, my $var) = snmpsetup(); my (@tb, @tags, @index); $snmpTableTop = $top->Toplevel(-width => 600, -height => 100); $snmpTable = $snmpTableTop->Scrolled(qw(Text -width 100 -height 10 )) ->pack(); $tableStatus = $snmpTableTop->Label(-text => "Loading...") ->pack(-side => 'top'); while (!$sess->{ErrorStr}) { my $val = $sess->getnext($var); last if (!defined($var->tag) || $sess->{ErrorStr} || SNMP::translateObj($var->tag) !~ /^\.$oid/); $newoid = "$var->[$SNMP::Varbind::tag_f].$var->[$SNMP::Varbind::iid_f]"; $snmpTable->insert('end',"$var->[$SNMP::Varbind::val_f]\n"); $top->update(); $newoid =~ /([^\.]+)\.([0-9\.]+)$/; if (!grep(/$1/,@tags)) { push @tags,$1; } if (!grep(/$2/,@index)) { push @index,$2; } $tb{$2}{$1} = $var->val; } initTable($#tags+1); for(my $k=0;$k <= $#tags;$k++) { $snmpTable->put(1,$k+2,$tags[$k]); } $snmpTable->put(1,1,"Index"); for(my $i=0;$i <= $#index;$i++) { $snmpTable->put($i+2,1,$index[$i]); } for(my $i=0;$i <= $#index; $i++) { for(my $k=0;$k <= $#tags;$k++) { $snmpTable->put($i+2,$k+2,$tb{$index[$i]}{$tags[$k]}); } } $tableStatus->destroy(); } sub snmpwalk { (my $oid, my $sess, my $var) = snmpsetup(); while (!$sess->{ErrorStr}) { my $val = $sess->getnext($var); last if (!defined($var->tag) || $sess->{ErrorStr} || SNMP::translateObj($var->tag) !~ /^\.$oid/); $result->insert('end',"$var->[$SNMP::Varbind::tag_f].$var->[$SNMP::Varbind::iid_f]:\n"); $result->insert('end',"$var->[$SNMP::Varbind::val_f]\n"); $top->update(); } if ($sess->{ErrorStr}) { $result->insert('end',"$sess->{ErrorStr}"); } } sub addMibOID { my $i = shift; $i = ".$i" if ($i !~ /^\./); my $name = SNMP::translateObj($i,1); if (defined($name)) { $name =~ s/.*\.([^.]+)$/$1/; } else { return; } $i =~ s/^\.//; $hlist->add($i, -text => $name); } sub showInfo { my $oid = shift; if (!defined($last) || "$last" ne $oid) { my $mib = $SNMP::MIB{".$oid"}; if (defined($mib)) { $mibNum->configure(-text => $mib->{'objectID'}); $mibTxt->configure(-text => SNMP::translateObj($mib->{'objectID'},1)); $descr->delete('0.0','end'); if (defined($mib->{'description'}) && $mib->{'description'} ne "") { my $desc = $mib->{'description'}; $desc =~ s/\n[ \t]+/\n/g; $descr->insert('end',$desc); } } } $last = $oid; } sub showChildren { my $oid = shift; if ($hlist->infoChildren($oid)) { my @a = $hlist->infoChildren($oid); my $i; foreach $i (@a) { $hlist->deleteEntry($i); } } else { $oid = ".$oid"; my $mib = $SNMP::MIB{$oid}; if (defined($mib)) { my $children = $$mib{'children'}; if (ref($children) eq "ARRAY") { foreach $i (sort {$$a{'subID'} <=> $$b{'subID'}} @{$children}) { addMibOID($$i{'objectID'}); } } } } }