Index: branches/stable/cgi-bin/IPDB.pm
===================================================================
--- branches/stable/cgi-bin/IPDB.pm	(revision 188)
+++ branches/stable/cgi-bin/IPDB.pm	(revision 192)
@@ -234,5 +234,5 @@
       eval {
 	$msg = "Unable to allocate $cidr as '$disp_alloctypes{$type}'";
-	if ($type eq 'rr') {
+	if ($type eq 'rm') {
 	  $sth = $dbh->prepare("update freeblocks set routed='y',city='$city'".
 	    " where cidr='$cidr'");
@@ -243,7 +243,14 @@
 	} else {
 	  # common stuff for end-use, dialup, dynDSL, pools, etc, etc.
-	  $sth = $dbh->prepare("delete from freeblocks where cidr='$cidr'");
-	  $sth->execute;
-
+
+	  # special case - block is a container/"reserve" block
+	  if ($type =~ /^(.)c$/) {
+	    $sth = $dbh->prepare("update freeblocks set routed='$1' where cidr='$cidr'");
+	    $sth->execute;
+	  } else {
+	    # "normal" case
+	    $sth = $dbh->prepare("delete from freeblocks where cidr='$cidr'");
+	    $sth->execute;
+	  }
 	  $sth = $dbh->prepare("insert into allocations".
 		" (cidr,custid,type,city,description,notes,maskbits,circuitid)".
@@ -305,5 +312,5 @@
 
 	# now we have to do some magic for routing blocks
-	if ($type eq 'rr') {
+	if ($type eq 'rm') {
 
 	  # Insert the new freeblocks entries
@@ -325,13 +332,22 @@
 	  $sth->execute;
 
-	} else { # done with alloctype == rr
+	} else { # done with alloctype == rm
 
 	  # Insert the new freeblocks entries
+	  # Along with some more HairyPerl(TM) in case we're inserting a
+	  # subblock (.r) allocation
 	  $sth = $dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed)".
-		" values (?, ?, (select city from routed where cidr >>= '$cidr'),'y')");
+		" values (?, ?, (select city from routed where cidr >>= '$cidr'),'".
+		(($type =~ /^(.)r$/) ? "$1" : 'y')."')");
 	  foreach my $block (@newfreeblocks) {
  	    $sth->execute("$block", $block->masklen);
 	  }
-
+	  # Special-case for reserve/"container" blocks - generate
+	  # the "extra" freeblocks entry for the container
+	  if ($type =~ /^(.)c$/) {
+	    $sth = $dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed)".
+		" values ('$cidr',".$cidr->masklen.",'$city','$1')");
+	    $sth->execute;
+	  }
 	  # Insert the allocations entry
 	  $sth = $dbh->prepare("insert into allocations (cidr,custid,type,city,".
@@ -354,5 +370,5 @@
 	  }
 
-	} # done with netblock alloctype != rr
+	} # done with netblock alloctype != rm
 
         $dbh->commit;
