Changeset 66


Ignore:
Timestamp:
01/05/18 18:06:47 (6 years ago)
Author:
Kris Deugau
Message:

/trunk/dnsbl

Add exclusion flagging and block-comment handling to IP list tools. Exclusion
flags can be set or unset on each submit; netblock comments can be added,
updated, or removed (or at least "set empty") on each submit.

Note this is focused on the CIDR (rbldnsd) export format, and may produce
excitingly weird results with the default "classful"/tinydns mode.

Location:
trunk/dnsbl
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/dnsbl/DNSBL.pm

    r54 r66  
    130130
    131131our $err;
    132 our $errstr;
     132our $errstr = '';
    133133
    134134# basic object subs
     
    184184        "WHERE b.block >>= ? ".
    185185        "GROUP BY b.block,b.level,b.listme,o.listme ORDER BY b.block");
    186   $sthmoron = $dbh->prepare("SELECT ip,s4list FROM iplist WHERE parent = ?");
     186  $sthmoron = $dbh->prepare("SELECT ip,s4list,white FROM iplist WHERE parent = ?");
    187187}
    188188
     
    193193  my $self = shift;
    194194  my $ip = shift;
    195   my $sth = $dbh->prepare("SELECT count FROM iplist WHERE ip=?");
     195  my $sth = $dbh->prepare("SELECT count, exclude FROM iplist WHERE ip=?");
    196196  $sth->execute($ip);
    197   my ($ret) = $sth->fetchrow_array();
     197  my $ret = $sth->fetchrow_arrayref();
    198198  return $ret;
    199199} # end ipexists()
     
    205205  my $self = shift;
    206206  my $rep = shift;
     207  my $exclude = shift;
    207208  my $sth;
    208209  my $rows = 0;
     
    214215      $rows = $sth->rows;
    215216      if ($rows == 0) {
    216         $sth = $dbh->prepare("INSERT INTO iplist (ip,parent) VALUES ".
    217                 "(?,(SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1))");
    218         $sth->execute($rep,$rep) or die "couldn't add entry for $rep: ".$dbh->errstr."\n";
     217        $sth = $dbh->prepare("INSERT INTO iplist (ip,parent,exclude) VALUES ".
     218                "(?,(SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1),?)");
     219        $sth->execute($rep,$rep,$exclude) or die "couldn't add entry for $rep: ".$dbh->errstr."\n";
    219220      } elsif ($rows == 1) {
    220         $sth = $dbh->prepare("UPDATE iplist SET count=count+1 WHERE ip=?");
     221        $sth = $dbh->prepare("UPDATE iplist SET count=count+1,".
     222                " exclude=".($exclude ? "'y'" : "'n'"). " WHERE ip=?");
    221223        $sth->execute($rep) or die "couldn't update listing for $rep: ".$dbh->errstr."\n";
    222224      } else {
     
    225227      $sth = $dbh->prepare("SELECT block FROM blocks WHERE block >> ?");
    226228      $sth->execute($rep);
    227       my $updsth = $dbh->prepare("UPDATE blocks SET ipcount=(SELECT count(*) FROM iplist WHERE ip << ?) WHERE block=?");
     229      my $updsth = $dbh->prepare("UPDATE blocks SET ipcount=(SELECT count(*) FROM iplist WHERE ip << ? AND exclude='n') WHERE block=?");
    228230      while (my ($block) = $sth->fetchrow_array) {
    229231        $updsth->execute($block,$block);
     
    309311  my $orgid = shift;
    310312  my $level = shift;
     313  my $exclude = shift;
     314  my $comment = shift;
    311315  $blockin =~ s/^\s+//;
    312316  $blockin =~ s/\s+$//;
     
    325329      ($parent) = $sth->fetchrow_array;
    326330    }
    327     $sth = $dbh->prepare("INSERT INTO blocks (block,orgid,level,parent,ipcount) VALUES (?,?,?,?,".
    328         "(SELECT count(*) FROM iplist WHERE ip << ?))");
    329     $sth->execute("$block",$orgid,$level,$parent,"$block");
     331    $sth = $dbh->prepare("INSERT INTO blocks (block,orgid,level,parent,exclude,comments,ipcount) VALUES (?,?,?,?,?,?,".
     332        "(SELECT count(*) FROM iplist WHERE ip << ? AND exclude='n'))");
     333    $sth->execute("$block",$orgid,$level,$parent,$exclude,$comment,"$block");
    330334    $sth = $dbh->prepare("UPDATE iplist SET parent=? WHERE parent=? AND ip << ?");
    331335    $sth->execute("$block",$parent,"$block");
     
    341345
    342346
     347# Update a netblock entry.  Supports (un)setting the exclude flag and the comment.
     348# Does NOT do any magic around leftover IPs within the block
     349sub updateblock {
     350  my $self = shift;
     351  my $blockin = shift;
     352  my $orgid = shift;
     353  my $level = shift;
     354  my $exclude = shift;
     355  my $comment = shift;
     356  $blockin =~ s/^\s+//;
     357  $blockin =~ s/\s+$//;
     358  my $block = new NetAddr::IP "$blockin";       # need this to clean up messes like ranges.  sigh.
     359
     360  return "$blockin not a single CIDR range" if !$block;
     361
     362  local $dbh->{AutoCommit} = 0;
     363  local $dbh->{RaiseError} = 1;
     364
     365  my $sth;
     366  eval {
     367    my $parent = '0/0';
     368    if ($level > 0) {
     369      $sth = $dbh->prepare("SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1");
     370      $sth->execute("$block");
     371      ($parent) = $sth->fetchrow_array;
     372    }
     373    $sth = $dbh->prepare("UPDATE blocks SET exclude = ?, comments = ?, ipcount = ".
     374        "(SELECT count(*) FROM iplist WHERE ip << ? AND exclude='n')".
     375        " WHERE block = ?");
     376    $sth->execute($exclude, $comment, "$block", "$block");
     377    $sth = $dbh->prepare("UPDATE iplist SET parent=? WHERE parent=? AND ip << ?");
     378    $sth->execute("$block", $parent, "$block");
     379    $dbh->commit;
     380  };
     381  if ($@) {
     382    my $msg = $@;
     383    eval { dbh->rollback; };
     384    return "failed to update $block: $msg";
     385  }
     386  # nb: no need to return anything, since the CIDR block is the key
     387}
     388
     389
    343390sub blockexists {
    344391  my $self = shift;
     
    351398
    352399
    353 # returns list (block,orgname) for the block that contains the passed IP.
     400# returns list (block,blockcomment,orgname) for the block that contains the passed IP.
    354401# accepts a level argument if you don't want the top-level registrar allocation block
    355402sub getcontainer {
     
    357404  my $ip = shift;
    358405  my $level = shift || 0;
    359   my $sth = $dbh->prepare("SELECT b.block,o.orgname FROM blocks b INNER JOIN orgs o ".
     406  my $sth = $dbh->prepare("SELECT b.block,b.comments,o.orgname FROM blocks b INNER JOIN orgs o ".
    360407        "ON b.orgid=o.orgid WHERE b.block >> ? AND b.level = ?");
    361408  $sth->execute($ip,$level);
     
    375422    # looking for IP
    376423
    377     $sth = $dbh->prepare("SELECT ip,s4list FROM iplist WHERE ip=?");
     424    $sth = $dbh->prepare("SELECT ip,s4list,exclude FROM iplist WHERE ip=?");
    378425    $sth->execute($entity);
    379426    my @ret = $sth->fetchrow_array;
     
    385432    my $masklen = $1;
    386433
    387     $sth = $dbh->prepare("SELECT block,listme FROM blocks WHERE block=?");
     434    $sth = $dbh->prepare("SELECT block,listme,exclude,ipcount FROM blocks WHERE block = ?");
    388435    $sth->execute($entity);
    389     my ($block,$listme) = $sth->fetchrow_array;
     436    my ($block, $listme, $exclude, $bcount) = $sth->fetchrow_array;
    390437
    391438    return if !$block;
    392439
    393     $sth = $dbh->prepare("SELECT ipcount FROM blocks WHERE block = ?");
    394     $sth->execute($entity);
    395     my ($bcount) = $sth->fetchrow_array;
    396     my @ret = ( ($bcount >= $autolist{$masklen}), $listme);
     440    my @ret = ( ($bcount >= $autolist{$masklen}), $listme, $exclude);
    397441    return @ret;
    398442
     
    433477  my $bitmask = shift || 0;
    434478
     479  if ($level == 0) {
     480    $errstr = '';
     481  }
     482
     483  return if ($errstr =~ /no connection to the server/);
    435484  if ($level > $maxlvl) {
    436485    warn "getting too deep, breaking off! ($container, $level)\n";
     
    447496  }
    448497
     498
     499  # catch database-went-away errors
     500  local $dbh->{RaiseError} = 1;
     501  eval {
     502
     503
    449504  my $sth = $dbh->prepare("SELECT count(*) FROM blocks WHERE parent = ?");
    450505  $sth->execute($container);
     
    459514  my $listorg;
    460515  my $bcount;
     516  my $bexclude;
    461517  if ($container ne '0.0.0.0/0') {
    462     $sth = $dbh->prepare("SELECT b.ipcount,b.listme,o.listme ".
     518    $sth = $dbh->prepare("SELECT b.ipcount,b.listme,b.exclude,o.listme ".
    463519        "FROM blocks b INNER JOIN orgs o ON b.orgid=o.orgid ".
    464520        "WHERE b.block = ?");
    465521    $sth->execute($container);
    466     ($bcount,$listme,$listorg) = $sth->fetchrow_array();
    467 
     522    ($bcount,$listme,$bexclude,$listorg) = $sth->fetchrow_array();
    468523    $bitmask |= $bitfields{$level-1} if $bcount >= $autolist{$masklen};
    469524    $bitmask |= $bitfields{"block".($level-1)} if $listme;
     
    473528# hm.  can't seem to move this prepare elsewhere.  :(
    474529  if ($nblocks > 0) {
    475     my $sthsubblocks = $dbh->prepare("SELECT block FROM blocks ".
     530    my $sthsubblocks = $dbh->prepare("SELECT block,exclude FROM blocks ".
    476531        "WHERE level = ? AND parent = ?");
    477532    $sthsubblocks->execute($level, $container);
    478     while (my ($cidr) = $sthsubblocks->fetchrow_array()) {
    479       $self->export($listhosts,$mode,$level+1,$cidr,$bitmask);
     533    while (my ($cidr, $exclude) = $sthsubblocks->fetchrow_array()) {
     534      if ($exclude) {
     535        $listhosts->{$cidr} = -1;
     536      } else { # don't check subtrees of an excluded block;  rbldnsd doesn't support deep flip-flopping like that
     537        $self->export($listhosts,$mode,$level+1,$cidr,$bitmask)
     538          or die $errstr;
     539      }
    480540    }
    481541  } # avoid checking content of subs if we don't have any
     
    534594
    535595  $sthmoron->execute($container);
    536   while (my ($ip,$moron) = $sthmoron->fetchrow_array()) {
    537     $listhosts->{$ip} |= $bitmask;
     596  while (my ($ip,$moron,$exclude) = $sthmoron->fetchrow_array()) {
    538597    if ($moron) {
    539598      $listhosts->{$ip} = $bitfields{slist};
     599    } elsif ($exclude) {
     600      $listhosts->{$ip} = -1;
    540601    } else {
     602      $listhosts->{$ip} |= $bitmask;
    541603      $listhosts->{$ip} |= $bitfields{ip};
    542604    }
    543605  }
     606
     607
     608  }; # db-went-away-catching eval
     609  if ($@) {
     610    $errstr = $@;
     611    warn "export truncated: $errstr\n";
     612    return;
     613  }
     614
    544615
    545616# get IPs which for reasons unknown are apparently allocated directly from the
     
    547618#  select * from iplist where not (select count(*) from blocks where ip << block) > 0;
    548619
    549   return;
     620  return 1;
    550621} # end export()
    551622
  • trunk/dnsbl/DNSBLweb.pm

    r59 r66  
    2121
    2222package DNSBLweb;
     23
     24use strict;
     25use warnings;
    2326
    2427use Exporter;
     
    5659  my $pblock = $args{block} || '0/0';
    5760
    58   my $basesql = "SELECT b.block,o.orgname,b.listme,o.listme,b.comments,o.comments ".
     61  my $basesql = "SELECT b.block,o.orgname,b.listme,o.listme,b.comments,o.comments,b.exclude ".
    5962       "FROM blocks b INNER JOIN orgs o ON b.orgid=o.orgid ".
    6063       "WHERE b.block <<=";
     
    6265  my $sthiplist = $dbh->prepare("SELECT * FROM iplist WHERE ip <<= ? ORDER BY ip");
    6366  $allsth->execute($pblock,$lvl);
    64   while (my ($block,$org,$listmeb,$listmeo,$bcomments,$ocomments) = $allsth->fetchrow_array) {
     67  while (my ($block,$org,$listmeb,$listmeo,$bcomments,$ocomments,$bexclude) = $allsth->fetchrow_array) {
    6568    my $tmpl = new HTML::Template(filename => "browse-block.tmpl");
    6669    my $blockcidr = new NetAddr::IP $block;
    6770    $tmpl->param(lvlclass => "lvl$lvl".($dnsbl->autolist_block($block) ? " auto$lvl" : '').
    6871       ( $ipcidr->within($blockcidr) ? ' inhere' : ''));
    69 
    70     $tmpl->param(netclass => ($listmeb ? "b$lvl".'list' : ''));
     72    # exclude takes precedence over listme
     73    $tmpl->param(netclass => ($bexclude ? 'exclude' : ($listmeb ? "b$lvl".'list' : '')));
    7174    $tmpl->param(net => $block);
    7275    $tmpl->param(orgclass => ($listmeo ? "b$lvl".'org' : ''));
     
    8184      next if $args{ipseen}->{$data4[0]};
    8285      my %iprow;
     86      my @ipclass;
    8387      $iprow{ip} = $data4[0];
    8488      $iprow{ipcount} = $data4[1];
    8589      $iprow{indent} = '  'x$lvl;
    86       $iprow{repeater} = 1 if $ip eq $data4[0];
    87 #       ip        | count | s4list |             added
     90      push @ipclass, 'repeater' if $ip eq $data4[0];
     91      push @ipclass, 'exclude' if $data4[5];
     92      $iprow{ipclass} = join(' ', @ipclass);
     93#       ip        | count | s4list |             added             |     parent     | exclude
    8894      push @iprows, \%iprow;
    8995      $args{ipseen}->{$data4[0]} = 1;
  • trunk/dnsbl/browse.cgi

    r51 r66  
    7070$template->param(pgcomment => $config{pgcomment}) if defined($config{pgcomment});
    7171
    72 my $out = DNSBLweb::retlvl($dbh, $dnsbl, 0, block => '0/0');
     72my $out = DNSBLweb::retlvl($dbh, $dnsbl, 0, block => '162.144.0.0/16');
    7373
    7474$template->param(enchilada => $out);
  • trunk/dnsbl/dnsbl.cgi

    r64 r66  
    6262my $cfgname = $ENV{SERVER_NAME}.$ENV{REQUEST_URI};
    6363$cfgname =~ s|[./-]|_|g;
    64 $cfgname =~ s|_dnsbl_cgi.+||;
     64$cfgname =~ s|_dnsbl_cgi.*||;
    6565$cfgname =~ s|_$||;
    6666if (-e "/etc/dnsbl/$cfgname.conf") {
     
    124124  }
    125125
    126   my $count = $dnsbl->ipexists($webvar{ip});
    127   $page->param(nreports => $count) if $count;
     126  my $ipinfo = $dnsbl->ipexists($webvar{ip});
     127  $page->param(nreports => $ipinfo->[0]) if $ipinfo;
     128  $page->param(ipexclude => $ipinfo->[1]) if $ipinfo;
     129  # extract and list the entire tree the IP is part of
    128130  $page->param(browsebits =>
    129131        DNSBLweb::retlvl($dbh, $dnsbl, 0, ip => $webvar{ip}, block => $dnsbl->getcontainer($webvar{ip},0) ));
    130132  for (my $i=0; $i <= $maxlvl; $i++) {
    131     my ($block,$org) = $dnsbl->getcontainer($webvar{ip},$i);
     133    my ($block,$comment,$org) = $dnsbl->getcontainer($webvar{ip},$i);
    132134    if ($block) {
    133       my ($bcl,$bal) = $dnsbl->islisted($block);
     135      $page->param("comment$i" => $comment);
     136      my ($bcl,$bal,$bwl) = $dnsbl->islisted($block);
    134137      $page->param("autob$i" => $bcl);
    135       $page->param("listb$i" => $bal);
     138      $page->param("flag$i" => ($bwl ? 'exclude' : ($bal ? 'b1list' : '')) );
     139      $page->param("excl$i" => $bwl);
    136140      my ($ol) = $dnsbl->islisted($org);
    137141      $page->param("listorg$i" => $ol);
     
    159163    my $orgn = "org$i";
    160164    my $blockn = "block$i";
     165    my $commentn = "comment$i";
     166    my $excln = "exclude$i";
    161167    $webvar{$orgn} =~ s/^\s*//;
    162168    $webvar{$orgn} =~ s/\s*$//;
    163169    $webvar{$blockn} =~ s/^\s*//;
    164170    $webvar{$blockn} =~ s/\s*$//;
     171    $webvar{$commentn} =~ s/^\s*//;
     172    $webvar{$commentn} =~ s/\s*$//;
     173    $webvar{$excln} =~ s/on/1/;
    165174    my $orgid = $dnsbl->orgexists($webvar{$orgn});
    166175    if (!$orgid) {
     
    180189    }
    181190    if (!$dnsbl->blockexists($webvar{$blockn})) {
    182       my $ret = $dnsbl->addblock($webvar{$blockn}, $orgid, $i);
     191      my $ret = $dnsbl->addblock($webvar{$blockn}, $orgid, $i, $webvar{$excln});
    183192      $err .= "error adding $webvar{$blockn}: $ret<br>\n" if $ret;
    184193      $page->param($blockn => $webvar{$blockn});
     194    } else {
     195      my $ret = $dnsbl->updateblock($webvar{$blockn}, $orgid, $i, $webvar{$excln}, $webvar{$commentn});
     196      $err .= "error updating $webvar{$blockn}: $ret<br>\n" if $ret;
    185197    }
    186198    last unless $webvar{"block".($i+1)};
    187199  }
    188200
    189   my $count = $dnsbl->report($webvar{ip});
     201  my $count = $dnsbl->report($webvar{ip}, $webvar{excludeip});
    190202
    191203  $page->param(ip => $webvar{ip});
  • trunk/dnsbl/export-dnsbl

    r53 r66  
    7575  foreach (sort ipcmp keys %iplist) {
    7676    my $entry;
     77    if ($iplist{$_} == -1) {
     78      print "!$_\n";
     79      next;
     80    }
    7781    if ($iplist{$_} >= 256) {
    7882      if ($iplist{$_} >= 65536) {
  • trunk/dnsbl/templates/browse-block.tmpl

    r22 r66  
    44<TMPL_IF subs><TMPL_VAR NAME=subs>
    55</TMPL_IF><TMPL_IF iplist><TMPL_VAR NAME=indent>  <div class=iplist>
    6 <TMPL_LOOP NAME=iplist><TMPL_VAR NAME=indent>    <span<TMPL_IF repeater> class="repeater"</TMPL_IF>><TMPL_VAR NAME=ip> (<TMPL_VAR NAME=ipcount>)</span><br>
     6<TMPL_LOOP NAME=iplist><TMPL_VAR NAME=indent>   
     7<span class="<TMPL_VAR NAME=ipclass>"><TMPL_VAR NAME=ip> (<TMPL_VAR NAME=ipcount>)</span><br>
    78</TMPL_LOOP>
    89<TMPL_VAR NAME=indent>  </div></TMPL_IF>
  • trunk/dnsbl/templates/dbreport.tmpl

    r52 r66  
    77<TMPL_VAR NAME=pgcomment>
    88<table><tr><td valign=top>
    9 added <TMPL_VAR NAME=ip>
     9added <TMPL_VAR NAME=ip><TMPL_IF ipexcl> as excluded</TMPL_IF>
    1010<TMPL_IF org0><br>added <TMPL_VAR NAME=org0></TMPL_IF>
    1111<TMPL_IF block0><br>added level 0 block <TMPL_VAR NAME=block0></TMPL_IF>
     12<TMPL_IF excl0> as excluded</TMPL_IF>
    1213<TMPL_IF org1><br>added <TMPL_VAR NAME=org1></TMPL_IF>
    1314<TMPL_IF block1><br>added level 1 block <TMPL_VAR NAME=block1></TMPL_IF>
     15<TMPL_IF excl1> as excluded</TMPL_IF>
    1416<TMPL_IF org2><br>added <TMPL_VAR NAME=org2></TMPL_IF>
    1517<TMPL_IF block2><br>added level 2 block <TMPL_VAR NAME=block2></TMPL_IF>
     18<TMPL_IF excl2> as excluded</TMPL_IF>
    1619<TMPL_IF org3><br>added <TMPL_VAR NAME=org3></TMPL_IF>
    1720<TMPL_IF block3><br>added level 3 block <TMPL_VAR NAME=block3></TMPL_IF>
     21<TMPL_IF excl3> as excluded</TMPL_IF>
    1822<TMPL_IF org4><br>added <TMPL_VAR NAME=org4></TMPL_IF>
    1923<TMPL_IF block4><br>added level 4 block <TMPL_VAR NAME=block4></TMPL_IF>
     24<TMPL_IF excl4> as excluded</TMPL_IF>
    2025<TMPL_IF org5><br>added <TMPL_VAR NAME=org5></TMPL_IF>
    2126<TMPL_IF block5><br>added level 5 block <TMPL_VAR NAME=block5></TMPL_IF>
     27<TMPL_IF excl5> as excluded</TMPL_IF>
    2228<TMPL_IF org6><br>added <TMPL_VAR NAME=org6></TMPL_IF>
    2329<TMPL_IF block6><br>added level 6 block <TMPL_VAR NAME=block6></TMPL_IF>
     30<TMPL_IF excl6> as excluded</TMPL_IF>
    2431<TMPL_IF err><hr><TMPL_VAR NAME=err></TMPL_IF>
    2532<hr><a href="<TMPL_VAR NAME=dnsblsiteroot>">Back</a>
  • trunk/dnsbl/templates/dnsbl.css

    r56 r66  
    22body {
    33  font-family: "Times New Roman",Times,serif;
     4  background: #cccccc;
    45}
    56input {
     
    166167  background: #990000;
    167168  border: 2px solid #000000;
     169  margin: 1px;
     170}
     171
     172.exclude {
     173  background: #ffffff;
     174  border: 1px solid #000000;
    168175  margin: 1px;
    169176}
  • trunk/dnsbl/templates/report.tmpl

    r65 r66  
    88<table><tr><td valign=top>
    99<table border=1>
    10 <tr>
    11 <td><TMPL_VAR NAME=ip><TMPL_IF NAME=nreports></td>
    12 <td>(reported <TMPL_VAR NAME=nreports> time(s))</TMPL_IF></td>
    13 <td><a href="<TMPL_VAR NAME=dnsblsiteroot>">Back</a></td></tr>
    14 <tr><td colspan="3"><TMPL_VAR NAME=revinfo></td></tr>
    1510
    1611<form action="dnsbl.cgi">
     
    1813<input type=hidden name=ip value=<TMPL_VAR NAME=ip>>
    1914
    20 <tr><td nowrap>Registrar delegation</td></tr>
     15<tr>
     16<td><TMPL_VAR NAME=ip></td>
     17<!-- fixme:  find a way to "grey-ish" the IP exclude checkbox if any of the block exclude boxes are checked - note, we don't care about *disabling* it -->
     18<td><input type="checkbox" name="excludeip"<TMPL_IF ipexclude> checked="checked"</TMPL_IF>>Exclude<TMPL_IF NAME=nreports></td>
     19<td>(reported <TMPL_VAR NAME=nreports> time(s))</TMPL_IF></td>
     20<td><a href="<TMPL_VAR NAME=dnsblsiteroot>">Back</a></td></tr>
     21<tr><td colspan="4"><TMPL_VAR NAME=revinfo></td></tr>
     22
     23<tr><td colspan="4"></td></tr>
     24<tr>
     25<td nowrap>Registrar delegation</td>
     26<td><input type="checkbox" name="exclude0"<TMPL_IF excl0> checked="checked"</TMPL_IF>>Exclude</td>
     27<td>Comment: <input name="comment0" value="<TMPL_VAR NAME=comment0 ESCAPE=HTML>"></td>
     28</tr>
    2129<tr<TMPL_IF autob0> class="auto0"</TMPL_IF>>
    22 <td><span class="<TMPL_IF listb0>b0list</TMPL_IF>">Netblock:</span></td>
    23 <td colspan=2><input name=block0 value="<TMPL_VAR block0>" size=40></td>
     30<td><span class="<TMPL_VAR flag0>">Netblock:</span></td>
     31<td colspan="3"><input name=block0 value="<TMPL_VAR block0>" size=40></td>
    2432</tr>
    2533<tr<TMPL_IF autob0> class="auto0"</TMPL_IF>>
    2634<td><span class="<TMPL_IF listorg0>b0org</TMPL_IF>">Org/Person:</span></td>
    27 <td colspan=2><input name=org0 value="<TMPL_VAR org0 ESCAPE=HTML>" size=40></td>
     35<td colspan="3"><input name=org0 value="<TMPL_VAR org0 ESCAPE=HTML>" size=40></td>
    2836</tr>
    2937
    30 <tr><td>1st subdelegation</td></tr>
     38<tr><td colspan="4"></td></tr>
     39<tr>
     40<td>1st subdelegation</td>
     41<td><input type="checkbox" name="exclude1"<TMPL_IF excl1> checked="checked"</TMPL_IF>>Exclude</td>
     42<td>Comment: <input name="comment1" value="<TMPL_VAR NAME=comment1 ESCAPE=HTML>"></td>
     43</tr>
    3144<tr<TMPL_IF autob1> class="auto1"</TMPL_IF>>
    32 <td><span class="<TMPL_IF listb1>b1list</TMPL_IF>">Netblock:</span></td>
    33 <td colspan=2><input name=block1 value="<TMPL_VAR block1>" size=40></td>
     45<td><span class="<TMPL_VAR flag1>">Netblock:</span></td>
     46<td colspan="3"><input name=block1 value="<TMPL_VAR block1>" size=40></td>
    3447</tr>
    3548<tr<TMPL_IF autob1> class="auto1"</TMPL_IF>>
    3649<td><span class="<TMPL_IF listorg1>b1org</TMPL_IF>">Org/Person:</span></td>
    37 <td colspan=2><input name=org1 value="<TMPL_VAR org1 ESCAPE=HTML>" size=40></td>
     50<td colspan="3"><input name=org1 value="<TMPL_VAR org1 ESCAPE=HTML>" size=40></td>
    3851</tr>
    3952
    40 <tr><td>2nd subdelegation</td></tr>
     53<tr><td colspan="4"></td></tr>
     54<tr>
     55<td>2nd subdelegation</td>
     56<td><input type="checkbox" name="exclude2"<TMPL_IF excl2> checked="checked"</TMPL_IF>>Exclude</td>
     57<td>Comment: <input name="comment2" value="<TMPL_VAR NAME=comment2 ESCAPE=HTML>"></td>
     58</tr>
    4159<tr<TMPL_IF autob2> class="auto2"</TMPL_IF>>
    42 <td><span class="<TMPL_IF listb2>b2list</TMPL_IF>">Netblock:</span></td>
    43 <td colspan=2><input name=block2 value="<TMPL_VAR block2>" size=40></td>
     60<td><span class="<TMPL_VAR flag2>">Netblock:</span></td>
     61<td colspan="3"><input name=block2 value="<TMPL_VAR block2>" size=40></td>
    4462</tr>
    4563<tr<TMPL_IF autob2> class="auto2"</TMPL_IF>>
    4664<td><span class="<TMPL_IF listorg2>b2org</TMPL_IF>">Org/Person:</span></td>
    47 <td colspan=2><input name=org2 value="<TMPL_VAR org2 ESCAPE=HTML>" size=40></td>
     65<td colspan="3"><input name=org2 value="<TMPL_VAR org2 ESCAPE=HTML>" size=40></td>
    4866</tr>
    4967
    50 <tr><td>3rd subdelegation</td></tr>
     68<tr><td colspan="4"></td></tr>
     69<tr>
     70<td>3rd subdelegation</td>
     71<td><input type="checkbox" name="exclude3"<TMPL_IF excl3> checked="checked"</TMPL_IF>>Exclude</td>
     72<td>Comment: <input name="comment3" value="<TMPL_VAR NAME=comment3 ESCAPE=HTML>"></td>
     73</tr>
    5174<tr<TMPL_IF autob3> class="auto3"</TMPL_IF>>
    52 <td><span class="<TMPL_IF listb3>b3list</TMPL_IF>">Netblock:</span></td>
    53 <td colspan=2><input name=block3 value="<TMPL_VAR block3>" size=40></td>
     75<td><span class="<TMPL_VAR flag3>">Netblock:</span></td>
     76<td colspan="3"><input name=block3 value="<TMPL_VAR block3>" size=40></td>
    5477</tr>
    5578<tr<TMPL_IF autob3> class="auto3"</TMPL_IF>>
    5679<td><span class="<TMPL_IF listorg3>b3org</TMPL_IF>">Org/Person:</span></td>
    57 <td colspan=2><input name=org3 value="<TMPL_VAR org3 ESCAPE=HTML>" size=40></td>
     80<td colspan="3"><input name=org3 value="<TMPL_VAR org3 ESCAPE=HTML>" size=40></td>
    5881</tr>
    5982
    60 <tr><td>4th subdelegation</td></tr>
     83<tr><td colspan="4"></td></tr>
     84<tr>
     85<td>4th subdelegation</td>
     86<td><input type="checkbox" name="exclude4"<TMPL_IF excl4> checked="checked"</TMPL_IF>>Exclude</td>
     87<td>Comment: <input name="comment4" value="<TMPL_VAR NAME=comment4 ESCAPE=HTML>"></td>
     88</tr>
    6189<tr<TMPL_IF autob4> class="auto4"</TMPL_IF>>
    62 <td><span class="<TMPL_IF listb4>b4list</TMPL_IF>">Netblock:</span></td>
    63 <td colspan=2><input name=block4 value="<TMPL_VAR block4>" size=40></td>
     90<td><span class="<TMPL_VAR flag4>">Netblock:</span></td>
     91<td colspan="3"><input name=block4 value="<TMPL_VAR block4>" size=40></td>
    6492</tr>
    6593<tr<TMPL_IF autob4> class="auto4"</TMPL_IF>>
    6694<td><span class="<TMPL_IF listorg4>b4org</TMPL_IF>">Org/Person:</span></td>
    67 <td colspan=2><input name=org4 value="<TMPL_VAR org4 ESCAPE=HTML>" size=40></td>
     95<td colspan="3"><input name=org4 value="<TMPL_VAR org4 ESCAPE=HTML>" size=40></td>
    6896</tr>
    6997
Note: See TracChangeset for help on using the changeset viewer.