@@ -485,5 +501,5 @@
     eval {
 
-      if ($type eq 'rr') {
+      if ($type eq 'rm') {
         $msg = "Unable to remove routing allocation $cidr";
 	$sth = $dbh->prepare("delete from routed where cidr='$cidr'");
@@ -499,6 +515,10 @@
       } else { # end alloctype routing case
 
-	$sth = $dbh->prepare("delete from allocations where cidr='$cidr'");
+	# Delete all allocations within the block being deleted.  This is
+	# deliberate and correct, and removes the need to special-case
+	# removal of "container" blocks.
+	$sth = $dbh->prepare("delete from allocations where cidr <<='$cidr'");
 	$sth->execute;
+
 	# Special case - delete pool IPs
 	if ($type =~ /^.[pd]$/) {
@@ -511,5 +531,7 @@
 	$sth = $dbh->prepare("select cidr from freeblocks where cidr <<= ".
 		"(select cidr from routed where cidr >>= '$cidr') ".
-		" and maskbits<=".$cidr->masklen." and routed='y' order by maskbits desc");
+		" and maskbits<=".$cidr->masklen.
+		" and routed='".(($type =~ /^(.)r$/) ? '$1' : 'y').
+		"' order by maskbits desc");
 
       } # end alloctype general case
@@ -562,14 +584,11 @@
       }
 
-      # Clear old freeblocks entries - if any.  $i==0 if not.
-      if ($i>0) {
-	$sth = $dbh->prepare("delete from freeblocks where cidr=?");
-	foreach my $block (@combinelist) {
-	  $sth->execute("$block");
-	}
-      }
+      # Clear old freeblocks entries - if any.  They should all be within
+      # the $cidr determined above.
+      $sth = $dbh->prepare("delete from freeblocks where cidr <<='$cidr'");
+      $sth->execute;
 
       # insert "new" freeblocks entry
-      if ($type eq 'rr') {
+      if ($type eq 'rm') {
 	$sth = $dbh->prepare("insert into freeblocks (cidr,maskbits,city)".
 		" values ('$cidr',".$cidr->masklen.",'<NULL>')");
@@ -577,5 +596,6 @@
 	$sth = $dbh->prepare("insert into freeblocks (cidr,maskbits,city,routed)".
 		" values ('$cidr',".$cidr->masklen.
-		",(select city from routed where cidr >>= '$cidr'),'y')");
+		",(select city from routed where cidr >>= '$cidr'),'".
+		(($type =~ /^(.)r$/) ? "$1" : 'y')."')");
       }
       $sth->execute;
Index: branches/stable/cgi-bin/consistency-check.pl
===================================================================
--- branches/stable/cgi-bin/consistency-check.pl	(revision 188)
+++ branches/stable/cgi-bin/consistency-check.pl	(revision 192)
@@ -17,12 +17,12 @@
 initIPDBGlobals($dbh);
 
-print "First check:  All blocks must be within one of the master blocks\n";
+print "Checking master containment...\n";
 
 # First check - make sure ALL routes and allocated blocks are part
 # of one of the master blocks.
-print "Checking routed blocks: ";
+print "  Checking routed blocks:";
 $sth = $dbh->prepare("select cidr from routed");
-# union select cidr from allocations union select cidr from freeblocks");
-$sth->execute;
+$sth->execute;
+$flag = '';
 ROUTED: while (@data = $sth->fetchrow_array) {
   $cidr = new NetAddr::IP $data[0];
@@ -30,12 +30,13 @@
     if ($master->contains($cidr)) { next ROUTED; }
   }
-  print "$cidr not mastered\n";
-}
-print " done.\n";
+  print "\n    $cidr not mastered";
+}
+print "$flag done.\n";
 
 # Next test:  All allocations must be part of a master.
-print "Checking allocations: ";
+print "  Checking allocations:";
 $sth = $dbh->prepare("select cidr from allocations");
 $sth->execute;
+$flag = '';
 ALLOCATED: while (@data = $sth->fetchrow_array) {
   $cidr = new NetAddr::IP $data[0];
@@ -43,12 +44,14 @@
     if ($master->contains($cidr)) { next ALLOCATED; }
   }
-  print "$cidr not mastered\n";
-}
-print " done.\n";
+  print "\n    $cidr not mastered";
+  $flag = "\n ";
+}
+print "$flag done.\n";
 
 # Next:  free blocks
-print "Checking freeblocks: ";
+print "  Checking freeblocks:";
 $sth = $dbh->prepare("select cidr from freeblocks order by cidr");
 $sth->execute;
+$flag = '';
 FREEBLOCK: while (@data = $sth->fetchrow_array) {
   $cidr = new NetAddr::IP $data[0];
@@ -56,9 +59,12 @@
     if ($master->contains($cidr)) { next FREEBLOCK; }
   }
-  print "$cidr not mastered\n";
-}
-print " done.\n";
-
-print "Done checking master containment.\n\nChecking pool containment:\n";
+  print "\n    $cidr not mastered";
+  $flag = "\n ";
+}
+print "$flag done.\n";
+
+print "Done checking master containment.\n\n";
+
+print "Checking pool containment...\n";
 
 $sth = $dbh->prepare("select pool,ip from poolips order by ip");
@@ -67,5 +73,5 @@
   $pool = new NetAddr::IP $data[0];
   $ip = new NetAddr::IP $data[1];
-  print "IP $ip listed with incorrect pool $pool\n"
+  print "  IP $ip listed with incorrect pool $pool\n"
     if !$pool->contains($ip);
 }
@@ -75,9 +81,11 @@
   $sth2 = $dbh->prepare("select cidr from allocations where cidr='$data[0]'");
   $sth2->execute;
-  print "Pool $data[0] does not exist in allocations table\n"
+  print "  Pool $data[0] does not exist in allocations table\n"
     if (($sth2->fetchrow_array)[0] eq '');
 }
 
-print "Done checking pool containment.\n\nChecking block-alignment consistency:\n";
+print "Done checking pool containment.\n\n";
+
+print "Checking block-alignment consistency...\n";
 
 # Block alignment consistency:  All allocated+free blocks within a master
@@ -95,10 +103,10 @@
 
 foreach $master (@masterblocks) {
-  print "Master $master:\n";
+  print "  Master $master:\n";
   $prev = $master;
   $sth = $dbh->prepare("(select network(cidr) as net, broadcast(cidr) as bcast ".
-	" from allocations where cidr <<= '$master') union ".
-	"(select network(cidr) as net, broadcast(cidr) as bcast ".
-	"from freeblocks where cidr <<= '$master') order by net");
+	"from allocations where cidr <<= '$master' and type not like '_c') ".
+	"union (select network(cidr) as net, broadcast(cidr) as bcast ".
+	"from freeblocks where cidr <<= '$master' and not (routed='c')) order by net");
   $sth->execute;
 
@@ -109,13 +117,13 @@
       # check if cur starts with master
       if ($cur->numeric > $prev->numeric) {
-        print " Gap from start of master $master to first block $cur\n";
+        print "    Gap from start of master $master to first block $cur\n";
       } elsif ($cur->numeric < $prev->numeric) {
-        print " BIG problem!  Current block $cur begins before master $master!\n";
+        print "    BIG problem!  Current block $cur begins before master $master!\n";
       }
     } else {
       if ($cur->numeric < ($prev->numeric + 1)) {
-        print " Block ".$prev->network." overlaps block $cur\n";
+        print "    Block ".$prev->network." overlaps block $cur\n";
       } elsif ($cur->numeric > ($prev->numeric + 1)) {
-        print " Gap between end of block ".$prev->network." and block $cur\n";
+        print "    Gap between end of block ".$prev->network." and block $cur\n";
       }
     }
@@ -129,10 +137,79 @@
   $master--;
   if ($cur->numeric ne $master->numeric) {
-    print " Gap from $cur to end of master at $master\n";
-  }
-  print "done $master.\n";
-}
-
-print "Done checking block alignment.\n\nChecking for correctness on 'defined' CustIDs:\n";
+    print "    Gap from $cur to end of master at $master\n";
+  }
+  print "  done $master.\n";
+}
+
+print "Done checking block alignment.\n\n";
+
+print "Checking containment on container blocks...\n";
+# First, we need a list of containers.
+# Then, we check all of the contained blocks to see if they're within
+# the proper container.
+$sth = $dbh->prepare("select cidr from allocations where type like '_c' order by cidr");
+$sth->execute;
+$i=0;
+while (@data = $sth->fetchrow_array) {
+  $containers[$i++] = new NetAddr::IP $data[0];
+}
+print "  Checking general containment:";
+$sth = $dbh->prepare("select cidr from allocations where type like '_r' order by cidr");
+$sth->execute;
+$flag = '';
+CONTAINED: while (@data = $sth->fetchrow_array) {
+  $cidr = new NetAddr::IP $data[0];
+  foreach $container (@containers) {
+    next CONTAINED if $container->contains($cidr);
+  }
+  print "\n    $cidr not contained";
+  $flag = "\n ";
+}
+print "$flag done.\n";
+print "  Checking alignment:\n";
+foreach $container (@containers) {
+  print "    Container $container:\n";
+  $prev = $container;
+  $sth = $dbh->prepare("(select network(cidr) as net, broadcast(cidr) as bcast ".
+        "from allocations where cidr <<= '$container' and type like '_r') ".
+        "union (select network(cidr) as net, broadcast(cidr) as bcast ".
+        "from freeblocks where cidr <<= '$container' and routed='w') order by net");
+    $sth->execute;
+
+  while (@data = $sth->fetchrow_array) {
+    $cur = new NetAddr::IP $data[0];
+
+    if ($container->numeric == $prev->numeric) {
+      # check if cur starts with master
+      if ($cur->numeric > $prev->numeric) {
+        print "      Gap from start of container $container to first block $cur\n";
+      } elsif ($cur->numeric < $prev->numeric) {
+        print "      BIG problem!  Current block $cur begins before container $container!\n";
+      }
+    } else {
+      if ($cur->numeric < ($prev->numeric + 1)) {
+        print "      Block ".$prev->network." overlaps block $cur\n";
+      } elsif ($cur->numeric > ($prev->numeric + 1)) {
+        print "      Gap between end of block ".$prev->network." and block $cur\n";
+      }
+    }
+
+    $prev = $cur;
+    $prev--;
+
+  } # while (@data...)
+
+  $cur--;
+  $container--;
+  if ($cur->numeric ne $container->numeric) {
+    print "      Gap from $cur to end of container at $container\n";
+  }
+  print "    done $container.\n";
+
+}
+print "  done container alignment.\n";
+print "Done checking container containment.\n\n";
+
+print "Checking for correctness on 'defined' CustIDs:\n";
 # New check:  Make sure "defined" CustIDs are correct.
 $sth = $dbh->prepare("select cidr,type,custid from allocations where not type='cn' order by cidr");
Index: branches/stable/cgi-bin/ipdb.psql
===================================================================
--- branches/stable/cgi-bin/ipdb.psql	(revision 188)
+++ branches/stable/cgi-bin/ipdb.psql	(revision 192)
@@ -120,4 +120,41 @@
 GRANT ALL on "cities" to "ipdb";
 
+--
+-- Selected TOC Entries:
+--
+\connect - ipdb
+
+--
+-- TOC Entry ID 2 (OID 92809)
+--
+-- Name: alloctypes Type: TABLE Owner: ipdb
+--
+
+CREATE TABLE "alloctypes" (
+	"type" character(2) DEFAULT '' NOT NULL,
+	"listname" character varying(40) DEFAULT '',
+	"dispname" character varying(40) DEFAULT '',
+	"listorder" integer DEFAULT 0,
+	"def_custid" character varying(16) DEFAULT '',
+	Constraint "alloctypes_pkey" Primary Key ("type")
+);
+
+--
+-- TOC Entry ID 3 (OID 92809)
+--
+-- Name: alloctypes Type: ACL Owner: 
+--
+
+REVOKE ALL on "alloctypes" from PUBLIC;
+GRANT ALL on "alloctypes" to "kdeugau";
+GRANT ALL on "alloctypes" to "ipdb";
+
+--
+-- Data for TOC Entry ID 4 (OID 92809)
+--
+-- Name: alloctypes Type: TABLE DATA Owner: ipdb
+--
+
+
 COPY "alloctypes" FROM stdin;
 cd	Static Pool - Cable	Cable pool	41	CBL-BUS
@@ -125,12 +162,6 @@
 mp	Static Pool - Dialup	Static dialup pool	43	DIAL-BUS
 wp	Static Pool - Wireless	Static wireless pool	44	WL-BUS
-dc	Dynamic cable block	Dynamic cable block	103	CBL-RES
-dy	Dynamic DSL block	Dynamic DSL block	102	DSL-RES
-dn	Dialup netblock	Dialup netblock	101	DIAL-RES
-dw	Dynamic WiFi block	Dynamic WiFi block	104	WL-RES
 mm	Master block	Master block	999	6750400
-rr	Routing	Routed netblock	500	6750400
 in	Internal netblock	Internal netblock	990	6750400
-ee	End-use netblock	End-use netblock	100	6750400
 sd	Static Pool - Servers	Server pool	40	6750400
 cn	Customer netblock	Customer netblock	0	
@@ -140,3 +171,13 @@
 wi	Static IP - Wireless	Static wireless IP	24	
 si	Static IP - Server pool	Server pool IP	20	6750400
+wc	Reserve for WAN blocks	WAN IP blocks	200	6750400
+wr	Internal WAN block	Internal WAN block	201	6750400
+pc	Reserve for dynamic-route DSL netblocks	Dynamic-route netblocks	202	6750400
+en	End-use netblock	End-use netblock	100	6750400
+me	Dialup netblock	Dialup netblock	101	DIAL-RES
+de	Dynamic DSL block	Dynamic DSL block	102	DSL-RES
+ce	Dynamic cable block	Dynamic cable block	103	CBL-RES
+we	Dynamic WiFi block	Dynamic WiFi block	104	WL-RES
+rm	Routing	Routed netblock	500	6750400
+pr	Dynamic-route DSL netblock	Dynamic-route DSL	203	
 \.
Index: branches/stable/cgi-bin/main.cgi
===================================================================
--- branches/stable/cgi-bin/main.cgi	(revision 188)
+++ branches/stable/cgi-bin/main.cgi	(revision 192)
@@ -325,12 +325,8 @@
 
   while (my @data = $sth->fetchrow_array) {
-    # cidr,custid,type,city,description,notes
-    # Fix up types from pools (which are single-char)
-    # Fixing the database would be...  painful.  :(
-##fixme LEGACY CODE
-    if ($data[2] =~ /^[cdsmw]$/) {
-      $data[2] .= 'i';
-    }
-    my @row = (qq(<a href="/ip/cgi-bin/main.cgi?action=edit&block=$data[0]">$data[0]</a>),
+    # cidr,custid,type,city,description
+    # Prefix subblocks with "Sub "
+    my @row = ( (($data[2] =~ /^.r$/) ? 'Sub ' : '').
+	qq(<a href="/ip/cgi-bin/main.cgi?action=edit&block=$data[0]">$data[0]</a>),
 	$data[1], $disp_alloctypes{$data[2]}, $data[3], $data[4]);
     # Allow listing of pool if desired/required.
@@ -599,5 +595,7 @@
 #    $data[2] =~ s/\s+//g;
 
-    my @row = ("<a href=\"/ip/cgi-bin/main.cgi?action=edit&block=$data[0]\">$data[0]</a>",
+    # Prefix subblocks with "Sub "
+    my @row = ( (($data[2] =~ /^.r$/) ? 'Sub ' : '').
+	qq(<a href="/ip/cgi-bin/main.cgi?action=edit&block=$data[0]">$data[0]</a>),
 	$data[1], $disp_alloctypes{$data[2]}, $data[3], $data[4]);
     # If the allocation is a pool, allow listing of the IPs in the pool.
@@ -622,5 +620,5 @@
 	qq(<input type=hidden name=action value="delete">\n).
 	qq(<input type=hidden name=block value="$master">\n).
-	qq(<input type=hidden name=alloctype value="rr">\n).
+	qq(<input type=hidden name=alloctype value="rm">\n).
 	qq(<input type=submit value=" Remove this block ">\n).
 	qq(</form>\n);
@@ -635,10 +633,13 @@
   # unrouted free blocks, but it's better to let the database do the work if we can.
   $count = 0;
-  $sth = $ip_dbh->prepare("select cidr from freeblocks where routed='y' and cidr <<= '$master' order by cidr");
+  $sth = $ip_dbh->prepare("select cidr,routed from freeblocks where cidr <<= '$master'".
+	" order by cidr");
   $sth->execute();
   while (my @data = $sth->fetchrow_array()) {
-    # cidr,maskbits,city
+    # cidr,routed
     my $cidr = new NetAddr::IP $data[0];
-    my @row = ("<a href=\"/ip/cgi-bin/main.cgi?action=assign&block=$cidr\">$cidr</a>",
+    # Include some HairyPerl(TM) to prefix subblocks with "Sub "
+    my @row = ((($data[1] ne 'y' && $data[1] ne 'n') ? 'Sub ' : '').
+	qq(<a href="/ip/cgi-bin/main.cgi?action=assign&block=$cidr&fbtype=$data[1]">$cidr</a>),
 	$cidr->range);
     printRow(\@row, 'color1') if ($count%2 == 0);
@@ -730,10 +731,27 @@
     $html =~ s|\$\$MASKBITS\$\$|$block->masklen|;
     my $typelist = '';
-    $sth = $ip_dbh->prepare("select type,listname from alloctypes where listorder < 500 and type not like '_i' order by listorder");
-    $sth->execute;
-    my @data = $sth->fetchrow_array;
-    $typelist .= "<option value='$data[0]' selected>$data[1]</option>\n";
-    while (my @data = $sth->fetchrow_array) {
-      $typelist .= "<option value='$data[0]'>$data[1]</option>\n";
+
+    # This is a little dangerous, as it's *theoretically* possible to
+    # get fbtype='n' (aka a non-routed freeblock).  However, should
+    # someone manage to get there, they get what they deserve.
+    if ($webvar{fbtype} ne 'y') {
+      # Snag the type of the block from the database.  We have no
+      # convenient way to pass this in from the calling location.  :/
+      $sth = $ip_dbh->prepare("select type from allocations where cidr >>='$block'");
+      $sth->execute;
+      my @data = $sth->fetchrow_array;
+      $data[0] =~ s/c$/r/;	# Munge the type into the correct form
+      $typelist = "$list_alloctypes{$data[0]}<input type=hidden name=alloctype value=$data[0]>\n";
+    } else {
+      $typelist .= qq(<select name="alloctype">\n);
+      $sth = $ip_dbh->prepare("select type,listname from alloctypes where listorder < 500 ".
+	"and type not like '_i' and type not like '_r' order by listorder");
+      $sth->execute;
+      my @data = $sth->fetchrow_array;
+      $typelist .= "<option value='$data[0]' selected>$data[1]</option>\n";
+      while (my @data = $sth->fetchrow_array) {
+        $typelist .= "<option value='$data[0]'>$data[1]</option>\n";
+      }
+      $typelist .= "</select>\n";
     }
     $html =~ s|\$\$TYPELIST\$\$|$typelist|g;
@@ -839,5 +857,5 @@
       my $city;
       my $failmsg;
-      if ($webvar{alloctype} eq 'rr') {
+      if ($webvar{alloctype} eq 'rm') {
         if ($webvar{allocfrom} ne '-') {
 	  $sql = "select * from freeblocks where maskbits<=$webvar{maskbits} and routed='n'".
@@ -853,5 +871,7 @@
 ##fixme
 # This section needs serious Pondering.
-	if ($webvar{alloctype} =~ /^.[pd]$/) {
+	# Pools of all types get assigned to the POP they're "routed from"
+	# This includes WAN blocks and other netblock "containers"
+	if ($webvar{alloctype} =~ /^.[pdc]$/) {
 	  if (($webvar{city} !~ /^(Sudbury|North Bay)$/) && ($webvar{alloctype} eq 'dp')) {
 	    printError("You must chose Sudbury or North Bay for DSL pools.");
@@ -870,8 +890,10 @@
 	if ($webvar{allocfrom} ne '-') {
 	  $sql = "select cidr from freeblocks where city='$city' and maskbits<=$webvar{maskbits}".
-		" and cidr <<= '$webvar{allocfrom}' and routed='y' order by cidr,maskbits desc";
+		" and cidr <<= '$webvar{allocfrom}' and routed='".
+		(($webvar{alloctype} =~ /^(.)r$/) ? "$1" : 'y')."' order by maskbits desc,cidr";
 	} else {
 	  $sql = "select cidr from freeblocks where city='$city' and maskbits<=$webvar{maskbits}".
-		" and routed='y' order by cidr,maskbits desc";
+		" and routed='".(($webvar{alloctype} =~ /^(.)r$/) ? "$1" : 'y').
+		"' order by maskbits desc,cidr";
 	}
       }
@@ -955,6 +977,5 @@
     } else {
       print qq(<div class="center"><div class="heading">The block $webvar{fullcidr} was ).
-	"sucessfully added as type '$webvar{alloctype}' ".
-	"($disp_alloctypes{$webvar{alloctype}})</div></div>";
+	"sucessfully added as: $disp_alloctypes{$webvar{alloctype}}</div></div>";
     }
     syslog "notice", "$authuser allocated '$webvar{fullcidr}' to '$webvar{custid}' as ".
@@ -963,5 +984,5 @@
     syslog "err", "Allocation of '$webvar{fullcidr}' to '$webvar{custid}' as ".
 	"'$webvar{alloctype}' by $authuser failed: '$msg'";
-    printError("Allocation of $webvar{fullcidr} as $disp_alloctypes{$webvar{alloctype}}".
+    printError("Allocation of $webvar{fullcidr} as '$disp_alloctypes{$webvar{alloctype}}'".
 	" failed:<br>\n$msg\n");
   }
@@ -1023,5 +1044,5 @@
   # Check POP location
   my $flag;
-  if ($webvar{alloctype} eq 'rr') {
+  if ($webvar{alloctype} eq 'rm') {
     $flag = 'for a routed netblock';
     foreach (@poplist) {
@@ -1095,12 +1116,14 @@
 # this has now been Requested, so here goes.
 
-  if ($data[2] =~ /^d[nyc]|cn|ee|in$/) {
+##fixme The check here should be built from the database
+  if ($data[2] =~ /^.[ne]$/) {
     # Block that can be changed
     my $blockoptions = "<select name=alloctype><option".
-	(($data[2] eq 'dn') ? ' selected' : '') ." value='dn'>Dialup netblock</option>\n<option".
-	(($data[2] eq 'dy') ? ' selected' : '') ." value='dy'>Dynamic DSL netblock</option>\n<option".
-	(($data[2] eq 'dc') ? ' selected' : '') ." value='dc'>Dynamic cable netblock</option>\n<option".
+	(($data[2] eq 'me') ? ' selected' : '') ." value='me'>Dialup netblock</option>\n<option".
+	(($data[2] eq 'de') ? ' selected' : '') ." value='de'>Dynamic DSL netblock</option>\n<option". 	(($data[2] eq 'dc') ? ' selected' : '') ." value='dc'>Dynamic cable netblock</option>\n<option".
+	(($data[2] eq 'ce') ? ' selected' : '') ." value='ce'>Dynamic cable netblock</option>\n<option". 	(($data[2] eq 'dc') ? ' selected' : '') ." value='dc'>Dynamic cable netblock</option>\n<option".
+	(($data[2] eq 'we') ? ' selected' : '') ." value='we'>Dynamic wireless netblock</option>\n<option". 	(($data[2] eq 'dc') ? ' selected' : '') ." value='dc'>Dynamic cable netblock</option>\n<option".
 	(($data[2] eq 'cn') ? ' selected' : '') ." value='cn'>Customer netblock</option>\n<option".
-	(($data[2] eq 'ee') ? ' selected' : '') ." value='ee'>End-use netblock</option>\n<option".
+	(($data[2] eq 'en') ? ' selected' : '') ." value='en'>End-use netblock</option>\n<option".
 	(($data[2] eq 'in') ? ' selected' : '') ." value='in'>Internal netblock</option>\n".
 	"</select>\n";
@@ -1199,5 +1222,5 @@
   my ($cidr, $custid, $type, $city, $circid, $desc, $notes, $alloctype);
 
-  if ($webvar{alloctype} eq 'rr') {
+  if ($webvar{alloctype} eq 'rm') {
     $sth = $ip_dbh->prepare("select cidr,city from routed where cidr='$webvar{block}'");
     $sth->execute();
@@ -1223,5 +1246,5 @@
     $desc = "N/A";
     $notes = "N/A";
-  } elsif ($webvar{alloctype} =~ /^.i$/) { # done with alloctype=rr
+  } elsif ($webvar{alloctype} =~ /^.i$/) { # done with alloctype=[rm]m
 
     # Unassigning a static IP
